Skip to main content
← Back to list
01Issue
BugShippedSwamp CLI
Assigneesstack72

Relationships

#1077 runModel(): nested outputs record triggeredBy "manual" with no parentOutputId — docs promise model-trigger lineage

Opened by mgreten · 7/10/2026· Shipped 7/11/2026

Hi! First off — thank you for shipping context.runModel() (#1022 / PR #1810). We audited both of our repos today and it dissolves a whole class of nested-CLI lock workarounds for us; we're already migrating our extensions onto it. Really lovely design, especially the fail-closed cross-extension authorization.

While reading the implementation to plan our migration, we noticed what looks like a small gap between the design doc and the shipped code, and thought you might want to know:

What the docs saydesign/models.md (Output lineage section): "Nested invocations produce ModelOutput records with triggeredBy: \"model\", parentOutputId pointing to the caller's output, and callerExtension for provenance tracking."

What we observe at HEAD (fb93097, and in release 20260710.223351.0):

  • The schema support is all there: TriggerTypes includes "model", and parentOutputId / callerExtension exist as optional fields (src/domain/models/model_output.ts:50,79-80).
  • But the only ModelOutput write on the nested-invocation path hardcodes triggeredBy: "manual" and sets neither parentOutputId nor callerExtension (src/domain/models/method_execution_service.ts:844). Grepping the tree, nothing ever writes triggeredBy: "model" or assigns parentOutputId — the only writers are "manual" (direct + nested runs) and "workflow" (src/domain/workflows/execution_service.ts:786).
  • The in-memory nested_model_invocation method event does fire, so the provenance exists at runtime — it just doesn't reach the persisted record.

Why it matters for us (data, not pressure): we're converting an autonomous PR-fix pipeline where a parent method chains worktree + build + test + ship children; the persisted parent↔child link would let our audit artifacts and swamp summarise/output-search views distinguish "this ran because model X called it" from a manual run. Today a chained child is indistinguishable from someone running it by hand.

Might it be worth wiring the invocation context through to that ModelOutput.create call, or alternatively adjusting the design doc if persisted lineage is intentionally deferred? Totally your call on priority, of course — the feature is already a huge win for us as-is. Happy to test a build or provide more detail from our migration if useful. Thanks again!

02Bog Flow
OPENTRIAGEDIN PROGRESSSHIPPED+ 1 MOREASSIGNED+ 2 MOREREVIEW+ 4 MOREPR_MERGED+ 1 MORECONTRIBUTOR_NOTIFIED

Shipped

7/11/2026, 12:31:58 AM

Click a lifecycle step above to view its details.

03Sludge Pulse
stack72 assigned stack727/10/2026, 11:21:03 PM
Editable. Press Enter to edit.

stack72 commented 7/11/2026, 12:32:10 AM

Thanks @mgreten for reporting this! The fix has been merged and a release is on its way. We appreciate your contribution to swamp.

mgreten commented 7/11/2026, 10:54:03 PM

Thank you for the quick fix! We updated to 20260711.221640.0 and re-tested against our real chain (adw-phase-runner → cli-agent via runModel, confirmed in-process). One small observation from that verification, in case it's useful: the provenance write itself looks right (method_execution_service.ts now pre-creates the parent output and builds child provenance from context._invocationProvenance), but in our run the child's ModelOutput record still wasn't persisted — the parent output exists, no child record appears.

From reading the release source (f8097a1), it looks like the write is gated on context.outputRepository, and both places that construct ModelInvocationService build commonDeps without an outputRepository: src/libswamp/models/run.ts:654-661 (CLI model-run path) and src/domain/workflows/execution_service.ts:534-540 (workflow path — which interestingly already has outputRepo destructured in scope just above). So the child context never receives a repository and the new provenance branch appears unreachable in practice.

Might passing the output repository through those two commonDeps close the loop? As before, no urgency from our side — and happy to re-verify a build against the same chain within minutes of a release. Thanks again for how quickly you turned the first fix around!

Sign in to post a ripple.