@pilotspace/add 1.9.0 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,54 @@
1
+ # Components — monorepo and multi-repo slices
2
+
3
+ Opt-in pillar for a milestone that spans **more than one green bar** — a backend
4
+ and its frontend, a shared lib and two apps, services across repos. A project
5
+ that declares no components is byte-identical to a single-codebase project. Reach
6
+ for this only when one milestone genuinely crosses components. Full narrative:
7
+ book chapter `17-components.md`.
8
+
9
+ ## Declare (never inferred)
10
+
11
+ `.add/components.toml`:
12
+
13
+ ```toml
14
+ [component.gateway]
15
+ root = "apps/gateway"
16
+ green-bar = "pytest + pyright"
17
+ [component.dashboard]
18
+ root = "apps/web"
19
+ green-bar = "vitest + a11y"
20
+ ```
21
+
22
+ A task binds with a `component: <name>` header line → that root joins its §5
23
+ Scope, and verify holds it to that component's green-bar.
24
+
25
+ ## The loop
26
+
27
+ 1. **Per-component verify.** A bound task must CITE its component's green-bar in
28
+ the §6 Build-expectations evidence, or the gate refuses
29
+ `component_green_bar_uncited`. The engine never runs the suite — you run the
30
+ right one; the gate checks the right bar was cited.
31
+ 2. **Freeze a cross-component contract.** Declare `[contract.<id>]`
32
+ (producer + consumers). A task names its role `produces: <id>` / `consumes: <id>`.
33
+ The producer's freeze (contract→tests) writes the immutable snapshot
34
+ `.add/contracts/<id>.json`; the consumer pins its hash. A changed re-freeze
35
+ flags consumers `contract_consumer_stale`; a missing/malformed snapshot
36
+ HARD-STOPS — never build against an unfrozen shape.
37
+ 3. **One milestone, full slice.** A `consumes:` task is HELD from advancing
38
+ scenarios→contract (`producer_contract_unfrozen`) until the producer's
39
+ snapshot exists. The FE stays downstream of the frozen BE endpoint, in one
40
+ milestone.
41
+ 4. **Across repos — federate.** A consumer repo declares `[federation.<id>]`
42
+ (`source` + optional `pin`); `add.py federate pull <id>` validates and lands a
43
+ byte-for-byte copy of the producer repo's published snapshot locally, where it
44
+ behaves as in a monorepo. Fail-loud: unknown id / unreadable source / invalid
45
+ snapshot / version mismatch each HARD-STOPS and lands nothing.
46
+
47
+ ## Hold the line
48
+
49
+ - **Declared, not inferred** — no scanning `apps/*`.
50
+ - **No central server / no shared mutable state** — federation copies an
51
+ immutable snapshot; each repo keeps its own git-native `state.json`.
52
+ - **No new approval** — these are engine-enforced gates on the existing six-step
53
+ flow, not extra human checkpoints. Ownership/autonomy per component is the
54
+ identity story (`streams.md`, governance), layered on this graph.
@@ -47,11 +47,17 @@ Never: invent a file, symbol, or signature you have not opened.
47
47
  ## Exit gate
48
48
 
49
49
  <exit_gate>
50
- - [ ] The real files/symbols the task touches are named (from the code, not assumed).
51
- - [ ] The conventions to honor are cited (task-delta only; no architecture re-scan).
52
- - [ ] The anchors §3 will cite are listed §3 names only anchors that exist here.
50
+ - [ ] **Touches** — the real files/symbols the task touches are named (from the code, not assumed).
51
+ - [ ] **Context** (working folder) the non-code artifacts the task touches (docs · todos · config · data) are named, task-delta only.
52
+ - [ ] **Honors** the patterns/conventions to honor are cited (task-delta only; no architecture re-scan).
53
+ - [ ] **Anchors** — the anchors §3 will cite are listed — §3 names only anchors that exist here.
53
54
  </exit_gate>
54
55
 
56
+ **Grounding is complete when** all four fields are filled from real assets: a STRONG grounding cites
57
+ actual files/symbols/docs/conventions you opened; a WEAK one leaves a `<…>` placeholder or names what you
58
+ assume. All four are non-optional — skipping **Context** (the working folder beyond code) is the usual
59
+ silent gap. §3 may cite only anchors that appear here.
60
+
55
61
  > **Advisor · Confidence** — a broad sweep is the canonical spawn case (advisor.md); self-score your grounding before you specify against it (confidence.md).
56
62
 
57
63
  ## Next
@@ -57,7 +57,7 @@ Capture each surfaced decision as an **ADR** into `PROJECT.md` **Key Decisions**
57
57
  ```bash
58
58
  python3 .add/tooling/add.py new-task <slug> --title "<first feature>"
59
59
  ```
60
- Draft §1 · §2 · §3. **Leave §3 `Status: DRAFT`** — the lock is its approval. You MAY `advance` pre-lock, but the engine **refuses crossing into build** until you `lock` (`setup_unlocked`). Sequence: bundle → lock → build.
60
+ Draft the full bundle **§1–§4** incl. the **§4 red suite** (`phases/4-tests.md`); the lock approves it whole. **Leave §3 `Status: DRAFT`** — the lock is its approval. You MAY `advance` pre-lock, but the engine **refuses crossing into build** until you `lock` (`setup_unlocked`). Sequence: **bundle (§1–§4, tests RED) → lock → build** — the red suite must FAIL **before build** (never start Build until §1–§4 exist and tests are red).
61
61
  4. **Write `.add/SETUP-REVIEW.md`** per `setup-review.md`: every drafted decision, **lowest-confidence-first**, tagged `guessed` | `evidence-grounded`.
62
62
 
63
63
  ## Run mode — how the build will be driven (propose parallel + auto; confirm to keep)
@@ -93,7 +93,7 @@ Typing it themselves stays the **escape hatch** — the decision is always the h
93
93
  <exit_gate>
94
94
  - [ ] `.add/state.json` exists; setup was seeded unlocked (`--await-lock`) then locked.
95
95
  - [ ] Living docs filled (brownfield: from code, tagged evidence-grounded; greenfield: from the interview).
96
- - [ ] First task created; §1–§3 drafted; `.add/SETUP-REVIEW.md` written lowest-confidence-first.
96
+ - [ ] First task created; **§1–§4 drafted — the red suite (per `phases/4-tests.md`) runs RED before build opens**; `.add/SETUP-REVIEW.md` written lowest-confidence-first.
97
97
  - [ ] Human confirmed the baseline approval and `add.py lock --by` ran with their name; first task §3 `FROZEN @ v1`; build open.
98
98
  </exit_gate>
99
99
 
@@ -19,7 +19,7 @@
19
19
 
20
20
  Before drafting the goal sentence, position the request in what already exists — distinct from intake's classification, not redundant with it.
21
21
 
22
- 1. **Ground in current assets.** Read the goal against `PROJECT.md` (domain · spec · UI/UX), the code it touches, and existing docs the goal must reflect what the project already is.
22
+ 1. **Ground in current assets.** Read the goal against what exists — the goal must reflect what the project already is. Ground as rigorously as a task's §0 (`phases/0-ground.md`), using the **same four fields** at milestone scope: **Touches** (the subsystems/files the milestone spans) · **Context** (the docs · todos · config · data it works against) · **Honors** (the `PROJECT.md` / `CONVENTIONS.md` invariants it must respect) · **Anchors** (the existing contracts/symbols its tasks will cite). Grounding is complete when each is named from real assets, not assumed.
23
23
  2. **Relate to the milestone map.** Read every existing goal — `.add/milestones/*/MILESTONE.md` and `.add/archive/*` — and name THIS request's relationship: *extends* X · *depends-on* Y · *overlaps* Z. Record in the `rationale` line.
24
24
  3. **If the goal is already delivered** by an existing milestone, reject `duplicate_goal` and route as `task` or `change-request`.
25
25