Skip to content

Admit the L2 fleet-context band and the GENERATED statements band on the MARY governance console route


Admit the L2 fleet-context band and the GENERATED statements band on the MARY governance console route

Section titled “Admit the L2 fleet-context band and the GENERATED statements band on the MARY governance console route”

Date: 2026-10-08 Status: closed Supersedes: none Superseded-by: none — current MR-compliance: MR-4, MR-7, MR-9

2026-10-07-mary-governance-console-route.md (closed, countersigned 2026-10-07) admitted /console/repo/mary-wiki/governance as a read-only route. It is built (#532) and now also renders mary-wiki’s L1 diagnostics band (#541) and a Cmd-K read palette (#542). Phase P6 of eva-hq:docs/reports/2026-10-03-mary-governance-surface-phases.md adds two more layers on top:

  • L2, fleet context for mary-wiki read from petrova.context: phase, IRINA trust share, deep-probe history and contract_sha parity. These are “context rows only, never merged into MARY’s own numbers”.
  • L3, a model pass over one snapshot that yields at most five statements.

mary-wiki has ruled on L3. Its D3, mary-wiki:docs/decisions/2026-10-07-inferred-statements-on-governance-surface-proposed.md, was ratified by FLIGHT on 2026-10-08 (R-1 to R-8, with open question 1 ruled (ii), so the surface label is GENERATED). D3 binds what a statement may be. It does not decide where generation runs, where the verifier runs, or how petrova renders the output. D3 says that “is petrova-codes’ (D6)” and that the render is “its own PR under its own repository’s rules”. eva-hq #109 (a7a4e96) merged the engine, prompts/mary-governance-diagnose/. Its verify.sh calls itself “the REFERENCE VERIFIER SPEC for D3 R-4”.

Why L2 needs this document too. The route’s terms do not admit an L2 band. Term 1 reads: “Scope is mary-wiki’s R-2 and nothing else. Five panels … as R-2 defines them.” Term 4 reads: “The feed is mary-wiki’s CI snapshot … The read is exposed to the dashboard as one read-only host RPC method.” The route’s own header comment says “The one read is petrova.mary.governance_snapshot”. Its module-graph test asserts that the page “reaches the host only over RPC: no host source, no tool-ctx, no credential resolver” (dashboard/src/pages/console/repo/mary-wiki/governance.test.ts:344).

The L1 band fits these terms because it rides inside the snapshot feed (term 4). #541 records “no new host read”. An L2 band read from petrova.context does not fit. It is a second host read, and it is not part of mary-wiki’s CI snapshot, so it is outside both term 1 and term 4. Mary-wiki’s siting R-6 also reads “the figures come from a snapshot emitted by this repository’s own CI”. D3 does call L2 “a derivation of the kind siting R-4 already covers”, but that ruling is about provenance, not about petrova’s read count. So L2 is admitted here (term 1), on its own terms, rather than built under the route decision.

petrova-codes admits two new bands on /console/repo/mary-wiki/governance only, on the terms below. The route’s terms 1–6 stand. Term 1 below adds one host read to route term 4, and terms 1 and 2 below add two bands to route term 1’s scope. Neither widens anything else.

  1. L2 “Fleet context (petrova)” band.

    • The read. The route may make one more read-only host RPC call: petrova.context with slug: "mary-wiki". It makes no other new call. The page still reaches the host only through callRpc. It imports no host source and no tool-ctx, and it holds no new credential.
    • Placement. The band renders below the L1 band, under the heading “Fleet context (petrova)”. The heading says that these rows describe mary-wiki as the fleet sees it and are not MARY’s figures.
    • Rows. There are four: phase, IRINA trust share, deep-probe history and contract_sha parity. Each row shows its value, the source tool (petrova.context) and its read time.
    • Failure. A failed or missing field renders as UNREAD with a reason. A failure of this read never changes, hides or delays a MARY band, and a failure of the MARY snapshot read never hides this band.
    • Isolation. No L2 value is added to, compared with or used to colour a MARY figure, and none feeds the palette’s computed answers.
  2. GENERATED band, strictly on D3’s terms. Statements produced by mary-governance-diagnose may render below the L1 and L2 bands, never above, beside or in place of a figure (D3 R-5). They never set a band’s colour, state or ordering. Each statement shows:

    • the label GENERATED on the statement itself;
    • the model id;
    • mary-governance-diagnose@<eva-hq sha>;
    • the snapshot run id;
    • its citations.

    There are at most five statements (D3 R-7). They are generated at snapshot time, once per run id, and never at page view (D3 R-6): the page reads stored output and never calls or waits on a model. The prompt’s strict output (mary.governance-diagnose.v1) has exactly four keys and carries no model id. So the stored record wraps it as {output, verdict, provenance: {model_id, prompt_id, prompt_sha, run_id, generated_at, job_run}}, and the page shows provenance from that wrapper. A citation <run_id>#<row id> links to the matching on-page anchor (#541). A JSON-pointer citation (D3 R-3 interim) renders as text naming its panel. No statement, citation or band element performs an act. Route term 3’s module-graph guard covers the band’s code.

  3. The verifier is deterministic, final, and runs on the host.

    • The port. The build ports eva-hq prompts/mary-governance-diagnose/verify.sh, at a pinned eva-hq sha, to TypeScript in host/src/. The port keeps the same envelope rules, per-statement rules (keys, label, one-line text up to 280 characters, citations resolving to an object in the same run, the digit rule) and surface lint.
    • Parity. It is parity-tested against that sha’s examples/* fixtures and against the seeded violations in eva-hq tests/test_mary_governance_diagnose_verify.py.
    • Where it runs. The generation job runs it before storing the output. The host runs it again at read time, over the stored output against the snapshot of the same run id. The page renders only the statements the host’s run keeps. Both runs are deterministic, so they agree. If they disagree, the band renders UNREAD (“verifier disagreement”) and shows no statement. The host’s verdict is final (D3 R-4). No model takes part in verification.
  4. Found-nothing and dropped-everything read differently. The band is always in one of five states, and each is stated in words, never by colour alone:

    • (a) found nothing: “0 statements generated for run N; 0 dropped”;
    • (b) all dropped: “n generated for run N; all n dropped by the verifier; none shown”;
    • (c) some dropped: the kept statements, then “k of n shown; d dropped”;
    • (d) output refused: “UNREAD: output for run N refused by the verifier (envelope)”. There is no statement count, because a refused envelope’s count is not trusted;
    • (e) no output: “UNREAD: no generated output for run N”, with the reason.

    The band shows how many statements were dropped, not why. The reasons quote model text, so they stay in the stored verdict. In states (d) and (e), statements from an earlier run are never shown, because they cite another run and D3 R-4 drops them. When the snapshot itself is UNREAD, the band is UNREAD too.

  5. Generation runs where FLIGHT chooses, from the candidates below, and nowhere else. Every candidate needs an Anthropic API credential, and only FLIGHT can provision or assign one.

    Where generation runsCredential and holding orgForAgainst
    (a)A step in mary-wiki’s governance-snapshot.yml, after the denylist scan. It uploads a governance-diagnose artifact in the same run.A new ANTHROPIC_API_KEY repo secret on mary-wiki/mary, held by the mary-wiki org. That repo has no model credential today, and the workflow says “Nothing here holds or needs a secret”. It also needs an eva-hq read for the prompt at its sha.One run id holds both input and output. The host keeps reading through the existing petrova.mary.governance_snapshot path with the existing read-only token.It adds mary-wiki’s first model secret to a profile: strict, human-merge repo, and needs a mary-wiki PR and decision under mary-wiki’s rules. L2 would need a petrova bearer in mary-wiki CI to freeze context into the input.
    (b)A scheduled petrova-codes workflow. It reads the newest snapshot artifact with MARY_SNAPSHOT_READ_TOKEN (route ruling (ii)) and generates once per new run id (idempotent by run id). It stores the wrapped record as a workflow artifact keyed by run id.petrova-codes. Either it reuses the repo’s existing ANTHROPIC_API_KEY (set 2026-09-11), which 2026-09-15-ir-017-irina-secret-scope-and-retention.md records as “used only by irina-cycle.yml”, or FLIGHT provisions a separate key. The eva-hq read uses the existing EVA_HQ_READ_TOKEN.mary-wiki stays secret-free. L2 can be frozen into the generation input from petrova’s own state at generation time, so cited L2 rows exist in a fixed capture (D3 R-2: “one L1/L2 snapshot”). The verifier port sits next to the render.Output lags the snapshot by up to one petrova schedule interval. petrova-codes’ own .petrova/contract.yaml declares eva: not_applicable because it “consumes neither rocky nor eva surfaces”, which stops being true (see Consequences).
    (c)The host, generating on the first page view of a run id and caching the result——Rejected: a page view would trigger and wait on a model (D3 R-6).

    The drafting agent recommends (b) with a separate key. It keeps the strict, human-merge repository free of a model secret, and a separate key makes this spend attributable and revocable apart from IRINA’s.

  6. Cost is capped before the first call. The job reads a per-run USD ceiling from its environment. If the ceiling is unset, the job does not call the model. It stores state (e) with the reason “no cost ceiling set” (the same skip-when-unset pattern as irina-cycle.yml, which uses IRINA_CYCLE_COST_CEILING_USD). A run that would exceed the ceiling is not retried. The snapshot schedule (41 */6 * * *) caps calls at four a day. The build PR records token counts and cost for its first runs.

  7. First render waits for D3 R-8. No GENERATED statement renders until bin/eva eval mary-governance-diagnose passes at the pinned sha. eva-hq #109 records 12/12 live at a7a4e96. The build re-runs it at whatever sha it pins. Citation precision is 100%, and the clean fixture returns zero statements.

This decision builds nothing.

  • Build L2 under the route decision as it stands. Rejected. Route term 4 admits “one read-only host RPC method”, and the L2 read is a second one, outside mary-wiki’s CI snapshot. A band built that way would breach a closed decision without a record.
  • Fold L2 into mary-wiki’s snapshot rather than a live host read. This was not chosen for the band. It would put a petrova bearer into mary-wiki CI, and fleet context is petrova’s own state, which the host already serves. It stays open, under candidate (a), for the frozen L2 capture that L3 cites.
  • Merge L2 values into MARY’s panels (for example, contract parity in the Drift panel). Rejected. P6 says “never merged into MARY’s own numbers”. It would also mix two sources under one provenance line (route term 5).
  • Trust the producer’s verdict and skip the host re-check. Rejected. Under (a) the producer runs in another org’s CI. The host’s own deterministic run is what keeps “the verifier’s verdict is final” true at the point of render.
  • Show the drop reasons on the page. Rejected. The reasons quote dropped model text, and D3 R-1 says “nothing is shown in its place except the count”.
  • No GENERATED band at all: stop at L1 and L2. Not rejected as a ruling. It is FLIGHT’s to make by refusing this document, and the route works without L3. It is not the recommendation, because D3 is ratified and the engine and its eval exist.

For code: none from this document. Build acts, in order:

  • L2 band PR. One petrova.context call. Tests for render, for failure isolation (each direction), and for absence (no field means UNREAD with a reason, never a stale value). The module-graph test is extended to allow exactly two RPC method names.
  • Verifier port PR (host). Parity tests against eva-hq fixtures at the pinned sha.
  • Generation job PR, in whichever repository term 5 lands in. It needs the credential and the cost ceiling to exist first.
  • GENERATED band PR (dashboard). Tests for states (a)–(e), the label, provenance, the ceiling of five, ordering below every computed band, and anchors for citations.

For docs: dashboard/PRODUCT.md lists the two bands when the render lands. If (b) is chosen, the IR-017 record of ANTHROPIC_API_KEY as “used only by irina-cycle.yml” is superseded by a dated note, not edited (MR-7).

For in-flight phases: P6-L2 and P6-L3 may proceed once this is closed. mary-wiki’s L2 and projection-drift analyzers are still unbuilt. When they land, eva-hq’s two synthetic fixtures (fleet-context, projection-drift) are regenerated from the real shape, as eva-hq #109 records.

For invariants: none added, modified or repealed. No blocking check is admitted. Nothing fails CI on a statement, the verifier or the eval (D3, “What this decision does NOT do”).

For downstream consumers (D6):

  • eva.consumption.v1 is unchanged and needs no bump. That profile (contracts/vendor/eva-consumption.v1.json) is a consumer repo’s declaration block: surfaces.{events,control,prompts}, where a prompts surface carries manifest and eva_sha, plus evidence_consumer. It has no field for a prompt’s output schema. eva-hq #109 already found that the prompt itself needs no D6.

  • The render consumes mary.governance-diagnose.v1, the prompt’s output. The build pins it as mary-governance-diagnose@<sha> and validates it in the host parser against that sha’s output_contract. That pin is local to this render, not part of the profile.

  • What does change is a declaration in the existing v1 vocabulary. It depends on where generation runs:

    • Under (b), petrova-codes invokes an eva prompt. Its own .petrova/contract.yaml eva: status: not_applicable (“consumes neither rocky nor eva surfaces”) becomes false. The generation-job PR updates that block, for example to a prompts surface with manifest and eva_sha, and reconciles petrova-codes’ contract_sha in the registry.
    • Under (a), the declaration that changes is mary-wiki’s own eva block (currently status: pending), under mary-wiki’s rules.

    Neither case changes the profile’s schema.

  1. Where generation runs: (a) the mary-wiki snapshot workflow, or (b) a petrova-codes job. The drafting agent recommends (b).

  2. Who holds the Anthropic API key, and which one.

    • Under (a): a new mary-wiki/mary repo secret, held by the mary-wiki org.
    • Under (b): petrova-codes either reuses its existing ANTHROPIC_API_KEY (IRINA’s key, recorded by IR-017 as single-use) or holds a new, separate key. The drafting agent recommends a separate key.

    Only FLIGHT can provision either. IR-017’s recommendation to confirm an account-level spend limit in the Anthropic console is still unconfirmed from this repository.

  3. Cost ceiling: a USD ceiling per run and per month. Term 6 refuses to call the model until the per-run ceiling is set.

  4. The L2 read: confirm that the route may make a second read-only RPC call (term 1, widening route term 4 by one named read). The alternative is to require L2 to arrive inside a snapshot.

  5. Model id: the prompt pins claude-opus-4-8 (meta.yml). Decide whether the job may run any other model. A model change produces a different model_id in provenance and needs the eval re-run (term 7).

Section titled “Recommended rulings (drafting agent, 2026-10-09; not rulings until FLIGHT signs)”

These are recommendations only. FLIGHT rules by ticking the Sign-off box in a commit FLIGHT authors, naming the ruling for each of 1–5. Anything left unnamed there stays open, and this document stays open.

  1. (b), a petrova-codes job. mary-wiki is profile: strict and human-merge, and its snapshot workflow states “Nothing here holds or needs a secret”. (b) keeps it that way. It also lets the job freeze L2 from petrova’s own state into the generation input, which (a) could only do by putting a petrova bearer into mary-wiki CI.
  2. A new, separate key, held by petrova-codes as its own repo secret (suggested name MARY_DIAGNOSE_ANTHROPIC_API_KEY), created in its own Anthropic workspace. Reusing IRINA’s key would falsify IR-017’s “used only by irina-cycle.yml” and pool two spends that should be attributable and revocable apart. A dedicated workspace is also where the monthly limit in 3 is enforced.
  3. $1.00 per run; $40 per month.
    • Size, measured 2026-10-09: the live snapshot (run 37828949461) is 95,151 bytes of JSON and the prompt body 8,729 bytes, about 35–45k input tokens. At claude-opus-4-8 rates ($5 / $25 per million input / output tokens) that is about $0.20 of input. Output is at most five one-line statements plus thinking, so an estimated $0.10–0.40. Expected cost is about $0.30–0.60 a run. The build PR’s first-run token counts (term 6) replace this estimate.
    • Per run: $1.00 gives roughly 2× headroom over the estimate and sits under IRINA’s IRINA_CYCLE_COST_CEILING_USD: "2.00". Set as a repo variable read by the job (term 6).
    • Per month: four snapshot runs a day is about 120 runs a month, or $36–72 at the estimate. $40 is a deliberate cap at the low end. If it binds, the job stores state (e) for the rest of the month, which the band states in words. Term 6 is per-run only, so the monthly cap is a spend limit on the dedicated workspace from 2, set in the Anthropic console, not a job check.
  4. Admit the second read. The draft’s term 1 is the cheaper shape: one named, read-only petrova.context call, with failure isolated in both directions and the module-graph test pinned to exactly two method names. Folding L2 into the snapshot instead would need a petrova bearer in mary-wiki CI, which is the cost 1 avoids.
  5. Keep claude-opus-4-8 for the first render. It is the model the 12/12 eval passed on (eva-hq #109, a7a4e96), and it is current, not deprecated. A later move, for example to claude-opus-5-5 at $4 / $20, needs no new decision. It needs only the term 7 conditions: the prompt’s meta.yml pin changes in an eva-hq PR, bin/eva eval passes at the new sha, and the build re-pins.
  • docs/decisions/2026-10-07-mary-governance-console-route.md (route terms 1–6; closed; term 1 “R-2 and nothing else”, term 4 “one read-only host RPC method”)
  • docs/decisions/2026-10-07-console-voice-modality-governance-route.md (closed; the palette’s intents perform no new host read)
  • docs/decisions/2026-09-15-ir-017-irina-secret-scope-and-retention.md (ANTHROPIC_API_KEY scope; account-level spend limit unconfirmed)
  • docs/decisions/2026-05-08-adopt-eva-consumption-v1.md, docs/decisions/2026-09-22-eva-consumption-v1-schema-widen.md (eva.consumption.v1)
  • mary-wiki:docs/decisions/2026-10-07-inferred-statements-on-governance-surface-proposed.md (D3, ratified 2026-10-08; R-1–R-8; label GENERATED)
  • mary-wiki:docs/decisions/2026-10-03-governance-read-surface-siting-proposed.md (ratified 17d26e7; R-2, R-4, R-6)
  • mary-wiki:.github/workflows/governance-snapshot.yml (artifact, schedule, “Nothing here holds or needs a secret”)
  • eva-hq:prompts/mary-governance-diagnose/ (verify.sh, meta.yml, eval.yml; merged in eva-hq #109, a7a4e96)
  • eva-hq:docs/reports/2026-10-03-mary-governance-surface-phases.md (P6 L2/L3, decisions table D6)
  • host/src/sources/mary-governance.ts (snapshot read, MARY_SNAPSHOT_READ_TOKEN)
  • host/src/registry.ts (petrova.context tool)
  • dashboard/src/pages/console/repo/mary-wiki/governance.astro, governance.test.ts:344 (the one read; module-graph guard)
  • .github/workflows/irina-cycle.yml (ANTHROPIC_API_KEY, skip-when-unset, IRINA_CYCLE_COST_CEILING_USD)
  • .petrova/contract.yaml (eva: not_applicable)
  • contracts/vendor/eva-consumption.v1.json
  • Subagent: Claude Opus 5.5, 2026-10-08 (drafted; read at petrova db36a194, mary-wiki 9ccc2be, eva-hq e7b1134)
  • Human: flight@arno.host, 2026-10-09 — admits the L2 fleet-context and GENERATED bands on terms 1–7, and rules the open questions as recommended: 1 (b) petrova-codes job; 2 new separate key MARY_DIAGNOSE_ANTHROPIC_API_KEY in its own workspace; 3 $1.00 per run, $40 per month; 4 second read admitted; 5 claude-opus-4-8 for first render, later moves per term 7.

Countersigned by human:flight@arno.host on 2026-10-09 — box ticked in commit c1fd547e (petrova #547), authored by the human, squashed into 955e7861 on main. Open questions 1–5 ruled as the recommended rulings state: (b) a petrova-codes job; a new, separate key MARY_DIAGNOSE_ANTHROPIC_API_KEY in its own Anthropic workspace; $1.00 per run and $40 per month; the second read admitted; claude-opus-4-8 for the first render. Status flipped open→closed on 2026-10-09 by an agent as scribe (MR-7).