valent-pipeline 0.6.0 → 0.6.1
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
|
@@ -392,11 +392,14 @@ if (!validation.valid) {
|
|
|
392
392
|
// before its dependent) and sprint.workflow.js runs the batch SEQUENTIALLY in array order on a
|
|
393
393
|
// shared branch — so a dependent must not precede its prerequisite. This is what lets a dependency
|
|
394
394
|
// chain ship together in one sprint.
|
|
395
|
+
// `groomed: true` — these stories were fully specced + passed the READINESS gate during grooming
|
|
396
|
+
// above, and their reqs-brief/uxa-spec/qa-test-spec are on disk. sprint.workflow.js reads this flag
|
|
397
|
+
// and SKIPS its Spec + Readiness phases, so execution doesn't redundantly re-spec and re-gate.
|
|
395
398
|
const sizedById = new Map(sizedStories.map((s) => [s.storyId, s]))
|
|
396
399
|
const plannedStories = pack.sprint_stories
|
|
397
400
|
.map((id) => sizedById.get(id))
|
|
398
401
|
.filter(Boolean)
|
|
399
|
-
.map((s) => ({ storyId: s.storyId, projectType: s.projectType, profiles: s.profiles }))
|
|
402
|
+
.map((s) => ({ storyId: s.storyId, projectType: s.projectType, profiles: s.profiles, groomed: true }))
|
|
400
403
|
|
|
401
404
|
return {
|
|
402
405
|
sprintId,
|
|
@@ -33,8 +33,15 @@
|
|
|
33
33
|
* their structured returns.
|
|
34
34
|
*
|
|
35
35
|
* args (either form):
|
|
36
|
-
* { stories: [{ storyId, projectType?, profiles? }, ...], projectType?, profiles?, maxRejectionCycles?, models?, reasoning? }
|
|
37
|
-
* { storyId, projectType, profiles?, maxRejectionCycles?, models?, reasoning? } // single-story (back-compat)
|
|
36
|
+
* { stories: [{ storyId, projectType?, profiles?, groomed? }, ...], projectType?, profiles?, preGroomed?, maxRejectionCycles?, models?, reasoning? }
|
|
37
|
+
* { storyId, projectType, profiles?, groomed?, maxRejectionCycles?, models?, reasoning? } // single-story (back-compat)
|
|
38
|
+
*
|
|
39
|
+
* `groomed` (per story) / `preGroomed` (batch-wide): the story was already specced + passed the
|
|
40
|
+
* READINESS gate during sprint planning (plan.workflow.js sets groomed:true on every story it
|
|
41
|
+
* returns), and its reqs-brief/uxa-spec/qa-test-spec are on disk. When true, this script SKIPS its
|
|
42
|
+
* Spec + Readiness phases and goes straight to Build — re-running them would be duplicated token
|
|
43
|
+
* spend. The standalone single-story path (valent-run-story-workflow) omits it, so an un-groomed
|
|
44
|
+
* story still gets Spec + Readiness here.
|
|
38
45
|
*
|
|
39
46
|
* `models` is the pipeline-config.yaml `models` tier->roles map (e.g. { opus:[...], sonnet:[...],
|
|
40
47
|
* haiku:[...] }); the invoking skill passes it through so per-agent model tiers stay config-driven
|
|
@@ -196,8 +203,9 @@ const batch = Array.isArray(a.stories) && a.stories.length
|
|
|
196
203
|
storyId: s.storyId,
|
|
197
204
|
projectType: s.projectType || a.projectType,
|
|
198
205
|
profiles: s.profiles || a.profiles || [],
|
|
206
|
+
groomed: s.groomed === true || a.preGroomed === true,
|
|
199
207
|
}))
|
|
200
|
-
: [{ storyId: a.storyId, projectType: a.projectType, profiles: a.profiles || [] }]
|
|
208
|
+
: [{ storyId: a.storyId, projectType: a.projectType, profiles: a.profiles || [], groomed: a.groomed === true || a.preGroomed === true }]
|
|
201
209
|
|
|
202
210
|
const maxRejectionCycles = a.maxRejectionCycles ?? 5
|
|
203
211
|
|
|
@@ -374,7 +382,7 @@ async function runIntegrationGate(shipped) {
|
|
|
374
382
|
// runStory: the per-story pipeline (kept inline, not a nested workflow(), so the single
|
|
375
383
|
// workflow() nesting level stays free for plan/retro — see reimplementation-plan §5b).
|
|
376
384
|
async function runStory(story) {
|
|
377
|
-
const { storyId, projectType, profiles } = story
|
|
385
|
+
const { storyId, projectType, profiles, groomed } = story
|
|
378
386
|
const profilesCsv = profiles.join(',')
|
|
379
387
|
|
|
380
388
|
phase('Resolve')
|
|
@@ -417,22 +425,30 @@ async function runStory(story) {
|
|
|
417
425
|
model: opts.model || modelFor(role),
|
|
418
426
|
})
|
|
419
427
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
'
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
428
|
+
// Spec + Readiness are SKIPPED for pre-groomed stories. plan.workflow.js already specced them
|
|
429
|
+
// (reqs-brief/uxa-spec/qa-test-spec are on disk) and passed the READINESS gate at planning time,
|
|
430
|
+
// so re-running here is duplicated token spend. The standalone single-story path leaves `groomed`
|
|
431
|
+
// false, so an un-groomed story still gets fully specced + gated before Build.
|
|
432
|
+
if (groomed) {
|
|
433
|
+
log(`${storyId}: pre-groomed at sprint planning — skipping Spec + Readiness (specs on disk, readiness already passed)`)
|
|
434
|
+
} else {
|
|
435
|
+
phase('Spec')
|
|
436
|
+
await spawn('REQS', 'reqs.md', 'Analyze the story and produce reqs-brief.md.', { phase: 'Spec' })
|
|
437
|
+
if (has('uxa')) {
|
|
438
|
+
await spawn('UXA', 'uxa.md', 'Translate the brief into uxa-spec.md.', { phase: 'Spec' })
|
|
439
|
+
}
|
|
440
|
+
await spawn('QA-A', 'qa-a.md', 'Produce qa-test-spec.md before any code is written.', { phase: 'Spec' })
|
|
441
|
+
|
|
442
|
+
phase('Readiness')
|
|
443
|
+
await runGate(storyId, 'READINESS', 'readiness.md', 'Validate the spec chain (reqs/uxa/qa) is implementation-ready.',
|
|
444
|
+
'Readiness', (verdict) => {
|
|
445
|
+
const target = verdict.rejectionTarget || 'REQS'
|
|
446
|
+
return spawn(target, `${target.toLowerCase()}.md`, 'Address the READINESS rejection and rewrite the affected spec.', {
|
|
447
|
+
label: `rework:${target.toLowerCase()}:${storyId}`,
|
|
448
|
+
phase: 'Readiness',
|
|
449
|
+
})
|
|
434
450
|
})
|
|
435
|
-
|
|
451
|
+
}
|
|
436
452
|
|
|
437
453
|
phase('Build')
|
|
438
454
|
// Genuine barrier: CRITIC needs ALL active dev agents' work before reviewing.
|
|
@@ -72,6 +72,7 @@ Every Workflow invocation returns a `runId`. If a run is interrupted — context
|
|
|
72
72
|
|
|
73
73
|
- **State model.** The **journal is the state of record.** `pipeline-state.json`, `sprint-{n}-status.yaml`, and the markdown handoffs are **derived, human-readable views** that agents write for visibility — the orchestrator never reads them back to make a control-flow decision (its state lives in JS variables the journal captures). A non-atomic multi-file state desync is structurally impossible here.
|
|
74
74
|
- **Planned sprint batches.** To run a planned batch instead of one story, pass `args: { stories: [{ storyId, projectType, profiles }, ...], maxRejectionCycles, models, reasoning }`. Produce that batch by running `plan.workflow.js` first (`args: { stories: [{ storyId, projectType }], sprintId, velocity, models, reasoning }`), then feed its `{ sprintId, stories: [...] }` straight into `sprint.workflow.js`. After a batch ships, run `retro.workflow.js` (`args: { batchNumber, sprintId, models, reasoning }`) to learn from it. Pass the same `config.models` and `config.reasoning` maps to all three. There is no `sprint-cycle` wrapper yet — run the three in sequence.
|
|
75
|
+
- `plan.workflow.js` marks each returned story `groomed: true` (it already specced them and passed the READINESS gate). `sprint.workflow.js` honors that flag and **skips its Spec + Readiness phases** for those stories — execution goes straight to Build, so a planned batch isn't re-specced or re-gated. A standalone single story (this skill's default args, no `groomed`) is still fully specced + gated. To force the skip manually, pass `preGroomed: true` (batch-wide) or `groomed: true` per story.
|
|
75
76
|
- **Per-agent reasoning effort.** The `reasoning` arg is a config-driven control surface (level→roles) that injects a thinking trigger into a role's prompt — blank by default, so it changes nothing until you fill it. Levels: `think` < `think-hard` < `think-harder` < `ultrathink`. Deeper thinking raises quality and token cost; check `valent audit` after enabling it. Edit it in `.valent-pipeline/pipeline-config.yaml` under `reasoning:`.
|
|
76
77
|
- **Per-agent models.** Each workflow assigns a model tier per agent: gates (READINESS/CRITIC/JUDGE) → opus, spec/build → sonnet, CLI-runner/IO steps → haiku. This comes from `config.models` (passed as the `models` arg); edit it with `/valent-configure` → "Model Assignments". Omitting the arg falls back to the same assignment baked into the script.
|
|
77
78
|
- **Known simplifications.** A CRITIC rejection currently re-runs ALL dev agents (not just the targeted one); there is no PMCP/visual-validation stage in the Workflow path yet. See `.valent-pipeline/orchestrators/claude-code/README.md`.
|