Surface native deployment approval to the initiating human (CL-7362) - #558
Open
TheGreatAxios wants to merge 8 commits into
Open
Surface native deployment approval to the initiating human (CL-7362)#558TheGreatAxios wants to merge 8 commits into
TheGreatAxios wants to merge 8 commits into
Conversation
TheGreatAxios
force-pushed
the
cl-7362-deploy-approval
branch
from
September 2, 2026 07:44
bfd9b76 to
2b77d64
Compare
TheGreatAxios
force-pushed
the
cl-7362-deploy-approval
branch
from
September 2, 2026 08:46
2b77d64 to
fc124c2
Compare
TheGreatAxios
force-pushed
the
cl-7362-deploy-approval
branch
2 times, most recently
from
September 2, 2026 09:27
39def2b to
62248e4
Compare
A create or PATCH-carried retarget now must clear the same two gates before it is persisted: resolveLaunchableDefinition must resolve the asset, and the acting principal must be authorized for workflow-definition:<id>/read — the same verb listRoutineTargets already checks per row. A denial is a typed 403 alongside the existing 400/404/409 target envelopes, on both the tenant-session and Myra's workflow-run-authenticated routine surfaces. Also routes a pre-existing catch in postRoutineEnabledNotice through reportError, since this change's diff now touches that line and check:report-error requires it.
…362) Covers the preview route/registry method with a fake deployer (no freeze, grants passed through), the wire-hash-mismatch 409 after a deploy that already froze a different definition, and the workflow_deploy approval headline rendering asset/sha/grants.
Composes the two seams docs/workflow-model.md's "Deploy approval for
agent-authored workflows" names, without adding an approval table:
- A `POST /:assetId/deploy/preview` route and matching
`WorkflowAuthorRegistry.previewDeploy` delegate to an optional
`WorkflowDeployer.previewDeploy`, so a workflow_deploy_preview tool
call can show the walked grant surface before anything parks. No
vendored `@intx/hub-sessions` entry point runs install+probe under a
caller-supplied approval policy without freezing today —
`session-service.ts`'s `buildInstallArgs` hardcodes
`approvals: { mode: "approve-probed" } as const`, and both callers
that reach it throw on a non-approval rather than returning it. That
gap is documented in `WorkflowDeployer.previewDeploy`'s doc comment
rather than reimplemented; `apps/hub`'s `workflowDeployer` leaves it
unwired, so previewDeploy fails closed with `unavailable` there today.
- `workflow_deploy`'s args gain `expectedWireHash` and `grants`, and its
description tells the model to call workflow_deploy_preview first and
pass both through, so the human approving the parked call sees them.
After a deploy, the registry compares `expectedWireHash` against the
newest `workflow_definition_version.approved_wire_hash` for the asset
and fails closed as `wire_hash_mismatch` (409) on a difference — the
frozen row from the deploy that already ran is NOT rolled back.
- `packages/approvals/src/headline.ts` renders workflow_deploy's
approval card directly from its own arguments ("Deploy workflow
<assetId> @ <sha7> — grants: a, b, c") instead of falling back to the
tool's generic description.
`@corbits/workflow-authoring-tools` bumped to 0.0.3 and re-pinned in
workflows/assistant.
Grepped apps/hub/src/tool-grants.ts and the grant-store wiring in
apps/hub/src/grant-allowance.ts: no path mints `approval:*`/`resolve`
(or any `approval:<id>`/`resolve`) for an agent principal — only a
human-authenticated resolve route (vendor/intx/hub-api/src/routes/
approvals.ts) checks that grant. Nothing changed there.
…l policy (CL-7362)
`InstallAndApproveWorkflowSourceParams` gains an optional `approvals?:
ProbeApprovalPolicy`, threaded through `buildInstallArgs` in place of the
hardcoded `approve-probed` default; `installAndApproveWorkflowSource`
returns the gate's `ProbeGateResult` instead of throwing on a non-approval
(a no-op for the default policy, which always approves). `previewDeploy`
in apps/hub calls it with an empty ApprovalSet, mapping the result to
{ wireHash, grants } without ever freezing.
TheGreatAxios
force-pushed
the
cl-7362-deploy-approval
branch
from
September 2, 2026 10:54
62248e4 to
a32b986
Compare
TheGreatAxios
marked this pull request as ready for review
September 2, 2026 11:09
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.
Implements docs/workflow-model.md's "Deploy approval for agent-authored workflows" section on top of CL-7361, without adding an approval table.
What's here
POST /:assetId/deploy/preview(packages/agent-workflow-authoring) andWorkflowAuthorRegistry.previewDeploy, delegating to an optionalWorkflowDeployer.previewDeploy.workflow_deploy(@corbits/workflow-authoring-tools, bumped to 0.0.3) now takesexpectedWireHashandgrants; its description tells the model to call the newworkflow_deploy_preview(no approval) first and pass both through.expectedWireHashagainst the newestworkflow_definition_version.approved_wire_hashfor the asset and fails 409wire_hash_mismatchon a difference. The frozen row from the deploy that already ran is not rolled back — a caller seeing this error must treat the definition as deployed-but-unverified.packages/approvals/src/headline.tsrendersworkflow_deploy's approval card asDeploy workflow <assetId> @ <sha7> — grants: a, b, c(or "no grants") straight from its own arguments.Native probe-without-freeze gap
No vendored
@intx/hub-sessionsentry point runs install+probe under a caller-supplied approval policy without freezing.session-service.ts'sbuildInstallArgshardcodesapprovals: { mode: "approve-probed" } as constinto every install; both callers that reach it (installAndApproveWorkflowSource,deployWorkflowFromSource, viaprepareCodeSourcedApproval) throwWorkflowDefinitionInvalidErrorwhenever the gate doesn't approve, rather than returning{ ok: false, reason: "grants_not_approved", unapprovedGrants }to the caller.Making this possible needs
InstallAndApproveWorkflowSourceParamsto accept a caller-suppliedapprovals: ProbeApprovalPolicy(threaded throughbuildInstallArgs) and a sibling ofinstallAndApproveWorkflowSourcethat returns the gate result ongrants_not_approvedinstead of throwing.Per AGENTS.md ("never reimplement
@intx/*"), this is not vendored here — it's documented onWorkflowDeployer.previewDeploy's doc comment in@corbits/agent-workflow-authoring.apps/hub'sworkflowDeployerleavespreviewDeployunwired; the registry fails those calls closed withunavailableuntil the native seam lands.Agent-cannot-approve finding
Grepped
apps/hub/src/tool-grants.tsand the grant-store wiring inapps/hub/src/grant-allowance.ts: no path mintsapproval:*/resolve(or anyapproval:<id>/resolve) for an agent principal — only the human-authenticated resolve route (vendor/intx/hub-api/src/routes/approvals.ts) checks that grant. Nothing changed there.Linear: https://linear.app/abklabs/issue/CL-7362
Test plan
bunx tsc --noEmit -p packages/agent-workflow-authoring -p packages/workflow-authoring-tools -p packages/approvals -p apps/hubbun test packages/agent-workflow-authoring packages/workflow-authoring-tools packages/approvals(93 pass)bun run check:tool-package-pinsResolves CL-7362