Skip to content

authority(0.7.1g1P2-Step3b): wire the canonical certificate ledger to the real transport - #474

Merged
GionaGranchelli merged 1 commit into
epic/0.7.1-control-plane-authorityfrom
task/0.7.1g1P2-3b-certificate-transport
Oct 2, 2026
Merged

GionaGranchelli merged 1 commit into
epic/0.7.1-control-plane-authorityfrom
task/0.7.1g1P2-3b-certificate-transport

Conversation

@GionaGranchelli

Copy link
Copy Markdown
Owner

Base: d192e2e (post-#473 epic tip; branch parent verified).

Step 3a proved the consumption semantics on fixtures. This proves the transport: the real committed certificate ledger and the real committed admission ledger, loaded through the real loaders from the repository root, fed to the real consumption verifier. This is the load path P1M reported as unwired.

Six discriminators against committed authority, not fixtures:

  • the canonical ledger loads through the real loader and holds exactly one certificate;
  • its admissionSetDigest equals the digest of the real committed identities (adding or removing an admission from the real ledger changes this outcome);
  • its fromDigest equals the single populationDigest the real committed admissions are bound to - M41's real binding;
  • real base authority produces a Valid consumption end to end;
  • a certificate absent from the real base ledger is refused by M43;
  • a certificate whose target digest was not this transition's measurement is refused by M40.

The negative cases are as load-bearing as the positive one: they show the verifier is fed real base authority and real measured data, rather than values arranged to agree with the certificate.

Verification: 39 tests / 0 failures (transport 6, consumption 13, loader 12, ceremony 8); spotless clean; Detekt baseline 4792 -> 4792 with 0 added; verifyChangePolicy PASSED, 1 changed file, class build-logic.

Not in this PR: certificate-aware M34, and the T1-T19 matrix at verifier and real-task level. No production code changed. Not merged by the agent.

… the real transport

Step 3a proved the consumption semantics on fixtures. This proves the transport: the real
committed certificate ledger and the real committed admission ledger, loaded through the real
loaders from the repository root, fed to the real consumption verifier.

This closes the load path P1M reported as unwired - until now nothing loaded
config/quality/mutation-authority-digest-certificates.yml from the repository root, so the
ledger's own load was only ever exercised against fixtures.

Six discriminators, all against committed authority rather than fixtures:

- the canonical ledger loads through the real loader and holds exactly one certificate;
- that certificate's admissionSetDigest equals the digest of the real committed identities,
  so adding or removing an admission from the real ledger changes this outcome;
- its fromDigest equals the single populationDigest the real committed admissions are bound
  to, which is M41's real binding rather than a fixture's;
- real base authority produces a Valid consumption, so the positive fact is reachable from
  the committed ledgers end to end;
- a certificate absent from the real base ledger is refused by M43, and one whose target
  digest was not this transition's measurement is refused by M40.

The negative cases matter as much as the positive one: they show the verifier is fed real
base authority and real measured data, not values arranged to agree with the certificate.

No production code changed. The remaining Step 3b work is certificate-aware M34 and the
T1-T19 matrix at both levels.

Verification: 39 tests / 0 failures (transport 6, consumption 13, loader 12, ceremony 8);
spotless clean; Detekt baseline 4792 -> 4792 with 0 added; verifyChangePolicy PASSED.
Copilot AI balanced review requested due to automatic review settings October 2, 2026 06:43

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

The change is correct and low-risk on its own, but it touches the authority/governance machinery where final transport-vs-task guarantees warrant a human sign-off.

Review effort: Balanced
Findings: None

What changed in this PR

This PR adds a single test file, CertificateLedgerTransportTest.kt, that proves the authority-transport half of certificate consumption (Step 3b). Where the earlier Step 3a PR (#473) proved consumption semantics against fixtures, this PR feeds the real committed certificate ledger and admission ledger — loaded through the real loaders from the repository root — into the real verifyCertificateConsumption verifier. It fits into the build-logic mutation-authority governance machinery, satisfying the AGENTS.md requirement that authority rules be proven at both the verifier level and against real committed state. No production code changes.

Changes:

  • Adds six transport-level discriminators: the canonical ledger loads with exactly one certificate; its admissionSetDigest matches the real admissions' digest; its fromDigest matches the single populationDigest the real admissions are bound to; a valid end-to-end consumption; an M43 refusal for a certificate absent from the base ledger; and an M40 refusal for a target digest this transition did not measure.
  • Reuses the established gradlew-marker walk-up idiom to locate the repository root, consistent with the Step‑2 loader test.
File Description
build-logic/​src/​test/​kotlin/​dev/​tramai/​build/​quality/​CertificateLedgerTransportTest.kt New real-ledger transport test wiring the committed certificate/admission ledgers through the real loaders into the consumption verifier, with positive and negative (M43/M40) discriminators.

I verified that every referenced API is used correctly (verifyCertificateConsumption, both loaders, the MutationAuthorityDigestCertificate constructor, admissionSetDigest, and the CertificateConsumption.Valid/Invalid + diagnostic.message surface), that the committed ledger exists with exactly one raw-v1 → authority-v2 certificate, and that each test's control flow reaches the asserted rule code (M43 fires before M40 via the verifier's refusal order; M40 fires on the overridden fresh projection). The repositoryRoot() idiom matches the existing loader test, and the assertions are exact (sizes, digests, rule codes) in line with the repository's test-rigor standard. I found no objective issues to raise.


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@GionaGranchelli
GionaGranchelli merged commit a2c6c3a into epic/0.7.1-control-plane-authority Oct 2, 2026
19 checks passed
GionaGranchelli added a commit that referenced this pull request Oct 2, 2026
…the instance

Review finding: there was one fact-production function but three fact-production events.
MutationRatchetVerifier recomputed base.admissionAuthority(...) for the outcome-ratchet context and
again for the certificate ceremony, and MutationPopulationAdmissionCeremony recomputed it once more
inside its own consumption loop for the appearing-identity verdicts. The three results were
value-equal, which is not the property the contract asks for: deterministic recomputation is not
shared evidence, and value equality lets a later change drift one consumer away from the others
without any test noticing.

Now:

  val admissionAuthority = base.admissionAuthority(freshAuthorityProjectionHash)   // once

and that exact instance is threaded to every consumer - the evolution context (M34 and the
appearing-identity path), the admission lifecycle ceremony, and the certificate ceremony (M44/M47)
via .certifiedConsumptions.

- MutationPopulationAdmissionCeremony.checks/lifecycleChecks/consumptionChecks now take the
  AdmissionAuthority instead of the raw projection hash and pass it through unchanged; the internal
  recomputation at the consumption loop is gone. Public signature change: checks() has exactly one
  caller, the verifier.
- The AdmissionAuthority KDoc states the invariant: produced once, never re-derived.
- CertificateCustodyTransportTest pins it with a source-level wiring assertion, the form the review
  sanctioned where a runtime === check would require exposing internals: exactly one
  admissionAuthority( production call in the verifier, zero in the ceremony, and the certificate
  ceremony consuming the shared local.

Rebased onto the post-#474 epic tip a2c6c3a; diff scope verified as exactly 9 files, and #474's
merged CertificateLedgerTransportTest.kt is present at the tip and absent from this diff.

Verification: 172 tests / 0 failures (certificate, admission and ratchet suites); spotless clean;
Detekt baseline 4792 -> 4792 with 0 added; verifyChangePolicy PASSED against base a2c6c3a, class
build-logic.
GionaGranchelli added a commit that referenced this pull request Oct 2, 2026
…epts certified migration + M44/M47 on the same facts (#475)

* authority(0.7.1g1P2-Step3b): read the certificate ledger at the base revision

M43/M47 are judged against the certificate ledger as it exists in the BASE, but the only loader
read the working tree. So the base side had no way to see a certificate at all, and M34 had no
facts it could ever consult. This closes that gap.

The base-side read now goes through the same path the population, classifications, enrollments
and admissions already use: git show "<baseSha>:<path>" into the temp tree, then the ledger's
own loader. One authority snapshot (MutationRatchetAuthority) therefore carries the whole base
context - population, classifications, enrollments, admissions and now certificates - which is
what one coherent transition context means.

Absent at base is handled like the other optional ledgers: a base that predates the certificate
ledger has none, which is the most restrictive state, since no certified migration exists and
every raw-v1 admission still fails M34. A present ledger is validated by its own loader, so a
malformed one fails hard rather than degrading into "no certificates".

Two discriminators, both against real immutable history rather than fixtures:

- at 9ebe7b4 (the P1M merge that minted the certificate) the authority snapshot exposes
  exactly one certificate, and its fromDigest is the single populationDigest the base's own
  admissions are bound to;
- at 64d0545 (the base P1M was proposed against, which predates the ledger) the snapshot
  exposes no certificates, while the same snapshot's admissions are non-empty - so the test
  isolates the certificate ledger instead of showing that some empty snapshot is empty.

The default on MutationRatchetAuthority.certificates is the conservative NONE for fixtures; the
loader always passes it explicitly from the base revision.

Verification: 40 tests / 0 failures (base-revision transport 2, ratchet authority, population
admission suites); spotless clean; Detekt baseline 4792 -> 4792 with 0 added; verifyChangePolicy
PASSED, 2 changed files, class build-logic.

Next: M34 consults these facts at the verifier's decision points, then the T1-T19 matrix.

* authority(0.7.1g1P2-Step3b): M34 accepts certified digest migration

Completes the certified-migration path: the base snapshot now carries the certificate ledger, and
M34 consumes the facts it proves.

- MutationRatchetAuthority gains the base-revision certificate read, using the same git-show-into-
  temp-tree path as the population, classifications, enrollments and admissions. Absent at base is
  the most restrictive state, as for the other optional ledgers.
- appearanceVerdict's M34 branch rejects a raw-v1 admission only when no certified consumption
  covers that admission's own historical digest. The facts come from one production site,
  certifiedConsumptions(...), which runs the real verification for each distinct historical digest
  against the base ledger and the exact base authorization set. A Valid exists only if M43-M42
  passed, so the branch cannot be reached by asserting anything.
- AdmissionAuthority carries the fresh projection plus the consumptions it certifies as one value.
  That is what makes the two judgment paths - the lifecycle scan and the appearing-identity path -
  receive the same object. Feeding one without the other would have made P2's diagnostics
  contradict themselves for the same 67 rows: admitted in the scan, M34-rejected in the appearing
  path. It also keeps both signatures inside the parameter budget without suppressing anything.

Without a certificate the M34 condition is exactly as before, and AdmissionAuthority(null) is the
fail-closed default everywhere. M36/M37 are untouched.

Verification: 158 tests / 0 failures, including the new discriminators - certifiedConsumptions
yields one fact from a real base certificate and none for an uncertified projection or no
certificate; M34 accepts the certified raw-v1 admission and still fails the uncertified one. Plus
the base-revision cases: the certificate is present at 9ebe7b4 (the P1M merge) and absent at
64d0545 (P1M's base) while that base's admissions remain non-empty.

spotless clean; Detekt baseline 4792 -> 4792 with 0 added; verifyChangePolicy PASSED, 6 changed
files, class build-logic. Four genuine Detekt findings fixed by hand - the two LongParameterList
ones by introducing the carrier, not by suppressing them.

Next: M44/M47 consume the same fact set, and the T1-T19 matrix at both levels.

* authority(0.7.1g1P2-Step3b): M44/M47 consume the same Valid facts

Last row of the Step 3b path: the certificate lifecycle is now driven by the facts M34 already
uses, produced at one site.

- MutationRatchetCandidate gains the transition's own certificate ledger, loaded from the
  repository like the candidate admissions. It is validated (M45 mint binding, M46 retained
  immutability) but can never authorize a consumption: only the base ledger is consulted, so a
  candidate that both mints and consumes fails M43.
- The verifier now calls MutationAuthorityDigestCertificateCeremony.checks with the base and
  candidate certificate ledgers and validConsumptions taken from
  base.admissionAuthority(...).certifiedConsumptions - the same object M34 decides on, so M44
  (single use) and M47 (removal custody) cannot disagree with the admission verdicts about what
  was consumed.
- M47's consuming half is now exercised end to end: a certificate may disappear only because a
  consumption was independently proven in the same transition, never because it was absent.

Two existing test fixtures were corrected rather than the rules relaxed:

- MutationRatchetAuthorityTest's identity-transition candidate now retains the base's
  certificate, exactly as it retains the base's admissions. Passing NONE asserted a transition
  that removes the certificate with no proven consumption, which M47 rightly refuses. This is
  the same class of fixture defect (and the same fix) as the admissions case in Step 1.
- CertificateCustodyTransportTest drives the real committed ledger through the real ceremony:
  unchanged, it survives; dropped without a proven consumption, M47 fails; dropped with the
  facts produced from the real ledgers, removal is permitted.

M47 firing on that fixture is the evidence that the consuming half is genuinely live, rather
than a branch nobody reaches.

Verification: 162 tests / 0 failures across the certificate, admission and ratchet suites;
spotless clean; Detekt baseline 4792 -> 4792 with 0 added; verifyChangePolicy PASSED, class
build-logic. A full :build-logic:test run reached 855 tests with zero genuine test failures
before the console call was truncated (its only entry was an infrastructure pseudo-failure from
the kill itself); CI runs the complete suite.

Remaining: the T1-T19 matrix at verifier and real-task level.

* authority(0.7.1g1P2-Step3b): T14/T17/T18 at the transport level, over the real ledger

Audited the discriminator matrix against the rules that actually have tests: every rule M01-M47 is
exercised somewhere, but three certificate-lifecycle attacks had only rule-level coverage, not the
real-task transport coverage the design requires. All three now run against the committed
certificate ledger loaded through the real loader.

- T18: a retained certificate whose enforced payload was rewritten (here its reason, which is in
  the payload) fails M46. The rewrite is derived from the real certificate's own fields, so the
  test cannot pass by accident of a fixture mismatch.
- T17: a certificate introduced with a fromBaseSha other than the transition's base fails M45, even
  alongside the legitimate retained certificate.
- T14: a certificate absent from the real base ledger cannot be consumed, however it is cited - the
  verifier refuses it as M43 rather than accepting the citation.

Together with the earlier cases this gives the certificate lifecycle transport coverage for
introduction (M45), retention (M46), consumption (M40-M43), single use (M44) and removal custody
(M47), all against the real committed ledger.

Verification: 165 tests / 0 failures; spotless clean; Detekt baseline 4792 -> 4792 with 0 added;
verifyChangePolicy PASSED, 9 changed files, class build-logic.

* authority(0.7.1g1P2-Step3b): produce the authority facts once, share the instance

Review finding: there was one fact-production function but three fact-production events.
MutationRatchetVerifier recomputed base.admissionAuthority(...) for the outcome-ratchet context and
again for the certificate ceremony, and MutationPopulationAdmissionCeremony recomputed it once more
inside its own consumption loop for the appearing-identity verdicts. The three results were
value-equal, which is not the property the contract asks for: deterministic recomputation is not
shared evidence, and value equality lets a later change drift one consumer away from the others
without any test noticing.

Now:

  val admissionAuthority = base.admissionAuthority(freshAuthorityProjectionHash)   // once

and that exact instance is threaded to every consumer - the evolution context (M34 and the
appearing-identity path), the admission lifecycle ceremony, and the certificate ceremony (M44/M47)
via .certifiedConsumptions.

- MutationPopulationAdmissionCeremony.checks/lifecycleChecks/consumptionChecks now take the
  AdmissionAuthority instead of the raw projection hash and pass it through unchanged; the internal
  recomputation at the consumption loop is gone. Public signature change: checks() has exactly one
  caller, the verifier.
- The AdmissionAuthority KDoc states the invariant: produced once, never re-derived.
- CertificateCustodyTransportTest pins it with a source-level wiring assertion, the form the review
  sanctioned where a runtime === check would require exposing internals: exactly one
  admissionAuthority( production call in the verifier, zero in the ceremony, and the certificate
  ceremony consuming the shared local.

Rebased onto the post-#474 epic tip a2c6c3a; diff scope verified as exactly 9 files, and #474's
merged CertificateLedgerTransportTest.kt is present at the tip and absent from this diff.

Verification: 172 tests / 0 failures (certificate, admission and ratchet suites); spotless clean;
Detekt baseline 4792 -> 4792 with 0 added; verifyChangePolicy PASSED against base a2c6c3a, class
build-logic.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants