Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .add/SEAMS.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Citations: 232 files reference "byte-identical" in `.add/tasks/` — method:

## scope-token-grammar
Name: §5 "Scope (may touch):" token-resolution grammar
Anchor: `add-method/tooling/add.py:5581` (`_declared_scope`) <!-- re-pinned 2026-07-13 fold-draft-at-close: 5562→5581 (the cmd_milestone_done draft block above it — the pin drifts on ANY upstream add.py change; symbol cited so the drift self-describes; todo #30 seams-symbol-pins retires this class) -->
Anchor: `add-method/tooling/add.py:5619` (`_declared_scope`) <!-- re-pinned 2026-07-13 compound-ticks: 5595→5619 (the _touches_paths helper above it — the pin drifts on ANY upstream add.py change; symbol cited so the drift self-describes; todo #30 seams-symbol-pins retires this class) -->
Contract: `_declared_scope` reads ONLY the first physical line after the §5 header — a
wrapped multi-line list silently truncates. Each backticked token then resolves
independently: `./...` = this task's dir, any token containing `/` = project-root-relative,
Expand Down
80 changes: 80 additions & 0 deletions .add/milestones/call-floor/MILESTONE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# MILESTONE: Call floor: drain the measured residual waste

goal: Close the gap the WM1 re-measure named: mean engine calls 18.7 -> ~12 and always-loaded read burden -> <=30KB, floors untouched — every lever engine-mechanical or additive, none prose-only
rationale: sub-milestone — human 'fix all' on the assessed levers 2026-07-13; every lever is evidence-traced to a measured residual in the WM1 re-measure; extends ceremony-to-effort's open meter criteria
stage: mvp · status: active · created: 2026-07-13T15:52:21+00:00
release: pending
extends: ceremony-to-effort

> SDD living doc for this milestone. Keep it THIN: breadth, shared decisions, and
> exit criteria only — per-task detail lives in each `.add/tasks/<slug>/TASK.md`,
> written just-in-time. Update this doc whenever a task reveals a milestone gap.

## Scope
In: message/engine mechanics for the 5 measured residuals — init resume pointer · new-milestone lane nudge · scope coverage hint at freeze · opt-in compound ticks (freeze --cross · gate-from-build) + recipe update · SKILL.md orient split (always-loaded read <=~8K)
Out: gate-semantics changes (freeze refusal etc. — separate re-intake) · default tick sequences (3488 fixtures pin them; compression is OPT-IN + recipe-advertised) · stdout terseness · agent-side prompting (wrapper text is the benchmark's, not the method's)

> UI/UX in scope? Name it precisely, not "make it nice" — information architecture ·
> interaction pattern · visual hierarchy · design tokens · component states ·
> accessibility floor (WCAG AA) · responsive breakpoints · user journey
> (`.add/personas-teacher/design/`). Precise ≠ distinctive: skip generic AI-design
> defaults (cream+serif+terracotta · near-black+neon · broadsheet-hairline) and name ONE
> deliberate signature element instead (Claude Code's `frontend-design` skill). A UI
> feature also triggers DESIGN.md via the `add` skill's design.md.

## Ground
Evidence = the ceremony-to-effort WM1 re-measure (benchmark/results/2026-07-ceremony-remeasure.md,
runs ceremony-r1..r3): mean 18.7 engine calls (bar <=12) · 134t/$3.51 (bar 77.7t/$2.97) · fid 0.98 ·
0 regressions. Residual anatomy, per rep: double-init +2 (arm setup already init'd; agent re-inits,
eats `already initialised`) · milestone bait r1 +9-10 (3x new-milestone despite the oneshot wrapper) ·
re-cross repairs x2 (declared scope too NARROW — tokens resolved [ok] but the build touched Touches
paths outside them; NOT the dead-token class scope-echo already renders) · status re-reads x3 ·
--help ~1. Read burden: fast lane 37KB, SKILL.md 12.8K = the dominant always-loaded read.
Oneshot lane floor today = 8-9 calls, of which freeze->tests and build->verify->gate are pure ticks
with no work between: compressible by OPT-IN flags (default sequences byte-identical — 3488 fixtures
pin them; the kickoff recipe advertises the compressed forms).

## Shared decisions & glossary deltas (living — every task must honor these)
- <cross-cutting rule, named from GLOSSARY.md>

## Shared / risky contracts (freeze these first)
- <contract name> -> owning task <slug>

## Tasks (breadth-first decomposition; detail lives in each TASK.md)
- [x] init-resume-pointer depends-on: none — the `already initialised` refusal gains a resume pointer (status), so the observed double-init dead-ends in one call; dup-failure hint covers the retry
- [x] milestone-lane-nudge depends-on: none — new-milestone success output gains one advisory line naming the oneshot lane for single-task work (the bait point, where r1 lost 9-10 calls)
- [x] scope-coverage-hint depends-on: none — freeze's scope echo ALSO lists §3 Touches paths OUTSIDE the declared scope (`note: ... outside the declared scope`) — the too-narrow class behind the re-cross repairs; propose-not-impose
- [x] compound-ticks depends-on: none — OPT-IN `freeze --cross` (stamp then land in tests) + `gate <outcome>` accepted at build (auto-cross build->verify, then record); defaults byte-identical; the new-task recipe advertises the compressed forms (oneshot lane 8-9 -> 6-7 calls)
- [x] skill-orient-split depends-on: none — SKILL.md keeps ONLY the orient path (~8K); intake summary + beyond-the-bundle + depth-by-stage move to an on-demand guide; pools re-anchored (human-signed restructure); fast-lane read path <=30KB

## Exit criteria (observable; map each to the task that delivers it)
- [x] `init` on an initialised project points at `status` in the same refusal — test-pinned (<- init-resume-pointer; test_init_resume_pointer.py 2 tests, commit a2df502)
- [x] `new-milestone` output names the oneshot lane — test-pinned (<- milestone-lane-nudge; `lane:` prefix v2 after the persona-nudge marker fence, test_milestone_lane_nudge.py, a2df502)
- [x] a freeze whose §3 Touches cite paths outside the declared scope prints the coverage note; TASK.md untouched — test-pinned (<- scope-coverage-hint; test_scope_coverage_hint.py 4 tests, a2df502)
- [x] `freeze --cross` lands in tests · `gate PASS` from build records after auto-cross · bare defaults byte-identical · the recipe prints the compressed forms — test-pinned (<- compound-ticks; test_compound_ticks.py 7 tests, d8e1718; SELF-PROVED: 4/5's own gate + 5/5's freeze and gate both ran the compound ticks)
- [x] SKILL.md <= ~8.5K with the orient path intact; moved content reachable on demand; all parity/pool fences green; fast-lane read path <= 30KB — test-pinned PARTIAL-ACCEPTED (<- skill-orient-split, 2d10b2a: SKILL.md landed 9498B vs the ~8.5K sketch — every structural pin bound the floor higher; ceiling test-pinned at 9500. Fast-lane read path ~33KB vs 30 — remaining levers live in the next milestone's phase-guide restructure)
- [x] floors untouched: full suite green 3508/3508 (fence-skill-orient-split-r2 exit 0), ENGINE_MD5 26f78f04 @ compound-ticks, twin parity green (<- all)
- [ ] (paid, human-gated) next WM1 re-measure: mean calls <= 12 on recipe-following reps (<- all)

## Close — ship review (AI fills when every task is done — the evidence behind the engine gate, read before the boxes are checked)
> Whole-milestone, cross-task review the AI fills in. It is the evidence behind the EXISTING engine
> gate (milestone-done / checking the Exit-criteria boxes) — NOT a new approval. Tool-agnostic.

### Ship by domain (what changed, per bounded context)
- tooling : <add.py / state.json / templates — what shipped, or "untouched">
- skill : <SKILL.md / phases/* / guides — what shipped, or "untouched">
- book : <docs/* — what shipped, or "untouched">

### Cross-task evidence (one row per task)
- <slug> : gate=<PASS|RISK-ACCEPTED> · tests=<n green> · residue=<none|note>

### Goal met? (map the evidence back to this milestone's Exit criteria — read before the Exit-criteria boxes are checked)
- [ ] each Exit criterion above is satisfied by a Cross-task evidence row or a Ship-by-domain change (cite which)
- goal: <restate the milestone goal — and the one evidence line that proves the ship meets it>

## Release steps (AI-DEFINED — fill the ordered steps to ship this milestone; engine records, human gate)
> The AI writes the release steps for THIS milestone here (hints, not engine commands). MERGE is one
> small step among them. These feed the release scope (release.md) when the cut is bundled.
- [ ] <step — e.g. open a PR from the Close ship-review above; the human reviews + merges>
- [ ] <step — e.g. export the ship-review to a hand-off doc, e.g. `pandoc CLOSE.md -o close.docx`>
- [ ] <step — e.g. tag / publish / deploy (human-run, per release.md)>
229 changes: 224 additions & 5 deletions .add/state.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"project": "AIDD / ADD Methodology",
"stage": "mvp",
"active_task": "fold-draft-at-close",
"active_task": "skill-orient-split",
"tasks": {
"add-check": {
"title": "add.py check: validate .add project integrity",
Expand Down Expand Up @@ -8828,10 +8828,219 @@
"email": "tindang.ht97@gmail.com",
"source": "git"
}
},
"init-resume-pointer": {
"title": "already-initialised refusal points at the resume command",
"phase": "done",
"gate": "PASS",
"milestone": "call-floor",
"depends_on": [],
"created": "2026-07-13T15:53:48+00:00",
"updated": "2026-07-13T16:09:54+00:00",
"fast": true,
"freeze": {
"version": "v1",
"frozen_at": "2026-07-13T15:53:49+00:00",
"approved_by": "Tin Dang",
"actor": {
"name": "Tin Dang",
"email": "tindang.ht97@gmail.com",
"source": "git"
}
},
"flag_verified": true,
"tripwire": {
"contract_md5": "96a0f388105a5525d3e2dd75fb02af21",
"tests": {
"add-method/tooling/test_init_resume_pointer.py": "534faa7ced7003bbde6d2484c0d01077"
}
},
"scope": {
"declared": [
"add-method/tooling/",
"add-method/src/add_method/_bundled/tooling/",
".add/",
".add/tooling/",
"add-method/.add/"
],
"snapshot_md5": "152585aa3e2da6cf37f2397c7fb780ae"
},
"gate_actor": {
"name": "Tin Dang",
"email": "tindang.ht97@gmail.com",
"source": "git"
}
},
"milestone-lane-nudge": {
"title": "new-milestone names the oneshot lane at the bait point",
"phase": "done",
"gate": "PASS",
"milestone": "call-floor",
"depends_on": [],
"created": "2026-07-13T15:55:44+00:00",
"updated": "2026-07-13T16:09:55+00:00",
"fast": true,
"freeze": {
"version": "v2",
"frozen_at": "2026-07-13T16:04:40+00:00",
"approved_by": "Tin Dang",
"actor": {
"name": "Tin Dang",
"email": "tindang.ht97@gmail.com",
"source": "git"
}
},
"flag_verified": true,
"tripwire": {
"contract_md5": "5a070bdfabb82f4574ec441a0ebb6106",
"tests": {
"add-method/tooling/test_milestone_lane_nudge.py": "0635a769da53b56a54918c6b35dbe422"
}
},
"scope": {
"declared": [
"add-method/tooling/",
"add-method/src/add_method/_bundled/tooling/",
".add/",
".add/tooling/",
"add-method/.add/"
],
"snapshot_md5": "f49bb5026beab179c46c4490b88a0051"
},
"gate_actor": {
"name": "Tin Dang",
"email": "tindang.ht97@gmail.com",
"source": "git"
}
},
"scope-coverage-hint": {
"title": "Freeze echo flags Touches paths outside the declared scope",
"phase": "done",
"gate": "PASS",
"milestone": "call-floor",
"depends_on": [],
"created": "2026-07-13T15:57:58+00:00",
"updated": "2026-07-13T16:09:57+00:00",
"fast": true,
"freeze": {
"version": "v1",
"frozen_at": "2026-07-13T15:57:58+00:00",
"approved_by": "Tin Dang",
"actor": {
"name": "Tin Dang",
"email": "tindang.ht97@gmail.com",
"source": "git"
}
},
"flag_verified": true,
"tripwire": {
"contract_md5": "300d41ce210018c97ac5c64ae7f6dd86",
"tests": {
"add-method/tooling/test_scope_coverage_hint.py": "5f6aa3350828f6852fbb2a5c38aac249"
}
},
"scope": {
"declared": [
"add-method/tooling/",
"add-method/src/add_method/_bundled/tooling/",
".add/",
".add/tooling/",
"add-method/.add/"
],
"snapshot_md5": "6a672e9c563f8c0543aedb2f15358e04"
},
"gate_actor": {
"name": "Tin Dang",
"email": "tindang.ht97@gmail.com",
"source": "git"
}
},
"compound-ticks": {
"title": "Opt-in compound ticks: freeze --cross + gate accepted from build",
"phase": "done",
"gate": "PASS",
"milestone": "call-floor",
"depends_on": [],
"created": "2026-07-13T16:12:17+00:00",
"updated": "2026-07-13T16:29:18+00:00",
"fast": true,
"freeze": {
"version": "v1",
"frozen_at": "2026-07-13T16:12:18+00:00",
"approved_by": "Tin Dang",
"actor": {
"name": "Tin Dang",
"email": "tindang.ht97@gmail.com",
"source": "git"
}
},
"flag_verified": true,
"tripwire": {
"contract_md5": "6678d764ed011d5b0e42532aca3de157",
"tests": {
"add-method/tooling/test_compound_ticks.py": "fd536b191413d6f013d51d0d96458959"
}
},
"scope": {
"declared": [
"add-method/tooling/",
"add-method/src/add_method/_bundled/tooling/",
".add/",
".add/tooling/",
"add-method/.add/"
],
"snapshot_md5": "d05c93c4544660aaaaba7c828b2f8e67"
},
"gate_actor": {
"name": "Tin Dang",
"email": "tindang.ht97@gmail.com",
"source": "git"
}
},
"skill-orient-split": {
"title": "Split SKILL.md: lean orient core + on-demand beyond.md routing guide",
"phase": "done",
"gate": "PASS",
"milestone": "call-floor",
"depends_on": [],
"created": "2026-07-13T16:34:34+00:00",
"updated": "2026-07-13T17:01:22+00:00",
"fast": true,
"freeze": {
"version": "v1",
"frozen_at": "2026-07-13T16:34:34+00:00",
"approved_by": "Tin Dang",
"actor": {
"name": "Tin Dang",
"email": "tindang.ht97@gmail.com",
"source": "git"
}
},
"flag_verified": true,
"tripwire": {
"contract_md5": "ecdc145a6c7557dd00597952dd97f3ee",
"tests": {
"add-method/tooling/test_skill_orient_split.py": "3765df86bfcbea64b138c66eec1934c7"
}
},
"scope": {
"declared": [
"add-method/skill/",
"add-method/tooling/",
"add-method/src/add_method/_bundled/skill/",
".claude/skills/add/"
],
"snapshot_md5": "1d1ca784603501b868b8edb165a2a730"
},
"gate_actor": {
"name": "Tin Dang",
"email": "tindang.ht97@gmail.com",
"source": "git"
}
}
},
"created": "2026-05-28T15:39:04+00:00",
"updated": "2026-07-13T11:44:36+00:00",
"updated": "2026-07-13T17:01:22+00:00",
"milestones": {
"v1-1": {
"title": "v1.1 \u2014 adoption & ergonomics",
Expand Down Expand Up @@ -9212,9 +9421,17 @@
"email": "tindang.ht97@gmail.com",
"source": "git"
}
},
"call-floor": {
"title": "Call floor: drain the measured residual waste",
"goal": "Close the gap the WM1 re-measure named: mean engine calls 18.7 -> ~12 and always-loaded read burden -> <=30KB, floors untouched \u2014 every lever engine-mechanical or additive, none prose-only",
"stage": "mvp",
"status": "active",
"created": "2026-07-13T15:52:21+00:00",
"updated": "2026-07-13T15:52:21+00:00"
}
},
"active_milestone": "ceremony-to-effort",
"active_milestone": "call-floor",
"archived": [
{
"slug": "v5",
Expand Down Expand Up @@ -10051,7 +10268,8 @@
"add-lean-loop",
"expectations-first",
"plan-legibility",
"ceremony-to-effort"
"ceremony-to-effort",
"call-floor"
],
"active_tasks": {
"flow-simplification": "phase-review",
Expand All @@ -10064,7 +10282,8 @@
"add-bench-2": "tiny-plan-small-scope",
"expectations-first": "book-plan-align",
"plan-legibility": "relations-surface",
"ceremony-to-effort": "fold-draft-at-close"
"ceremony-to-effort": "fold-draft-at-close",
"call-floor": "skill-orient-split"
},
"todos": [
{
Expand Down
Loading