feat(method): call-residuals — kill the WM1 call-count residuals (6 tasks, message-layer)#154
Merged
Merged
Conversation
…me pointer call-residuals task 1/4. The WM1 re-measure showed every rep re-running `init` on an already-initialised project (+2-4 calls/rep — the double-init lever). - cmd_init: a re-init WITHOUT --force is now a LOUD NO-OP — exit 0, print the resume pointer, write NOTHING (early return before any seed). --force still resets; a fresh init still seeds. Reverses the prior nonzero-refusal contract. - cmd_status: the default view opens with "project exists — do not re-init (use --force to reset)" when state.json is present, so the agent never re-calls init in the first place. --brief/--json/--section unaffected. Change-request supersession (human-approved, not a weakening): the frozen init-resume-pointer v1 refusal contract is replaced by the exit-0 no-op; the three legacy tests pinning it (test_init_resume_pointer, test_add's reinit test) flip to the new contract, and test_init_idempotent_nudge pins the full new behavior (5 asserts, red-first). Zero enforcement-path change (milestone OUT-of-scope). Engine synced ×4 twins, ENGINE_MD5 -> ee4ef957, SEAMS _declared_scope pin 5653->5670. Full fence green (3575 tests). One human freeze at the frozen §3 contract; scope re-crossed once after the pin/twin/test touches widened §5. author: Tin Dang <tindang.ht97@gmail.com>
… when Touches uncovered
call-residuals task 2/4. The WM1 re-measure showed post-freeze re-cross repairs
driven by a too-narrow §5 Scope: the tokens resolve [ok], yet a §3 Touches path
sits outside them, so the gate trips scope_violation → return-to-build → re-cross
(the measured call lever). The freeze scope-echo already printed a per-token
"note: … outside the declared scope"; this escalates it to a fix.
- _scope_echo: in the non-empty-resolved branch, collect the uncovered §3 Touches
paths ONCE (reused by the existing per-token note loop). When any are uncovered,
print exactly one paste-ready line:
scope (paste-ready — declared misses §3 Touches): Scope (may touch): <T>
where <T> = the declared tokens followed by each uncovered Touches path,
space-joined, order-preserving, de-duplicated. The agent pastes the corrected
line at freeze instead of re-deriving scope at the gate.
Propose-not-impose: printed to stdout only, TASK.md is never written. Zero
enforcement change — the UNDECLARED / garbage / all-missing "proposed" path is
untouched (milestone OUT-of-scope). Red test first (test_scope_first_draft, 3
asserts: emits-when-uncovered · silent-when-covered · never-writes).
Engine synced ×4 twins, ENGINE_MD5 -> 3b438d30, SEAMS _declared_scope pin
5670->5677. Full fence green. One human freeze at the frozen §3 contract; scope
re-crossed once after the engine_pin twins widened §5.
author: Tin Dang <tindang.ht97@gmail.com>
…, §5 Scope owns the file write-set
call-residuals task 3. Both TASK templates (full + fast) invited the SAME file
list twice: §3 Grounding `Touches (files · symbols)` and §5 Build-strategy
`Scope (may touch)`. Agents duly authored the write-set twice — the exact
duplication scope-first-draft's own Grounding had to be hand-fixed for this
session ("fix grounding and plan as duplicated scope, touch").
- reworded the 4 placeholder VALUES (2 templates × Touches + Scope):
· §3 Touches → "name symbols, not the full file list — §5 Scope owns the write-set"
· §5 Scope → "the file write-set, the single source of truth (§3 Touches names
symbols, this names files); scope-lock source"
- LABELS + the `./src/` default token are byte-unchanged, so the label-integrity
guard (test_seams_template_wiring) and the twin-byte guard (test_bundle_parity)
stay green.
- migrated the one ripple: test_fastlane_ground_lite now matches the Touches line
by label + `<…>` regex instead of the exact old placeholder — robust to this
and any future reword (greens against both). A content-pin migrating with its
template, not a weakening.
Documentation-layer only — no engine/parser/gate change, so no ENGINE_MD5/SEAMS
re-pin. Red test first (test_template_touches_scope_dedup, 4 asserts across both
tracked template trees). Synced ×4 template twins. Full fence green (3582 tests).
One human freeze at the frozen §3 contract.
author: Tin Dang <tindang.ht97@gmail.com>
…lling §5/§6/exit-criteria restatement
call-residuals task 4. Investigating the recent TASK.md files surfaced a
restatement class: this session's own fast tasks wrote §5 Approach as an echo of
the Strategy stance and §6 Build-expectations as a paraphrase of §1 Accept, and
milestone Exit-criteria restated each task's plan line. The fields were being
re-authored from text already frozen upstream.
Two of the four candidates turned out to be load-bearing GATES, not ceremony —
so the fix tightens the HINT (never drops the field), keeping every gate intact:
- fast TASK.fast.md.tmpl §5 Approach -> a <=6-word domain-technique TAG,
"NOT a restatement of the Strategy above"
- fast §5 Strategy-actually-used -> "as planned" or ONLY divergences ("don't re-narrate")
- fast §6 Build-expectations -> a CONCRETE observable you can SEE (printed line /
exit code / file byte), "NOT a paraphrase of §1 Accept". The `<...>` wrapper +
label stay, so the build-expectations gate (add.py:1446) still fires on the
unfilled shipped template — NON-weakening.
- MILESTONE.md.tmpl Exit-criteria -> the SEEN outcome only, "NOT the task's plan
line"; the `(<- <slug>)` mapping stays (goal_auto_ready unchanged).
The full TASK.md.tmpl §6 block already guards this ("evidence you can SEE, not
test names") — the redundancy was fast-lane-only, so the full template is
untouched.
Doc-layer only -> NO ENGINE_MD5/SEAMS re-pin. Red test first
(test_template_hint_dedup, 6 asserts across both tracked template trees, incl. a
gate-still-fires + parity guard). Full fence caught one downstream pin
(test_strategy_facets.py:FAST_FACET_LINE pinned the old Approach placeholder) —
migrated it to the new text (still one collapsed line, same §5 position: the
facets fast-collapse invariant holds; a pin migration, not a weakening), widened
§5, re-crossed. Synced x4 twins per template. Full fence green (3588 tests).
One human freeze at the frozen §3 contract.
author: Tin Dang <tindang.ht97@gmail.com>
…ume glance card
call-residuals task 5. The WM1 anatomy measured 3-4 status re-reads/rep. The
resume info already lives in the plain `status` view — but at line ~67 of a
69-line dump, so an agent scrolls past project/personas/milestones/tasks to find
its place and re-reads to re-orient.
- cmd_status plain view now leads (right after the do-not-init line, before
`project :`) with a 2-line "now" glance card when an active task exists:
now : '<slug>' · phase=<phase> · next: <verb>
TASK.md: .add/tasks/<slug>/TASK.md · re-orient: add.py status --brief
It reuses `_next_footer` (the ONE next-verb composer, also used by --brief) —
no divergent wording. Distinct "now" label so it never collides with the bottom
`resume :` block (~8 tests pin that). Guarded on an active task — setup and
no-task paths stay byte-identical. --brief / --json / --section unchanged.
Additive stdout reorder — no gate / enforcement / state change (milestone
OUT-of-scope). Red test first (test_status_orientation_diet, 5 asserts incl.
positioned-before-project + brief-unchanged + no-card-guard). Engine synced x4
twins, ENGINE_MD5 -> c0c972e2, SEAMS _declared_scope pin 5677->5688. Full fence
green (3593 tests). One human freeze; scope re-crossed once after the engine_pin
twins widened §5.
author: Tin Dang <tindang.ht97@gmail.com>
…match, not the 50-choice dump
call-residuals task 6 (final). A mistyped top-level command made argparse dump the
full ~50-choice usage — unreadable at a glance, so the agent's reflex is `--help`
or a re-read (the measured 1/rep call lever).
- new _AddArgParser(argparse.ArgumentParser) overrides error() to intercept ONLY
the top-level unknown-command case (prog == "add.py" + an "invalid choice"
message):
add.py: unknown command 'statuss' — did you mean 'status'?
see where you are + all commands: add.py status
difflib.get_close_matches (lazy-imported) picks the suggestion; when nothing is
close the suggestion is omitted but the status pointer stays. Exit 2. No
50-choice dump, no "--help" mention.
- every OTHER parse error delegates to super().error(): a subcommand's own invalid
choice (`stage <bad>`), a missing positional, unrecognized arguments — all keep
argparse's default, so test_graduate_guard / test_argv_portability stay green.
- build_parser now instantiates _AddArgParser for the top-level parser only.
Message-layer only — no gate / enforcement / state change (milestone OUT-of-scope).
Red test first (test_help_habit_kill, 4 asserts incl. the no-near-match variant +
the valid-command invariant). Engine synced x4 twins, ENGINE_MD5 -> 9267a41f (SEAMS
unchanged — _declared_scope sits above the new class). Full fence green (3597 tests).
One human freeze at the frozen §3 contract.
author: Tin Dang <tindang.ht97@gmail.com>
| _active = _active_task(load_state(root)) | ||
| if _active: | ||
| msg += f" (active task: {_active})" | ||
| except Exception: |
| _active = _active_task(load_state(root)) | ||
| if _active: | ||
| msg += f" (active task: {_active})" | ||
| except Exception: |
| try: | ||
| with redirect_stdout(out), redirect_stderr(err): | ||
| add.main(list(argv)) | ||
| except SystemExit: |
| try: | ||
| with redirect_stdout(out), redirect_stderr(err): | ||
| add.main(list(argv)) | ||
| except SystemExit: |
| try: | ||
| with redirect_stdout(out), redirect_stderr(io.StringIO()): | ||
| add.main(list(argv)) | ||
| except SystemExit: |
|
|
||
| Run: python3 -m unittest test_template_touches_scope_dedup -v | ||
| """ | ||
| import re |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
call-residuals — kill the measured WM1 call-count residuals (message-layer only)
Sub-milestone from the six-phase-loop close: the WM1 re-measure proved fidelity MET (0.98) but calls UNMET (20.7 vs ≤12). The anatomy pinned four message-layer levers (double-init · post-freeze re-cross repairs · status re-reads · the
--helphabit). This closes them with zero enforcement-path changes — plus two dedup tasks the user requested along the way.Tasks (6, all gate PASS, red/green TDD, full fence green each)
init-idempotent-nudgeiniton an initialized project is an exit-0 no-op resume pointer (was a nonzero refusal);statusopens with "do not re-init"scope-first-draftScope (may touch):line when declared tokens miss §3 Touches → a re-cross repair becomes a copy-pastetemplate-touches-scope-deduptemplate-hint-dedupstatus-orientation-dietstatusleads with a resume glance card (task · phase · next verb · file) so a single read orients — the resume info was buried at line ~67 of 69help-habit-killadd.py statuspointer instead of the ~50-choice dump — kills the--helpreflexTrust floor held
ENGINE_MD5re-pinned per task (9be0267f→…→9267a41f); SEAMS_declared_scopepin migrated where add.py grew.Notable recoveries (disclosed, not hidden)
template-hint-dedup: the fence caught a value-pin (test_strategy_facets:FAST_FACET_LINE) the plan missed → migrated the pin (not a weakening), re-crossed.scope-first-draft/status-orientation-diet: engine_pin bundle-twin sync tripped the tamper tripwire → widened §5 + re-crossed.Exit bar
5/6 exit criteria are the test-pinned behaviors above (all met). The 6th — a paid, human-gated WM1 re-measure (calls ≤12 mean, fidelity ≥0.97, zero double-init / zero post-freeze re-cross in transcripts) — is intentionally deferred to a human decision, same as prior rounds.
🤖 Generated with Claude Code