Skip to content

Fix everything the SPEC.md migration's grounding pass flagged - #1611

Merged
brillout merged 3 commits into
mainfrom
claude/github-commit-review-i08gay
Aug 21, 2026
Merged

Fix everything the SPEC.md migration's grounding pass flagged#1611
brillout merged 3 commits into
mainfrom
claude/github-commit-review-i08gay

Conversation

@brillout

Copy link
Copy Markdown
Member

Follow-up to #1609: that PR preserved every spec claim the code contradicts and listed them as findings; this PR closes them all — the 13-finding list, plus the watch-relay amplification suleimansh's review added. Three commits:

1. Website copy bug — the Queues section of the-framework.ai rendered "it keeps humans under control"; the spec (and the point of the product) says "in control". One word, Queues.tsx.

2. Watch-relay orphans — the shared watch link's serving side was removed in #1536, but the browser side survived: RelayView.tsx, App's dead ?run= early return, and six spec sentences still promising the feature (watch mode, the "copy a shareable watch link" menu item that AgentActionsMenu.tsx doesn't have, the shared-watch page in the components list, the shared-link sentence in the package spec, and the relay's-own-agents case in events.SPEC.md). All gone; the useWorking/useFavicon/useDaemonHealth calls fall back to their defaults since the dashboard is always local now. The device relay (daemon-to-daemon, /_relay/events?run=) is a live feature and is untouched.

3. Spec-drift corrections — each flagged claim brought back to what the code does, verified against the named code before editing:

  • src/dashboard/dashboard.SPEC.md + test spec: the rollup carries no recent-activity data; the test spec now describes the actual tests (totals, working-now, ordering, ticket presence, and the shape guard pinning retired fields absent).
  • src/dashboard/agent-handoff.test.SPEC.md: tests read the recorded branch and PR rather than re-deriving across candidate names.
  • src/handoff-level.SPEC.md: no stored spelled-out three-stage form exists — the sanitizer reads only handoff.
  • src/dashboard-rpc/SPEC.md: control-file appends (stop, choice, message, arm handoff) separated from direct writes (push/PR/merge run the handoff; start and queue-ticket go through the daemon's wiring).
  • src/dashboard-rpc/control.SPEC.md: "previews" dropped from the direct-wiring list.
  • src/dashboard-rpc/projects.SPEC.md: the removed public-host mode no longer qualifies the onboarding hint.
  • src/dashboard/projects.SPEC.md: last activity comes from the project's agents alone.
  • dashboard/lib/preferences.SPEC.md: notification defaults are framework-side; the theme default (absent follows the OS) lives dashboard-side.
  • dashboard/components/SettingsPage.SPEC.md: the editor dropdown is assembled at run time from detected editors.
  • src/project.SPEC.md + project.ts: the dependency-detection remnants go — stale spec claims, the unused readFileSync import, and the docblock's "detection signals".

No feature is added or removed: the watch relay was already removed in #1536 (it has no FEATURES-SPEC.md row), so FEATURES-SPEC.md is untouched.

Verification: pnpm typecheck clean, pnpm build + all 1489 node tests pass, all 776 dashboard vitest tests pass (the 8 daemon-test failures in a buildless checkout reproduce without these changes — they need dist/ and pass after a build), and the spec linter is green over all 557 SPEC.md files.

🤖 Generated with Claude Code

https://claude.ai/code/session_011XvEviGLEJZsp1h6iWzgma


Generated by Claude Code

claude added 3 commits August 20, 2026 22:58
The Queues section's rendered copy flipped the meaning of its own spec —
"the cockpit that keeps humans in control" — into "keeps humans under
control".

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011XvEviGLEJZsp1h6iWzgma
The shared watch link's serving side went in #1536; the browser side stayed:
RelayView, App's dead ?run= branch, and six spec sentences still promising
the feature. The component and branch go, the hooks fall back to their
defaults (the dashboard is always local now), and the specs stop naming the
watch view, the shareable-link menu item, and the relay's own agents. The
device relay — a different, live feature — is untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011XvEviGLEJZsp1h6iWzgma
The migration's grounding pass flagged claims the code contradicts; this
closes them: the Overview rollup carries no recent-activity data (spec and
test spec now say what the tests cover, including the shape guard), the
handoff tests read the recorded branch and PR rather than re-deriving them,
the handoff setting has no legacy spelled-out form, dashboard-rpc separates
control-file writes from direct handoff/daemon writes and drops the preview
claim, onboarding no longer names the removed public-host mode, last
activity comes from agents alone, the theme default lives dashboard-side,
the editor dropdown is runtime-detected, and project.ts loses its dead
dependency-detection remnants (unused import, stale docblock, stale spec
claims).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011XvEviGLEJZsp1h6iWzgma
@brillout
brillout merged commit 99b05cc into main Aug 21, 2026
2 checks passed
@brillout
brillout deleted the claude/github-commit-review-i08gay branch August 21, 2026 08:02
suleimansh added a commit that referenced this pull request Aug 21, 2026
Rom on #1612: wrapping the reference in backticks stopped the closing, but it
also stopped the reference being a link, and stopped the issue's own timeline
recording that a pull request had mentioned it. The ticket lost the backlink
that says someone is discussing it.

GitHub only obeys a closing keyword when the reference follows it directly, so
two words in between are enough: `close #1164` becomes `close the ticket
#1164`. The sentence still reads as the agent wrote it, the reference is
untouched — clickable, and still cross-referenced onto the issue.

Idempotence now falls out of the rewrite instead of needing a guard: after the
first pass the keyword is followed by the filler, not by a reference.

A reference already inside backticks is still skipped — it is a code sample,
GitHub does not act on it, and the filler would corrupt it.

Also lands the agent-handoff.test.SPEC.md clause deferred while #1611 was
rewriting that sentence.
suleimansh added a commit that referenced this pull request Aug 21, 2026
…hemselves (#1567) (#1612)

* Agents open a pull request through the framework by describing it, rather than running gh themselves

#1567 found that a plan agent's PR body ended "…then comment on and close
#1164", which GitHub read as a closing keyword: the plan merged, the issue
closed, and the next tickets sync deleted the ticket and its fresh plan.

The first fix directions were both wrong. Linting closing keywords out of every
PR body breaks the correct case — 8 of the last 40 PRs legitimately close their
issue that way. And the body that caused it was the agent's own: it ran
`gh pr create` itself, outside the handoff path, where the framework never sees
the text.

brillout's answer on the issue: "As always, I'd frame it as a capability… We
avoid limiting agents — we *enable* agents instead." So there is no
prohibition here. An `open-pr` block is a new non-blocking signal, alongside
set-session-name and ready-for-merge: the agent writes the description, the
framework opens the PR. The agent gets to say what the change turned out to be
instead of the PR body reciting the opening prompt; the framework keeps the
parts that have to stay consistent — the title from the session name, the
ticket's `(fix #N)`, and recording the number on the agent. An agent that
prefers to open its own still can.

The closing-keyword bug is then fixed where it belongs: a plan agent's
description is defused before it is published, because a plan agent's PR lands
the plan, not the work. That is the same rule that already keeps `(fix #N)` off
a plan agent's title (#1327) — this is its other half. Defusing wraps the issue
reference in backticks: the sentence a human reads is unchanged, and GitHub
stops acting on it.

Suite green: 1502 framework tests, 776 dashboard, typecheck clean.

* Tie the open-pr block to the ready-for-merge moment, after a dogfood run skipped it

Live evidence: a Sonnet run on a scratch project got the protocol verbatim in
its system prompt (12,686 chars, `open-pr` present), emitted set-session-name
and ready-for-merge from that same file, and did not emit open-pr.

The other two signals name a concrete moment — the setSessionName() and
setReadyForMerge() calls. This one said "when your work is ready to be
published", which is not a moment the agent can recognize, and the agent had
already emitted ready-for-merge by then. It now hangs off exactly that signal,
and says what is lost without it.

* Defuse closing keywords with a filler, so the issue reference stays live

Rom on #1612: wrapping the reference in backticks stopped the closing, but it
also stopped the reference being a link, and stopped the issue's own timeline
recording that a pull request had mentioned it. The ticket lost the backlink
that says someone is discussing it.

GitHub only obeys a closing keyword when the reference follows it directly, so
two words in between are enough: `close #1164` becomes `close the ticket
#1164`. The sentence still reads as the agent wrote it, the reference is
untouched — clickable, and still cross-referenced onto the issue.

Idempotence now falls out of the rewrite instead of needing a guard: after the
first pass the keyword is followed by the filler, not by a reference.

A reference already inside backticks is still skipped — it is a code sample,
GitHub does not act on it, and the filler would corrupt it.

Also lands the agent-handoff.test.SPEC.md clause deferred while #1611 was
rewriting that sentence.
suleimansh added a commit that referenced this pull request Aug 21, 2026
* Remove the code the watch relay's deletion left behind

#1536 deleted the hosted watch relay and #1611 cleaned up after it, but three
things it was the only reason for stayed:

- AgentFeed's showSessionLink/showName/showStatus were passed `false` by
  AgentView, its only caller, so the AgentOverview they configured hit its
  `if (!sessionLink && !status) return null` on every render. The props and
  that render are gone; AgentOverview itself stays, since ProjectHome uses it
  with the defaults.
- The `enabled` parameter on useWorking/useDaemonHealth/useFavicon was never
  passed `false` by anything — the relay view had been its only caller. Gone,
  along with the two tests that existed only to cover it.
- Comments and specs across nine files still explained live behaviour by
  naming the deleted relay: FileTree "has no checkout", GitStatusBar "on the
  relay", EventList's "read-only relay watch", RoutineWork's sweep note,
  favicon, use-daemon-health's tests. The behaviour is real in each case, only
  the reason was a ghost — reworded to state the condition itself.

The device relay (#1067) is untouched: relay-endpoints, relay-dispatch and
relay-agent are a different feature that shares the word.

No FEATURES-SPEC.md change: none of this was user-visible.

Suite 1489 + 774, typecheck clean.

* AgentFeed's projectId is required: an open gate must never render as log text

The last of the same shape #1615 removes. AgentView is AgentFeed's only caller
and always passes projectId, so the optional prop had exactly one production
value — and the conditional forward below it could only ever take one branch.

Required is the point, not tidiness: with it optional, a future caller that
omits it gets an open choice gate silently rendered as plain log text, which is
a run parked with nothing to answer it (#846). A required prop makes that a
compile error instead of a dead-quiet downgrade.

EventList's own projectId stays optional. It is a leaf presentational component
with 35 direct test renders, and its browser pane already degrades on a
genuinely nullable agentId, so the absent case is a real render mode there
rather than a fiction.
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.

2 participants