Skip to content

a task whose contract names an HTTP route like /top is refused as a folder it does not stand in #1066

Description

@santoshkumarradha

What happened

A task about a web server is refused before it starts when its deliverable or acceptance names an HTTP route. The ground lint reads a route like /top or /links as an absolute folder outside the task's ground:

this task names a folder it does not stand in: /top

The model usually rewrites the contract and proposes again, so the conversation fills with refused propose_task calls ("stuck: propose_task has failed the same way 3 times") and the work starts late or not at all. Any web project hits it, because routes are the natural way to say what an HTTP task delivers.

Seen on dev@7cb6fd58f, codeaf chat in any git repository.

Replication

Deterministic (no model). Add this beside TestATaskNamingAFolderItDoesNotStandInIsRefused in internal/session/taskstands_test.go:

func TestARouteInTheContractIsNotAFolder(t *testing.T) {
	repo := newTestRepo(t)
	agent, _ := newTestAgent(t, &scriptedCompleter{}, func(config *Config) {
		config.Workspace = repo
	})
	arguments, _ := json.Marshal(taskArguments{
		Title: "top links page", Summary: "s", Brief: "Add a page listing the most clicked links.",
		Deliverable: "a GET /top handler and its test",
		Acceptance:  "GET /top returns 200 and lists links by clicks; POST /links still returns 201",
	})
	result, isError, err := agent.proposeTask(context.Background(), arguments)
	if err != nil {
		t.Fatalf("proposeTask errored the turn: %v", err)
	}
	if isError {
		t.Fatalf("refused: %q", result)
	}
}
make test-focus PKGS=./internal/session RUN='^TestARouteInTheContractIsNotAFolder$$'

Today it fails:

route_repro_test.go:24: refused: "this task names a folder it does not stand in: /top"

Field (real models). In a small Go HTTP service in a git repository, run codeaf chat with any open model (e.g. --model deepseek/deepseek-v4.1-flash) and ask for two or three HTTP features as separate tasks, for example "rate limit link creation per IP and add a page listing the most clicked links, one task each". Most runs show at least one refusal naming a route. A few cents, a couple of minutes.

Where

groundLint in internal/session/taskstands.go: the second loop over pathTokens(spec.deliverable + "\n" + spec.acceptance) refuses any absolute token that groundHolds rejects. pathTokens / looksLikePath treat every token containing / as a path, so /top, /links, /{code} and /api/v1/users all qualify.

The fix

A token that looks absolute but whose first folder does not exist on this machine names a route, not a place, and is not a reason to refuse. Real absolute paths outside the ground (/Users/..., /home/..., /tmp/...) keep refusing exactly as today. Checking the first component on disk is enough and costs one stat per token; a route that happens to share a top-level name with a real root folder (/usr, /opt) still refuses, which is acceptable and rare.

Acceptance

  • e2e: the tmux suite drives a proposal whose acceptance says GET /top returns 200 in a git repository and asserts the task row appears running, with no names a folder it does not stand in line on screen.
  • e2e: the control: a proposal whose deliverable names a real directory outside the ground is still refused with this task names a folder it does not stand in: followed by that directory.
  • Unit: TestARouteInTheContractIsNotAFolder above passes, and TestATaskNamingAFolderItDoesNotStandInIsRefused still passes.
  • The manual page on where a task works (internal/manual/chat/) says a route in a task's contract is not read as a folder, and the change entry's invalidates names the old refusal.

Drafted with CodeAF · reviewed and owned by the author

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    good first issueSmall and isolated, the acceptance already written, no ruling owed; a safe first pull request

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions