Corpus predicate — validation notes¶
Task 0.7 of the delivery plan: check the R-KB-1 discovery predicate against the actual estate before Phase 2 builds on it.
Validated 2026-07-27. The predicate holds. Two implementation constraints emerged that the requirement did not anticipate, plus one confirmation that a stated risk was real.
The exclusion list is load-bearing — confirmed¶
R-KB-2 warns that infra and iac satisfy the
discovery predicate and are excluded only by the deny list. This is now confirmed against the real
repositories, not predicted: phpboyscout/infra carries zensical.toml and publishes a docsite.
Without the exclusion evaluated before discovery, the bot would index the AWS account topology — account structure, role naming, bucket naming — and recite it on request in a public Discord channel. The corpus-safety tests asserting this rejection are not defensive padding; they guard a live path.
Finding 1 — discovery must deduplicate by canonical repository¶
Several local working directories resolve to the same GitLab project:
| Directory | Actual repository |
|---|---|
gtb-config-migration |
phpboyscout/go-tool-base |
infra-reel-media |
phpboyscout/infra |
keyrx-reel-scrim |
phpboyscout/keryx |
rust-tool-base-style |
phpboyscout/rust-tool-base |
These are worktrees and task-scoped clones. Naive enumeration counts them as distinct sources and would index the same content several times — inflating the index, skewing BM25 term statistics, and producing duplicate citations pointing at one document.
Discovery MUST key on the canonical repository path returned by the API, never on a directory
name or a local path. Note also that keyrx → keryx and haileys-app → krites: directory
names do not reliably match project names anywhere in this estate.
Finding 2 — enumerate from the API, never from disk¶
This validation ran against local checkouts because they were to hand, which is precisely why it is only indicative. Local disk cannot answer the questions the predicate actually asks:
- Completeness — a group repository never cloned locally is invisible, so the corpus would silently depend on which repositories happen to be checked out on the host.
- Visibility — R-KB-2a requires verifying a
repository is
public. A local clone says nothing about it; a repository made private yesterday looks identical on disk. - Freshness — a stale clone reports the docsite marker and file set as of whenever it was last pulled.
- Canonical path — R-KB-2b requires re-verifying namespace membership each refresh, since GitLab redirects renamed and transferred projects. A local remote URL can be a stale redirect that still resolves.
Discovery MUST enumerate the group through the GitLab API. The local checkout is a debugging convenience, never a source.
Pages liveness¶
Every sampled module docsite returned 200 (config, forge, chat, controls, credentials,
redact, regexutil, observability, transport, authn, browser), as did gtb.phpboyscout.uk
and go.phpboyscout.uk.
Carrying zensical.toml and publishing are still separate conditions, and the predicate rightly
tests both — a repository can hold the marker with Pages disabled or a failed deploy. The liveness
check is cheap and must stay.
Rough scale¶
Around 31 distinct repositories currently satisfy the predicate once duplicates are collapsed —
the great majority being phpboyscout/go/* modules, plus the headline projects. Small enough that
a full index rebuild is inexpensive, and comfortably within what SQLite FTS5 handles without
tuning.