shapeup-sdlc 1.6.2

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.
Files changed (135) hide show
  1. package/.claude/settings.local.example.json +20 -0
  2. package/.claude-plugin/marketplace.json +16 -0
  3. package/.claude-plugin/plugin.json +18 -0
  4. package/.env.shapeup.example +14 -0
  5. package/AGENTS.md +133 -0
  6. package/LICENSE +21 -0
  7. package/README.md +362 -0
  8. package/SECURITY.md +72 -0
  9. package/bin/init.mjs +329 -0
  10. package/commands/build.md +14 -0
  11. package/commands/eval.md +15 -0
  12. package/commands/hammer.md +12 -0
  13. package/commands/orient.md +11 -0
  14. package/commands/qa.md +12 -0
  15. package/commands/retro.md +13 -0
  16. package/commands/scopes.md +14 -0
  17. package/commands/shape.md +12 -0
  18. package/commands/ship.md +53 -0
  19. package/commands/wire.md +11 -0
  20. package/hooks/anti-rationalization.mjs +244 -0
  21. package/hooks/compact-snapshot.mjs +47 -0
  22. package/hooks/gate-deadline.mjs +151 -0
  23. package/hooks/gate-intake.mjs +110 -0
  24. package/hooks/gate-l2.mjs +161 -0
  25. package/hooks/gate-zerowork.mjs +264 -0
  26. package/hooks/hooks.json +118 -0
  27. package/hooks/lib/decision.mjs +183 -0
  28. package/hooks/safety-spine.mjs +296 -0
  29. package/hooks/sandbox-guard.mjs +172 -0
  30. package/hooks/session-rehydrate.mjs +109 -0
  31. package/hooks/slop-cleaner.mjs +176 -0
  32. package/oracles/_shared.mjs +46 -0
  33. package/oracles/http-oracle.mjs +155 -0
  34. package/oracles/index.mjs +36 -0
  35. package/oracles/process-oracle.mjs +146 -0
  36. package/oracles/snapshot-oracle.mjs +119 -0
  37. package/oracles/test-oracle.mjs +138 -0
  38. package/package.json +49 -0
  39. package/skills/advisor-protocol/SKILL.md +171 -0
  40. package/skills/ba-pitch-analyzer/SKILL.md +175 -0
  41. package/skills/ba-pitch-analyzer/assets/templates/_index.tmpl.md +84 -0
  42. package/skills/ba-pitch-analyzer/assets/templates/api-feasibility.tmpl.md +65 -0
  43. package/skills/ba-pitch-analyzer/assets/templates/assess-report.tmpl.md +127 -0
  44. package/skills/ba-pitch-analyzer/assets/templates/contracts/be-service.contract.tmpl.md +62 -0
  45. package/skills/ba-pitch-analyzer/assets/templates/contracts/offline-storage.contract.tmpl.md +92 -0
  46. package/skills/ba-pitch-analyzer/assets/templates/contracts/third-party-api.contract.tmpl.md +66 -0
  47. package/skills/ba-pitch-analyzer/assets/templates/cross-context/context-map.tmpl.md +64 -0
  48. package/skills/ba-pitch-analyzer/assets/templates/cross-context/event-choreography.tmpl.md +77 -0
  49. package/skills/ba-pitch-analyzer/assets/templates/cross-context/migration-plan.tmpl.md +104 -0
  50. package/skills/ba-pitch-analyzer/assets/templates/cross-context/team-handoff.tmpl.md +79 -0
  51. package/skills/ba-pitch-analyzer/assets/templates/domain-model.tmpl.md +79 -0
  52. package/skills/ba-pitch-analyzer/assets/templates/feedback.tmpl.md +87 -0
  53. package/skills/ba-pitch-analyzer/assets/templates/integration.tmpl.md +64 -0
  54. package/skills/ba-pitch-analyzer/assets/templates/run-state.tmpl.md +77 -0
  55. package/skills/ba-pitch-analyzer/assets/templates/scope-summary.tmpl.md +105 -0
  56. package/skills/ba-pitch-analyzer/assets/templates/synthesis.tmpl.md +215 -0
  57. package/skills/ba-pitch-analyzer/assets/templates/task-board.tmpl.md +35 -0
  58. package/skills/ba-pitch-analyzer/assets/templates/task-spike.tmpl.md +86 -0
  59. package/skills/ba-pitch-analyzer/assets/templates/task.tmpl.md +84 -0
  60. package/skills/ba-pitch-analyzer/assets/templates/usecase.tmpl.md +105 -0
  61. package/skills/ba-pitch-analyzer/assets/templates/ux-behavior.tmpl.md +65 -0
  62. package/skills/ba-pitch-analyzer/references/contract-patterns.md +152 -0
  63. package/skills/ba-pitch-analyzer/references/ddd-patterns.md +173 -0
  64. package/skills/ba-pitch-analyzer/references/doc-schemas.md +275 -0
  65. package/skills/ba-pitch-analyzer/references/integration-analysis.md +152 -0
  66. package/skills/ba-pitch-analyzer/references/task-generation.md +623 -0
  67. package/skills/ba-pitch-analyzer/references/test-surface.md +102 -0
  68. package/skills/ba-pitch-analyzer/references/ux-behavior-patterns.md +269 -0
  69. package/skills/ba-pitch-analyzer/scripts/board-derive.mjs +241 -0
  70. package/skills/ba-pitch-analyzer/scripts/spec-lint.mjs +239 -0
  71. package/skills/coach/SKILL.md +202 -0
  72. package/skills/orient/SKILL.md +262 -0
  73. package/skills/qa-edge-hunter/SKILL.md +369 -0
  74. package/skills/scope-architect/SKILL.md +111 -0
  75. package/skills/scope-hammer/SKILL.md +186 -0
  76. package/skills/shapeup/SKILL.md +403 -0
  77. package/skills/shapeup/resources/breadboard-reflection.md +88 -0
  78. package/skills/shapeup/resources/breadboarding.md +334 -0
  79. package/skills/shapeup/resources/context-compaction.md +240 -0
  80. package/skills/shapeup/resources/framing-doc.md +92 -0
  81. package/skills/shapeup/resources/kickoff-doc.md +95 -0
  82. package/skills/shapeup/resources/shaping.md +194 -0
  83. package/skills/shapeup/resources/spike.md +86 -0
  84. package/skills/solution-architect/SKILL.md +129 -0
  85. package/skills/spec-evaluator/README.md +93 -0
  86. package/skills/spec-evaluator/SKILL.md +213 -0
  87. package/skills/spec-evaluator/references/anti-leniency.md +50 -0
  88. package/skills/spec-evaluator/references/dimension-contract.md +126 -0
  89. package/skills/spec-evaluator/references/dimensions/_registry.md +40 -0
  90. package/skills/spec-evaluator/references/dimensions/completeness.md +102 -0
  91. package/skills/spec-evaluator/references/dimensions/integration.md +129 -0
  92. package/skills/spec-evaluator/references/dimensions/performance.md +48 -0
  93. package/skills/spec-evaluator/references/dimensions/security.md +60 -0
  94. package/skills/spec-evaluator/references/dimensions/spec-conformance.md +134 -0
  95. package/skills/spec-evaluator/references/dimensions/tdd-surface.md +110 -0
  96. package/skills/spec-evaluator/references/dimensions/test-surface-conformance.md +100 -0
  97. package/skills/spec-evaluator/references/probing.md +177 -0
  98. package/skills/spec-evaluator/references/report-schema.md +101 -0
  99. package/skills/spec-evaluator/references/verdict-ledger.md +92 -0
  100. package/skills/spec-evaluator/scripts/verdict-ledger.mjs +166 -0
  101. package/skills/task-executor/SKILL.md +194 -0
  102. package/skills/tech-lead/README.md +71 -0
  103. package/skills/tech-lead/SKILL.md +459 -0
  104. package/skills/tech-lead/references/delegation.md +254 -0
  105. package/skills/tech-lead/references/gates.md +379 -0
  106. package/skills/tech-lead/references/invocation.md +45 -0
  107. package/skills/tech-lead/references/ledger-schema.md +214 -0
  108. package/skills/tech-lead/references/round-protocol.md +184 -0
  109. package/skills/tech-lead/references/state-model.md +66 -0
  110. package/skills/tech-lead/references/tiny-lane.md +52 -0
  111. package/skills/tech-lead/schemas/domain.schema.json +2294 -0
  112. package/skills/tech-lead/schemas/gate-answers.schema.json +92 -0
  113. package/skills/tech-lead/schemas/work-order.schema.json +21 -0
  114. package/skills/tech-lead/schemas/work-result.schema.json +40 -0
  115. package/skills/tech-lead/scripts/aegis-digest.mjs +124 -0
  116. package/skills/tech-lead/scripts/budget-check.mjs +156 -0
  117. package/skills/tech-lead/scripts/compile-order.mjs +518 -0
  118. package/skills/tech-lead/scripts/fit-check.mjs +196 -0
  119. package/skills/tech-lead/scripts/gate-answers.mjs +338 -0
  120. package/skills/tech-lead/scripts/ingest-result.mjs +270 -0
  121. package/skills/tech-lead/scripts/init-run.mjs +326 -0
  122. package/skills/tech-lead/scripts/lib/argv.mjs +224 -0
  123. package/skills/tech-lead/scripts/lib/contract-md.mjs +481 -0
  124. package/skills/tech-lead/scripts/lib/is-main.mjs +82 -0
  125. package/skills/tech-lead/scripts/lib/paths.mjs +278 -0
  126. package/skills/tech-lead/scripts/lib/ratchet-tree.mjs +112 -0
  127. package/skills/tech-lead/scripts/run-snapshot.mjs +269 -0
  128. package/skills/tech-lead/scripts/ship-report.mjs +275 -0
  129. package/skills/tech-lead/scripts/stats.mjs +423 -0
  130. package/skills/tech-lead/scripts/t0-verify.mjs +470 -0
  131. package/skills/tech-lead/scripts/trace-lint.mjs +367 -0
  132. package/skills/tech-lead/scripts/validate-envelope.mjs +283 -0
  133. package/skills/translator/README.md +66 -0
  134. package/skills/translator/SKILL.md +258 -0
  135. package/skills/translator/references/preservation-rules.md +102 -0
@@ -0,0 +1,48 @@
1
+ ---
2
+ id: performance
3
+ title: "Performance"
4
+ enabled: false # ⛔ STUB — not run until flipped true or named in --dimensions
5
+ weight: 1.0
6
+ hard_threshold: count<=0
7
+ applies_to:
8
+ variant: [be, web]
9
+ package: any
10
+ requires_browser: true
11
+ ---
12
+
13
+ # Performance (stub)
14
+
15
+ Not run in v0.1. Worked example only. Performance is deliberately out of scope now;
16
+ this file documents how it would attach later without touching the core.
17
+
18
+ ## Criteria (TODO — fill before enabling)
19
+
20
+ ```yaml
21
+ - id: PERF-API
22
+ statement: "Endpoints touched by the task respond within the budget stated in the spec."
23
+ probe: cmd
24
+ evidence_required: true
25
+ pass_rule: "TODO: measured p95 under the spec's budget for the documented payload."
26
+ source: contract
27
+
28
+ - id: PERF-WEB
29
+ statement: "The screen the task delivers meets its interaction budget (no obvious jank)."
30
+ probe: ui
31
+ evidence_required: true
32
+ pass_rule: "TODO: drive the screen; primary interaction completes within budget."
33
+ source: scope-summary
34
+ ```
35
+
36
+ ## Threshold
37
+ `count<=0` — every performance criterion must meet its budget (no over-budget items
38
+ tolerated). Tune to `count<=N` if soft budgets are acceptable.
39
+
40
+ ## Bug template
41
+ ```
42
+ severity: [critical|major|minor]
43
+ criterion: [PERF-API | PERF-WEB]
44
+ location: <endpoint | screen>
45
+ repro: <load / measurement performed>
46
+ expected: <budget from spec>
47
+ actual: <measured value>
48
+ ```
@@ -0,0 +1,60 @@
1
+ ---
2
+ id: security
3
+ title: "Security"
4
+ enabled: false # ⛔ STUB — not run until flipped true or named in --dimensions
5
+ weight: 1.0
6
+ hard_threshold: no-critical
7
+ applies_to:
8
+ variant: [be, shared] # backend + shared contracts; not graded on .web/.mobile tasks
9
+ package: any
10
+ requires_browser: false
11
+ ---
12
+
13
+ # Security (stub)
14
+
15
+ Not run in v0.1. Shipped as a worked example of the dimension contract so turning it on
16
+ later is a one-line registry change, no core edits.
17
+
18
+ > The user explicitly scoped v0.1 to spec + AC correctness only. This file exists to prove
19
+ > the injection path, not to be enabled now. Flip `enabled: true` (or pass
20
+ > `--dimensions spec-conformance,security`) when security becomes in scope.
21
+
22
+ ## Criteria (TODO — fill before enabling)
23
+
24
+ ```yaml
25
+ - id: SEC-AUTHZ
26
+ statement: "Every endpoint touched by the task enforces the authorization rule from the spec."
27
+ probe: cmd
28
+ evidence_required: true
29
+ pass_rule: "TODO: unauthenticated/forbidden requests are rejected with the documented code."
30
+ source: contract
31
+
32
+ - id: SEC-INPUT
33
+ statement: "Inputs are validated against the contract; malformed input is rejected, not crashed on."
34
+ probe: cmd
35
+ evidence_required: true
36
+ pass_rule: "TODO: fuzz the documented fields; no 500 / unhandled exception leaks."
37
+ source: contract
38
+
39
+ - id: SEC-SECRETS
40
+ statement: "No secrets/keys committed in the task's changed files."
41
+ probe: static
42
+ evidence_required: true
43
+ pass_rule: "TODO: scan the diff for secret patterns; zero hits."
44
+ source: code
45
+ ```
46
+
47
+ ## Threshold
48
+ `no-critical` — minor/major findings are reported but do not fail the build; any
49
+ `critical` finding fails the dimension. (Contrast with spec-conformance's `all-pass`:
50
+ correctness is binary, security is risk-tiered.)
51
+
52
+ ## Bug template
53
+ ```
54
+ severity: [critical|major|minor]
55
+ criterion: [SEC-AUTHZ | SEC-INPUT | SEC-SECRETS]
56
+ location: <file:line | endpoint>
57
+ repro: <request / scan that surfaced it>
58
+ expected: <secure behavior per spec>
59
+ actual: <observed weakness>
60
+ ```
@@ -0,0 +1,134 @@
1
+ ---
2
+ id: spec-conformance
3
+ title: "Spec conformance"
4
+ enabled: true
5
+ weight: 1.0
6
+ hard_threshold: all-pass
7
+ applies_to:
8
+ lens: [lite, standard]
9
+ package: any
10
+ variant: any
11
+ requires_browser: true
12
+ ---
13
+
14
+ # Spec conformance
15
+
16
+ The one dimension the evaluator runs by default. Answers a single question with no
17
+ leniency: **does the built task do exactly what its spec and acceptance criteria say —
18
+ no less (missing/stubbed behavior) and no more (out-of-scope changes)?**
19
+
20
+ Correctness only. Not security, not performance, not aesthetics. Those are other
21
+ dimensions, off by default.
22
+
23
+ ## Criteria
24
+
25
+ ```yaml
26
+ - id: SC-AC
27
+ statement: "Every UC Step, Error Case, and (when present) Invariant/Test-Surface row for the
28
+ use case(s) this task/feature implements is satisfied."
29
+ probe: cmd # most are cmd; [ui]/[data] criteria use those probes per GATE V1.2 classification
30
+ evidence_required: true
31
+ pass_rule: >
32
+ Each criterion is drawn from usecases/UC-*.md (numbered ## Steps, ## Error Cases rows,
33
+ ## Invariants [INV-NN] entries, ## Test Surface derived rows when present) for every UC
34
+ named in this task's use_case_refs (or confirmed with the user at V1.1 when no local task
35
+ file exists). Run each via its classified probe and PASS. Zero failing criterion.
36
+ A stubbed/display-only implementation that satisfies a local task file's own AC wording but
37
+ not the UC's actual behavior FAILS — the task's AC (if present) is a paraphrase read only
38
+ for traceability (GATE V0.2b), never the grading text itself.
39
+ source: usecases
40
+
41
+ - id: SC-DONE-WHEN
42
+ statement: "Each 'Done when:' statement for this task (scope-summary) is satisfied."
43
+ probe: ui
44
+ evidence_required: true
45
+ pass_rule: >
46
+ Drive the running app to reproduce the user-visible outcome each Done-when describes.
47
+ The outcome is observed, not inferred from code. Done-when statements are honored verbatim.
48
+ source: scope-summary
49
+
50
+ - id: SC-REQ
51
+ statement: "Request shape matches contracts/<repo>.contract.md #Request table."
52
+ probe: cmd
53
+ evidence_required: true
54
+ pass_rule: "A real request built from the contract is accepted; every field/type/required flag matches."
55
+ source: contract
56
+
57
+ - id: SC-RES
58
+ statement: "Response mapping matches contracts/<repo>.contract.md #Response table."
59
+ probe: cmd
60
+ evidence_required: true
61
+ pass_rule: "The actual response is compared field-by-field to the Response table; all map correctly."
62
+ source: contract
63
+
64
+ - id: SC-ERR
65
+ statement: "Every error code in contracts/<repo>.contract.md #Error Cases is handled."
66
+ probe: cmd
67
+ evidence_required: true
68
+ pass_rule: "Each error case is triggered and the documented code/shape is returned; none unhandled."
69
+ source: contract
70
+
71
+ - id: SC-NONGO
72
+ statement: "The implementation respects the feature's '## Non-Go' boundary (_index.md) and
73
+ each touched UC's own scope."
74
+ probe: static
75
+ evidence_required: true
76
+ pass_rule: >
77
+ Inspect the diff / changed files. No file outside the feature's declared package/scope is
78
+ modified, and no item in _index.md's ## Non-Go list is touched. Any out-of-scope change
79
+ FAILS with file:line. (A local task file's own Non-Go section, when present, is consistent
80
+ with _index.md by construction — ba-pitch-analyzer derives it from the pitch — but the
81
+ committed _index.md is the grading source since the task file may not exist locally.)
82
+ source: index
83
+
84
+ - id: SC-LAYER
85
+ statement: "No upward layer leak — the task does not reach above its declared layer."
86
+ probe: static
87
+ evidence_required: false # advisory unless a concrete violation is found
88
+ pass_rule: >
89
+ A Layer-N task does not implement or depend on un-built Layer N+1 code.
90
+ Only FAILS if a concrete violation is observed; otherwise PASS.
91
+ source: code
92
+ ```
93
+
94
+ Criteria applicability by variant (the core uses `applies_to` for the dimension, then
95
+ common sense per task):
96
+ - `SC-REQ / SC-RES / SC-ERR` apply only when the task touches a repository / contract
97
+ (typically `.be` and `.shared`). For a pure `.web` UI task with no contract, they are N/A
98
+ and excluded — not auto-passed.
99
+ - `SC-DONE-WHEN` and `SC-AC` apply to every task.
100
+ - For `.e2e` tasks, `SC-AC` is satisfied by running the existing e2e suite green.
101
+
102
+ ## Threshold
103
+
104
+ `all-pass` — every **applicable** criterion must PASS. One FAIL fails the dimension, and
105
+ since this is the only enabled dimension by default, one FAIL fails the task. There is no
106
+ partial credit and no halo effect: a beautiful, fast, working-90% build with one broken
107
+ AC is a FAIL. This bluntness is intentional — it is the antidote to lenient self-grading.
108
+
109
+ N/A criteria (e.g. contract criteria on a contractless UI task) are excluded from the
110
+ denominator; they are never counted as PASS to pad the result.
111
+
112
+ ## Bug template
113
+
114
+ ```
115
+ severity: [critical|major|minor]
116
+ critical = a Done-when or AC central to the feature does not work
117
+ major = a secondary AC fails, or a contract field/error is mishandled
118
+ minor = a non-go breach or layer leak with no user-visible effect (still a FAIL)
119
+ criterion: [SC-AC | SC-DONE-WHEN | SC-REQ | SC-RES | SC-ERR | SC-NONGO | SC-LAYER]
120
+ location: <file:line | endpoint | screen+element>
121
+ repro: <exact steps or command that produced the evidence>
122
+ expected: <quoted from the AC / Done-when / contract table>
123
+ actual: <observed evidence: output excerpt, console error, or DB state>
124
+ fix_hint: <optional — the wiring point the generator should look at>
125
+ ```
126
+
127
+ ## Probing notes specific to this dimension
128
+ - Prefer driving the **running** app over reading code. The classic failure (from the
129
+ harness blog) is code that looks correct but whose wiring is broken with no surface
130
+ signal — only exercising it catches that.
131
+ - When an AC's literal text is satisfied but behavior is not (a button exists but does
132
+ nothing), FAIL `SC-AC` and localize the dead wiring to file:line.
133
+ - For `SC-DONE-WHEN`, reproduce the PO's described outcome end to end; a "Done when" is a
134
+ user-acceptance statement, so verify it as a user would.
@@ -0,0 +1,110 @@
1
+ ---
2
+ id: tdd-surface
3
+ title: "TDD surface"
4
+ enabled: true
5
+ weight: 1.0
6
+ hard_threshold: no-critical
7
+ applies_to:
8
+ lens: [lite, standard]
9
+ package: any
10
+ variant: any
11
+ requires_browser: false
12
+ ---
13
+
14
+ # TDD Surface Dimension
15
+
16
+ **Why this exists.** `spec-conformance` answers "does the built behavior match the spec?"
17
+ It does not answer "did the build produce regressions, and is the new code actually tested?"
18
+ An implementation can be spec-conformant and still fragile — passing all AC manually but
19
+ having zero automated tests, or silently deleting tests that used to catch a class of bugs.
20
+ This dimension adds the discipline layer: the evaluator refuses a PASS unless the test
21
+ suite is green and new code carries test coverage.
22
+
23
+ **TDD in this context** means: tests exist alongside production code, they actually run,
24
+ they stay green after the change, and they exercise the AC behaviors — not just internal
25
+ wiring. The classic failure mode is a PR that passes `pnpm typecheck` but deletes or
26
+ skips the one test that would have caught the regression.
27
+
28
+ **`.e2e` variant:** the e2e suite *is* the tests. TDD-2 (companion file check) is N/A
29
+ and excluded from the denominator; TDD-1 (suite passes) still applies and is redundant
30
+ with `SC-AC` — dual enforcement is intentional for e2e tasks.
31
+
32
+ ---
33
+
34
+ ## Criteria
35
+
36
+ ```yaml
37
+ - id: TDD-1
38
+ statement: "The package test suite runs green — non-zero test count, no failing tests."
39
+ probe: cmd
40
+ evidence_required: true
41
+ pass_rule: >
42
+ Run `pnpm --filter <pkg> test` (or the equivalent runner for the package). The command
43
+ exits 0. The output shows ≥1 test executed (zero tests = no coverage = FAIL, not a skip).
44
+ Capture stdout + exit code as evidence. A suite that is skipped entirely or that has
45
+ no test files is a FAIL at `critical` — "tests pass" is vacuously true with no tests,
46
+ and that vacuous truth is worse than a failure.
47
+ source: task
48
+
49
+ - id: TDD-2
50
+ statement: "Each new non-trivial source file introduced by this task has a companion test file."
51
+ probe: static
52
+ evidence_required: true
53
+ pass_rule: >
54
+ List all `.ts`/`.tsx` files added (not modified) by this task, excluding test files
55
+ themselves (`*.test.ts`, `*.spec.ts`, `__tests__/`), type-only files (`*.d.ts`), and
56
+ index/barrel files (`index.ts` whose sole content is re-exports). For each remaining
57
+ file, a companion test file must exist: either co-located (`foo.test.ts` next to `foo.ts`)
58
+ or in the package's test directory pointing at it. A new service or use-case with zero
59
+ test coverage → FAIL at `critical`. A new utility under 20 lines → FAIL at `major` (still
60
+ needs a test, just lower severity). Do not credit test files that were deleted or emptied
61
+ as part of this task.
62
+ source: code
63
+
64
+ - id: TDD-3
65
+ statement: "Tests target AC behaviors, not just internal structure — each key AC scenario has a corresponding test case."
66
+ probe: static
67
+ evidence_required: false
68
+ pass_rule: >
69
+ Read the test files covering the task's new code. For each `[cmd]` or `[data]` AC that
70
+ passed spec-conformance, verify that a test case exercises that exact scenario (not just
71
+ that the function is imported). Tests that only call `expect(result).toBeDefined()` or
72
+ only test constructor/initialization do NOT count. A gap between AC scenarios and test
73
+ scenarios is a `minor` finding — advisory, does not fail the dimension. evidence_required
74
+ is false: a spec with no discoverable test gap simply yields no TDD-3 finding.
75
+ source: code
76
+ ```
77
+
78
+ ---
79
+
80
+ ## Threshold
81
+
82
+ `no-critical` — TDD-1 (suite green) and TDD-2 (companion files) are `critical` FAILs:
83
+ a build with no passing tests or no test coverage is not done regardless of how well it
84
+ scores on `spec-conformance`. TDD-3 (AC-scenario alignment) is advisory (`minor`) and
85
+ does not block — it is a quality signal for the generator, not a gating condition.
86
+
87
+ ---
88
+
89
+ ## Bug template
90
+
91
+ ```
92
+ severity: [critical|major|minor]
93
+ criterion: [TDD-1|TDD-2|TDD-3]
94
+ location: <package path | file:line | test file path>
95
+ repro: <command run — e.g. "pnpm --filter api test" | "find src/modules/canvas -name '*.ts' ! -name '*.test.ts'">
96
+ expected: <e.g. "test suite passes with ≥1 test" | "companion test file for BoardService.ts">
97
+ actual: <e.g. "exit code 1; 2 failing tests" | "no BoardService.test.ts found anywhere in packages/api/">
98
+ fix_hint: <e.g. "add __tests__/BoardService.spec.ts; cover the createBoard and getBoard use cases">
99
+ ```
100
+
101
+ ## Probing notes
102
+
103
+ - Run `pnpm --filter <pkg> test` (or `pnpm --filter <pkg> test:unit` if scripts are split).
104
+ Capture the full output. Most Jest/Vitest outputs emit `Tests: N passed` and an exit code.
105
+ - For TDD-2, `git diff --name-only --diff-filter=A HEAD~1` (or the relevant base) lists
106
+ added files. Use `find <pkg>/src -name '*.ts'` if the git range is unclear; then diff
107
+ against `find <pkg>/src -name '*.test.ts' -o -name '*.spec.ts'` to spot uncovered modules.
108
+ - Never skip TDD-1 because the test suite "probably hasn't changed." Always run it. Wiring
109
+ changes in one module routinely break tests in another — that is the exact regression
110
+ class this gate exists to catch.
@@ -0,0 +1,100 @@
1
+ ---
2
+ id: test-surface-conformance
3
+ title: "Test surface conformance"
4
+ enabled: false
5
+ weight: 1.0
6
+ hard_threshold: all-pass
7
+ applies_to:
8
+ lens: [lite, standard]
9
+ package: any
10
+ variant: any
11
+ requires_browser: true
12
+ ---
13
+
14
+ # Test Surface Conformance Dimension
15
+
16
+ > **Auto-enable rule (read at GATE V0.5):** stays `enabled: false` by default — a no-op on
17
+ > every spec generated before `ba-pitch-analyzer` v2.9. The core flips it ON for a run
18
+ > **only when** the spec's `usecases/` contains at least one `## Test Surface` section
19
+ > (fresh v2.9 spec, or a pre-v2.9 spec retrofitted via a retrofit-surface order). Pre-surface
20
+ > specs → never activates → existing verdicts unchanged (non-regression guarantee).
21
+ > Explicit `--dimensions ...,test-surface-conformance` always wins over the auto rule.
22
+
23
+ **Why this exists.** `spec-conformance` grades the AC that were written; it does not
24
+ *expand* them. The QA meeting (2026-06-11) located the gap: nobody systematically derives
25
+ the test matrix — boundary values, negative cases, error-code coverage, no-go breaches —
26
+ that the spec already implies. The BA now derives that matrix into each UC's
27
+ `## Test Surface` (D1 Invariants · D2 Error Cases · D3 Contract shapes · D4 No-gos,
28
+ mechanical-only); this dimension is the judge-side half: probe every derived row against
29
+ the running app. Judge probes; it never authors rows — a missing or thin Test Surface is
30
+ reported as a finding and routed back to the planner's retrofit-surface operation, never filled in here.
31
+
32
+ **Distinctions held:**
33
+ - conformance = *the AC that were written pass* · test-surface = *the matrix the spec
34
+ implies passes* · completeness = *the tasks that must exist, do exist*.
35
+ - This dimension covers **derivable** tests only. Exploratory edges (concurrency, state
36
+ interruption, cross-UC journeys, data residue) belong to `/qa-edge-hunter`, which runs
37
+ post-PASS and reads this run's `EVAL-*.md` as its negative-space input — every TS row
38
+ probed here is territory QA must NOT re-hunt. Recording probed rows in the report is
39
+ therefore part of this dimension's contract, not optional logging.
40
+
41
+ ---
42
+
43
+ ## Criteria
44
+
45
+ - id: TSC-1
46
+ statement: "Every row in every UC `## Test Surface` table passes its Probe with the stated Expect, evidence captured."
47
+ probe: ui
48
+ evidence_required: true
49
+ pass_rule: >
50
+ For each TS-* row across usecases/: execute the Probe via the handler its phrasing
51
+ implies (API/data probes → cmd/data; screen-level → ui) and compare observed behavior
52
+ to Expect. Side-effect clauses ("no side effect", "state unchanged") MUST be verified
53
+ by a data probe, not assumed from the response code. Zero failing rows → PASS. Any
54
+ failing row → FAIL at `critical` (a derived case the spec itself implies is broken).
55
+ Rows whose probe cannot run (endpoint absent, screen unreachable) are FAILs, not skips
56
+ — absence of evidence is a FAIL.
57
+ source: code
58
+
59
+ - id: TSC-2
60
+ statement: "The Test Surface is internally complete against its own sources: every [INV-NN] has a TS-INV-NN row; every Error Cases code has a TS-ERR-* row; rows cite D1–D4."
61
+ probe: static
62
+ evidence_required: true
63
+ pass_rule: >
64
+ Cross-check each UC: Invariants ↔ TS-INV rows, Error Cases codes ↔ TS-ERR rows, and
65
+ every row's Source cites D1–D4. A UC with `## Test Surface` whose own sources are
66
+ uncovered → FAIL at `major` with `next: retrofit-surface order (ba)` (judge surfaces the gap;
67
+ generator fills it — this dimension NEVER authors rows). A UC carrying the explicit
68
+ empty-sources line passes TSC-2 vacuously. A v2.9+ spec UC with NO `## Test Surface`
69
+ section at all → FAIL at `major`, same routing.
70
+ source: code
71
+
72
+ ---
73
+
74
+ ## Threshold
75
+
76
+ `all-pass` — TSC-1 failures are correctness failures of behavior the spec itself derives;
77
+ leniency here is leniency on the spec. TSC-2 `major` findings also block (the surface must
78
+ be trustworthy before QA subtracts it as covered territory), but their fix is a planner
79
+ retrofit-surface re-run, not a build round — the bug template's `next:` field routes them.
80
+
81
+ ---
82
+
83
+ ## Bug template
84
+
85
+ ```
86
+ severity: [critical|major]
87
+ criterion: [TSC-1|TSC-2]
88
+ location: [usecases/UC-Name.md#Test-Surface TS-ID | endpoint | screen]
89
+ ts_row: <the full row probed, verbatim>
90
+ repro: <probe executed — command / UI steps>
91
+ expected: <the Expect cell>
92
+ actual: <observed evidence — response, state, screenshot ref>
93
+ next: <TSC-1 → task-executor fix via tech-lead round r+1 | TSC-2 → retrofit-surface order re-run>
94
+ ```
95
+
96
+ ## Report obligation (the QA handoff)
97
+
98
+ The EVAL report section for this dimension MUST list every TS row probed (PASS and FAIL),
99
+ keyed `UC-id / TS-id`. `/qa-edge-hunter` Phase Q1 subtracts exactly this list when building
100
+ charters — an unlisted probe is invisible to QA and will be wastefully re-hunted.
@@ -0,0 +1,177 @@
1
+ # Probing (Phase A)
2
+
3
+ How to collect evidence by criterion `probe` type and by task variant. Default to the
4
+ running app over reading source.
5
+
6
+ ## Browser mode: prefer CLI over MCP
7
+ For `[ui]` criteria, drive the browser via the Playwright **CLI**, not the MCP server, by
8
+ default. The CLI saves accessibility snapshots as files on disk and the agent reads them
9
+ on demand; MCP streams the full accessibility tree into context every step. The CLI path
10
+ uses roughly 4x fewer tokens for the same work, and the Playwright team recommends it for
11
+ coding agents specifically. Use `--browser mcp` only in a sandboxed environment where the
12
+ CLI's filesystem access isn't available.
13
+
14
+ Both paths read the browser's **accessibility tree**, not screenshots — structured
15
+ role/label/state per element, no vision model needed. That is what makes the verdict
16
+ localizable: a missing or dead element shows up as a tree node, then read the source to
17
+ pin file:line.
18
+
19
+ **Lazy preflight — run this check only when the spec actually contains a `[ui]` criterion,
20
+ at the moment you reach the first one.** Playwright is NOT an install-time prerequisite of the
21
+ harness; a run with no `[ui]` criteria must complete on a machine with no browser installed.
22
+
23
+ ```
24
+ npx --no-install playwright --version || <missing>
25
+ ```
26
+
27
+ If the CLI or the chromium binary is missing, FAIL the probe (not the whole run) with an
28
+ actionable message that names the criterion that needed it and the fix:
29
+
30
+ > `[ui]` criterion <UC/AC id> requires a browser to verify. Run `npx playwright install chromium`,
31
+ > then re-run the eval. (For MCP mode, also `claude plugin install playwright@claude-plugins-official`.)
32
+
33
+ Never auto-install a browser mid-eval, and never silently skip the criterion — a `[ui]` AC
34
+ without a probe is a FAIL with reason "unverifiable: no browser", not a PASS.
35
+
36
+ ```
37
+ The probe loop per [ui] criterion:
38
+ 1. navigate to the screen under test
39
+ 2. snapshot the accessibility tree → save to evaluation/.evidence/<task>-<crit>.txt
40
+ 3. perform the action the criterion describes (click/type/submit)
41
+ 4. snapshot again; diff state; capture any console error
42
+ 5. record: element observed, state before/after, console output, and — if broken —
43
+ the source file:line where the handler/wiring fails
44
+ ```
45
+
46
+ ## Oracle dispatch (evaluation contract — Stage G)
47
+
48
+ Each criterion / Test-Surface row carries an `oracle` tag — the dispatch key that declares *how*
49
+ this criterion is verified. **Dispatch on it to choose the probe mechanism; default to `ui` when
50
+ the tag is absent** (web pitches are unchanged). The single-judge invariant is untouched — one
51
+ verdict per criterion, evidence-or-FAIL — the oracle changes only *how* evidence is gathered, never
52
+ *who* decides.
53
+
54
+ For every non-`ui` oracle you gather evidence by **running the deliverable yourself** (the Bash
55
+ tool) and grading its *observed* output against the criterion's `expect`. Treat each criterion as a
56
+ small declarative `{ id, desc, probe, expect }` row and grade it directly; never grep source in
57
+ place of running it. A probe that throws, cannot spawn, or cannot reach the deliverable is a
58
+ **FAIL** (absence of evidence), never a silent pass.
59
+
60
+ | `oracle` | Deliverable | Probe procedure — run it, cite the observed output | Evidence to record |
61
+ |---|---|---|---|
62
+ | `ui` *(default)* | running web app | Playwright CLI loop (above) | a11y-tree node, state before/after, console |
63
+ | `process` | CLI / script | spawn the binary with the criterion's `argv` in a **throwaway temp dir** (never the real cwd), seeded with any required store/fixture via env; read exit + stdout/stderr | exit code + stdout/stderr + crash check |
64
+ | `test` | library / module | run the project's own test command; parse the summary line | suite exit + executed-test count + failing-test names |
65
+ | `snapshot` | generator / pure refactor | run the deliverable, capture stdout, diff it against the agreed golden output | unified diff (empty = PASS) |
66
+ | `http` | service / API | start the server on a free port, wait until it answers, send the request, assert; tear it down | status code + response body/JSON |
67
+
68
+ **Per-oracle `probe`/`expect` shape (author it inline, one row per criterion):**
69
+ - `process` — `probe: { argv, store }`, `expect: { exit, stdout, no_crash }`. Sandbox in a temp
70
+ dir + controlled env + a timeout so corrupted-input / missing-file probes cannot touch user data.
71
+ - `test` — `probe: { cmd }`, `expect: { exit, min_tests, no_failures }`. **A suite that runs zero
72
+ tests is a FAIL** (matches TDD-1 below): a suite that runs nothing is not green.
73
+ - `snapshot` — `probe: { argv }` + an agreed `golden` (normalize trailing whitespace + the final
74
+ newline so a benign EOL diff is not a false FAIL).
75
+ - `http` — `server: { cmd, ready_path }` + `probe: { method, path, json }`, `expect: { status,
76
+ body, json }`. An unreachable server FAILs **every** criterion (a service you cannot reach does
77
+ not pass).
78
+
79
+ **Shared `expect` grammar:** `exit`/`status` accept a number or a comparison string (`==0`, `!=0`,
80
+ `>=200`, `<500`, or `*` = any); `stdout`/`stderr`/`body` accept `/regex/flags` matched against the
81
+ observed output; `no_crash: true` requires no stack-trace/panic signature; `json` is a subset match
82
+ on the parsed response body.
83
+
84
+ The `ba` Test Surface emits the `oracle` per row; for a non-UI deliverable the rows are already
85
+ tagged `process`/`test`/`snapshot`/`http`, so do not fall back to driving a browser that does not
86
+ exist.
87
+
88
+ ## By probe type
89
+ - `cmd` — run the command the AC implies (`pnpm --filter <pkg> test`, `pnpm typecheck`,
90
+ `curl` against a running endpoint, `migration up && migration down`). Capture stdout,
91
+ stderr, exit code. Non-zero exit or failing assertion = evidence of FAIL. (Backs the `test`,
92
+ `snapshot`, and `http` oracles.)
93
+ - `ui` — Playwright CLI loop above. (Backs the `ui` oracle.)
94
+ - `data` — query the DB / inspect storage after the action; capture the actual row/state
95
+ and compare to what the criterion expects.
96
+ - `static` — read the diff / changed files (for `SC-NONGO`, `SC-LAYER`, secret scans,
97
+ TDD companion-file checks, integration test setup inspection). Use sparingly; never
98
+ substitute a code read for exercising behavior an AC describes.
99
+
100
+ ## TDD probing (for `tdd-surface` dimension)
101
+
102
+ **TDD-1 (suite green):** Run `pnpm --filter <pkg> test` and capture the full output.
103
+ Most Jest/Vitest runs emit something like `Tests: 4 passed, 0 failed` on the last line.
104
+ Non-zero exit = FAIL. Zero tests executed = FAIL (a suite that runs nothing is not a green
105
+ suite). Save the raw output to `evaluation/.evidence/<task>-TDD-1.txt`.
106
+
107
+ **TDD-2 (companion files):** List files added by this task:
108
+ ```bash
109
+ git diff --name-only --diff-filter=A HEAD~1 # files added; adjust base ref as needed
110
+ ```
111
+ Filter to source files (`.ts`, `.tsx`) excluding `*.test.ts`, `*.spec.ts`, `*.d.ts`, and
112
+ index/barrel-only files. For each remaining file, check whether a companion test file
113
+ exists either co-located or in the package's `__tests__/` or `test/` directory:
114
+ ```bash
115
+ # example check for a specific module
116
+ find <pkg>/src -name 'BoardService.test.ts' -o -name 'BoardService.spec.ts'
117
+ ```
118
+ Record the missing companions as evidence for TDD-2 FAILs.
119
+
120
+ **TDD-3 (AC-scenario alignment, advisory):** Read the test file for the main new module.
121
+ Look for test cases that match the AC scenario descriptions. Tests that only call
122
+ `expect(result).toBeDefined()` or only exercise the constructor do not count.
123
+ This is a static read; no running required. Record whether each key AC has a matching test.
124
+
125
+ ## Integration probing (for `integration` dimension)
126
+
127
+ **Finding integration test files:** Check for files matching `*.integration.spec.ts`,
128
+ `*.e2e-spec.ts`, or a top-level `test/` directory in the package. Also inspect
129
+ `package.json` scripts for `test:e2e`, `test:int`, or `test:integration` targets.
130
+
131
+ **INT-1 (no mocks):** After locating integration test files for the task's feature:
132
+ ```bash
133
+ grep -rn "jest\.mock\|vi\.mock" <integration-test-file>
134
+ ```
135
+ Mocking HTTP clients, email senders, or third-party APIs is acceptable. Mocking
136
+ `PrismaClient`, a repository class, or the database connection defeats integration testing.
137
+ Then run the integration suite: `pnpm --filter <pkg> test:e2e` (or equivalent). Capture
138
+ exit code and test count.
139
+
140
+ **INT-2 (auth boundary):** Locate the test case exercising the unauthorized path. Inspect
141
+ its setup: it should create a different user's JWT (or use no auth) and assert a 403 or
142
+ empty-set response. Capture the test body and the run output as evidence.
143
+
144
+ **INT-3 (RLS-JWT pattern + pooler port):**
145
+ ```bash
146
+ # Check for set_config call in test setup or helper
147
+ grep -rn "set_config\|request\.jwt\.claims" <test-setup-files>
148
+
149
+ # Check connection string in test env
150
+ grep "DATABASE_URL" .env.test apps/api/.env.test
151
+ ```
152
+ The `DATABASE_URL` must end with `:6543/...` (transaction-mode pooler). If no `.env.test`
153
+ exists, check `jest.config.ts` or `globalSetup` for a `DATABASE_URL` override. A missing
154
+ `set_config` call means queries run without RLS — false-positive auth passing silently.
155
+
156
+ ## By task variant
157
+ - `.be` — no browser (`--browser none`). Start the API; send contract-shaped requests;
158
+ assert Response + Error tables; run the package test suite. Evidence = request/response
159
+ transcripts + test output.
160
+ - `.shared` — usually `cmd` only: typecheck + unit tests on the shared package; verify
161
+ contract types compile and match the tables.
162
+ - `.web` — Playwright CLI against the running web app for `SC-AC` and `SC-DONE-WHEN`.
163
+ - `.mobile` — Playwright does not drive a native RN app. Options: probe via the platform's
164
+ e2e tool (Detox / Maestro) if present; otherwise mark the `[ui]` criteria `[manual]` at
165
+ GATE V1 and require an explicit user check (or `--strict` to FAIL them). Do not fake UI
166
+ evidence for native screens.
167
+ - `.e2e` — run the existing end-to-end suite; green suite is the evidence for `SC-AC`.
168
+
169
+ ## App must be reachable before grading
170
+ If the run command does not produce a reachable app, that is not "untestable" — it is a
171
+ **FAIL** of every `[ui]`/`[data]` criterion under `NO EVIDENCE`, plus a critical bug:
172
+ "app does not start with the stated run command." A build you cannot run does not pass.
173
+
174
+ ## Evidence storage
175
+ Write raw evidence under `.shapeup/<slug>/evaluation/.evidence/` and reference it by path in the report.
176
+ Keep the report itself readable; the evidence files are the audit trail the generator and
177
+ the user can open.