SEC-KN-4C-MIGRATION-HOOK-RESTORE-FREEZE.md markdown
297 lines 14.1 KB
Raw
sha256:700fafdd1afa490919f9515d660ca6e75456bcd5bb67513abcd8757a634c01f6 docs: record AIP-b SD-21 land (KN #308) Human 9 days ago

SEC-KN-4c — frozen spec: restore migration hook to identity (T4 land)

Phase: SEC-KN-4c (SEC-KN-4c-a Thinking freeze → SEC-KN-4c-b Auto land) Freeze status: CLEARED for SEC-KN-4c-b Auto land — freeze-review pass (2026-08-01; mechanical stamp + Thinking semantic clearance). Live T4 already on canister (0x039360a0…); residual is Muse/main + muse-mirror land + test flips. Date: 2026-08-01 Model (this artifact): Thinking Owner repo: Knowtation Parent freeze: docs/SEC-KN-4-DELEGATION-PRINCIPAL-BINDING-FREEZE.md (§8 gate T4, R1.4, D2 ratified 2026-07-26)

Freeze-contract declaration

phase: SEC-KN-4c-a
outputs:
- id: sec-kn-4c-freeze
  path: docs/SEC-KN-4C-MIGRATION-HOOK-RESTORE-FREEZE.md
  frozen: true
  notes: Identity migration on StableStorage after T1; Muse/main + muse-mirror land of Motoko already live on canister; no redeploy unless module hash diverges; no posture/env flips; F7 parked; P6 share UNVERIFIED; live created_by field probe optional
frozen_inputs:
- id: sec-kn-4-freeze
  path: docs/SEC-KN-4-DELEGATION-PRINCIPAL-BINDING-FREEZE.md
  notes: frozen:true; review_stamp pass; R1.4 one-shot hook + T4; D2 ratified option A
- id: migration-mo
  path: hub/icp/src/hub/Migration.mo
  notes: live tip on feat/sec-kn-4c-identity-migration already identity; Muse main still V7→current + TODO
- id: verify-migration
  path: scripts/verify-canister-migration.mjs
  notes: must require identity hook + forbid TODO(SEC-KN-4c) after land
- id: sec-kn-4-tests
  path: test/sec-kn-4-delegation-principal-binding.test.mjs
  notes: unit assertion still matches TODO(SEC-KN-4c) — Auto must flip
review_stamp:
  reviewed_at: '2026-08-01T13:14:37Z'
  verdict: pass
  reviewer_mode: agent
  reviewer_model: thinking-high
  reviewer_provider: local
  kit_version: 0.1.0
  artifact_digest: sha256:67d6a9f1a0c92b4ab7d7a9d35623862f27f3d35ac856c2ce6989f57d3641bbe3
downstream:
- id: SEC-KN-4c-b
  model: Auto
  consumes_as_ground_truth: true
  notes: Land identity Migration.mo + verify script + test flips onto Muse tip; seven-tier; BV pass; no canister redeploy unless hash mismatch
tier3_gates:
- T1 Muse main merge of the identity-restore Motoko (SD-14 path only)
- T2 muse-bridge + GitHub muse-mirror → main PR (never feature→main)
- T3 Any new canister WASM deploy (forbidden unless live module hash ≠ frozen expected hash)
- T4 Any posture / write-env / Delegation gate flip (out of scope — hard stop)

Review record

Round Reviewer Verdict Resolution
0 Thinking (this session) draft Freeze authored from live evidence + source
1 ok review --freeze (mechanical) findings F1 MINOR C8 — artifact lacked literal file+line citation-readiness evidence; fixed in §4C-R0
2 Thinking semantic + ok review --freeze pass Re-derived: live module hash matches T4 record; Muse/main still V7 hook; feature-branch Motoko identity + verify script OK; SEC-KN-4 unit still expects TODO(SEC-KN-4c) (4C-R6 required). C1–C8 pass; nothing escalating open. Cleared for 4c-b Auto land only.

Round 1 findings (cited — file+line)

ID Sev Cat Citation Finding Fix
CLI-F1 MINOR consistency docs/SEC-KN-4C-MIGRATION-HOOK-RESTORE-FREEZE.md:1 Checklist C8 requires literal file+line citation-readiness evidence. Added §4C-R0.

4C-R0 — Citation readiness

Every freeze-review / build-verification finding against this artifact must cite file+line. Uncited findings are invalid.


1. Plain-language summary

After the canister learned who created each proposal (created_by), the upgrade code that added that field had to stay special for exactly one install. Leaving that special code in place blocks every later upgrade. This step puts the upgrade code back to “do nothing — state is already current,” so future fixes can ship. The live canister already runs that safe version; Muse/main and GitHub still show the old special code. Auto must land the safe version into the canonical Muse tip without redeploying the canister unless the live module hash no longer matches.

2. Technical summary

SEC-KN-4c discharges freeze gate T4 from docs/SEC-KN-4-DELEGATION-PRINCIPAL-BINDING-FREEZE.md:415 (R1.4 addendum): restore Migration.migration to identity on StableStorage so repeat upgrades are accepted (moc --stable-compatible exit 0; no Compatibility error [M0216]).

Measured consequence of leaving the T1 hook in place (2026-07-26): repeat deploy refused with M0216 (Missing field 'created_by'), blocking hotfixes — not silent authorship erase.

2.1 Verified state (this Thinking session — 2026-08-01)

Fact Evidence
Live hub module hash dfx canister --network ic info rsovz-byaaa-aaaaa-qgira-caiModule hash: 0x039360a0985c79e2ec993e0d0b81dc6e6b85e4d924c1123f5d1af26cdfd69bae
Matches 2026-07-28 T4 deploy record docs/OVERSEER-HANDOVER.md on feat/sec-kn-4c-identity-migration (Prior session §FCA.2)
Live health (raw) GET https://rsovz-byaaa-aaaaa-qgira-cai.raw.icp0.io/health{"ok":true,"gateway_auth_configured":true}
Feature-branch Motoko hub/icp/src/hub/Migration.mo:455-457 is identity migration(old : { var storage : StableStorage }) { old }
Feature-branch verify script scripts/verify-canister-migration.mjs:49-50 + :101-106 require identity + forbid TODO(SEC-KN-4c)
canister:verify-migration on feature branch exit 0
Muse/main + GitHub origin/main Motoko still migration(old : { var storage : StableStorageV7 }) + TODO(SEC-KN-4c) + _proposalV7ToCurrent wired into the actor hook
Live proposal created_by field UNVERIFIED this session (optional probe; not a land blocker)
P6 MCP / SESSION_SECRET share UNVERIFIED (out of scope)
MuseHub F7 AWS-parked (do not start)

Board honesty: later relay refreshes on Muse/main (docs/relay-sd21-landed) re-opened SEC-KN-4c as “TODO” while live T4 already matched 0x039360a0…. This freeze corrects that: live T4 is DONE; canonical Muse/main land is the residual.


3. Frozen requirements (4C-R1 … 4C-R9)

4C-R1 — Actor hook is identity on StableStorage

hub/icp/src/hub/Migration.mo public hook must be exactly:

public func migration(old : { var storage : StableStorage }) : { var storage : StableStorage } {
  old
};

(Equivalent { var storage = old.storage } is acceptable if type-identical; prefer old matching 2624dbf V5 identity pattern.)

Forbidden: any actor-hook domain still typed StableStorageV7, or any map through _proposalV7ToCurrent inside the public migration function.

4C-R2 — Remove the one-shot TODO marker

The literal TODO(SEC-KN-4c) must not appear in Migration.mo after land. A non-TODO comment naming SEC-KN-4c / T4 (as on the feature branch today) must remain so verify-script and operators can locate the restore.

4C-R3 — Keep historical helpers

Retain as private/historical (not called by the actor hook):

  • _proposalV7ToCurrent (sets created_by = "" for provenance / tooling)
  • _proposalBeforeEnrichToCurrent / _proposalV4ToV5 returning ProposalRecordV7
  • StableStorageV5 / V6 / V7 type pins on ProposalRecordV7

Do not delete the one-shot map function — only disconnect it from the actor hook (same pattern as historical V4→V5 after identity restore).

4C-R4 — Module header documents the post-T1 invariant

Header / hook comments must state: after the one-time V7→created_by upgrade (T1) has run on a canister, the hook is identity on StableStorage so repeat deploys succeed. Canisters that have never received T1 must not install this identity WASM as their first created_by upgrade (they need the one-shot V7→current WASM once — git history / feat/sec-kn-4a-… tip).

4C-R5 — Verify script contracts flip

scripts/verify-canister-migration.mjs must:

  1. Require migration(old : { var storage : StableStorage }) (identity domain).
  2. Require _proposalV7ToCurrent still present (historical).
  3. Require a SEC-KN-4c mention and !includes('TODO(SEC-KN-4c)').
  4. Stop requiring the actor hook to be StableStorageV7 (the pre-4c check name “V7→V8 adds cors…” is obsolete for the actor hook; V7 type may remain as a historical type declaration check).

npm run canister:verify-migration must exit 0 on the landed tree.

4C-R6 — SEC-KN-4 unit assertion flips

test/sec-kn-4-delegation-principal-binding.test.mjs (unit tier, currently :453-464 on trees that still expect the TODO) must:

  • Assert identity hook domain migration(old : { var storage : StableStorage }).
  • Assert _proposalV7ToCurrent retained.
  • Assert absence of TODO(SEC-KN-4c).
  • Keep V5/V6/V7 → ProposalRecordV7 pin assertions.

Renaming the test title to drop “+ TODO(SEC-KN-4c)” is required.

4C-R7 — Seven-tier matrix (land-focused)

Tier Expectation
unit Source assertions in 4C-R6; canister:verify-migration exit 0
integration Motoko compile check: env -i PATH="…" HOME="…" NO_COLOR=1 TERM=dumb dfx build --check hub exit 0
e2e No new HTTP surface — assert actor still uses (with migration = Migration.migration) in main.mo (existing verify-script mainChecks)
stress Identity hook body is O(1) — no Array.map over proposalEntries in the public migration function (source assertion)
data-integrity _proposalV7ToCurrent still sets created_by = "" (historical map unchanged); public hook does not call it
performance canister:verify-migration completes under 2s locally (wall clock)
security No secrets added; no X-User-Id / body authorship path introduced; diff limited to Migration.mo + verify script + SEC-KN-4 test assertion + governance docs

Auto may place these in test/sec-kn-4c-migration-hook-restore.test.mjs or extend the existing SEC-KN-4 suite — either is fine if all seven tiers are green and named.

4C-R8 — No canister redeploy by default

If live module hash is still 0x039360a0985c79e2ec993e0d0b81dc6e6b85e4d924c1123f5d1af26cdfd69bae, Auto must not run dfx deploy / canister install. Land is source + mirror only.

If the hash differs, Auto stops (gates_tier3) and reports — Operator decides whether a new WASM is required. Do not improvise a redeploy.

4C-R9 — Hard stops (out of scope)

  • No Delegation / Tasks / Media / Flow / Lab posture or write-env flips
  • No MuseHub F7 work
  • No P6 exploitability assessment (leave UNVERIFIED)
  • No claim that live proposal created_by was re-probed unless an authenticated GET is executed and cited this session
  • No GitHub PR from a feature branch to main (SD-14 — only muse-mirrormain)
  • No redesign of R1–R9 from SEC-KN-4a/4b

4. Auto land procedure (SEC-KN-4c-b) — mechanical

  1. Start from current Muse/main tip (or rebase feat/sec-kn-4c-identity-migration onto it).
  2. Bring forward only:
    • hub/icp/src/hub/Migration.mo identity hook (4C-R1–R4)
    • scripts/verify-canister-migration.mjs (4C-R5)
    • SEC-KN-4 / SEC-KN-4c test assertion updates (4C-R6–R7)
    • docs/ROADMAP.md + docs/OVERSEER-HANDOVER.md (SD-17)
  3. Run seven-tier suite for the land + npm run canister:verify-migration + Motoko --check compile.
  4. Re-read live module hash (4C-R8). If match → no deploy.
  5. /build-verification-reviewpass before ROADMAP → DONE for 4c-b code land on the feature branch.
  6. Stop for Operator on Muse/main merge + muse-bridge + muse-mirror → GitHub main (Tier 3 / SD-14), unless SD-21 land-hygiene criteria are explicitly met for this diff (Motoko-only identity restore with no live posture flip qualifies for SD-21 path only when the Operator/session is in finish-mode land — still never git push origin main or feature→main).

Reference implementation already exists on Muse branch feat/sec-kn-4c-identity-migration @ sha256:57be6cf27cfc… (2026-07-28). Auto may cherry-pick / rebase that Motoko+script delta; it must still satisfy 4C-R6 (test flip was incomplete on that tip — unit test still expects TODO(SEC-KN-4c)).


5. Definition of Done

# Gate
D1 Freeze-review pass (this artifact) before Auto starts
D2 4C-R1–R7 implemented on feature branch; seven-tier green
D3 /build-verification-review pass
D4 Live module hash re-checked; redeploy skipped when hash matches frozen expected
D5 ROADMAP + OVERSEER-HANDOVER updated together; NEXT points past 4c-b
D6 Muse/main + GitHub main contain identity hook (via SD-14 mirror) — Operator land
D7 No secrets; no posture/env flips; F7 untouched

6. Ground-truth edge

SEC-KN-4c-b (Auto) may treat §§3–5 as ground truth and must not re-open the T1 one-shot design, re-derive principal binding (SEC-KN-4 R1–R9), or “improve” the identity shape. If land reveals the live hash diverges from 0x039360a0…, stop for Operator — do not redeploy from Auto.


7. Residual / also open (not blockers for 4c-b)

Item Status
Operator probe of proposal created_by on a live record UNVERIFIED — optional
P6 MCP / SESSION_SECRET share exploitability UNVERIFIED
MuseHub F7 AWS-parked

8. Paste-ready Auto prompt (after freeze pass)

Step: SEC-KN-4c-b
Model: Auto
Authority: knowtation
Branch: feat/sec-kn-4c-identity-migration (rebase onto current Muse main) or fresh feat/sec-kn-4c-land

Implement docs/SEC-KN-4C-MIGRATION-HOOK-RESTORE-FREEZE.md (4C-R1–R9) exactly.
Land identity Migration.migration on StableStorage + verify-script + SEC-KN-4 test flips.
Live module hash expected: 0x039360a0985c79e2ec993e0d0b81dc6e6b85e4d924c1123f5d1af26cdfd69bae — do NOT redeploy if it matches.
Seven-tier green; canister:verify-migration exit 0; Motoko dfx build --check hub.
/build-verification-review → pass before DONE.
Keep F7 AWS-parked. P6 share UNVERIFIED. No posture/env flips.
Muse main / muse-mirror = Tier 3 stop (or SD-21 land hygiene only if criteria met).
File History 1 commit
sha256:700fafdd1afa490919f9515d660ca6e75456bcd5bb67513abcd8757a634c01f6 docs: record AIP-b SD-21 land (KN #308) Human 9 days ago