feat(pipeline): load packs from config + create-from-pack over the wire - #209
Merged
Conversation
Makes packs reachable end-to-end from a client. Before this, loadPack /
create({pack}) existed only in-process (#208); nothing wired them to the
daemon or the control plane.
- config: pipeline.packs = [{ dir, trusted? }] — each dir is loadPack'd +
installPack'd at boot (fail-soft: a malformed pack logs and is skipped,
it never takes down boot). trusted (default false) gates command-gate
execution. The pre-existing defaultPack is now honored.
- wire: pipeline.create gains optional `pack` (phases now optional too —
XOR enforced in the manager, since the schema is in a discriminated
union and can't use .refine()). Neither given → defaultPack.
- PhaseDef/wire carry `role`; the phase's capability role is projected
onto pipeline snapshots so a client can render its tool envelope.
Tests: full E2E (pack on disk → config load → wire create-from-pack →
advance through a mock backend → done; untrusted command gate fails
closed; unknown pack → invalid_request; defaultPack fallback), wiring
install + fail-soft, and protocol-schema coverage for pack/role/optional
phases. Verified the real ai-factory aif-sdlc pack loads via this path
(5 phases, roles intact). tsc (3 pkgs) + biome clean.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #209 +/- ##
=======================================
Coverage 88.01% 88.02%
=======================================
Files 129 129
Lines 22028 22045 +17
=======================================
+ Hits 19388 19405 +17
Misses 2640 2640
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
This was referenced Jul 20, 2026
Merged
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Makes packs reachable end-to-end from a client. #208 added the pack loader +
create({ pack })in-process, but nothing wired them to the daemon or the control plane — a client couldn't create a pipeline from a pack, and the daemon loaded no packs. This closes that gap.The motivating consumer is the new private
highflame-ai/ai-factorypack registry (packs/aif-sdlc/) — this PR is verified against that real pack.Changes
pipeline.packs: [{ dir, trusted? }]. Each dir isloadPack'd +installPack'd at boot. Fail-soft: a malformed/missing pack logs and is skipped, never taking down boot.trusted(defaultfalse) gates command-gate execution. The pre-existing (inert)defaultPackis now honored.pipeline.creategains optionalpack;phasesbecomes optional too. Exactly-one-of is enforced in the manager (the schema is a member of atype-discriminated union, so it can't use.refine()). Neither given →defaultPack.PhaseDefWire/PipelinePhaseWirecarryrole; a phase's capability role is projected onto pipeline snapshots so a client can render its tool envelope (e.g. a read-only reviewer).Tests
pipeline-pack-e2e.test.ts): pack on disk → loaded via config at boot →pipeline.create { pack }over the wire → advanced through a real worker turn (mock backend) → done. Plus: untrusted pack's command gate fails closed → halt; unknown pack →invalid_request;defaultPackfallback.pack/role/ optionalphases.aif-sdlcpack loads via this path:spec[implementer] → architect[implementer] → implement[implementer] → review[reviewer] → ship[orchestrator].tsc(main + protocol + core) +biomeclean. Full suite: 1651 pass; the only failures are the live-ZeroID conductor integration tests (no server on this box — unrelated to this change).Next (not in this PR)
Runtime capability enforcement: compile a phase's
role→ Cedar → Shield so an out-of-envelope tool call is denied at runtime (the pack carries the capability today; enforcement is the follow-on). Studio sandbox-screen pack selection.