Skip to content

Mission run authority: bind run credentials to mission-run/RUN - #6263

Merged
schickling-assistant merged 14 commits into
mainfrom
schickling/2026-11-10-program-engine-run-credential
Nov 10, 2026
Merged

schickling-assistant merged 14 commits into
mainfrom
schickling/2026-11-10-program-engine-run-credential

Conversation

@schickling-assistant

@schickling-assistant schickling-assistant commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

Problem

Program steps must act as mission-run/RUN (docs/st3/program-engine.md §3, D2). Today a program effect is a daemon descendant without ST_AGENT, so its requests act as an unrestricted person and can name any actor.

Goal

Second PR of the M1.4 run-authority stack (stacked on #6260): the run credential and the binding. The engine minting it per attempt, the journal claims written as the run and child runs created as the parent run follow in a PR stacked on the engine branch; enforcement follows after.

Decisions

  • Credential = a row of the existing local capabilities table: kind program-run, subject the step run, incarnation the attempt, secret stored hashed (Store::issue_run_credential).

  • No revocation API: Store::run_binding binds only while the attempt is the step run's current attempt and the step is live (ready|working|blocked), so a credential dies with its attempt (retry, completion, cancellation).

  • The ancestry walk reads ST_RUN_CREDENTIAL beside ST_AGENT (HarnessAncestry::Run). A credential and an agent marker in one environment bind neither. The secret's Debug is redacted.

  • The serving guard resolves the credential to BoundRun; a credential that no longer binds makes the caller unverifiable. A bound run follows the bound-agent rules (no internal routes, no person headers, actor/requester must be the run), and the write principal fills a missing actor with the run.

  • CLI: configured_actor defaults to mission-run/$ST_MISSION_RUN when the credential is present; --as mission-run/RUN parses.

  • Review fixes: the trusted Unix client carries a run actor (Client::unix_run; ClientSession::local_run accepts mission-run/RUN only when the request's credential binds that run). Handlers that hold a bound caller to itself (documents, publication, attributed repair) read one BoundActor extractor for agents and runs, so a run writes no seat's doc/agents/… document and is the writer its document writes name.

Verification

Run on the Linux build host at the stack head 5494372 (contains this PR), all pass:

fractal-store  run_credentials_tests: a_run_credential_binds_its_run_only_while_its_attempt_runs ok, a_run_credential_is_refused_when_unknown_expired_or_of_another_kind ok
fractal-api-core: a_run_credential_in_the_environment_binds_a_run_and_never_an_agent_too ok, a_program_effects_descendant_binds_its_run ok, a_run_credential_binds_requests_to_its_run ok, incomplete_linux_environment_is_unavailable ok
fractal (lib): a_program_effect_acts_as_its_run ok

Focused tests :

  • fractal-store: a_run_credential_binds_its_run_only_while_its_attempt_runs, a_run_credential_is_refused_when_unknown_expired_or_of_another_kind.
  • fractal-api-core: a_run_credential_in_the_environment_binds_a_run_and_never_an_agent_too, a_program_effects_descendant_binds_its_run (real process tree, descendant with a cleared environment), a_run_credential_binds_requests_to_its_run (router + guard: attributed to the run, foreign actors refused, nothing written after the attempt ends).
  • fractal CLI: a_program_effect_acts_as_its_run.
    Hosted CI at the exact head is the proof; pushed with ST_EVIDENCE_LOCAL=off.

Complexity

High risk by docs/review.md: a new bound identity at the trust boundary. Nothing mints credentials in this PR, so production behaviour is unchanged until the engine dispatches attempts.

Concerns

  • The same-UID boundary is cooperative, as for agents: a descendant that sets ST_AGENT nearer in its ancestry binds as that agent.
  • Handlers that read BoundAgent directly (records, work) see a run-bound request as unbound; the guard and write principal still pin its actor to the run.

Friction & bottlenecks

Build host memory pressure; builds serialized.

Follow-ups

Mint in dispatch_program, journal actor, child-run starter (stacked on the engine branch); enforcement (audit, then enforce, as a daemon setting).

References

docs/st3/program-engine.md §3; #6260.

…gine-authority' into schickling/2026-11-10-program-engine-run-credential

# Conflicts:
#	docs/st3/large-value-sites.json
@schickling-assistant

Copy link
Copy Markdown
Contributor Author

Review record: independent reviewer round 1 at 524d0e31f3 returned CHANGES (the CLI's run actor was refused by its clients; BoundAgent-keyed handlers treated a run as an unbound person). Round 2 at 450b6587f893122135e7d7ea2faab638cdbcb074 returned GO, delta: unix_run and ClientSession::local_run are bound to the credential's run, and one BoundActor extractor now covers documents, apply and repair (both tested). Risk high (new identity family at the trust boundary). The owner pre-approved queueing this effort's high-risk pull requests on an independent GO plus green CI. Queue alone after #6260 merges and this PR targets main, with CI green at the head.

Base automatically changed from schickling/2026-11-10-program-engine-authority to main November 10, 2026 18:31
@schickling-assistant
schickling-assistant marked this pull request as ready for review November 10, 2026 18:31
@schickling-assistant

Copy link
Copy Markdown
Contributor Author

Delta review record for head 1437eb600b2ad2a2f4820b60f629cf192448bc6a.

  • Independent reviewer: GO at 450b6587f8 (earlier rounds recorded above).
  • Delta at 1437eb600b2ad2a2f4820b60f629cf192448bc6a: GO. The only change is a clean merge of main (787e8ed592, which contains Mission run authority: parse, render and store the authority block #6260). git show --remerge-diff is empty and the PR's diff against main matches its earlier diff against the Mission run authority: parse, render and store the authority block #6260 branch line for line. Main's new client-v0 routes are GET-only behind a client session and add no BoundAgent consumers; its authenticate changes do not touch the Unix person/run branch.
  • Advisory (non-blocking, unchanged): the work handlers take BoundAgent only to recover a seat's runtime incarnation; the guard already forces the actor on /v1/work/ bodies to be the run.
  • Risk high: a new identity family at the trust boundary. Queue alone, ahead of Mission run authority: decide every write by a run, audited by default #6272.
  • The owner pre-approved queueing this effort's high-risk pull requests on an independent GO plus green CI.
  • Verdict: GO; queue alone on hosted CI green at this exact head.

@schickling-assistant
schickling-assistant added this pull request to the merge queue Nov 10, 2026
Merged via the queue into main with commit c194824 Nov 10, 2026
75 of 76 checks passed
@schickling-assistant
schickling-assistant deleted the schickling/2026-11-10-program-engine-run-credential branch November 10, 2026 19:53

This branch was previously deployed

1 inactive deployment
evidence-signing — 1437eb60 Deployed Nov 10, 2026 by schickling-assistant via evidence-note-linux-gate #19602
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants