valent-pipeline 0.19.52 → 0.19.54
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/package.json
CHANGED
|
@@ -2076,6 +2076,25 @@ async function runStory(story) {
|
|
|
2076
2076
|
if (has('uxa')) {
|
|
2077
2077
|
await spawn('UXA', 'uxa.md', 'Translate the brief into uxa-spec.md.', { phase: 'Spec' })
|
|
2078
2078
|
}
|
|
2079
|
+
// Fix D (rework-reduction, 2026-06-24): QA-A proves its acceptance suite is honestly RED BEFORE
|
|
2080
|
+
// handoff, instead of the RED gate discovering a premature-pass a cycle later — after the dev
|
|
2081
|
+
// fan-out is already staged (the 2.29 class: 10 cycles, an escalation, a build break, zero
|
|
2082
|
+
// implementation burned). The lever mirrors the dev pre-handoff self-gate (Fix #3): thread the
|
|
2083
|
+
// SAME acceptance command the RED gate will run into QA-A's authoring turn so it self-checks in
|
|
2084
|
+
// context. Deliberately the RAW command (not the `evidence run` wrapper) — QA-A only needs to
|
|
2085
|
+
// OBSERVE pass/fail, and minting a labeled `acceptance` assert here would shadow the baseline the
|
|
2086
|
+
// RED/green/evidence gates freeze against. The RED gate stays the mechanical backstop. atddEnabled
|
|
2087
|
+
// + args only => journal-replay safe.
|
|
2088
|
+
const qaaRedSelfCheck = atddEnabled
|
|
2089
|
+
? ` Then prove the suite is honestly RED before handoff (Fix D — shift-left the RED gate): run ` +
|
|
2090
|
+
`\`${subCmd(atddCommandTpl, storyId, effectiveWorkspaces)}\` against the current (unimplemented) tree. ` +
|
|
2091
|
+
`Every \`required: true\` case MUST run and FAIL for a behavioral reason (404 / empty / missing element) — ` +
|
|
2092
|
+
`exactly what the RED gate will demand. A required case that PASSES now is a premature-pass spec bug: ` +
|
|
2093
|
+
`re-target it to assert a NEW endpoint/element this story has not built yet, or — if it only guards an ` +
|
|
2094
|
+
`already-established infrastructure invariant — mark it \`required: false\` ` +
|
|
2095
|
+
`(steps/qa-a/write-acceptance-tests.md Step C), never weakening or deleting the guard. Fix every ` +
|
|
2096
|
+
`premature-pass before handoff so the RED gate passes first-try.`
|
|
2097
|
+
: ''
|
|
2079
2098
|
await spawn('QA-A', 'qa-a.md',
|
|
2080
2099
|
'Produce qa-test-spec.md before any code is written.' +
|
|
2081
2100
|
(atddEnabled
|
|
@@ -2083,7 +2102,7 @@ async function runStory(story) {
|
|
|
2083
2102
|
`under ${atddDir}/${storyId}/ — one+ per AC, TC id in the test title, black-box against the running system, ` +
|
|
2084
2103
|
`no mocks — plus the manifest kind:"acceptance"/testFile/files[] fields. The prose spec is companion notes. ` +
|
|
2085
2104
|
`Then self-attack your tests (steps/qa-a/self-attack.md) and fix what you find before handoff.`
|
|
2086
|
-
: ''),
|
|
2105
|
+
: '') + qaaRedSelfCheck,
|
|
2087
2106
|
{ phase: 'Spec' })
|
|
2088
2107
|
|
|
2089
2108
|
phase('SpecCheck')
|
|
@@ -2115,10 +2134,21 @@ async function runStory(story) {
|
|
|
2115
2134
|
// the round-trip cost and the rework-cycle count. Same preCriticChecks the gate runs; the
|
|
2116
2135
|
// skip-waiver / spec-conformance rules are always named. Static + args only => journal-replay safe.
|
|
2117
2136
|
const preHandoffStaticCmds = preCriticChecks.map((c) => subCmd(c, storyId, effectiveWorkspaces))
|
|
2118
|
-
|
|
2137
|
+
// Fix #3 (rework-reduction, 2026-06-24): the pre-CRITIC gate ALSO runs spec-conformance + trace check
|
|
2138
|
+
// (runPreCriticGate below), but the dev was only TOLD the rules, never handed the commands to run them.
|
|
2139
|
+
// The field's `rework after static` round-trips were test files with a dropped assertion target / a
|
|
2140
|
+
// missing AC trace-id / a mis-placed waiver — all catchable by running these two CLIs in the build turn.
|
|
2141
|
+
// Thread the SAME commands the gate runs into the self-gate so the dev catches them in-context (no
|
|
2142
|
+
// re-spawn). Static + args only => journal-replay safe.
|
|
2143
|
+
const preHandoffSpecCmds = [
|
|
2144
|
+
...(specConformanceEnabled ? [`node .valent-pipeline/bin/cli.js check-spec-conformance --story ${storyId}`] : []),
|
|
2145
|
+
...(traceCheckEnabled ? [`node .valent-pipeline/bin/cli.js trace check --story ${storyId}`] : []),
|
|
2146
|
+
]
|
|
2147
|
+
const preHandoffNote = (preHandoffStaticCmds.length || preHandoffSpecCmds.length)
|
|
2119
2148
|
? '\n\n## Definition of done — run these BEFORE you write your handoff\n' +
|
|
2120
2149
|
'The deterministic pre-CRITIC gate runs the moment you hand off; a failure costs a full rework cycle (a re-spawn). Pass them first-try:\n' +
|
|
2121
2150
|
preHandoffStaticCmds.map((c) => ` - \`${c}\` — must exit 0 (lint / type / static).\n`).join('') +
|
|
2151
|
+
preHandoffSpecCmds.map((c) => ` - \`${c}\` — must exit 0 (spec-conformance / trace: catches a dropped assertion target, an omitted spec\'d case, a missing AC trace-id, or an un-waived skip BEFORE the gate round-trips you).\n`).join('') +
|
|
2122
2152
|
' - Every deliberately skipped or pending test MUST carry an inline `// valent-waiver: <reason>` (on the skip line or in the test name) — an un-waived skip is rejected by the spec-conformance check.\n' +
|
|
2123
2153
|
' - Do NOT drop a spec\'d assertion target or omit a spec\'d case to make a suite pass.\n' +
|
|
2124
2154
|
'Run them locally, fix EVERYTHING they flag, and only then write your handoff — this is part of the build, not the gate\'s job to find for you.'
|
|
@@ -12,3 +12,15 @@ Probe each acceptance case as the laziest implementer who wants green with minim
|
|
|
12
12
|
- **Implementation sniffing (ATDD):** the dev can read your tests. Avoid magic fixture values an implementation could special-case; randomize or parameterize identifying data where cheap. (CRITIC's acceptance pass audits the implementation side of this.)
|
|
13
13
|
|
|
14
14
|
Rate residual gameability **low | medium | high** per AC. HIGH means you have not finished — strengthen the test and re-rate. Record the final ratings + what you hardened in `qa-test-spec.md#self-attack` so CRITIC and JUDGE see what was already attacked.
|
|
15
|
+
|
|
16
|
+
## Prove the suite is RED before handoff (ATDD)
|
|
17
|
+
|
|
18
|
+
This is the mechanical close-out, run AFTER the gameability pass above. The orchestrator hands you the exact acceptance command to run — execute it against the current, **unimplemented** tree and read the result:
|
|
19
|
+
|
|
20
|
+
- **Every `required: true` case MUST run and FAIL for a behavioral reason** — a 404, an empty/absent response, a missing element. That is precisely what the RED gate checks a cycle later; proving it here means the gate passes first-try instead of bouncing your spec back after the dev fan-out is already staged.
|
|
21
|
+
- **A `required: true` case that PASSES now is a premature-pass spec bug.** It does not assert anything this story builds — it asserts behavior that already exists. Two fixes, both before handoff:
|
|
22
|
+
- **Re-target it** so it asserts a NEW endpoint/element/field this story has not built yet (e.g. route the assertion through a new path that 404s until implemented). This is the right fix when the case is meant to prove new behavior.
|
|
23
|
+
- **Or mark it `required: false`** (write-acceptance-tests.md Step C) when it only guards an already-established infrastructure invariant — still executed and asserted at the GREEN gate, but exempt from the red-required set. **Never weaken or delete the guard** — just make red honest.
|
|
24
|
+
- A required case that **errors for a non-behavioral reason** (import failure, harness misconfig, syntax) is not honest red either — fix the test so it fails *because the feature is absent*, not because it cannot run.
|
|
25
|
+
|
|
26
|
+
Do not hand off while any `required: true` case passes against the unimplemented tree. The RED gate will dead-end the story if you do; catching it here costs one self-run instead of a full round-trip.
|