Skip to content

The proposal store is a separate repo from published state


The proposal store is a separate repo from published state

Section titled “The proposal store is a separate repo from published state”

Date: 2026-08-18 Status: open Supersedes: none Superseded-by: none — current Upholds: MR-13

Cycle stage 6 lets a chat surface a STATE CHANGE proposal; stage 7 tests it against repo truth at the next harvest. LOOP-1 requires that stage 6 never writes stage 4: a chat-originated delta is a proposal with a lifecycle, never a state mutation. If conversation could write STATE, the derivation hash would attest to repo derivation for content that came from a chat, and provenance would collapse silently — the failure is invisible precisely because the artefact still looks correctly signed.

The question is whether proposals live alongside state or in their own store.

The proposal store is its own repo, panto-proposals. MIM writes there and nowhere else.

Five reasons, in order of force:

  1. The provenance claim depends on it. state.example.json asserts generated_by and source_commit. That claim is checkable only if the ONLY writer to panto-state is the deterministic pipeline. A second writer makes commit authorship the sole discriminator between a derived fact and a model’s suggestion — and a reader fetching state.json over HTTP never sees the commit author.
  2. It is existing estate law, not a new idea. Intent and observation are separate state spaces (https://petrova.blog/meta-rules/mr-13). state/.yaml is observation, written by probes; registry.yaml is intent. Proposals are intent.
  3. Repo scope is the only enforceable grain. A GitHub App installation token scopes to repositories, not paths.
  4. Different retention: state is tombstoned and kept, proposals churn and expire.
  5. PANTOGRAPH’s own I-1 — ‘Observer, never mutator… never opens a PR, never pushes’, declared as write-surface: none. A proposal directory inside the observer’s output repo contradicts the invariant the system is named for.

Promotion is human-only. A proposal never becomes state; it becomes a decision-record PR against the tenant’s repo, opened by a human.

One store, proposals under a path prefix inside panto-state

Section titled “One store, proposals under a path prefix inside panto-state”

Rejected: Trust level becomes a naming convention. A consumer would have to read a path convention to know whether the bytes are deterministic pipeline output or model-authored, which is exactly the failure invariant I-2 (‘rendered, never generated’) exists to prevent.

Proposals as pull requests against panto-state, reusing GitHub’s review mechanism

Section titled “Proposals as pull requests against panto-state, reusing GitHub’s review mechanism”

Rejected: Requires granting MIM write on panto-state — branch creation is a write — on precisely the repo the credential boundary is defending. It also makes panto-state’s ref namespace a function of an LLM’s output volume.

Rejected: The correct eventual shape, deferred on operational surface rather than principle: every published surface in the estate today is build-time static. Revisit at roughly 50 proposals/day/tenant, or the first status transition that is not a commit.

  • docs/panto/README.md
  • panto-cloud/state.example.json
  • petrova-codes/state/kahn-hq.yaml

Human merge required — this PR is opened with the awaiting-human-merge label and does not auto-merge.