Skip to content
floor edited this page Oct 19, 2026 · 7 revisions

Kernel

Status: Accepted core; sections from amendments 01–03 draft

1. The question

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.

2. What we propose

The commitments are the accepted text's chapters, in their order, under their numbers. A chapter's promise carries its BCP 14 keyword once; its detail keeps the accepted text's words. Every chapter ends with the spec section that holds its formats and its Today line at v0.5.0.

Where we stand, and the one test (§2)

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 MUST own 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. The Kernel also MUST carry 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.

§3. The capability vocabulary

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 MUST be closed, enumerated, and release-versioned. A capability the team's configuration names that the tool does not know MUST be refused, not honoured. The complete set for this release is a registry; a later release adds to it only in a release, and a team's config pins the capability version. A new version MUST NOT lengthen a seat's list by itself (001 commitment 1), and MUST NOT widen what an existing name means: 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 MUST fail closed if a seat's pinned list no longer resolves. The words and the scope dimensions each takes are in the capability registry; the eight operational words are write, read, review, gate, merge, deploy, use-broker, act-as, and the administrative words are create, grant, agree, leads.

The tool-reserved set. The team's configuration, 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. 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's configuration, the ledger writer, the merge service maintaining .git — change reserved objects through narrow Kernel-defined transitions, never through a seat-requested file effect. The line between the two: a merge whose change-tree touches a reserved path MUST be 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.

Operational capabilities (each carries a scope, §6; the registry lists the dimensions each takes):

  • 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. A seat MUST be refused files outside its read scope — the folder-by-folder, per-lab disclosure refusal 001 committed to. Every disclosure of file contents by the tool is a read: a diff, a review view, a merge or write diagnostic and a record that embeds file contents are served only within the requesting seat's read scope, 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 own read scope. 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 own read scope — every disclosure is a read — and withholding unrelated project content and any field the secret-shape check flags) — and nothing else. read is distinct from write: 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. A merge MUST be refused unless it consumes a successful gate decision bound to the same effect (§15), and it MUST be refused for any change that touches a reserved object: those change only through the owner's or a grant holder's agreement (§10), never through a merge.
  • deploy (env, optionally branch) — release to an environment. A deploy MUST consume a successful, still-valid gate decision (or the merge that consumed one) whose effect id matches the artifact it ships, exactly as merge does (§15): an ungated tree MUST NOT be deployed. The consumed pass proves what is shipped only; where it goes (the env) and under whose identity (the account) are authorized independently, at deploy-time, from the deploying seat's own deploy(env) and act-as(account) scope — the effect id carries no environment, so a gate pass blesses an artifact, never a destination. The pass is re-validated at deploy-time: the deploy MUST be refused if the pass has since been revoked or voided by a refused/unknown outcome for its effect id (§15). A failed deploy's refused outcome 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. 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; 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; 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. The accounts are a declared set, owner-sovereign (§8). merge and deploy do not imply it; a seat without it MUST be refused wherever the tool would act under the owner's name. act-as is required in addition to — never instead of — the operational capability the action itself needs (a push that merges needs merge too; a publish that deploys needs deploy too).

A dimension a capability does not take MUST be 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, create and leads are never copied (§10).

Team-lifecycle operations — start, stop, add a seat, remove a seat — are executed through the Runtime and MUST be 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.

Spec: the words and dimensions are in Specs-registries-capabilities; the operation rows in Specs-registries-operations. Proof: the vocabulary and the command map at the tag: test/authority-edit.test.ts, test/permissions/grants.test.ts. Today (v0.5.0). In part: the eight operational words are a closed, versioned list on a signed grant record (src/permissions/grants.ts, GRANT_CAPABILITIES, GRANT_VOCABULARY_VERSION), and a closed command map and resolver decide who may run what (src/permissions/map.ts, src/permissions/resolve.ts); grants are written by the owner alone, and the map's own words say 0.5.0 gates none of the operational capabilities. The reserved set is not built.

§4. Roles — the composition grammar

A role MUST be 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 MUST resolve them to one capability-with-scope set checked at the gate. A capability not in the vocabulary (§3) resolves to no gate and MUST be refused at launch. Identity signs; it does not grant. A role MUST be 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.]

Spec: the bundle and its resolution go to the Roles & Skills spec (roles.md), owned elsewhere. Proof: none yet. Today (v0.5.0). Not built: the resolver's caller type carries a role bundle as an input (src/permissions/resolve.ts), but no roles configuration or resolution to a capability set exists; a seat is known by where it runs.

§5. Constraints — what a composition may not be, and when it is checked

A small enforced constraint language MUST sit 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 MUST be 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 MUST be owner-only (§9). Separation of duties and the lab predicate below MUST be tool-fixed: no configuration, role or grant switches them off.

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 — MUST be 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 MUST be refused, naming the rule.
  • Expiry, revocation, stop, and a lease's source ceasing to cover it (§7), are not requests: they MUST apply unconditionally. 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 gate and merge whose cardinality or review floor it sets, and any act the owner bound to it — MUST pause until it is restored (and the owner is told, §11). 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 a grant holder'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. 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 MUST hold — the seat(s) that wrote a change may not gate or merge it — nor deploy it, where the owner binds deploy to this author-inequality. Authorship is read from the ledger's full author set; if it cannot be established the act MUST be 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 (a write-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); the §9 deploy row carries it.

Cross-lab review is a lab predicate, not a seat count. The owner sets, per team, a review mode:

  • Cross-lab mode: lab(author) ∌ lab(gater) and lab(author) ∌ lab(merger) MUST hold for every author in the full author set, and, where the owner sets a review floor, ≥N reviewer seats from distinct labs. A seat's lab is 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 MUST be 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 MUST name 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; 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.

Spec: the constraint program's form is the policy spec's (policies.md), owned elsewhere; the ledger records it ranges over are in Specs-records-and-ledger §3. Proof: none yet. Today (v0.5.0). Not built: no constraint program is read; the resolver takes a role bundle and active grants only (src/permissions/resolve.ts).

§6. Scope — a capability is bounded

An operational capability MUST carry 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 MUST be one of three states, kept distinct:

  • Unconstrained — omitted or *: the whole declared set on that axis. The tool MUST print 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 MUST be 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): 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 cover docs-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 — that is reachable by any name outside the scope or inside the reserved set (§3) — a hard link, which has no target to read — MUST be 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 MUST be refused (fail-closed, §11) — the workable reading is st_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 MUST be total and decidable; a pair it cannot decide MUST be 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; a change that fits no single authority is a mixed-scope change and MUST be 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 — MUST be 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).

Spec: the effect id's fields are in Specs-records-and-ledger §3. Proof: none yet. Today (v0.5.0). Not built as an enforced scope: a grant record carries a concrete scope of absolute paths and resolves inside the team's declared roots (src/permissions/grants.ts), and the resolver refuses a target outside it (src/permissions/resolve.ts); no file effect is gated by it, and the map says the read scope is not enforced in 0.5.0 (src/permissions/map.ts).

§7. Delegation — a bounded, recorded lease

Delegation MUST be a bounded capability grant. RFC 010 is retired. Two shapes:

  • Standing grants — the roles of §4, in the team's configuration, held until changed (§10).
  • Leases (conferral + attenuation) — 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 MUST have exactly two origins:

  • Root lease — its source is a standing grant the issuer holds, or the leads envelope when the issuer is leads — 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, or leads acting from its envelope, may issue one — and, like any lease, only while the team has a present leads (§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 — MUST be refused. 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 MUST be 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."
  • A lease MUST be live only while the authority it descends from still covers it — up the whole chain to the originating grant. 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 leads envelope, 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, the leads envelope narrowed, leads removed, a parent expired or revoked, or a scope name the lease depends on retargeted (§8) — MUST kill the lease and everything below it, whether or not a revocation record was written for it. Narrowing or reassigning a grant, or removing leads, also MUST eagerly revoke 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, removing leads, 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 MUST be 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. 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. 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 MUST bound every lease: the lease-ttl dimension of the ceiling (§8), owner-settable under a tool maximum no lease may exceed; a "years-long lease" MUST be refused.
  • A lease MUST NEVER return authority upward — over its whole chain, at any number of hops. The recipient of any lease — root or re-lease — MUST 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 excluding leads, the originating issuer, and the in-chain seats. 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 root leads above 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. So A's merge(trunk) cannot reach leads through B's re-lease, nor through any longer relay; a non-executing leads cannot reacquire, through any chain of leases, a capability it only holds in its envelope.
  • A lease MUST bind 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).
  • Revocation MUST be 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 leads envelope only when the issuer is leads (§9), recorded and bounded — it is what lets a non-executing leads delegate at all; a re-lease only attenuates its parent. act-as is operational and so is leasable like any root lease — 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 (§8) (§17). The attenuate-only form (a lease only narrows what the issuer executes) is the alternative; this text selects the envelope form, with the ban above and the mandatory parent, and the board ratifies it (§17).

Spec: the lease record's fields and the liveness walk are in Specs-records-and-ledger §3. Proof: none yet. Today (v0.5.0). Not built: grants are standing signed records with an optional expiry and an append-only revocation record (src/permissions/grants.ts); no lease, parent pointer, lineage walk or cascade exists.

§8. The ceiling, the deny, and owner sovereignty

Free composition is safe because it MUST sit under a boundary the tool holds:

  • Owner-sovereign limits: 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 and lab names — plus the seat-to-lab binding (which lab a seat is, and the rebinding of a seat) MUST be set by a signed owner act. A second owner (grant holder) may grant within them but MUST 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, adding prod to the declared env set, 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 MUST durably revoke 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; the spend counter and the unattended-runtime timestamp keep counting across a rebind — invalidated attribution never reopens the remainder. Retargeting or removing any declared-set name — an env, branch, account, repository root or task resource — MUST durably revoke (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).
  • Deny MUST win through every role, overlay, lease, and envelope.
  • The ceiling MUST bound 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: the owner-sovereign ceiling MUST bound 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). 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 text demotes it from commitment to advice. The Kernel owns the rule; the Runtime supplies timers, meters and process control and MUST set 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 MUST reserve the owner-set per-dispatch maximum against the remainder, so concurrent dispatches cannot together exceed it; work MUST be 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) MUST debit 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 — and create debits 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 second create or any child dispatch can read them — the same reservation discipline as a dispatch. Creation MUST be 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). A child seat's add is then checked against its lab's named slice and debits nothing further; an add in a lab the bound did not name, or beyond that lab's slice, MUST be 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. 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-create only within its own create-bound, debiting a grandchild's slices from the child's own per-lab remainders — the same discipline, recursively. Spend is a per-period cap, and a carved slice persists across the creator's period rollover: a child carries its origin period, and each period the creator's per-lab and aggregate remainders are cap − 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. 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 likewise its 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. The shadow is a single, prospective, serialized draw-down: 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" MUST NOT reset it. At the limit, the team MUST pause and the owner is told.
  • Seats — the count of live seats, per lab, MUST be checked at add and at launch.
  • Per-lab visibility — the union of a lab's seats' read scopes MUST NOT exceed the owner's per-lab read cap; a read that would widen the union past it MUST be refused (§3).
  • A created team MUST inherit within the creator's envelope, by the same conservation as the spend slice: 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 create is 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 MUST NOT renew the child's clock (consistent with create minting no fresh runtime). A lab's remaining seat allowance is the cap minus its live seats minus the per-lab slices already debited to descendants; a create whose named per-lab seat or spend slice does not fit the matching remaining allowance MUST be refused.

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 MUST say so. [Selected contract:] spend and runtime stay in the Kernel ceiling as commitments, as drafted; the board ratifies it (§17).

Spec: the budget readings and their check contracts are the budgets spec's (budgets.md), owned elsewhere. Proof: none yet. Today (v0.5.0). Not built as the Kernel ceiling: a per-account budget gate refuses up or add when a counted subscription reading is inside its reserve or a spend reading is at or below its floor, and an uncountable reading is said and never a refusal (src/budgets/gate.ts, test/budget-refusals.test.ts); no aggregate/per-lab spend conservation, unattended clock, seat cap or per-lab visibility cap exists.

§9. leads — the authority root, and who may do what

Exactly one capability MUST be 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. Two MUST be 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 MUST append 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).

The authorization table. Each operation MUST have 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. The table is a registry, one row per operation, with its authorizing principal and bounds: start; stop; machine-wide stop; add a same-copy; add any other; remove; issue a lease; grant a capability or edit the team's configuration; a configuration change that is not a same-copy; revoke a lease; --abandon; a use-broker call; act-as; write/read/ review/gate/merge/deploy; create; and rebinding a seat's lab or changing a ceiling, deny, declared set, minimum, maximum, exclusion, review mode or the two-granter requirement. Their full bounds are in the operations registry; the rules that do not fit a row follow.

The owner MUST be able to 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 MUST keep 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.

Spec: the rows are in Specs-registries-operations; the record of signer and actor is in Specs-records-and-ledger §3. Proof: none yet. Today (v0.5.0). In part: a team's one lead is read from leads: true or the coordinator: key (src/file/sections/lead.ts), and the command map admits the owner or the lead to up, down, restart, reload, remove and rename (src/permissions/map.ts); there is no delegation envelope, no lease-derived authority and no two-granter record.

§10. The grant, and how it is agreed

The grant/agreement mechanism is carried from RFC 001 §6. The model collapses if any of these is advisory.

  • A list for each seat MUST exist; 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" MUST be 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 neither agree, grant, create, nor leads, and inherits no 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.
  • add is never a third grant channel. A new seat's list is whatever its agreed copy or grant says — never what leads or the executing actor chooses (§9). start MUST run the pinned command and its full hashed execution context — lab, working root, environment bindings — and only those, refusing any caller-supplied environment.
  • The all-capabilities word means the vocabulary as agreed, and never includes grant, leads, or create.
  • By default, nobody but you: a new team gives no agent agree, grant, create, leads, the all-word, or a pre-filled envelope; a fresh machine grants create to no agent (001 §6).
  • create is 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 given grant (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). These bounds are owner-sovereign. create MUST be 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). A create an agent runs MUST be recorded as that agent's act, never the owner's (§11, §15), and resets no unattended clock (§8): the owner's earlier grant of create is not an owner signature on each later creation.
  • 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 MUST confirm 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. A lease is not a path around this: 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 MUST be refused. 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). 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 MUST 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.
  • Recorded and signed, taking-back is one act that stays taken — §14 says how far each reaches today.
  • Between agreement and act, the tool MUST compare again; a mid-flight edit is caught, not prevented; one agreement is a whole file.

Spec: the grant record and its signature are in Specs-records-and-ledger §3; the agreement's canonical proposal is the same spec's. Proof: none yet for the agreement; the owner-only grant record is proved at the tag by test/authority-edit.test.ts. Today (v0.5.0). In part: the owner writes a standing grant alone, as a signed record naming an agent id or a team id, a capability list from the closed eight, a scope, an optional expiry and a generation (src/permissions/grants.ts, src/commands/grant.ts), and revokes it with its own appended record (src/commands/revoke.ts); approval records retained from 0.3.5 — the approved team file, its signed, generation-numbered record (src/store/store.ts) — are compatibility data, and a delegates: entry still gates delegated runs against the live file, on a verified retained approval standing (src/delegate.ts); team approve is not a command at 0.5.0 (the live team file is the record, UPGRADE-0.5.md), so no delegated approval ships. No agent holds agree or grant, no copy agreement by hash is built, and taking-back is not a general "one act that stays taken".

§11. The security substrate

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: the key's unforgeability is the against-an-attempt property available first; local enforcement MUST wait 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: 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 MUST stop (001 §4).
  • Secrets. TeamCLI MUST 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 configuration carrying a known key shape MUST be 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). The one present exception, disclosed: 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 MUST use 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. TeamCLI itself MUST open 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 MUST refuse to return any field carrying its credential — enforced, not promised. The use-broker operation list is here: 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); leads is 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 MUST take instructions only from the principals the owner named, through TeamCLI; the tool MUST refuse any other channel as a source of instructions — the enforceable part. Whether a model is swayed by material it reads is not enforceable (§12).
  • The owner is told. 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 — MUST produce 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. One owner action MUST stop every team on the machine; today there is one stop per team, and it is unreliable (§14). The owner's stop and a revocation MUST NOT depend on the ledger being writable (§15), nor on the store being up.
  • The general fail-closed rule. 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 MUST refuse or wait, and say why.
  • Assent has provenance. Each recorded agreement MUST say 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).

Spec: the notice record and the stop/revocation flags are in Specs-records-and-ledger §3. Proof: none yet. Today (v0.5.0). In part: the approval and grant records are signed with a key kept under the home (src/store/keys.ts), and the same-user limit below stands; secrets are handled as §14 records; nothing in the list above is enforced as a refusal.

§15. The record ledger — defined here, kept in the Runtime

Every grant, agreement, lease, revocation, gated action, and refused attempt MUST be signed and recorded; an action that cannot be recorded MUST be refused, so by §2 the ledger is Kernel. The Kernel defines the record, the ordering and the refusal; the Runtime implements the store and MUST NOT decide these policies on its own (breaking the cycle).

Every record MUST carry the fields the spec defines: 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); 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 configuration 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 MUST add 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 MUST add 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 (the team's configuration) 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). A merge or deploy record, and any gate/merge/deploy outcome, MUST carry that same effect id, so a void keys to it.

Revocation MUST be its own record, and liveness 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; a revocation sticks even if later tombstoned — a tombstone hides the content for archive and leaves a stub the gate still counts. There MUST be no in-place field, so the chain cannot be broken by an update.

Order and effect. The act MUST be 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 MUST NOT happen. If the tool dies between intent and outcome, recovery MUST write 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 MUST say so. An unknown outcome MUST block its target and its request id. While an effect is unknown, every act on the same target MUST be refused, and a retry under the same request id MUST NOT be re-dispatched: it returns the recorded state. A record presenting an already-used request id with a different payload MUST be refused — a retry must be byte-identical. A byte-identical retry while the original is still pending MUST await that in-flight result; while it is complete, it MUST return the recorded outcome — never a second dispatch. 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 MUST refuse 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 MUST keep a signed head — sequence number and hash — and the gate MUST refuse 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 MUST persist across process and machine restart; an update interrupted mid-write MUST be detected and the gate MUST fail closed until the head is reconciled.

Failure boundary. If the store is unavailable, an act MUST be 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 MUST 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). The stop and revocation are appended when the store returns, marked late; reconciliation MUST NOT clear a stop nor drop 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; a team resumes only after the head is reconciled, so stale state cannot be reused.

Deletion MUST be a signed tombstone, never a silent erase: "owner-removable" applies to archived history, never to an in-flight record the gate reads. The gate MUST fail 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 MUST consume a successful decision. The successful gate decision is exactly one object: a gate record of result = pass; 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 — MUST void any pass already recorded for that effect id. 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 MUST be 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.

Spec: every record type, the effect id, the intent/outcome ordering and the liveness rules are in Specs-records-and-ledger §3. Proof: none yet. Today (v0.5.0). Not built: the approval store keeps one signed per-project approval record and a generation (src/store/store.ts), and grants and revocations are separate signed records (src/permissions/grants.ts); there is no general action ledger, no chain and head, no intent or outcome record.

3. Why

The incidents are 001's and this text's; no new ones. The Kernel exists because TeamCLI is operated by agents that run as the owner unless contained, so the tool's refusals — not its prose — are what bounds a team. Round 9's adversarial walks exposed the two conservation holes that §8 now closes (per-lab conservation did not imply a separately tighter aggregate cap; a carved slice must persist across a period roll). The four §8 residuals of round 11 are stated as one rule — the shadow is a single, prospective, serialized draw-down — because four separate sentences had left four ways to read the same remainder. The fixed vocabulary and the one authorization principal exist because a power an agent can talk its way into by another name is not bounded; the lease rules exist because delegation without a lineage is authority that cannot be taken back.

4. What it costs, and what it does not cover

§12. What this does not cover

  • 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 can git push directly; a worktree checked out on the trunk makes a write a trunk edit the merge gate never sees; and read is 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 stop does 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); 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. 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'.

What this release must not pretend

  • No row of the capability model holds against an attempt at v0.5.0; every gate that exists is an integrity control.
  • A grant record is not an enforced gate: v0.5.0 writes and resolves grants, and its own map says the operational capabilities gate no command.
  • The leads mark is an address and a small command gate, not the delegation envelope: no lease, no lineage, no two-granter record exists.
  • The budget gate is a provider-account check, not the resource envelope: it neither counts the aggregate nor stops an agent spending on its own credential.
  • The approval record is not the ledger: it signs one file and its generation, not a chain of actions.
  • The broker's field policy is built, the per-seat scope check is not: the broker returns only the allowed fields, and the Kernel's per-seat use-broker check does not yet bind a caller.

5. What would change our mind

The accepted text's triggers: the Charter's. Within this text, the two selected contracts (§7's envelope-conferral lease with the whole-chain ancestor-recipient ban, and §8's spend/runtime in the Kernel ceiling, soft until effects are mediated) are put to the board at the vote; a review that found the aggregate/per-lab conservation unsound, the shadow rule ambiguous, or the category distinction (what needs containment vs what does not) wrong would reopen the text rather than amend it.

6. What is true today

"Today" is the tag v0.5.0 (52db9b75). Nothing of the capability model holds against an attempt. Kind: M against a mistake, A against an attempt. No row holds against an attempt.

# Commitment Today Kind
1 Capability vocabulary + gate In part. The eight operational words are a closed, versioned list on a signed grant record (src/permissions/grants.ts, GRANT_CAPABILITIES, GRANT_VOCABULARY_VERSION = 1); a closed command map (src/permissions/map.ts) and a resolver (src/permissions/resolve.ts) decide who may run what. The map's capability rows say 0.5.0 gates none of them; grants are owner-written only M
2 read / lab-visibility refusal (c5) In part: which labs work on a project is set per team (that choice holds); the file carries visibility public/private (src/file/sections/visibility.ts), read by the config check and by public-name worktree placement (src/check/config.ts, src/worktree/place.ts); folder-by-folder read disclosure is not built, and the map names the read scope unenforced M
3 Reserved-object denylist (team configuration/ledger/verifier/.git) Not built —
4 Roles, constraints, scope, SoD, cross-lab predicate, seat-to-lab binding Not built; the resolver's caller carries a role bundle (src/permissions/resolve.ts), but no roles configuration or constraint program is read; a seat is known by where it runs —
5 Leases (bounded/recorded/revocable/TTL) Not built; the configuration's lists and the signed standing grants are the only grants —
6 Ceiling, deny, owner-sovereign limits Not built as the Kernel ceiling. A per-account budget gate refuses a launch inside a subscription reserve or at/below a spend floor, and says an uncountable reading without refusing (src/budgets/gate.ts); a team can spend/run unbounded by the Kernel —
7 Resource envelope (spend/runtime/lab-count) (c1) Not built; no aggregate or per-lab spend conservation, no unattended clock, no seat cap —
8 leads authority root, the §9 table In part. A team has one lead from leads: true or the coordinator: key (src/file/sections/lead.ts), and the map admits the owner or the lead to up, down, restart, reload, remove, rename (src/permissions/map.ts). No envelope, no lease-derived authority M
9 Grant / agreement In part. Owner-signed standing grants at team and seat level, by registry identity, with an optional expiry, and revocations as separate signed records effective at the next gate (src/permissions/grants.ts, src/commands/grant.ts, src/commands/revoke.ts); the resolver (deny by default, list ∩ envelope) and the command-to-vocabulary map decide who may run what (src/permissions/resolve.ts, src/permissions/map.ts), and the map gates none of the operational capabilities. Approval records retained from 0.3.5 — the approved team file, its signed record and its generation — are compatibility data (src/store/store.ts) and the standing evidence a delegates: entry is checked against (src/delegate.ts); team approve is not a command at 0.5.0 (the live team file is the record, UPGRADE-0.5.md), and no delegated approval ships. No grant holder, no agree, no create bounds, no two-granter; who/when, witnessed-versus-told, general agreements by agents, taking-back that stays taken: not built M (signing key readable by an agent)
10 Record ledger (fields, chain, head, tombstones, refusals) Not built; approval records retained from 0.3.5 (one signed record and a generation, src/store/store.ts) are compatibility data, and grants/revocations are separate signed records; no general action ledger —
11 The owner is told (c2) Not built; nothing reaches the owner unasked about an authority change —
12 Stop (c2) One command per team, and unreliable (001 §8); the machine-wide stop is a commitment to build M
13 Identity — key on device In part. The tool mints and keeps an Ed25519 approval key under the home, and signs grants and retained approval records with it (src/store/keys.ts); the key is readable by any process of the same user, so the signature is evidence, not a wall; no contained verifier M
14 Containment + fail-closed-on-break Not built —
15 Fail-closed when in doubt (c3) Holds, against a mistake, where the released tool already looks — a caller it cannot place, a record it cannot verify, a registry it cannot read (src/caller.ts, src/permissions/who.ts, src/store/store.ts) M
16 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); the one Keychain exception holds (src/release/keychain.ts). The broker's per-field policy is built at v0.5.0 (src/broker/policy.ts): a returned task record carries only the allowed fields, and the credential stays in the adapter (src/tasks/linear.ts); the per-seat use-broker scope check is not built M
17 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.

7. The security boundary

The Kernel's security substrate is §11; the boundary is stated once there and once here. Every gate in this text is an integrity control, not an authority control, until the verifier's files are contained and effects are bound: it stops a mistake, not a determined agent running as you. The key's unforgeability is the one property that holds against an attempt without containment. The same-user limit: every seat runs as the same OS user, so a seat can read the signing key, the state folder and the records; a signature is evidence of who wrote a record, not a wall against the process that runs it. The tool's refusals bind its own commands, not the world's effects: an agent that bypasses the tool, inherits an environment credential, or edits a file it opened itself is outside them until containment. A hosted TeamCLI, several people on one machine, and whether a lab's model can be trusted are not covered.

8. Where it sits, and what it leaves to others

§13. What is deliberately not in the Kernel

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. The gate MUST ignore 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 MUST NOT 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.

§16. Where it sits

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 MUST set 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.

9. Prior art and alternatives

Only the alternatives this text argues. §7: the attenuate-only lease form — a lease only narrows what the issuer executes — is the rejected alternative; the text selects the envelope-conferral form with the whole-chain ancestor-recipient ban and the mandatory re-lease parent, and the board ratifies it (§17). §8: spend and runtime outside the Kernel ceiling (leaving them to the Runtime or a module) is the alternative; the text selects keeping them in the Kernel as commitments, soft until effects are mediated. §3: the hold-credential name was the draft concept; it is renamed use-broker, because the seat never holds the secret. §5: the author-inequality on deploy is an owner-added constraint, not a default; the two checks (same-seat exclusion and per-change author≠deployer) are incomparable. §10: 001 left "no passing on of the right to create" open; this text makes it a firm bar, with the copy/lease/shorthand mechanics new.

10. Open questions

  1. Added for the round; not a question of draft-12-final — whether §3 names the storage registry in so many words (an owner decision). The team's configuration, a reserved object of §3, becomes the registry's records under a pluggable storage backend; the Kernel's rule on reserved objects and §15's verification of every record stand whatever the backend. The accepted text leaves no question open; this one is added by the v2 draft, and the round says whether §3 should name the registry in so many words.

No other question is added. Draft 3's two [RULING] points are selected: 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; and spend/runtime enforced in the Kernel ceiling, soft until effects are mediated (§8), with create's budget-slice debited and conserved in the aggregate, per lab, and per period. They are for the board to ratify at the vote; reviewers judge the selected contracts as drafted.

12. Links to the spec

The entries this text contributes to the registries are in Specs-records-and-ledger §6, in each registry's row shape: under capabilities.md the operational words write, read, review, gate, merge, deploy, use-broker, act-as and the administrative words create, grant, agree, leads, and under operations.md the §9 rows, each with its authorizing principal and bounds. The registries' owner collects them from the file.

The three sections below fold Kernel amendments 01–03 (2026-10-18 and 2026-10-19) into this page. They are reviewed drafts, not accepted. Their headings and commitment numbers are the amendments' own, numbered from 1; the accepted core above keeps its own numbering (§3–§17).

Grants, delegations and revocation

Kernel amendment 01 — reviewed draft, not accepted.

1. The question

Agents operate TeamCLI, and the owner should not need a terminal for routine work: what is a grant, who gives it, how two grants on one seat resolve, how a grant ends and who is told, which command is which word, and what is recorded, with everything the release cannot keep said plainly — the minimum of the Kernel's model 0.5.0 may code without setting a Kernel rule by accident.

2. What we propose

The commitments, numbered as in the earlier draft, grouped under its chapters.

The grant (§3)

3.1. A grant is the Kernel's standing grant, never a lease (Kernel §7, §10). The grantor is the owner; the grantee is a registry identity, a team by its team id or a seat by its registry id; the capability words come from the closed vocabulary with its version pinned; the scope sits within the declared roots; the time issued is recorded; an optional expiry MUST be checked at every use; the record carries a generation and the owner's signature over the whole. There MUST be no parent pointer, no re-lease, no liveness walk: a dated grant is a standing grant with an expiry, and it is called a grant. Spec: Specs-grants §3.1. Proof: test/permissions/grants.test.ts, test/grant.test.ts. Today (v0.5.0). The signed record in the owner's grants folder, one JSON file per record, signed under the grant's own domain tag so a renamed or edited record does not verify; a record with a field this version does not know is skipped (src/permissions/grants.ts).

3.2. The grantee is a registry identity and nothing else. A seat MUST be named by the id the registry minted for it, which the seat keeps across its occupants, a rename and a relaunch (an owner decision; Runtime commitment 2); a team by its team id. A record spelling a name, a seat, a pane, a session or a runner is not a grant. A registry identity with no seat is a grantee too (an owner decision): the same grant record with seat: none, its admission checked at delivery against the grant, so the watch plays no part — and no new vocabulary word is needed. Spec: grants.md §3.1, rule 2. Proof: test/grant-registry-id.test.ts. Today (v0.5.0). team grant <seat> --capabilities … resolves the seat to its registered agent and writes the id, never the name; @team writes this project's team id; the create-grants in the same folder name their holders the same way, and the create-grant's admission by registry id only is an owner decision — the send-grants are the legacy exception: their from/to are unsigned strings and their admission also accepts agent-id, seat@team and session/seat forms (spec §3.4), so registry-only identity is the target, not yet the whole folder. The seatless grantee is settled, not built: v0.5.0 is still seat-named, and no seat: none record is written yet (src/permissions/manage.ts, findAgent — the record carries the agent's id; src/permissions/grants.ts, covers — matches the id).

3.3. A grant MUST carry operational capabilities only. The eight words, and never the administrative ones, which move by the owner's act alone (§3, §7, §10); never a lifecycle operation, which is reached only through leads held in a role or through a delegation record (the Lifecycle delegation section); never a setting, except the one owner setting a team grant may carry beside its capabilities, dialogs.trust, which lets the team's lead answer a folder-trust dialog (an owner decision) and is a word of the record, never a command. Spec: grants.md §2, rule 1, and registries/capabilities.md. Proof: test/permissions/grants.test.ts. Today (v0.5.0). GRANT_CAPABILITIES is the eight; a team grant naming one of the four is refused at write with the reason named; dialogs.trust is the one GRANT_SETTINGS word (src/permissions/grants.ts: GRANT_CAPABILITIES, TEAM_GRANT_FORBIDDEN, GRANT_SETTINGS).

3.4. A vault is reached through a grant's scope (an owner decision). An entity's vault — its long-term memory, the memory module's object (003) — is read and written under grants and nothing else: the grant carries the capability (read or write, words of the closed vocabulary) and a vault scope, a path pattern within one entity's vault, its written form the spec's (planned, §3.9 there). A grant MUST NOT reach into two entities' vaults, and a seat MUST NOT read or write another entity's vault (the memory module's commitment 1). By the owner's word, an entity's main orchestrator holds read and write on its entity's whole vault; every other seat holds the scopes its role and task need. Every vault read and write is logged with the scope it used, and cross-memory reads ride the same grants: one source of truth per fact, no open memory. Decided with: an owner decision and §2.8. Spec: the vault scope's written form and its generic examples are Specs-grants §3.9 (planned); the vault's schema and operations are the memory module's spec's to come; the record is grants.md §3.1 with a scope of the vault form (planned). Proof: none at the tag. Today (v0.5.0). Not built: no vault: scope is parsed, no vault command exists (src/permissions/grants.ts; contract/cli.json), and no grant of this shape is in the folder; the vault is today a folder agents edit by hand under its own conventions, which the memory module's plan replaces with commands under grants (its §4, steps 3–4). The decision's ingest and record are read here as the vault commands' operations, not capability words — question 9.

Who grants (§4)

  1. The owner, alone, in 0.5.0. The Kernel's default is that nobody but the owner holds grant (§10), and the owner MAY always grant alone, even where a two-granter rule is set. Granting is the approval: an owner-signed grant is the agreement, and nothing waits for a separate yes after it is recorded. The grant holder of §10 (a second owner, bounded by §8) is the Kernel's and not this release's: no grant of grant is written, and a record that tried would be refused as carrying an administrative word. Spec: grants.md rule 5. Proof: test/permissions/grants.test.ts, test/dev-mode-gates.test.ts. Today (v0.5.0). team grant and team revoke refuse every caller but the owner at a terminal outside the multiplexer, in every mode, with one sentence; dev mode never reaches them (src/permissions/manage.ts, src/dev_mode.ts, contract/cli.json). team approve is gone: "the live team file is the record, and nothing needs approving" (UPGRADE-0.5.md).

How a team grant and a seat grant resolve (§5)

5.1. A team grant MUST be an envelope. It bounds what the team as a whole may be granted (the record's own term; the Kernel's "envelope" in §8 and §9 is the delegation envelope leads holds, a different object). Spec: grants.md rule 9. Proof: test/permissions/resolve.test.ts. Today (v0.5.0). Built: the resolver reads a team grant as the team's envelope, and the role bundle the roles catalogue fills (009) is empty at v0.5.0, so a seat's list is its seat grants within it (src/permissions/resolve.ts).

5.2. A seat's effective list is its own list intersected with that envelope: the capabilities its role's resolved bundle names plus its own seat-level grants, and nothing outside the envelope. Never a union: a team grant gives no seat a capability its role does not hold (an owner decision); a seat grant MAY only narrow the envelope for that seat; a seat resolves within its own team's envelope and never another's; every grant is read within its scope, and a target outside a grant's scope or the envelope's is refused as outside scope. Spec: grants.md rule 9. Proof: test/permissions/resolve.test.ts. Today (v0.5.0). Built for seat grants and the envelope: a seat's list is its own grants intersected with the team's, the most specific admitting rule is recorded, and the role bundle (009 Roles and skills) is empty at v0.5.0; a registry that cannot be read fails closed (src/permissions/resolve.ts).

5.3. Deny MUST win through every grant (§8); absent is deny; a revoked or expired record is not among the active set; a caller with no registry record is refused; every refusal names its rule; the same inputs always give the same answer. Spec: grants.md rule 8. Proof: test/permissions/resolve.test.ts, test/permissions/fail-closed.test.ts. Today (v0.5.0). Built: absent is deny, deny wins through every admitting rule, a revoked or expired record is not in the active set, a caller with no registry record is refused, and every refusal names its rule (src/permissions/resolve.ts).

5.4. Resolution MUST NOT depend on a role's name, in any language. The name is recorded in the answer; the bundle's capability words decide. Spec: grants.md rule 8. Proof: test/permissions/resolve.test.ts. Today (v0.5.0). The resolver is src/permissions/resolve.ts: deny by default, most specific wins among the admitting rules and the admitting rule is recorded, the intersection, outside-scope. The role's resolved bundle is the slot the roles catalogue fills (009 Roles and skills); in 0.5.0 the bridge (src/permissions/who.ts) hands the resolver an empty bundle, so a seat's list is its seat grants within the envelope and its leads, read from the roster's mark or from the file's resolved lead, either one, and nothing from a role yet. A team the registry holds no record of is judged from its file: its seats stand, carry no id, and no grant can name them; a registry that cannot be read fails closed.

How a grant ends (§6)

6.1. A revocation MUST be its own record, never an edit of the grant. It names the grant by its stem and its generation, the pair that is the record's identity, so a later grant under the same name is a new record the revocation never touches. "Revoked" is derived from the record's presence, read fresh at every gate, and depends on no ledger (§15). Spec: grants.md rule 6. Proof: test/permissions/grants.test.ts. Today (v0.5.0). Built: team revoke <name> writes one owner-signed revocation record naming the grant's stem and its generation; the reader matches the pair and leaves the grant out of the active set (src/permissions/grants.ts). One gap: every CLI revocation under a name writes the same record stem (revoke-<name>), so revoking a second generation after the name is reused overwrites the earlier revocation record — the never-removed history is not built across name reuse (question 13).

6.2. Who revokes. The owner MUST be the only revoker, with one exception: a holder may renounce its own (narrowing itself is never an escalation). Nobody else: no revoke capability exists (§3), leads revokes leases and not grants (§7, §9), and a seat relaying the owner's words has no power to write a revocation. Spec: grants.md rule 5. Proof: test/permissions/grants.test.ts, test/dev-mode-gates.test.ts. Today (v0.5.0). Built for the owner: team revoke refuses every caller but the owner at a terminal outside the multiplexer, in every mode; the holder's renunciation is not built (by is owner and the command is owner-only) (src/permissions/manage.ts, src/permissions/grants.ts).

6.3. When it takes effect. A revocation MUST take effect at the next gate check, for every act decided after the record is written; an act that already passed its gate completes (the Kernel promises no mid-effect abort). Spec: grants.md rule 6. Proof: test/permissions/grants.test.ts. Today (v0.5.0). Built: the active set is read fresh at every gate, so a revocation decides every act after its record is written, and nothing aborts an act that already passed its gate (src/permissions/resolve.ts).

6.4. What it does to what was done. A revocation MUST NOT kill anything: seats already running keep running and lose the right at their next gate. Revoking a team grant ends every seat grant inside it, because a seat's list is the intersection and the envelope is gone. The owner is told (§11). Spec: grants.md rules 6 and 9. Proof: test/permissions/grants.test.ts, test/permissions/resolve.test.ts. Today (v0.5.0). Built as the intersection: a running seat is not stopped, it loses the right at its next gate; revoking a team grant removes the envelope, and a seat grant inside it stops admitting while no envelope covers it — a later covering envelope would admit an unchanged seat grant again, and no revocation record is appended for each seat grant (question 13) (src/permissions/resolve.ts, src/permissions/manage.ts). No notice reaches the owner beyond the command's own output (question 8).

6.5. Expiry. A grant MAY carry an expiry, with no default; past it the grant authorises nothing, with no action needed; expiry is routine, not distrust. A grant's expiry is not a lease's and lease-ttl does not bound it. Spec: grants.md rule 6. Proof: test/permissions/grants.test.ts. Today (v0.5.0). Built: an expiry is optional and checked at every use; past it the grant is left out of the active set with no action needed, and lease-ttl does not bound it (src/permissions/grants.ts).

6.6. Revival MUST be a new grant, never a restore of the old record. A revocation record is never removed. Spec: grants.md rule 6. Proof: test/permissions/grants.test.ts. Today (v0.5.0). Built: a revocation record is never removed, and a later grant under the same name is a new record with a new generation, which the revocation never touches (src/permissions/grants.ts) — except across name reuse, where the second revocation overwrites the first (6.1's Today, question 13).

The revocation channel (§7)

  1. In 0.5.0, the owner at a terminal. A revocation MUST come from the owner's terminal: the owner's enrolled device, once it exists, writes the same record with the device's signature, which nothing on the machine can forge. A seat relaying the owner's words with told-provenance would need a power the Kernel's vocabulary does not have (§3; §9 names revocation of a lease by the owner, leads or a holder above it, and of a grant by the owner or a grant holder); that is a later amendment's decision, not this one's and not code. The session's --told relay and its revoke holders are therefore not in this text. Spec: grants.md rule 5, §4. Proof: test/permissions/grants.test.ts, test/dev-mode-gates.test.ts. Today (v0.5.0). As stated: team revoke from the owner's terminal; no device; no relay (src/permissions/manage.ts, src/dev_mode.ts).

The command-to-vocabulary map (§8)

  1. The code MUST invent no capability and gate no command the Kernel's table does not name. The vocabulary is closed and release-versioned (§3), and a grant "per command" is written against the map; the last row is the only thing a grant carries. The map, as the earlier draft's table states it:
Command In the Kernel's terms Authorised by, in 0.5.0 A grant may carry it
team init (and a create where it exists) writing a team where none exists: the owner's act, or the administrative capability create when an agent does it (§10) the owner only; no create-bounds exist, so no agent holds create never (administrative)
team up start a team or seat (§9): runs the hash-pinned start command the owner, or leads for its own team; dev mode lifts only the caller gate no: an operation, reached only through leads held in a role or a delegation record (the Lifecycle delegation section)
team down stop a team (§9) the owner, or leads for its own team; the owner may always stop; the machine-wide stop is the owner's alone (§11) no
team restart, team reload the start row of §9 for one seat (closing and relaunching one seat is the same act) as start no
team add add a seat (§9): a same-copy by an agree holder or the owner; any other seat by the owner or a grant holder the owner (no agree or grant holders in 0.5.0) no
team remove remove a seat (§9) the owner, or leads; a seat holding grant, agree or leads by the owner only; --abandon the owner's in every mode no
team rename editing the roster's display names (the seat keeps its id and its grants, an owner decision) the owner, or leads for its own team no
team register a registry record: a report, confers no right (§4: identity signs, it does not grant) the owner or the seat's own team; dev mode lifts the caller gate; the record's provenance says which not a capability
team grant, team revoke the §9 row "grant a capability or edit the team's configuration" (removing a standing grant is such an edit; §5: an owner can always revoke a compromised power) and, for leases only, "revoke a lease" the owner only never (administrative)
team delegate, the file's delegates section read as standing grants with a command list (one mechanism, not two: the Policies section's open question 4, closed this way for 0.5.0 by an owner decision); kept until registry-bound grants and the Lifecycle delegation section's record replace them the owner it is a grant, written against this map
team send admission, a setting of 002 Communication, never a capability; a refusal names the rule the send admission: chain position and the pair's setting; a grant naming send admits one more pair, recorded as an owner setting as a setting, not a capability
team answer a key into another agent's pane: the pane-authority policy, enforced; pane-conduct advised the target rule: the pane's lead, a seat above it, or the owner's word for that case; trust, login and security prompts by the owner, or by a lead where the owner turned dialogs.trust on for that team (an owner decision) — the built subset in 0.5.0 accepts only the recorded folder-trust operation (src/commands/answer.ts) no
team messages, feed, status, list, check, usage, available, next, waits read surfaces of the Runtime and the modules; the read scope of §3 is not enforced in 0.5.0 any seat with a registry record no
write, read, review, gate, merge, deploy, act-as, use-broker the Kernel's operational capabilities (§3), each with its scope (§6) the seat holding it, within its scope and the constraints of §5; 0.5.0 gates none of them (integrity only, §14) yes: the only things a grant carries, and the only names a grant may use

Spec: grants.md §6 (registries/capabilities.md, operations.md), rules 9–10. Proof: test/permissions/resolve.test.ts. Today (v0.5.0). The map is code, one row per command (src/permissions/map.ts, COMMAND_GATES): a word with no row is refused by the resolver rather than judged; create has no row because it is no command; reload and rename have rows the record's table did not list, under the principals above; available and waits are rows with no command yet; send and answer are rows whose gates live elsewhere and the map admits no one to either. Dev mode's list is nine operations (the decision's eight — the owner decision's seven plus reload, an owner decision — plus rename, the one word left to the round), read as the same words for the two commands that are the start row for one seat and the roster's edit (§10, question 4).

The records, and the owner is told (§9)

  1. Every grant and every revocation MUST be recorded with its provenance, and the owner is told (§11, §15). Until the ledger exists, the records are the signed grant and revocation files and the owner-decisions log; a grant written under dev mode says so in its provenance (an owner decision). Spec: grants.md §3. Proof: test/permissions/grants.test.ts. Today (v0.5.0). The files are signed and carry their generation (src/permissions/grants.ts, src/registry/agents.ts, src/permissions/manage.ts); team grant and team revoke are the owner's alone so no dev-mode provenance arises on them; the registry's agent record carries the dev-mode mark and the delegation a write ran under (Runtime commitment 26). The owner is told by the command's own output alone: writing or revoking a standing grant writes no team-log line in 0.5.0, no notice reaches him, and no command lists the standing grants, the folder's listing being the only view (§10, question 8).

The team file's own forms, kept in 0.5.0 (§10)

  1. The delegates section and the grant section MUST be read as the owner's standing authorizations with a command list (Runtime commitment 24). The owner as signer, the pane as actor, one command per mark; an entry never widens itself; a delegate adds only a same-copy seat. They are the one place a lifecycle operation is given to a pane rather than to a role, which is what the Lifecycle delegation section's lifecycle delegation record replaces by a registry identity, a signer and an expiry. The word approve is still read in a command list and in the grant's scope so that older files parse, and no command consults it. Spec: grants.md §3.6, §3.7, rule 12. Proof: test/permissions/delegates.test.ts. Today (v0.5.0). Built as described, beside the standing records of §3 in the grants folder; their removal edits the file (src/file/sections/delegate.ts, src/file/sections/grant.ts, src/delegate.ts, src/delegate-types.ts).

The Kernel's text, changed (§11)

  1. The exact sentences, so reviewers judge a diff and not a summary (an edit plan for the Kernel, not a commitment).

    1. §7, "Standing grants". Was: "Standing grants — the roles of §4, in the team's configuration, held until changed (§10)." Becomes: "Standing grants — the roles of §4 and the owner's grant records (the Grants section), held until changed, revoked by a separate record, or past an optional expiry the grant carries; a standing grant is not a lease, and lease-ttl does not bound it" [changed].
    2. §10, after the whole bullet "Recorded and signed, taking-back is one act that stays taken — §14 says how far each reaches today". Added: "An owner-signed grant is the agreement to what it grants: no separate approval step follows it, and a seat it names acts under it from the record's generation on" [new].
    3. §14, the row "Grant / agreement". Becomes: "0.5.0: owner-signed standing grants at team and seat level, by registry identity, with an optional expiry, revoked by a separate record effective at the next gate; the resolver (deny by default, list ∩ envelope); the command-to-vocabulary map; no grant holder, no agree, no create bounds, no two-granter; the key readable by every seat; who/when, witnessed-versus-told, general agreements by agents, taking-back that stays taken: not built" with the row's Kind unchanged, M (signing key readable by an agent). The row "Capability vocabulary + gate" becomes: "0.5.0: the eight operational words pinned (vocabulary: 1), refused when unknown; none gated beyond integrity" with Kind M [changed].
    4. §15, after the first paragraph. Added: "Until the ledger is built, the signed grant and revocation files in the owner's grants folder, each under a generation, and the owner-decisions log are the records of grants and revocations; they carry no hash of the previous record, no intent and outcome pair, no signed head, and a revocation never depends on them being complete" [interim].

    Nothing else changes. §3's vocabulary and §9's table are cited as they stand.

3. Why

The owner's decisions, each of which rules something out: grants are per command, granular and revocable (2026-10-15: no all-capabilities shorthand, no grant that cannot be ended); granting is the approval (2026-10-15: no team approve, no first-trust question, nothing waits for a second yes); identity, not seat name (2026-10-15; two owner decisions: a grantee is a registry identity, never a runner, a pane, a session or a name); no self-grant and no self-widening (2026-10-15; Kernel §3, §7); the seven points (an owner decision, "Absolutely"), which are §3 to §9 here; grants at team and seat level, leads in the role (an owner decision); dev mode lifts only the caller gate (three owner decisions). Before 0.5.0 four separate shapes gave agents power (a delegates pane with a command list, the file's grant naming the orchestrator, an out-of-band owner token, dev mode), none could be taken back without the owner's terminal and a new approval, and none named its holder by anything stabler than a seat's name or a pane; the Kernel had the model and none of it was built.

4. What it costs, and what it does not cover

The threat model, said once (§7 below), is the cost: everything here is integrity, not authority, until the key is on the owner's device and agents are contained. What this release must not pretend — the record's list in the Kernel's words, which the code prints (team doctor and team --about):

  • Integrity, not authority. The checks, the owner check included, stop mistakes by agents in multiplexer panes, not a process of the same OS user that sets out to get around them (an owner decision: shipped with the limit stated in SECURITY.md).
  • Standing grants with an expiry, not leases. A seat cannot lend a right to another for a task and take it back; no lease, no re-lease, no parent pointer, no liveness walk, no cascade.
  • No two-granter agreement, no agree, no create bounds. Only the owner grants rights and adds seats.
  • No read scoping, no act-as, no use-broker, no deploy gating. The words are pinned and refused when unknown; they gate nothing yet.
  • No constraint program beyond one leads per team and no seat starting with two exclusive rights: no cardinality, no separation of duties at a gate, no cross-lab predicate.
  • The policy object is built for dev-mode and seven other enforced names and the advised ones (the Policies section); the delivery order is applied with the legs that exist.

Today (v0.5.0). The code's block carries the first five lines, each with its Kernel reference in --json (src/permissions/must-not-pretend.ts); the sixth is this text's own statement of the Policies section's state.

5. What would change our mind

None argued in this text; the open questions of §10 carry the round's decisions.

6. What is true today

"Today" is the tag v0.5.0 of floor/teamcli (52db9b75), read clause by clause.

# Rule Today
3.1 The grant object Yes: the signed record with the nine fields
3.2 Grantee by registry identity Yes: agent id or team id; a name, pane, session or runner is not a grant; the seatless grantee (seat: none) is settled, not built — v0.5.0 is still seat-named
3.3 Operational words only; dialogs.trust the one setting Yes
3.4 Vault access by grant scope Not built: no vault: scope is parsed and no vault command exists at v0.5.0; decided by an owner decision, with the main orchestrator holding read and write on its entity's whole vault
4 The owner grants alone; granting is the approval Yes; team approve gone
5 List ∩ envelope, deny wins, no role name Yes for seat grants and the envelope; the role bundle is empty until 009 fills it
6 Revocation a record, next gate, no ledger; expiry optional; revival a new grant Yes; the holder's renunciation and the notice to the owner not built; running seats keep running; the revocation record's never-removed history is not built across name reuse — the second revoke overwrites the first (question 13)
7 The channel: the owner at a terminal As stated
8 The map Yes, as code; nine dev-mode operations against the decision's eight (the owner decision's seven plus reload, an owner decision), rename the one word open (question 4)
9 Records with provenance; the owner told In part: signed files with a generation; no log line, no notice, no listing command
10 The file's forms kept, approve read and inert Yes
— Must-not-pretend printed (the earlier draft's row 12; not a commitment) Yes: team doctor, team --about, --json with each line's reference (five lines)

7. The security boundary

On a single-user machine whose signing key every seat can read, everything here is integrity, not authority (Kernel §11, §12, §14). It holds against a mistake, gives attribution, and is the slot real authority fills when the key is on the owner's device and agents are contained; until then no rule here holds against a process of the same user that sets out to break it (the same-user limit, Kernel §14, stated once here).

8. Where it sits, and what it leaves to others

Kernel section Effect
§3 (the vocabulary) Unchanged. No revoke capability is added; removing a grant is the §9 row "grant a capability or edit the team's configuration", the owner's. The eight operational words are the only names a grant carries
§7 (delegation) Amended (§2, item 11, sentence 1): a standing grant is held until changed, revoked, or past an optional expiry; it is not a lease, and lease-ttl does not bound it
§9 (the table) Unchanged. The rows stand; this text says which principal 0.5.0 implements for each (§8)
§10 (the grant) Amended (§2, item 11, sentence 2): an owner-signed grant is the agreement; there is no separate approval step after it
§14 (today) Amended (§2, item 11, sentence 3): the grant and agreement row and the vocabulary row rewritten for 0.5.0
§15 (the ledger) Amended (§2, item 11, sentence 4): until the ledger exists, the signed grant and revocation files and the owner-decisions log are the records, and the text says what they lack
The session's rfc-structure.md table Superseded where it adds revoke to §3, a revoke row to §9, sealed_under to §15, a holder's approve, or a runtime window on a grant: none of these is in the record, and the record wins
The team file's delegates and grant sections Kept in 0.5.0, read as standing grants with a command list (§10 here); their retirement is a later release's, after the Lifecycle delegation section

The mechanics (the folder, the record files, the commands, the map as code, the resolver) are the spec's: Specs-grants. Tier 1: every rule here is a refusal or a recorded obligation (Kernel §2); the mechanics are the spec's and the Runtime's.

9. Prior art and alternatives

The session of 2026-10-15 argued a structure this text supersedes where it adds revoke to §3, a revoke row to §9, sealed_under to §15, a holder's approve, or a runtime window on a grant (the decision record wins; the README of the folder lists the differences); its --told relay and its R3/R12 revoke holders are not in this text (§7). The harness grants draft's §3 (the dated grant) is folded into 3.1.

10. Open questions

  1. The holder's renunciation (the record's point (d); the session's D2): written by the holder, by: <agent id>, as the one non-owner revocation; not in 0.5.0. Confirm it stays in the text.
  2. The relay. A seat writing a revocation on the owner's told word (the session's R3, R12) needs a power the vocabulary lacks; the record defers it. Keep deferred, or decide it here as a revoke that only narrows?
  3. The file's forms' retirement. When delegates and the file's grant go: after the Lifecycle delegation section's record exists for lifecycle operations and registry-bound grants cover the rest; one release as forwarders, as an owner decision does for the launch scripts.
  4. Gate-lift's nine against the decision's eight (in code: dev-mode, until the rename ships). reload is decided in by an owner decision (the owner decision's seven plus it are the decision's eight); rename is in the code's list and in no decision's — read here as the same word (the roster's edit), to confirm or to take out.
  5. The approve word read and inert: remove at the forms' retirement, or sooner.
  6. The session's sealed approvals (its R6, sealed_under): moot while nothing is approved; the rule returns if a holder ever seals a file under a grant (a create bound, Kernel §10).
  7. The owner's enrolled device: the same record with the device's signature; its scope should name revocation first, since a relayed revocation is safe and a relayed grant is not.
  8. The listing and the log line. Point (g) asks for records with provenance and the owner told; the records exist, and neither a listing command (team grants, the session's name for it) nor a team-log line on a grant or a revocation does. To build in 0.5.x, as the round's first condition, or later.
  9. The vault effects' words (an owner decision). The decision's note says a grant names "an effect (read, write, ingest, record)". read and write are words of the closed vocabulary; ingest and record are not, and the vocabulary gains no word by a fold (§3; the Lifecycle delegation section §4.2). Read here as: the capabilities are read and write, and ingest and record are the vault commands' operations, gated by the map's rows like every command — unless the owner widens the vocabulary in his own act. To confirm at the round.
  10. A grant to an agent with no seat — settled (an owner decision). Yes: the grantee is a registry identity (commitment 3.2), with or without a seat; the record is the same grant record with seat: none; admission is checked at delivery against the grant, so the watch plays no part; and no new vocabulary word is needed (the concept note's point 4, answered).
  11. The whole-vault orchestrator grant's generality. 3.4's Today reads an owner decision as settling that an entity's main orchestrator holds read and write on its entity's whole vault; that decision is one owner's grant to one orchestrator, not a rule for every entity's. Should the Today read the grant as conditional on an explicit applicable owner grant, with an owner decision standing as the specific precedent, rather than as the default for every main orchestrator? The round to decide.
  12. The seatless grantee's planned spec contract. 3.2 settles the seatless grantee (seat: none) and the spec's planned §3.9 is its written form. Should the spec carry a versioned extension contract for the registry-identified seatless principal — new fields only at a bumped version, so the released decoder never mistakes a new field for one it knows — without implying the 0.5.0 decoder accepts a new field today? The round to decide.
  13. What "ends every seat grant inside it" requires, and the revocation history across name reuse. 6.4's commitment says revoking a team grant ends every seat grant inside it; the built behaviour is the intersection — a seat grant admits while an envelope covers it, a later covering envelope would admit an unchanged seat grant again, and no revocation record is appended per seat grant. Should "ends" mean durable termination, or is the intersection the rule and the commitment's word read at it? And the never-removed history is not built across name reuse: every CLI revocation under a name writes the same record stem, so the second revoke overwrites the first (6.1's Today). The round to rule.
  14. §5's reversal criteria. The source's §9 named two dated-grant falsifiers — owners who rarely revoke and seldom read the log, and an off-machine key solution arriving quickly. Should §5 carry them as the named things that would change the mind, or stay as it is (no argument; the open questions carry the decisions)? The round to decide.

12. Links to the spec

  • Specs-grants §3.1–3.2 — the grant and revocation records (from §3, §6).
  • grants.md §3.3–3.5 — the folder, the send-grant, the create-grant (from §9, §14).
  • grants.md §3.6–3.7 — the file's delegates and grant forms (from §10).
  • grants.md §3.8 — the lifecycle delegation record, planned (from the Lifecycle delegation section).
  • grants.md §4 — the commands and their exit codes (from §14).
  • grants.md §5 — the resolver's, the map's and the bridge's rules (from §5, §8).
  • Registries contributed: capabilities.md, operations.md (grants.md §6).

Policies

Kernel amendment 02 — reviewed draft, not accepted.

1. The question

Every working day produces rules that are neither a capability the Kernel names nor a feature a module ships: which development mode a team works in, whether everyday team commands may run from an agent's context, where an entity's agents may act, how a shared checkout is used, who may press a key in another agent's pane; each project and each entity using TeamCLI also has its own rules for who decides and who validates. Where are those rules written, at which level, who may write them, how do they combine, and what does TeamCLI do with them: refuse, or advise?

2. What we propose

2.1. A policy MUST be a named rule with a value, set at one level, by a named setter, on a date, with a kind. Its content — the name, the allowed values, the default, the kind, the gate or surface it applies to — is defined once, in the text whose feature it governs, and listed in the catalogue; this section defines the object and its rules, not the policies themselves. Enforced policies come from a closed, release-owned vocabulary, like capabilities (Kernel §3): the tool can refuse only what it knows. An advised policy can be a project's own text; the tool carries it and shows it (§2.5). Spec: Specs-policies §3.1, §3.3. Proof: test/policy.test.ts. Today (v0.5.0). The object is built: a signed entry per policy per level, and a catalogue in code of eight enforced names and six advised ones with their defaults and tightening rules (src/policy/types.ts).

2.2. Four levels: entity, project, team, seat. A policy set at a level MUST apply to everything below it: an entity binds its projects, a project its teams, a team its seats (the entity boundary and the team and seat levels of an owner decision; the owner decision's 'defined by project, team'). Spec: Specs-policies §3.2. Proof: test/policy.test.ts. Today (v0.5.0). The four levels are code (src/policy/types.ts:21–23), each with one source file (src/policy/sources.ts:1–6); a fifth, machine level exists only in the settings inheritance, not in the policy levels (§10, question 9).

2.3. Inheritance tightens, never loosens. A lower level MAY set a policy only to a value within the value it inherits; "within" is defined by the policy's own text — a total order on its values, or the within relation of Kernel §6 where the value is a scope. A policy whose text defines no order cannot be overridden below the level that set it, with one exception, for advised policies only (§2.5): where the policy's own text says a lower level chooses, as 010 §2b says of the development mode, the lower level's value stands as a choice, not a loosening; nothing is refused, and the choice is recorded and shown like any value (§2.6). A value that loosens what is inherited MUST be refused when the policy is loaded, not when it is used, and the refusal names the two levels. Where no level sets a value, the release default applies; for a policy that lifts a gate (§2.7), absent means off. Where two values at one level conflict, the stricter stands; a pair the tool cannot order is refused (fail closed, Kernel §11). This is the resolver grants and role bindings already use: the most specific level wins while it tightens, deny beats allow at equal rank. Spec: Specs-policies rule 3. Proof: test/policy.test.ts, test/settings-as-policies.test.ts. Today (v0.5.0). The chain resolves outermost first and refuses a loosening at load, naming both levels and values (src/policy/resolve.ts, src/policy/types.ts); the lower-level-chooses exception is carried by two advised names; one source per level means one value per name per level, so the two-values-at-one-level rule has no case in the code; the settings resolver still lets the project level loosen four settings, which this section does not allow (a residue of the settings surface: src/settings/inherit.ts:56,102,156,162; §10 and the spec's open points 1–7 contain no such question — add one to policies.md §7).

2.4. Setters per level. Entity: the owner, by a signed owner act (Kernel §8). Project and team: the owner; or a holder the owner named for that level by grant, a second owner within the owner's bounds (Kernel §8, §10); or, for a team and only tighter than what it inherits, the role holding leads for that team (Kernel §9), where the owner delegated the right to tighten, which is never a right to loosen. Seat: a seat may set a policy for itself only tighter than what it inherits, and never one that lifts a gate or widens what it may do (§2.7; Kernel §3 and §8, no agent gives itself more). No self-service, at any level: a change that widens the setter's own authority, names the setter as its own approver, or lets the setter's seat gate its own work MUST be refused at load (Kernel §5, separation of duties; §10). Spec: Specs-policies rule 1, open point 3. Proof: test/policy.test.ts. Today (v0.5.0). team policy set and team policy unset admit the owner only, at every level (src/commands/policy.ts); the non-owner setters this section names are not wired.

2.5. Two kinds, fixed by the policy's defining text, not by the setter. An enforced policy is checked at the gate of the operation it names and refuses: it does nothing, names the policy, the level that set it and the rule, and offers no prompt and no fallback to the owner's terminal. An advised policy is shown to the actor where it applies (in a seat's brief at start, and before the command it concerns), and the showing is logged; it never blocks, and a departure from it is a finding for the modules that read findings (Quality, Analysis), never a refusal. A project MUST NOT turn an advised policy into an enforced one (that would add a refusal outside the Kernel, §13), nor an enforced one into an advised one; a policy whose values include off is switched off by its value, under §2.3. Spec: Specs-policies §3.3. Proof: test/policy.test.ts. Today (v0.5.0). The kinds are fixed by the catalogue and a mismatched kind is refused at load (src/policy/types.ts, src/policy/resolve.ts:171–177); the enforced kind refuses at the caller gate it owns — gate-lift (in code: dev-mode, until the rename ships; src/dev_mode.ts); the advised showing — the brief at start, the line before the command, the logged departure — is not built; team policy lists advised values and one advised name is read by a setting's helper (src/settings/seat-numbering.ts:29).

2.6. Every change is a record, and the owner is told. Setting, changing, expiring and revoking a policy are ledger records (Kernel §15) carrying the level, the setter, the old and the new value and the time; the owner is told (Kernel §11). A policy MUST be read from one signed source (the team file's owner sections, the entity's configuration); a readable copy beside the texts is never the source, and a difference is reported, never resolved in favour of the copy. A policy the tool cannot read, verify or order MUST be refused; the default does not silently apply in its place. Spec: Specs-policies rules 2, 4 and 6, open points 1–2. Proof: test/policy.test.ts. Today (v0.5.0). Each level's source is signed and verified fail closed — a source that cannot be parsed, lacks the key, fails verification or mismatches its target refuses and the default never stands in (src/policy/sources.ts, src/policy/resolve.ts); a set or an unset writes a log line and an expiry is logged once and reverts to the default (src/commands/policy.ts:298, src/log.ts); no ledger record and no separate notice to the owner exist yet.

2.7. A policy may lift a "who may run it" gate only for everyday operations — a closed list the owner fixed (an owner decision; exactly those operations, an owner decision), held by the spec's gate-lift rules and not restated here. It may never reach grant, delegate, revoke, approve, create, agree, leads, the machine-wide stop, a reserved object (Kernel §3), the constraint program (§5) or an owner-sovereign limit (§8). Such a policy MUST be set at entity, project or team, never by a seat for itself; MUST carry an optional expiry; MUST lift only the caller gate, never the placement, CLI, record or scope checks; and every use MUST be logged with the caller, the command and the level that set it. The first policy of this class is gate-lift (in code: dev-mode, until the rename ships; the catalogue). Spec: Specs-policies rules 5, 7 and 8. Proof: test/policy.test.ts, test/dev-mode.test.ts, test/dev-mode-gates.test.ts. Today (v0.5.0). Built (src/dev_mode.ts, src/policy/types.ts, src/log.ts): gate-lift set at entity, project or team with an optional expiry; while on for the caller's level the caller gate of the class's operations folds into a warning — nine in the code, the decision's seven plus two more, read as the same words (the Grants section's question 4; the list is the spec's) — every use warned and logged; the compatibility variable is honoured only while no value governs, then ignored and logged once; an expiry reverts to off and is named in the next refusal; the reaches this section forbids are outside it (the spec's gate-lift rules name them).

2.8. No policy goes below the Kernel's floor. Whatever a policy says: an agent never approves its own work (§5); an agent never grants itself a right or widens its own (§3, §7, §10); deny wins through every role, overlay, lease, envelope and policy (§8); the owner holds the keys and the emergency stop (§9, §11); administrative rights are never leased (§3, §7); the reserved objects stay outside every policy (§3). Where a policy and the floor disagree, the floor wins and the tool refuses, naming the rule. A policy MAY be stricter than the floor, never looser. Spec: the Kernel, the sections the promise itself cites (§§3, 5, 7, 8, 9, 10, 11 and any other it names), as the floor. Proof: test/policy.test.ts (the chain's load-time refusals: a loosening refused, gate-lifting fails to off); none at the tag for the floor as such. Today (v0.5.0). The floor holds where the policy resolves (src/policy/types.ts, src/policy/resolve.ts): the chain fails closed, and no policy name reaches an owner power (the catalogue's enforced names are everyday-setting names alone).

2.9. Every command MUST be checked against the policies in force. team init, team create, team up and the other commands read the effective policy for their level before acting. A missing or unknown level permits nothing beyond the default. Spec: Specs-policies §4 (the commands) and §5 rule 7 (the nine operations' gate, the part built); no rule yet makes every command resolve. Proof: none at the tag for the general rule; the resolving paths are covered by test/dev-mode-gates-matrix.test.ts and test/policy.test.ts. Today (v0.5.0). In part (src/dev_mode.ts, src/check/team.ts, src/commands/policy.ts): the commands that resolve a chain today are the gate-lift gates, team check (which reports refusals with their repairs for the team and each seat) and team policy itself (view, set and unset); the seat-numbering helper also resolves one advised name, though it is not a command; a command with no policy of its own to read resolves nothing.

2.10. Granting is the approval; there is no team approve (owner, 2026-10-15). A grant, or a policy that allows an act, MUST take effect when it is set and recorded; nothing waits for a separate yes. Spec: Kernel §10; Specs-policies §4. Proof: none at the tag for the general rule. Today (v0.5.0). team approve is not a command (contract/cli.json); the name is still registered as a stub that prints the removal message and approves nothing (src/cli.ts); a policy set takes effect at the next read of its chain. As the structural reading: after a grant is revoked, approve is refused as grant.not-ordinary (test/authority-edit.test.ts at v0.5.0); a standing grant of approve passes.

2.11. Policies and grants are two things. A grant gives a seat a capability (Kernel §3, §10); a policy sets how the tool behaves for a level. A policy MUST NOT add a capability to a seat's list; where a policy opens a gate (§2.7), the gate is the Kernel's and the opening is bounded here. Floor's rules for who decides on an RFC and how many reviewers it takes are a project's policies of the advised kind, kept in advised project policies, not the tool's. Spec: Kernel §§3, 10; Specs-policies §3.3 (the catalogue's names). Proof: none at the tag. Today (v0.5.0). The two vocabularies are separate in code (src/policy/types.ts, contract/cli.json): no policy name is a capability word, and the command map admits no one through a policy; the project-level advised names board and review-terms are strings the tool writes and lists and nothing else reads.

2.12. Where a policy is written, and how it is read. Each level has one source, and the source is signed: the entity's configuration, under the tool's own folder in the owner's home, signed by the owner (the machine level of open question 9 is its parent, where the owner so decides); the project's registry record, written by the owner through team policy and signed as a grant is (the Grants section); the team file's owner sections, the record in the clone; and, for a seat setting a policy for itself (§2.4), the seat's own registry record, written by the tool with the seat as actor and the owner told. These sources are reserved authority objects in the Kernel's sense ("the team's configuration", §3): no seat-requested file effect reaches them, and a policy written anywhere else MUST NOT be read. A gate reads the chain outermost first, entity, project, team, seat, fresh at every check, and resolves it once (§2.3); a level whose source cannot be read, verified or ordered refuses the command and names the level (§2.6), the default never standing in for a broken source. The effective policy of a level is readable by any caller the record admits to the read surfaces: team policy prints, for one level, every policy in force, its value, the level and the setter that set it, its expiry and its kind, from the same resolution the gate uses, so the view and the gate cannot disagree. The format of the sources, the writing commands and the view are the spec's; the loading of them at every check is the Runtime's (§8). Spec: Specs-policies §3.2, §3.4, rule 9. Proof: test/policy.test.ts. Today (v0.5.0). Built as four source files with a signed policies: map each, read outermost first and verified fail closed (src/policy/sources.ts, src/policy/resolve.ts, src/commands/policy.ts); a seat-level policy, set by the owner, is written to the seat's registry record (§2.12's seat source); team policy prints the effective view per level from the same resolution the gates use, and --json carries it as a schema; unsigned legacy fields are still read — the delivery order beside the signed maps (src/check/team.ts for its shadow report), and the seat-state thresholds in the settings resolver (src/settings/declared.ts, src/commands/seats.ts:67–75, src/watch/pass.ts:333); team check reports the delivery order when shadowed, and has no shadow check for the thresholds.

2.13. The entity's model rule. The entity's model rule MUST be an entity-level, advised policy (an owner decision; advised until the Kernel has a model predicate — §10, question 3), carried out by the tool in every team of the entity: it lists the seats that break the rule, proposes each replacement from the seat's allowed models and the team's visibility, swaps one by one with the handover and reads the status bar back, and team check and team watch flag every breach. Spec: policies.md §5, rule 10; policy-names, the planned model-rule row. Proof: none at the tag. Today (v0.5.0). Not built at v0.5.0: model-rule is not in src/policy/types.ts; this remains a proposed policy.

2.14. The queued swap's wait is a setting. A swap queued under the model rule MUST wait for the seat's task boundary (an owner decision), and the seat takes no new task while it waits (an owner decision), and the wait before the swap runs at the next pause between two turns is a setting — 30 minutes proposed, the swap logged — while a broken seat swaps at once (an owner decision). Spec: policies.md §5, rule 11; policy-names, the planned swap-wait-seconds row. Proof: none at the tag. Today (v0.5.0). Not built at v0.5.0: swap-wait-seconds is not in src/policy/types.ts; the queue and its wait remain proposed.

2.15. The minimum review labs are a setting. The minimum review labs MUST be a setting (an owner decision): a policy at entity, project or team level, default 2, setting the least number of labs — other than the author's — that review the naming-method text and every casting; it is not Quality's review-count, which counts reviewers, not labs. Spec: policies.md §5, rule 12; policy-names, the planned review-labs-min row. Proof: none at the tag. Today (v0.5.0). Not built at v0.5.0: review-labs-min is not in src/policy/types.ts; the lab minimum remains a proposed policy.

2.16. The team file is sectioned, and the tool's commands stay plain. The team file MUST be parsed and written one section at a time — each section a module owning its own schema fragment, the cross-section checks held by the core, the owner sections named by metadata generated from the section list, never by a hand-kept list — and the tool's commands MUST stay plain functions over the parsed file, with no registry of command objects between the parse and the call. A new section lands as one module and its own fragment; nothing else in the file's reading changes. Spec: Specs-cli-extension §3.7, rules 7–8. Proof: test/file-sections.test.ts (rule 7); none at the tag for rule 8 — a structural reading of the commands. Today (v0.5.0). Built: twenty-nine section modules under src/file/sections/, each owning its fragment; the owner sections' names are generated (OWNER_SECTIONS from SECTIONS); the commands are plain functions.

2.17. The entity's value stands across its projects. Where the entity has set a policy, a project below it MUST NOT displace the value: the entity's value always stands (an owner decision). Where the owner wants a project to go further within a policy the chain cannot order, the entity's policy MUST be written as a bound — a floor or a ceiling — not a value; there is no project-first flag. Spec: Specs-policies §3.2, rule 3. Proof: test/policy.test.ts. Today (v0.5.0). Built as the chain's own order: the resolver reads the entity level outermost and a project value that loosens it is refused at load; no project-first flag exists (src/policy/types.ts); a bound is how the owner writes the entity's policy, not a code shape.

2.18. A board reaches the advised policies only. Where a project's own charter delegates to a board (the Charter's Part 2), the board MAY change that project's advised policies without the owner, and MUST NOT change an enforced one (an owner decision); the reach is the delegation's, never this section's. Spec: Specs-policies §3.3 (the kinds); none at the tag for the board's reach — the spec's rule 1 is still owner-only. Proof: test/policy.test.ts. Today (v0.5.0). Not built (src/commands/policy.ts, src/policy/types.ts): team policy set admits the owner only (§2.4), no board principal exists in the code, and the project-level advised names board and review-terms are strings the tool lists and nothing else reads (§2.11).

Adding a policy

The living catalogue's steps.

  1. Define it in the text whose feature it governs, in the headed format, inside that text's rounds.
  2. Add its block or row to the policy catalogue in policies.md, in the same commit.
  3. An enforced policy needs a gate that refuses and a log line; an advised one needs the surface where it is shown. Say which.
  4. Values a team sets go in its team file or entity configuration, recorded as this section says; never in the catalogue.

3. Why

  • The Charter already says that how a team works is a setting with a default, and that a few things hold whatever is set (Part 1, "Yours to set"); this section names that setting, the levels it is set at, how values combine, and the few things that hold (§2.8).
  • The rules of 2026-10-16 and 2026-10-17 had no home: the development mode landed in a module (010 §2b), the gate lift in an environment variable, the entity boundary in a decision log, the pane rule nowhere. With one object and one resolver, each has a home, a level and a record, and the tool can answer "what is in force for this team".
  • The Kernel's membership test (§2) puts the object here: an enforced policy is a refusal, setting one is an exercise of authority, and the resolver is the one grants already use (§6 within, §8 deny wins). A tier of its own would renumber the series and rest authority on the Runtime; a module would let a module add a refusal (§13).
  • An earlier draft showed the gap: Floor's board and reviewer count were written into the Charter and into Kernel §17 as if they were TeamCLI's rules. They are one project's policies.

4. What it costs, and what it does not cover

  • Not everything is enforceable. "Independent by model" has no Kernel predicate today (the Kernel checks labs, §5); until it does, such a rule is advised, and the tool says so.
  • One more object to keep true. A level that writes nothing gets the default; a level that writes a policy must keep it within what it inherits, or the load refuses.
  • Not a security boundary yet. Every gate is integrity, not authority, until containment (Kernel §11, §12); a policy is no stronger than the gate that enforces it.
  • Not covered here: the storage, the commands and the effective-policy view (the Runtime, and the spec); the content of each policy (its defining text and the catalogue); what a role is (009); how several voices become one decision (006); what counts as done (005).

What this release must not pretend

The current text's own limits, restated: the enforced kind refuses at one gate class only (the caller gate of §2.7's operations); the advised kind is listed, not yet shown or logged as §2.5 promises; the changes are log lines, not ledger records, and tell the owner nothing beyond the command's own output; the non-owner setters of §2.4 are not wired; the machine level of question 9 is unsettled.

The three added policies are proposals; their Today rows follow a later decision:

Commitment Today
2.13 not built at v0.5.0
2.14 not built at v0.5.0
2.15 not built at v0.5.0

5. What would change our mind

  • If every rule turns out to be either a grant or a module setting and no level ever sets a policy, the object adds weight for nothing.
  • If a needed rule cannot be stated in Kernel terms without widening the Kernel, the line of §2.1 (a closed vocabulary for enforced policies) must be redrawn.
  • If gate-lifting policies (§2.7) are used in practice to pass around review, the list shrinks or the class goes.

6. What is true today

"Today" is the tag v0.5.0 (52db9b75). The current text's §7 (0.5.0-rc.3.2: "there is no policy object") is superseded by the release; the rows are re-read at the tag.

# Commitment Today
2.1 The object, its fields, the closed enforced vocabulary Built: signed entries; eight enforced names, six advised, with defaults and tightening rules in code
2.2 Four levels Built; a machine level exists only in the settings inheritance (question 9)
2.3 Tighten-only, load-time refusal, absent-means-off Built for the policy chain; the settings resolver still loosens four settings at project level
2.4 Setters per level, no self-service Owner-only wired; leads tightening and seat self-tightening not built
2.5 Two kinds fixed by the defining text Kinds fixed and mismatch refused; the advised showing and its logging not built
2.6 Records, one signed source, fail closed Sources signed and verified fail closed; changes are log lines, no ledger record, no owner notice
2.7 The bounded gate-lifting class Built for gate-lift: nine operations — the decision's seven plus two more, the list the spec's — expiry, every use logged; the forbidden reaches outside
2.8 The floor Holds where the chain resolves; no policy name reaches an owner power
2.9 Every command checked In part: the gate-lift gates, team check and team policy itself; the seat-numbering helper resolves one advised name
2.10 Granting is the approval team approve is not a command
2.11 Policies and grants are two things Separate vocabularies; no policy is a capability word
2.12 One signed source per level, outermost-first read, the view Built, with unsigned legacy fields still read — the delivery order beside the signed maps (shadow-reported by team check), the seat-state thresholds in the settings resolver (no shadow check)
2.13 The entity's model rule not built at v0.5.0; model-rule remains planned
2.14 The queued swap's wait not built at v0.5.0; swap-wait-seconds remains planned
2.15 The minimum review labs not built at v0.5.0; review-labs-min remains planned
2.16 The sectioned file and the plain commands Built: twenty-nine section modules, generated owner-section names, plain command functions
2.17 The entity's value across projects Built as the chain's order — outermost first, a loosening refused at load; no project-first flag
2.18 A board reaches the advised policies only Not built: owner-only setters, no board principal

7. The security boundary

  • A policy is an authority object. Whoever can change it can change who decides and who may act. So it is reserved (Kernel §3), owner-sovereign at the entity level (§8), signed, recorded and told (§11, §15). A grant holder sets within its grant and may not widen it; a delegate can never approve a change to it, as the shipped delegates guard already does for its own section.
  • Load-time refusal. A loosening, a self-service change and an unknown enforced name are refused when the policy is loaded, so a bad policy never reaches a gate.
  • Gate-lifting is the dangerous class (§2.7). Its reach is bounded by the operation list, the level, the expiry and the log; a policy that would reach an owner power is refused at load. The environment variable that lifted the gate before the object existed takes effect only where the effective policy allows it, and its ignoring is logged.
  • Refusal by level and rule. A command refused by a policy names the policy, the level and the rule, before it acts. A missing or unknown level permits nothing beyond the default.
  • Placement is not identity. Today's delegation matches a pane by its herdr id and process ancestry; that guards a mistaken agent, not a hostile one. A policy that relies on it says so.
  • Fail closed, one source, the floor is not a setting (§2.6, §2.8; Kernel §5, §11, §13). The same-user limit is the Kernel's §14, stated once (the Grants section §7).

8. Where it sits, and what it leaves to others

Tier 1, Kernel amendment 02: this text and the catalogue (the policies in force, a living page). The mechanics are the Runtime's and the spec's: where values live, load order, team policy and team check, expiry, the log lines, the effective view per level; the Runtime sets no policy of its own (Kernel §16). Each policy's content lives in the text whose feature it governs and is listed in the catalogue; the catalogue's rows are the policy-names registry's rows and the spec's defaults. Floor's governance of the RFC process (who decides, review terms) lives in advised project policies. The pane conduct rule is 002 Communication's.

9. Prior art and alternatives

An early draft (2026-10-15) proposed three candidate locations and "a policy is written by role"; later rounds and the owner's go of 2026-10-17 settled Tier 1, and the changes became catalogue rows and §2.4's delegated tightening. The alternative — a tier of its own, or a module — is refused in §3.

10. Open questions

  1. For the build: Storage. Answered in shape by §2.12: one signed source per level, the four sources named. Open: which key signs the entity's configuration before the owner's device key exists, and whether a seat's own tightening, once a seat may set one, is written to its registry record, as §2.12 says (the code writes the seat-level source, but only the owner can set it), or to the team file.
  2. Entity across projects — settled (an owner decision). The entity's value always stands; where the owner wants a project to go further within a policy the chain cannot order, the entity's policy is written as a bound — a floor or a ceiling — not a value; there is no project-first flag.
  3. Lab or model. Does the Kernel gain a model predicate, so that "not the authoring model" can be enforced rather than advised?
  4. Words. A delegation (the team file's delegates) and a lease (Kernel §7): one mechanism or two? Closed for 0.5.0 by an owner decision: one mechanism, a delegates entry is read as a standing grant; the lease side of the question stays for the Grants section.
  5. Agreement. With granting as the approval, what remains of agree and of two-granter agreement (Kernel §10)? In 0.5.0: nothing, the owner grants alone (an owner decision); the question stays for this section's rounds.
  6. Names — settled (an owner decision). The gate-lifting switch is renamed gate-lift — it lifts a gate, it is not a mode — and local-fast stays the development mode's one name; the rename is applied in this text and in the specs that name the switch, the code's identifiers keeping the tag's spelling until the port carries the echo.
  7. The board — settled (an owner decision). A project's board may change the project's advised policies without the owner, never the enforced ones, where the Charter's Part 2 delegation names the board.
  8. Expiry. Should every gate-lifting policy carry a mandatory expiry, as a lease does, rather than an optional one?
  9. For the build: A machine level. The owner named the tool's own configuration as a place to set a policy ("in the teamcli config or by project or by team", 2026-10-17, on commit-signature, an owner decision): a level above the entity, bound to the machine TeamCLI runs on, set by the owner. Is it a fifth level of §2.2, with its own setter and its place in the inheritance, or the release default of §2.3 made settable? A fifth level binds every entity on the machine, which the entity model (an owner decision) did not foresee; a settable default keeps four levels but is then a value with no record of its own unless §2.6 reaches it. The catalogue's commit-signature uses it as a level, pending the answer; the settings inheritance already carries the fifth level and the policy levels do not.
  10. 2.16's two promises. 2.16 joins the sectioned file and the plain commands with one "and" — two promises carried from 0002 §§4.3–4.4 and folded as one. Either say why they are one promise (a section is a module, a command a plain function over the parsed file; the file's structure is data, not a framework) or split them at the next numbering the round allows. The round to decide.

12. Links to the spec

  • Specs-policies §3.1 — the signed policy entry (from §2.1, §2.6).
  • Specs-policies §3.2 — the four level sources and the expired marker (from §2.12).
  • Specs-policies §3.3 — the catalogue names, aliases, defaults and tightening rules (from the catalogue's rows).
  • Specs-policies §3.4, §4 — the team policy output schema and command synopses (from §2.12).
  • Specs-policies §5 — the resolver's, the signer's and the gate-lift runtime's rules (from §2.3, §2.5, §2.6, §2.7).
  • Specs-cli-extension §3.1–3.8, §5 — the screen grammar, the composer-region safety floor, the restricted portable patterns, the staged escape hatch, the sectioned team file and the plain commands, the conformance suite (from §2.16, the carried feature note of question 10).
  • Registries contributed: policy-names.md (policies.md §6, both tables).

Lifecycle delegation

Kernel amendment 03 — reviewed draft, not accepted.

1. The question

Who may start, stop, restart, reload, add a declared copy to, or remove an ordinary seat from a team, when the owner is not at the machine and the seat acting is not the team's lead: a seat of the entity's own team that handles many teams, or an operator acting on its lead's line?

2. What we propose

  1. The record. A lifecycle delegation MUST be a first-class, immutable ledger record (§15).

3.1. signer. The owner; or leads, for its own team only and only for the operations the §9 table gives leads (start, stop, restart, reload, the execution of a same-copy add, the removal of an ordinary seat). A signer MUST never delegate what it does not hold, and leads MUST never re-delegate a delegation it received. 3.2. delegate. One seat, by its registry id (an owner decision, point 14): never a pane, a runner, a session or a name. The seat MUST keep the delegation across a pane change and an occupant change inside its binding; a rebind of the seat (§8) revokes it; removing the seat ends it. 3.3. operations. MUST be a subset of start, stop, restart, reload, add-same-copy, remove-ordinary, register, swap (the lead's agent replaced and nothing else, as in the Runtime's commitment 24), and MUST NOT reach --abandon (owner only, an owner decision), an add that is not a same-copy (a grant, §9), the removal of a seat holding grant, agree or leads (owner only), a change to a sovereign section of the file, or grant, agree, create or a lease. 3.4. teams. An explicit list by team id. An owner-signed record MAY name any team of the entity; a leads-signed record names its own team and no other. One act per team: a stop or a start names one team and never reaches another (§9), whatever the list holds. 3.5. issued, expiry, generation, signature, revocation. Issued; an optional expiry checked at every use; a generation; the signer's signature; and it MUST be revoked by a separate revocation record from the signer or the owner (§7, §15). Spec: Specs-grants §3.8. Proof: none at the tag. Today (int/0.5.1 8acb470b, unreleased). Not built: no record of this kind exists in the code at the integration tip (src/delegate-types.ts, src/file/sections/delegate.ts — the only delegation forms, no lifecycle-record type); the shape above is this section's decision, staged in the spec as a planned format (Specs-grants §3.8).

3.6. How an act under it is read. The signer MUST be the principal on every record the act writes and the delegate is the actor (§9; Runtime commitment 24); the log line says both before the effect. A same-copy add under an owner-signed record is authorized by that record, the owner's standing agreement to the copies the file declares exactly as written (§10); under a leads-signed record the add is executed only, and waits for an agree holder or the owner as today. A delegated run needs no gate-lift (in code: dev-mode, until the rename ships): the record is the caller gate's answer, and gate-lifting returns to what an owner decision made it, a development convenience and never the way a team is operated. Spec: Specs-grants §3.8, "How an act under it is read". Proof: none at the tag. Today (int/0.5.1 8acb470b, unreleased). Not built; a delegated run still needs gate-lift (§6 row 3.6).

  1. What it replaces, and what it does not change.

4.1. Replaces: the delegates section and the grant section's lifecycle scope words it consults (up, down, reload) — approve is read and inert, init is owner-only and stays the owner's, and the record's swap replaces the section's swap, which no gate consults — both owner sections read as standing grants in 0.5.0; and the dependence of operators' lifecycle commands on gate-lifting. The file sections MUST stay readable until migrated; team check MUST report an entry with no record behind it, and 0.5.1 writes the record from the entry at the owner's team grant (the approval, the Policies section §2.10). Spec: Specs-grants §§3.6–3.8. Proof: none at the tag. Today (int/0.5.1 8acb470b, unreleased). The file forms it replaces stand (the delegates and grant sections, read as standing grants; src/file/sections/delegate.ts, src/file/sections/grant.ts, src/file/types.ts); the migration step, the team check report and the write-from-entry are not built (§6 row 4.1).

4.2. Does not change. This section MUST NOT change the §9 table's principals (the owner, leads for its own team); the owner-sovereign limits of §8; the closed vocabulary of §3, which gains no word; the send admission (002), where the lead of the entity's own team already reaches every team lead of the entity and any further pair is the owner's send grant, a setting; or anything the owner decided on 2026-10-17 (three owner decisions, one of them kept as its universal-channel requirement alone, its address grammar superseded by another). The owner's direction for a main orchestrator "that can handle many teams" is met by this record signed by him for every team of the entity, with him as principal on every act; where that direction said "grant", the Kernel's word is this record. Spec: Specs-grants §§3.6–3.8. Proof: none at the tag. Today (int/0.5.1 8acb470b, unreleased). Holds (src/permissions/map.ts, src/policy/types.ts): the §9 principals, §8's limits, §3's vocabulary and the send admission are as they were; the create-grant's admission by name remains ended by an owner decision (§6 row 4.2).

3. Why

Lifecycle operations are not capabilities: §3 lists start, stop, add and remove as operations, and the §9 table gives each one principal — the owner, or leads for its own team; "the executing actor is recorded separately and authorizes nothing". A grant carries none of them (the Grants section's record, point f), and a lease carries only operational capabilities (§7), so neither a grant nor a lease can hand them to anyone. What exists for the case is the team file's delegates section: up to eight panes outside the team's session, each with a command list, read in 0.5.0 as a standing grant with a command list (an owner decision; Runtime commitment 24): the owner is the signer, the pane the actor. It is keyed by a pane, so it dies with a pane change and names no seat; and an operator of the team's own session is not in it at all: today its lifecycle commands pass the caller gate only because a gate-lifting policy lifts that gate (an owner decision; Runtime commitment 12). The gap is one object: a standing authorization of lifecycle operations, signed by the principal the §9 table names, naming the acting seat by its registry id.

4. What it costs, and what it does not cover

Lean by design; the round widens it (the earlier draft's own note). One more record kind beside the grant and the revocation, and a migration for the two file forms it replaces.

What this release must not pretend

Nothing of this section is code at the integration tip: the record, its revocation, the migration and the team check report are decided and not built; the owner at the machine remains the way a team is operated outside gate-lift, and operators' lifecycle commands still pass only under gate-lift.

5. What would change our mind

None argued in this text.

6. What is true today

"Today" is int/0.5.1 8acb470b, unreleased.

# Rule Today
3.1–3.5 The record and its fields Not built at int/0.5.1 8acb470b
3.6 How an act under it is read Not built; a delegated run still needs gate-lift
4.1 Replaces the file forms; migration The file forms stand (the delegates entry, pane-keyed, and the orchestrator's grant scope); the migration, the check's report and the write-from-entry are not built
4.2 Changes nothing listed Holds: the §9 principals, §8's limits, §3's vocabulary and the send admission are as they were; the create-grant's admission by name remains ended by an owner decision
— The caller gate today The gate-lift policy (or, while ungoverned, the environment variable) lifts the caller gate of the nine everyday operations in every running team; the record is to be the answer that needs neither

7. The security boundary

The record is integrity, not authority, on a machine whose signing key every seat can read (Kernel §11, §12, §14; the same-user limit stated once, the Grants section §7). What it fixes is identity and attribution: the delegate is a registry id that survives a pane change, not a pane's name; the signer is the principal on every act, and the log line says both.

8. Where it sits, and what it leaves to others

Kernel amendment 03, beside amendments 01 and 02: it amends the Kernel's §9 (the lifecycle rows and the executing actor), with §3 (lifecycle operations are not capabilities), §7 (only operational capabilities are leasable), §8 (what a rebind revokes), §10 (the same-copy) and §15 (the record) cited; it adds one record kind and changes no accepted sentence until it is itself accepted (the review process, rule 4). The record's format is the grants spec's (Specs-grants §3.8); the caller gate it answers is the Runtime's; the roles that need it are 009's catalogue.

9. Prior art and alternatives

The delegates section is the existing mechanism for the case, and this section argues its defects (pane-keyed, dies with a pane change, names no seat, excludes the team's own operators); the dependence on gate-lift is the alternative it removes. Drafted beside the 0.5.1 roles catalogue (009 Roles and skills), whose main orchestrator and operator rows need the object.

10. Open questions

  1. Re-delegation. leads never re-delegates here. Is there a case for an operator's operator?
  2. Two-granter. Where the owner set the two-granter requirement (§10), does an owner-signed lifecycle delegation need the co-authorization too? The draft says yes for remove-ordinary and add-same-copy, no for start, stop, restart, reload.
  3. The notice. Every delegation and revocation tells the owner (§11) and is a ledger record (§15): is the ledger's first file this record, or the grant's?
  4. register. Registering a running seat is a report, not a lifecycle change (Runtime commitment 5); keep it in the list for the operator's convenience, or leave it to the caller gate's own rule?
  5. 3.1's parenthetical. 3.1 lists "the execution of a same-copy add" among "the operations the §9 table gives leads"; the table gives the add to the owner or an agree holder, and 3.6 carries the execution-only reading (a leads-signed add waits for an agree holder or the owner). Should 3.1's list separate the execution-only case from the operations the table gives leads outright? The round to decide.
  6. §5's stated condition. §5 says "None argued in this text." Should it state the condition under which a separate lifecycle delegation record would become unnecessary — lifecycle operations folding into operational capabilities, or every team operated solely by its own leads with no cross-team or operator seats? The round to decide.

12. Links to the spec

  • Specs-grants §3.8 — the lifecycle delegation record, its fields and the reading of an act under it (from §3); marked planned, not built at int/0.5.1 8acb470b.
  • The caller gate the record answers: Specs-policies §5 rules 7–8 (the gate-lift runtime), and the map's rows in Specs-grants §6.
  • Registries contributed: none new (the operations list is the operations registry's, fed by the Grants section).

Clone this wiki locally