I read this as a read-only architecture/contract adjudication - I’ll trace the evidence pipeline and reviewer authority end to end, compare the three recursion models, then return one decision-complete contract with a decisive PASS/FAIL rationale.


I read this as a read-only contract adjudication - I recommend a finite post-seal attestation DAG that keeps candidate `2e` immutable and exact-candidate-bound.

# Decision

**Adopt A: an external append-only post-seal readiness checkpoint, followed by an append-only inventory-state observation.**

Candidate:

`2e0894eac92bc396cc4723bf1f18ebc653b95018dd41574df435941c235da925`

**remains the current immutable candidate.** Do not reseal it and do not modify its in-tree checkpoint.

Invariant 10 requires evidence **from and bound to** the exact candidate; it does not require every later review receipt to be embedded inside that candidate. Task26 review receipts are already external attestations.

The evidence graph must be acyclic:

```text
v2 normative inventory
  -> predecessor-653 authenticated trainer-free inputs
  -> immutable candidate 2e + in-tree seal checkpoint
  -> external 2e post-seal readiness checkpoint
  -> external v2 inventory-state observation
  -> independent trainer-free final re-audit receipt
```

No artifact references a later artifact.

## Important implementation fact

The current `full_candidate_digest` is not actually a digest of the complete candidate tree. The sealer computes it from `manifest_core`; `candidate-checkpoint.json` is excluded. Therefore the literal hash recursion is partly a naming/contract problem.

Editing the in-tree checkpoint is nevertheless prohibited because it would change the frozen tree and invalidate:

- checkpoint SHA-256 in `verifier-input.json`;
- freeze receipt bindings;
- the observed immutable-tree commitment;
- the claim that candidate `2e` was not mutated.

A sidecar attestation is therefore still the correct solution.

# Options

| Option | Viability | Trade-offs |
|---|---|---|
| **A. External post-seal checkpoint and inventory observation** | **Recommended now** | Lowest coupling and migration cost. Preserves `2e`, its freeze, wheel, manifest and tree. Pure hash verification is easy. Main risk is external-record equivocation or deletion. |
| **B. Domain-separated self-excluding checkpoint** | Viable for a future candidate format | Architecturally clean if candidate identity is explicitly a payload digest and checkpoint identity is separate. Requires coordinated changes to sealer, verifier, freeze schema, reviewers and naming. Retrofitting it to frozen `2e` would redefine existing identity semantics. |
| **C. Successor reseal containing its own digest** | **Reject** | Unsatisfiable when the successor digest covers the checkpoint containing that digest. Every checkpoint creates another digest. More reseals only increase provenance complexity and attack surface. |

For a future B-format, use:

```text
payload_digest =
  SHA256("task26-candidate-payload-v2\0" || canonical(payload_manifest))

checkpoint_digest =
  SHA256("task26-readiness-checkpoint-v2\0" ||
         canonical(checkpoint_binding_payload_digest))

package_digest =
  SHA256("task26-package-v2\0" ||
         payload_digest || checkpoint_digest)
```

The checkpoint may contain `payload_digest`, never `package_digest`. Candidate identity must explicitly mean `payload_digest`. That redesign does not pay for itself for `2e`.

# Required contract

Use canonical JSON:

```text
UTF-8
sort_keys=true
separators=(",", ":")
ensure_ascii=true
allow_nan=false
duplicate keys forbidden
arrays retain declared order
```

All evidence files must be unique-path, atomically published, regular non-symlinks, `st_nlink == 1`, owner-private, and never overwritten.

Define:

- `C` = immutable candidate `2e...da925` root
- `E` = `.omo/evidence/task26`

## 1. External post-seal readiness checkpoint

Logical top-level field order:

1. `schema`
2. `status`
3. `recorded_at_utc`
4. `execution_head`
5. `git_status_porcelain_v1_z_sha256`
6. `git_status_entry_count`
7. `candidate_manifest_path`
8. `candidate_manifest_sha256`
9. `candidate_digest`
10. `candidate_file_count`
11. `v1_runtime_closure_manifest_path`
12. `v1_runtime_closure_manifest_sha256`
13. `production_wheel_path`
14. `production_wheel_sha256`
15. `production_wheel_member_count`
16. `trainer_free_migration_receipt_path`
17. `trainer_free_migration_receipt_sha256`
18. `preclean_fixture_manifest_path`
19. `preclean_fixture_manifest_sha256`
20. `preclean_fixture_receipt_path`
21. `preclean_fixture_receipt_sha256`
22. `verification_receipt_paths`
23. `verification_receipt_sha256`
24. `task22_permission_receipt_path`
25. `task22_permission_receipt_sha256`
26. `hash_algorithm`
27. `product_profile_service_telegram_provider_delivery_mutations`
28. `commits_pushes_releases`
29. `authority`
30. `scope`
31. `candidate_root`
32. `candidate_core_digest`
33. `seal_checkpoint`
34. `freeze_receipt`
35. `candidate_tree`
36. `current_candidate_verification`
37. `source_evidence_transfer`
38. `trainer_free_control_binding`
39. `inventory_contract_binding`
40. `non_actions`
41. `privacy`

Required values include:

```text
schema =
  task26-trainer-free-current-candidate-postseal-checkpoint-v1

status =
  READY_FOR_TASK26_SECURITY_READONLY_REAUDIT

authority =
  CURRENT_CANDIDATE_READINESS_ONLY_NOT_TASK26_PASS_OR_RELEASE_AUTHORITY

candidate_digest =
  2e0894eac92bc396cc4723bf1f18ebc653b95018dd41574df435941c235da925

candidate_core_digest =
  a8d099d5372b1ac87c9b47e7d5b47c8bb4cdff7681e093bb3cd79d0303e6e88e

candidate_manifest_sha256 =
  7b6d0d6e275426fada6bc585989052e03fdc056587fc2051764e47c61756752d

candidate_file_count = 43
execution_head = 0dc0f228dcec8fa54430882daf72e901d6a89f79
git_status_entry_count = 1294
git_status_porcelain_v1_z_sha256 =
  ca1ce2705c0c406f30461e5f05e8d09468dee33348960c3650b6b98758895478

production_wheel_sha256 =
  af4a9d0a1ffffb6eb7551c1d6dc2b32853ca6d024332a4f8f5702bbf992f141b

production_wheel_member_count = 860
hash_algorithm = sha256
product_profile_service_telegram_provider_delivery_mutations = 0
commits_pushes_releases = 0
```

The existing seal checkpoint remains separately bound:

```text
seal_checkpoint.sha256 =
  5ae5b75bc10fdbe86d13d18f9204b5a4def17d5c5b6dc90da5fb8534fccea102

seal_checkpoint.status =
  SEALED_SUCCESSOR_CANDIDATE_NOT_TASK26_PASS
```

The freeze binding is:

```text
freeze_receipt.sha256 =
  002c8c64e79d757b38c13251475ec2b6a5ff70c0fc01222cf29066a060fbd521
```

These statuses are not contradictory: one proves sealed bytes; the external checkpoint proves readiness for review.

### Candidate-tree commitment

Use rows over `[root, *root.rglob("*")]`, sorted by full path. Each row is:

```json
{
  "path": "." or candidate-relative POSIX path,
  "type": "directory" or "regular_file",
  "mode": four-digit octal string,
  "bytes": null for directories, otherwise file size,
  "sha256": null for directories, otherwise file SHA-256
}
```

Hash the canonical row list. Reject symlinks, non-file/non-directory entries, wrong modes and hard-linked files.

Expected observation:

```text
entry_count = 51
directory_count = 8
regular_file_count = 43
mode_violation_count = 0
tree_sha256 =
  d5213d1b71d6e4d1e14f1b6f18c57d72551e295a3c0e0735bd4198dfb3dc75b4
```

### Source-evidence transfer

The predecessor must remain explicitly predecessor-scoped:

```text
source_candidate_digest =
  653cc2f0b47873e95f985ea3eb32b8f2c044d6de64cd9e8fe37ebcec67c7a723

exact_source_delta_sha256 =
  4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945

product_source_delta_count = 0
product_wheel_byte_identical = true
historical_execution_retargeted_to_successor = false
```

Do not rewrite the predecessor receipts to claim execution on `2e`. Their results transfer only as source-bound evidence through proven byte identity. Current-candidate authority comes from the new checkpoint, current verifier and tree binding.

The control object must bind at least:

```text
trainer_free_v4_successor_binding_sha256 =
  2e46a3bae7c6f6194449b841685b568412b1cbe74cf742cba3f534f3dd093d47

authoritative_inventory_v2_sha256 =
  3ce7f5b93ac9265cd82bb18a04cbc4363efa7d08e16a2810835980aa0d69b4d8

inventory_v2_supersession_sha256 =
  fa6a0d1de70a8496c6e0dbb9c008cc13bbbdefe7a9bd684317da686ebbe59024

runtime_closure_v2_sha256 =
  f8b732bd42c0142931d06f37f5f2c64315bcbb3686ec7fe50473e69ee5eab4b0

sealer_input_index_sha256 =
  2ca3b8db32bcc8124f053ca0d778bd64c86916d019956dd0657985619aed202c

sealer_input_index_digest =
  470f2bb25c95babd3d786355de5bf9b718fdef50b14bd2bdb21e06baf0930471

indexed_leaf_count = 763
indexed_leaf_mismatch_count = 0
checkpoint_field_count = 23
acceptance_gate_count = 14
```

Gate IDs must retain the v2 order from `TFV1-CLOSURE-001` through `TFV1-CANDIDATE-001`.

## 2. Append-only inventory-state observation

Do not create a modified copy of v2. Preserve it as the normative policy and append a state-supersession record with this logical order:

1. `schema`
2. `status`
3. `recorded_at_utc`
4. `authority`
5. `state_parent`
6. `supersedes`
7. `current_candidate`
8. `postseal_checkpoint`
9. `contract_invariance`
10. `acceptance_gate_observation`
11. `effective_state`
12. `anti_equivocation`
13. `non_actions`
14. `privacy`

Required semantics:

```text
authority =
  INVENTORY_STATE_SUPERSESSION_ONLY_NOT_TASK26_PASS

supersedes:
  v2 current_verdict = FAIL
  v2 checkpoint_observed = false
  prior 2e trainer-free final verdict = FAIL

effective_state:
  candidate_digest = 2e...da925
  checkpoint_observed = true
  current_verdict = READY_FOR_TASK26_SECURITY_READONLY_REAUDIT
  task26_pass = false
```

It must bind the raw SHA-256 of the new checkpoint and preserve these policy digests exactly:

```text
required_fields_sha256 =
  9068f017d63340389c1909cd0dfcbc51d53bf11d9bcbe0aac70ebce42d7ff9b0

required_values_sha256 =
  daefea96e08ff2575e00a3fbce4cdc567d8ac5af3ca7656e484f190392db677b

checkpoint_contract_sha256 =
  a91f3401c0052542303d393f983062b8ab01eb5a6ae5370348f918020a9b9f59

acceptance_gates_sha256 =
  f6b83edbcb3c1f2d4ac338a737f2c271c9098c3866eb3521cb88f810985ec98a

global_trainer_free_scan_sha256 =
  f397d35d5a5b47f66e423078cea55eae76621afd1221072df28908ccebe8c03a

required_reaudit_execution_sha256 =
  d45437e933124c2c92efc000b73a95d09ebd6b5b6d4bb7aeddc1e85b3f3052a
```

Thus the observation supersedes only v2's historical state flags. It cannot remove, rename, relax or reinterpret any of the 14 gates.

# Authority rules

1. `2e...da925` is the only current candidate digest.
2. `653...a723` may appear only as inherited source-evidence provenance.
3. The in-tree checkpoint establishes sealed bytes, not readiness.
4. The external checkpoint establishes readiness, not Task26 PASS.
5. The inventory observation advances state, not policy.
6. Only a later independent trainer-free reviewer may issue that lane's PASS.
7. Only the overall release review may grant Task26 or release authority.
8. Timestamps never select authority. Hash-chain membership and exact candidate match do.
9. Any competing valid child of the same inventory-state parent is an equivocation and decisive FAIL; do not choose “latest”.
10. Any candidate-tree drift, missing 763 input, altered gate digest, nonzero absence count or predecessor receipt retargeting is decisive FAIL.

# Hidden weaknesses

- **“Full digest” is misleading.** It commits the manifest domain, not the complete candidate tree or checkpoint. The external checkpoint must therefore bind the tree, seal checkpoint and freeze explicitly.
- **POSIX read-only is not immutable or append-only.** The owner can chmod, replace or delete evidence. Hashes prove integrity of available bytes, not authorship or non-deletion. The minimum mitigation is unique paths, parent-hash chaining, stable descriptor-bound reads and fail-closed fork detection. A detached signature or transparency log is required only if the threat model includes a malicious evidence owner.
- **The 763-input index commits hashes but not availability.** Many source leaves and Gate18-20 receipts remain outside the candidate. They must all be present and reauthenticated at checkpoint time. A future format should package them content-addressably.
- **Absolute-path/TOCTOU risk exists.** Verification should use directory descriptors, `O_NOFOLLOW`, stable pre/post `fstat`, single-link files and stable root device/inode.
- **Byte parity transfers code-bound evidence, not historical live execution.** This contract must not convert Task22-25 historical Telegram actions into execution against `2e`.

# Final PASS/FAIL rationale

- **Current evidence state:** **FAIL**, correctly. The post-seal checkpoint and state observation do not yet exist.
- **Contract satisfiability:** **PASS** under option A.
- **Candidate decision:** `2e...da925` remains current and unchanged.
- **Literal endless-successor remediation:** **FAIL / structurally unsatisfiable**.
- **Substantive reviewer remediation:** Can be fulfilled with two append-only evidence records, read-only hash/verifier authentication, and one later final review receipt.
- **Required operational actions:** zero product edits, zero test edits or reruns, zero profile/runtime/service actions, zero archive changes, zero network/Telegram/provider actions and zero Git actions. Evidence-only writes are required.
- **Scope:** Success permits the trainer-free lane to re-audit `2e`; it does not by itself make overall Task26 or the release PASS.