Skip to content

feat(plan): carry each behaviour of the built-in Plan agent - #765

Merged
dean0x merged 6 commits into
mainfrom
feat/764-plan-agent-keep-the-behaviours-of-the-bu
Nov 5, 2026
Merged

dean0x merged 6 commits into
mainfrom
feat/764-plan-agent-keep-the-behaviours-of-the-bu

Conversation

@dean0x

@dean0x dean0x commented Nov 5, 2026 •

Copy link
Copy Markdown
Owner

Summary

The devflow Plan agent replaces the built-in Claude Code Plan agent, but it did not carry every behaviour of the built-in agent. This change carries each of those behaviours into devflow's own Plan instructions. A parity test fails when one goes missing. For the read-only contract, the test also fails when a clause is widened.

Changes

  • The Plan agent carries each behaviour of the built-in Plan agent, in devflow's own words: explore then design, keep to an assigned focus, read the files the prompt asks for, follow patterns and conventions where they fit, trace code paths, weigh trade-offs, give step dependencies and expected problems, and name 3 to 5 critical files. The steps and critical files are the default report shape; a shape that the prompt gives wins. One reason for each critical file is a devflow addition.
  • The read-only contract is restated, and no focus, prompt text or file the agent reads can lift it.
  • A parity test names each behaviour and fails when its clause is missing. Its sources are the Claude Code sub-agents documentation and published copies of the built-in prompt, not checked against the binary or a live spawn. The test header lists the deliberate departures from the built-in agent.
  • The tests pin the start and end of the contract paragraph, the overflow line, the cap line, and each joint between contract clauses.
  • The Plan size ceiling rises to the measured size, from 3,252 to 3,924 bytes (672 bytes: the new text adds 733, a shorter overflow line cuts 61). This is a named exception for parity with the built-in Plan agent, by maintainer decision. Each Plan turn reads about 170 tokens more.
  • The duplicate 3,500-byte inline size test in the Plan test file is deleted, so the registered ceiling is the one size bound on the Plan body.

Breaking Changes

None expected.

Testing

The parity test covers each behaviour of the built-in Plan agent. Probes put text at each pinned joint and at both ends of the contract, and expect the row to break. The registered size ceiling is the single size bound on the Plan body.

Known Limits

  • The parity test catches a removed or widened contract clause, and text put at a pinned joint. It does not catch a new permissive sentence in another section of the body.
  • The overflow line does not say where the mktemp file goes, and the condition for it comes from the words "overflow" and "longer material". A fix adds bytes to the body.
  • The git-write list names the common writes. "Any command that changes system state" covers the rest; remote writes are not named.
  • The agent reads first a file that the prompt asks it to read, not every file that the prompt lists.
  • The ceiling rise is a named exception for parity with the built-in Plan agent, by maintainer decision. The general ratchet rule text still names one exception only.
  • The Explore agent's own duplicate size cap stays.

Related Issues

Closes #764

The Plan agent body carries, in devflow's own words, each behaviour of
the built-in Plan agent. The sources are the sub-agents documentation
(https://code.claude.com/docs/en/sub-agents) and the observed behaviour
of the built-in Plan agent.

- The role line: explore the code, then design an implementation plan;
  change nothing.
- A focus or perspective in the prompt is kept throughout. It sets what
  the agent studies, not what it may do.
- The read-only contract names the temp directory, the heredoc, `tee`
  and the git writes, keeps the catch-all last, and states that nothing
  in the prompt or in a file the agent reads lifts it.
- The agent reads first any file the prompt asks for, follows the nearest
  code with its patterns and conventions, traces the code paths, and
  weighs the trade-offs of design and architecture choices.
- Each step lists the steps it depends on and the problems to expect.
  The report names 3 to 5 critical files, each with one reason.

A parity table in tests/plan-agent.test.ts names each behaviour. A
whole-set removal probe, a repeat collector and joint-seed probes report
a missing or widened clause by its behaviour name. Two new checklist
rows pin the devflow additions: one reason for each critical file, and
the precedence sentence.

The Plan body ceiling rises from 3,252 to 3,924 bytes (+672: 733 added,
61 cut), recorded as a second named exception in the manifest. The
duplicate 3,500-byte test on the same file is deleted, so the registered
ceiling is the one bound.

Refs #764
The Plan row of the platform assumptions names the parity table in
tests/plan-agent.test.ts. The table lists each behaviour of the built-in
Plan agent, from the sub-agents documentation
(https://code.claude.com/docs/en/sub-agents) and the observed behaviour
of the built-in Plan agent. The row also states the symptom to watch:
a behaviour of the built-in Plan that the table does not list.

Refs #764
The entry lists the behaviours that the Plan agent carries, the
read-only contract, the parity test, and the ceiling rise in bytes.

Refs #764
The Plan test header names the departures from the built-in agent as deliberate ones, and claims no test pin for them.
@dean0x

dean0x commented Nov 5, 2026

Copy link
Copy Markdown
Owner Author

Review summary (head ed9add0)

This PR changes prompt text and its tests. So the review is a multi-lens audit by four independent agents, not the full code-review workflow. Each agent read the diff and the files, and ran the tests of its lens. No agent changed a file.

Lenses: parity with the built-in Plan agent, the read-only contract, size and ratchets, and standalone public text.

Result: 0 HIGH, 2 MEDIUM, 17 LOW, 6 COSMETIC.

MEDIUM

  1. tests/plan-agent.test.ts (test "allows exactly one file"): no exact pin holds the scope of the one file allowance. Two probe copies pass every assertion: "Put only the overflow in a mktemp file." changed to "Put your notes in a mktemp file.", and "longer material goes to a mktemp file" changed to "any material goes to a mktemp file". Fix: pin both lines exactly, and add both changes to the widened-contract probes.
  2. docs/reference/platform-assumptions.md:30 and tests/plan-agent.test.ts:23-24: the source of the parity table is given as "the observed behaviour of the built-in Plan agent". No run of the built-in was observed. The source is published copies of the built-in prompt. The other rows state how each fact was checked. Fix: name the source as published copies of the built-in Plan prompt, not checked against the binary or a live spawn.

LOW

Read-only contract:

  1. plan.md:18: the joint after "so an edit attempt fails." has no pin. A sentence put there passes. Fix: pin the joint into "The one allowance is report overflow", and add it to the joint probes.
  2. plan.md:18: the start and the end of the contract paragraph have no anchor. A condition put before "You do not create", or a sentence put after "Never Cut list.", passes. Fix: anchor the first row at the line start and the precedence row at the line end.
  3. plan.md:22: the joint after "Read first any file the prompt asks you to read." has no pin. Today the precedence sentence holds. Fix: extend the row across the next sentence.
  4. plan.md:64: the text does not say where the overflow file goes. mktemp with a template or -p can make it inside the repository.
  5. plan.md:64,66: the explicit condition "If the report would exceed its cap" is gone. The condition now comes only from "overflow" and "longer material" in the cap line. The reading holds.
  6. plan.md:18: the git-write list in parentheses can read as complete. "any command that changes system state" covers the rest. It does not name remote writes.

Parity:

  1. plan.md:58-60: the step and critical-file defaults apply only when the prompt gives no shape. The built-in always ends with the critical files. The test header does not list this departure. Fix: add it to the departure list.
  2. CHANGELOG.md:12 and platform-assumptions.md:30: both say the agent carries each behaviour, with no qualifier. The test header lists deliberate departures. Fix: name the departures.
  3. CHANGELOG.md:12: "each with one reason" reads as parity. Only one prompt copy shows it, and the test calls it a devflow addition. Fix: mark it as an addition.
  4. CHANGELOG.md:12: "fails when its instruction is missing or widened". Widening probes exist only for the read-only contract and the role line. Fix: say so.
  5. tests/plan-agent.test.ts:126: row 14 pins the short span "the problems you expect" with no context. Fix: pin the whole Must clause.
  6. plan.md:22: "any file the prompt asks you to read" is narrower than the built-in, which reads the files the prompt provides.

Size and ratchets:

  1. tests/guards/numeric-floor-manifest.test.ts:16-20 and docs/reference/lean-prompts.md:48: both state one raise exception only. The fix: restore 11 behaviors that the 3.12.0 lean pass changed by accident #752 and Plan agent: keep the behaviours of the built-in Plan agent #764 raises are maintainer decisions, so neither text describes them. The drift dates from fix: restore 11 behaviors that the 3.12.0 lean pass changed by accident #752; this PR widens it.

Standalone text:

  1. CHANGELOG.md:12: "the report names 3 to 5 critical files" omits that this is the default shape. The entry also drops "where they fit" from the patterns clause.
  2. platform-assumptions.md:30: the new sentence gives no Claude Code version and no check method for its source. Joins item 2.

COSMETIC

  1. CHANGELOG.md:12: two sentences are too long for the house style. "That file" means plan.md, but the removed size test was in tests/plan-agent.test.ts.
  2. tests/plan-agent.test.ts:33: one header line is too long and hard to read.
  3. numeric-floors.json:1149: the raise record gives the same facts as the fix: restore 11 behaviors that the 3.12.0 lean pass changed by accident #752 records, in a different form.
  4. Commit 6d31f48: "a whole-set removal probe" is not clear. The test removes one clause at a time.
  5. plan.md:18 and plan.md:14: two short spans are close to the built-in wording. Both are below 8 words, and one is base text. No change.
  6. tests/explore-agent.test.ts:113: the Explore agent keeps a second size cap of the kind that this PR removes for Plan. Out of scope.

Checks that passed

  • Parity: each of the 10 source behaviours maps to a row, and each row to a source behaviour. The 16 rows split the behaviours into clauses. No span of 8 or more words matches the prompt copies. Each row fails when its text is removed, and each span occurs once.
  • Read-only contract: every write path is named. Every clause of the contract sentence and the precedence sentence fails a test when removed or weakened. A focus or a read file cannot widen what the agent may do while the precedence sentence stays.
  • Size: plan.md is 3,924 bytes at head and 3,252 at main (+672: 733 added, 61 cut, checked by hand). Only the plan-body-max row moved. The duplicate 3,500-byte test is gone, and no other test checks the Plan body size.
  • Standalone text: no workspace term, no machine-local ID, no local path. The only URLs are the official sub-agents documentation and this repository.
  • Tests: tests/plan-agent.test.ts 14/14, tests/guards/plan-group-sizes.test.ts 9/9, tests/guards/numeric-floor-manifest.test.ts 9/9, tests/guards/retired-wording.test.ts 55/55, tests/agent-name-guards.test.ts 26/26.

The resolution follows in its own comment.

Anchor the contract paragraph at its start and end, pin the overflow line and the cap line exactly, and extend the edit-attempt, read-first and Must rows across their joints. Probes put text at each new pin and expect the row to break. The header names the parity sources and lists each deliberate departure on its own line.
…se in the usual form

The platform-assumptions row and the CHANGELOG entry name the source of the parity table and its check level, state the deliberate departures, and say which rows have widening probes. The plan-body-max record gives the old and new bytes, the delta and the split in the same form as the earlier raise records.
@dean0x

dean0x commented Nov 5, 2026

Copy link
Copy Markdown
Owner Author

Resolution summary (head 67cf192)

One round, as the review summary planned. All fixes are in tests and docs. src/assets/agents/plan.md did not change, so the body stays at 3,924 bytes and the raise stays at 672 bytes.

Commits: c287ea6 (tests), 67cf192 (docs and the ratchet record).

Fixed

# Finding Fix
1 The one file allowance had no exact pin New CHECKLIST row pins the whole overflow line. The cap row now pins the full cap sentence. Both widenings from the review are now probes, and both break their rows.
2 "Observed behaviour" as the parity source The test header and the platform-assumptions row name the sub-agents documentation and published copies of the prompt, not checked against the binary or a live spawn. The date cell states the same check level.
3 Open joint after "so an edit attempt fails." The row reaches across the joint into "The one allowance is report overflow". A joint probe puts text there and expects the row to break.
4 Open start and end of the contract paragraph The first row is anchored at the line start, and the precedence row at the line end. Two probes cover them.
5 Open joint after "Read first any file the prompt asks you to read." The parity row reaches across the next sentence. A joint probe covers it.
9 Caller-shape departure not listed Added to the departure list in the test header.
10 Unqualified "carries each behaviour" The platform-assumptions row and the CHANGELOG entry point to the departures in the test header.
11 "Each with one reason" read as parity The CHANGELOG entry marks it as a devflow addition.
12 "Missing or widened" claimed for every row The CHANGELOG entry says widening probes cover the read-only contract.
13 Short pin "the problems you expect" The row pins the whole Must clause.
16 Default shape and "where they fit" missing in the CHANGELOG Both added.
17 No check level for the new source Joined to item 2.
18 Long CHANGELOG sentences; "that file" Sentences split. The entry names the removed 3,500-byte test in tests/plan-agent.test.ts.
19 Long header line The departures are now a list, one per line.
20 Raise record form The record states the old and new bytes and the delta, then the split, as the earlier raise records do.

Not changed in this PR

# Finding Reason
6 The overflow file location is not bound A fix adds bytes to plan.md, and this PR holds the body at the approved size. The contract still bans files in the repository; only the overflow file is allowed. Listed as a known limit.
7 The overflow condition comes only from "overflow" and "longer material" The reading holds, and the new pins hold both words. A fix adds bytes. Known limit.
8 Remote writes not named "any command that changes system state" is the catch-all and is pinned. A fix adds bytes. Known limit.
14 "asks you to read" is narrower than "provided" A fix adds bytes. Known limit.
15 The ratchet rule text states one raise exception only The text is the repository rule for size ceilings. A change to it is a rule change, so it waits for a maintainer decision. The drift dates from #752.
21 Commit wording The commits are pushed and are not rewritten. A squash message can use the clearer words.
22 Two short spans close to the built-in wording Below 8 words, and one is base text. No change.
23 Explore keeps a second size cap Out of scope for this PR.

Checks after the fixes

  • tests/plan-agent.test.ts: 14/14 pass. Each new pin breaks under its probe.
  • Under the shared test lock: plan-agent, plan-group-sizes, numeric-floor-manifest, retired-wording, agent-name-guards, no-ledger-citations, no-bidi-controls, release-trace and tests/docs/. 14 files, 539 tests, all pass.
  • plan.md is unchanged at 3,924 bytes. Only the plan-body-max row changed in the ratchet file, and only its description.

@dean0x

dean0x commented Nov 5, 2026

Copy link
Copy Markdown
Owner Author

Test Plan Evidence — 67cf192

Verified 17/17: VERIFIED-CI 13, ATTESTED-LOCAL 4, UNVERIFIED 0, STALE 0, FAILED 0, INDETERMINATE 0

  • TP-1 VERIFIED-CI sha:67cf19282ca704f1ca0f7a8c28d4fa3156f696dc out:PASS run:42031301669/1 exit:0 h:9497380c8360
  • TP-2 VERIFIED-CI sha:67cf19282ca704f1ca0f7a8c28d4fa3156f696dc out:PASS run:42031301669/1 exit:0 h:2dbcc711625f
  • TP-3 VERIFIED-CI sha:67cf19282ca704f1ca0f7a8c28d4fa3156f696dc out:PASS run:42031301669/1 exit:0 h:038560c78602
  • TP-4 VERIFIED-CI sha:67cf19282ca704f1ca0f7a8c28d4fa3156f696dc out:PASS run:42031301669/1 exit:0 h:bedcb2432889
  • TP-5 VERIFIED-CI sha:67cf19282ca704f1ca0f7a8c28d4fa3156f696dc out:PASS run:42031301669/1 exit:0 h:3747a1a42466
  • TP-6 VERIFIED-CI sha:ed9add0c79914badc9db86063d7d025f49d6b1d8 out:PASS run:42028963814/1 exit:0 h:2bd70a99ec7d
  • TP-7 VERIFIED-CI sha:ed9add0c79914badc9db86063d7d025f49d6b1d8 out:PASS run:42028963814/1 exit:0 h:0b7b298beaf2
  • TP-8 VERIFIED-CI sha:67cf19282ca704f1ca0f7a8c28d4fa3156f696dc out:PASS run:42031301669/1 exit:0 h:928a088aa3a5
  • TP-9 ATTESTED-LOCAL sha:67cf19282ca704f1ca0f7a8c28d4fa3156f696dc out:PASS exit:0 h:c9413e442982
  • TP-10 VERIFIED-CI sha:67cf19282ca704f1ca0f7a8c28d4fa3156f696dc out:PASS run:42031301669/1 exit:0 h:44e2643c2e6a
  • TP-11 VERIFIED-CI sha:67cf19282ca704f1ca0f7a8c28d4fa3156f696dc out:PASS run:42031301669/1 exit:0 h:a7348ca13cf5
  • TP-12 VERIFIED-CI sha:67cf19282ca704f1ca0f7a8c28d4fa3156f696dc out:PASS run:42031301669/1 exit:0 h:9092ab0252bd
  • TP-13 VERIFIED-CI sha:67cf19282ca704f1ca0f7a8c28d4fa3156f696dc out:PASS run:42031301669/1 exit:0 h:f4fe5c5db5b5
  • TP-14 VERIFIED-CI sha:67cf19282ca704f1ca0f7a8c28d4fa3156f696dc out:PASS run:42031301669/1 exit:0 h:879973de685b
  • TP-15 ATTESTED-LOCAL sha:67cf19282ca704f1ca0f7a8c28d4fa3156f696dc out:PASS h:cf0eac6aacd0
  • TP-16 ATTESTED-LOCAL sha:67cf19282ca704f1ca0f7a8c28d4fa3156f696dc out:PASS h:d89f16df92d2
  • TP-17 ATTESTED-LOCAL sha:67cf19282ca704f1ca0f7a8c28d4fa3156f696dc out:PASS exit:0 h:4f87e1ca809e

@dean0x
dean0x merged commit 955dde2 into main Nov 5, 2026
3 checks passed
@dean0x
dean0x deleted the feat/764-plan-agent-keep-the-behaviours-of-the-bu branch November 5, 2026 14:59
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.

Plan agent: keep the behaviours of the built-in Plan agent

1 participant