groundwork-method 0.10.0 → 0.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.
- package/CHANGELOG.md +42 -0
- package/bin/groundwork.js +86 -17
- package/dist/src/generators/system-test-runner/generator.js +52 -4
- package/dist/src/generators/system-test-runner/generator.js.map +1 -1
- package/package.json +1 -1
- package/src/docs/principles/design/usability-and-ux.md +11 -0
- package/src/docs/principles/foundations/testing.md +32 -6
- package/src/docs/principles/index.md +2 -1
- package/src/docs/principles/quality/observability.md +2 -2
- package/src/engineer-skills/groundwork-electron-engineer/SKILL.md +6 -1
- package/src/engineer-skills/groundwork-electron-engineer/references/documentation.md +126 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/observability.md +37 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/performance-and-reliability.md +80 -0
- package/src/engineer-skills/groundwork-electron-engineer/references/testing-and-smoke.md +22 -0
- package/src/engineer-skills/groundwork-electron-engineer/sync-anchor.md +12 -4
- package/src/engineer-skills/groundwork-flutter-engineer/SKILL.md +7 -1
- package/src/engineer-skills/groundwork-flutter-engineer/references/documentation.md +122 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/observability.md +37 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/performance-and-reliability.md +100 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/security.md +96 -0
- package/src/engineer-skills/groundwork-flutter-engineer/references/testing.md +25 -0
- package/src/engineer-skills/groundwork-flutter-engineer/sync-anchor.md +13 -4
- package/src/engineer-skills/groundwork-go-engineer/SKILL.md +5 -2
- package/src/engineer-skills/groundwork-go-engineer/references/documentation.md +130 -0
- package/src/engineer-skills/groundwork-go-engineer/references/testing.md +63 -1
- package/src/engineer-skills/groundwork-go-engineer/sync-anchor.md +13 -4
- package/src/engineer-skills/groundwork-nextjs-engineer/SKILL.md +6 -1
- package/src/engineer-skills/groundwork-nextjs-engineer/references/accessibility.md +111 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/observability.md +48 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/security.md +131 -0
- package/src/engineer-skills/groundwork-nextjs-engineer/references/testing.md +59 -1
- package/src/engineer-skills/groundwork-nextjs-engineer/references/ux-principles.md +1 -49
- package/src/engineer-skills/groundwork-nextjs-engineer/sync-anchor.md +10 -3
- package/src/engineer-skills/groundwork-python-engineer/SKILL.md +5 -2
- package/src/engineer-skills/groundwork-python-engineer/references/security.md +148 -0
- package/src/engineer-skills/groundwork-python-engineer/references/testing.md +40 -1
- package/src/engineer-skills/groundwork-python-engineer/sync-anchor.md +11 -4
- package/src/generators/electron-app/docs/principles/stack/electron/index.md +2 -0
- package/src/generators/electron-app/files/tests/smoke/app.spec.ts.template +73 -8
- package/src/generators/flutter-app/docs/principles/stack/flutter/testing.md +14 -2
- package/src/generators/flutter-app/files/integration_test/app_test.dart.template +46 -12
- package/src/generators/go-microservice/docs/principles/stack/go/testing.md +17 -1
- package/src/generators/python-microservice/docs/principles/stack/python/testing.md +41 -0
- package/src/generators/system-test-runner/NATIVE-CHECK-CONTRACT.md +20 -0
- package/src/generators/system-test-runner/files/tests/system/test_render_smoke.py.template +30 -0
- package/src/generators/system-test-runner/generator.ts +58 -4
- package/src/generators/workspace-dev-cli/cli-src/dist/dev-bundle.js +1 -1
- package/src/hidden-skills/code-intelligence.md +6 -0
- package/src/hidden-skills/groundwork-architect/SKILL.md +1 -1
- package/src/hidden-skills/groundwork-architect/sync-anchor.md +2 -2
- package/src/hidden-skills/groundwork-bet/briefs/acceptance-auditor.md +68 -0
- package/src/hidden-skills/groundwork-bet/briefs/blind-reviewer.md +56 -0
- package/src/hidden-skills/groundwork-bet/briefs/coverage-auditor.md +95 -0
- package/src/hidden-skills/groundwork-bet/briefs/edge-case-tracer.md +64 -0
- package/src/hidden-skills/groundwork-bet/briefs/experience-auditor.md +83 -0
- package/src/hidden-skills/groundwork-bet/briefs/slice-worker.md +92 -26
- package/src/hidden-skills/groundwork-bet/instructions.md +4 -4
- package/src/hidden-skills/groundwork-bet/templates/bet-progress-test.md +16 -27
- package/src/hidden-skills/groundwork-bet/templates/change-proposal.md +1 -1
- package/src/hidden-skills/groundwork-bet/templates/decomposition/milestone-index.md +12 -16
- package/src/hidden-skills/groundwork-bet/templates/decomposition/slice.md +4 -8
- package/src/hidden-skills/groundwork-bet/templates/technical-design/03-api-design.md +1 -1
- package/src/hidden-skills/groundwork-bet/workflows/01-discovery.md +3 -1
- package/src/hidden-skills/groundwork-bet/workflows/02-design.md +11 -1
- package/src/hidden-skills/groundwork-bet/workflows/03-decomposition.md +60 -64
- package/src/hidden-skills/groundwork-bet/workflows/04-delivery.md +75 -42
- package/src/hidden-skills/groundwork-bet/workflows/05-validation.md +18 -7
- package/src/hidden-skills/groundwork-designer/sync-anchor.md +1 -1
- package/src/hidden-skills/groundwork-persona/instructions.md +11 -0
- package/src/hidden-skills/groundwork-review/checklists/implementation-readiness.md +1 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: blind-reviewer
|
|
3
|
+
description: >
|
|
4
|
+
Reviews a slice diff for correctness bugs with no bet context, so familiarity cannot
|
|
5
|
+
hide them. One of four independent review lenses the Delivery driver dispatches per
|
|
6
|
+
slice (groundwork-bet/workflows/04-delivery.md, Step 2); only the report flows back.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Blind Reviewer
|
|
10
|
+
|
|
11
|
+
## How This Brief Is Invoked
|
|
12
|
+
|
|
13
|
+
This brief runs in an **isolated subagent context** (Protocol 9 mechanics), dispatched
|
|
14
|
+
by the Delivery driver during the slice review, in parallel with the edge-case tracer,
|
|
15
|
+
the acceptance auditor, and the coverage auditor. It is **not** the slice-worker that
|
|
16
|
+
wrote the diff — a diff cannot judge itself, and an author re-reading their own work
|
|
17
|
+
sees what they meant, not what they wrote. Only the report flows back to the driver.
|
|
18
|
+
|
|
19
|
+
The lens is deliberately starved of context. It receives the diff and nothing else: no
|
|
20
|
+
bet, no design, no Proof of work. Familiarity is what hides bugs — a reviewer who knows
|
|
21
|
+
the intent fills the gaps in their head and reads past the off-by-one. This lens has no
|
|
22
|
+
intent to fill the gaps with, so it reads only what the code actually says.
|
|
23
|
+
|
|
24
|
+
## Inputs
|
|
25
|
+
|
|
26
|
+
The driver passes:
|
|
27
|
+
|
|
28
|
+
- The slice's **uncommitted diff** — the full patch, and nothing more. Do not request
|
|
29
|
+
the bet, the design, or the slice file; the blindness is the instrument.
|
|
30
|
+
|
|
31
|
+
## The work
|
|
32
|
+
|
|
33
|
+
Read the diff as a stranger would and judge the code on its own terms — does it do what
|
|
34
|
+
it plainly appears to intend, correctly. Report defects that live in the code itself,
|
|
35
|
+
visible without bet context:
|
|
36
|
+
|
|
37
|
+
- Logic that contradicts itself — an inverted condition, a wrong operator, a branch that
|
|
38
|
+
can never be taken, a return that drops the value it just computed.
|
|
39
|
+
- Mishandled results — an error swallowed, a `nil`/`null`/`None` dereferenced, a
|
|
40
|
+
resource opened and never closed, a lock not released on the failure path.
|
|
41
|
+
- State and concurrency — a shared value mutated without synchronisation, an ordering
|
|
42
|
+
assumption that does not hold, an iteration that mutates what it iterates.
|
|
43
|
+
- Off-by-ones and boundaries visible in the arithmetic itself.
|
|
44
|
+
|
|
45
|
+
You cannot judge whether the code matches the design — you cannot see the design. That
|
|
46
|
+
is the acceptance auditor's lens; do not guess at intent to manufacture a finding. Report
|
|
47
|
+
what is wrong in the code as written, not what might be wrong against a spec you were
|
|
48
|
+
not given.
|
|
49
|
+
|
|
50
|
+
## The report
|
|
51
|
+
|
|
52
|
+
For each finding: a one-line title, the location (file and the diff hunk or line), what
|
|
53
|
+
is wrong, and why it bites. Suggest a nature (decision-needed / patch / defer / dismiss);
|
|
54
|
+
the driver makes the final call and dedupes across the four lenses. If the diff is clean
|
|
55
|
+
on this lens, say so in one line — do not invent findings to look thorough. Keep it to
|
|
56
|
+
the findings; no narration of what you read.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: coverage-auditor
|
|
3
|
+
description: >
|
|
4
|
+
Judges whether the permanent best-practice tests a slice rolled out are comprehensive
|
|
5
|
+
and actually assert, against the stack's testing strategy. One of four independent
|
|
6
|
+
review lenses the Delivery driver dispatches per slice
|
|
7
|
+
(groundwork-bet/workflows/04-delivery.md, Step 2); only the report flows back.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Coverage Auditor
|
|
11
|
+
|
|
12
|
+
## How This Brief Is Invoked
|
|
13
|
+
|
|
14
|
+
This brief runs in an **isolated subagent context** (Protocol 9 mechanics), dispatched by
|
|
15
|
+
the Delivery driver during the slice review, in parallel with the blind reviewer, the
|
|
16
|
+
edge-case tracer, and the acceptance auditor. It is **not** the slice-worker that wrote
|
|
17
|
+
the diff. Only the report flows back to the driver.
|
|
18
|
+
|
|
19
|
+
This lens exists to close a seam the other three leave open. The honest-green check and
|
|
20
|
+
the acceptance auditor confirm the implementation is not *gamed*; the edge-case tracer
|
|
21
|
+
finds unhandled paths in the *code*. None of them asks whether the slice's **permanent
|
|
22
|
+
test suite** is comprehensive and whether its assertions actually bite. That is this
|
|
23
|
+
lens's only job — and it is reviewable here precisely because the slice-worker now rolls
|
|
24
|
+
the permanent tests out *into the diff*, before review, rather than after it.
|
|
25
|
+
|
|
26
|
+
The distinction from the edge-case tracer is sharp: the tracer asks "does the code handle
|
|
27
|
+
this path?"; this lens asks "does a test *check* that it does?" A path handled in code but
|
|
28
|
+
unasserted by any test is invisible to the tracer and is exactly what this lens catches.
|
|
29
|
+
|
|
30
|
+
## Inputs
|
|
31
|
+
|
|
32
|
+
The driver passes:
|
|
33
|
+
|
|
34
|
+
- The slice's **uncommitted diff** — both the implementation and the permanent
|
|
35
|
+
best-practice tests the worker rolled out.
|
|
36
|
+
- The slice's **Required Capabilities** (its Scope, from the slice file).
|
|
37
|
+
- The **stack's testing strategy** — the promoted engineer skill at
|
|
38
|
+
`.agents/skills/groundwork-<stack>-engineer/references/testing.md`, especially its
|
|
39
|
+
**Bet Slice Rollout** section. This is the authority the suite is held against; read it
|
|
40
|
+
first, because "comprehensive" means "what this strategy asks for," not a fixed list.
|
|
41
|
+
|
|
42
|
+
## The work
|
|
43
|
+
|
|
44
|
+
Map each Required Capability the slice delivered to the permanent tests that should guard
|
|
45
|
+
it, then judge the suite the worker rolled out against the strategy on two axes:
|
|
46
|
+
|
|
47
|
+
**Completeness — is the coverage the strategy asks for actually present?**
|
|
48
|
+
|
|
49
|
+
- The service-perimeter or interface test exists for each capability the slice delivered.
|
|
50
|
+
- Error and boundary cases are covered to the **rigour of the happy path** — the strategy
|
|
51
|
+
treats a skipped error case as a gap, not an optional extra. A capability with three
|
|
52
|
+
documented failure modes and a test for only the success path is under-covered.
|
|
53
|
+
- Genuinely complex logic the slice introduced carries a unit test; plumbing does not need
|
|
54
|
+
one (the perimeter test covers it) — apply the strategy's own "what earns a unit test"
|
|
55
|
+
rule, do not demand tests the strategy says are waste.
|
|
56
|
+
- An invariant the slice introduced is pinned by a property-based test where the strategy
|
|
57
|
+
calls for one.
|
|
58
|
+
- A slice that added an **observable path** (a backend service emitting OpenTelemetry
|
|
59
|
+
spans) carries a critical-path trace assertion. A slice on a stack that emits no traces
|
|
60
|
+
(a Flutter or Electron client) owes none — the strategy says so; do not invent one.
|
|
61
|
+
- A `graphical-ui` slice has component render tests across the **named states** the design
|
|
62
|
+
system defines (default, loading, empty, error, long-content) and registers any new
|
|
63
|
+
route for the system gates.
|
|
64
|
+
- **A fake the suite leans on has a real-producer test behind it.** When a test uses a
|
|
65
|
+
fixture or stub for work a real stage performs, the suite must also test the real stage
|
|
66
|
+
that produces it. A fixture with no real-producer test is uncovered work masquerading as
|
|
67
|
+
covered — the gap that ships a feature whose real pipeline was never exercised
|
|
68
|
+
(`docs/principles/foundations/testing.md`).
|
|
69
|
+
|
|
70
|
+
**Assertion quality — do the tests bite, or only execute?**
|
|
71
|
+
|
|
72
|
+
- A sociable service test that drives a branch through one call but asserts only on the
|
|
73
|
+
status code, not the resulting state, is a gap even on a green board — it covers the
|
|
74
|
+
line without checking it.
|
|
75
|
+
- A test whose assertions only mirror the current output, with no oracle independent of
|
|
76
|
+
the implementation, cements behaviour rather than verifying it — the failure mode of an
|
|
77
|
+
implementation-derived (often AI-generated) test.
|
|
78
|
+
- Where a changed function is dense and high-risk, name it as a candidate for a **targeted
|
|
79
|
+
mutation spot-check** (the strategy's signal-only read-out) — a surviving mutant there is
|
|
80
|
+
concrete evidence of a weak assertion. Recommend the spot-check on the named function;
|
|
81
|
+
do not ask for a full mutation run, which the strategy reserves and review cannot afford.
|
|
82
|
+
|
|
83
|
+
You judge the tests, not the implementation's correctness (the blind reviewer's lens), its
|
|
84
|
+
design conformance (the acceptance auditor's), or unhandled code paths (the tracer's). A
|
|
85
|
+
missing test is your finding; a code bug is not.
|
|
86
|
+
|
|
87
|
+
## The report
|
|
88
|
+
|
|
89
|
+
For each gap: a one-line title, what is under-covered or under-asserting (the capability,
|
|
90
|
+
path, state, or assertion), the specific strategy rule it falls short of (quote the Bet
|
|
91
|
+
Slice Rollout line), and the concrete test that would close it. Suggest a nature
|
|
92
|
+
(usually `patch` — write the missing test before the slice closes — or `decision-needed`
|
|
93
|
+
when the gap reveals a real ambiguity); the driver makes the final call and dedupes across
|
|
94
|
+
the four lenses. If the suite meets the strategy and the assertions bite, say so in one
|
|
95
|
+
line — do not pad with tests the strategy does not ask for. Keep it to the findings.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: edge-case-tracer
|
|
3
|
+
description: >
|
|
4
|
+
Walks every branch and boundary a slice diff introduces and reports only the
|
|
5
|
+
unhandled paths. One of four independent review lenses the Delivery driver dispatches
|
|
6
|
+
per slice (groundwork-bet/workflows/04-delivery.md, Step 2); only the report flows back.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Edge-Case Tracer
|
|
10
|
+
|
|
11
|
+
## How This Brief Is Invoked
|
|
12
|
+
|
|
13
|
+
This brief runs in an **isolated subagent context** (Protocol 9 mechanics), dispatched
|
|
14
|
+
by the Delivery driver during the slice review, in parallel with the blind reviewer, the
|
|
15
|
+
acceptance auditor, and the coverage auditor. It is **not** the slice-worker that wrote
|
|
16
|
+
the diff. Only the report flows back to the driver.
|
|
17
|
+
|
|
18
|
+
Where the blind reviewer reads the code as written, this lens reads the code as *run* —
|
|
19
|
+
it traces what happens on the inputs and timings the happy path never exercises. Its job
|
|
20
|
+
is exhaustive path-walking, not general critique.
|
|
21
|
+
|
|
22
|
+
## Inputs
|
|
23
|
+
|
|
24
|
+
The driver passes:
|
|
25
|
+
|
|
26
|
+
- The slice's **uncommitted diff**.
|
|
27
|
+
- **Repo read access** — so a path that leaves the diff into existing code can be
|
|
28
|
+
followed to confirm whether it is genuinely handled there, rather than assumed. When
|
|
29
|
+
the Serena MCP server is registered, follow those paths with it (`find_referencing_symbols`
|
|
30
|
+
to enumerate callers, `find_symbol` to read the body you land in) rather than by guesswork;
|
|
31
|
+
`.groundwork/cache/repo-map.json` edges serve the same purpose offline, and ordinary
|
|
32
|
+
search is the fallback when neither exists.
|
|
33
|
+
|
|
34
|
+
## The work
|
|
35
|
+
|
|
36
|
+
Walk every branch and boundary the diff introduces. For each, ask what the code does on
|
|
37
|
+
the input it does not expect, and follow the call into existing code when the answer is
|
|
38
|
+
not in the diff. Report **only unhandled paths** — concrete, reachable cases the diff
|
|
39
|
+
does not account for:
|
|
40
|
+
|
|
41
|
+
- Empty and null inputs — an empty list, a missing field, a zero, a `nil`/`None` where a
|
|
42
|
+
value is assumed.
|
|
43
|
+
- Failure timing — a dependency that errors, times out, or returns partial data midway;
|
|
44
|
+
a retry that double-applies; a cleanup that does not run when the body throws.
|
|
45
|
+
- Concurrency — two requests racing the same row, an await that interleaves with a
|
|
46
|
+
mutation, an assumption that an operation is atomic when it is not.
|
|
47
|
+
- Boundaries — off-by-ones, an unbounded input, pagination that loses or duplicates the
|
|
48
|
+
edge element, an overflow.
|
|
49
|
+
- Callers the diff did not update — when the diff changes a symbol's signature or shape,
|
|
50
|
+
enumerate its references (Serena `find_referencing_symbols`, or the repo-map edges
|
|
51
|
+
offline) and confirm each was updated in the same diff. A caller left on the old shape
|
|
52
|
+
is an unhandled path the compiler may not catch in a dynamically-typed stack.
|
|
53
|
+
|
|
54
|
+
Report a path only when it is genuinely unhandled and reachable — trace it into existing
|
|
55
|
+
code first. Do not report a case the code already covers, and do not report stylistic
|
|
56
|
+
preferences; this lens finds holes, not opinions.
|
|
57
|
+
|
|
58
|
+
## The report
|
|
59
|
+
|
|
60
|
+
For each unhandled path: a one-line title, the location (file and line, plus the existing
|
|
61
|
+
code you traced into), the exact input or timing that triggers it, and the consequence.
|
|
62
|
+
Suggest a nature (decision-needed / patch / defer / dismiss); the driver makes the final
|
|
63
|
+
call and dedupes across the four lenses. If you traced the diff and found no unhandled
|
|
64
|
+
path, say so in one line. Keep it to the findings.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: experience-auditor
|
|
3
|
+
description: >
|
|
4
|
+
Judges whether an assembled, running milestone (and, at validation, the whole bet) is
|
|
5
|
+
on-design and a genuine pleasure to use — best-in-class patterns implemented in full, no
|
|
6
|
+
dead-end flows, every state present, design-system match. A milestone-level review lens
|
|
7
|
+
the Delivery driver dispatches at milestone close and the Validation phase dispatches over
|
|
8
|
+
the finished bet (groundwork-bet/workflows/04-delivery.md Milestone close;
|
|
9
|
+
05-validation.md Step 2.6); only the report flows back.
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Experience Auditor
|
|
13
|
+
|
|
14
|
+
## How This Brief Is Invoked
|
|
15
|
+
|
|
16
|
+
This brief runs in an **isolated subagent context** (Protocol 9 mechanics), adopting the
|
|
17
|
+
designer persona (`.groundwork/skills/groundwork-designer/SKILL.md`, reference
|
|
18
|
+
`design-review.md`). It runs at **milestone granularity, not per slice** — design fidelity
|
|
19
|
+
and flow completeness need the whole assembled surface, which a single slice cannot show.
|
|
20
|
+
The Delivery driver dispatches it once a milestone has closed and there is a running
|
|
21
|
+
milestone to look at; the Validation phase dispatches it again over the finished bet to
|
|
22
|
+
catch gaps that only appear across milestone seams. Only the report flows back.
|
|
23
|
+
|
|
24
|
+
It is distinct from the **coverage auditor**, which checks per slice that the state and
|
|
25
|
+
render *tests exist* (a mechanical question). This lens judges whether the assembled,
|
|
26
|
+
running product is **on-design and good to use** (a designer's judgement). One asks "is
|
|
27
|
+
there a test for the empty state"; this one asks "does the empty state read as designed,
|
|
28
|
+
and is the whole thing a pleasure to use." Neither substitutes for the other.
|
|
29
|
+
|
|
30
|
+
## Inputs
|
|
31
|
+
|
|
32
|
+
The driver (or validator) passes:
|
|
33
|
+
|
|
34
|
+
- The **running milestone or bet** to drive — the shipping build, reached the way its
|
|
35
|
+
consumer reaches it, plus the captured per-state screenshots under
|
|
36
|
+
`.groundwork/cache/visual/<bet-slug>/<surface>/`.
|
|
37
|
+
- The **UI design** — `docs/bets/<bet-slug>/technical-design/01-ui-design.md`: the
|
|
38
|
+
wireframes, the named states, the micro-polish spec, and the best-in-class patterns the
|
|
39
|
+
designer chose for each view.
|
|
40
|
+
- The project **design system** (`docs/design-system.md`) and the **design-phase reference
|
|
41
|
+
apps**, as the comparison baseline for patterns and craft.
|
|
42
|
+
- The **scope** — which milestone (and its agreed front-door cases), or, at validation, the
|
|
43
|
+
whole bet across all its surfaces.
|
|
44
|
+
|
|
45
|
+
## The work
|
|
46
|
+
|
|
47
|
+
Drive the product the way its consumer does, and judge it on four axes against the design.
|
|
48
|
+
The baseline is the written `01-ui-design.md` spec and the reference apps, not unaided
|
|
49
|
+
taste — where the spec settles a question, judge against the spec; where it is silent,
|
|
50
|
+
judge against the reference apps and the design system, and surface genuine uncertainty as
|
|
51
|
+
a `decision-needed` for the owner rather than passing it silently.
|
|
52
|
+
|
|
53
|
+
- **Patterns implemented in full.** Each best-in-class pattern the design named is present
|
|
54
|
+
and complete — every affordance it implies works (the filter pill removes when its x is
|
|
55
|
+
clicked, the skeleton resolves to real content). A pattern shipped as a shell that
|
|
56
|
+
promises an interaction it does not honour is a finding.
|
|
57
|
+
- **Flow completeness — no dead ends.** Every screen the milestone delivers is reachable
|
|
58
|
+
and has a way back; no flow strands the consumer with no exit. At bet scope, check the
|
|
59
|
+
**seams between milestones** — a flow that works within each milestone but breaks where
|
|
60
|
+
they join is exactly what this pass exists to catch.
|
|
61
|
+
- **States present and on-design.** Every async view carries its full set of states —
|
|
62
|
+
empty, loading, in-progress, error — and each reads as designed rather than as a failure
|
|
63
|
+
(a screen that works but shows no progress reads as frozen; a grid with no empty state
|
|
64
|
+
reads as broken on first run).
|
|
65
|
+
- **Design-system match and the joy bar.** The surfaces render in the design system (tokens,
|
|
66
|
+
components, the specified atmosphere) and cohere across the milestone; and, stepping back,
|
|
67
|
+
is the product a genuine pleasure to use — considered, well-rounded, not a bare shell.
|
|
68
|
+
|
|
69
|
+
You judge the assembled experience, not slice-level test coverage (the coverage auditor's
|
|
70
|
+
lens), code correctness (the blind reviewer's), or design conformance of a single diff (the
|
|
71
|
+
acceptance auditor's). A dead-end flow, a half-built pattern, a missing state, or an
|
|
72
|
+
off-design surface is your finding.
|
|
73
|
+
|
|
74
|
+
## The report
|
|
75
|
+
|
|
76
|
+
For each finding: a one-line title, where it is (the screen, flow, or state, with the
|
|
77
|
+
screenshot path where one exists), the specific design element it falls short of (quote
|
|
78
|
+
`01-ui-design.md`, name the design-system token or the reference-app pattern), and why it
|
|
79
|
+
hurts the experience. Suggest a nature — a dead-end flow, a missing state, or a
|
|
80
|
+
design-system miss is `decision-needed` and **blocks the milestone**; a smaller refinement
|
|
81
|
+
is `patch`; a genuinely out-of-scope polish idea is `defer` with a `docs/maturity.md` row.
|
|
82
|
+
The driver makes the final call and dedupes across lenses. If the milestone (or bet) is
|
|
83
|
+
on-design, complete, and a pleasure to use, say so in one line. Keep it to the findings.
|
|
@@ -38,7 +38,7 @@ same regardless of how the isolated execution is realised.
|
|
|
38
38
|
### Model
|
|
39
39
|
|
|
40
40
|
The worker may run on a cheaper tier than the driver. Its correctness is not taken on
|
|
41
|
-
trust: the driver gates every slice through an independent review (
|
|
41
|
+
trust: the driver gates every slice through an independent review (four isolated
|
|
42
42
|
lenses) before the slice closes. The worker's job is to implement honestly and report
|
|
43
43
|
honestly, not to be the final judge of its own work.
|
|
44
44
|
|
|
@@ -53,6 +53,11 @@ The driver passes:
|
|
|
53
53
|
`docs/bets/<bet_slug>/decomposition/NN-<milestone>/NN-<slice>.md`. Read it in full
|
|
54
54
|
first: its **Scope** (Required Capabilities), **Design** (where it lands), and
|
|
55
55
|
**Proof of work** (what it must prove) are the worker's whole brief.
|
|
56
|
+
- **Working directory & isolation** — the bet's worktree, already opened and
|
|
57
|
+
bootstrapped by the driver. Run every command from it. Leave all changes
|
|
58
|
+
**unstaged** — the driver reviews the working-tree diff and commits; the worker
|
|
59
|
+
never stages, commits, branches, or opens its own worktree (no `EnterWorktree`).
|
|
60
|
+
You build in the worktree handed to you; you do not manage isolation.
|
|
56
61
|
- **Context capsule** — the small set of pointers that let the worker build without
|
|
57
62
|
re-deriving the bet:
|
|
58
63
|
- The **previous slice's delivery commit** — hash, message, and diff. The patterns
|
|
@@ -60,12 +65,26 @@ The driver passes:
|
|
|
60
65
|
`Notes:` line for the next slice are all there. Repeat its lessons, not its
|
|
61
66
|
mistakes.
|
|
62
67
|
- The **exact existing files this slice modifies**, to read in full.
|
|
63
|
-
-
|
|
64
|
-
|
|
65
|
-
what the
|
|
66
|
-
|
|
68
|
+
- When the slice **builds on a prior slice's proven contract**, that slice's **green
|
|
69
|
+
test file** — the proof it wires onto. Its green assertions tell the worker exactly
|
|
70
|
+
what the prior slice already guarantees, so the worker's work stays bounded to what
|
|
71
|
+
this slice adds instead of re-deriving behaviour already proven.
|
|
67
72
|
- The named `Test file:` path(s) for this slice (already materialized red at
|
|
68
73
|
Delivery start).
|
|
74
|
+
- The **stack's testing strategy** — the promoted engineer skill for the slice's
|
|
75
|
+
stack (`.agents/skills/groundwork-<stack>-engineer/references/testing.md`). Its
|
|
76
|
+
**Bet Slice Rollout** section defines the permanent best-practice tests this slice
|
|
77
|
+
owes; it is the authority the worker rolls out against in step 4 and the
|
|
78
|
+
coverage-auditor lens reviews against.
|
|
79
|
+
- Any **slice-specific constraints** — a frozen signature not to change, a
|
|
80
|
+
subsystem not to touch, a safety or content guardrail, the fixtures to prove on.
|
|
81
|
+
These are hard constraints, not suggestions; a conflict between a constraint and
|
|
82
|
+
the proof is a blocking concern, not a judgement call.
|
|
83
|
+
- Any **prior spike or proven recipe** the driver hands over — a working
|
|
84
|
+
invocation, a validated config, a dependency already on disk. Reuse it rather
|
|
85
|
+
than re-deriving. If it sits in an ephemeral location (a job-temp or scratch
|
|
86
|
+
path), copy what you need into a durable path in the repo or the project cache
|
|
87
|
+
and depend on that — never on the ephemeral path at runtime.
|
|
69
88
|
|
|
70
89
|
---
|
|
71
90
|
|
|
@@ -76,6 +95,19 @@ The driver passes:
|
|
|
76
95
|
Most implementation failures are context failures — the agent that breaks an existing
|
|
77
96
|
behaviour usually never read the file it was changing. Before writing any code:
|
|
78
97
|
|
|
98
|
+
- **Orient through the repo map, then trace what you are about to touch.** Refresh the
|
|
99
|
+
deterministic map (`npx groundwork-method repo-map`, incremental) and read its
|
|
100
|
+
`centrality` ranking to find the hubs this slice lands among — real for graph-fidelity
|
|
101
|
+
stacks (Go/Python/TS/JS/Java/Dart); for a symbols-fidelity stack lean on its symbol
|
|
102
|
+
index and on Serena instead. Before you change any symbol other code depends on, run
|
|
103
|
+
live impact analysis with Serena (`find_referencing_symbols`) to see every caller that
|
|
104
|
+
breaks if its signature or shape changes — the missed-call-site class you would
|
|
105
|
+
otherwise lean on the compiler to catch late. Navigate with `get_symbols_overview` /
|
|
106
|
+
`find_symbol` and edit by symbol (`replace_symbol_body` / `rename`) where it fits. Full
|
|
107
|
+
workflow and the graceful-degradation contract are in
|
|
108
|
+
`.groundwork/skills/code-intelligence.md`; when the map or Serena is unavailable,
|
|
109
|
+
navigate with ordinary reads and project search and let the compiler and tests be the
|
|
110
|
+
backstop — the contract is identical, only the means differ.
|
|
79
111
|
- **Read the previous slice's delivery commit** — its message and its diff.
|
|
80
112
|
- **Read every existing file this slice modifies, in full.** For each, hold three
|
|
81
113
|
things: what it does today, what this slice changes, and what must keep working. A
|
|
@@ -93,7 +125,7 @@ Note the baseline commit (`git rev-parse HEAD`) and return it in the report —
|
|
|
93
125
|
the slice's diff to the exact code state it was built against, and is the reference
|
|
94
126
|
the driver's review and the integrity check read.
|
|
95
127
|
|
|
96
|
-
### 3. Implement to green
|
|
128
|
+
### 3. Implement to green (the headline proof)
|
|
97
129
|
|
|
98
130
|
Run the slice's bet-progress tests (`tests/bets/<bet_slug>/test_slice_<n>_*`) — red,
|
|
99
131
|
because the implementation does not exist. Implement until they pass, staying inside
|
|
@@ -120,31 +152,62 @@ quietly substitute a mock and move on — **stop and report it as a blocking con
|
|
|
120
152
|
green and satisfy the API and data design. Stay within this slice. Do not refactor
|
|
121
153
|
unrelated subsystems or reach into other slices' work.
|
|
122
154
|
|
|
123
|
-
### 4.
|
|
124
|
-
|
|
125
|
-
|
|
155
|
+
### 4. Roll out the permanent best-practice tests
|
|
156
|
+
|
|
157
|
+
The headline proof is green; now write the coverage that stays. The bet-progress
|
|
158
|
+
tests prove the slice's capability once and are archived at bet close — the permanent
|
|
159
|
+
best-practice tests are what guard the slice against regression for the life of the
|
|
160
|
+
codebase, and they ship in *this* slice's diff so the review judges them alongside the
|
|
161
|
+
implementation that they are meant to pin.
|
|
162
|
+
|
|
163
|
+
What the slice owes is defined by the stack's testing strategy — the promoted engineer
|
|
164
|
+
skill at `.agents/skills/groundwork-<stack>-engineer/references/testing.md`,
|
|
165
|
+
specifically its **Bet Slice Rollout** section. Read it and roll out what this slice
|
|
166
|
+
earns: the service-perimeter or interface test for each capability the slice
|
|
167
|
+
delivered, unit tests for any genuinely complex logic it introduced, a property-based
|
|
168
|
+
test for any invariant, a critical-path trace assertion where it added an observable
|
|
169
|
+
path (a backend service that emits OpenTelemetry spans), and — for a `graphical-ui`
|
|
170
|
+
slice — component render tests across the states the design system names (default,
|
|
171
|
+
loading, empty, error, long-content) plus registering any new route in
|
|
172
|
+
`tests/system/routes.json`. These live in the service repos and `tests/system/`, never
|
|
173
|
+
in `tests/bets/`. Run them green before reporting.
|
|
174
|
+
|
|
175
|
+
Match the depth to the slice's risk, not a fixed count — the strategy names which tier
|
|
176
|
+
carries each assertion, and a sociable service test that executes a branch without
|
|
177
|
+
asserting on it is a gap even when the suite is green. The independent coverage-auditor
|
|
178
|
+
lens holds this suite against the same strategy, so an under-covered error case or a
|
|
179
|
+
missing trace assertion surfaces in review: write the suite the strategy asks for, not
|
|
180
|
+
the minimum that compiles.
|
|
181
|
+
|
|
182
|
+
### 5. Mechanical self-reconcile (first pass, not the gate)
|
|
183
|
+
|
|
184
|
+
A green suite proves nothing if the approved prose was quietly altered or the code was
|
|
126
185
|
gamed to pass. Run two cheap checks and **report their result** — they are the
|
|
127
186
|
worker's honest first pass, not the authoritative gate (the driver's independent
|
|
128
187
|
review is that):
|
|
129
188
|
|
|
130
|
-
- **Prose integrity.** The approved contract
|
|
131
|
-
design
|
|
132
|
-
`git
|
|
133
|
-
must show no change
|
|
189
|
+
- **Prose integrity.** The approved contract is the decomposition tree and technical
|
|
190
|
+
design.
|
|
191
|
+
`git status --short -- docs/bets/<bet_slug>/decomposition/ docs/bets/<bet_slug>/technical-design/`
|
|
192
|
+
must show no change — the worker never edits that prose. If a proof looks wrong, that
|
|
134
193
|
is a blocking concern, not an edit.
|
|
135
|
-
- **Honest green.** The implementation must satisfy the proof for the right reason
|
|
136
|
-
return value hardcoded to the test's expected output, an
|
|
137
|
-
fixture, a `if TEST_MODE`-style branch,
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
194
|
+
- **Honest green.** The implementation must satisfy the proof for the right reason,
|
|
195
|
+
against the real product. A return value hardcoded to the test's expected output, an
|
|
196
|
+
input special-cased to the fixture, a `if TEST_MODE`-style branch, a mocked-out unit
|
|
197
|
+
of real work, or a fixture standing in for a real pipeline stage that nothing else
|
|
198
|
+
produces is a defect even though the suite is green — *a weak suite that generated
|
|
199
|
+
code passes is worse than no suite* (`docs/principles/foundations/testing.md`). If a
|
|
200
|
+
fake the slice leans on has no real test behind it, or the proof runs against a test
|
|
201
|
+
target rather than the shipping build, flag it. Surface any of these in the report
|
|
202
|
+
rather than leaving them for the review to find.
|
|
203
|
+
|
|
204
|
+
### 6. Do not commit
|
|
205
|
+
|
|
206
|
+
The worker implements to green, rolls out the permanent tests, and stops. It does
|
|
207
|
+
**not** stage, commit, or close the slice — those are the driver's, after its
|
|
208
|
+
independent review and triage. Leave the working tree with all of the slice's changes
|
|
209
|
+
unstaged — the implementation, the bet-progress tests turned green, and the permanent
|
|
210
|
+
best-practice tests — and return the report.
|
|
148
211
|
|
|
149
212
|
---
|
|
150
213
|
|
|
@@ -158,6 +221,9 @@ triage, and close the slice:
|
|
|
158
221
|
SLICE: <n> <slice-slug> (service: <owner-service>, surface: <core|slug>)
|
|
159
222
|
BASELINE: <git rev-parse HEAD at open>
|
|
160
223
|
SUITE: green | red — <one line: which slice tests pass; if still red, why>
|
|
224
|
+
COVERAGE: <the permanent best-practice tests rolled out, by kind — service/interface,
|
|
225
|
+
unit, property, trace; for graphical-ui, the component states covered. Note any the
|
|
226
|
+
strategy asks for that this slice does not owe, and why.>
|
|
161
227
|
|
|
162
228
|
FILES:
|
|
163
229
|
- added: <path>, ...
|
|
@@ -21,8 +21,8 @@ Each phase establishes one thing the next phase depends on:
|
|
|
21
21
|
|
|
22
22
|
- **Discovery** establishes the *what* and the *why*. It produces the pitch — the problem, the appetite, the solution sketch, the success signal, and the explicit no-gos. Without it, design has nothing to anchor against.
|
|
23
23
|
- **Design Foundations** establishes the *contract*. It produces the technical design — UI design first (one subsection per in-scope surface), then the headless core beneath it: data flows and business logic, API design, and schema & data design, surface-neutral. Without a locked design, decomposition produces milestones and tests that contradict each other.
|
|
24
|
-
- **Decomposition** establishes *the order of work and the proof*. With the design locked, it authors the full **milestone ladder** —
|
|
25
|
-
- **Delivery** materializes the red board from the approved prose, then drives it green as an orchestration. The agent is the *driver* — it holds the thin spine (the board, the milestone order, the granularity the user chose, the triage judgement) and dispatches a fresh slice-worker subagent per slice (`briefs/slice-worker.md`) so the heavy implementation context stays disposable. It reviews each worker's diff through independent lenses, commits the slice, and at every milestone boundary runs a postmortem that confirms the milestone honestly proved its intent, re-checks the remaining ladder, and authors the next milestone's slices from what this one taught (introducing a new rung when the ladder is missing one, within appetite) —
|
|
24
|
+
- **Decomposition** establishes *the order of work and the proof*. With the design locked, it authors the full **milestone ladder** — thin, user-visible steps ordered to front-load risk, each carrying a headline Proof-of-work proof that **drives the real product through its real front door** (no stub, double, or scripted stand-in can satisfy it; any fake it leans on needs a real test behind it; this is the success signal made executable) — but slices only the **first milestone**; later rungs are sliced on arrival in Delivery, from what the milestones before them taught. Every milestone names a consumer who observes its outcome at their real surface; the first user-visible milestone lands the design system in the running app; the ladder must sum to a complete, well-rounded experience. Every shape traces to the prose API/data design. No test code is written here. The user reviews proof by proof and approves; the approved prose is committed as the recorded baseline, and changing *what a milestone proves* afterwards is an owner-approved amendment recorded in git history with a reason — steering how slices break down is free. The tests are generated red at Delivery start from this approved prose. Without this Proof of Work, delivery has no proof to satisfy and no sequence to follow.
|
|
25
|
+
- **Delivery** materializes the red board from the approved prose, then drives it green as an orchestration. The agent is the *driver* — it holds the thin spine (the board, the milestone order, the granularity the user chose, the triage judgement) and dispatches a fresh slice-worker subagent per slice (`briefs/slice-worker.md`) so the heavy implementation context stays disposable. It reviews each worker's diff through independent lenses, commits the slice, proves each milestone at the front door (folding in the visual checks and a polish pass, with the experience-auditor lens judging the assembled milestone), and at every milestone boundary runs a postmortem that confirms the milestone honestly proved its intent, re-checks the remaining ladder, and authors the next milestone's slices from what this one taught (introducing a new rung when the ladder is missing one, within appetite) — recording each authored rung as it goes, course-correcting through the Amendment Protocol or Change Navigation when an approved proof or the design is wrong, never editing approved prose around without a recorded amendment. Delivery is offered at three cadences — slice by slice, milestone by milestone (default), or whole bet — which set where the driver pauses; hard stops pause regardless. The suite is the board (`./dev bet status`, derived not stored) and each slice's commit is its record, so progress is visible and resumable. As each slice completes, permanent best-practice tests are rolled out, and a per-slice reconciliation checks that the approved prose has not silently moved. Without the Decomposition contract, every design question becomes a mid-implementation conversation made under coding pressure.
|
|
26
26
|
- **Validation** confirms the delivered bet behaves as designed, captures each touched service's served contract into the canonical `docs/architecture/api/` record, writes the bet's capability-ledger rows (when the project keeps a surface registry), archives the **whole bet** (docs and tests), runs the bet retrospective, and folds what the bet learned back into upstream documents for every subsequent bet.
|
|
27
27
|
|
|
28
28
|
The lifecycle is sequential because each phase's output is the next phase's input. The order is structural, not procedural — gating design before decomposition is not a rule to follow but the only way the artifacts compose.
|
|
@@ -37,8 +37,8 @@ Each phase runs in its own workflow file because each demands a different mode.
|
|
|
37
37
|
|---|---|---|---|
|
|
38
38
|
| 1. Discovery | `workflows/01-discovery.md` | `discovery` | `docs/bets/<slug>/pitch.md` |
|
|
39
39
|
| 2. Design Foundations | `workflows/02-design.md` | `design` | `docs/bets/<slug>/technical-design/` (`01-ui-design.md`, `02-data-flows.md`, `03-api-design.md`, `04-data-design.md`) |
|
|
40
|
-
| 3. Decomposition | `workflows/03-decomposition.md` | `decomposition` | `docs/bets/<slug>/decomposition/` prose tree — full milestone ladder + first milestone sliced, approved and
|
|
41
|
-
| 4. Delivery | `workflows/04-delivery.md` (driver) + `briefs/slice-worker.md` (per-slice subagent) | `delivery` | Red board materialized from the approved prose, then driven green milestone by milestone — slice-workers implement, the driver reviews/commits, and at each milestone boundary a postmortem course-corrects and opens the next milestone (authoring its slices
|
|
40
|
+
| 3. Decomposition | `workflows/03-decomposition.md` | `decomposition` | `docs/bets/<slug>/decomposition/` prose tree — full milestone ladder + first milestone sliced, approved and committed as the recorded baseline |
|
|
41
|
+
| 4. Delivery | `workflows/04-delivery.md` (driver) + `briefs/slice-worker.md` (per-slice subagent) | `delivery` | Red board materialized from the approved prose, then driven green milestone by milestone — slice-workers implement, the driver reviews/commits, and at each milestone boundary a postmortem course-corrects and opens the next milestone (authoring and recording its slices); each slice committed as its record |
|
|
42
42
|
| 5. Validation | `workflows/05-validation.md` | `validation` → `delivered` | Canonical `docs/architecture/api/` captured from running code; retrospective; whole bet archived |
|
|
43
43
|
|
|
44
44
|
The pitch's frontmatter `status` field tracks where the bet sits in the lifecycle. Status transitions on entry to each phase and is the routing signal that lets a fresh context pick up the bet at the right place.
|
|
@@ -8,20 +8,14 @@
|
|
|
8
8
|
|
|
9
9
|
Bet-progress tests are **temporary, black-box proof-of-work** materialized from the approved prose before any implementation exists. Each one renders the Proof-of-work prose of a milestone or slice — the proof the user already reviewed and approved in the decomposition tree — into a runnable red stub. At Delivery start the board is materialized for the whole **milestone ladder** plus the **first milestone's slices**; each later milestone's slice stubs are added when Delivery opens that milestone (its slices are authored then). So the board shows progress at milestone granularity before the later rungs are sliced. They assert what the milestone's consumer would observe if the feature were complete. Red means the work is not done. Green means it is proven. Running the suite is the bet's live progress board.
|
|
10
10
|
|
|
11
|
-
A milestone's
|
|
12
|
-
|
|
13
|
-
**Capability-level tests** prove a capability milestone — they hit the contract directly, end-to-end against the running services over HTTP (or against the embedded core's public API), with no surface in the loop. Every business rule the bet introduces is proven here, exactly once.
|
|
14
|
-
|
|
15
|
-
**Interface-level tests** prove a surface milestone — they assert what that surface's users observe, in that surface's medium:
|
|
16
|
-
- `graphical-ui` — a browser-driven test that navigates to the feature and verifies what the user sees
|
|
11
|
+
**A milestone test drives the real product through its consumer's front door.** It exercises the shipping build the way the milestone's consumer would, on the real pipeline and real data, and asserts what the consumer observes — in their surface's medium:
|
|
12
|
+
- `graphical-ui` — a browser-driven (or platform-driven) test that navigates to the feature and verifies what the user sees on the running app
|
|
17
13
|
- `cli` — a test that invokes the command and verifies the output, exit code, or side-effect
|
|
18
14
|
- `agentic-protocol` — a test that sends a protocol request and verifies the response structure
|
|
19
15
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
When the project has no surface registry, the two layers pair up per milestone exactly as they always have: an interface-level test in the project's single medium, plus an API-level system test that localizes failures.
|
|
16
|
+
The milestone test resolves its consumer's surface through the surfaces fixture (slug → entry point). It is the front-door proof: it runs the whole path end to end, not a back-channel against an internal contract with no consumer in the loop. Proving a backend contract directly is real work, but it belongs to a *slice* test, not a milestone test — the milestone proves the consumer's outcome.
|
|
23
17
|
|
|
24
|
-
Slice tests prove the vertical capability a slice contributes toward its parent milestone. They are **informed by and bounded by** the parent milestone's
|
|
18
|
+
Slice tests prove the vertical capability a slice contributes toward its parent milestone, at that slice's service edge. They are **informed by and bounded by** the parent milestone's front-door proof — a slice test proves a specific capability; the milestone test proves the consumer-visible outcome those capabilities enable. A slice that builds a screen proves the screen renders and behaves through the pattern it implements in full.
|
|
25
19
|
|
|
26
20
|
---
|
|
27
21
|
|
|
@@ -69,18 +63,18 @@ tests/bets/_archive/<bet-slug>/
|
|
|
69
63
|
|
|
70
64
|
Bet-progress tests reuse the shared fixtures from `tests/conftest.py`:
|
|
71
65
|
- `cluster` — boots and health-checks all services; provides the running topology
|
|
72
|
-
- `api_client` — an HTTP client configured with the discovered service base URLs;
|
|
66
|
+
- `api_client` — an HTTP client configured with the discovered service base URLs; slice tests use this to exercise a service edge directly
|
|
73
67
|
- `pure_state_reset` — truncates all service data stores before each test (autouse)
|
|
74
|
-
- `surfaces` — the mapping from registry slug to that surface's entry point (base URL for a web surface, binary path for a CLI, protocol endpoint for an agentic surface);
|
|
68
|
+
- `surfaces` — the mapping from registry slug to that surface's entry point (base URL for a web surface, binary path for a CLI, protocol endpoint for an agentic surface); milestone front-door tests resolve their consumer's surface here
|
|
75
69
|
- `frontend_base_url` — the legacy alias for the single graphical surface's base URL; present when exactly one graphical surface exists, for suites written before the surfaces fixture
|
|
76
70
|
|
|
77
71
|
Declare the fixtures you need as test-function parameters; pytest resolves them from the parent conftest automatically.
|
|
78
72
|
|
|
79
|
-
For
|
|
73
|
+
For a front-door test against a `graphical-ui` surface, the `page` fixture (from pytest-playwright) drives a real browser. For `cli` surfaces, use `subprocess` or `pexpect` to invoke the binary directly.
|
|
80
74
|
|
|
81
75
|
## Capturing screenshots for the visual verification loop
|
|
82
76
|
|
|
83
|
-
For `graphical-ui` interface tests, capture a screenshot of each key state of the screen under test — default, hover, focus, empty, loading, error — written to `.groundwork/cache/visual/<bet-slug>/<surface>/<state>.png` (create the directory first). These are the states where "renders broken" and "looks unfinished" both live, and the captures are what the delivery agent reads (Tier 2 inspection) and the
|
|
77
|
+
For `graphical-ui` interface tests, capture a screenshot of each key state of the screen under test — default, hover, focus, empty, loading, error — written to `.groundwork/cache/visual/<bet-slug>/<surface>/<state>.png` (create the directory first). These are the states where "renders broken" and "looks unfinished" both live, and the captures are what the delivery agent reads (Tier 2 inspection) and the experience-auditor review judges at milestone close and over the whole bet. Capture after the state is reached and assertions pass — the screenshot records the proven state, it does not replace the assertion. Capture nothing for `cli` and `agentic-protocol` surfaces; their observable output is text, asserted directly.
|
|
84
78
|
|
|
85
79
|
**What capture sees, and what it does not.** A static screenshot verifies render correctness, coherence, and composition. It does *not* see motion (easing, durations, press physics) or perceived latency — both committed in the design system — so those stay behaviour-tested, asserted on timing and state, never on a frame. Do not treat a captured screen as proof of an animation or a latency budget.
|
|
86
80
|
|
|
@@ -96,18 +90,13 @@ When the implementation does not exist yet, a test stub must be **explicitly red
|
|
|
96
90
|
- Go: `t.Fatal("bet-progress test not yet implemented — <describe target state>")`
|
|
97
91
|
- TypeScript: `throw new Error("bet-progress test not yet implemented — <describe target state>")`
|
|
98
92
|
|
|
99
|
-
Comment the stub with what it will eventually assert, so the Delivery agent knows exactly what to implement. For a
|
|
100
|
-
```
|
|
101
|
-
# Contract: [the end-to-end behaviour the core should prove — request, response, persisted effect]
|
|
102
|
-
```
|
|
103
|
-
For a surface milestone stub:
|
|
93
|
+
Comment the stub with what it will eventually assert, so the Delivery agent knows exactly what to implement. For a milestone stub, name the consumer's front-door outcome:
|
|
104
94
|
```
|
|
105
|
-
#
|
|
95
|
+
# Front door (<consumer> via <surface>): [what the consumer observes when they drive the real product — the action, what they see, on real data]
|
|
106
96
|
```
|
|
107
|
-
For
|
|
97
|
+
For a slice stub, name the capability at its service edge:
|
|
108
98
|
```
|
|
109
|
-
#
|
|
110
|
-
# Layer 2 — API: [what the service should return end-to-end over HTTP]
|
|
99
|
+
# Slice capability: [the behaviour at this slice's edge the milestone's front-door proof builds on]
|
|
111
100
|
```
|
|
112
101
|
|
|
113
102
|
---
|
|
@@ -115,12 +104,12 @@ For an untyped milestone (no surface registry), comment both layers:
|
|
|
115
104
|
## What makes a good bet-progress test
|
|
116
105
|
|
|
117
106
|
A bet-progress test is good when:
|
|
118
|
-
- It asserts a **falsifiable, consumer-visible outcome** —
|
|
107
|
+
- It asserts a **falsifiable, consumer-visible outcome** — what the consumer observes at their front door, never an internal state
|
|
119
108
|
- It would fail if the feature shipped incomplete
|
|
120
|
-
- For a **milestone headline**, it
|
|
109
|
+
- For a **milestone headline**, it **drives the real product through the real front door** — the consumer's action runs the shipping build on the real pipeline and real data, so a stub, mock, scripted driver, or hardcoded return cannot turn it green. A milestone proof a double can satisfy proves plumbing, not the milestone (`workflows/03-decomposition.md`). Seeded inputs are fine; faking the work in the middle is not
|
|
110
|
+
- **Any fake it leans on has a real test behind it** — if the proof uses a fixture for work a real stage should do, another test exercises the real producer; a fixture nothing real ever generates is a green light wired to nothing (`docs/principles/foundations/testing.md`)
|
|
121
111
|
- It would pass without any special knowledge of how the feature is implemented internally
|
|
122
|
-
- It proves each business rule exactly once — at the contract; surface tests assert only wiring, rendering, and interaction
|
|
123
112
|
- It is a **headline proof, not a permutation** — it proves the milestone's outcome or the slice's capability, not every input variant or error code
|
|
124
113
|
- A reviewer can read it and confirm it matches the milestone's acceptance criteria and Proof-of-work prose in its `decomposition/NN-<milestone-slug>/index.md`
|
|
125
114
|
|
|
126
|
-
**Keep the suite lean.** Bet-progress tests render the high-impact proofs the user reviewed and signed as prose — a milestone's consumer-visible outcome and each slice's vertical capability, typically one to three assertions apiece. If an assertion is an edge case, a permutation, or an error variant rather than the headline outcome, it does not belong here; it is part of the slice's permanent best-practice tests, written when the slice is built in Delivery (`workflows/04-delivery.md
|
|
115
|
+
**Keep the suite lean.** Bet-progress tests render the high-impact proofs the user reviewed and signed as prose — a milestone's consumer-visible outcome and each slice's vertical capability, typically one to three assertions apiece. If an assertion is an edge case, a permutation, or an error variant rather than the headline outcome, it does not belong here; it is part of the slice's permanent best-practice tests, written when the slice is built in Delivery (`workflows/04-delivery.md`, the Slice Loop). A wall of assertions is unreviewable upstream and front-loads coverage the delivery suite is meant to carry.
|
|
@@ -35,4 +35,4 @@
|
|
|
35
35
|
|
|
36
36
|
## Routing
|
|
37
37
|
|
|
38
|
-
[Minor: edits applied on approval, mutated docs re-reviewed, affected proofs amended through the Amendment Protocol (edit the slice/milestone prose,
|
|
38
|
+
[Minor: edits applied on approval, mutated docs re-reviewed, affected proofs amended through the Amendment Protocol (edit the slice/milestone prose, commit it beside the decomposition with a reason, then change the code), slice resumed. Structural: bet reverts to Design Foundations with this proposal as input; delivered slices that survive the change are listed here.]
|