51 KiB
Governed Weight-Adjustment Layer (toy) — Phase 0: research and design
Date: 2026-09-17
Author: Claude Code (executor) — Claude Fable 5.1
Tag: [PROPOSAL] — the executor's own characterization of its own work; re-taggable by steward or jurist.
Status: Returned for steward and jurist review under §5 of the brief. No PENDING id assigned; nothing appended to PENDING.md. A completed design is not authorization to build. Nothing was built. Two one-shot checks were run (a register search and an arithmetic check); both are reported in §11 with their controls.
Scope boundary: Standalone sandbox. No code, data, credentials or substrate of CapableMind, L1 or the Chamber is used or touched. One observation about an existing CapableMind spec is recorded in §9 — as an observation, not a proposal.
Self-contained: written to be ruled on without repository access.
Claim marks used throughout
| Mark | Meaning |
|---|---|
| [V] | Verified this session against a source; the source is named in §11 |
| [R] | Recalled from training; not checked this session |
| [P] | Prediction about what a build would show; each carries its falsifier |
| [J] | Judgment. Standpoint, disclosed once: I am the party who would build this; my bias runs toward composing more mechanism than a toy needs; and every line here has had exactly one reader |
0. One-screen summary
Recommendations
- Setup — split-MNIST, class-incremental, five tasks of two digits, one 10-way output head, a 784-400-400-10 MLP with no BatchNorm and no dropout, CPU only.
- Staging object — a low-rank (LoRA-style) delta file, bound by hash to the exact base state it was trained against. Replay is recommended as the proposer's training technique — it is not a staging mechanism. EWC is not recommended.
- Gate metric — the per-merge, per-task paired accuracy change on a protected set (the one-step term of backward transfer), plus cumulative drop against a high-water mark, plus counts of flipped examples. The gate emits findings, never dispositions.
- Verifiable non-effect — bases are immutable and content-addressed; the hash runs over a defined state surface that is wider than the weights; a behavioural probe and a counterfactual replay check by different routes; and every check has a negative control proving it can fire.
- Ruling — AUTHORIZED / DEFERRED / REJECTED, signed by the human, bound by hash to the candidate, the gate report, the parent state and the gate policy. Promotion is compare-and-swap on the parent hash. A ruling does not survive a state transition.
Five framing findings (§1) — places where the brief's framing needs adjusting before the design can be honest:
- F1 The brief's three 'candidate mechanisms' are not three answers to one question. One stages; two mitigate.
- F2 Under a never-mutate design, 'no residue in the base' is true by construction — so a bare checksum demonstrates nothing. The proof burden moves elsewhere.
- F3 Governance preserves; it does not teach. The gate's value is invisible on the happy path and appears only under proposer faults.
- F4 The PENDING → REVIEWED analogy breaks at legibility: the human never reads the delta, only a measurement of it.
- F5 The engineering pattern is not novel. This is pattern transfer, and should be described that way.
1. Framing findings
F1 — One of the three mechanisms stages; the other two do something else
The brief (§2) asks for a survey of 'candidate mechanisms for staging a weight delta as a separate, revertible object: LoRA/adapter-style low-rank deltas; Elastic Weight Consolidation …; a simple replay buffer', and a recommendation of 'one as primary … against the other two'.
Only the first is a staging mechanism. EWC is a penalty term in the loss; replay is extra data in the batch. Both act during training and shape which delta gets produced. Neither yields an object separable from the base, and neither offers any reversion of its own — to revert an EWC-trained model one restores a checkpoint, at which point the checkpoint is the staging mechanism and EWC is merely the optimizer's objective.
So the question has two axes, and gets two answers:
| Axis | Question | Answer |
|---|---|---|
| Representation | What object holds a proposed change before a decision? | A low-rank delta file (§2.2) |
| Proposer technique | How does the proposer produce deltas that deserve to pass? | Replay (§2.2) |
The governance consequence is the useful part: the gate must be indifferent to the second axis. It evaluates what the delta does, never how it was made. 'This candidate was trained with replay, so it is safe' is a claim by the proposer about its own work; the gate does not read it.
F2 — 'No residue' is trivially true of the base, so the proof burden moves
If the base is never written before a ruling, then a rejected candidate trivially leaves the base unchanged, and a before/after checksum is a check that cannot fail. A check that cannot fail is not evidence. The demonstration therefore has to earn its weight in three other places:
- (a) The state surface. The weights are not the whole governed state. The replay buffer, the protected set, the gate's thresholds and the high-water marks all condition future behaviour, and each is a channel through which a rejected candidate could leave something behind (§2.4).
- (b) Negative controls. Each check must be shown to fire on a planted violation (§3.9).
- (c) Counterfactual replay. Show that everything downstream of a rejected candidate is bit-identical to a run in which that candidate was never proposed — the only differences being the ledger entries that record it (§2.4).
One residue is not eliminable and should be named rather than hidden: the proposer learns from the rejection. Whoever trains the next candidate has seen the gate report. 'Zero residue' is a claim about the governed state, never about the system including its proposer. This is also the mechanism by which a protected set stops being held-out (§2.3).
F3 — Governance preserves; it does not teach
Consider four arms over the same five-task stream:
| Arm | Proposer | Gate | Outcome [P] |
|---|---|---|---|
| A1 | naive fine-tuning | none | ≈ 20% — knows only the last two digits; everything earlier destroyed |
| A2 | naive fine-tuning | governed | ≈ 20% — every candidate rejected; still knows only 0 and 1; nothing destroyed, nothing learned |
| A3 | replay | none | ≈ 90% |
| A4 | replay | governed | ≈ 90% — and, given determinism, bit-identical weights to A3 |
A1 and A2 land on the same headline number by opposite failures. A3 and A4 are indistinguishable. On these four arms the gate contributes nothing visible to accuracy.
Its value appears only when the proposer sometimes fails — a replay buffer silently empty, a learning rate off by an order of magnitude, a mislabelled batch. The convincing demonstration is therefore differential outcome under injected proposer faults (arms A5/A6, §4.1), not an accuracy curve. A demo that shows only the happy path shows a button.
Nothing in the gate says whether task k ought to be learned at all. That judgment sits with the human ruling and is not supplied by the structure.
F4 — The analogy breaks at legibility
The steward reads a PENDING item itself. Nobody can read a weight delta. The human rules on the gate's measurement of the delta, so the ruling knows exactly what the protected set covers and nothing else. 'Inspectable' (brief §1) is true of the delta as an object — hash, rank, norms, provenance — and false of it as meaning.
In split-MNIST the protected set nearly exhausts what the model is for, which is what makes the toy clean. That cleanliness is the least transferable thing about it: in any model of interest the protected set is a vanishing sample of behaviour. I recommend the demonstration include one scenario in which the gate is blind (S8, §4.2), so the artefact teaches its own limit rather than false confidence. The full audit of where the analogy holds, bends and breaks is §5.
F5 — The pattern is not novel engineering
- Model registries already carry a manual approval status. SageMaker's is literally
PendingManualApproval/Approved/Rejected[V]. - Champion–challenger evaluation before promotion is standard model-risk practice (e.g. US Federal Reserve SR 11-7) [R].
- Hot-swappable adapters over a frozen base are how LoRA is ordinarily served [R].
- Immutable content-addressed objects plus compare-and-swap on a parent hash is git.
What the toy adds is granularity (one ruling per update in a continual stream, not per model release), a proof obligation for non-effect, and parent-binding of rulings. It should be described as a demonstration of pattern transfer, not as a research contribution.
2. Research answers (brief §2)
2.1 Smallest toy setup that shows catastrophic forgetting cheaply and legibly
Recommendation: split-MNIST, class-incremental — tasks {0,1}, {2,3}, {4,5}, {6,7}, {8,9}; a single 10-way head evaluated over all ten outputs at all times; MLP 784-400-400-10 with ReLU, the architecture of the reference study [V].
| Option | Cost | Legibility | Verdict |
|---|---|---|---|
| Split-MNIST, class-incremental | seconds on CPU; 11 MB of data | total: a model that knew 0 and 1 calls every 0 a 2 or a 3; failures are viewable images | Recommended |
| Split-MNIST, task-incremental (multi-head) | same | forgetting is mild (87% with no mitigation [V]); near-zero-damage merges make every ruling trivial | Rejected — nothing to rule on |
| Permuted MNIST (domain-incremental) | same | forgetting is gradual; permuted pixels mean nothing to the eye | Rejected — illegible |
| Split CIFAR-10 | CNN, minutes to hours, GPU-ish | visual but noisy; accuracies too low to read cleanly | Rejected — cost |
| Sequential text classification (e.g. AG News → DBpedia → Yelp) | pretrained transformer, hundreds of MB, GPU nondeterminism | closest to 'real LoRA' | Rejected for Phase 1 — named as the escalation path if the pattern is later wanted at that fidelity |
Reference figures, split-MNIST, average accuracy over all five tasks after training on all five (van de Ven & Tolias 2019, Table 4) [V]:
| Method | Task-IL | Domain-IL | Class-IL |
|---|---|---|---|
| None — plain fine-tuning | 87.19 | 59.21 | 19.90 |
| EWC | 98.64 | 63.95 | 20.01 |
| Online EWC | 99.12 | 64.32 | 19.96 |
| Synaptic Intelligence | 99.09 | 65.36 | 19.99 |
| LwF | 99.57 | 71.50 | 23.85 |
| DGR (generative replay) | 99.50 | 95.72 | 90.79 |
| DGR + distillation | 99.61 | 96.83 | 91.79 |
| iCaRL (2,000 stored exemplars) | — | — | 94.57 |
| Joint training — upper bound | 99.66 | 98.42 | 97.94 |
Two further reasons for class-incremental beyond legibility [J]:
- Every merge costs something. Even a replay-trained candidate loses a little on earlier digits. There is no 'no-damage' candidate, so every ruling is a genuine trade of measured loss for measured gain. That is what gives the human something to do.
- The inspectable evidence is human-readable. The gate can show the specific digits the model used to get right and would now get wrong.
Caveat [P]. The published figures are for full fine-tuning. That low-rank deltas over a base trained from scratch on {0,1} reproduce both the ≈ 20% collapse and the ≈ 90% replay result is a prediction. Falsifier: the calibration run. Fallback: rank is a dial — at full rank a LoRA delta is a dense delta, so the choice in §2.2 degrades gracefully rather than failing.
2.2 Mechanisms for staging a delta as a separate, revertible object
| Mechanism | What it is | Separable object? | Exact reversion? | Role here |
|---|---|---|---|---|
| Low-rank delta (LoRA) — Hu et al. 2021 [R] | W' = W + (α/r)·B·A; base frozen, only A, B trained |
Yes — a small file | Yes, by never merging, or by restoring the prior base file. Not by subtracting (§2.4, checked) | Primary — the staging object |
| EWC — Kirkpatrick et al. 2017 [R] | quadratic penalty, weighted by Fisher information, on movement of the base weights, which are trained in place | No | None of its own | None. Also fails this scenario outright: 20.01% against 19.90% for doing nothing [V] |
| Replay buffer | stored earlier examples mixed into each training batch | No | n/a | Proposer technique. The only family above 90% in class-IL [V]; it is what makes AUTHORIZED reachable at all |
| Dense delta (also-ran) | full W_candidate − W_base |
Yes | as LoRA | The full-rank limit of the primary; adequate for a toy, but loses 'small and summarizable' |
Why LoRA rather than a dense delta, when both are cheap at this scale [J]:
- Structural write-isolation. The optimizer is constructed holding only adapter parameters. It has no handle on the base. 'Training cannot write the base' is then a property of how the optimizer was built, not of programmer care.
- It is the unit the brief names — 'the way a LoRA update or a model edit already is'. Rank-one model edits of the ROME/MEMIT family [R] fit the same object.
- It has meaningful summary statistics — rank, per-layer norm, ratio to the base norm — which is the only sense in which a delta is inspectable (F4).
- The rank dial subsumes the alternative.
LoRA is reported to forget less than full fine-tuning as a side-effect of its rank limit (Biderman et al. 2024 [V]). The design does not rely on this. Continual-learning LoRA variants (O-LoRA, InfLoRA [R]) are proposer-side techniques and would slot in without touching the governance layer — which is the point of F1.
Replay makes the buffer governed state. If the buffer gained new-task samples when a candidate was staged, a rejection would leave them behind. Buffer growth must therefore happen only at promotion, and the buffer belongs inside the state hash (§2.4).
A constraint this choice imposes. The adapter-form forward pass, Wx + (α/r)·B(Ax), and the merged-form forward pass, (W + (α/r)BA)x, are different floating-point computations; borderline examples can classify differently. The gate must evaluate the merged form — the exact bytes that would be promoted — so that 'what was evaluated is what was promoted' is a hash equality and not an approximation (invariant I3).
2.3 The metric
Standard definitions. Let R[j,i] be test accuracy on task i after the model has learned through task j.
- Backward transfer (Lopez-Paz & Ranzato 2017) [V]:
BWT = 1/(T−1) · Σ_{i<T} ( R[T,i] − R[i,i] ). Negative means forgetting. - Forgetting (Chaudhry et al. 2018) [R]: for each task, best accuracy ever achieved minus current accuracy.
BWT is an end-of-sequence aggregate. A gate needs the per-merge form, and needs it as a worst case, not an average:
| Reported per protected task i | Definition | Why |
|---|---|---|
| Step change | acc_i(base ⊕ Δ) − acc_i(base), same examples, paired |
the one-step term of BWT: what this merge would do, now |
| Cumulative drop | high_water_i − acc_i(base ⊕ Δ) |
Chaudhry's forgetting. Guards against salami-slicing: ten merges each within a 0.5-point step tolerance is five points gone, every one of them individually passed |
| Flips | count correct→wrong and wrong→correct | paired counts (McNemar-style) are more sensitive than a difference of two accuracies, and the correct→wrong list is the viewable evidence |
| Interval | 95% interval on the step and cumulative drops | evaluation is deterministic, so the interval is about the population the protected set samples — which the audit set then tests |
Also reported, but never folded into the finding: new-task gain (the benefit side — weighing it is the human's job) and delta statistics.
The held-out set stops being held-out. A protected set queried repeatedly by a proposer who adapts to its reports is no longer independent of the candidates (Dwork et al. 2015, the 'reusable holdout' problem [R]). Two responses, both cheap:
- Each task's protected data is split once into a gate set (~70%) and a sealed audit set (~30%). The audit set is never evaluated by the gate nor shown at ruling time. It is opened once, at the end of a run, by an
AUDITentry comparing audit-set and gate-set accuracies. One layer of checking; there is no audit of the audit. - No automatic retry loop. A retry after rejection is a fresh human-triggered proposal, logged with
retry_of, and every gate report states how many candidates have now been gated against this protected set.
2.4 What makes a rejected delta's non-effect verifiable rather than asserted
The state surface — every channel through which residue could travel:
| # | Channel | Treatment |
|---|---|---|
| 1 | Base parameters | in the state hash |
| 2 | Base buffers (e.g. BatchNorm running statistics, which update on a forward pass in training mode even with frozen parameters) | the toy has none by design; the hash covers the whole state_dict regardless |
| 3 | The base file on disk | content-addressed filename, read-only mode, file-level hash |
| 4 | Replay buffer membership | in the state hash; changes only at promotion |
| 5 | Protected-set membership, thresholds, allowed signers ('gate policy') | in the state hash; changes only by a signed POLICY_SET entry |
| 6 | High-water marks | in the state hash; change only at promotion |
| 7 | Process state — global RNG, caches, counters | each candidate's seed is derived as H(parent_state_hash ‖ canonical(spec)); nothing is drawn from a global stream or from a ledger sequence number |
| 8 | State invisible to state_dict (mode flags, non-persistent buffers, globals) |
caught by the behavioural probe, below |
| 9 | The proposer's knowledge of the gate report | not eliminable (F2); bounded by the sealed audit set; made visible by retry_of |
| 10 | The ledger entries and the archived delta | the intended residue |
The canonical hash. Iterate the state_dict in sorted key order; for each tensor feed name, dtype, shape and contiguous little-endian bytes to SHA-256. Hash tensor bytes, not the container file, so the result is independent of serialization format. The state hash is SHA-256 over canonical JSON of {base_hash, buffer_hash, policy_hash, high_water, seq}.
Four checks, by four different routes:
- State hash, recomputed from bytes on disk — never read from a cached pointer — equals the parent state hash recorded when the candidate was staged.
- File-level hash and mode of the base file unchanged.
- Behavioural probe. The base's logits on a fixed probe batch (256 fixed indices from the training split, so that no protected data is touched) are hashed and compared with the fingerprint recorded when that state became current. This reaches channel 8, which no weight hash can.
- Counterfactual replay (a suite-level test, not run per rejection). Run the faulty stream with its rejections, and the clean stream in which the faulty candidates were never proposed. Assert that every downstream artefact — state hashes, later delta hashes, merged hashes, gate-report bodies — is bit-identical, and that the ledgers differ only by the entries concerning the rejected candidates. Because seeds derive from the candidate's spec, the clean retry after a rejected fault is the same candidate as in the clean run, so the governed faulty run (A6) should end on exactly the same state hash as the clean governed run (A4) [P].
Check 4 is not tautological: purity is what the design claims; the replay tests whether the implementation has a hidden channel. Its negative control plants one (N6, §3.9).
Checked this session — reversion must restore, never subtract [V]. In emulated float32 over 200,000 weight/delta pairs, merge-then-unmerge (W + d) − d left 16.6% of elements different from the original (maximum error 1.5 × 10⁻⁸) and a different hash. Controls: a zero delta round-tripped exactly (0 differing, hash equal); a change of one unit in the last place to one weight changed the hash. 'Unmerge' is therefore not reversion at the level at which this design makes claims. Scope: an arithmetic fact about float32 established on synthetic values, not on the toy's tensors; the build repeats it on real ones (N5).
Determinism — prerequisite and claim scope. CPU only; one thread; torch.use_deterministic_algorithms(True); seeded data order; no loader workers. The claim is bit-identity on the same machine in the same environment; an environment fingerprint is logged with every candidate so that a mismatch is explicable rather than mysterious. [P] Falsifier: two runs of one candidate spec produce different delta hashes. Consequence if falsified: check 4 falls back to tolerance-level comparison, and 'demonstrated' weakens to 'approximately demonstrated'. That would be reported, not smoothed.
3. Design (brief §3)
3.1 Objects
STATE MANIFEST S_n — the governed state; nothing else is governed
base_hash canonical hash of the full state_dict
buffer_hash hash of the sorted replay-buffer index list (indices into MNIST train)
policy_hash hash of policy.json: τ_step, τ_cum, n_min, interval method,
gate/audit index lists per task, allowed-signers file hash
high_water {task_id: best gate-set accuracy recorded at any promotion}
seq n
state_hash = SHA-256(canonical JSON of the above)
CANDIDATE
candidate_id = H(parent_state_hash ‖ delta_hash ‖ resubmission_of) content-derived
display_seq C-0007 — for reading only; nothing ever binds to it
parent_state_hash
delta_hash → deltas/<delta_hash>.safetensors {layer: (A, B)}, α, r
merged_hash hash of W' materialized by the one fixed, deterministic merge procedure
spec task_id, data index-list hashes, replay indices used, hyperparameters, salt
seed = H(parent_state_hash ‖ canonical(spec))
provenance trigger, code version, environment fingerprint
proposer_note free text: what the proposer says it intended. NOT evidence; the gate never reads it
retry_of candidate_id | null
GATE REPORT
binds candidate_id, parent_state_hash, merged_hash, policy_hash
per protected task n, acc_base, acc_cand, step change, cumulative drop, flips, intervals
new task acc_base, acc_cand on the new task's gate set
delta stats rank; per-layer ‖ΔW‖, ‖ΔW‖/‖W‖
flipped test indices that went correct→wrong, plus a rendered contact sheet
exposure 'candidate number k gated against this protected set for task t'
coverage literal sentence: 'Measured: accuracy on N gate-set examples of digits {…}.
Not measured: everything else.'
finding WITHIN_TOLERANCE | EXCEEDS_TOLERANCE | INDETERMINATE | NOT_MEASURABLE
+ the task and the clause that decided it
RULING — the human's act
binds candidate_id, gate_report_hash | null, parent_state_hash, policy_hash,
prev_entry_hash
decision AUTHORIZED | DEFERRED | REJECTED
rationale required
conditions required when DEFERRED: what would cause reconsideration
against_finding true when the decision departs from the gate's finding
ruler, signature over the canonical bytes of everything above
Status is computed, never stored. Whether a candidate is staged, stale, promotable or archived is derived by replaying the ledger against the current state. A stored status field is a dated measurement waiting to be read as a present-tense fact.
3.2 Lifecycle
trigger ──► PROPOSE ──► delta file written and hashed
│ (on exception: PROPOSAL_FAILED is logged; no candidate exists)
▼
CANDIDATE_STAGED binds parent state hash, delta hash, merged hash, spec
│
▼
GATE ─────────► GATE_REPORT finding ∈ {WITHIN, EXCEEDS, INDETERMINATE, NOT_MEASURABLE}
│ └────► GATE_ERROR may still be REJECTED or DEFERRED; can never be AUTHORIZED
▼
human reads the report and the flipped digits
│
RULING (signed) ─┬─ REJECTED ───► delta archived, unpromotable ──────────► RESIDUE_CHECK
├─ DEFERRED ───► stays staged; its report decays if the state moves ─► RESIDUE_CHECK
└─ AUTHORIZED ─► PROMOTE ─┬─ every binding holds ─► PROMOTION (state S_n → S_n+1)
└─ any binding fails ──► PROMOTION_REFUSED ─► RESIDUE_CHECK
Fail-closed throughout: the default condition of every candidate is not applied. No ruling means no effect, indefinitely. Nothing times out into promotion.
3.3 Staging
The object is the CANDIDATE of §3.1: a delta file plus the hashes that bind it to one parent state.
What triggers creation — two things only:
- T1 — the stream driver emits 'task k data available'.
- T2 — the human requests a proposal with an explicit spec.
A re-gate (§3.5) produces a new report for an existing candidate, not a new candidate. There is no automatic retry: a proposer that loops until the gate passes is an optimizer aimed at the protected set (§2.3).
Ordering. The delta file is written and hashed first; CANDIDATE_STAGED is appended second, so that the entry can bind the hash. Staging asserts index-set disjointness between everything the proposer trained on and every protected index (I8), and recomputes the parent state hash from bytes on disk.
Genesis. M₀ is trained on task 1 and recorded as a signed GENESIS entry: base hash, initial buffer, initial protected set, first high-water mark, policy hash, probe fingerprint. It is not gated — nothing exists yet to protect — and the ledger says so in words rather than recording a vacuous pass.
3.4 The gate
Inputs: a parent state hash and a delta file. Nothing else. It does not read proposer_note, spec or provenance (F1).
Procedure: verify that the delta hash and the parent state hash match the staged entry → materialize merged weights by the fixed procedure → verify merged_hash → evaluate base and merged on every protected task's gate set and on the new task's gate set → compute §2.3's quantities → render the flipped-digit contact sheet → append GATE_REPORT.
Finding rule:
| Finding | Condition |
|---|---|
NOT_MEASURABLE |
a protected task has fewer than n_min examples, or the protected set is empty, or any hash precondition fails |
EXCEEDS_TOLERANCE |
for some protected task, the interval for the step drop lies wholly above τ_step, or the interval for the cumulative drop lies wholly above τ_cum |
WITHIN_TOLERANCE |
for every protected task, both intervals lie wholly below their thresholds |
INDETERMINATE |
otherwise — some interval straddles a threshold |
The finding vocabulary is deliberately disjoint from the ruling vocabulary. The gate never says pass, safe, approved or rejected. WITHIN_TOLERANCE means 'no damage beyond τ was found on the protected set'; the coverage sentence travels with every report so that this cannot be read as 'no damage'.
Thresholds are set by the steward after a calibration run and frozen in policy.json before any demonstration scenario runs. They are not tuned afterwards. I do not know the right values: in class-incremental learning even good candidates cost earlier tasks something, so they may need to be several points [P].
3.5 The ruling
| Disposition | Effect on governed state | Effect on the candidate |
|---|---|---|
| AUTHORIZED | none by itself; it makes PROMOTE executable (§3.6) |
promoted, if every binding holds |
| DEFERRED | none | stays staged. conditions records what would cause reconsideration |
| REJECTED | none | delta moved to the archive and kept. Terminal for this candidate_id: PROMOTE refuses any candidate with a REJECTED ruling on the ledger. To revisit, stage afresh; resubmission_of enters the new id |
Three properties that differ from the document case and carry weight:
- A DEFERRED delta decays. Its gate report is a measurement of parent ⊕ Δ. If another candidate is promoted meanwhile, the parent is no longer the current state and the report describes a model that will never exist. Reconsideration then requires a re-gate against the new state — evaluation only, no retraining — yielding a new report and needing a new ruling.
- Measurements are timeless; authorizations are acts in time. A gate report stays valid whenever its hashes match the current state — including after a rollback that restores its parent. A ruling is executable only if no state transition (
PROMOTION,ROLLBACK,POLICY_SET) lies between it and the promotion in the ledger. This forecloses the surprise case in which an old AUTHORIZED ruling becomes executable again long after it was given. - Two candidates AUTHORIZED against one parent: the first promotes; the second's ruling is void by the rule above; it must be re-gated and re-ruled. Deltas do not compose for free.
Keeping the human's step real:
- A rationale is required.
- The human may rule against the finding in either direction, and
against_findingrecords it — REJECTED despiteWITHIN_TOLERANCE(S5: nothing was learned, so the merge is unmeasured risk for no gain) or AUTHORIZED despiteEXCEEDS_TOLERANCE(S6: a loss knowingly accepted and written down). - The ledger makes the agreement rate between finding and ruling countable. An honest limit: if that rate is 100% over a long run, the ledger cannot say whether the gate matches the human's judgment or the human has become a button.
Who is the ruler? In a single-user sandbox nothing prevents a script from invoking the ruling command. Unless rulings are signed with a key the proposer and gate code paths never touch, 'human-authorized' is a convention, not a property. Recommended: ssh-keygen -Y sign (present on any Mac) or GPG, over the canonical ruling bytes including prev_entry_hash; PROMOTE verifies against an allowed-signers file whose hash sits inside the policy. What this proves: possession of the key at signing time. What it does not: that anyone deliberated, or that the key is out of reach of an agent on the same machine — which holds only if the key is passphrase- or hardware-protected. This is Decision D1.
3.6 Promotion — what AUTHORIZED does
PROMOTE(candidate):
require a RULING with decision AUTHORIZED for this candidate_id, signature valid
require no REJECTED ruling for this candidate_id anywhere on the ledger
require ruling.gate_report_hash = the candidate's latest GATE_REPORT
require report.parent_state_hash = current state hash, RECOMPUTED FROM BYTES ← compare-and-swap
require report.policy_hash = current policy hash
require no PROMOTION / ROLLBACK / POLICY_SET entry after the ruling
require hash(delta file) = candidate.delta_hash
write bases/<merged_hash>.safetensors — a NEW file, read-only; nothing is ever overwritten
require hash(the written file's tensors) = report.merged_hash ← I3
append PROMOTION { old state, new state, buffer additions, protected-set additions,
new high-water marks, new probe fingerprint } ← THE COMMIT POINT
update HEAD ← a cache of the ledger
re-evaluate the promoted file on the gate sets; must reproduce the report's numbers exactly
on any failed requirement: append PROMOTION_REFUSED naming the requirement, then RESIDUE_CHECK
The ledger append is the single commit point. A crash before it leaves an orphan file and no change of state; a crash after it leaves a stale HEAD, which verify detects and repairs by replaying the ledger. The ledger is the authority; HEAD is a witness to it.
3.7 The log
One file, ledger.jsonl. Append-only, single writer, fsync on append. Each entry carries seq, ts, type, body, prev_hash, entry_hash. It is the only canonical record; a Markdown rendering in PENDING/REVIEWED style is a derived view, regenerated on demand and marked as derived.
Entry types: GENESIS · POLICY_SET · PROPOSAL_FAILED · CANDIDATE_STAGED · GATE_REPORT · GATE_ERROR · RULING · PROMOTION · PROMOTION_REFUSED · RESIDUE_CHECK · ROLLBACK · AUDIT.
What survives every candidate whatever its fate:
- what changed —
CANDIDATE_STAGED: hashes, spec, statistics, the proposer's note; - what the gate found —
GATE_REPORT, orGATE_ERRORwith the exception; - the disposition —
RULING, with rationale and signature; - the effect —
PROMOTION,PROMOTION_REFUSEDorRESIDUE_CHECK.
Refusals and errors are entries. A command that fails silently is the defect this pattern exists to exclude.
Cross-references bind by content hash, never by display number or by position. A ruling that names 'C-0007' authorizes whatever later answers to that name; a ruling that names a hash authorizes one thing.
What the chain does and does not detect. A hash chain detects in-place edits. It does not detect a wholesale rewrite from genesis by someone able to recompute it. Signed rulings cover prev_entry_hash, so a rewriter without the key cannot carry the rulings across. Committing the ledger to a git repository gives an independent second chain at almost no cost.
Naming. This ledger shares an idea — hash-chained, append-only — with L1's logchain, and shares nothing else: no code, no format, no storage. Nothing observed about one is evidence about the other. The word 'ledger' is used to keep them apart.
3.8 Reversion
REJECTED — what it does to the base: nothing, because the base was never written. The delta file moves to archive/. It is kept so that the gate's finding stays reproducible; 'no residue' is a claim about governed state, not about disk (Decision D3).
How 'nothing happened' is demonstrated rather than claimed: a RESIDUE_CHECK entry follows every non-promoting outcome — REJECTED, DEFERRED, GATE_ERROR, PROMOTION_REFUSED — carrying checks 1–3 of §2.4 with their expected and observed values. The suite-level counterfactual replay (check 4) covers the system. The negative controls of §3.9 show that each check can fail.
ROLLBACK — reverting an AUTHORIZED promotion. A signed ruling naming an ancestor state hash. Because bases are immutable files, rollback is a pointer move plus a ledger entry, verified by recomputing the target's state hash from bytes and matching its recorded probe fingerprint. Buffer, protected set and high-water marks revert with the manifest. The ledger is never truncated; abandoned promotions stay on the record.
A limit to state plainly. History is linear. Revocation is truncation, not excision: one cannot remove the delta of step 2 and keep the delta of step 3, because step 3 was trained and measured against a base that contained step 2. One rolls back to before step 2 and re-proposes; whatever is wanted from step 3 goes through the gate again. Subtracting a delta ('task negation', Ilharco et al. 2023 [R]) is an approximation in behaviour and, per §2.4, inexact even in arithmetic.
3.9 Invariants, their checks, and their negative controls
| # | Invariant | Check | Negative control — the check must be seen to fire |
|---|---|---|---|
| I1 | No base file is ever modified | state hash recomputed from bytes at staging, at ruling and at residue check | N1 change one weight by one unit in the last place → detected |
| I2 | Only PROMOTION, ROLLBACK and POLICY_SET change governed state |
state hash before = after, for every other entry type | N2 a deliberately leaky proposer adds new-task samples to the buffer at staging → RESIDUE_CHECK fails |
| I3 | What was evaluated is what is promoted | promoted file's hash = the report's merged_hash |
N3 alter the delta after gating → refused |
| I4 | No promotion without a valid, signed, fully bound, un-superseded AUTHORIZED ruling | the require list of §3.6 |
N4a no ruling · N4b a ruling for another candidate · N4c stale parent · N4d policy changed since the report · N4e bad signature · N4f a state transition after the ruling |
| I5 | Reversion restores; it never subtracts | by construction | N5 merge-then-unmerge on the toy's real tensors does not restore the hash (§2.4: 16.6% on synthetic values) |
| I6 | A rejected candidate has no downstream effect beyond its records | counterfactual replay | N6 derive seeds from the ledger sequence number instead of the spec → the replay test fails |
| I7 | The ledger is append-only and self-consistent; HEAD agrees with it |
chain verification; HEAD = replay of the ledger |
N7a edit an old entry → detected · N7b alter HEAD → flagged and repaired |
| I8 | Training never sees protected data | index-set disjointness asserted at staging | N8 plant one gate-set index in a replay buffer → staging refuses |
A negative control that fails to fire is a finding about the instrument, and is reported as one.
4. Demonstration plan
4.1 Arms
A0 joint-training upper bound · A1–A4 as in F3 · and the pair that carries the demonstration:
| Arm | Stream | Gate | Expected [P] |
|---|---|---|---|
| A5 | replay proposer with three injected faults — Fa buffer silently empty · Fb learning rate × 50 · Fc new-task labels swapped | none — everything merges | collapse at the first fault; never recovers |
| A6 | the same faulty stream | governed; faults rejected; clean retries authorized | ≈ A4 in accuracy, and the same final state hash as A4 |
4.2 Scenarios
| # | Scenario | Exercises |
|---|---|---|
| S1 | naive candidate → EXCEEDS → REJECTED → residue check |
reversion; I1, I2 |
| S2 | replay candidate → WITHIN → AUTHORIZED → promoted |
I3, I4; post-promotion re-evaluation |
| S3 | small-buffer candidate → INDETERMINATE → DEFERRED, with conditions |
the third disposition |
| S4 | a second candidate for the same task is authorized; the state moves; S3's candidate is now stale → promotion refused → re-gate → new ruling | parent-binding; decay of DEFERRED |
| S5 | label-fault candidate → WITHIN on the protected set, new-task gain ≈ 0 → REJECTED against the finding |
ruling ≠ function of the gate |
| S6 (extended) | slight EXCEEDS, large gain → AUTHORIZED against the finding, the loss written down |
the same, in the other direction |
| S7 (extended) | ROLLBACK of S6 | truncation; hash identity with the earlier state |
| S8 (extended; Decision D2) | a candidate carrying a trigger-pixel backdoor (the standard BadNets-style classroom example [R]) passes the gate and is AUTHORIZED; a probe outside the gate shows that the trigger works | the gate's blind spot (F4) |
| S9 | end-of-run AUDIT on the sealed sets |
adaptive overfitting of the gate set |
4.3 Predictions, registered before any build, each with its falsifier
| # | Prediction | Falsified if |
|---|---|---|
| P1 | A1 ends at ≈ 20%, with accuracy on tasks 1–4 near zero | low-rank deltas forget materially less than full fine-tuning here — then the forgetting demonstration needs a higher rank or a dense delta |
| P2 | rank-8 deltas trained with replay reach ≈ 85–92% over five tasks | they do not — raise the rank; at full rank this is a dense delta |
| P3 | re-running one candidate spec gives a bit-identical delta hash | hashes differ — check 4 falls back to tolerance, and the claim weakens as stated in §2.4 |
| P4 | A4's final weights are bit-identical to A3's | they differ — the governance layer has a hidden channel into training, which is a finding |
| P5 | A6's final state hash equals A4's | they differ — a rejected candidate left residue somewhere §2.4 did not enumerate |
| P6 | every negative control N1–N8 fires | any does not — that check was not evidence |
| P7 | at S9, audit-set and gate-set accuracies agree within sampling error | they do not — the gate set was overfit by the propose/reject loop |
| P8 | the promoted file reproduces the gate report's numbers exactly | it does not — a merge-path discrepancy; I3 is not doing its job |
4.4 Build slices
Each leaves something complete in itself and depends on no later slice to mean something:
- The problem — A0 and A1, per-task accuracy plots. Shows forgetting; tests P1.
- REJECTED, proven — staging, gate, ledger, REJECTED,
RESIDUE_CHECK, N1, N2, N5, N7a–N7b. Tests P3. - AUTHORIZED and DEFERRED — promotion, parent-binding, staleness, re-gate; S2–S4; N3, N4a–N4f, N8. Tests P2, P8.
- The point of it — A5 against A6, counterfactual replay, S5, S9, N6. Tests P4, P5, P7.
- Extended — S6–S8; rollback; signatures, if not taken in slice 3.
5. Where the analogy holds, bends and breaks
| PENDING → REVIEWED | Weight-delta toy | |
|---|---|---|
| a proposal is a discrete block of text | a delta is a discrete file | holds |
| no effect until ruled | the delta never touches the base until promoted | holds — and more strongly: hash-verifiable, as the document case is not |
| a rejected item stays on the record | the same; the delta is archived | holds |
| append-only register | hash-chained ledger | holds |
| the steward reads the proposal itself | the human reads a measurement of the delta | breaks — the ruling is on a proxy bounded by protected-set coverage (F4) |
| 'Files affected' scopes a change | a delta touches every behaviour at once; there is no locality | breaks |
| an authorized item can later be struck out | truncation only, never excision (§3.8) | breaks |
| partial authorization is possible | a scaled or partial delta is a new candidate needing its own gate | breaks |
| a DEFERRED item keeps | a DEFERRED delta decays: its report is bound to a parent that may move | bends |
| the proposer's rationale is part of the case | the proposer's note is not evidence; the gate never reads it | differs by design (F1) |
| an item can be amended | a delta cannot; any change is a new candidate | bends — toward simplicity |
6. Limits — what this toy cannot show
- Coverage. The gate sees the protected set and nothing else. At MNIST scale that is nearly everything; at any scale of interest it is nearly nothing.
- Goodhart. A proposer adapting to gate reports optimizes against the gate. The sealed audit set bounds this for one run; it does not abolish it.
- A ruling on a proxy invites automation bias.
against_findingmakes that countable, not impossible. - Stability only. The gate measures forgetting. It does not measure loss of plasticity — the other failure of continual learning (Dohare et al. 2024 [R]). Declining new-task gain across successive candidates would be visible in the ledger, but nothing thresholds it.
- Linear history (§3.8).
- Determinism belongs to the toy. On GPUs, 'what was evaluated is what was promoted' survives, because a file is hashed; bit-exact re-derivation of a candidate does not, so the counterfactual replay would not transfer as designed.
- No claim about continual learning proper. Each candidate here is a supervised fine-tune on a labelled, pre-segmented task. Nothing here touches credit assignment from raw experience, which is the actual research problem (Sutton's, at Oak Lab [V]) and is a stated non-goal.
- One machine, one user. Write-protection is detection, not prevention. Ruler identity is exactly as strong as custody of the key.
- Robustness, not legitimacy. The structure sharpens whatever it is pointed at. Whether the model should learn task k at all is not something it can supply.
7. Open decisions for the steward
| # | Decision | Recommendation |
|---|---|---|
| D1 | Signed rulings, or a TTY-only convention? | Signed — otherwise 'human-authorized' is asserted, and the point of the toy is the difference between asserted and demonstrated. Requires a passphrase- or hardware-protected key. If cut, the README must say that ruler identity is unverified |
| D2 | Include S8, the blind-spot scenario? | Yes — it is the honest counterweight to F4. It is a textbook backdoor on a digit classifier, with no bearing on any real system. Steward's call, because it builds a deliberately bad artefact |
| D3 | Rejected deltas: retain, or delete keeping only the hash? | Retain — they are kilobytes, and retention keeps every gate finding reproducible |
| D4 | Who sets τ_step, τ_cum, n_min, and when? |
The steward, after the calibration run, frozen before any scenario runs |
| D5 | Where would a build live? | A new standalone repository, inside none of the existing ones. Name to be given |
| D6 | If rank-8 cannot learn new digits adequately (P2 falsified) — raise the rank, or go dense? | Raise the rank first; dense is its limit |
| D7 | Minimal cut (slices 1–4; S1–S5, S9) or extended (adding slice 5)? | Minimal first. Each slice stands alone |
8. What I would ask the jurist to attack
- F1 — is 'one stages, two mitigate' a fair reading of brief §2, or does it dodge the comparison that was asked for?
- §2.4, check 4 — I argue the counterfactual replay is not tautological because it tests the implementation against the design's purity claim. Is there a residue channel that survives bit-identity of every downstream artefact? Channel 9, the proposer's knowledge, is the one I know of.
- §3.5 — 'measurements are timeless, authorizations are acts in time'. Is voiding every ruling at every state transition too strict, or not strict enough?
- §5 — which 'holds' rows are decorative? In particular: is 'no effect until ruled: holds, and more strongly' an honest comparison or a flattering one?
- Proportion — is this more mechanism than a toy should carry? My standpoint (top of document) predicts that I would not see it.
9. Boundary observation — CapableMind (observation only; outside this brief's scope)
The register search turned up CapableMind-AI/docs/specs/modules/batch/training-module-spec.md. I did not read it in full — I grepped it for a handful of terms and read the matching lines. At that grain it already specifies: LoRA adapters where 'the base model is not modified' (line 480); four validation gates before deployment (lines 415, 512); rollback to a previous version (from line 698); a training-cycle history as audit trail (line 815); and operator approval as an optional step defaulting to require_approval: false (lines 640 and 926).
I draw no conclusion from this: the brief places CapableMind out of scope, and a default read at grep grain is not a finding about a system. It is recorded for two reasons. It is the 'what already says this?' half of grounding — the steward should know the toy's pattern has a specified cousin in-house. And the toy's two distinguishing commitments — a human ruling that cannot be defaulted away, and non-effect that is proven rather than assumed — are precisely where the two differ at the grain I read. Whether that difference matters is a question for a separate, later proposal, if ever.
10. Build outline — for sizing only; not authorization
Python 3.11+; PyTorch (CPU) with torchvision for MNIST; safetensors; matplotlib for plots and contact sheets. LoRA hand-written for the MLP (about thirty lines) rather than imported, so the merge procedure is ours to fix and hash. Estimated 600–900 lines including tests [J]. Runtime: seconds to a couple of minutes per arm on a laptop CPU [P]. No network after the MNIST download; no credentials; no GPU; no remote machine.
11. Sources and checks
Verified this session [V]
- van de Ven & Tolias, 'Three scenarios for continual learning', arXiv:1904.07734 — Table 4, architecture and task protocol, read via ar5iv (
ar5iv.labs.arxiv.org/html/1904.07734). Note: the fetch tool returns a small model's extraction of the page, not the page itself; the figures matched my independent recall (19.90 / 20.01). Two witnesses; neither is a notary. - Lopez-Paz & Ranzato, 'Gradient Episodic Memory for Continual Learning', arXiv:1706.08840 — the BWT definition, confirmed through secondary summaries in a search plus recall; the PDF itself was not opened.
- Biderman et al., 'LoRA Learns Less and Forgets Less', TMLR 2024, arXiv:2405.09673 — headline findings confirmed by search.
- Amazon SageMaker Model Registry —
PendingManualApproval/Approved/Rejected, confirmed against AWS documentation pages returned by a search. - Oak Lab — founded by Richard Sutton with Khurram Javed, July 2026, reported by heise online, MLQ News and TechTimes. This post-dates my training; I would have flagged the brief's reference as unknown had I not checked.
Recalled, not checked [R]
Hu et al. 2021 (LoRA, arXiv:2106.09685) · Kirkpatrick et al. 2017 (EWC, PNAS) · Chaudhry et al. 2018 (the forgetting measure) · Dwork et al. 2015 ('The reusable holdout', Science) · Dohare et al. 2024 ('Loss of plasticity in deep continual learning', Nature) · Ilharco et al. 2023 (task arithmetic, ICLR) · Meng et al. 2022 (ROME) · Gu et al. 2017 (BadNets) · Wang et al. 2023 (O-LoRA) · Liang & Li 2024 (InfLoRA) · Federal Reserve SR 11-7.
Checks run
- Register search for prior treatment of this subject in
PENDING.md,REVIEWED.md,PENDING-archive.md, the memory directory andCapableMind-AI/docs. The first pass was defective: a case-insensitiveLoRApattern matched 'exploration' and returned spurious hits throughout. Re-run with word boundaries and case sensitivity, with a control proving the pattern finds a known positive and ignores 'exploration'. Result: nothing in the three register files; five memory files and some ten CapableMind documents mention LoRA, all apparently about CapableMind's own training pipeline (§9). I read one memory file's head and the grep lines of one spec; the rest I did not open. - Merge-then-unmerge arithmetic (§2.4). Pure Python, float32 emulated by rounding through
structafter each operation;numpyis not installed on the system Python. 200,000 pairs,W ~ N(0, 0.05),d ~ N(0, 0.01). Differing elements 33,250 (16.6%); zero-delta control 0 differing; one-unit-in-the-last-place sensitivity control detected. Scope: an arithmetic fact about float32 on synthetic values — not a measurement of the toy.