feat(deliverables): auto-producer reconciler + DELIVERABLE_EMIT skill (Slice 3)#41
Merged
Merged
Conversation
Slice 3 — makes the git-first write-path (PR #39) fire from completed issues, so agents capture verifiable artifacts without a manual call. - artifact-block.ts: parseArtifactBlock() extracts a fenced `wavex-artifact` block (kind/title/mime header + `---` + body) from issue text. Mirrors the wavex-contract block convention. - reconcile-deliverables.ts: - reconcileDeliverables() — pure, testable: for each terminal-state issue carrying a block with no existing deliverable, calls writeDeliverable() (which git-commits the artifact). Idempotent; one deliverable per issue. - fetchCompletedIssuesForCompany() — defensive I/O glue: reads the paperclip-handoff, GETs the local Paperclip issues, flattens to ReconcileIssue[] (field-name fallbacks; comments appended so a block posted as a closing comment is still scanned). Any failure yields [] so a tick no-ops rather than throwing. - route POST /api/mission-control/:companyId/reconcile-deliverables — board-auth trigger. Intended for the Liaison heartbeat or a cron; safe to call anytime. - DELIVERABLE_EMIT.md (liaison-ext, non-frozen) — teaches agents to emit the block on completion. code_change/db_migration still go through the Git Engineer PR flow, not this block. No always-on scheduler in this PR: the producer fetch hits the local Paperclip issues API, which isn't verified against a live instance here. The route makes it triggerable now; wiring it to the Liaison heartbeat is a one-line follow-up once the issues API shape is confirmed live. Tests: 9 new (parse: 5, isTerminalState: 1, reconcile: 3 incl. idempotency + git-commit assertion). All green alongside Slice 1+2's 6. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
fe2fd09 to
968a84a
Compare
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.
Summary
Slice 3 of the deliverable write-path. PR #39 added the git-first write-path + verify but nothing called
writeDeliverable()automatically. This makes it fire from completed Paperclip issues: an agent emits awavex-artifactblock when it finishes → the reconciler captures it as a git-committed deliverable.Stacked on #39 — base is
feat/deliverable-git-writepath. Merge #39 first.What's here
artifact-block.ts—parseArtifactBlock()extracts a fenced```wavex-artifactblock (kind/title/mimeheader +---+ body). Mirrors thewavex-contractconvention.reconcile-deliverables.tsreconcileDeliverables()— pure + testable: for each terminal-state issue carrying a block with no existing deliverable, callswriteDeliverable()(git-commits the artifact). Idempotent — one deliverable per issue.fetchCompletedIssuesForCompany()— defensive I/O glue: reads the paperclip-handoff, GETs local Paperclip issues, flattens toReconcileIssue[]with field-name fallbacks (id|key, state|status, body|description) and appends comments. Any failure →[](tick no-ops, never throws).POST /api/mission-control/:companyId/reconcile-deliverables— board-auth trigger. For the Liaison heartbeat or a cron; safe anytime.DELIVERABLE_EMIT.md(liaison-ext, non-frozen) — teaches agents to emit the block.code_change/db_migrationstill go through the Git Engineer PR flow, not this block.Deliberate scope call: no always-on scheduler
The producer fetch hits the local Paperclip issues API, which I could not verify against a live instance in this environment. Rather than ship an always-on loop hitting an unverified endpoint on every install, the route makes it triggerable now. Wiring it to the Liaison heartbeat (which already polls issues) is a one-line follow-up once the issues API shape is confirmed live. The fetcher degrades gracefully in the meantime.
Tests
9 new, all green (
test/reconcile-deliverables.test.ts):parseArtifactBlock: header/body split, no-block→null, missing-title→null, kind defaults, header-only.isTerminalState: terminal hints vs open states.reconcileDeliverables: terminal+block → git-committed deliverable (assertscommitSha); non-terminal/no-block → skipped; idempotent (2nd run skips, no duplicate row).Plus the 6 from #39 still green.
tsc --noEmit= baseline (only pre-existing pool-b-health + vendored sdk).🤖 Generated with Claude Code