Skip to content

fix(cursor): repair crashing attribution suppression and register cursor for crew-dispatch - #10

Merged
Quidge merged 2 commits into
mainfrom
fm/cursor-adapter-fix
Aug 5, 2026
Merged

fix(cursor): repair crashing attribution suppression and register cursor for crew-dispatch#10
Quidge merged 2 commits into
mainfrom
fm/cursor-adapter-fix

Conversation

@Quidge

@Quidge Quidge commented Aug 5, 2026

Copy link
Copy Markdown
Owner

Intent

Fix two defects in the freshly-merged cursor-agent crew harness adapter (Quidge/firstmate PR #9), which is non-functional because cursor crashes at launch. Scope is strictly these two defects plus their tests/docs; explicitly NOT adding context7/MCP wiring (that is a separate task). No behavior change for any existing harness - changes are cursor-scoped and additive/corrective.

Defect 1 (fatal): fm-spawn wrote a per-worktree project .cursor/cli.json of {"version":1,"attribution":{...}} to suppress cursor's default commit/PR agent-attribution trailer (Co-authored-by: Cursor cursoragent@cursor.com). cursor-agent validates that PROJECT config against a strict schema that accepts ONLY permissions, so it rejects version/attribution with "Unrecognized key(s)" and drops the pane to bash; the worker never starts. The attribution block is valid only in the GLOBAL ~/.cursor/cli-config.json, which cursor rewrites at runtime and shares across concurrent workers, so a global edit is unsafe; and there is no CLI flag or env var to disable attribution (verified empirically against cursor-agent 2026.07.23-e383d2b's bundled zod schema). Chosen fix: a per-task git commit-msg hook under state/.cursor-git-hooks/ that strips the Cursor co-author trailer, reached ONLY by the cursor worker via env-injected core.hooksPath (GIT_CONFIG_* exported before launch on the same channel as GOTMPDIR). This choice is deliberate because git resolves a linked worktree's hooks from the shared common .git/hooks dir (empirically proven), so a per-worktree hooks dir would not fire, whereas an env-injected core.hooksPath does. Deliberate constraints, all met: does not crash the launch; touches NO cursor config; makes no destructive or racy global-config edit; installed by fm-spawn and removed at teardown; strips only Co-authored-by trailers in cursor's agent namespace (@cursor.com/@cursor.sh) so it never interferes with legitimate commit messages or human co-authors. Mandatory live proof was performed against a real cursor-agent worker in a throwaway git repo (interactive launch in a separate tmux window, since a crewmate cannot launch the cursor TUI in its own pane): the old .cursor/cli.json reproducibly crashes the launch ("Unrecognized key(s)", pane drops to bash), and the new mechanism launches clean (pane_current_command=cursor-agent) while the worker's OWN autonomous git commit --trailer "Co-authored-by: Cursor <cursoragent@cursor.com>" lands a commit whose body has NO trailer - proving the hook is the sole reason it is absent. Evidence recorded in docs/verification/runtime-backends.md. A unit test alone is intentionally treated as necessary-but-not-sufficient here because the trailer is server-driven and only a real worker emits the --trailer commit.

Defect 2 (minor): cursor was missing from the crew-dispatch verified-harness set in fm-bootstrap.sh, so a valid config/crew-dispatch.json routing work to cursor was wrongly rejected as "unverified harness: cursor". Added cursor to that verified set, and (for validator correctness) to the no-effort branch of the dispatch effort check, since cursor has no effort flag - exactly like opencode/kimi - so a cursor profile carrying an effort is correctly rejected. Deliberate scoping decision: cursor is intentionally NOT added to the remote-secondmate lists (fm-remote-secondmate-control.sh, fm-remote-doctor.sh) or the secondmate-liveness gate in fm-bootstrap.sh, because cursor was verified only as a LOCAL crewmate, not for remote-secondmate use; those omissions are correct and preserved.

Tests/docs: reworked the cursor-harness attribution tests to cover the commit-msg hook behavior (strips the Cursor trailer, preserves human co-authors and clean messages byte-for-byte) and the core.hooksPath env wiring, and to assert the crash-inducing .cursor/cli.json is no longer written; added crew-dispatch cursor validation cases; corrected the attribution mechanism description in harness-adapters SKILL.md; recorded the live crash/fix proof in docs/verification/runtime-backends.md. All colocated tests, shellcheck 0.11.0, and the doc-audience check pass.

What Changed

  • Replace the per-worktree .cursor/cli.json attribution config — which cursor-agent rejects against its project-config schema and crashes the launch on — with a per-task commit-msg hook under state/<id>.cursor-git-hooks/ that strips only cursor-agent's Co-authored-by: <…@cursor.com/.sh> trailer; fm-spawn.sh writes and activates it via env-injected GIT_CONFIG_*/core.hooksPath (gated to non-secondmate cursor workers), and fm-teardown.sh removes the hook dir and drops all .cursor/cli.json cleanup.
  • Add cursor to the crew-dispatch verified-harness set in fm-bootstrap.sh, and to the no-effort branch of the dispatch effort check (alongside opencode/kimi) so a cursor profile carrying an effort flag is correctly rejected.
  • Rework the cursor-harness tests to cover the trailer-stripping hook, human/clean-message preservation, and core.hooksPath wiring, assert .cursor/cli.json is no longer written, add crew-dispatch cursor validation cases, and update the attribution-mechanism description in the harness-adapters SKILL plus the live crash/fix proof in the runtime-backends doc.

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed
✅ **Rebase** - passed
✅ **Review** - completed
✅ **Test** - passed
✅ **Document** - passed
✅ **Lint** - passed
✅ **Push** - passed

Quidge added 2 commits August 5, 2026 00:32
…ister cursor for crew-dispatch

The freshly-landed cursor-agent adapter (PR #9) crashed at launch and could
not be routed via crew-dispatch. Two cursor-scoped, additive/corrective fixes:

Defect 1 (fatal): fm-spawn wrote a project .cursor/cli.json carrying
`{"version":1,"attribution":{...}}`. cursor-agent validates that project
config against a strict schema that accepts only `permissions`, so it rejected
`version`/`attribution` with "Unrecognized key(s)" and dropped the pane to a
bash prompt; the worker never started (the `attribution` block is only valid in
the GLOBAL ~/.cursor/cli-config.json, which cursor rewrites at runtime and
shares across workers). There is no CLI flag or env var to disable attribution.

Replace it with a per-task git commit-msg hook that strips cursor's
`Co-authored-by: Cursor <cursoragent@cursor.com>` trailer, reached only by the
cursor worker through an env-injected core.hooksPath (git resolves a linked
worktree's hooks from the shared common dir, so a per-worktree hooks dir would
not fire). The hook lives under state/, touches no cursor config, never races a
concurrent worker, preserves human co-authors, and is removed at teardown.

Defect 2 (minor): add cursor to the crew-dispatch verified-harness set in
fm-bootstrap so a config/crew-dispatch.json routing work to cursor validates
clean, and treat cursor like opencode/kimi in effort validation (it has no
effort flag). Scoped to crewmate/scout-facing lists only; the remote-secondmate
lists and secondmate-liveness gate correctly continue to omit cursor, which was
verified only as a local crewmate.

Tests: rework the cursor-harness attribution tests to cover the commit-msg hook
(trailer stripped, human co-authors and clean messages preserved) and the
core.hooksPath env wiring, and to assert the crash-inducing .cursor/cli.json is
no longer written; add crew-dispatch cases for cursor. Docs: correct the
attribution mechanism in harness-adapters and record the live crash/fix proof.
@Quidge
Quidge merged commit a52bcb1 into main Aug 5, 2026
13 checks passed
@Quidge
Quidge deleted the fm/cursor-adapter-fix branch August 5, 2026 03:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant