ADR-0088.
ADR-0088-runwards-own-delivery-runs-under-a-delegation-charter-the-gate-reads.md
ADR-0088 — runward's own delivery runs under a delegation charter the gate reads: agents act under their own identity, the maintainer signs the policy and one weekly sample, not each act
Date: 2026-10-01
Status: accepted (2026-10-01) — the maintainer accepted this record as written: agents under their own
identity, a charter signed once, a weekly signed acknowledgement, two stages, option (a) for runward's own
regulated lock (decision 4), and the signed release tag as the authorization for a class I patch;
stage 1 is the next work, and nothing is delegated before its pieces are in the gate
Deciders: the maintainer
Method: an inventory of every act in runward's delivery that requires the maintainer's hand,
measured on origin/main@8a18489 with read-only gh api calls; the texts that bear on human approval
read at source or at a named mirror on 2026-10-01; prior art from forges and large projects; the
doctrine read against the code (src/lib/conformance.ts, src/commands/ratify.ts,
src/commands/wire.ts, src/lib/harness.ts); a regulatory review and a security review of the draft
the same day; then five platform measurements on a throwaway public repository,
github.com/stranxik/runward-delegation-lab, with the GitHub App runward-steward (id 5150097) on
2026-10-01, quoted under "What the platform does, measured"
Relates to: ADR-0039,
ADR-0045,
ADR-0050,
ADR-0054,
ADR-0065,
ADR-0066,
ADR-0080,
ADR-0082,
ADR-0084,
ADR-0085,
ADR-0086, ADR-0087 (proposed, PR #346)
Would amend, by name, once accepted (none of these ADRs is edited by this one): ADR-0080, the
"runward itself" paragraph; ADR-0082, decision 3 extended, for the single-accountable case only;
ADR-0084, point 5, for advisory drafting; ADR-0085, decision 3 and its consequence "The only
irreversible gesture of a release is the maintainer's", for patch releases only.
Context
What the maintainer said. On 2026-10-01: « c'est un système qui doit fonctionner sans ma main directe [...] c'est absurde de développer un système justement fait pour encadrer l'IA agentique et que je doive moi-même gérer cela manuellement » [it is a system that must work without my direct hand; it is absurd to build a system meant to frame agentic AI and then manage it all by hand myself]. This is, from the inside, the reevaluation trigger ADR-0080 names: ratification cost leading to bulk ratification without reading.
What the forge records today. All 277 merged pull requests not opened by Dependabot were opened and
merged by the maintainer's account, with 0 reviews; median creation-to-merge 0.076 h. Since
2026-07-01, 823 commits carry the maintainer's name and 0 an agent's. 11 draft advisories were created
in 8 seconds on 2026-10-01. .github/CODEOWNERS is * @stranxik. Every agent session on the
maintainer's machine uses the same token. The forge cannot tell the maintainer's acts from an agent's:
the attribution ADR-0082 forbids for ratification ("never under a human's name") already holds for
merges, releases and advisories. While that token is within agent reach, no control in this ADR binds
an agent: with it, an agent can give the CODEOWNERS approval, change rulesets, clear a stop, or bypass
an environment wait.
What the human validation measured last week. runward's 46 rows were ratified on 2026-09-27 en bloc,
"sample 18/46, sampled rows accepted 18/18": 28 rows were never displayed. A later entry (2026-09-30) is
signed with a different spelling of the maintainer's name than the other five; by RWD-2026-0119 the
trace cannot tell who ran it. By the same record, a script on a pseudo-terminal can produce a
person-shaped trace: ratify's human path checks process.stdin.isTTY (ratify.ts:142), and
agentRuntimeSignal(process.env) (harness.ts:110) is environment detection.
What ADR-0082 already allows, and its gap. ratify --agent <name> --for <person> records
mode: agent, refused when the agent or its accountable person is the row's proposer. agentCause()
(conformance.ts:756) compares free declared strings (declaredNameIn): --agent is any string, and
--for thibaultsouris does not match a proposer Thibault Souris. Proposals do not record the
proposer's accountable person. Under the regulated tier, ADR-0082 decision 3 extended counts
agentRatification only "when its accountable person differs from the proposer" and "never relaxes
ADR-0080 part 2: the forge approval still requires a human account, not a bot or an app". runward's own
lock (runward/scaffold-lock.json) carries "regulated": true.
What ADR-0080 already refused. docs/operator-role.md: a "validated by" field in a mission artifact
"would be re-signable by whoever writes the artifact — declarative, worth nothing to an assessor". A
delegation charter is such an artifact. This ADR does not ask it to prove anything (decision 3).
What the platform does, measured (2026-10-01, github.com/stranxik/runward-delegation-lab, public,
throwaway). The App runward-steward (id 5150097, private, owner stranxik) is installed on the lab
repository only, with metadata: read, contents: write, pull_requests: write,
repository_advisories: write, actions: read, checks: read, statuses: read, and no
administration, workflows or variables. Its private key sits in the macOS keychain of the
maintainer's user; installation tokens are minted per use and live one hour.
- T1, a review. Branch ruleset on the default branch: pull request required, 1 approving review, no
bypass. Pull request #1, opened by the maintainer's account, approved by
runward-steward[bot](REST;gh pr reviewover GraphQL errored with an App token), merged by the maintainer's account: merged,reviewDecisionAPPROVED, rule suite result pass. Control, pull request #2 with no review: merge refused, "At least 1 approving review is required by reviewers with write access." The App's approval satisfies a required review. - T2, a release. The App created a draft release for a tag
v0.0.1that did not exist, then published it (PATCH draft=false): release published, authorrunward-steward[bot]; the workflow onrelease: publishedran with actor and triggering actorrunward-steward[bot]. An installation token fires the event theGITHUB_TOKENdoes not, so the App key alone can make a release's irreversible gesture and start everything ADR-0085 hangs on it, npm publication included. - T3, an advisory by the App.
POSTcreate: draftGHSA-vm9v-39qg-jf2c, state draft, authorrunward-steward[bot];PATCH state=closed: closed. Publishing an advisory and requesting a CVE were not measured: either would write to the public Advisory Database. - T4, an advisory by the workflow token. A
GITHUB_TOKENwithcontents: read: listGET200, createPOST403. A workflow token cannot create an advisory. (The lab note does not record the state filter or the content of the list call; ADR-0084's question onstate=triagestays open.) - T5, a tag. Tag ruleset on
refs/tags/v*, rule "creation", no bypass: the App creatingrefs/tags/v0.0.2was refused ("Reference update failed"); control, the App creatingrefs/tags/lab-1succeeded; the App publishing a draft whose tagv0.0.3did not exist was refused ("Cannot create ref due to creations being restricted"); the maintainer's account creatingv0.0.4was refused too. A no-bypass tag ruleset stops the App and the maintainer alike. - A fact about one agent runtime. During the lab, Claude Code's own permission classifier refused, unprompted, an agent approving through the App a pull request the same agent had opened, a merge without review even as a control, reading the App key, and making a repository public; the maintainer ran T1's approval and its control by hand. This is a property of one harness's configuration, which runward neither ships nor can read, and no decision below relies on it.
What follows from the measurements. From T2: the custody of the App key is a precondition of any
delegation, not a hardening step; whoever holds the key holds the release. From T1: if the author and
the reviewer are two identities whose keys one process can read, the forge's "approved" is one actor
approving itself; the reviewer's key must be under a custody separate from the author's, and even then,
with one accountable person, the forge's "approved" is not independent and must not be presented as
such. From T5: a no-bypass tag ruleset cannot serve a chain where the maintainer pushes the tag
(ADR-0085 decision 1); an admin-role bypass keeps the App out but protects only once agents no longer
hold the maintainer's credential, because with it an agent is the admin. From T3 and T4: advisory drafts
come from the App, never from the GITHUB_TOKEN; App publication and CVE requests rest on documentation
until measured.
What the texts require. Read 2026-10-01; EUR-Lex refused automated fetches, so DORA was read on an unofficial mirror and RTS art. 17 on springlex.eu.
- DORA art. 9(4)(e) (https://eur-lex.europa.eu/eli/reg/2022/2554/oj; read at https://www.digital-operational-resilience-act.com/Article_9.html): controls so that "all changes to ICT systems are recorded, tested, assessed, approved, implemented and verified in a controlled manner"; management approval of the process is additional, not a substitute. DORA requires every change to be approved.
- RTS 2024/1774 art. 17(1) (https://eur-lex.europa.eu/eli/reg_del/2024/1774/oj; read at https://www.springlex.eu/en/packages/dora/rts-rmf-regulation/article-17/): applies "in respect of all changes"; (b) "independence of the functions that approve changes and the functions responsible for requesting and implementing those changes"; (f) "adequate safeguards"; (g) post-implementation approval for emergency changes only, every one of them. The charter-and-sample model does not meet these. It is acceptable for runward only because runward is not a financial entity, and it is never presented as a change-approval control.
- AI Act art. 14(1) (https://artificialintelligenceact.eu/article/14/): a design obligation on providers of high-risk systems, which "shall be designed and developed [...] [to] be effectively overseen by natural persons during the period in which they are in use"; 14(4)(d)-(e) abilities to override and to "interrupt the system through a 'stop' button"; 14(5) two-person verification for remote biometric identification only. Art. 26(2) (https://artificialintelligenceact.eu/article/26/): deployers assign oversight to natural persons with "competence, training and authority, as well as the necessary support". runward is not a high-risk system. The applicability date of the high-risk obligations, and any postponement, was not re-read.
- NIST AI 100-1 (https://nvlpubs.nist.gov/nistpubs/ai/NIST.AI.100-1.pdf): MANAGE 2.4, mechanisms "to supersede, disengage, or deactivate AI systems". The appendix on human-AI interaction: "Some AI systems may not require human oversight, such as models used to improve video compression. Other systems may specifically require human oversight."
- SLSA v1.2 Source (https://slsa.dev/spec/v1.2/source-requirements): the second level requires the source control system to issue "Source Provenance Attestations for each new Source Revision"; the third, enforced technical controls recorded in attestations and Verification Summary Attestations; the fourth, "two or more trusted persons", a trusted person being "a human". The "Trusted Robot" exception requires an automation whose "identity and codebase cannot be unilaterally influenced"; an App held by one maintainer does not qualify. runward's current Source level is not measured.
- Cyber Resilience Act (primary text not read; secondary: https://www.cyberresilienceact.eu/reporting.html, https://zavodsky.org/en/intelligence/regulatory-radar/cyber-resilience-act-reporting-11-september-2026/): art. 14 reporting of actively exploited vulnerabilities applies from 2026-09-11, with a 24-hour early warning; open-source stewards have art. 24 obligations. Whether runward is a manufacturer, a steward or out of scope depends on commercial activity; paid pilots are envisaged. Not determined.
- GitHub Terms of Service (https://docs.github.com/en/site-policy/github-terms/github-terms-of-service): "Accounts registered by 'bots' or other automated methods are not permitted"; "A machine account is an Account set up by an individual human who accepts the Terms on behalf of the Account, provides a valid email address, and is responsible for its actions"; "You are responsible for all content posted and activity that occurs under your Account". The terms do not forbid automation under one's own account: today's defect is an attribution defect under ADR-0082, not a breach of the terms.
- GitHub Actions (https://docs.github.com/en/actions/concepts/security/github_token): "events triggered
by the
GITHUB_TOKENwill not create a new workflow run". Rulesets (https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets): push rules with file-path restriction apply only "to a private or internal repository"; "Any person or integration with write permissions to a repository can set the state of any status check".
What prior art does (read 2026-10-01). Prow
(https://docs.prow.k8s.io/docs/components/plugins/approve/approvers/): for /lgtm, "Authors of the PR
cannot give the label, but they can cancel it"; approve lets an author in OWNERS approve their own
files by default (secondary source; the approve-plugin page is a placeholder). Chromium Rubber Stamper
(https://chromium.googlesource.com/infra/infra/+/refs/heads/main/go/src/infra/appengine/rubber-stamper/README.md)
approves narrow benign classes and "never provides OWNERS approval, by design". Copilot coding agent
(https://docs.github.com/en/copilot/concepts/agents/coding-agent/risks-and-mitigations): commits authored
by the agent, the requester co-author and barred from approving; Copilot reviews do not count toward
required approvals by default, an administrator can let them count since 2026-09-01 (recorded in
ADR-0080), approvals in public preview (https://docs.github.com/en/copilot/concepts/agents/code-review).
Apache lazy consensus (https://community.apache.org/committers/lazyConsensus.html): intent stated "on a
public email", "usually 72 hours", "Silence indicates consent". Anthropic
(https://www.anthropic.com/engineering/claude-code-auto-mode): "Claude Code users approve 93% of
permission prompts". OpenAI, "Practices for Governing Agentic AI Systems"
(https://cdn.openai.com/papers/practices-for-governing-agentic-ai-systems.pdf): §4.2 opens "Some
decisions may be too important for users to delegate to agents [...] (such as independently initiating
an irreversible [...] transaction)" and lists the "rubber stamp" among its open questions; §4.4:
"Actions that can only be reviewed after the fact should be more easily reversible than those that
require approval." Class I below answers this with a signed prior authorization, never silence.
Not read. CRA primary text; ISO/IEC 42001 and 27001; ITIL 4; PCAOB AS 2201; GitHub's CNA review practice; npm's terms on automated publishing; npm trusted-publisher environment binding; GitHub environment admin-bypass documentation.
Decision
Agents act under their own identity, inside a charter the gate reads; the maintainer's recurring act is one signed weekly commit. It starts in two stages, and every surface says which stage holds.
Two stages, displayed.
- Stage 1, now. Delegated acts run under the App; the maintainer's credential and the App key are
still within agent reach. Every surface (
check,report, the charter header, README) prints « delegation: declared, not proved — the maintainer's credential is within agent reach ». Classes R and H stay the maintainer's, class I is not delegated (releases and advisories as ADR-0085 and ADR-0084 decide them today), class D is delegated. Stage 1 adds attribution; it adds no protection, and says so. - Stage 2, provable. Agent sessions run under a separate macOS user (or a container) that holds
no maintainer
ghtoken (at most a fine-grained read-only one) and cannot read the App keys; trust-root acts happen only from a 2FA web session or a commit signed by the maintainer's hardware key (sk-ssh-ed25519, touch required). The gate checks what it can: every commit onmainafter the cut-over is the App's (web-flow signature verified) or signed by a key inallowedSigners; an agent-side probe (gh api userfails or returns the App) is shown as self-declared. Only the hardware-key signature is evidence an agent cannot produce.
- Stage 1, now. Delegated acts run under the App; the maintainer's credential and the App key are
still within agent reach. Every surface (
Four classes of acts.
- R, trust roots, the maintainer's: signing, renewing, widening and revoking the charter; forge
and admin settings;
allowedSigners; lock opt-ins; arming the gate (ADR-0065, unchanged); constitutional ADRs (verdict path or ADR-0054 crossing,AGENTS.mdboundaries,SECURITY.mdpromises, the public-claim ceiling, the charter, superseding an accepted decision). - H, judgement owed to a third party, the maintainer's: a reported vulnerability, its acknowledgement, a CVE request, embargo coordination, and any CRA art. 14 notification if runward is in scope.
- I, irreversible public acts, delegated in stage 2 only, covered by a signed prior authorization, never by silence: patch releases whose diff contains no constitutional ADR, no shipped-code merge not yet covered by a signed digest, and no dependency version younger than N days, with checks green, the ratchet held and the four assets verified. Advisory publication joins class I only after the CRA scope determination and the measurement of App publication (What would settle it); until then it stays human. Minor and major releases remain the maintainer's gesture.
- D, reversible or internal, delegated: merges outside the pre-merge list (decision 7), agent
ratification of rows, non-constitutional ADRs, Dependabot merges (with
cooldown), defect-register entries, documentation syncs, advisory drafts by the App (T3; never by theGITHUB_TOKEN, T4), golden regeneration.
- R, trust roots, the maintainer's: signing, renewing, widening and revoking the charter; forge
and admin settings;
Identities and key custody. Delegated acts run under
runward-steward, installed on runward's repository with the lab's permission set and neveradministration,workflowsorvariables. Because the App key alone can publish a release (T2), its custody is part of the decision: in stage 2 it leaves the agents' reach (a signer the agents' OS user cannot read, preferably KMS/HSM with a per-App policy). Because the App's approval satisfies a required review (T1), a review counts only from an identity whose key is under a custody separate from the author's: preferably a third-party- hosted reviewer whose key no local process holds (Copilot review, if the administrator enables it), otherwise a second App under separate custody, outside any agent's filesystem, the operator-layer agent's included. In stage 1 no App review is presented as a review. Invariant: no App in any bypass list. Every act carries « by: (agent) · for: (accountable) ». README and GOVERNANCE state that the forge's "approved" is not independent with one accountable person: the forge UI, ruleset audit and SLSA tooling do not carry runward's disclosure.Independence fixed, and never claimed where it does not exist.
proposerecords the proposer's accountable person; accountable persons are compared by canonical id (forge user id plus aliases);by:is bound to the git identity that committed the entry (the App bot, web-flow signature verified), not a free string. A ratification whose accountable person equals the proposer's is refused, except asagent (single accountable):- in a default mission it counts, disclosed on every surface as « single accountable person; agent ratifications are disclosed throughput, not independent approval »;
- under the regulated tier it is refused by default (ADR-0082 decision 3 extended stands). For one
case only this ADR would amend it: it counts when the lock names the exception
(
"singleAccountable": "<canonical id>") and the period is covered by a passing signed sample; otherwise it is a named strict gap. Every surface then prints « not a DORA change-approval control; ADR-0080 Part 2 unchanged ». - For runward's own mission, chosen: (a) the named amendment to ADR-0082 above and the
exception declared in
runward/scaffold-lock.json. The others: (b) leave the regulated tier on runward's own mission, losing the strictest dogfooding; (c) keep the agent rows as named strict gaps, which turns runward's own strict gate red or sends the maintainer back to ratifying in person. The maintainer chose (a) on 2026-10-01.
A charter the gate reads, which proves nothing by itself:
runward/delegation.md. Delegates, the accountable person as a canonical id, classes, scopes, budgets, sample size,expires:(at most 90 days). Guarded by CODEOWNERS with required code-owner review, the only file guard a public repository has, void while stage 1 holds. The answer tooperator-role.md: the charter is declared and the gate says so; what carries evidence is the sample ledger, signed by a key only the maintainer holds and verified offline (decision 6). The gate prints « charter: declared, not proved; samples: signed by (presence shown, reading declared) ». A renewal is shown as a diff against the last signed charter; any widening (new scope, smaller sample, shorter window) needs its own signed commit and cannot ride a renewal.One weekly signed act: sample, digest, acknowledgement.
- Population from git alone: first-parent merges on
main, tags, ratification entries since the last signed sample; counts reconciled; population hash published. - Draw: fixed, stratified, risk-weighted, 5 acts plus 1 seeded defective item; randomness from a
source fixed after the period closes that no agent can steer (a pre-announced drand round), never
from the mission-state digest. The seed is committed as
H(seed, nonce)before the sample and revealed after, so an auditor can re-perform the control. - One commit signed by the maintainer carries the sample outcome, the 100 % digest of shipped-code
merges (decision 7) and, in stage 2, the authorization of that week's class I patches (decision 8).
The gate verifies it offline against
allowedSigners. This is the remaining human act and is named as such. - Missing the seed records
control missed: the sample does not count. A rejected act suspends that class for that delegate. Seeds also measure the reviewer; its catch rate is a published counter. - In stage 1 the signing key is within agent reach: entries print « sample: declared human, not proved » and never unlock class I.
- Population from git alone: first-parent merges on
The system comes to the maintainer; silence is never consent; escalation is deterministic.
- Push notifications for: sample ready, pre-merge escalation, charter expiring within 14 days, minor release ready. A delivery receipt is shown as « delivered, not read », is an agent's attestation when the operator-layer agent sends it, and is never consent.
- Before merge, the maintainer's pre-approval:
src/lib/{conformance,evidence,verdict}*,src/commands/{wire,ratify,propose}.ts,src/lib/harness.ts,plugins/runward-gate/hooks/**,.github/**(CODEOWNERS and workflows included),package.json(scripts,prepublishOnly, dependencies), lock opt-ins,AGENTS.md,SECURITY.md, README claims, the charter,allowedSigners; disagreement between agents; a check red then green on re-run; a ratchet drop; anygate-bypass.logline. - After merge, 100 %, in the weekly digest: every other merge touching a file in the published
tarball (
package.jsonfiles,templates/,plugins/). No patch release may contain one before a signed digest covers it. - One missed week: « unsampled since » everywhere. Two missed periods:
check --strictturns red on any class D act since the last signed sample, and agent ratifications stop counting.
The release window, built on what was measured. For a class I patch (stage 2), the prior authorization is the annotated tag
vX.Y.Zsigned by the maintainer's hardware key and pushed in the weekly session. Thev*tag ruleset carries an admin-role bypass, so the maintainer can push it and the App cannot (T5; a no-bypass ruleset would refuse the maintainer too). ADR-0085's prepare run makes the draft; the App may then publish it (T2: thepublishedevent fires for its token). Thepublishjob verifies the tag's signature againstallowedSignersbeforenpm publishand refuses otherwise, so the App key alone no longer reaches npm. Minor and major releases keep ADR-0085 decision 3 as is.Stop. A repository variable or ruleset toggle only an administrator can change, read by a required check whose source is pinned to the GitHub Actions app; the escalation budget (3 consecutive refusals, 20 per period) is counted by that check, not by the agent. Revocation by uninstalling the App. Exercised on a schedule, result committed under signature. In stage 1 an agent holding the maintainer's credential can clear it; the surfaces say so.
Public claims narrowed first (ADR-0050 claims guard), before any delegation:
AGENTS.md:39"The maintainer merges";GOVERNANCE.mdroles;README.md:166"publishing to npm is a deliberate human gesture (creating the Release)" and "The deterministic executes; the human decides the crossing. The discipline is demonstrated, not claimed." Added: one accountable person; agent ratifications and forge approvals are disclosed throughput, not independent approval; not a DORA change-approval control; the SLSA Source level once measured, the two-person level out of reach with one person.
Implementation order. (1) This ADR decided, including decision 4's option. (2) Claims narrowed
(decision 10). (3) CLI, each in its own pull request: canonical ids and the agentCause() fix,
propose recording the accountable person, by: bound to the committing identity, the charter reader
and its stage banner, the git-built population, the signed sample with commit-reveal. (4) The App
installed on runward from a 2FA web session, CODEOWNERS, the stop, Dependabot cooldown; class D on, in
stage 1, with its banner. (5) Stage 2: separate OS user, hardware key in allowedSigners, the App key
and the reviewer's key under separate custody, the v* tag ruleset with admin-role bypass, the tag
signature check in publish. (6) SLSA Source level measured; CRA scope determined. (7) Class I patches
after four consecutive weeks of hardware-signed samples with no control missed.
Alternatives discarded
- Keep the maintainer's hand on each act. Measured as a login, not a gesture; bulk ratification left 28 of 46 rows unseen.
- Agents act under the maintainer's account (the status quo, never decided). The attribution ADR-0082 forbids; it also voids every human control, since the human identity is within agent reach.
- Wait for stage 2 before delegating anything. Cleaner, and it keeps the attribution defect open for as long as the separate user and the hardware key take; stage 1 fixes attribution now and says it proves nothing.
- Agent ratification without a sample (ADR-0082 as is). No human measurement, and the free-string independence check reads independence where one person answers for both sides.
- Sampling a share of acts (20 %). At September's volume, 20 or more items a week at about 30 seconds each: the rubber stamp it claims to prevent.
- Silence windows for irreversible acts. Counter to the cited OpenAI guidance; a delivery receipt does not show the notice was read.
- An App review counted as independent approval. T1 shows the forge would accept it; with one accountable person and, in stage 1, one custody for every key, it is one actor approving itself.
- A no-bypass tag ruleset. Measured to stop the maintainer as well (T5), which breaks ADR-0085 decision 1.
- A second human approver staged for appearance. ADR-0080 Part 2 already refuses it.
- Full automation including all releases and third-party security judgement. Irreversible acts and duties owed to a reporter or a CSIRT need a human.
- A machine user with a long-lived token instead of an App. Allowed by the terms, but a long-lived secret; fallback only.
- Pre-merge escalation of every shipped file. About 60 of 96 September merges; the bottleneck restored. Replaced by pre-merge on gate-critical paths plus a 100 % weekly digest gating the patch envelope.
Consequences
- This is not a DORA change-approval control, and runward does not present it as one. Under the regulated tier ADR-0080 Part 2 (forge approval by a human account) is unchanged for adopters; the single-accountable exception counts only when named in the lock and covered by a signed sample.
- Stage 1 changes who the forge names, not what anyone can do. Until stage 2, an agent can still act as the maintainer; the banner is the control, and it is a disclosure.
- The maintainer's recurring work: one signed weekly commit (6 items, the shipped-code digest, the patch tags in stage 2), pre-merge escalations on gate-critical paths, about four minor-release gestures a month, constitutional ADRs, quarterly renewal, third-party and CRA duties. Weekly minutes are not estimated; they are published after four weeks.
- Every delegated act is attributable to a named agent and a canonical accountable id; no surface presents an agent approval as a human one, nor the forge's approval as independent.
- The evidence changes meaning, and says so: "it matched a policy the maintainer signed, a second declared identity under the same accountable person validated it, and a weekly sample signed by the maintainer's hardware key passed a seeded control an auditor can re-perform".
- Adopters can use the charter, the signed sample and the disclosure in a default mission; under the regulated tier they gain nothing that relaxes ADR-0080 Part 2.
- Cost: a separate OS user for agents; a hardware key; an App and a reviewer under separate custody; a
notification channel; CLI changes to
propose,ratifyand the conformance reader. - Risk accepted: the charter is written by the audited party; it is declared, and the gate says so.
- No CLI change and no
runward/delegation.mdship with this ADR.
What would settle it
- Measurements still missing, each on the lab repository first: an App publishing a repository
advisory and requesting a CVE (both write to public databases, so a dedicated test advisory is
needed); a
v*tag ruleset with an admin-role bypass refusing the App and admitting the maintainer; whether a CODEOWNERS required review is satisfied by an App; whether GitHub refuses an App approving a pull request the same App authored; disabling admin bypass on thereleaseenvironment; npm trusted publishing bound to an environment; aGITHUB_TOKENonstate=triage(ADR-0084's open item); runward's SLSA Source level. - Stage 2 holding: every commit on
mainafter the cut-over attributable to the App or to anallowedSignerskey, and the agents' OS user unable to read either App key. - Four weeks of class D with signed samples: share of
control missed, rejected acts, escalation volume, measured weekly minutes; the reviewer's catch rate on seeds. - The CRA scope determination, before advisory publication enters class I.
- Decision 4's option chosen by the maintainer for runward's own lock.
Reevaluation trigger (mandatory, dated)
Reopen on 2027-01-01, or earlier on: a sampled act rejected twice in one class; control missed twice
in a row; stage 1 still in force three months after acceptance; a second maintainer joining
(independence becomes possible); a supervisor statement on agents as the approving function under RTS
art. 17(1)(b); GitHub changing whether App reviews count toward required approvals, or taking Copilot
approval out of preview; the CRA scope determination concluding runward is in scope, or paid pilots
starting.
Trigger set on: 2026-10-01 · Watched via: the weekly signed sample (its rejections and
control missed), the stage banner on check, the GitHub changelog at each release's runbook step 2.
Note, 2026-10-02: the gate reads time from the tree, never from a clock
Recorded so the choice lives in the record, not only in the code. The verdict path reads no clock (ADR-0054, same working tree, same verdict), and two decisions above name dates:
- Charter expiry (decision 5).
checkcomparesexpires:only with the dates the tree declares: an agent ratification entry dated afterexpires:is acharter-expiredgap. A charter that lapses with no act after it reads the same before and after the date;runward doctor, outside the verdict path, setsexpires:beside today's date and warns 14 days ahead (docs/delegation-charter.md). - Missed periods (decisions 6 and 7). Periods are
effective:plus multiples ofsample-period-days:. The samples that count form a chain ending at the last one's end. The gate's only "now" is the latest date a ratification entry in the tree declares; every period ended on or before it after the chain's end is missed. One missed period prints « unsampled since »; two make agent ratifications dated on or after the chain's end strict gaps, and under the regulated tier stop them counting.runward doctorandrunward sampleread the same periods against today.
What this costs, said as it is: a tree in which nobody declares anything after a period ended shows no missed period, whatever the calendar says, and entry dates are declared by whoever writes them. Both are readable in the diff; neither is a proof. The randomness of the sample is recorded the same way: the drand round is recomputed from the period's end and its randomness from its signature, offline; the signature itself is not verified against drand's public key in the gate (a pairing library would enter the verdict path), so the gate prints « randomness: declared ».
References
- DORA, Regulation (EU) 2022/2554: https://eur-lex.europa.eu/eli/reg/2022/2554/oj (not fetched); read at https://www.digital-operational-resilience-act.com/Article_9.html (2026-10-01)
- Delegated Regulation (EU) 2024/1774: https://eur-lex.europa.eu/eli/reg_del/2024/1774/oj (not fetched); art. 17 read at https://www.springlex.eu/en/packages/dora/rts-rmf-regulation/article-17/ (2026-10-01)
- AI Act art. 14, 26: https://artificialintelligenceact.eu/article/14/, https://artificialintelligenceact.eu/article/26/ (2026-10-01)
- Cyber Resilience Act (secondary only): https://www.cyberresilienceact.eu/reporting.html, https://zavodsky.org/en/intelligence/regulatory-radar/cyber-resilience-act-reporting-11-september-2026/ (search results, 2026-10-01)
- NIST AI 100-1: https://nvlpubs.nist.gov/nistpubs/ai/NIST.AI.100-1.pdf (2026-10-01)
- SLSA v1.2 Source requirements: https://slsa.dev/spec/v1.2/source-requirements (2026-10-01)
- GitHub Terms of Service: https://docs.github.com/en/site-policy/github-terms/github-terms-of-service (2026-10-01)
- GITHUB_TOKEN: https://docs.github.com/en/actions/concepts/security/github_token (2026-10-01)
- Rulesets: https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/available-rules-for-rulesets (2026-10-01)
- Copilot code review: https://docs.github.com/en/copilot/concepts/agents/code-review (2026-10-01)
- Copilot coding agent risks: https://docs.github.com/en/copilot/concepts/agents/coding-agent/risks-and-mitigations (2026-10-01)
- Prow approvers: https://docs.prow.k8s.io/docs/components/plugins/approve/approvers/ (2026-10-01)
- Chromium Rubber Stamper: https://chromium.googlesource.com/infra/infra/+/refs/heads/main/go/src/infra/appengine/rubber-stamper/README.md (2026-10-01)
- Apache lazy consensus: https://community.apache.org/committers/lazyConsensus.html (2026-10-01)
- Anthropic, Claude Code auto mode: https://www.anthropic.com/engineering/claude-code-auto-mode (2026-10-01)
- OpenAI, Practices for Governing Agentic AI Systems: https://cdn.openai.com/papers/practices-for-governing-agentic-ai-systems.pdf (2026-10-01)
- GitHub App permissions: https://docs.github.com/en/rest/authentication/permissions-required-for-github-apps (2026-10-01)
- npm trusted publishing: https://docs.npmjs.com/trusted-publishers (2026-10-01; environment binding not verified)
- Platform measurements:
github.com/stranxik/runward-delegation-lab, Apprunward-steward(id 5150097), T1 to T5, 2026-10-01.