Session Handoff — 2026-05-16 — Abuse-Case Hardening Strategy
Topic: Plan and document the institutional-failure-mode hardening doctrine so ICN cannot become an administrative panel with receipts.
Branch: docs/abuse-case-hardening-strategy
Worktree: /home/matt/projects/icn-worktrees/abuse-case-hardening
Base: origin/main @ d57ff1d6e (schema(network): define QuorumSyncCheck + FederationSyncWindow records (#1861))
Closes: none.
Refs: none filed by this session — see strategy doc §14 for the candidate roster.
This handoff records a docs/control-plane-only landing. No runtime change, no schema mint, no new ADR, no new RFC, no new contract URN, no production-readiness claim, no live-federation claim, no formal-NYCN-pilot claim, no Phase 2 completion claim. The deliverable is a strategy document plus an unfiled follow-up issue roster. Filing the issues, picking the first implementation slice, and updating PHASE_PROGRESS.md are all deferred to human decision.
Session Goal
Translate the red-team finding — "ICN's stronger risk is legitimacy laundering, not data corruption" — into a repo-native strategy document. Anchor every abuse story to real code, name the doctrine in ten one-line rules, propose a closed lifecycle vocabulary, list the production invariants, define the authority-shortcut policy, sketch the fixture matrix, and produce a P0–P3 follow-up roster. Do all of this without widening the meaning firewall, without minting new contract URNs, and without claiming any runtime change has landed.
Decisive Test
This handoff fails if any of the following holds:
- It claims the substrate is now hardened. It is not. The strategy document is descriptive; the work it sequences has not happened.
- It files follow-up issues, posts closure comments, or amends an ADR. None of those steps are part of this session.
- It mints a new contract URN, a new schema field, a new ADR, a new RFC, or a new ADR-0026 receipt class.
- It changes any runtime code, any gateway / kernel / actor / handler / receipt-backend / dispatch behavior.
- It touches K3s, DNS, Forgejo, deployment scripts, NYCN partner data, or any live infrastructure.
- It claims Phase 2 completion, live federation, formal NYCN pilot, or production readiness.
- It widens the meaning firewall or imports domain semantics into kernel crates.
- The strategy document never uses payment / wallet / currency / balance / token / crypto / blockchain / timebank framing outside negation context.
- Code anchors in the strategy doc do not resolve in
main @ d57ff1d6e.
Final State (Verified)
main HEAD at session start
d57ff1d6efafcaaebeb33d43c6f8cf104cd68a0e — schema(network): define QuorumSyncCheck + FederationSyncWindow records (#1861)
Worktree and branch
| Attribute | Value |
|---|---|
| Worktree | /home/matt/projects/icn-worktrees/abuse-case-hardening |
| Branch | docs/abuse-case-hardening-strategy |
| Base | origin/main @ d57ff1d6e |
CARGO_TARGET_DIR for the session |
/tmp/icn-target-abuse-hardening (defensive; no Rust check actually ran) |
Code anchors verified from the worktree
The strategy doc cites file:line anchors. Each was re-verified by running grep from inside the worktree before the prose was written.
| Anchor | Symbol | Verified |
|---|---|---|
icn/crates/icn-rpc/src/auth.rs:947 |
GOVERNANCE_WRITE = "governance:write" |
✓ |
icn/apps/governance/src/http/handlers.rs:386 |
pub async fn create_domain<E ...> |
✓ |
handlers.rs:548 |
pub async fn add_domain_member<E ...> |
✓ |
handlers.rs:593 |
pub async fn remove_domain_member<E ...> |
✓ |
handlers.rs:694 |
pub async fn activate_charter<E ...> |
✓ |
handlers.rs:751 |
pub async fn create_proposal<E ...> |
✓ |
handlers.rs:1177 |
pub async fn close_proposal<E ...> |
✓ |
handlers.rs:1695 |
pub async fn cast_vote<E ...> |
✓ |
handlers.rs:2550 |
pub async fn create_action_item<E ...> |
✓ |
handlers.rs:3415 |
pub async fn create_structure<E ...> |
✓ |
handlers.rs:3678 |
pub async fn create_meeting<E ...> |
✓ |
handlers.rs:78, 572, 617, 1111, 1203 |
MembershipSource::TrustThreshold(_) => true (fail-open sites) |
✓ |
handlers.rs:1245-1294 |
resolver-aware delegation exclusion at close-time (positive precedent) | ✓ |
handlers.rs:1267-1268 |
inline // Fail-open on resolver errors comment |
✓ |
icn/apps/governance/src/http/configure.rs:197-201 |
MemberStandingChecker type alias |
✓ |
configure.rs:214-218 |
SuspensionChecker type alias |
✓ |
configure.rs:244, 253, 264 |
Option<...> fields on GovernanceContext |
✓ |
icn/apps/governance/src/dispatch_evidence.rs:34-87 |
EffectDispatchEvidence struct |
✓ |
dispatch_evidence.rs:131-169 |
ReconciliationStatus enum (EmittedOnly, ExecutionEvidenced, ExecutionFailed) |
✓ |
icn/apps/governance/src/receipt_backend.rs:42, 80, 106, 146, 178-210, 248 |
typed receipt write entry points | ✓ |
receipt_backend.rs:178-190 |
comment block stating put_mandate_with_grants default is NOT atomic |
✓ |
icn/crates/icn-kernel-api/src/proofs.rs:646-661 |
ArtifactDigest::scoped_vault_reference digest-only rendering boundary |
✓ |
icn/crates/icn-kernel-api/src/proofs.rs:1699-1739 |
SyncDegradedStatus precedent |
✓ |
icn/crates/icn-ccl/src/governance.rs:146-163 |
current quorum_met semantic-only validation |
✓ |
Source-of-truth docs cited
All seven docs cited in the strategy doc exist with current Status: descriptive / Canonical: yes / Last Reviewed: YAML headers, verified by test -f from inside the worktree.
docs/STATE.md(Last Reviewed 2026-05-15)docs/PHASE_PROGRESS.mddocs/architecture/ARCHITECTURE_DUE_DILIGENCE.md(Last Reviewed 2026-05-04)docs/architecture/KERNEL_APP_SEPARATION.mddocs/spec/effect-dispatch-contract.mddocs/spec/member-shell-v0.mddocs/spec/steward-cockpit-v0.mddocs/security/production-hardening.md
Open PRs at session start
None of the open Dependabot PRs (#1790, #1791) intersect this work.
What Changed
1. docs/architecture/ABUSE_CASE_HARDENING_STRATEGY.md (created, 608 lines)
The strategy document. Sections in order: status / non-claims, why-this-exists, core doctrine (ten one-line rules), abuse stories (ten scenarios, each with code anchors), hardening tracks (ten subsections matching the abuse stories), production invariants, closed lifecycle vocabulary (draft), authority-shortcut policy, resolver / checker fail-closed policy, receipt-semantics policy, governance-sanity strategy (draft bands: fixture-valid / pilot-valid / production-valid), shell / cockpit fixture matrix, privacy / ScopedVault abuse-prevention regression set, typed-receipt atomicity inventory plan, implementation issue roster (P0–P3, names only — no numbers minted), open questions (5), recommended sequencing (Stages A–E), non-claims preserved, see-also cross-links.
Doctrine encoded:
- Receipts prove events, not legitimacy.
- Authority shortcuts must label themselves as shortcuts.
- Unresolved standing is not standing in production.
- Accepted is not applied. Receipt exists is not complete.
- Convenience paths must not become authority paths.
- Bootstrap is not democracy.
- A token is not a mandate.
- A UI must not launder uncertainty into confidence.
- Privacy posture is not private content.
- Index absence is not record absence.
2. docs/dev/handoff-2026-05-16-abuse-case-hardening.md (this file)
Mirrors the established 2026-05-15 sprint handoff exemplar. No new sections invented.
3. docs/INDEX.md (one architecture-section line)
Added a single line listing the strategy doc alongside ARCHITECTURE_DUE_DILIGENCE.md and the other architecture documents. No structural change to INDEX.md.
4. docs/registry.toml (one [docs."..."] row)
Added the canonical control-plane entry for the strategy doc using the same field set as the ARCHITECTURE_DUE_DILIGENCE.md row (category, status, title, description, last_updated, owner, audiences, truth_class, role, canonical, freshness, domain_tags, recommended_action, last_reviewed).
5. docs/STATE.md (one new HTML-comment sync block at the top)
A new <!-- [sync edit] 2026-05-16 --> block preceding the existing 2026-05-15 block. The block records the landing, names the non-claims, and explicitly states this sync does not modify any contract field, mint any new URN, add any ADR/RFC, change any runtime behavior, or touch any infrastructure.
No other STATE.md narrative is touched.
What's Open
Deferred by this session
- Open the PR. The local commit is in place; the suggested push and PR-creation command is recorded in §"Next Move" for human invocation.
- File any of the P0–P3 candidate issues from the strategy doc's §14 roster. The roster names titles and anchors; no GitHub issue is created here.
- Pick the first implementation slice. The strategy doc's §16 sequencing recommends Stage B (safety rails) as the first executable stage, but selection is a human decision.
- Resolve the five open questions in the strategy doc's §15 (scope decomposition vs mandate gating, administrative receipt class, closed-vocabulary owner, degraded-state record class, direct-mutation lifetime).
- Update
docs/PHASE_PROGRESS.md. Nothing in this session completes a phase; the doc remains unchanged. - Update
docs/DOCUMENT_REGISTRY.md. Regeneration is downstream ofdocs/registry.toml; the regen is part of normal doc maintenance, not this session. - Update labels / milestones on follow-up issues. None are filed.
Preserved boundaries
- No issue closure, no draft closure comments.
- No new ADR, no new RFC, no new contract URN, no new schema field.
- No runtime / code changes. No
cargoinvocations needed; no Rust source touched. - No SDK / TypeScript regeneration. No
npminvocations needed. - No K3s / DNS / Forgejo / deploy / observability surface touched.
- No NYCN partner data, no private-data handling.
- The meaning firewall is not widened. The strategy doc explicitly does not propose domain semantics inside kernel crates; §4.1 keeps mandate-gating as the ICN-native path where it fits.
Unsafe Assumptions
- Anchor drift. All file:line citations in the strategy doc are pinned to
main @ d57ff1d6e. Ifmainadvances between this session and PR merge, the cited line numbers may move. Symbols (create_proposal,add_domain_member, etc.) remain stable; line numbers do not. A reviewer shouldgrepeach anchor before merge. - Scope-string permanence.
GOVERNANCE_WRITEatauth.rs:947is the current single-broad scope. A parallel PR reorganizingauth.rscould move the symbol; the strategy doc would then need a one-line edit. - Inline fail-open trade-off note. The strategy doc cites the existing inline comment at
handlers.rs:1267-1268("Fail-open on resolver errors") as a known production gap. The comment is a deliberate trade-off made at design time, not a bug; reframing it as a production gap is a design opinion this strategy doc explicitly takes. - SyncDegradedStatus precedent. Recent commits
d57ff1d6e,4d0a6b83b,f3c8b9a0daddedQuorumSyncCheck,FederationSyncWindow,SyncDegradedStatus, andPeerSyncReport. The strategy doc referencesSyncDegradedStatusatproofs.rs:1699-1739as a precedent for resolver-degraded governance states. If the API of those records is in flux, the strategy doc's §15 open question covers it explicitly. - Linter posture.
docs/scripts/lint-arch.pyis targeted atdocs/ARCHITECTURE.md(per its docstring) and enforces a per-section<!-- truth: ... -->marker thatARCHITECTURE_DUE_DILIGENCE.mditself does not use. The strategy doc adopts the canonical-doctrine-doc posture (no truth-class markers); 19 expected "missing truth-class" errors result from running the linter on it. The vocabulary check (the part that actually matters for this doc) is clean: 0 forbidden-term warnings, 0 hard-forbidden errors. See §"Checks Run" for the exact invocation.
Review Feedback Applied
None — this is the pre-review handoff for the initial PR.
Next Move
Open the PR with the suggested title
docs(architecture): abuse-case hardening strategy.cd /home/matt/projects/icn-worktrees/abuse-case-hardening git push -u origin docs/abuse-case-hardening-strategy # or use /push to invoke the sanctioned push helper gh pr create \ --title "docs(architecture): abuse-case hardening strategy" \ --base main \ --body-file - <<'EOF' ## Summary Codify the institutional-failure-mode hardening doctrine in `docs/architecture/ABUSE_CASE_HARDENING_STRATEGY.md`. Strategy document only — no runtime change, no new ADR, no new contract URN, no new schema. Sequences a P0–P3 follow-up roster against real code anchors (broad `governance:write` scope, direct charter activation, direct membership mutation, optional checker wiring, effect-dispatch idempotency, typed-receipt atomicity). Builds on the upstream doctrine in `docs/architecture/ARCHITECTURE_DUE_DILIGENCE.md` (twin doctrines: convenience-vs-authority, participation-access). ## Non-claims - No production-readiness claim. - No live-federation claim. - No formal NYCN pilot claim. - No Phase 2 completion claim. - No new ADR, no new RFC, no new contract URN, no new schema. - No K3s / DNS / Forgejo / NYCN partner-data mutation. - No runtime behavior changes. ## Files - `docs/architecture/ABUSE_CASE_HARDENING_STRATEGY.md` (new, 608 lines) - `docs/dev/handoff-2026-05-16-abuse-case-hardening.md` (new) - `docs/INDEX.md` (one line added) - `docs/registry.toml` (one row added) - `docs/STATE.md` (one sync-edit comment block added) ## Checks - `docs/scripts/lint-arch.py` — 0 forbidden-vocab warnings, 0 hard-forbidden errors. The 19 "missing truth-class" errors are expected (this linter targets `docs/ARCHITECTURE.md`; sibling `ARCHITECTURE_DUE_DILIGENCE.md` has the same posture). - `docs/scripts/doc_control_check.py` — clean. ## Test plan - [ ] Re-verify code anchors against current `main` before merge. - [ ] Confirm no token / payment / wallet / currency / balance / blockchain / timebank framing escapes negation context. - [ ] Confirm Stage 0 / Stage A in the strategy doc has not been claimed beyond what this PR actually does (the strategy document is descriptive, not implementation). EOFAfter merge: file the P0 candidate issues from §14 with the existing label taxonomy (
epic:trust-hardening,tier:1-correctness, etc., per.github/ISSUE_POLICY.md).Sequence implementation per §16 — Stage B (safety rails) before Stage C (evidence correctness) before Stage D (surface regression) before Stage E (governance sanity). Stage A (this PR) is the documentation / control-plane layer.
Architectural Decisions
- The doctrine lives in
docs/architecture/, notdocs/strategy/ordocs/security/. This is institutional-failure-mode doctrine, parallel toARCHITECTURE_DUE_DILIGENCE.md. It is upstream ofdocs/security/production-hardening.md(transport / crypto / replay) — the two are complementary, not overlapping. - No new ADR. The doctrine is a process / principle document, not a single architectural decision. Specific design decisions (scope decomposition, administrative receipt class, lifecycle-vocabulary owner) are deferred to follow-up PRs that may file ADRs as the design firms up. The convention here matches
ARCHITECTURE_DUE_DILIGENCE.md. - Closed lifecycle vocabulary is proposed in the strategy doc but not yet bound to any kernel-api type. Where the enum lives (kernel-side vs governance-app-side) is explicitly listed in §15 as an open question. Pre-deciding it here would be the kind of meaning-firewall widening this strategy is supposed to prevent.
- The §14 issue roster names titles and anchors only. No numbers are minted. Filing is a human decision. This matches the 2026-05-15 sprint-wrap pattern (
docs/dev/handoff-2026-05-15-architecture-spec-sprint-wrap.md). - Authority shortcuts are kept available, not removed. The substrate must be bootstrappable; direct charter activation and direct membership mutation are honest answers to a real need. The doctrine is that they label themselves as shortcuts, not that they vanish. Whether they remain post-pilot is the institution-adopting-ICN's decision, not the substrate's.
- Mandate gating is named as the ICN-native alternative to SaaS-style scope decomposition. §4.1 keeps both options on the table because the kernel still needs a capability primitive for enforcement; the institution still authorizes by mandate. The two are not in tension. The follow-up PR picks per call site.
Checks Run
| Check | Command | Result |
|---|---|---|
| Forbidden-vocab lint (strategy doc) | python3 docs/scripts/lint-arch.py docs/architecture/ABUSE_CASE_HARDENING_STRATEGY.md |
0 warnings, 0 hard-forbidden errors. 19 expected "missing truth-class" errors (linter targets ARCHITECTURE.md; canonical doctrine docs like ARCHITECTURE_DUE_DILIGENCE.md do not use truth-class markers). |
| Forbidden-vocab lint (handoff) | (deferred to commit-time pre-flight) | pending |
| Doc-control validator | python3 docs/scripts/doc_control_check.py --repo . --registry docs/registry.toml |
pending — runs after the registry row is added (Stage 4). |
| Anchor verification | grep -n '<symbol>' <file> for every cited anchor |
All 24 anchors resolve in main @ d57ff1d6e. |
git status --short |
from inside the worktree | clean at session start; five expected files at commit time. |
Checks Not Run and Why
| Check | Why skipped |
|---|---|
cargo check / test / clippy / fmt |
No Rust source modified in this session. The strategy doc cites Rust code but does not change it. |
cd sdk/typescript && npm run generate-types && npm test |
No API change. No TypeScript change. |
| Full CI workflow simulation | Not invoked locally. CI will run on PR. |
| K3s / cluster / pod state checks | Out of scope. No infrastructure change. |
mcp__icn-ops__* / mcp__plugin_icn-dev_icn-dev__icn_* |
Out of scope. No deploy / ops decision. |
| Receipt-store integration tests | Out of scope. The doc inventories typed write paths; it does not exercise them. |