Session Handoff — 2026-05-14 (storage durability policies spec)
Session Goal
Define StorageSpec, BackupPolicy, ReplicationPolicy, RecoveryPolicy, ArchivePolicy, and IntegrityPolicy as design-level forward-direction policy objects so the storage-durability half of the operating model is precise enough for later schema, provider, and proof-loop work to be filed safely.
Decisive Test
Can a downstream implementer — looking only at this spec plus the canon it harmonizes with — name (1) what each of the six policy objects carries at design granularity, (2) how StorageSpec ties to the merged GovernedServiceBinding and DomainPolicy, (3) what the locality / privacy inheritance rule is and why it cannot be silently broadened, (4) what a restore-test receipt MUST record, (5) which authority class covers a restore of authoritative state? If yes, the spec has done its job.
Final State (Verified)
main HEAD
09331622d — docs(spec): define governed service binding, workload manifest, and runtime provider (#1822) (merged earlier today).
Open PRs
| PR | Branch | State | CI Status | Blocker |
|---|---|---|---|---|
| #1823 | spec/storage-durability-policies |
OPEN | All required checks passed on commit e375687b3 (initial spec push). Two Copilot threads landed after the initial no-feedback polling window; a fix commit follows this handoff edit and must re-run CI before merge. |
Awaiting CI re-run on the Copilot fix commit, then mergeability re-check |
| #1790 | dependabot (pilot-ui dev deps) | OPEN | n/a | Out of session scope |
| #1791 | dependabot (ts-sdk dev deps) | OPEN | n/a | Out of session scope |
Branches
spec/storage-durability-policies— pushed to origin. Last verified head before this fix:e375687b3. The head moves with each push; checkgit rev-parse HEADon the branch after the next push for the current SHA.- Local
mainsynced to09331622d(unchanged this session).
Issues
#1816— OPEN. This session writes the candidate spec doc. PR will useRefs:, notCloses:.#1815— OPEN (your manual closure decision deferred; PR #1822 usedRefs:notCloses:).#1767,#1792,#1798,#1799,#1801,#1818— sibling storage / privacy / network / compute / mobile issues, all OPEN.#1797,#1793,#1817— closed previously.#1794— OPEN (deferred closure decision).
What Changed
1. Spec doc drafted (docs/spec/storage-durability-policies.md, ~490 lines)
The doc:
- Defines six policy objects at design granularity.
StorageSpec(binding identifier, custody class, kernelStorageClass,DataLocality, privacy class, capacity, six policy references, export requirement, deletion expectation, receipt expectations).BackupPolicy(cadence class, target locality + custody, privacy inheritance, encryption / key custody, retention window, integrity check, restore-test cadence, authority, receipt classes).ReplicationPolicy(replica count class, placement constraints, anti-entropy expectation, divergence detection, repair authority, replica lifecycle authority, receipt classes).RecoveryPolicy(restore objective class — NOT SLA, restore authority, drill cadence, restore-target constraints, full / partial / point-in-time, challenge / reversal / audit, receipt classes).ArchivePolicy(long-term retention class, immutability expectation, access path, redaction, institutional hold, export, verification cadence, expiration authority, receipt classes).IntegrityPolicy(verification cadence, proof shape, repair path, relationships to replication and recovery and anti-entropy, receipt classes). - Maps the seven-class custody taxonomy (canonical store / service state / artifact-blob / volume-block / scoped vault / secret-key material / cache-derived) to the implemented kernel-level
StorageClass(3 variants) verbatim. Per-class design expectations cover custody, locality, privacy, backup, replication, archive, restore authority, export, receipts. - Surfaces the drift honestly. The 7-class taxonomy (spine doc) and the 3-variant kernel enum (
icn/crates/icn-kernel-api/src/storage.rsline 53) overlap but do not align 1:1. Reconciliation is deferred to a named follow-up; both stand today. - Restore-test receipts in their own section. What a drill is, what triggers, what constraints (no silent mutation of authoritative state), what the receipt records (source, target, authority, verification outcome, convergence time), what failure means (governance-relevant event surfaced in the steward cockpit), how it surfaces in the member shell.
- The single load-bearing inheritance rule in §"Locality and privacy inheritance", stated three ways: backups, replicas, archives, exports, and restore targets inherit the source's
DataLocalityand privacy / disclosure constraints; policy MAY narrow disclosure; policy MAY NOT broaden locality or disclosure without an explicit governance act. - Backup / export / restore authority mapped to ADR-0014 (
AuthorityClass,Mandate) and the effect dispatch chain. Routine backup execution is operational; restore of authoritative state is governed; emergency authority is bounded, reviewable, receipt-backed. - Cross-links every sibling issue.
#1767(encrypted private overlay),#1792(disclosure boundary),#1798(ArtifactRegistry / ScopedVault),#1799(anti-entropy proof loops),#1801(compute placement),#1818(member shell),#1795(steward cockpit). No duplication. - Sixteen-row failure / safety table. Each failure mode has a deterministic response. Cross-cutting rule: fail closed, surface honestly, never silently fall back.
- Eleven open questions with named forward homes.
2. Registered the doc (docs/registry.toml, +13 lines before the governed-service-binding.md entry)
Same registry pattern as #1819 / #1820 / #1821 / #1822: category = "architecture", status = "draft", no truth_class / role overrides (lets the docs/spec/ prefix default supply truth_class = "normative", role = "spec"). Carries description, last_updated / last_reviewed, owner, audiences, domain_tags, depends_on, recommended_action.
3. Added the spec to docs/INDEX.md Specifications section
Proactively added before any reviewer surfaces it. INDEX.md's Specifications section now lists all five recent specs (KERNEL_CONTRACTS, effect-dispatch, institutional-domain, ccl-policy-registry, governed-service-binding, storage-durability-policies).
4. Regenerated docs/DOCUMENT_REGISTRY.md
Ran python3 docs/scripts/doc_control_check.py --repo . --registry docs/registry.toml --strict --write-document-registry docs/DOCUMENT_REGISTRY.md. Diff is small (corpus 804 → 805 markdown files; explicit rows updated; Last Reviewed 2026-05-14).
5. Followed prior review-cycle lessons proactively
- YAML frontmatter
Status: normative; matchesdocs/spec/prefix default. - Doc opening labeled "spec, work-in-progress" — honest about which clauses are forward-direction.
- MUST claims gated on existing types. Where the abstract model adds new names, those are explicitly forward-direction.
- Verified all 23 cross-link targets exist before commit.
- Used canonical vocabulary verbatim:
StorageClass(withCanonical/ServiceState/Blobs),DataLocality(withCellLocal/CoopReplicated/FederationMirrored/CommonsPublic),GovernanceProof/GovernanceDecisionReceipt/ArtifactReceipt/FederationProvenance,Mandate/AuthorityGrant/AuthorityClass,EffectManifest/KernelEffect,DomainPolicy,GovernedServiceBinding,WorkloadManifest. Forbidden vocabulary only in the explicit anti-claim sentence. - Acknowledged the 7-class vs 3-variant
StorageClasstaxonomy drift explicitly (lesson from the Codex P2 catch on #1822 about ADR-0030's privacy-class names vs the implementedPrivacyClassenum).
6. Drafted follow-up issues (not filed)
Per the established pattern. Six titles named in §"Next Move" below.
What's Open
- Branch created (
spec/storage-durability-policies). - Spec doc drafted; registry updated; INDEX.md updated; DOCUMENT_REGISTRY.md regenerated.
- Validation suite passed locally. (doc_control_check pass with 54 pre-existing/generated-doc warnings; lint-arch CLEAN; compliance_linter clean; freshness exit 1 from pre-existing
docs/ARCHITECTURE.mdstaleness — same pattern as #1814 / #1819 / #1820 / #1821 / #1822.) - Initial commit (
e375687b3) and push. - PR #1823 opened.
- Initial CI passed on
e375687b3(all required checks green; non-required skip). - Two Copilot review threads landed after the initial no-feedback polling window: (1) opening-paragraph internal inconsistency about "wire-stable form" and sibling-spec list; (2) handoff Final State stale recording the branch as local/pending push.
- Copilot review-feedback fix applied in this session's pending commit.
- Push the Copilot fix commit and re-run CI.
- Recheck
mergeStateStatusafter CI returns green. - Reply to / resolve the two Copilot threads with the fix commit SHA.
- Per the user's current prompt: "If checks are green, mergeability is clean, and no valid unresolved feedback remains, squash-merge PR #1823." Squash-merge if clean.
- Sync local
mainand prune the branch (squash-merge requiresgit branch -D). - Leave
#1816closure to human review (PR usesRefs:, notCloses:). - Decide whether to file the follow-up issue drafts listed in §"Next Move §5" (deferred to user).
- After
#1816is closed by the user (if they decide closure is warranted), the recommended next PR is#1798(ArtifactRegistryv0 andScopedVaultboundary). The user explicitly asked not to start#1798/#1799/#1801/#1818/ implementation in this session.
Carried forward (not addressed in this PR)
docs(agents): reconcile handoff path with HANDOFF_TEMPLATE.md — AGENTS.md lines 281–313 still say docs/dev-journal/; docs/dev/HANDOFF_TEMPLATE.md (lines 10, 109–111) and 15+ merged PRs use docs/dev/. The docs/dev-journal/ directory does not exist. Surfaced in #1820 review; carried through #1821, #1822, and now this PR. Recommended one-line edit. Not addressed in this PR to keep scope tight.
Unsafe Assumptions
StorageClassandDataLocalitydefinitions inicn/crates/icn-kernel-api/src/storage.rsare stable. Verified by reading the file (line 53 + line 155). If a follow-up PR has amended the variant set since the Explore agent's read this session, my "reuse verbatim" framing may need adjustment.- No
StorageSpec/BackupPolicy/ReplicationPolicy/RecoveryPolicy/ArchivePolicy/IntegrityPolicytypes exist in code. Verified by Explore-agent grep (no matches). If a parallel in-flight PR is adding any of these, my "forward-direction" framing for those names is wrong. storage-governance-spec.mdis the foundational storage doc. I treated it as the canonical source forStorageClassandDataLocality. If a follow-up doc has been written or it has been deprecated, my harmonization framing may need revisiting.- The 7-class custody taxonomy from the spine doc is current canon. Mapped to the kernel-level
StorageClassenum with an explicit drift note. If the spine has been amended to align the taxonomies, the drift note is unnecessary; otherwise it stays. #1767'sPrivateOverlay+SecretCredentialprivacy classes are still the forward-direction names. I referenced them via#1792'sPrivacyClasstaxonomy. If those names have changed in an in-flight draft of#1767or#1792, my privacy-inheritance section needs a re-read.- The 23 cross-link targets exist at session start. Verified by file-existence sweep before committing. If a downstream PR renames or removes one before
#1816lands, the spec's link will rot. - The Codex P2 lesson from #1822 (ADR text vs implementation drift) was correctly internalized. The spec acknowledges the 7-class vs 3-variant
StorageClassdrift explicitly and names reconciliation as forward work. If a reviewer disagrees with the framing, the reword pattern from #1822 applies.
Next Move
- Push the Copilot fix commit prepared in this session. Watch CI to settle.
- Reply to / resolve each open Copilot thread on PR #1823 with the new fix commit SHA. The two open Copilot comments are: (a) opening-paragraph "wire-stable form" / sibling-spec list conflation; (b) handoff Final State staleness.
- Re-check
mergeStateStatusafter CI returns green. - Per the user's current prompt: squash-merge PR #1823 if clean. Sync local
main; force-delete the branch (git branch -D spec/storage-durability-policies) since squash-merge invalidates the ancestor check for-d. - Follow-up issue drafts (deferred; not filed in this PR):
schema(storage): define StorageSpec and durability policy records— the wire-stable schema deliberately omitted.spec(storage): define restore-test receipt envelope— the Rust type, persistence, and audit-query surface.spec(storage): define locality/privacy inheritance checks— thevalidate_storage_access()-style enforcement function named as TBD instorage-governance-spec.md.spec(storage): define archive verification and export contract— per-archive proof shape, hand-off protocol, custodian agreement.spec(storage): define backup provider / runtime provider interface— how aBackupPolicyis executed by aRuntimeProviderper#1815.spec(anti-entropy): connect IntegrityPolicy receipts to network proof loops— the integration with#1799.- Optional:
spec(storage): reconcile 7-class custody taxonomy with kernel StorageClass enum— if the user wants the drift formally resolved.
- Separate process cleanup recommendation (carried from #1820 review):
docs(agents): reconcile handoff path with HANDOFF_TEMPLATE.md. Not in this PR's scope.
Architectural Decisions
- Six policy objects at design granularity.
StorageSpecis the binding; the other five are referenced policies. None introduces a Rust type; all are forward-direction. - Reuse kernel
StorageClassandDataLocalityverbatim. The 3-variant kernel enum and the 4-level locality enum fromicn/crates/icn-kernel-api/src/storage.rsare canonical. The spec does not redefine them. - Acknowledge the 7-class custody taxonomy as a richer design-level grouping. Reconciliation with the 3-variant kernel enum is forward work, not a hidden assumption.
- Locality and privacy inheritance is mandatory. Backups, replicas, archives, exports, and restore targets MUST inherit source constraints. Policy MAY narrow disclosure; policy MAY NOT broaden locality or disclosure without explicit governance.
- Restore of authoritative state is governed. The restore-execution receipt is the institutional record; emergency restore authority is bounded, reviewable, receipt-backed.
- Restore drills produce real receipts. A failed restore test is a governance-relevant event, not a hidden warning. The steward cockpit surfaces it; member shell summarizes the recovery posture (not the data).
- Replication is not backup. Both share a verification surface (
#1799's anti-entropy proof loops) but answer different institutional questions. - Archive is not quiet deletion. Archive expiration is a governance act with a named authority and an expiration receipt.
- Integrity verification reuses existing hash / proof vocabulary (
blake3content hashes pericn-ccl/src/registry.rs, Merkle proofs pericn-store/src/lib.rs). The spec does not introduce new hash algorithms or proof formats.
Verification Commands
cd /home/matt/projects/icn
# Branch + PR state
git branch --show-current
gh pr view <pr-number> --json state,mergeable,mergeStateStatus
# Validation suite
python3 docs/scripts/doc_control_check.py --repo . --registry docs/registry.toml --strict
python3 docs/scripts/lint-arch.py docs/spec/storage-durability-policies.md --cargo icn/Cargo.toml
python3 .github/scripts/compliance_linter.py
python3 docs/scripts/freshness-check.py --freshness docs/freshness.toml --status docs/status.toml --repo .
# Review thread state
gh api repos/InterCooperative-Network/icn/pulls/<pr-number>/comments \
--jq '.[] | {id, user: .user.login, line, in_reply_to_id, created_at}'
Expected at session start before push: doc_control_check pass with 54 enforcement warnings (none on the new doc); lint-arch CLEAN (already verified); compliance_linter no violations; freshness-check exit 1 from pre-existing docs/ARCHITECTURE.md staleness.
Truth-Plane Notes
- Declared project truth: loaded from
docs/STATE.mdanddocs/PHASE_PROGRESS.md. No conflict surfaced. - Implementation truth: verified by reading
icn-kernel-api/src/storage.rs(lines 53, 155, 272) for the canonicalStorageClass,DataLocality,StorageValidationErrorenums. Verified that none of the six policy objects exist as Rust types today. Verified thatRestoreReceipt/BackupReceipt/IntegrityReceiptdo not exist; spec defers their wire-stable form to follow-up. - Execution truth: confirmed
mainHEAD09331622d, two dependabot PRs open, no other open PRs.#1816confirmed OPEN with the body matching the user's prompt. - Known truth-plane conflict #1:
freshness-check.pyreportsdocs/ARCHITECTURE.mdas carrying stale sections (06-identity-cryptography, 10-state-ledger, 11-contract-execution, 12-governance, 14-federation). CI workflow treats this as informational and reports SUCCESS; the script itself exits 1. Same pattern as #1814, #1819, #1820, #1821, #1822. - Known truth-plane conflict #2 (the spec surfaces honestly): The 7-class custody taxonomy in the spine doc vs the 3-variant
StorageClasskernel enum. Both stand today; reconciliation is named as forward work. - Known process drift (carried, not in this PR): AGENTS.md vs
docs/dev/HANDOFF_TEMPLATE.mddisagree on handoff path. De-facto canon isdocs/dev/handoff-*.md. Recommend separate scoped fix.