Repository navigation
History Kernel
Accepted 2026-10-09 by the project board, after unanimous review across four independent labs (none the author's lab). Tier 1 of TeamCLI's RFC re-architecture: the one fixed, enforced layer of authority, capabilities and trust that every other tier conforms to. It absorbs RFC 001: Security and the enforced half of RFC 009: Roles & Skills.
Authors: the project's founder, with Claude (Opus 5.5). Part of TeamCLI's RFC re-architecture; see RFC 000: The Charter (Tier 0).
When a team of AI agents does your project's work, and the agents themselves operate TeamCLI, what is the complete set of things the tool will refuse to do — and what makes each refusal mean something rather than a sentence an agent can talk its way past? Read this document alone and you have audited all of TeamCLI's power: every capability is named in §3, every operation's principal in §9, every limit on enforcement in §12.
Four facts, carried from RFC 001: TeamCLI is operated by agents; an agent that works for you runs as you unless contained; so TeamCLI must contain its agents, and today does not; and there are two kinds of protection — against an attempt and against a mistake — and the tool always says which, saying the weaker when unsure. Today nothing in the Kernel holds against an attempt (§14).
The membership test: a thing is in the Kernel iff the tool refuses the action without it (with the two named non-refusal exceptions stated just below — inherited obligations and carried advisories/status). What only advises, informs, or describes is otherwise pushed out to a module (§13). Where the Kernel states an obligation the tool cannot itself refuse (the owner is told, §11), it says so and names who delivers it. Put precisely: the Kernel owns every enforced rule — each one a refusal — and in addition records a small, named set of inherited obligations it cannot itself refuse, naming who delivers each; the refusal test decides what is enforced, and the named obligations are the stated exception, not a second policy owner [new]. The Kernel also carries two kinds of non-refusal text, named as such and never the basis of a gate: a few advisories inherited from 001 (the envelope-sequencing of §8) and the structural/status sections (§12 costs, §13 the modular boundary, §14 today-table, §16 where it sits, §17 review) — these inform; they neither enforce nor make a second policy owner [new].
A capability is a permission the tool enforces — a power it checks before a seat acts. It is not a competence; competence is a skill (Roles & Skills module) and a skill never gates (§5, §13). A capability grants nothing by name alone. Where this document says a seat's right (to grant, agree, create), that right is a capability — "right" is prose, never a second kind of thing.
The vocabulary is closed, enumerated, and release-versioned. A capability a team file names that the tool does not know is refused, not honoured. The complete set for this release is below; a later release adds to it only in a release, and a team's config pins the capability version. A new version never lengthens a seat's list by itself (001 commitment 1), and never widens what an existing name means [new]: a release that widens an existing capability's operation or scope interpretation counts as a new capability version and needs a fresh agreement (§10). A capability a later version renames or removes is resolved at launch and fails closed if a seat's pinned list no longer resolves.
The tool-reserved set. The team file, the ledger and its head, the verifier, .git, the signing and
broker material, and the start files the tool pins (§10) are reserved authority objects. No scope,
role, lease or ceiling opens them to any seat-requested effect — not write, not read, not merge
(below) [new]. Matching is by object identity, not name: after canonicalization (§6) a path is
reserved if it is or lies under a reserved path, or if its inode is also reachable by a reserved name.
The tool's own services — the grant and agreement mechanism that updates the team file, the ledger
writer, the merge service maintaining .git — change reserved objects through narrow Kernel-defined
transitions, never through a seat-requested file effect (round 3, Astra/Grok). The line between the
two: a merge whose change-tree touches a reserved path is refused; the git-internal update of .git
for a tree that contains no reserved path is the merge service's allowed Kernel transition, not a
seat-requested effect [new].
Operational capabilities (each carries a scope, §6; the dimensions each takes are listed with it):
-
write(path) — change files in the project. It never covers a reserved object (above). -
read(path) — be served the contents of files in the project [new, restores 001 commitment 5]. A seat is refused files outside itsreadscope — the folder-by-folder, per-lab disclosure refusal 001 committed to. Every disclosure of file contents by the tool is aread: a diff, a review view, a merge or write diagnostic and a record that embeds file contents are served only within the requesting seat'sreadscope, whichever capability the operation runs under — the one exception is the two-granter confirmation view in the controlled record view below, served within the confirmer's ownreadscope [new; carries the exception pointer so the two sentences no longer contradict]. A reserved object is never served raw; a controlled record view is a separate, tool-built output limited to an enumerated allowlist — the requesting seat's own resolved capabilities, its own live leases, the named rule of a refusal that just applied, and — only for a seat that must confirm a two-granter agreement — a proposal/difference view bound to the exact change proposed and no broader (the tool-shown difference of §10, confined to that one proposal, served within the confirmer's ownreadscope — every disclosure is aread(above) — and withholding unrelated project content and any field the secret-shape check flags) — and nothing else [new].readis distinct fromwrite: a path a seat may change is not automatically one it may see, and the reverse. What a lab learns is what its seats were served — the union of its seats' scopes — and the owner's per-lab setting (§8) caps that union. -
review(path,branch) — record a verdict on a change. -
gate(path,branch) — let a change pass a required check. -
merge(path,branch) — bring a change into a trunk. Amergeis refused unless it consumes a successfulgatedecision bound to the same effect (§15) [new], and it is refused for any change that touches a reserved object: those change only through the owner's or agrantholder's agreement (§10), never through a merge. -
deploy(env, optionallybranch) — release to an environment. Adeployconsumes a successful, still-validgatedecision (or themergethat consumed one) whose effect id matches the artifact it ships, exactly asmergedoes (§15): an ungated tree cannot be deployed [new]. The consumed pass proves what is shipped only; where it goes (theenv) and under whose identity (theaccount) are authorized independently, at deploy-time, from the deploying seat's owndeploy(env)andact-as(account)scope — the effect id carries no environment, so a gate pass blesses an artifact, never a destination [new]. The pass is re-validated at deploy-time: the deploy is refused if the pass has since been revoked or voided by arefused/unknownoutcome for its effect id (§15). **A failed deploy'srefusedoutcome voids the artifact's pass, so promoting the same artifact to another environment requires re-gating — intended fail-closed behavior; because the effect id excludes the environment, a voiding outcome voids the artifact's pass in every environment [new]. It is exempt only from the cross-lab / author-inequality of separation of duties by design — the gate and merge upstream carry that — never from needing a gated tree [new]; an owner who wants the author-inequality on deploy too adds the constraint of §5. -
use-broker(the task resources the owner declared, §8) — be served a secret-bearing resource through the broker [new; renamed from the draft concepthold-credential]; the seat never holds the secret. The operation list is in §11. -
act-as(account) — use the owner's external identity (the push, publish or comment account) through a command the tool mediates [new, restores the interim rule of 001 §4]. The accounts are a declared set, owner-sovereign (§8).mergeanddeploydo not imply it; a seat without it is refused wherever the tool would act under the owner's name.act-asis required in addition to — never instead of — the operational capability the action itself needs (a push that merges needsmergetoo; a publish that deploys needsdeploytoo) [new].
A dimension a capability does not take is rejected at launch, not ignored.
Administrative capabilities (no project scope; each is its own gate; none is ever leased, §7):
-
create— start a team, bounded by what the giver wrote (§10). -
grant— give a capability to a seat; a holder is a second owner (§10) — bounded by §8. -
agree— confirm a same-copy change (§10); never a grant. -
leads— the single authority root (§9).agree,grant,createandleadsare never copied (§10).
Team-lifecycle operations — start, stop, add a seat, remove a seat — are executed through the
Runtime and authorized by the table in §9, which gives each exactly one principal; they are the
degenerate case of today's tool (§14) and are named here so the closed set is complete.
A role is a named bundle binding capabilities (with scope §6, constraints §5) to a seat. The Kernel owns the enforced structure; the owner-facing part (which roles exist, names, templates, inheritance, the library) lives in the Roles & Skills module (§13). A seat references roles and may hold direct capabilities; the tool resolves them to one capability-with-scope set checked at the gate. A capability not in the vocabulary (§3) resolves to no gate and is refused at launch. Identity signs; it does not grant. A role is agreed as its resolved content (hashed and kept, §10), so an unchanged name can never silently resolve to wider permissions. [New relative to 001: 001 enumerated a command-list per agent; role composition, resolution to a capability-with-scope set, and the what/how split are new here.]
A small enforced constraint language sits beside the grant. It ranges over capabilities, scopes,
seat identities, and Kernel-defined ledger records only — grants, agreements, leases, review records,
and gated actions — and never over a record a module writes. A violation is a visible refusal naming the
rule. Who may change the program: the constraints the owner writes — minimum cardinality, maximum
cardinality, mutual exclusion, and the review mode (below) — are owner-sovereign (§8): a grant
holder cannot change them at all — neither loosen (lower a minimum, raise a maximum, delete an
exclusion, weaken the review mode) nor tighten them; every constraint-program change is owner-only (§9)
[new; maximum cardinality and the review mode join minimum and exclusion in the sovereign set, and
tightening is owner-only too — aligning §5/§8 with the §9 table].
Separation of duties and the lab predicate below are tool-fixed: no team file, role or grant switches
them off [new].
Checked at three times, each constraint declaring which:
- At launch (static): mutual exclusion of capabilities/roles on one seat; minimum/maximum cardinality of seats holding a capability/role.
-
On every authority change —
add,remove, a standing grant, a lease issued (each a request): all three composition invariants — maximum cardinality, minimum cardinality, and mutual exclusion — are re-checked over each seat's effective authority (standing list plus live leases), atomically with the change, concurrent changes counted in ledger order. A request that would break any of them is refused, naming the rule [new; continuous re-check over standing-plus-leased authority]. -
Expiry, revocation, stop, and a lease's source ceasing to cover it (§7), are not requests: they apply unconditionally [new]. A lease dies at its expiry
and a revoked power ends, however the minimum then stands; the tool never keeps a power alive to keep a
floor met. When a minimum becomes unmet this way, the acts that
minimum gates — the
gateandmergewhose cardinality or review floor it sets, and any act the owner bound to it — pause until it is restored (and the owner is told, §11) [new]. An owner can always revoke a compromised power or stop a team. An owner's own narrowing or revocation is not a request: it commits unconditionally, its cascade appends in the same atomic batch (§7), and any floor it leaves unmet pauses — whereas agrantholder's request that would break a minimum is refused. So "an owner can always revoke" and "a request that breaks a minimum is refused" do not conflict: the owner path commits-and-pauses, the delegated-request path is refused [new; resolves the narrow-vs-refuse tension]. Where a minimum depends on a compromised seat, the owner's removal likewise commits and pauses the floor (no revoke-then-lower-then-remove dance is forced, though the owner may do that to avoid the pause). -
At the gate (act-time), against the signed ledger: separation of duties — the seat(s) that
wrote a change may not gate or merge it — nor
deployit, where the owner bindsdeployto this author-inequality [new; the act-time author-set check, extended todeployon the owner's say-so]. Authorship is read from the ledger's full author set; if it cannot be established the act is refused. This owner extension is the per-change author≠deployer check, over the ledger author set — incomparable to the same-seat mutual-exclusion of §3: that exclusion is the more restrictive on the same-seat axis (awrite-holder may then deploy nothing, its own or others'), while this check covers multi-author changes the exclusion does not (a deploy-only seat deploying another seat's change) [new; corrected — the two are incomparable, neither simply stronger]; the §9deployrow carries it.
Cross-lab review is a lab predicate, not a seat count [new; relative to 001, which asked for different labs only for two-granter agreement (001 §6)]. The owner sets, per team, a review mode:
-
Cross-lab mode:
lab(author) ∌ lab(gater)andlab(author) ∌ lab(merger)for every author in the full author set [extended to the merger, so a same-lab author cannot merge after a cross-lab gate], and, where the owner sets a review floor, ≥N reviewer seats from distinct labs. A seat'slabis a binding signed by the owner (§8) — a seat-asserted label establishes nothing. If any author's, the gater's, or the merger's binding is missing or unsigned, the act is refused — not downgraded, not paused: the integrity claim rides on the refusal. The mode is never automatically downgraded — only an owner act changes it (§8). - Distinct-seat mode: an explicit, owner-chosen policy that requires only distinct seats. The tool names this mode in every record and view and never calls it cross-lab.
Whichever mode, the owner-signed lab binding identifies the actual adapter and launch configuration
the tool checks a seat against, not merely a label beside it [new]; it is only as trustworthy as
where the seat runs until containment (§11, §14 marks it), and the tool does not claim the binding itself
holds against an attempt. Whether a review was
actually given is Quality's judgement over the ledger (§13), expressed, if the owner wants it enforced,
as a cardinality/SoD constraint over the Kernel review record — not a module predicate.
An operational capability carries a scope over the dimensions it takes (§3): path, branch, env,
account, and the broker's task resource set. Defined here (not RFC 008). [New relative to 001: 001
bounded commands and repositories; the path/branch/env/account/resource scope grammar is new here.] Each dimension is one of three
states, kept distinct:
-
Unconstrained — omitted or
*: the whole declared set on that axis. The tool prints it rather than leaving it assumed. - Bounded — one or more values/patterns.
-
Empty — written
[]; it means nothing, and a capability with an empty dimension grants nothing.
Every named set a dimension draws from is a declared set, owner-sovereign (§8) — and so is what each name resolves to (the target behind staging, an account, a task resource; changing it is an owner act, not a grant) [new]: branch, env,
account, the task resources, and the repository roots. A name or ref outside the declared set is
outside every scope, unconstrained or globbed — a seat cannot widen the world by creating a ref.
-
path— repo-root-relative prefixes, relative to a declared root (a submodule or linked worktree is outside every scope until the owner declares it a root). Matched component-wise after canonicalization (symlinks resolved,./..removed, and case/Unicode folded as the target filesystem folds, never more broadly); a prefix covers a file iff the file's canonical path is at or under it as whole components (docs/does not coverdocs-secret/). Objects, not names: an effect on an inode — or the platform file identifier where the filesystem exposes no inode, the NTFS FileId on Windows [new] — that is reachable by any name outside the scope or inside the reserved set (§3) — a hard link, which has no target to read — is refused; the check is on the object's link set, not a link target. Where the filesystem exposes neither an inode nor a file identifier, or the object's link set cannot be completely and stably determined, the effect is refused (fail-closed, §11) [new] — the workable reading isst_nlink-based: refuse a multiply-linked object whose link count exceeds the names in scope, rather than promise a full-tree scan. Authorization is checked on the opened object and stays stable through use. -
branch— names or*-globs over the normalized ref namespace (main≡refs/heads/main; a glob matches the short name), evaluated against the declared branch set, not against whatever refs exist at use time. -
env,account, the task resources — names from their declared sets.
A is within B (for attenuation §7 and the ceiling §8) iff, per dimension: B unconstrained ⇒
always within; A empty ⇒ within; otherwise every value/prefix of A is covered by B (component-wise
for paths; for refs, a glob g₁ is within g₂ iff every name g₁ matches also matches g₂). The relation
is total and decidable; a pair it cannot decide is refused, not treated as universal.
Intersection is per-dimension, commutative, and: unconstrained ∩ X = X, empty ∩ X = empty.
Authorities are alternatives, never merged: several scoped authorities for one capability — standing
grants or leases (merge(docs/, main) and merge(src/, feature)) — stay separate, and a multi-path
operation must be covered whole by one single live authority (one standing grant or one lease), never
assembled from pieces of several grants, several leases, or a grant and a lease together [new]; a
change that fits no single authority is a mixed-scope change and is refused, not partially applied. Scope is checked at the same gate as the capability, against the action's
actual effect — the full set of paths a change touches (renames and copy-from count as paths
touched; the destination tree is diffed against the destination ref, not a caller-chosen parent) and the
real destination ref/environment/account the operation resolves to, not a caller-supplied label. The
artifact of that effect — paths, destination tree, destination ref, base, policy — is bound to an
immutable effect id (§15) that a gate pass is keyed to; the environment and account are authorized
against the seat's own scope at act-time and are not part of the effect id (§3 deploy, §15) [new].
Delegation is a bounded capability grant. RFC 010 is retired. Two shapes:
- Standing grants — the roles of §4, in the team file, held until changed (§10).
-
Leases (conferral + attenuation) [new] — a holder hands an existing seat a signed, recorded,
time-bounded lease: a root lease confers from an envelope, a re-lease attenuates a held
lease (the two origins below). Only operational capabilities are leasable. Every administrative capability (
create,grant,agree,leads) is never in a lease (an allowlist, not a list of exceptions).
A lease has exactly two origins [new]:
-
Root lease — its source is a standing grant the issuer holds, or the
leadsenvelope when the issuer isleads— named in the lease's root-grant field (§15); it has no parent, and is live only while that named source currently covers it (liveness below). Only a seat acting from a standing grant, orleadsacting from its envelope, may issue one — and, like any lease, only while the team has a presentleads(§9). - Re-lease — its source is a lease the issuer holds; its parent pointer is mandatory and names that held lease; it is an attenuation checked against its live parent, never against the team envelope — never wider than the parent, never past the parent's expiry.
A lease presented with no parent whose issuer is acting from a lease — not from a standing grant — is refused [new]. The mandatory parent is exactly what the ancestor ban and the revocation cascade both rely on: a parentless re-lease can no longer exist to escape either.
A lease is anchored:
- A lease is a first-class, immutable ledger record (§15): a lease id; its parent lease (mandatory for a re-lease, absent only for a root lease); the root grant it derives from; the issuer; the recipient (an existing member seat, by its stable identity); the capability-and-scope; the issue time; and a hard expiry. It has no mutable field: it is revoked by a separate revocation record, and "revoked" is derived, monotonic state (§15). The gate authorizes a leased action only by reading a live lease (not expired, no revocation record, and its whole lineage live — the liveness walk below) whose capability-and-scope covers the effect. "A seat holds its list and its live leases, and nothing else" [changed-from-001].
-
A lease is live only while the authority it descends from still covers it — up the whole chain to the
originating grant [new; completes draft 5's mandatory-parent rule]. The gate validates a leased
action by walking the lease's lineage against current authority: a root lease is live only
while its named source — the standing grant the issuer holds, or the
leadsenvelope, in its root-grant field (§15) — currently covers its capability-and-scope and the issuing seat still holds that source (reassigning the source to another seat, even at an unchanged scope, kills the lease), under the current deny and ceiling; a re-lease is live only while its parent is live and its whole chain, the originating grant included, is live, and it too is bounded by the current deny and ceiling (not only its parent). Any link ceasing to cover the capability — the originating grant removed or narrowed, theleadsenvelope narrowed,leadsremoved, a parent expired or revoked, or a scope name the lease depends on retargeted (§8) — kills the lease and everything below it, whether or not a revocation record was written for it. Narrowing or reassigning a grant, or removingleads, also eagerly revokes every lease below it — re-leases by the parent pointer each carries, root leases by their root-grant field — appending a durable revocation in one atomic ledger transition with the narrowing/removal (both commit or neither) (cascade); the lineage walk is a use-time check, and the durable revocations are the anti-revival guarantee: a later restoration of the grant does not revive the dead lease — a restored grant is a fresh grant (§5 re-checks it), under which new leases may issue while the revoked ones stay dead. Because any operation that kills leases — narrowing or reassigning a grant, removingleads, retargeting a declared name (§8) — commits its cascade revocations in one atomic ledger batch with the operation itself (the store writes the whole batch or none of it), there is no torn state: recovery sees the operation together with its revocations (leases dead) or neither (leases still live), never the operation without its revocations — so no crash window can revive a lease, and a later restore or retarget-back is always a fresh grant [new; round-8 SHOULD: the atomic-batch requirement stated directly, replacing a dangling §15 reconciliation cite, and it closes the retarget window too]. One narrowing is a use-time shadow, not a durable revocation: narrowing the ceiling or the deny hides a lease at the gate while the narrowing stands, but writes no revocation and is not in the cascade — so restoring the ceiling re-covers the lease. This is intended (the owner's durable path is a direct revocation, §7); only grant/leads/retarget changes append durable cascade revocations [new; round-9 nit: ceiling/deny shadowing is use-time, revocation is durable]. So no delegated power stays alive after the authority it descends from is gone — now literally, for a root lease as for a re-lease. -
A hard maximum lifetime bounds every lease: the
lease-ttldimension of the ceiling (§8), owner- settable under a tool maximum no lease may exceed; a "years-long lease" is refused. -
A lease never returns authority upward — over its whole chain, at any number of hops
[new; the ban ranges over the full chain, not the parentless form — closes the round-7 MUST].
The recipient of any lease — root or re-lease — may be neither
leads, nor the chain's originating issuer (the seat that issued the root lease), nor any seat upstream — an issuer lying between this lease and the originating grant along the mandatory parent pointers — nor the issuer or recipient of any lease already in the chain (compared by stable seat identity). So defined, the "upstream" seats are themselves in-chain, so that clause only ever further-restricts; and for a root lease drawn from a standing grant the originating issuer is the top of the chain, so nothing is upstream of it — the ban then reduces to excludingleads, the originating issuer, and the in-chain seats [new; the "upstream" wording now matches its walk-based definition]. Stated plainly as the invariant: no lease path, of any length, may land an operational capability on a seat that a direct root lease could not — the authority rootleadsabove all — nor hand it back up the chain it descends from. The check is over the chain's full constraint set, computed by walking the mandatory parent pointers to the originating issuer and its root grant (§15) — not immediate parent-chain membership alone. SoA'smerge(trunk)cannot reachleadsthroughB's re-lease, nor through any longer relay; a non-executingleadscannot reacquire, through any chain of leases, a capability it only holds in its envelope (round 3; the round-7 one-hop bypass is closed here). - A lease binds to an identity (§9, §10). Rebinding a seat (§8), or removing a seat (§9), revokes every lease it holds or issued, each by a signed revocation record (§15) [new].
-
Revocation is a signed record; the owner,
leads, or any issuer above the revoked lease in its chain may revoke it. -
Selected contract (confer, not attenuate-only). A root lease may confer any operational
capability within the authority it is drawn from — the issuer's own standing grant, or the
leadsenvelope only when the issuer isleads(§9), recorded and bounded — it is what lets a non-executingleadsdelegate at all; a re-lease only attenuates its parent.act-asis operational and so is leasable like any root lease — within the issuer's ownaccountauthority (its standingact-asgrant, or theleadsenvelope only when the issuer isleads), bounded by the declaredaccountset (§8) (§17). The attenuate-only form (a lease only narrows what the issuer executes) is the alternative; this draft selects the envelope form, with the ban above and the mandatory parent, and the board ratifies it (§17).
Free composition is safe because it sits under a boundary the tool holds:
-
Owner-sovereign limits [changed-from-001: reserves whole classes of change to the owner, narrowing 001 §6's second-owner grant model]: the ceiling (bounding set, with the
resource dimensions below and
lease-ttl), the explicit deny, the delegation envelope (§9), the create-bounds (§10), the constraint program's owner-written part (minimum cardinality, maximum cardinality, mutual exclusion, and the review mode, §5), the two-granter requirement (§10), and every declared set —env,branch,account, task resources, repository roots andlabnames — plus the seat-to-lab binding (which lab a seat is, and the rebinding of a seat) are set by a signed owner act. A second owner (grantholder) may grant within them but may not change them. Raising a ceiling, deleting a deny, widening an envelope, lowering a minimum, raising a maximum, weakening the review mode from cross-lab to distinct-seat, deleting an exclusion, removing the two-granter requirement, addingprodto the declaredenvset, or rebinding a seat's lab is not a grant — it is an owner act; so is every tightening (raising a minimum, lowering a maximum, adding an exclusion) — the whole constraint program is owner-only, §5. A rebind durably revokes every lease that rested on the old binding (re-granted, not re-agreed — matching retarget, §7), and invalidates every read grant, agreement and budget attribution that rested on it, until agreed again (round 3, Astra); the spend counter and the unattended-runtime timestamp keep counting across a rebind — invalidated attribution never reopens the remainder [new]. Retargeting or removing any declared-set name — anenv,branch,account, repository root or task resource — durably revokes (a durable revocation in the same atomic batch, §7) every lease whose scope names it, and invalidates every other authority and evidence that rested on the old target; removing a name from a declared set revokes, fail-closed, everything that depended on it, and re-adding the name later does not auto-restore them — they must be re-granted; a name never silently re-resolves under a live lease (§4) [new; addsbranch, and the remove-then-re-add rule]. - Deny wins through every role, overlay, lease, and envelope.
- The ceiling bounds capability-and-scope, and the resource dimensions (next): a capability or scope outside the ceiling is unreachable even if a role or lease names it.
The resource envelope [restores 001 commitment 1]: the owner-sovereign ceiling bounds how many
seats (per lab), how much may be spent, how long a team may run unattended, and how much any
one lab may be shown — a per-lab cap on the union of that lab's seats' read scopes (§3) [new].
Irreversible powers (publish, deploy, delete, spend, write where others read) open last — advisory sequencing of how an owner builds the envelope, not itself an enforced gate; 001 commitment 1 placed this sequencing inside the commitment, and this draft demotes it from commitment to advice [changed-from-001]. The Kernel
owns the rule; the Runtime supplies timers, meters and process control and sets no policy of its
own. The rule counts:
-
Spend — an amount in the provider's billing currency, per team and per lab, over an owner-set
period, as reported by a meter the broker or provider signs. Before the tool dispatches work it
reserves the owner-set per-dispatch maximum against the remainder, so concurrent dispatches cannot
together exceed it; work is refused or stopped at the next boundary when the remainder cannot cover
the reservation. Usage the tool cannot establish — unknown or stale beyond the owner's limit — counts
as spent (fail closed). A team's
create(§10) debits the child's slice atomically at create-time — against both a single enforced aggregate ceiling and each named per-lab cap: the owner-signed create-bound names the child's slice as an aggregate spend amount and explicit per-lab amounts — each lab, its spend, its seat allowance — andcreatedebits the aggregate from the creator's per-team remainder and each per-lab amount from the creator's matching per-lab remainder, in one atomic transaction (net of the creator's in-flight reservations in each dimension), before any secondcreateor any child dispatch can read them — the same reservation discipline as a dispatch. Creation is refused if either the aggregate or any per-lab dimension cannot cover its slice; the per-lab caps are independently tighter floors that never replace the aggregate, and the binding limit on any spend is min(aggregate remaining, lab-slice remaining) [new; round-9 MUST: the aggregate/per-team debit is restored alongside the per-lab debit — per-lab conservation alone did not imply the separately tighter aggregate cap]. A child seat'saddis then checked against its lab's named slice and debits nothing further; anaddin a lab the bound did not name, or beyond that lab's slice, is refused. So conservation holds in the aggregate and per lab — the authorized spend across a creator and all its descendants, in every lab and in total, is at most the creator's cap, conserved; and because the bound names the labs, the child's lab distribution is known at create-time [new; the per-lab debit is at create-time via the named bound, not deferred toadd— closes the round-8 per-lab conservation hole and the draft-8 §8 contradiction]. A child dispatch reserves against its per-lab remainder as well as its per-team slice; seat-adds within one lab serialize against each other and against in-flight dispatches; and the sum of the named per-lab slices never exceeds the aggregate. Removing a child seat does not return its slice to the creator — the slice stays with the child team; and a child may onward-createonly within its own create-bound, debiting a grandchild's slices from the child's own per-lab remainders — the same discipline, recursively [new; round-8 MUST specifics]. Spend is a per-period cap, and a carved slice persists across the creator's period rollover [new; round-9 MUST + DeepSeek SHOULD-3]: a child carries its origin period, and each period the creator's per-lab and aggregate remainders arecap − reported spend − in-flight − the slices already carved to descendants— carved slices are not refunded at a period roll, and each descendant's per-period amount refills only to its named slice, never higher — and never past the current remaining cap: a refill, and every dispatch, re-validate against the aggregate and per-lab caps as they stand that period, including any the owner has lowered, so lowering a cap below standing carves shadows the excess at use-time (as §7's ceiling shadow does) — the invariant only tightens, never loosens [new; round-10 SHOULD: a refill is bounded by the current cap, not only the named slice]. A dispatch that crosses into a later period re-validates against that period's remaining aggregate and lab caps and never receives a fresh full cap on top of the already-carved descendant slices. Invariant: across any period roll, the total committed spend — the creator's own plus every descendant's refilled slice — is at most that period's cap, in the aggregate and in each lab. The formula applies recursively at every level: an intermediate child's own per-period remainder is likewiseits cap − its reported spend − its in-flight − the slices it has carved to its grandchildren, so a child cannot refill its full slice while its own carves also refill. Example: C carves D1 a $300 slice and D1 carves G a $50 slice; at a new period C refills to its cap less $300, D1 to $300 less $50, and G to $50 — the chain sums to C's cap, never more [new; round-10 SHOULD: the refill subtraction is recursive at every level]. The shadow is a single, prospective, serialized draw-down [new; round-11: the remaining §8 residuals as one rule]: the remaining tree budget each period is the remainder defined above, before the slices carved to descendants are subtracted —cap − reported spend − in-flight— and every refill and dispatch across the whole descendant tree draws down that one remaining budget, in serialized order (as seat-adds already serialize), not by independent per-node re-validation against the raw cap. The creator's own further spend is that remaining budget minus the slices still carved to descendants; a descendant's refill takes its recursive remainder only out of what the tree budget still holds. The shadow is prospective, not retroactive (as §7's): already-reported spend and irrevocably-committed reservations stand and cannot be un-spent — the invariant is read as the cap in force at each commitment — so lowering a cap bounds only future refill and dispatch, authorizes no new commitment past the lowered cap, leaves any overage visible, and refuses further authorization while no remainder exists. Examples: 80 is already spent and the owner lowers the cap to 70 — the 80 stands, shows as a 10 overage, and nothing more is authorized while the applicable period's remainder, net of in-flight reservations, is nonpositive. C's cap is $1,000 with a carve of $600 to D1 and $500 under D1 to G; the owner lowers C to $400 — the whole branch may commit at most $400, drawn from the one remaining tree budget in order, never $400 per node. A cap lowered mid-period to 50, with 20 already metered (committed) and a carved slice of 70 outstanding: the 20 stands, the 70 carve is shadowed to fit, and only 30 more is authorized across the descendants (the one remaining tree budget), for a period total of 50. - Unattended runtime — the time since the last owner-signed act (the only trusted renewal event). A restart, a handover, a new lease or an agent-reported "approval" does not reset it. At the limit, the team pauses and the owner is told.
-
Seats — the count of live seats, per lab, checked at
addand at launch. -
Per-lab visibility — the union of a lab's seats'
readscopes may not exceed the owner's per-lab read cap; areadthat would widen the union past it is refused (§3) [new]. -
A created team inherits within the creator's envelope, by the same conservation as the spend slice
[new]: its per-lab seat allowance is named in the create-bound and atomically debited from the
creator's matching per-lab remainder at create-time — several children cannot each consume the same
remainder — and its unattended-runtime clock inherits the creator's remaining time. An agent's
createis never an owner-signed act and mints no fresh runtime (only a genuine owner act resets the clock, §11); an agent cannot buy a child a fresh window by creating it at minute 59. The owner's create-bound (§10) may instead state an explicit child-runtime window; absent that, the child runs down the creator's remainder. A later owner act on the parent does not renew the child's clock (consistent withcreateminting no fresh runtime) [new]. A lab's remaining seat allowance is the cap minus its live seats minus the per-lab slices already debited to descendants; acreatewhose named per-lab seat or spend slice does not fit the matching remaining allowance is refused [new].
This is a measured, soft bound until effects are mediated: the tool refuses and stops its own dispatches past the line; an agent already running and spending on its own credential is not stopped (§12). It is a ceiling only as far as the provider's own limit or mediated spending makes it one, and the tool says so. [Selected contract:] spend and runtime stay in the Kernel ceiling as commitments, as drafted; the board ratifies it (§17).
Exactly one capability is tool-owned and singular: leads. It is only three things: the holder of
the delegation envelope the owner signed; the root of the delegation envelope and the chains that
descend from it; and the single team-level address — the one seat the tool and the broker send a
team-level question to. (A root lease need not descend from leads: an ordinary standing-grant holder
may issue one from its own grant, §7 — such a lease's originating authority is that grant, not the
envelope.) The address is not an
authorization: who may do an operation is the table below, and nothing is inferred from leads being
the address. Operational powers (merge, deploy, gate) are separate capabilities, never part of
leads.
leads holds the root envelope; a lease drawn from it is a bounded subordinate envelope derived
from it, a re-lease derives a narrower one, and a root lease from an ordinary standing grant derives
from that grant instead (§7) — each checked, at use time, against the authority it names (§7 liveness). Zero or one leads per team. Zero = no lease-derived delegation (the owner's standing grants still
function), owner present; no lease of any origin can be issued — a present leads is the prerequisite
for any lease, a standing-grant holder's root lease included [new]. Two is refused. A deputy is a
second seat given the operational capabilities without leads. If the leads seat is gone, authority
does not pass itself: the owner reassigns it or --abandons, and the tool appends a revocation for every live lease in the
team — the selector is all live leases, not only those below leads by parent pointer or root-grant
field — so no delegation survives without a leads (§7) [new; names the departure selector].
The authorization table [new]. Each operation has exactly one authorizing principal (whose signature the ledger records as signer); the executing actor is recorded separately and authorizes nothing. The one exception is a two-granter change: it records a primary signer plus one co-authorization — two signatures over the same canonical proposal (§10) — rather than a single principal [new; reconciles the single-principal schema with two-granter].
| Operation | Authorized by | Bounds |
|---|---|---|
start a team or seat |
owner, or leads for its own team |
runs the hash-pinned start command and its full hashed execution context — lab, working root, environment bindings (§10); takes no command argument and refuses a caller-supplied environment; a create whose bound says "also starts" triggers it (§10) |
stop a team |
owner, or leads for its own team |
a team stop never reaches another team |
| machine-wide stop | owner only | §11 |
add a seat that is a same-copy (§10) |
an agree holder, or the owner |
leads may execute it; it authorizes nothing |
add any other seat |
owner, or a grant holder |
a grant: inside §8, two-granter where the owner set it (§10) |
remove a seat |
owner, or leads
|
a seat holding grant, agree or leads is removed by the owner only; removing any seat revokes every lease it holds or issued, and removing leads revokes every live lease in the team (§7); a delegate's removal that breaks a minimum is refused, while an owner's removal commits and pauses the floor (§5) |
| issue a lease | the issuer | within the issuer's live parent lease (re-lease), or a standing grant the issuer holds, or the leads envelope only when the issuer is leads (root lease); parent pointer mandatory when the source is a lease; the lease stays live only while that named source covers it and the issuer still holds it (§7); the recipient passes the whole-chain ban, a present leads is required, and a two-granter capability needs a co-signed lease; re-checks §5 |
| grant a capability or edit the team file | owner, or a grant holder |
inside §8; two-granter where set, though the owner may grant alone. leads has no grant power |
| a team-file change that is not a same-copy | the same | a grant (§10) |
| revoke a lease | owner, leads, or a holder above it |
§7 |
--abandon |
owner only | |
a use-broker call |
the requesting seat, by its own scope and deny |
leads is not a proxy and is not required in the call; it is the root of the delegation envelope, not of a lease a seat holds from its own standing grant (§7) |
act-as |
the seat holding it, within its account scope |
|
write, read, review, gate, merge, deploy
|
the seat holding that capability, within its scope (§6) and the constraints of §5 |
merge/deploy consume a valid gate pass (§15); the author-inequality binds gate/merge, and deploy where the owner binds it (§5); a deploy under the owner's identity also needs act-as (§3) |
create (execute) |
the seat holding create, within its create-bounds (§10) |
recorded as that seat's act, never the owner's; resets no unattended clock (§8) |
| rebind a seat's lab, change a ceiling, deny, declared set, minimum, maximum, exclusion, the review mode, or the two-granter requirement | owner only | §8, §10 |
The owner can do everything above except where the table says otherwise; a rule written on the owner is
never given to leads by implication. Where a signed approval is submitted by another seat, the
ledger keeps the approver as signer and the submitter as actor. The operational row names the capability
principal; where an action also acts under the owner's identity it additionally needs act-as (§3), and
any file content it discloses stays within the seat's read scope (§3) — these compose with the principal,
they do not replace it [new].
The grant/agreement mechanism is carried from RFC 001 §6. The model collapses if any of these is advisory.
- A list for each seat; a seat holds its list and its live leases (§7) and nothing else.
-
Agreeing is narrow; granting is its own word. An
agree-only seat may agree to one more seat that is a copy of one the team has — "the same" is checked as hash identity of the start/instruction files, the resolved role content and the resolved capability set, together with the rest of the execution context 001 §6 names (lab, working root, environment bindings — hashed and kept, so the hash is auditable), not a semantic text compare. The copy holds neitheragree,grant,create, norleads, and inherits no live lease [changed-from-001: the copy also excludescreate,leadsand any live lease]. Anything else is a grant: granting never comes by shorthand — no agent holds it unless the owner writes it, and a holder is a second owner, bounded by §8. -
addis never a third grant channel. A new seat's list is whatever its agreed copy or grant says — never whatleadsor the executing actor chooses (§9).startruns the pinned command and its full hashed execution context — lab, working root, environment bindings — and only those, refusing any caller-supplied environment [new]. -
The all-capabilities word means the vocabulary as agreed, and never includes
grant,leads, orcreate[changed-from-001:leads/createadded to the exclusion; marked]. -
By default, nobody but you [restores 001's safe default; 001 already withheld the all-word, so only
leadsand a pre-filled envelope are additions — a new team is given none of them]: a new team gives no agentagree,grant,create,leads, the all-word, or a pre-filled envelope; a fresh machine grantscreateto no agent (001 §6). -
createis written on the machine, bounded by what the giver wrote — how many teams, where, which start commands, whether creating also starts, whether the new lead may be givengrant(off unless given), the child's slice — an aggregate spend amount, and per lab its spend and its seat allowance — and any explicit child-runtime window (§8) [new; the aggregate + per-lab slice and the child-runtime window are additions to 001's create-bound]. These bounds are owner-sovereign.createis non-transferable — never copied, leased, or issued onward by any holder (001 §6 raised "no passing on of the right to create" as an open question, not a closed commitment; this Kernel rule is stronger — a firm bar — with the copy/lease/shorthand mechanics new) [new; firmer than 001's open question]. Acreatean agent runs is recorded as that agent's act, never the owner's (§11, §15), and resets no unattended clock (§8): the owner's earlier grant ofcreateis not an owner signature on each later creation [new]. - Two can be asked to agree (the owner may require the two come from different labs — 001 §6 already made this optional, so it is faithful carry — each confirming the tool-shown difference, the scoped agreement view of §3, bound to the exact proposed change) — holds against a mistake, not an attempt; the owner may always grant alone, even where two-granter is set [new]. A lease is not a path around this [new]: a capability the owner put behind two-granter agreement is leasable only via a lease that itself satisfies two-granter — two granters co-sign the lease issuance; a single-issuer lease of such a capability is refused [new; preserves both the two-granter guarantee and leasing]. The issuing seat must itself be one of the two granters, so the two co-signatures are the issuer's authorization plus the second granter's — no third principal (§9 schema) [new; resolves the issuer-plus-two-granters schema gap]. The constraints of §5 are re-checked, counting the leased capability, when a lease is issued and when a standing grant is made. Both granters sign the same canonical proposal, keyed to its exact input state (§15); both signatures are retained; a change to that input state voids both approvals (re-propose); these authorization signatures are distinct from the tool's own seal on outcomes, notices and refusals [new].
- Recorded and signed, taking-back is one act that stays taken — §14 says how far each reaches today.
- Between agreement and act, the tool compares again; a mid-flight edit is caught, not prevented; one agreement is a whole file.
Read this first: until the verifier's files are contained and effects are bound, every gate here is an integrity control, not an authority one — it stops a mistake, not a determined agent running as you.
- Identity — a key on the holder's own device. Two properties, kept separate: a signature's unforgeability holds against an attempt with no containment — a yes signed on your phone cannot be minted on the agents' machine (this is 001 commitment 8's claim, and it stands). What needs containment is the local verifier's enforcement. So [changed-from-001: refined, not reversed]: the key's unforgeability is the against-an-attempt property available first; local enforcement waits on containment.
- Containment — from the OS — and the two protections. It moves a gate from "against a mistake" to "against an attempt". The target, from 001 [restores 001's containment target]: an agent may write its own work folder and what its program needs to run, and nothing else of yours; it cannot read your credentials; it cannot read or change TeamCLI's own records — and a tool-mediated reserved-object check (§3) is not itself that OS boundary. It will come system by system, each measured before we claim it (001 §4); it contains files, not the network; an agent's program keeps its own login; the way through for exactly TeamCLI's commands is itself something to get right; it does not survive someone who already controls the machine. When containment exists and fails, work stops [restores 001 §4].
- Secrets. TeamCLI does not ask for, store, or print the keys of the labs you use; the agents' own programs hold them, as they did before TeamCLI (001 commitment 7); a team file carrying a known key shape is refused (a few known shapes, not a detector); a value that is a filesystem path is not treated as a credential — a path is exempted only when it resolves to a real directory (the shipped shape check, §14) [changed-from-001: refines commitment 7's key-shape refusal]. The one present exception, disclosed [restores 001 commitment 7's keychain exception]: the release check reads one key from the system key store, only on macOS, only in an interactive run, and sends it only to the tracker it belongs to, with one question; the key is not printed and not written down; further exceptions are listed the same way. TeamCLI uses no one else's code when it runs, and runs nothing when it is installed. The connection inventory is 001's — the release check (package registry, code host, tracker) and the two places the tool asks the version-control program to fetch — plus, where a team configures a broker, the broker's own connection to that team's tracker: a connection beyond 001's inventory, disclosed here as such [changed-from-001: commitment 7's connection list gains the configured broker, so c7 is not "restored in full"]. TeamCLI itself opens no other connection, and is published only by its own repository's workflow, with a signed statement of where it came from.
-
The broker. Where a team reaches a tracker through a broker, the broker refuses to return any
field carrying its credential — enforced, not promised (built on
main, in no released tag today — §14). Theuse-brokeroperation list is here [new]: a holder may ask the broker to pull a task, claim a task, and read a task's non-secret fields, and nothing else. One principal: the requesting seat — the broker authenticates that seat and checks that seat's scope and deny (§9);leadsis no proxy. The Kernel owns this refusal, the operation list and the per-seat check; the broker process is Planning. - The instruction boundary. A seat takes instructions only from the principals the owner named, through TeamCLI; the tool refuses any other channel as a source of instructions — the enforceable part. Whether a model is swayed by material it reads is not enforceable (§12). [changed-from-001: this narrows commitment 4's horizon, marked.]
- The owner is told [restores 001 commitment 2, the part draft 3 dropped]: every change to what a team may do — a grant, a lease to a seat, a revocation, a rebind, a ceiling change, a lost minimum — produces a notice record the Runtime delivers to the owner without being asked (the Communication module shapes the message). Being told is not being asked (001 §4): a notice follows the change, so it is not a prior approval; a prior approval is the agreement of §10. This is an obligation the tool states and the Runtime delivers (§16), not a refusal, and §14 marks it not built.
- The machine-wide stop [restores 001 commitment 2, as a commitment to build]: one owner action stops every team on the machine; today there is one stop per team, and it is unreliable (§14). The owner's stop and a revocation never depend on the ledger being writable (§15).
- The general fail-closed rule [restores 001 commitment 3]: when the tool cannot establish what it needs — a screen it cannot read, an unverifiable record, an unreadable control state, a caller it cannot place, a file that is not the one agreed, a scope it cannot decide, a lease it cannot validate, authorship or a lab binding it cannot establish — it refuses or waits, and says why.
- Assent has provenance. Each recorded agreement says whether the tool witnessed a person give it (a signature from the holder's key) or was told that one did; a reported yes is never recorded as the owner's (001 §4/§6 target). Today it records neither distinction (§14).
- The whole Kernel is integrity, not authority, until containment + bound effects — every mechanism here runs inside the principal it bounds.
- The broker/owner gate is integrity, not authenticity, until containment.
-
Bypass by not using the tool — the gate binds the tool's commands, not the world's effects.
write+ an inherited credential cangit pushdirectly; a worktree checked out on the trunk makes awritea trunk edit themergegate never sees; andreadis the tool's serve path only — an agent that opens a file itself and sends it to its lab is not stopped — until effects are bound and files contained. - The clock. The gate's clock is, until containment, the agent's own: a clock set backward extends every lease and a forward one expires them early. Authenticated time is a promise to build.
- A power taken back can return, until containment; a team can spend beyond what the tool dispatches (§8 — soft); unattended seats, shared terminals stand until containment. Keys in the environment are inherited, and file containment does not solve this even once built (001 §4).
-
An agent can leave something behind that a
stopdoes not remove; suspected key exposure requires key replacement; a yes said in conversation is not a record; what an agent writes must identify its author (001 §4 — an acknowledged limit, not a refusal) [restores 001 §4]; memory can mislead a later session. - What the tool does on the network, it does as you (001 §4); TeamCLI starts agents with their own confirmations turned off, and puts nothing as strong in their place until containment; a folder is not a boundary; containment has a running cost and does not survive someone who already controls the machine; more autonomy is more to take back.
- Not covered, and said so: a hosted TeamCLI, several people on one machine, and whether a lab's model can itself be trusted. Vulnerabilities have a private reporting route — repository security advisories; we answer, fix, and say afterwards what it was; the text is published only once that route exists [restores 001 §7]. The "what would change our mind" triggers live in the Charter.
- The tool does not judge the agents' work, their labs' data handling, or whether a page told them what to do. Those risks are yours and the labs'.
Each uses capabilities but defines no gate, so each is a Tier-3 module depending only on Kernel +
Runtime: Communication, Memory, Analysis, Quality, Consensus, Roles & Skills (owner-named roles,
inheritance, library, and skills — free text, never a gate), Planning (the backlog, intake rule,
task-claim queue, and the broker process). One hosted exception, on the Runtime-store precedent: the
broker process lives in Planning yet executes a Kernel-owned refusal (the credential-withholding and the
per-seat check, §11) — it hosts a Kernel gate, it does not define one [new]. The gate ignores every module payload: a record a module
writes to the shared store is never a review, gate or lease record, and no constraint ranges over it.
Module policy may select among Kernel-defined settings; it cannot add a refusal. The module
registration wording of the spine is read as registration against the closed, release-owned
vocabulary (§3), never as a module adding a capability. Fixing any of these in the Kernel would bet
against the field and enforce nothing a capability cannot.
"Today" is TeamCLI 0.3.5. Nothing of the capability model is built. Kind: M against a mistake, A against an attempt. No row holds against an attempt.
| Piece | Today | Kind |
|---|---|---|
| Capability vocabulary + gate | One list: start/stop/add/remove for an outside agent. The enumerated, versioned, scoped set is designed |
M |
read / lab-visibility refusal (c5) |
In part: which labs work on a project is set per team (that choice holds); folder-by-folder read disclosure is not built |
M |
Reserved-object denylist (team file/ledger/verifier/.git) |
Not built | — |
| Roles, constraints, scope, SoD, cross-lab predicate, seat-to-lab binding | Not built; a seat is known by where it runs | — |
| Leases (bounded/recorded/revocable/TTL) | Not built; the team-file lists are the only grants | — |
| Ceiling, deny, owner-sovereign limits | Not built. A team can spend/run unbounded | — |
| Resource envelope (spend/runtime/lab-count) (c1) | Not built | — |
leads authority root, the §9 table |
Not built | — |
| Grant / agreement | Exact agreement text is a signed record; first needs a person at the machine; upgrade keeps an agreement as it was. 0.3.4 ships a first bounded delegated-approve: a team-file-named delegate pane may approve ordinary roster changes (seats and their launch lines), re-checked against the live file and the approved copy, everything else refused (docs/commands/approve.md). Who/when, witnessed-versus-told, general agreements by agents, taking-back that stays taken: not built |
M (signing key readable by an agent) |
| Record ledger (fields, chain, head, tombstones, refusals) | Not built; agreements are signed, a general action ledger is not | — |
| The owner is told (c2) | Not built; nothing reaches the owner unasked | — |
| Stop (c2) | One command per team, and unreliable (001 §8); the machine-wide stop is a commitment to build | M |
| Identity — key on device | Decided, not built; needs a contained verifier for local enforcement | — |
| Containment + fail-closed-on-break | Not built | — |
| Fail-closed when in doubt (c3) | Holds, against a mistake, where the released tool already looks — a screen it cannot read, a caller it cannot place, a record it cannot verify (001 §8) | M |
| Secrets (c7, with the macOS exception) | No lab key asked/stored/printed; key-shape refusal (a filesystem path is not a credential — exempt only when it is a real directory, ≥0.3.4); the one keychain exception holds. The broker's credential-withholding is built on main, in no released 0.3.x tag — not a released behavior today
|
M |
| Instruction-channel refusal (c4 enforceable half) | A sentence to each seat; the tool refuses no channel yet | — |
Roadmap: containment first, then the key (unforgeability is available without it, local enforcement is not), then the ledger, then bound effects and the resource ceiling.
Every grant, agreement, lease, revocation, gated action, and refused attempt is signed and recorded; an action that cannot be recorded is refused, so by §2 the ledger is Kernel. The Kernel defines the record, the ordering and the refusal; the Runtime implements the store and may not decide these policies on its own (breaking the cycle).
Every record carries [new; "every gated action" is a tightening beyond 001]: a type (grant,
agreement, lease, revocation, intent, outcome, review, gate, refusal, notice, tombstone);
the actor and the signer as distinct fields (a caller-supplied name is recorded as an
unauthenticated claim, never as actor), plus a co-authorization field for a two-granter record —
the second granter's signature over the same canonical proposal (§9, §10) [new; the schema now
describes a two-signer record]; the action; the capability and scope used; the
action payload — a canonical, typed statement of domain (team, repository root), target
(ref, environment, account, task, team), before/after artifact identity where one exists (typed
"none" where not — no fictional hashes), the root grant it derives from, and a unique request id;
the exact input state (the tree hash, the team-file hash and the lease-set hash, so two
implementations agree on what "the same act" is); an authenticated time (§12 says the limit); and the
hash of the previous record. A lease record adds its id, its parent (mandatory for a re-lease,
absent only for a root lease, §7), root grant and expiry — and nothing mutable. A gate record adds the effect id: a hash over the changed-path set (renames
and copies included), the destination tree, the destination ref, the base, and the policy (team-file)
hash — it identifies the artifact that was gated (what), and deliberately excludes the environment and
account (where, and as whom), which are authorized separately at act-time (§3 deploy, §6) [new]. A
merge or deploy record, and any gate/merge/deploy outcome, carries that same effect id, so
a void (below) keys to it [new].
Revocation is its own record, and liveness is derived. A lease's state is computed from its immutable issue record, its expiry, the presence of any revocation record for it or for an ancestor, and whether the authority it descends from still covers it — the gate reads the lease's root-grant field and walks the whole chain to the originating standing grant or envelope (§7), so a lease whose root grant no longer covers it — or whose issuer no longer holds that source — is not live, with or without a revocation record [new]; a revocation sticks even if later tombstoned — a tombstone hides the content for archive and leaves a stub the gate still counts. There is no in-place field, so the chain cannot be broken by an update (round 3, Grok).
Order and effect. The act is recorded in two steps: an intent record (the authorization the gate
decided, appended durably before the effect) and an outcome record (done, refused, or
unknown). If the intent cannot be appended, the act does not happen. If the tool dies between
intent and outcome, recovery writes an unknown outcome before any new act on that target; an
external effect already made is never "undone" by a failed append, and the record says so.
An unknown outcome blocks its target and its request id [new]. While an effect is unknown, every
act on the same target is refused, and a retry under the same request id is never re-dispatched: it
returns the recorded state. A record presenting an already-used request id with a different payload is
refused — a retry must be byte-identical [new]. A byte-identical retry while the original is still
pending awaits that in-flight result; while it is complete, it returns the recorded outcome — never a
second dispatch [new]. Resolution is a recorded reconciliation: the tool asks the external
service where it can (done / not done) and writes the real outcome; where the service offers no way to
tell, only an owner-signed recovery decision (repeat as a new request id, or accept as done)
unblocks the target, and the decision is a record. The reservation (§8) held for the effect stays counted as spent until resolved.
The Kernel does not promise exactly-once external execution; it promises no silent repeat. A revocation
record appended before an intent refuses that intent; the gate reads the head at the moment it
decides, under a single serialization per team.
A trusted head, not a valid prefix. A previous-record hash proves the links of the history shown; it does not prove it is the latest. The tool keeps a signed head — sequence number and hash — and the gate refuses if the history it reads does not match the head it last signed (rollback, a hidden later revocation, a restart on old state). Archival moves records and keeps the head commitment. Until containment the head is as trustworthy as where it is kept (§12). The signed head and the emergency stop/revocation flags persist across process and machine restart; an update interrupted mid-write is detected and the gate fails closed until the head is reconciled [new].
Failure boundary. If the store is unavailable, an act is refused and the refusal is reported to
the caller but cannot be recorded — the Kernel does not owe a record of the failed log, and says so.
The owner's stop and a revocation do not depend on the store: they take effect at once through a
local flag the gate honours before reading any record. That flag is as trustworthy as where it is
kept — the same clause that governs the signed head (§12) [new]. The stop and revocation are
appended when the store returns, marked late; reconciliation never clears a stop and never drops a
pending revocation — a locally-held stop or revocation holds until the store records it, the flag retains
each signed stop and revocation payload so recording one never drops another, and a stop further holds
until an owner act clears it [new]; a team resumes only after the head is reconciled,
so stale state cannot be reused.
Deletion is a signed tombstone, never a silent erase: "owner-removable" applies to archived
history, never to an in-flight record the gate reads. The gate fails closed: if a change's
authorship, a lease's validity, a seat's lab binding, or the required gate record cannot be read or
verified, the gate/merge/leased action is refused.
A merge consumes a successful decision. The successful gate decision is exactly one object: a
gate record of result = pass [new]; an intent record alone never authorizes a merge or
deploy, and an outcome of refused or unknown — which carries the effect id of the decision it
concerns — voids any pass already recorded for that effect id [new]. It qualifies only a gate record of result = pass, made
by a signer who held gate over the effect at that time, satisfying the constraints of §5, whose
effect id equals the merge's effect (a pass on a smaller footprint, another base or another
destination never blesses a larger or different merge). A refusal record, an obsolete pass — one whose
effect id does not equal the merge's effect — or a pass about the same tree in another context never
qualifies. If the gater's authority has since been
revoked, the pass is void (the conservative policy: a merge or deploy re-validates the pass against
current authority and against any voiding outcome at act-time). The gate and merge records are Kernel
types; a module payload is neither.
Charter states the beliefs; Runtime implements the ledger store (§15), the seat registry, delivers the machine-wide stop and the owner's notices, and supplies timers and meters under the Kernel's rules (§8) — it sets no authority policy; every Tier-3 module inherits the instruction- channel refusal (§11) and only a capability grants (§3), and reaches the gate for every power it uses.
Public RFC: ≥3 reviewers from ≥3 labs, none the author's, in rounds to unanimity, then the board
votes. This revises the text accepted 2026-10-07, in force until re-accepted. The package includes
RFC 001. Draft 3's two [RULING] points are selected in the text — the envelope-conferral lease
with the whole-chain ancestor-recipient ban and the mandatory re-lease parent (§7), under which
act-as is leasable within the issuer's own account authority (its standing act-as grant, or the
leads envelope only when the issuer is leads), bounded by the declared account set (so a lease may
carry the owner's push/publish/comment identity, within that bound), and spend/runtime enforced in the
Kernel ceiling, soft until effects are mediated (§8), with create's budget-slice now debited and
conserved in the aggregate, per lab, and per period — and are for the board to ratify at the vote;
reviewers judge the selected contracts as drafted.