Skip to content

ID-68 — Repo visibility and IP separation: PRODUCT

ID-68 — Repo visibility and IP separation: PRODUCT

Section titled “ID-68 — Repo visibility and IP separation: PRODUCT”

{68.2} PRODUCT artefact — authored after the S301a-7 reframe (ID-68 originally ran RESEARCH→TECH directly, ID-54 precedent; that skip is now superseded). This document pins the product invariants of the corrected model so that TECH ({68.3}) and PLAN ({68.4}) can be revised against a stable acceptance contract.

  • Task: ID-68 “Repo visibility and IP separation — private→public readiness”
  • Authored: S301a (05/06/2026).
  • Status: RATIFIED (Liam review, S317 05/06/2026 — “agreed in principle”; OQ resolutions recorded in §Open questions; ID-83 impact + ID-9.20/9.21 coordination added to Invariant 40 / Invariant 42 / §Revision directives).
  • Δ late-S301a-8 (post-authoring, same session): three facts moved after this spec was drafted — see the inline Δ markers: Invariant 4 (docs-site sync retired + build green), Invariant 21 (.planning/ + count-strip now done; docs/generated/ still pending), and the PLAN sequencing constraint (the held deletions LANDED on canonical-pipeline-setup, 9b1e5aaf, Liam-directed). No invariant contracts changed — only their current-state annotations.
  • Canonical spine: TARGET-STATE-ARCHITECTURE.md (S301a-7) — the corrected topology.
  • Doc-class model: DOC-LIFECYCLE-DESIGN.md (S301a-8) — referenced, not duplicated.
  • Integrated: PRE-FLIP-DEID-PLAN.md ({68.13}, ratified S301a) — still valid for de-ID of genuine client content; its §4 D3 routing is subsumed (see §Supersession).

Make ai-solution-hub/knowledge-hub safe to flip PRIVATE→PUBLIC without leaking client identity or proprietary IP, under the corrected four-tier model: a public code repo, a private docs-site repo holding ALL documentation and the JSON ledgers, a cold-storage archive repo, and external (never-in-git) client-corpus ingestion. Public ≠ open-source — visibility changes; IP retention does not.

The prior ID-68 corpus conflated two private destinations: the ID-9 docs-site (private, dev-team-only, holds ALL docs) and a separate “private repo” invented purely as the public-flip leak gate. The conflation crystallised at S301 (OQ-R12, Option S-B) and produced a wrong 3-repo topology, a per-space routing matrix, cross-repo bridges, and a large de-ID burden over docs that were never going public anyway. S301a-7 corrected the model (TARGET-STATE-ARCHITECTURE.md §1): 2 git repos + cold-storage + external ingestion. Most of the sanitisation workstreams collapse; what remains is de-ID of genuine client content on the public tier, the bridge, guard-CI, and the history purge. This PRODUCT is authored post-correction to fix the invariants before TECH/PLAN revision.

Code-intelligence orientation: not applicable — repo-governance/doc-lifecycle scope, no application symbols specified for modification (per the legacy TECH’s verified greenfield finding; the grounding corpus is the two S301a design documents above).


Invariants are numbered continuously and individually testable. “Public clone” means a fresh git clone of ai-solution-hub/knowledge-hub with no private checkout and no bridge knob set.

A. Topology and privacy boundaries per tier

Section titled “A. Topology and privacy boundaries per tier”
  1. The platform’s repository topology is exactly four tiers:

    TierLocationHoldsPrivacy
    PUBLIC codeai-solution-hub/knowledge-hubApp code; eval harness code + operators; synthetic fixtures; metric baselines; CI gate files; minimal docs floor (Group C)public
    PRIVATE docs-siteknowledge-hub-docs-siteALL documentation (doc-classes 1+2) + JSON ledgers + the Astro Starlight site (gated Vercel) + the 2 bid-prose eval fixturesprivate (dev team only)
    COLD-STORAGEknowledge-hub-archive.planning/.archive/ content; docs/workflow-evaluation/ corpus; pruned continuation-prompt historyprivate, un-indexed by default
    EXTERNAL ingestionlocal-fs (dev) → /corpus mount / client file server (prod)The real client corpus; any real client documentsnever in git
  2. Public ≠ open-source. The visibility flip confers no licence: the public repo carries no OSI-approved open-source licence file, and no licence grant is added as part of ID-68. IP (code, ontology, process) remains retained.

  3. knowledge-hub-docs-site is the single private home for documentation and ledgers. Access is dev-team-only (Liam + Claude); its Vercel deployment is gated. No documentation space is split between repos at end-state (interim duplication only per Invariant 23).

  4. All relocated documentation content is git-tracked in the docs-site repo (the §0.1 stranding risk — content copied into a gitignored build-output path — is resolved). A clean clone of the docs-site repo contains the full docs corpus without reference to the public repo. (Δ Ratified + executed S301a-8: src/content/docs/ is the tracked canonical source — f9c92ba2; sync model retired + corpus frontmatter-normalised + build green 617 pages — 1ad3e1cf; repo renamed knowledge-hub-docs-site + pushed. The docs-site→repo-root move remains pending, entangled with the Invariant 7 eval-lane split.)

  5. knowledge-hub-archive is indexed by nothing by default: the canonical gitnexus and ccc indexes contain zero nodes from archive content. A separate, opt-in index over the archive repo is permitted (point-in-time, possibly-stale, on-demand). The vestigial .graphifyignore is deleted (it is not consumed by gitnexus).

  6. The real client corpus is never tracked by any git repo in the topology. The ingestion pipeline reads from the external location only (ID-69, already ratified and shipped). In-repo test inputs are synthetic — with one accepted exception: the ITT/procurement test templates that are public downloads, not client-specific, stay public as-is (OQ-2 resolution).

  7. Eval lane split — CODE public, DATA split:

    • Public: lib/eval/*; the 5 scripts/eval-*.ts runners; the 4 operators; eval-baselines/*.json (metrics-only); search-evaluation.json + search.baseline.json; the classification and entity gold-standards after a placeholder name-swap (Invariant 33).
    • Private (docs-site repo): the summarisation and procurement-drafting gold-standards (verbatim client bid prose; OQ-1 resolution — synthesise public equivalents later only if public CI ever needs them).
    • Mechanism: fixture-path indirection via an env knob, so the public runners load synthetic-public or real-private fixtures by environment. The indirection must not reintroduce a routing matrix (Invariant 27); both suites remain EVAL_*=1-gated out of PR CI.
  8. Cutover, not big-bang: no live mechanism (ledger writes, doc reads, deploys) flips until its replacement is integrated and tested. The canonical track continues on ledger-cli, single-repo, until the ID-20 patch-server cutover.

Acceptance — Group A

  • AC-A1: gh repo view reports knowledge-hub-docs-site and knowledge-hub-archive as private; ai-solution-hub/knowledge-hub public only after Group F gates pass.
  • AC-A2: public clone contains no OSI-approved licence file.
  • AC-A3: git ls-files in the docs-site repo returns the documentation corpus for every space (not only index.md placeholders).
  • AC-A4: the canonical gitnexus/ccc indexes return zero results for archive-repo paths.
  • AC-A5: public clone git ls-files returns zero rows for client-corpus paths; every in-repo test input is synthetic or on the accepted public-tender list.
  • AC-A6: public clone holds the 2 name-swapped gold-standards and zero rows for the summarisation/procurement-drafting gold-standards; the docs-site repo holds the latter.
  1. The seven-class taxonomy of DOC-LIFECYCLE-DESIGN.md §3 is normative for every artefact the SDLC produces. Every artefact has a class assigned at birth by the producing skill/template; nothing lands in a generic folder. (Reference: the full class and folder-disposition tables live in DOC-LIFECYCLE-DESIGN.md §3/§4 — they are not duplicated here.)

  2. Docs-site spaces = Class 1 + Class 2 only: reference/ runbooks/ product-functionality/ ontology/ design/ themes/ handover-guides/ specs/ (plus the scaffolded decisions/ pending OQ-D). Class 3/4/5/6/7 content is never site content.

  3. Class 2 (task-lifecycle specs): the spec chain per ID-N is frozen at task close and kept forever in the docs-site specs/ space (ratified S301a-8). Only legacy pre-ID-convention dirs are bulk-archive candidates. The freestanding docs/research/ folder dissolves: future research is the {N.1} RESEARCH.md in the task spec dir.

  4. Class 3 (session-transfer artefacts) is never canonical. The spec-dir CONTINUATION pattern is explicitly not the session-transfer model (ratified S301a-8 — an ID-68-interim expedient, not a precedent). Interim: continuation prompts and cmux-briefs stay where they are; cmux-briefs consolidate to one home. The scripted Class-3 design is deferred to the wider workflow review (OQ-B) — this Task must not pre-empt it.

  5. Class 4 (point-in-time evidence) archives on the decision-captured trigger — a ledger reference exists — not on age. Archive home is knowledge-hub-archive.

  6. Class 5 (ledgers + mirrors): task-list/backlog/roadmap/retros JSON and their mirrors are structured state, homed in the private docs-site repo, written via the ID-20 patch-server substrate. Rationale (upheld): ledgers carry the same product-strategy/reconnaissance sensitivity as the docs spaces — e.g. a backlog item naming an unfixed vulnerability — so they are private, not sanitised-public.

  7. Class 6 (generated/derived) is never canonical: deleted from docs/ (Invariant 21); CI baselines live as root dotfiles.

  8. Class 7 (docs/testing/test-data/ templates) are platform-functionality fixtures — simulated client-file-server content — not an IP question. Disposition is owned by the ID-80.2 forms-architecture re-scope, not this Task.

Acceptance — Group B

  • AC-B1: the docs-site space list equals the Invariant 10 set; no continuation-prompts / audits / workflow-evaluation / generated / test-data space exists on the site.
  • AC-B2: a closed task’s spec dir (spot-check: ID-68 itself) remains in the docs-site specs/ space after close.
  • AC-B3: no new files land under a freestanding docs/research/; new research artefacts appear as …/ID-N-<slug>/RESEARCH.md.
  • AC-B4: spot-checked Class-4 docs in the archive each carry a ledger reference.

C. Public-repo minimal docs floor and content hygiene

Section titled “C. Public-repo minimal docs floor and content hygiene”
  1. Floor rule (ratified S301a-8): a file stays in the public repo only if something reads it from the repo at runtime — the agent harness or CI. Everything else moves private; agent sessions get documentation context via the bridge (Group D); CI executes code, not prose.

  2. The harness floor is exactly: README.md (GitHub landing), AGENTS.md, CLAUDE.md, .claude/** (skills/hooks/checks), .gitnexus/CLAUDE.md, .ast-dataflow/CLAUDE.md.

  3. The CI floor is the gate inputs: .knip-baseline.json, .type-drift-baseline.json (renamed with dot-prefix and moved to repo root from docs/generated/), reference-doc-paths.json. Any test or harness pointer that asserts on docs/ paths (doc-freshness.test.ts, fixture-sync guards, CLAUDE.md doc references) is reworked at cutover to target the bridge or move private — the relocation sweep’s job (Invariant 40). Post-cutover, the public repo contains no dangling references to removed docs/ paths.

  4. No CONTRIBUTING.md (ratified S301a-8 — public ≠ soliciting contribution).

  5. Generated artefacts are deleted from public: docs/generated/codebase-stats.{md,json}, mcp-inventory.{md,json}, their generator scripts, and their docs-site sync entries. Live gitnexus counts are stripped from the committed <\!-- gitnexus:start --> block (config flag preferred; static line as fallback). docs/generated/ and .planning/ are absent from public HEAD. (Δ S301a-8: .planning/ removal + the count-strip landed — 9b1e5aaf; docs/generated/ deletion + the .type-drift-baseline.json root move remain open.)

  6. scripts/ hygiene: scripts/run-1m-context.ts and scripts/wf-export.py (zero KH coupling, copied from bid-manager) are deleted.

  7. Interim duplication: docs/specs/ + docs/themes/ may remain duplicated in the public-candidate repo only until the bridge is proven and the ID-20 cutover lands. They are absent from public HEAD at flip time.

  8. A sanitised ontology subset remains public only if code or tests read ontology docs (OQ-E — the relocation sweep answers). If present, it satisfies Group E and preserves the client-customisation seam as a forward design note.

Acceptance — Group C

  • AC-C1: post-cutover, public clone git ls-files 'docs/**' returns zero rows (sole permitted exception: the OQ-E ontology subset, if ratified in).
  • AC-C2: floor files (Invariants 18–19) present; CONTRIBUTING.md absent.
  • AC-C3: bun run test, bun build, and PR-blocking CI pass on a public clone with no private checkout and no bridge knob set.
  • AC-C4: zero git ls-files matches for the Invariant 21/22 deletion set; .type-drift-baseline.json exists at repo root.
  • AC-C5: a link/path sweep over README/AGENTS/CLAUDE/.claude/** finds zero references to removed docs/ paths.
  1. There is exactly one standing bridge knob: KH_PRIVATE_DOCS_DIR (renamed from KH_DOCS_DIR). It names the local checkout of knowledge-hub-docs-site, resolved from the public repo. Read direction is public→private only.

  2. The rename is complete: zero KH_DOCS_DIR consumers remain anywhere in the public repo.

  3. The per-space routing matrix and KH_PUBLIC_REPO_DIR are retired. Single exception: the docubot code→docs sync lane, where docubot (operating from the private repo) genuinely resolves the public code checkout — KH_PUBLIC_REPO_DIR survives only there.

  4. Resolution: in local/dev contexts the knob points at a sibling checkout; in CI the private checkout is materialised via a GitHub-App installation token before consumers run. Either way, consumers see one directory path — they do not implement their own resolution.

  5. Failure behaviour when the knob is unset or unresolvable: any consumer that requires private docs fails loudly with an actionable error naming KH_PRIVATE_DOCS_DIR and the expected resolution (sibling checkout / App token). No silent fallback to stale duplicated public copies; no partial output.

  6. Public-repo self-sufficiency: nothing in the public repo’s build, unit tests, or PR-blocking CI requires the knob. Bridge-dependent consumers are opt-in lanes only.

Acceptance — Group D

  • AC-D1: grep -r 'KH_DOCS_DIR' over the public repo returns zero matches; KH_PRIVATE_DOCS_DIR consumers are the documented bridge lanes only.
  • AC-D2: grep -r 'KH_PUBLIC_REPO_DIR' matches only the docubot sync lane.
  • AC-D3: invoking a bridge consumer with the knob unset exits non-zero and names the knob in its error output.
  • AC-D4: AC-C3 (CI green with no knob) doubles as the self-sufficiency check.
  1. The genuine-client identity set (normative; case-insensitive unless stated):

    ItemExamples in tree/history
    Client-name stem phew + derived identifiersphew.json, public/clients/phew/*, capture_phew_domain_hook, export-phew-articles.ts, phew.org.uk, support@phew.org.uk, kh.phew.org.uk
    Legal name Phew Design Limitedmigration 20260419212103_*.sql:48 seeded row; historical docs
    Verbatim client bid proseclassification worked-examples; the 4 eval gold-standards’ source content (ISO 27001, CREST, DBS, employee counts, client lists)
    Datacentre literal telehousehardcoded in eval-holder-rule-ts.ts
    Real ICO numberplaceholder’d at HEAD (S301a 83525b84); survives in history until purge

    Carve-out (permitted residuals): parameterised-mechanism config keys (default config, slug examples) and intentionally generic placeholders.

  2. Public HEAD is clean: a public clone greps zero identity-set matches outside the carve-out.

  3. Itemised closures (per PRE-FLIP-DEID-PLAN.md, still valid):

    • Alib/branding/clients/phew.json + public/clients/phew/* untracked; the static import/map entry removed so the bundle ships { default } only; real branding supplied at deploy time via a private overlay (live-tenant item, Invariant 39).
    • B — the signup-domain auth hook genericised via a new migration (append-only history; generic function name; domain from config), config.toml repointed; staging-tested before the live cutover (live-tenant item, Invariant 39). The B2 seeded client-name row: OQ-G.
    • Cdocs/reference/classification-prompt.md (real bid prose at L194–758) leaves the public surface via kb_pipeline retirement (verified: canonical cocoindex_pipeline does not read it), or is relocated+repointed if the flip must precede retirement. The flip gates on one of the two (live-tenant item, Invariant 39).
    • Eval dataclassification + entity gold-standards name-swapped to placeholders; the 'telehouse' literal in eval-holder-rule-ts.ts parameterised; the 2 bid-prose gold-standards moved private (Invariant 7).
    • Fkh.phew.org.uk genericised in public source: the production domain becomes per-deploy config (APP_URL), with an explicit residual sweep covering at minimum deploy/coolify/docker-compose.production.yaml:69, the 7 scripts/tests/*.py webhook URLs, and the CLAUDE.md production-URL line.
  4. Session-start awareness of the current live domain is preserved via a private/local location (e.g. gitignored .env.local surfaced by start-session) — never a public reference.

  5. History purge ({68.10}) scope: both path-removal (--invert-paths over the AC2 inventory + relocated docs/** + .planning/** + docs-site/**) and content redaction (--replace-text over the Invariant 31 identity set), applied across all history on a fresh mirror. Mandatory first action: a pre-purge mirror backup (tagged pre-id68-purge) — the only safety net. A verification clone proves zero residual matches before force-push. Irreversible; runs last; explicit Liam GO required.

  6. Public-visibility precondition: at the instant the repo becomes public, no commit reachable from any ref contains identity-set matches outside the carve-out — history is clean before exposure, not after.

  7. Re-introduction guards: guard-CI runs as a required branch-protection check on the public repo, rejecting identity-set re-introductions at HEAD. The ledger client-name write guard ({68.13}) ports into the ID-20 patch-server substrate as a write-time gate (ID-20 boundary).

Acceptance — Group E

  • AC-E1: public clone: git grep -i 'phew' and git grep -i 'telehouse' return only carve-out matches (target: zero for telehouse).
  • AC-E2: post-purge verification clone: git log --all -S (or filter-repo --analyze) shows zero blobs matching any redaction-map entry across all refs.
  • AC-E3: git ls-files zero rows for lib/branding/clients/phew.json, public/clients/phew/**; the deploy-overlay supplies branding on the client deploy (deployed site still branded).
  • AC-E4: the migration list contains the generic-named superseding hook migration; config.toml references no client-named hook; staging signup gate verified working.
  • AC-E5: a pre-purge mirror backup exists and is recorded before {68.10} executes.
  • AC-E6: guard-CI appears in the public repo’s required status checks.
  1. The visibility flip ({68.9}) is HELD until all of the following hold (the re-derived target-state §6 set, plus the carried-forward {68.9} gates):

    #GateVerifiable by
    1Docs + ledgers moved to the private docs-site repo (no sanitisation — private)AC-A3, AC-C1
    2Ledgers private via the ID-20 patch-server cutover — the flip waits for ID-20 (OQ-3 = A)ID-20 cutover recorded done
    3Genuine client content out of public HEAD and historyAC-E1, AC-E2
    4guard-CI required branch-protection check liveAC-E6
    5History purge {68.10} executed over the genuine-client set + relocated docsAC-E2, AC-E5
    6Archive + workflow-evaluation corpus cold-storagedAC-A4
    7Relocation sweep re-run against current canonical HEAD (Invariant 40)sweep report cites current HEAD SHA
    8Dependabot high-severity gate re-verified live = 0 open (state drifts)gh api …/dependabot/alerts count = 0
    9Explicit Liam GO (outward-facing action)recorded in the ledger journal
  2. The 3 live-tenant items exist as tracked ID-68 subtasks before flip-readiness is assessable: (i) the B signup-domain migration cutover on the live tenant; (ii) the A branding deploy-overlay wired into the client deploy; (iii) the C kb_pipeline/classification-prompt retirement-or-relocation.

  3. Gate 7 substance: the original relocation analysis was performed on a branch forked 38 commits behind canonical — before deploy/, datapath-watch, /walk, and scripts/cocoindex_pipeline/ existed. The sweep re-runs the leak/reference analysis against current canonical HEAD; its findings extend the de-ID set (Group E) and the pointer-rework list (Invariant 19). The sweep explicitly covers ID-83’s landed changes (S316, done): the boot-decoupled cocoindex worker, the bearer-gated POST /walk route, the realigned compose files + onprem-deploy workflow, and the rewritten burn-prevention runbook + Coolify scheduled-task stand-up doc — verified S317 still carrying identity refs (deploy/coolify/docker-compose.production.yaml:69 comment; 5 scripts/tests/*.py files).

Acceptance — Group F

  • AC-F1: every gate row in Invariant 38 has its named verification artefact recorded before {68.9} executes; the ledger shows the Invariant 39 subtasks as tracked.
  • AC-F2: no flip occurs while any gate is open (Checker verifies ordering from the ledger journal).
  1. The following are collapsed by the corrected model and must not reappear in the revised TECH/PLAN:

    Collapsed workstreamWhy
    A third repo as a distinct docs destinationThe docs-site is the private repo
    The per-space routing matrixOne bridge knob (Invariant 25)
    De-ID/sanitisation of reference/runbooks/product-functionality/specsPrivate — never public, no de-ID needed
    Ledger sanitisation-for-publicLedgers are private (Invariant 14)
    The bolted-on internal-repo harnessPrivate repo is repurposed as the docs-site home (OQ-5)
    KH_PUBLIC_REPO_DIR retro write-backRetired except the docubot lane (Invariant 27)
  2. Cross-task boundaries — this Task references, but does not own:

    BoundaryOwned by
    Ledger patch-server substrate (design, write-time gates port, cutover)ID-20 — separate sub-track, own spec chain, parallel cmux; ID-68 consumes its cutover as Gate 2
    External client-corpus ingestionID-69 — ratified + shipped; ID-68 inherits only “never in git”
    docs/testing/test-data/ template dispositionID-80.2 forms-architecture re-scope
    Class-3 scripted-artefact design (handoff/cmux-brief mechanisation)The wider workflow review (OQ-B); emeraldwalk task-tracking prior art, task-view substrate
    Warp WARP.md/CLAUDE.md comparisonSeparate task (Liam, Part-1 feedback)
    Docs-site IA/build standup (Astro→root, Vercel repoint, harness strip)ID-9 lineage, constrained here only by Invariant 4 (content tracked)
    docubot decommission gates: Session A verification (3 sample docs-PRs) + Session B atomic update-docs removal incl. the CLAUDE.md atomic editID-9.20 / ID-9.21 — ID-68’s Invariant 19 pointer rework and Invariant 21 deletion set MUST sequence against these (see §Revision directives)

Acceptance — Group G

  • AC-G1: the revised TECH/PLAN contain no work items from the Invariant 41 table and express every Invariant 42 boundary as a Task-level dependency or explicit reference, never as in-scope work.

Ratification pass (Liam, S317) — per-OQ dispositions below. Remaining-open items must not be resolved in TECH/PLAN without ratification.

  • OQ-A (ID-80.2): OPEN, boundary unchanged — test-data fixture home + forms-architecture re-scope owned by ID-80.2 (DOC-LIFECYCLE-DESIGN.md §8).
  • OQ-B (workflow review): SCOPE NARROWED (ratified S317) — interest in the emeraldwalk prior art is only the three “equivalent KH move” items (DOC-LIFECYCLE-DESIGN.md §7): (i) session-transfer state as commands over the ledger substrate (task-view patch server, ID-20); (ii) handoff as scripted state transition + generated summary; (iii) cmux-briefs template-generated from the dispatch record. Explicitly no interest in run_task_loop.sh, the next/claim cycle, or the mock-agent harness. Driving goal: make session mechanics programmatic where possible to cut unnecessary token overhead. Design remains deferred to the workflow review + ID-20 co-scope.
  • OQ-C: RESOLVED (ratified S317) — archive-sweep mechanics for Class 4 belong to the workflow review (§7); no manual-cadence mechanism is designed inside ID-68.
  • OQ-D: RESOLVED (ratified S317) — the decisions/ ADR scaffold is dropped; decision capture stays in the retros ledger (product-retros.json). In its place, adopt changelog functionality (Warp model): PR-template changelog entries with prefixes CHANGELOG-NEW-FEATURE: (sizable features, sparing), CHANGELOG-IMPROVEMENT: (new functionality on existing features), CHANGELOG-BUG-FIX: (known bugs/regressions), CHANGELOG-IMAGE: (hosted image URLs), with lines left blank/removed when no entry is needed; CLAUDE.md guidance to match. Ownership: workflow review co-scope (process change, not an ID-68 work item).
  • OQ-E: OPEN — sanitised-ontology subset for public; the relocation sweep (Invariant 40) answers (§8).
  • OQ-G (auth-hook residue): PARTIALLY CLOSED (state verified S317) — the generic config-driven hook migration already exists at HEAD (20260603121652_hook_restrict_signup_to_allowed_domain.sql: additive-only, fail-closed on unset app.allowed_signup_domain GUC, no domain literal). Still open: (a) the live-wiring cutoverconfig.toml still references hook_restrict_signup_to_phew_domain (line ~78); repoint + drop the superseded client-named function + set the per-deploy GUC = the Invariant 39 item (i) live-tenant subtask, deliberately gated on staging verification; (b) disposition of the 20260419212103 seeded legal-name row (supersede via follow-up migration vs accept-as-data + rely on history redaction) — still open.
  • OQ-H (redaction map): OPEN (TBD, Liam) — the final --replace-text map contents; whether HEAD-scrub-only is acceptable for any low-sensitivity strings (PRE-FLIP-DEID-PLAN §2 E).

(Resolved during authoring: the former OQ-F — docs-site source of truth — was ratified and executed S301a-8: src/content/docs/ is the tracked canonical source; see Invariant 4.)

This PRODUCT supersedes the legacy TECH.md header note that {68.2} was “deliberately skipped (ID-54 precedent)” — the acceptance contract now lives here, not inline in TECH §Context.

Already superseded (per the TARGET-STATE-ARCHITECTURE.md header — topology + routing): RELOCATION-INVESTIGATION.md, RELOCATION-INVESTIGATION-V2.md, RELOCATION-IMPLEMENTATION-PLAN.md (Option S-B), DEPLOY-OVERLAY-DESIGN.md (its topology; the deploy-inject branding mechanism survives as Invariant 33-A’s mechanism), DOCS-RELOCATION-SUBTASK.md. RESEARCH.md is historical — reframed by TARGET-STATE-ARCHITECTURE.md (§8).

Integrated with amendment: PRE-FLIP-DEID-PLAN.md remains valid for items A, B, C, E, F. Its §4 D3 routing is subsumed by the corrected topology — specs AND ledgers are both private now (no ledger sanitise-in-public lane); the {68.13} ledger client-name guard survives, ported into the ID-20 substrate (Invariant 37).

Revision directives:

  • TECH ({68.3} revision, fresh Planner): repo-split mechanics; the KH_PRIVATE_DOCS_DIR rename + resolution; docubot repoint; cold-storage finalisation; the public de-ID set (Group E); the history purge design; the Group C floor + pointer rework. One proposed change per invariant above.
  • ID-9.19/9.20/9.21 sequencing (added at ratification, S317): ci.yml’s regenerate-stats job (ID-9.19, live at ci.yml:1245) regenerates exactly the docs/generated/ artefacts Invariant 21 deletes, and ID-9.21’s acceptance asserts that job runs (Session B: update-docs removal + CLAUDE.md atomic edit). TECH must sequence: ID-9.20 (deps done — dispatchable) and ID-9.21 complete first under the current model, THEN the Invariant 21 deletion executes with the regenerate-stats job removal + generator-script deletion + package.json script cleanup folded into the same change — or ID-9.21’s acceptance is formally amended. The CLAUDE.md atomic edit (ID-9.21) and the Invariant 19 pointer rework touch the same file: coordinate, do not interleave.
  • PLAN ({68.4} revision): re-decompose against the smaller scope; drop every Invariant 41 workstream; open the Invariant 39 live-tenant subtasks; sibling-only dependencies; {68.10} stays last and irreversible.
  • Sequencing constraint for PLAN (Δ superseded S301a-8): the held migration deletions LANDED on canonical-pipeline-setup (9b1e5aaf, Liam-directed — the branch had no other active work, both destination repos were verified committed first, and the CI dangler was removed in the same commit). PLAN should treat the docs-site/.planning relocation as DONE ({68.12} partial — the docs/ spaces themselves remain, pending the doc-lifecycle relocation set) rather than re-planning it.