Skip to content

feat(formal): compose the policy profile from the kernel library - #185

Open
lan17 wants to merge 5 commits into
claude/kernel-slice9afrom
claude/kernel-slice9b
Open

lan17 wants to merge 5 commits into
claude/kernel-slice9afrom
claude/kernel-slice9b

Conversation

@lan17

@lan17 lan17 commented Sep 16, 2026

Copy link
Copy Markdown
Owner

Summary

Step 5 of #165, slice 9B: the policy conformance profile is composed from the kernel library over the layered shape. Stacked on #184 (the seam); the base moves to main when #184 merges. The corpus differential replays the hand-written model's corpus through the composed one and back: 541 of 541 histories agree in both directions.

What changes in the library

  • policy_overlay (new): the drivers' 26 overlay codes resolved against a fixture's baseline Ttls: the TTLs the reply carries and whether it coalesces (codes 10 to 19 repeat 0 to 9 with coalescing disabled); the reply's layer set is the shape's (remote only when Redis is available) and the traversal's gated turns a layer off when the reply's TTL for it is 0, the same rule runtime_policy states for runtime TTLs; a failed reply (provider fault or invalid read budget) resolves to the bypass.
  • config_errors (new): the policyErrors channel as an opt-in record; a wrapper records one config_resolution error against no layer for the release whose reply failed.
  • receipts (new): one record of the latest release, which caller it served, for which key, from which layer (local hit, remote hit, a started source, or none), and the local slot the release saw (value and insertion expiry), judged from the same layeredRelease judgment the traversal consumed; Receipts::release is the receipted variant of the layered release, as diagnostics wraps the request-only one. It exists because the two read invariants (a local hit respects the entry's insertion expiry, a remote hit respects the acquired freshness) cannot be restated from the post-state alone: a remote hit warms the very slot the local property would read.
  • serving.layeredRelease: the layered release decision (caller, call, effective resolution, decision) stated once, as requestRelease is for the request-only shape; release consumes it and receipts reads it.

The policy profile

formal/dialcache-policy-conformance.qnt (670 -> 612 lines) assigns state only through Serving::admit, Serving::release wrapped in Receipts::record and ConfigErrors::recordConfigError, Serving::settle, Clock::advance, Clock::shiftWall, Remote::seedFrame and record updates of the overlay and the four fault switches. Its 29 regressions are verbatim in inputs and expectations, with the private expectations translated to the composed fields, and a thirtieth pins that a remote hit warms local for the reply's local TTL rather than its freshness. Eleven invariants: the two read invariants are one-step in both directions over the receipt (a local hit happened only with the local layer on, with no pending shared flight to join, over a live entry holding the caller's value, and left its insertion expiry unchanged; any other outcome with the local layer on found no live entry; a remote hit happened only with no flight to join, over a retained fresh frame, and a miss found none), a third pins that a remote hit warms local for the reply's local TTL, a fourth that a join happens only when a registered shared flight was joinable; seven are restated over library records (the gate, the process registry, the source list); eachFailedPolicyReplyHasOneDiagnostic is dropped with named carriers (the regression providerFailureReportsStablePolicyCategoryTest and the drivers' compared policyErrors channel). Deleted: the hand-written traversal and settlement, the two receipt lists, the reply list, and the private slot and frame fields.

Evidence

  • node formal/differential.mjs --composed --reference=<the #184 head>: policy forward 541 of 541 and reverse 542 of 542 (512 sampled, 29 regressions, the new one candidate-only), bytes per state 3405 -> 2533 (x0.74); layers, runtime-boundaries, scope and source-budgets agree both ways at x1.00.
  • Challenges: policy-inclusive-local-expiry re-anchored on local_storage.localValue and policy-inclusive-remote-freshness on remote_frames.fresh, both with reproducers that partition every profile (the freshness one gains an exported-regression reproducer and leaves the backlog); two new challenges on serving.decide: policy-hit-before-join (C13, the join-first order; observable in policy, runtime-boundaries and layers, each carried by an exported regression, two of them new: a coalescing caller joins the pending flight before reading a seeded frame in layers, and a default-sharing reply joins the registered leader over a warmed local entry in runtime-boundaries) and policy-join-ignores-coalesce (C13, the coalesce conjunct of the process join, reproducer independentCompletionKeepsRegisteredLeaderTest); all detected, as is stale-recovery-future-candidate. Regressions 415 scheduled, 248 exported.
  • Composition lint: policy 47 violations -> 0 with 13 library transitions. quint test 30 of 30; the nine invariants clean at 2000 x 40 under the manifest seed; kernel fixtures 47 of 47; make audit, typecheck and the vitest pins green.
  • Witnesses: the public-only policy classifier (test(formal): read the policy witnesses from inputs and public observations only #183) is untouched; its fidelity check is re-encoded to the composed layout (clocks as now and skew, the held caller, per-key local slots and frames, the process registry, and each source's captured TTLs) and ran on every one of the 541 candidate histories without a mismatch; every label count is identical to the recorded baseline, whose corpus fingerprint is the only baseline change.
  • Ledgers: quint-case-audit rows re-cite the kernel definitions; go-parity mirrors them; the fixture projection for the policy smoke follows the composed fields (the smoke artifact regenerates); formal/README.md names the fifth composed profile (ledger refreshed).

Review

A report-mode review-loop round (seven lanes plus holistic) on the first version found the local read invariant weaker than the one it replaced: it could not see a remote hit served over a live local entry, so a traversal reading remote before local passed every invariant where the old model caught it in under a second. The fix commit gives the receipt the local slot the release saw and states the property in both directions; the reviewers' traversal-order and renew-on-hit mutants now fail. Also from that round: the receipted release is one library variant instead of the profile spelling the same five arguments twice; the receipt's caller is read instead of derived from the newest admission, and a started source has its own code; the invalid-read-budget diagnostic is pinned by a regression after its invariant was dropped; the asymmetric-TTL regression above; the fidelity check compares the receipt; the overlay decoder no longer restates the TTL gate the traversal owns. A second round found two more directions the old biconditional receipts had covered: a local hit was not required to happen with the local layer on, and neither hit clause forbade serving a layer past a pending shared flight for the same key (a traversal joining after reading layers passed every invariant). Both are stated now, and the hit-before-join fault is ledgered as a challenge. Also from that round: the overlay decoder reads the fixture's configured layers and remote availability instead of a literal; the release judgment carries only what the traversal consumes and the receipt reads the pre-release slot from the same state; the alias block and the string-dispatch fault setter are gone; the fidelity check compares the receipt and the owners; a third invariant pins the remote-hit warming TTL. A third round returned only low items, landed as the last commit: the join direction of the old receipts stated as an invariant with its own challenge; the hit-before-join partition corrected and carried by exported regressions instead of a scratch probe; the overlay decoder returning the shape's layer set so the traversal's TTL gate is the one statement of layer participation (as for runtime TTLs); doc residue and a stale exclusion reason fixed; fidelity probes for the receipt and the owners.

The policy conformance profile is the fifth composed profile: held
replies over the layered shape, with three new kernel modules.
policy_overlay decodes the drivers' 26 overlay codes and the provider
fault against the fixture's baseline TTLs into a Resolution and the Ttls
the reply carries (the layers a reply enables follow from its TTLs,
stated once). config_errors is the policyErrors channel as an opt-in
record composed around the release whose reply failed. receipts records
the caller, key and layer of the latest release from the release judged
once: serving gains layeredRelease, which release itself now consumes,
mirroring requestRelease.

The two read invariants are one-step over the receipt and the storage
the caller read (the frames and clocks do not move during a release),
in both the hit and the miss direction; the post-state alone cannot tell
a local hit from a remote hit that warmed local storage, which is why
the receipt exists. eachFailedPolicyReplyHasOneDiagnostic is dropped:
its one-step form needs a pre-state count, and a counter in the record
would be incremented by the same definition as the error; the regression
providerFailureReportsStablePolicyCategoryTest and the drivers' policy
error channel carry it. The other seven invariants are restated over the
library records; the 29 regressions keep their inputs and expectations,
with private-field expectations translated to the composed layout.

The two policy challenges re-anchor on local_storage::localValue and
remote_frames::fresh as shared-library faults, each with a reproducer
that partitions every profile; the remote-freshness one leaves the
backlog. Ledgers re-cite the moved rules against the kernel definitions;
the fixture projection, the policy smoke artifact and the shadow-walk
fixture take the composed layout; the witness classifier's fidelity view
maps the public-only shadow onto it (per-source localMs and retentionMs
from the source record, remote from the refill flag) and the classifiers
are unchanged, every label count identical.

Corpus differential against claude/kernel-slice9a (5154bbc, where policy
is still hand-written): policy 541/541 both directions at x0.744 bytes
per state; layers 527/527, runtime-boundaries 282/282, scope 270/270 and
source-budgets 264/264 agree at x1.000. Lint 0 violations (was 47).
The local read property had lost its remote-hit direction: a remote hit
warms the slot the miss arm read, so a release over a live local entry
that served from the remote layer went unconstrained, and a traversal
that read the remote layer before local passed every invariant. The
layered release judgment now carries the local slot it found for the
call's identity, the receipt copies it, and the property is stated for
every non-join release: a local hit found the entry live with the
caller's value and left its insertion expiry alone; any other release
that reached the layers with the local layer on found no live entry.
The remote-before-local and renew-on-hit mutants now violate within a
tenth of a second.

receipts::release is the receipted variant of the layered release, judged
once beside the transition on the same pre-release state, so the wrapper
names the reply once; the receipt records the caller, that a source
started or a flight was joined, and the properties read it instead of
deriving the caller from the call count and the start from the owners.
policy_overlay::resolve returns the fixture's configured layer set and
coalescing; gating by TTL is layer_policy::gated's at release.

invalidReadBudgetBypassesAllCachingTest pins one config_resolution error
per failed reply for the invalid read budget, the half the dropped
invariant covered that no run pinned. remoteHitWarmsLocalForTheReplysLocalTtlTest
pins that a remote hit warms local storage for the reply's local TTL,
not the frame's freshness, with asymmetric TTLs; it is exported, cited
under C09.insertion-age and replays through the TypeScript driver. The
fidelity check binds the receipt; the policy projection drops the
constant watermark. The local-expiry reproducer keeps source-budgets
among the observing profiles: its expiry-boundary regression fails under
the mutant.

Corpus differential against claude/kernel-slice9a: policy 541/541
forward and 542/542 reverse at x0.762 bytes per state; layers,
runtime-boundaries, scope and source-budgets agree at x1.000.
@lan17
lan17 force-pushed the claude/kernel-slice9b branch from d12491c to aa06651 Compare September 16, 2026 17:16
A local hit is now stated as one served with the local layer on: a
reply whose local TTL is 0 cannot hit local storage, and a gate that
ignored the local TTL passed every invariant before. Both hit clauses
require that no flight was there to join: a coalescing reply with a
shared layer on joins the pending flight registered for its key before
any layer is read, so a hit under such a reply is a fault. The order is
ledgered as a policy challenge on the traversal's decision (the process
join moved below the layer tests), measured through the remote clause,
which reaches the state in a few steps through a seeded frame, and
pinned by independentCompletionKeepsRegisteredLeaderTest; the fault is
also observable in runtime-boundaries, where a source started under
disabled sharing warms local storage beside a registered leader.

policy_overlay::resolve reads the fixture: a baseline TTL configures a
layer and the remote layer also needs remote storage, as
runtime_policy::resolve does. The layered release judgment carries only
what release consumes; the receipted variant reads the pre-release local
slot from the state it judges. The profile imports policy_overlay
unqualified and spells the codes with the library's names; the string
dispatcher over the fault switches is gone and the regressions call the
switch they set. The fidelity view binds each caller's owner. A new
one-step invariant pins that a remote hit warms local storage with the
served value for the reply's local TTL.

Corpus differential against claude/kernel-slice9a: policy 541/541
forward and 542/542 reverse at x0.744 bytes per state; layers,
runtime-boundaries, scope and source-budgets agree at x1.000.
The join direction is now a property: a caller joins only a flight it
could join, so a decision that ignored whether the reply coalesces fails
an invariant rather than only a regression. The fault is ledgered beside
the hit-before-join one, anchored on the coalesce conjunct of the
process join, and pinned by an expect placed right after the independent
release in independentCompletionKeepsRegisteredLeaderTest, where the
mutant joins instead of starting.

The decide-order challenges partition the profiles on carried evidence:
a layers regression seeds a frame while a flight is pending and expects
the coalescing caller to join before reading it, and a runtime-boundaries
regression starts a source under disabled sharing beside the registered
leader, lets it warm local storage, and expects the default reply to
join the leader rather than hit the entry. Both are exported and replay
through the TypeScript driver; both fail at their expects under the
mutants they carry.

policy_overlay::resolve returns the shape's layer set with remote
availability folded in and lets the traversal gate each layer on the
reply's TTL, runtime_policy's semantics for the same behavior; the
unused baseline parameter is gone. The composition example and the
scope challenge's policy exclusion say what the profile does now, and
the fidelity tests pin that a corrupted receipt or owner entry is
refused.

Corpus differential against claude/kernel-slice9a: policy 541/541
forward and 542/542 reverse at x0.744 bytes per state; layers 527/528,
runtime-boundaries 282/283 (each with its new candidate-only
regression), scope 270/270 and source-budgets 264/264 agree at x1.000.
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.

1 participant