Retarget routines via PATCH and enforce target authorization (CL-7353, CL-7354) - #555
Merged
Merged
Conversation
TheGreatAxios
force-pushed
the
cl-7353-retarget-authz
branch
from
September 2, 2026 07:44
036fbe4 to
c73fda7
Compare
TheGreatAxios
changed the base branch from
cl-7351-target-discovery
to
cl-7359-myra-routine-tools
September 2, 2026 07:45
TheGreatAxios
force-pushed
the
cl-7353-retarget-authz
branch
from
September 2, 2026 08:08
c73fda7 to
581b34c
Compare
TheGreatAxios
force-pushed
the
cl-7353-retarget-authz
branch
from
September 2, 2026 08:31
581b34c to
018e5ac
Compare
A routine's definitionAssetId can now be retargeted through the same PATCH used for every other field, persisted in one UPDATE alongside whatever else the patch carries. The launcher already re-resolves definitionAssetId to the definition that runs at the moment of each fire, so a retarget lands atomically for the next run without any optimistic-locking machinery.
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.
… arity from rebase merge
TheGreatAxios
force-pushed
the
cl-7353-retarget-authz
branch
from
September 2, 2026 10:37
018e5ac to
ec2b67b
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 CL-7353 and CL-7354 on top of CL-7351's target discovery.
CL-7353 — retarget via PATCH
PATCH /routines/:id(both the tenant-session route inroutes.tsandMyra's workflow-run-authenticated route in
workflow-routine-routes.ts)now accepts an optional
definitionAssetId, persisted in the samesingle
updateRoutineUPDATE as every other patchable field — no newendpoint, no optimistic-locking machinery. The hub's routine launcher
already re-resolves
definitionAssetIdthroughresolveLaunchableDefinitionexactly once, at the moment each firelaunches, so a retarget lands atomically for the next run.
CL-7354 — authorize the target
A create, and any PATCH that carries
definitionAssetId, now mustclear two gates before persisting:
resolveLaunchableDefinitionmustresolve (400/404/409 per the existing typed envelope), and the acting
principal must be authorized for
workflow-definition:<resolved id>/read— the same verblistRoutineTargetsalready checks per row. Adenial is a new typed 403 (
routine_target_forbidden). Both routineroute surfaces gained optional
grantStore/conditionRegistrydeps,wired in
apps/hub/src/index.tsto the sameroutineGrantStore/chatConditionRegistryalready used elsewhere in this file.Launch-time (
launchAndCorrelate/fireScheduledRoutine) was leftalone: the target is already re-resolved fail-closed at every fire, and
adding a second authorize check there (keyed off the routine creator's
principal for a scheduled fire) would be a real behavior change outside
this ticket's test scope — flagging as a possible follow-up rather than
bundling it in.
Verify
bunx tsc --noEmit -p packages/routines -p apps/hubbun test packages/routines/src packages/routines/test(280 pass)bun run scripts/checks/report-error.ts,error-envelope.ts— both okCloses CL-7353, CL-7354.
Resolves CL-7353
Resolves CL-7354