Skip to content

feat(pipeline): SDLC pipeline primitive — engine, store, registries (dark) - #204

Merged
saucam merged 3 commits into
mainfrom
feat/sdlc-pipeline
Jul 20, 2026
Merged

feat(pipeline): SDLC pipeline primitive — engine, store, registries (dark)#204
saucam merged 3 commits into
mainfrom
feat/sdlc-pipeline

Conversation

@saucam

@saucam saucam commented Jul 19, 2026

Copy link
Copy Markdown
Collaborator

What

First slice of the SDLC pipeline (docs/sdlc-pipeline.md): the generic, methodology-agnostic pipeline primitive. Lands dark — no daemon wiring, no methodology content, no behavior change until a manager is instantiated (PR #2).

New package src/daemon/pipeline/:

File Role
interface.ts PhaseDef / PipelineState / PhaseState + the four plugin seams — PhaseKind, GatePlugin (at: entry|exit), SkillPlugin, Pack — plus the §5a fields (tools, reads/writes, entryGate, per-phase provider/model)
registry.ts MapRegistry (register/unregister/resolve/list/has, last-wins-with-warn) + createRegistries()
builtin.ts content-free built-ins: a noop phase kind + always / manual gates
engine.ts pure advance logic — step/run, entry+exit gates, onFail halt/retry/abort, terminal/halted guards
store.ts durable pipelines table on bun:sqlite, mirroring Store conventions; listActive() drives restart rehydration
manager.ts PipelineManager — create/get/list/advance/abort + resume() (rehydrate non-terminal pipelines)

Why this shape

Follows the design's three-layer split: a generic pipeline primitive (this PR) → blocker-approval + audit (reuses existing seams) → swappable capability packs. The primitive is pure data + a side-effect-free engine, so the transition rules are unit-testable and the whole thing is off by default.

Verification

  • bun test src/daemon/pipeline26 pass / 0 fail
  • tsc --noEmit — clean
  • biome check — clean
  • Restart survival is covered end-to-end: a manual-gated pipeline halts, and a brand-new PipelineManager over the same store comes back halted at the same phase (the concrete win over ADLC's pipeline-state.json).

Not in this PR (next slices)

Also includes the design-doc enrichment (external prior-art §2a, refinements §5a, open Q3/Q4/Q6 resolved, default flipped to off/freestyle).

🤖 Generated with Claude Code

…efinements

Add §2a (Spec Kit / BMAD / Kiro / Roo / Aider + 2026 papers + omnigent/kiss_ai) and §5a (per-phase tool scoping, typed artifacts, entry/grounding gates, constitution/steering layer, gate enforcement tiers). Resolve open Q3/Q4/Q6; default the pipeline off (freestyle) until a pack is selected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented Jul 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.50746% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 87.66%. Comparing base (98133d8) to head (ab8bf98).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/daemon/pipeline/manager.ts 93.33% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #204      +/-   ##
==========================================
+ Coverage   87.52%   87.66%   +0.13%     
==========================================
  Files         118      124       +6     
  Lines       21122    21390     +268     
==========================================
+ Hits        18488    18752     +264     
- Misses       2634     2638       +4     
Flag Coverage Δ
daemon 87.66% <98.50%> (+0.13%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/daemon/pipeline/builtin.ts 100.00% <100.00%> (ø)
src/daemon/pipeline/engine.ts 100.00% <100.00%> (ø)
src/daemon/pipeline/interface.ts 100.00% <100.00%> (ø)
src/daemon/pipeline/registry.ts 100.00% <100.00%> (ø)
src/daemon/pipeline/store.ts 100.00% <100.00%> (ø)
src/daemon/pipeline/manager.ts 93.33% <93.33%> (ø)
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread src/daemon/pipeline/store.ts
Comment thread src/daemon/pipeline/engine.ts Outdated
Comment thread src/daemon/pipeline/engine.ts
@github-actions

Copy link
Copy Markdown

🤖 Gemini code review

This PR implements a generic, methodology-agnostic SDLC pipeline primitive including the engine, store, in-memory registries, and a manager. The architecture is solid and clean, but there are reliability issues around unhandled plugin exceptions causing crash loops, and a performance bottleneck in the SQLite store where active pipelines are loaded via a full table scan rather than utilizing the status index.

Findings: 🔴 0 · 🟠 3 · 🟡 0 · 🟢 0


Tokens spent · ⬆️ Input: 16,955 · ⬇️ Output: 688 · Σ Total: 24,699
Total may be higher due to thinking token counts.

…dark)

Methodology-agnostic pipeline foundation (docs/sdlc-pipeline.md §5): PhaseDef/PipelineState types + the four plugin seams (PhaseKind, GatePlugin, SkillPlugin, Pack), a Map-backed registry, a built-in noop phase kind + always/manual gates, the advance engine (entry/exit gates; onFail halt/retry/abort), durable bun:sqlite state, and PipelineManager with resume() for restart survival. No daemon wiring, no methodology content — lands dark. 26 unit tests; tsc + biome clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@saucam
saucam force-pushed the feat/sdlc-pipeline branch from 2d76c7c to ab8bf98 Compare July 19, 2026 23:15
@saucam

saucam commented Jul 19, 2026

Copy link
Copy Markdown
Collaborator Author

Addressed all three Gemini findings in ab8bf98:

  • store.ts listActive() — now filters in SQL (WHERE status NOT IN (…)) instead of scanning every row into JS; the placeholders are derived from TERMINAL_STATUSES so the terminal set stays single-sourced (no drift with isTerminal()).
  • engine.tsPhaseKind.run() and GatePlugin.evaluate() are now wrapped; a throwing plugin becomes a phase failure (handled by onFail) rather than crashing the run and leaving the pipeline stuck running (the restart crash-loop you flagged). Added tests for both paths.

Fixes propagate up the stack to #205 / #206 via rebase.

…205)

* feat(pipeline): config schema (off by default) + daemon boot wiring

Add a PipelineSchema to config (enabled=false default, defaultPack=null) with a CODEOID_PIPELINE_ENABLED env switch, and construct a PipelineManager in SessionManager when enabled — sharing the daemon DB and rehydrating non-terminal pipelines on boot (resume). Undefined when disabled, so the daemon stays dark by default. Pure createPipelineManagerFromConfig() factory keeps the enable/disable + share-DB + restart-survival behavior unit-tested without a full SessionManager.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(pipeline): skill phase kind + PhaseRunner seam + halt/answer/resume (#206)

Add the runtime layer. A 'skill' PhaseKind runs fn skills natively and drives prompt/slash skills through an injectable PhaseRunner (the backend seam; a SessionManager-backed adapter lands in a follow-up). PipelineManager.answer(id, requestId, {approved, value}) is the daemon side of halt -> answer-from-a-frontend -> resume: it resolves a halted phase (pass/fail) and continues advancing to the next halt or terminal. Fully unit-tested with fakes; no live backend required. Still dark (pipeline off by default).

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@saucam
saucam merged commit f6d1280 into main Jul 20, 2026
2 checks passed
saucam added a commit that referenced this pull request Jul 20, 2026
Bump package.json 0.3.1 → 0.3.2 and roll the 0.3.2 CHANGELOG section
(the release workflow gates on package.json matching the tag). 0.3.2 carries
the SDLC pipeline primitive (#204#209), the /settings MCP Servers surface
(#203), embedded-handoff ZeroID token consumption (#210), and the cross-cutting
audit fixes (#211).

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant