diff --git a/lib/autospec/formatter.rb b/lib/autospec/formatter.rb
new file mode 100644
index 00000000000..bbc151b194c
--- /dev/null
+++ b/lib/autospec/formatter.rb
@@ -0,0 +1,20 @@
+require "rspec/core/formatters/base_formatter"
+
+module Autospec; end
+class Autospec::Formatter < RSpec::Core::Formatters::BaseFormatter
+
+  def dump_summary(duration, total, failures, pending)
+    failed_specs = examples.delete_if{|e| e.execution_result[:status] != "failed"}.map{|s| s.metadata[:location]}
+
+    # if this fails don't kill everything
+    begin
+      FileUtils.mkdir_p('tmp')
+      File.open("./tmp/rspec_result","w") do |f|
+        f.puts failed_specs.join("\n")
+      end
+    rescue
+      # nothing really we can do, at least don't kill the test runner
+    end
+  end
+
+end
diff --git a/lib/autospec/runner.rb b/lib/autospec/runner.rb
new file mode 100644
index 00000000000..5cef584a245
--- /dev/null
+++ b/lib/autospec/runner.rb
@@ -0,0 +1,232 @@
+require "drb/drb"
+require "thread"
+
+module Autospec; end
+
+class Autospec::Runner
+  MATCHERS = {}
+  def self.watch(pattern, &blk)
+    MATCHERS[pattern] = blk
+  end
+
+  watch(%r{^spec/.+_spec\.rb$})
+  watch(%r{^lib/(.+)\.rb$})     { |m| "spec/components/#{m[1]}_spec.rb" }
+  watch('spec/spec_helper.rb')  { "spec" }
+
+  # Rails example
+  watch(%r{^app/(.+)\.rb$})                           { |m| "spec/#{m[1]}_spec.rb" }
+  watch(%r{^app/(.*)(\.erb|\.haml)$})                 { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
+  watch(%r{^app/controllers/(.+)_(controller)\.rb$})  { |m| "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb" }
+  watch(%r{^spec/support/(.+)\.rb$})                  { "spec" }
+  watch('app/controllers/application_controller.rb')  { "spec/controllers" }
+
+  # Capybara request specs
+  watch(%r{^app/views/(.+)/.*\.(erb|haml)$})          { |m| "spec/requests/#{m[1]}_spec.rb" }
+
+
+  def self.run
+    self.new.run
+  end
+
+  def initialize
+    @queue = []
+    @mutex = Mutex.new
+    @signal = ConditionVariable.new
+    start_service_queue
+  end
+
+  def run
+    if already_running?(pid_file)
+      puts "autospec appears to be running, it is possible the pid file is old"
+      puts "if you are sure it is not running, delete #{pid_file}"
+      return
+    end
+    write_pid_file(pid_file, Process.pid)
+
+    start_spork
+    Signal.trap("HUP") {stop_spork; exit }
+    Signal.trap("SIGINT") {stop_spork; exit }
+
+    Thread.start do
+      Listen.to('.', relative_paths: true) do |modified, added, removed|
+        process_change([modified, added].flatten.compact)
+      end
+    end
+
+    @mutex.synchronize do
+      @queue << ['spec', 'spec']
+      @signal.signal
+    end
+
+    Process.wait
+
+  rescue => e
+    puts e
+    puts e.backtrace
+    stop_spork
+  end
+
+
+  def process_change(files)
+    return unless files.length > 0
+    specs = []
+    files.each do |file|
+      MATCHERS.each do |k,v|
+        if m = k.match(file)
+          spec = v ? ( v.arity == 1 ? v.call(m) : v.call   ) : file
+          if File.exists?(spec) || Dir.exists?(spec)
+            specs << [file, spec]
+          end
+        end
+      end
+    end
+    queue_specs(specs)
+  rescue => e
+    p "failed in watcher"
+    p e
+    p e.backtrace
+  end
+
+  def queue_specs(specs)
+    if specs.length == 0
+      locked = @mutex.try_lock
+      if locked
+        @signal.signal
+        @mutex.unlock
+      end
+      return
+    else
+      spork_service.abort
+    end
+
+    @mutex.synchronize do
+      specs.each do |c,spec|
+        @queue.delete([c,spec])
+        if @queue.last && @queue.last[0] == "focus"
+          focus = @queue.pop
+          @queue << [c,spec]
+          if focus[1].include? spec || c != spec
+            @queue << focus
+          end
+        else
+          @queue << [c,spec]
+        end
+      end
+      @signal.signal
+    end
+  end
+
+  def start_service_queue
+    @worker ||= Thread.new do
+      while true
+        @mutex.synchronize do
+          last_failed = false
+          current = @queue.last
+          if current
+            result = run_spec(current[1])
+            if result == 0
+              @queue.pop
+            else
+              last_failed = true
+              if result.to_i > 0
+                # focus
+                specs = failed_specs[0..10]
+                if current[0] == "focus"
+                  @queue.pop
+                end
+                @queue << ["focus", specs.join(" ")]
+              end
+            end
+          end
+          @signal.wait(@mutex) if @queue.length == 0 || last_failed
+        end
+      end
+    end
+  end
+
+  def failed_specs
+    specs = []
+    path = './tmp/rspec_result'
+    if File.exist?(path)
+      specs = File.open(path) { |file| file.read.split("\n") }
+      File.delete(path)
+    end
+
+    specs
+  end
+
+  def run_spec(specs)
+    File.delete("tmp/rspec_result") if File.exists?("tmp/rspec_result")
+    args = ["-f", "progress", specs.split(" "),
+            "-r", "#{File.dirname(__FILE__)}/formatter.rb",
+            "-f", "Autospec::Formatter"].flatten
+
+    spork_service.run(args,$stderr,$stdout)
+  end
+
+
+  def spork_pid_file
+    Rails.root + "tmp/pids/spork.pid"
+  end
+
+  def pid_file
+    Rails.root + "tmp/pids/autospec.pid"
+  end
+
+  def already_running?(pid_file)
+    if File.exists? pid_file
+      pid = File.read(pid_file).to_i
+      Process.getpgid(pid) rescue nil
+    end
+  end
+
+  def write_pid_file(file,pid)
+    FileUtils.mkdir_p(Rails.root + "tmp/pids")
+    File.open(file,'w') do |f|
+      f.write(pid)
+    end
+  end
+
+  def spork_running?
+    spork_service.port rescue nil
+  end
+
+  def spork_service
+
+    unless @drb_listener_running
+      begin
+        DRb.start_service("druby://127.0.0.1:0")
+      rescue SocketError, Errno::EADDRNOTAVAIL
+        DRb.start_service("druby://:0")
+      end
+
+      @drb_listener_running = true
+    end
+
+    @spork_service ||= DRbObject.new_with_uri("druby://127.0.0.1:8989")
+  end
+
+  def stop_spork
+    pid = File.read(spork_pid_file).to_i
+    Process.kill("SIGHUP",pid)
+  end
+
+  def start_spork
+
+    if already_running?(spork_pid_file)
+      puts "Killing old orphan spork instance"
+      stop_spork
+      sleep 1
+    end
+
+    @spork_pid = Process.spawn("RAILS_ENV=test bundle exec spork")
+    write_pid_file(spork_pid_file, @spork_pid)
+
+    running = false
+    while !running
+      running = spork_running?
+      sleep 0.1
+    end
+
+  end
+end
diff --git a/lib/tasks/autospec.rake b/lib/tasks/autospec.rake
new file mode 100644
index 00000000000..20c5db253f1
--- /dev/null
+++ b/lib/tasks/autospec.rake
@@ -0,0 +1,9 @@
+# I like guard, don't get me wrong, but it is just not working right
+# architectually it can not do what I want it to do, this is how I want
+# it to behave
+
+desc "Run all specs automatically as needed"
+task "autospec" => :environment do
+  require 'autospec/runner'
+  Autospec::Runner.run
+end