ID-68 — Repo visibility and IP separation: private→public readiness
ID-68 — Repo visibility and IP separation: private→public readiness
Section titled “ID-68 — Repo visibility and IP separation: private→public readiness”{68.1} RESEARCH artefact. This is the investigation phase of the spec-driven
lifecycle: it scopes the problem, records current-state findings, lays out
options with trade-offs, and surfaces decisions for Liam. It is not an
implementation plan. Liam ratifies this before PRODUCT ({68.2}) / TECH
({68.3}) / PLAN ({68.4}).
- Task: ID-68 “Repo visibility and IP separation — private→public readiness”
- Roadmap theme: 12 “Repo visibility and IP separation” (time horizon: next)
- Provenance: Triggered in S288 during ID-66 on-prem Coolify setup by the ghcr package-public question; this Task is the broader repo-public question that the narrower ghcr decision deferred to.
- Authored: S289 (31/05/2026), main branch.
- Status: Draft, pending ratification.
1. Problem framing
Section titled “1. Problem framing”A public GitHub repo unlocks GitHub’s free security tooling for public repositories — Dependabot alerts, code scanning, and secret scanning — and the direction of travel aligns with the on-prem pivot (ID-66), where the build artefact (the ghcr cocoindex image) is already public. The pull toward public is real and has a concrete security payoff.
The blocker is equally real: the repository currently contains pre-launch
client-specific documentation and proprietary process/IP artefacts that must
remain protected. The hard constraint from theme 12 is unchanged — client
documentation and IP must remain protected. The question this Task answers is
not “should we go public” in the abstract, but: what must be excluded,
relocated, scrubbed, or accepted before the knowledge-hub repository can be
made public without leaking client documentation or IP, and is the supporting
machinery (docs-site, security features) ready to make that worthwhile.
A second framing nuance discovered this session: a meaningful slice of the
“leak” is already public via the ghcr cocoindex image (which ships scripts/
verbatim — see §4.1). So part of this Task is reactive cleanup of an existing
exposure, not purely prevention of a future one.
gitnexus orientation: no existing symbols match — greenfield surface
(this is a repo-governance / publication-readiness Task, not a code feature;
the relevant artefacts are build config, tracked files, and GitHub settings,
not application symbols. The two gitnexus-flagged symbols
scripts/export-phew-articles.ts and scripts/split_phew_site_content.py are
incidental client-named scripts, catalogued in §4.)
The five investigation areas (theme 12)
Section titled “The five investigation areas (theme 12)”- What must be excluded or relocated before the repo goes public — client
docs,
.planning/**, other IP, the client-name leak inscripts/. (§4) - Whether the ID-9 Astro docs-site is the right mechanism to host public-facing docs separately from the code repo. (§6)
- Disposition of
.planning/**— retire, archive externally, or retain private. (§5) - GitHub security-feature gains post-publication (Dependabot, code scanning, secret scanning; the repo currently has open Dependabot vulns). (§7)
- Container image visibility policy (ghcr
kh-cocoindex-pipeline, already public). (§8)
2. Method and scope of this investigation
Section titled “2. Method and scope of this investigation”All findings below were derived from the repository at HEAD on the main
branch (commit 075bd282) on 31/05/2026:
git ls-files/git grepover the tracked tree (untracked / gitignored content is out of scope — it never ships).ghAPI queries for repo visibility, Dependabot alert counts, and ghcr package visibility (live, 31/05/2026).- Direct reads of
deploy/onprem/docker-compose.yml,.github/workflows/onprem-deploy.yml,lib/client-config.ts,docs-site/astro.config.mjs, and.gitignore.
Scope boundary. This RESEARCH scopes and recommends; it does not
execute. The actual scrub, relocation, and the GitHub flip belong to
{68.4+} implementation Subtasks after ratification. The dedicated scrub
session (client-name parameterisation, catalogue-script relocation) is planned
for a later session and folds into this Task’s PLAN.
3. Current-state baseline (verified S289)
Section titled “3. Current-state baseline (verified S289)”| Fact | Value | Source |
|---|---|---|
| Repo visibility | PRIVATE | gh repo view ai-solution-hub/knowledge-hub |
| Total tracked files | 5,094 | git ls-files |
ghcr kh-cocoindex-pipeline visibility | PUBLIC | gh api .../packages/container |
| Open Dependabot alerts | 23 (8 high / 11 medium / 4 low) | gh api .../dependabot/alerts |
.planning/ | git-TRACKED, 36 MB, 1,269 files | git ls-files .planning/ |
docs/client-documentation-corpus/ | git-TRACKED, 33 files | git ls-files |
| docs-site (ID-9) | BUILT + committed, NOT deployed | docs-site/astro.config.mjs:30 |
Correction to the S288/S289 brief. The brief cited “3 open Dependabot vulns (2 moderate, 1 low)”. The live count on the default branch is 23 open alerts (8 high, 11 medium, 4 low). The “3” was likely a stale or filtered figure. Whichever is canonical, the directional point holds: publication turns these alerts on for free and there is open vulnerability debt to clear (see §7). PRODUCT should re-pull the live count at the time of the go decision.
4. Area 1 — What must be excluded, relocated, scrubbed, or accepted
Section titled “4. Area 1 — What must be excluded, relocated, scrubbed, or accepted”This is the core of the investigation. The exposure splits into two distinct risk channels with different urgency, because of how the ghcr image is built.
4.1 The ghcr image ships only a pruned scripts/ tree — not the whole repo
Section titled “4.1 The ghcr image ships only a pruned scripts/ tree — not the whole repo”This is the single most important finding for prioritisation, and it corrects
the working assumption in the S289 brief (“the ghcr image bundles all of
scripts/ verbatim”).
.github/workflows/onprem-deploy.yml builds the cocoindex image from an
explicitly pruned build context, not the repo root:
CTX="$(mktemp -d)"cp -R scripts "${CTX}/scripts"cp requirements.txt "${CTX}/requirements.txt"pack build "${IMAGE}:${TAG}" --path "${CTX}" ...The workflow comment is explicit about why: pack does not reliably honour
.gcloudignore / project.toml excludes (a whitelist attempt leaked .claude,
docs-site, __tests__ into /workspace), so the build copies only
scripts/ + requirements.txt into a temp dir and builds from there. The
asserted post-condition is ls /workspace → scripts requirements.txt only.
Consequence — two risk channels:
- Channel A (already public, via the image). Everything under
scripts/(all.pyand.ts) is already shipped in the public ghcr image, verbatim. Anyone who pullsghcr.io/ai-solution-hub/kh-cocoindex-pipelinecan extract it. The client-name leak inscripts/(§4.2) is therefore already exposed, independent of the repo flip. This makes thescripts/scrub reactive cleanup, not future prevention. - Channel B (exposed only if the repo goes public). Everything outside
scripts/—docs/,.planning/,lib/,app/, fixtures, the client corpus — is not in the image and is exposed only by the repo flip. This is the higher-severity, still-private content (§4.3), and it is the real gate on going public.
A go-public decision must clear both channels, but they are scoped and sequenced differently: Channel A can be cleaned at leisure (the horse has bolted; cleanup limits future image builds and is good hygiene); Channel B is the hard pre-condition.
4.2 Channel A — client-identity leak in scripts/ (already public)
Section titled “4.2 Channel A — client-identity leak in scripts/ (already public)”“phew” (case-insensitive) appears in 602 tracked files repo-wide; the
scripts/-only subset (the part already in the public image) includes:
scripts/eval-holder-rule-ts.ts:100—const CLIENT_ORG_LOWER = 'phew design limited';plus named third-party content: “Telehouse” certs and the disclaimer text “…held by Telehouse, not Phew Design Ltd” (lines 528–557).scripts/seed-phew-guides.ts— header “Seed script for Phew Design guide definitions.”scripts/catalogue-charnwood-itt.ts— “Catalogue Charnwood Borough Council ITT Services requirements. Inserts 30 requirements…” (named third-party tender content; a public-tender PPN-style ITT, but still a named council).scripts/restore-eval-corrupted-items.ts,scripts/reclassify-items.ts,scripts/export-phew-articles.ts,scripts/split_phew_site_content.py,scripts/kb_pipeline/classify.py,scripts/keyword_classifier.py, and ~20 morescripts/files referencing the client name or eval fixtures.
No live credentials/keys/JWTs are leaked. Verified: no sk-ant-api03…,
AKIA…, or BEGIN … PRIVATE KEY in non-test, non-.planning tracked files;
the compose file uses only ${VAR} refs (Coolify injects secrets at deploy);
Supabase project-refs are public DNS subdomains that identify but do not
authenticate a project, and the prod ref rovrymhhffssilaftdwd is already in
the committed CLAUDE.md.
Severity of Channel A. Low-to-moderate. The client name (“Phew Design Limited”) is Liam’s own organisation, and the Charnwood ITT is public-tender content (a published council ITT / PPN material). The Telehouse reference is a factual data-point about whose certifications apply, embedded in an eval rubric. Per Liam’s S289 decision, this is ACCEPTED for now and folded into this research; a dedicated scrub session is planned.
Mitigation lead (scrub-not-rewrite). The codebase already supports parameterising the client identity, so the scrub is mostly reading config instead of literals, not a rewrite:
lib/client-config.tsis a single-source client config. It already hardcodesentity_examples.organisation_name: 'Phew Design Limited'/organisation_short: 'Phew'/product_name: 'Phew Audit System'as the default config, and resolves per-client branding fromNEXT_PUBLIC_CLIENT_IDagainstCLIENT_BRANDING_MAP(default,phew).lib/branding/clients/phew.json+public/clients/phew/{logo,favicon}.*are the per-client assets — already separated fromdefault.json.NEXT_PUBLIC_CLIENT_IDis consumed bylib/client-config.ts,lib/env-client.ts, and several scripts (eval-holder-rule-ts.ts,reclassify-items.ts,restore-eval-corrupted-items.ts,wp-b-triage-report.ts).
So the scrub direction is: move literal client strings in scripts/ to read
from CLIENT_CONFIG / NEXT_PUBLIC_CLIENT_ID, and relocate the two
catalogue-*-itt.ts seed scripts out of the shipped tree (they are
historical one-shot seeds explicitly marked “Do not re-run”, carry named-council
ITT content, and have no reason to ship in the pipeline image). default.json
becomes the genuinely generic config; the phew.* files would move to a private
overlay (or stay, accepted, per the §9 decision).
4.3 Channel B — higher-severity content exposed only by the repo flip
Section titled “4.3 Channel B — higher-severity content exposed only by the repo flip”These are not in the ghcr image; they become public only if the repo flips. Counts are tracked-file counts at HEAD.
| Path | Tracked files | What it is | Severity |
|---|---|---|---|
docs/client-documentation-corpus/ | 33 | The ingest corpus: actual client bid-library markdown + binary-originals/ .docx, plus Telehouse-South-Fact-Sheet-2025.pdf (named third party), 04-named-clients-and-case-studies.md, 05-team-structure-and-key-people.md, company overview, brand voice. | HIGH |
docs/client-briefs/ | 8 | Product / sector-intelligence briefs, gap-analysis trackers, “Liam-Final” strategy docs. | HIGH |
docs/testing/test-data/templates/ | 9 | Real third-party tender documents: Charnwood ITT (.xls/.docx), British Council RFP set, EFA ITT vol8, SQ PPN-03-24, CSP checklist. | MODERATE (some are public-tender artefacts; British Council RFP may not be) |
docs/testing/uat/ | 6 | UAT scenarios referencing Charnwood ITT method statements. | MODERATE |
.planning/ | 1,269 | Process IP + historical specs/audits (see §5). | MODERATE–HIGH |
docs/themes/canonical-pipeline/ | 66 | Phase-0 investigation docs naming Telehouse/Phew/Charnwood. | LOW–MODERATE |
docs/audits/ | 28 | Classifier eval reports with Telehouse-attributed cert fixtures. | LOW–MODERATE |
The clearest hard blocker is docs/client-documentation-corpus/. This is
the ingest corpus itself — actual proprietary client documentation (a real bid
library, draft tender responses, named clients and case studies, team
structure, and a third party’s fact-sheet PDF). It directly violates the theme
12 hard constraint and must be excluded or relocated before any public flip.
There is no parameterisation story here (it is content, not config) — it must
leave the tracked public tree (git-rm + history scrub, or move to a private
sibling repo / private branch).
Note on git history. Excluding a file from the current tip does not remove it from history. For a public repo, sensitive content under
docs/client-documentation-corpus/,docs/client-briefs/, and the client-named test-data must be purged from history (e.g.git filter-repo), not just deleted at HEAD — otherwise it remains retrievable from the public commit graph. This is a non-trivial, one-way operation and is a first-class PLAN item, not an afterthought. (See OQ-68-5.)
4.4 Test fixtures and the app surface
Section titled “4.4 Test fixtures and the app surface”“phew”/“Telehouse” also appear in __tests__/fixtures/*-gold-standard.json,
__tests__/lib/ai/classify.test.ts, components/entity-management/ entity-detail-panel.tsx, and lib/ai/skills/classification.md /
lib/ai/skills/inlined.generated.ts. These are eval gold-standard fixtures and
classification prompt examples. Severity is low (the client name is Liam’s own
org), but they are in Channel B and would be part of a thorough scrub if the
decision is “scrub fully” rather than “accept the client-name presence”.
5. Area 3 — disposition of .planning/**
Section titled “5. Area 3 — disposition of .planning/**”5.1 What it is
Section titled “5.1 What it is”.planning/ is git-TRACKED (not gitignored), 36 MB, 1,269 files, in two
structurally distinct parts:
.planning/codebase/— 7 current architecture documents (ARCHITECTURE.md,CONCERNS.md,CONVENTIONS.md,INTEGRATIONS.md,STACK.md,STRUCTURE.md,TESTING.md). These are live and cited:CLAUDE.mdnames.planning/codebase/as the codebase map, and thewrite-tech-specskill points at.planning/codebase/STRUCTURE.md. Removing these degrades agent grounding immediately..planning/.archive/— the large historical store:.specs/(~324 entries),.audits/(~207),.continuation-prompts/(~344),.research/,.plans/,.reviews/,.feasibility/,.reference/, etc. This is the bulk of the 1,269 files and the 36 MB, and it is where the process IP, stale specs, and client-named historical material concentrate (Charnwood/Telehouse appear throughout.planning/.archive/).
5.2 How it is indexed (and why removal has a recall cost)
Section titled “5.2 How it is indexed (and why removal has a recall cost)”.planning/ is indexed by both code-intelligence systems:
- GitNexus has
.planningfiles in its graph (≈2,574 files in the broader graph). - ccc / cocoindex indexes it too, despite a
**/.*exclude that appears to be a no-op against top-level dot-directories. - MemPalace is a separate MCP memory system — it is not a filesystem
indexer of
.planning/and does not depend on it. So removing.planning/does not touch MemPalace recall.
The trade-off is therefore concrete: keeping .planning/.archive/ preserves
tool-assisted historical recall but (a) exposes process IP if the repo goes
public and (b) surfaces stale specs in code-search, which can mislead agents.
Removing it shrinks recall, and there is no live replacement yet (the
docs-site is not deployed — §6).
5.3 Options
Section titled “5.3 Options”| Option | Description | Pros | Cons |
|---|---|---|---|
| R1 — Retain private (status quo) | Leave .planning/ tracked; do not go public until a better split exists. | Zero recall loss; no work. | Does not unblock public; IP exposed the moment we flip. |
R2 — Split: keep codebase/, evict .archive/ | Keep the 7 current architecture docs tracked; move .planning/.archive/ out of the indexed tree (separate private branch/repo, or a tool-exclude that actually works). | Preserves the live, cited codebase map; removes the bulk of IP + stale-spec noise; shrinks the public surface ~1,260 files. | History scrub still needed for the public flip; need a working ccc/gitnexus exclude or a real relocation. |
R3 — Retire .archive/ entirely | Delete the archive (history-purge for public). | Smallest public surface; ends stale-spec pollution. | Irreversible recall loss of all historical decisions; high regret risk; MemPalace does not cover it. |
| R4 — Archive externally | Move .archive/ to a private GitHub repo / cold store, keep a pointer. | Preserves recall somewhere; clean public repo. | Loses in-repo tool indexing of the archive; extra repo to maintain. |
5.4 Recommended framing for .planning/
Section titled “5.4 Recommended framing for .planning/”Do NOT remove .planning/ now. It is not the gate (the client corpus is),
and the codebase docs are actively cited. The recommended sequence is R2,
deferred: once the docs-site is live (so there is a real home for any
public-facing architecture content), evaluate moving .planning/.archive/ out
of the indexed/tracked tree while keeping .planning/codebase/. This is the
disposition decision Liam should ratify (OQ-68-1) — but the execution is
gated on the docs-site, not on this RESEARCH.
6. Area 2 — is the ID-9 Astro docs-site the right public-docs mechanism?
Section titled “6. Area 2 — is the ID-9 Astro docs-site the right public-docs mechanism?”6.1 Status
Section titled “6.1 Status”The Astro 5 + Starlight docs-site is BUILT and committed in-repo at
docs-site/, but NOT deployed:
docs-site/astro.config.mjs:30still has the placeholdersite: 'https://vercel-default-subdomain.vercel.app'.- There is no Vercel deploy workflow for the docs-site (the 15 workflows in
.github/workflows/includedocubot.yml,sync-source-docs.yml,review-docs-pr.yml, etc., but nodocs-site-deploy/ Vercel publish). - ID-9 is
in_progress: 21 of 25 subtasks done. The open ones are decommission-gate / E2E-conversion / dangling-ref cleanup — and notably there is no completed “first deploy” subtask; deploy readiness is implied by the placeholdersitevalue. - No docs-site runbook exists (
docs/runbooks/has none matching docs-site/astro/starlight). This is a documentation gap that PLAN should flag.
6.2 Assessment
Section titled “6.2 Assessment”The docs-site is the intended mechanism for hosting public-facing docs separately from the code repo — that is precisely its design purpose, and it is the natural home for the generic product/architecture docs that today live in-repo (and which a public repo would otherwise expose in raw, unpolished form). It is the right answer to “where do public docs live, separate from code”.
But it is not yet a usable replacement. Until it is deployed with a real
site URL and a deploy pipeline, there is no live surface to migrate in-repo
docs to. So the docs-site cannot today substitute for any in-repo docs that we
might want to remove before going public.
This produces the central sequencing question (OQ-68-2): do we gate the public-go on the docs-site being deployed, or do we go public first (clearing only the hard IP blockers) and migrate polished docs to the docs-site later? The two are separable — the repo can go public with raw docs/ present (minus the client corpus) and have the docs-site come later as the polished public face, or we hold the flip until the docs-site is the front door.
7. Area 4 — GitHub security-feature gains post-publication
Section titled “7. Area 4 — GitHub security-feature gains post-publication”Public repos get, for free, the GitHub Advanced Security subset that is otherwise paid on private repos:
- Dependabot alerts (vulnerable dependency detection) — already partially on; full alert + auto-PR flow on public.
- Dependabot security updates (automated fix PRs).
- Code scanning (CodeQL) — static analysis for security bugs, free for public repos.
- Secret scanning (+ push protection) — detects committed secrets and can block pushes that introduce them; free for public repos, including partner patterns.
Current debt: 23 open Dependabot alerts (8 high / 11 medium / 4 low) on the default branch (live S289; the brief’s “3” is stale — §3). Going public turns the full alerting on and makes the high-severity items visible to anyone, so clearing or triaging the high-severity alerts should precede the flip (or be an immediate post-flip Subtask) rather than exposing open high-sev vulns on a public repo.
Secret scanning is doubly relevant here: it is both a gain (push protection prevents future leaks) and a gate (it will flag any historically committed secret across the whole history once enabled — see the history-scrub note in §4.3 / OQ-68-5).
8. Area 5 — container image visibility policy
Section titled “8. Area 5 — container image visibility policy”8.1 Current state
Section titled “8.1 Current state”ghcr.io/ai-solution-hub/kh-cocoindex-pipeline is PUBLIC (verified S289).
This was the original S288 trigger: the package-public decision was held pending
verification that the buildpack did not bake private docs into the image.
8.2 What it bundles (verified — §4.1)
Section titled “8.2 What it bundles (verified — §4.1)”The image build context is a pruned scripts/ + requirements.txt only.
The onprem-deploy.yml Inv-9 assertion further checks the image carries no
pullmd / Playwright (AGPL boundary). So the buildpack-bakes-private-docs concern
from S288 is resolved: the image does not contain docs/, .planning/,
the Next.js app, docs-site, .claude, or tests. It contains the Python
pipeline + the client-name leaks in scripts/ (Channel A, §4.2).
8.3 Policy options
Section titled “8.3 Policy options”| Option | Description | Trade-off |
|---|---|---|
| I1 — Keep public (status quo) | Leave the cocoindex image public. | Simplest; matches on-prem direction. But Channel A leaks stay public and any future scripts/ content is auto-public on each build. |
| I2 — Make private | Flip the package to private; pull with a token in Coolify. | Closes Channel A exposure; adds a registry-auth step to the on-prem deploy (Coolify pull credential). Reversible. |
I3 — Keep public + scrub scripts/ | Keep public, but complete the §4.2 scrub so the image carries no client identity. | Best end-state if public is desired anyway; couples image-visibility to the scrub timeline. |
The image-visibility policy is logically downstream of the repo-public decision: if the whole repo goes public, the image being public is moot; if the repo stays private, the image is the only public surface and I2/I3 become the levers for Channel A. Recommended: align the image policy with the repo decision rather than deciding it in isolation (OQ-68-4).
9. Open questions for Liam
Section titled “9. Open questions for Liam”-
OQ-68-1 —
.planning/disposition. Ratify the §5 direction? Recommended: R2 deferred (keep.planning/codebase/, evict.planning/.archive/once the docs-site is live), not R3 (retire) or R1 (status quo). Which option? -
OQ-68-2 — Gate the public-go on docs-site deploy? Do we hold the repo flip until the ID-9 docs-site is deployed and is the polished public front door (sequential), or go public first after clearing only the hard IP blockers and migrate docs to the docs-site afterwards (parallel)? This sets the whole Task’s critical path.
-
OQ-68-3 — Scrub scope. For the client identity (“Phew Design Limited” / Telehouse / Charnwood): (a) full parameterise-and-remove sweep across all 602 files; (b)
scripts/+ image only (the already-public Channel A), accept the rest; or (c) accept the client name throughout (it is Liam’s own org) and scrub only genuine third-party / proprietary content (the client corpus, British Council RFP, team/case-study docs)? The S289 default is “accept for now, dedicated scrub session next”; this OQ pins the target scope for that session. -
OQ-68-4 — ghcr image visibility. Keep public (I1), make private (I2), or keep-public-after-scrub (I3)? Recommended: decide jointly with the repo flip — if the repo goes public, keep public; if not, I2/I3 to close Channel A.
-
OQ-68-5 — History scrub. Do we require a full git-history purge (
git filter-repo) of the client corpus + briefs + client-named test-data before going public (correct but one-way and disruptive), or accept that history-deletion happens at HEAD only with the understanding that the public commit graph would still hold the old content? For a genuinely client-protecting public repo, history scrub is effectively mandatory — this OQ confirms appetite and surfaces the cost. -
OQ-68-6 (secondary) — Dependabot debt timing. Clear the 8 high-severity Dependabot alerts before the flip, or flip and clear immediately after? Exposing open high-sev vulns on a public repo is a (small) reputational/risk cost.
10. Recommended direction
Section titled “10. Recommended direction”A pragmatic, reversible sequence that respects the hard constraint and the S289 “accept-for-now” posture:
-
Treat the client corpus as the only true blocker, not the client name. The gate on going public is Channel B proprietary content —
docs/client-documentation-corpus/(33 files: real bid library, named clients/case studies, team structure, third-party Telehouse PDF),docs/client-briefs/(8), and the non-public-tenderdocs/testing/test-data/items (British Council RFP). These must be relocated to a private store and purged from history. The client name (Phew, Liam’s own org) and public-tender artefacts (Charnwood ITT, PPN SQ) are accepted per S289 and scrubbed opportunistically, not as a gate. -
Channel A (
scripts/leak) is already public via the ghcr image — so its cleanup is hygiene, not a gate. Parameterise the client literals inscripts/against the existingCLIENT_CONFIG/NEXT_PUBLIC_CLIENT_IDmachinery and relocate the twocatalogue-*-itt.tsone-shot seed scripts out of the shipped tree. Schedule with the dedicated scrub session. -
.planning/: R2, deferred. Keep.planning/codebase/(live, cited); plan to evict.planning/.archive/once the docs-site is live, since that is where the IP + stale-spec noise concentrates and where eviction has the biggest surface reduction (~1,260 files) for the least recall cost. -
Sequence the docs-site as the public front door, but do not necessarily hard-gate on it (OQ-68-2). The docs-site (ID-9) is the right mechanism; finishing its deploy (real
siteURL + deploy workflow + a runbook — all currently missing) is the natural predecessor to evicting in-repo docs. If Liam wants public sooner, the repo can flip after the Channel B content purge with rawdocs/present, and the docs-site lands afterwards as the polished surface. -
Clear the high-severity Dependabot alerts around the flip and rely on the free public-repo security suite (code scanning, secret scanning + push protection) as the ongoing payoff — and as a guard against re-introducing the very leaks this Task cleans up.
-
Keep everything reversible until the history scrub. Visibility flips (repo, ghcr image) are reversible; the history purge is the one-way door. Order the PLAN so the irreversible step (history
filter-repo+ public flip) is the last action, after content relocation, scrub, and Dependabot triage are all verified.
This keeps the hard constraint intact (client documentation and proprietary IP
leave the public tree and its history), unblocks the security-tooling payoff,
and aligns with the on-prem direction without forcing a premature or
irreversible move. PRODUCT ({68.2}) should turn items 1–6 into ratified
acceptance criteria and pin the OQ-68-* answers.
11. Ratification & corrections (S289, Liam)
Section titled “11. Ratification & corrections (S289, Liam)”Terminology correction (load-bearing — supersedes any conflation above, incl. §10.1 “Phew, Liam’s own org”):
- AI Solution Hub = our organisation (the vendor). Public-safe.
- Phew (Phew Design Limited) = our first client. The hardcoded
phew/phew design limitedliterals inscripts/are therefore client identity, not org identity — they are genuinely sensitive and in scope for the scrub (Rec 2). “AI Solution Hub” appearing in code/docs is fine. - Knowledge Hub = the platform (the product itself).
Other correction: under docs/testing/test-data/, the only non-public
item is the CSP, not the RFP (the §10.1 “British Council RFP” framing is
corrected — the RFP is not the sensitive artefact; the CSP is).
OQ resolutions (ratified):
- OQ-68-1 (
.planningdisposition): R2 — keep.planning/codebase/, defer.planning/.archive/eviction until the docs-site is live. - OQ-68-2 (gate public-go on docs-site?): Moot — the docs-site is NOT
public. Its purpose is the canonical Knowledge Hub platform documentation
location (NOT Phew/client docs, NOT public marketing), kept accurate against
the codebase by the already-deployed docs skills + CI actions. It is an
internal-canonical surface, so it is not the “public front door” §10.4 framed.
Hosting options (priority order): (a)
docs.knowledge-hub-seven-kappa.vercel.appif Vercel allows that subdomain (the platform URL before the Phew domain went live); (b) temporarily onaisolutionhub.co.uk(owned) until a long-term domain is purchased; (c) a fresh Vercel project for its default domain. Deploying it is still prioritised (supports OQ-68-1 archive eviction). - OQ-68-3 (scrub scope): parameterise the client literals in
scripts/(org name “AI Solution Hub” stays). Tooling — see “Scrub tooling” below. - OQ-68-4 (ghcr visibility): I1 — keep public (cocoindex is MIT; nothing proprietary ships). Revisit only if a proprietary artefact ever enters the image build context.
- OQ-68-5 (history scrub): agreed — full
git filter-repoof the relocated client content; automate the content-site discovery via the OQ-68-3 tooling, then run the history purge as the last, one-way step. - OQ-68-6 (Dependabot timing): clear the 8 high-severity alerts BEFORE the flip.
Scrub tooling (answer to OQ-68-3 — find vs rewrite are different jobs):
- Find (exhaustive site inventory):
ast-dataflow string-literal-usesfor the TS/TSX corpus + agrepsweep for Python / SQL / Markdown (ast-dataflow is TS-only). gitnexus / cocoindex-code (ccc) are semantic navigation tools, andgitnexus_renameonly renames symbols, not string literals — neither rewrites literals, so they are find-aids at most here. - Rewrite: the AST-aware rewriters are ts-morph (TS — the lib
ast-dataflowis built on, already used inscripts/codemods/) and ast-grep (sg --rewrite, covers TS and Python in one pass — best single tool for a cross-language literal swap). - Caveat — Rec 2 is parameterisation, not blind replacement. Swapping a
literal for a
getClientConfig()/NEXT_PUBLIC_CLIENT_IDlookup is a semantic edit needing per-site judgement (parameterise vs delete-the- historical-script vs leave-org-name). So the scrub session should: (1) ast-dataflow + grep to build the categorised site list; (2) a guided ts-morph codemod for the uniform parameterise cases; (3) manual for the nuanced ones. History removal (OQ-68-5) isgit filter-repo, a separate git operation — no AST tool does it.
New scope surfaced by this ratification (carried to {68.2} PRODUCT / next
session):
- Relocate
docs/client-documentation-corpus/(+client-briefs/) OUT of the repo and point a KH ingest at Liam’s local Mac filesystem instead — deliberately replicating how a real KH deployment points at a client’s file store (production-aligned, not a repo-embedded corpus). This also intersects ID-45/T7 (the ingest source root) and the bl-206 path-drift gate. - Define the required client-setup directory structure when KH points at a
client’s files (what layout/conventions, if any, the ingest expects). This is
likely already defined or referenced in the pipeline intended-architecture
docs (
docs/themes/canonical-pipeline/intended-architecture/) — confirm and surface it as the contract. - Housekeeping (next session): reconcile the
task-viewversion drift (local cachev0.3.1vs the CI/drift-workflow pinv0.2.0-task-view).