t1k:knowledge-retrieval
| Field | Value |
|---|---|
| Module | t1k-extended |
| Version | 3.5.0 |
| Effort | medium |
| Tools | AskUserQuestion, Bash, Glob, Grep, Read |
Keywords: assembly lookup, corpus search, doc_get_member, doc_search, does this exist, have we built this, knowledge-retrieval, prior art, rag query, reuse check, semantic search, studio docs
How to invoke
Section titled “How to invoke”/t1k:knowledge-retrieval<capability or need> [--engine unity|cocos] [--json <out>]Studio Knowledge Retrieval — Prior-Art Lookup That Actually Returns the Answer
Section titled “Studio Knowledge Retrieval — Prior-Art Lookup That Actually Returns the Answer”Retired 2026-08-26 — you may now query a bare symbol name. This skill previously required every query to contain an all-lowercase word, because a query of only capitalized tokens returned a fixed junk set at ~0.79 similarity. That was a deployment defect (AIPGDS#9/#16), it is fixed (AIPGDS#18), and the corpus has been rebuilt.
IObjectPoolManagernow returnsTheOne.Pooling.ObjectPoolManagerat 0.7302 on the vector arm.Correction 2026-08-26 — “fixed” is premature. PR AIPGDS#18 merged, but issues #9 and #16 are both still OPEN, and the symptoms remain measurable. Bare-symbol search now works for some types (
RingSpawnRequest0.7745,DraftPool0.6925) and still fails for others (DotDamageAccumulator,CombatTarget,CurrencyIdall miss their own record on a bare-name query). Root cause of the residue: the lexical arm is a full-text index oversummaryonly (002_init_rag_docs.sql:63—to_tsvector('english', coalesce(summary, '')));simple_namehas a separate btree that the hybrid search does not use. A type is therefore lexically findable only if its own summary happens to repeat its name — while its members’ summaries routinely do name the parent, which is why members outrank their own type. Measured: of 40 types known to be indexed, 8 could not be found by typing their own name (100% coverage, 80% reachability), and rank 1 in only 8 of 32 successful lookups.It is called out here, not only in
references/query-technique.md§0, because anyone who internalised the old rule has no reason to re-open the reference that retired it. The lexical arm is still conjunctive (AIPGDS#10), so the 2–3-content-word guidance stands — for that reason, not this one.
Ask the studio corpus “do we already have this?” against one MCP that indexes both engine worlds — and get an answer scoped to the engine you are actually working in.
The whole problem in one line: the corpus is overwhelmingly Unity/.NET, so the same unscoped query is correct for a Unity question and confidently wrong for a Cocos one. Scope is not an optimization here; it decides whether the answer is usable at all.
Query mechanics and corpus facts are the SSOT in
references/doc-search-contract.md. How to shape the query
— the part that most changes result quality — is
references/query-technique.md. Cite them; do not restate them.
The server
Section titled “The server”| Name | knowledge-retrieval (HTTP MCP, https://mcp.the1studio.org/mcp) |
| Tools | doc_search, doc_get_member, doc_list_assemblies |
| Auth | your own gh auth token; needs active The1Studio org membership |
| Install | ~/.claude/skills/t1k-mcp-management/scripts/install-knowledge-retrieval.sh |
| Declared | mcp.required[] with autoInstall: true in both t1k-config-unity.json and t1k-config-cocos.json |
Registration, credentials, and the auto-install policy belong to t1k-mcp-management. This skill
owns only what to do once the tools are loaded.
When to invoke — the second half of prior art, not the first
Section titled “When to invoke — the second half of prior art, not the first”Sweep the corpus FIRST — grep only confirms what you already know to ask for.** The discovery
protocol is corpus-first, grep-second (theonekit-unity#533): the corpus is the default entry
point for “does this already exist?”, and local grep is the step that turns a corpus hit into an
actionable path. For a need you can name as a symbol, grep is fast and authoritative (real file
path, on-disk version, actual implementation, reference count) — but a clean grep is not a miss;
it is the corpus that answers a capability not checked out here, a sibling project’s source, or a
need phrased as behaviour.
That verdict generalizes only to needs you can name. Grep answers the questions you knew to ask in the folder you knew to open. A need phrased as behaviour — “cancel a looping hint safely” — names no symbol, has no grep target, and remains a corpus question even when the answer is already installed locally. The skip is licensed by a nameable symbol, never by “it was installed” (the Cocos drift log carries the worked case where that exact reasoning lost a hit).
Invoke for the three things grep structurally cannot answer:
| Case | Why grep fails |
|---|---|
| Capability not checked out here | You cannot grep a file that is not on disk. Confirm that is really the situation first — package count is not capability count. |
| Design precedent from another project | Sibling projects are indexed. You cannot grep a repo you do not have. |
| You do not know what to grep for | Semantic search answers “does anything solve X?” when you cannot name the symbol. |
Not for: package names and versions (Cocos → CPM, https://cpm.playablelabs.ai/); needs a grep you could actually phrase already answers; a question about a third engine — the corpus indexes Unity/.NET and Cocos only, and a React-Native or web question returns confident nonsense from both.
Workflow
Section titled “Workflow”- Establish the engine. Unity, Cocos, or neither. This picks the scoping profile in § Scoping and it is not optional — the same query needs opposite handling.
- Name the needs as capabilities, not class names.
"combo multiplier score streak", not"ComboMeterController". The index is semantic; a local symbol name is the one string guaranteed not to appear in another project. - Shape the query as an answer, not a question — see
references/query-technique.md§ Write the answer. This is the single highest-leverage step and it is free. - Retrieve with the engine’s budget (§ Scoping). One call per need.
- Filter, then apply the positive test before citing anything. A name predicate is not proof; confirm the hit’s language and types match the engine you are in.
- Deepen survivors worth citing:
doc_get_member({ id })for the real signature. - Tag and emit the prior-art table. Every
○is new work someone will be asked to pay for — be sure the miss is real, and not a filter artefact or an absent MCP. - Promote genuinely new, charter-generic work upstream. A corpus-miss on code carrying no
project-specific token is a contribute-back case, not just a
○in the table — see § Contribute back. This is the other half of the same sweep, not a separate task.
Scoping — the same corpus, two opposite problems
Section titled “Scoping — the same corpus, two opposite problems”Do not quote a corpus count from memory or from this prose. The exact split lives in
references/doc-search-contract.md’s pointer to
assets/corpus-summary.json — regenerate it via scripts/refresh-corpus-summary.cjs before citing
a number in a report. What stays true regardless of the exact count on any given day: Unity/.NET is
the large majority of the corpus, Cocos is a small minority split between a fixed set of foundation
subsystems and a growing list of projects. Your engine decides which failure mode you are fighting.
| Unity | Cocos | |
|---|---|---|
| Share of corpus | the large majority | a small minority |
| Failure mode | Too many valid hits — 20 near-identical overloads, no wrong-language noise | Right answers outranked — C# APIs a playable can never import take the top slots |
Default limit | 10 | 25 (mandatory) |
| Primary mechanism | assembly_prefix to disambiguate a known subsystem | filter-after-search against the committed allowlist |
| Main risk | picking a deprecated or internal overload | filtering your way to an empty result on a capability the studio demonstrably has |
The rule underneath both columns: filter-after-search is post-filtering, and post-filtering
loses recall in proportion to how little of the corpus survives your filter. Retrieve budget must
scale inversely with filter selectivity. Cocos keeps only a small slice of the corpus, so it must
over-retrieve; Unity keeps nearly all of it, so it need not. Derivation, the measured ranking proof,
and the ceiling rule: references/query-technique.md § Over-retrieve.
When limit: 25 still is not enough, the answer is not a bigger limit — 25 is the schema
maximum. Switch mechanisms: an assembly_prefix drill-down is pre-filtering, which has no
oversampling problem because the filter is applied before the search rather than after it.
Broad-at-25 → prefixed drill-down is the intended shape.
⛔
Section titled “⛔ assembly_prefix at FAMILY level is a truncation switch, not a narrowing aid”assembly_prefixat FAMILY level is a truncation switch, not a narrowing aidMeasured 2026-08-26 against
unity-dots-library.assembly_prefixis a raw string prefix over assembly names, and this library ships two naming conventions — only 9 of ~97 indexed assemblies begincom.the1studio.; the other ~88 are bare CLR names (DOTSCore,DOTSCombat.Spawning,DOTSEconomy.Runtime,DOTSProgression.*,DOTSBridges.*,DOTSUiKit). The tell:com.the1studio.dots-core.Editorcarries the prefix while its own runtimeDOTSCoredoes not.So
assembly_prefix: "com.the1studio"hides ~91% of the library and reports success. It destroyed the correct answer in 7 of 20 benchmark queries and then backfilled each page to 10 rows with no signal. Cleanest case: a fertilizer query returned 10/10 correctDOTSFarming.Runtimerows unfiltered and zero farming content filtered — ten confident decoys from other packages.Rule: only pass
assembly_prefixan assembly name you have already seen in a result. Never a package family, never a guess. And note a prefix is not a boundary —assembly_prefix: "DOTSCombat.Spawning"silently also matchesDOTSCombat.Spawning.Authoring, while scoping toDOTSProgressionspans several distinct assemblies.
Cocos callers: the committed allowlist and the ranking proof live in the Cocos kit
(t1k-cocos-base-knowledge-sweep), which cites this file for everything above. Use that skill
directly in a Cocos project — it adds the generated allowlist, the project detector, and the
prior-art table shape its four consumers read.
Reading a result
Section titled “Reading a result”⚠️ Two of the three criteria below were measured non-functional (2026-08-26)
Section titled “⚠️ Two of the three criteria below were measured non-functional (2026-08-26)”
summary_quality: "high"discriminates nothing. It washighon 100% of 200 measured hits, on every hit returned for three deliberate nonsense queries, and on a member that does not exist in any source file. Corpus-wide it is 96.6%high. It rates prose completeness, never correctness or lifecycle. Treat it as metadata, never as a gate.similarity ≳ 0.65admits confirmed junk. A wrong Cocos hit ranked #1 at 0.760; an entirely irrelevant page sat at 0.720–0.729. Meanwhile the nonsense floor is 0.535–0.616 (a query about Vietnamese trademark law scored 0.616 — higher than a page containing a real, shipped capability at 0.599–0.623). The bands overlap, so no threshold separates them; 0.65 screens literal gibberish and nothing else.- Only the engine/assembly check actually works — and see the
assembly_prefixwarning above before trying to enforce it with a filter.Use instead: does the returned
summarydescribe the capability you asked for, in an assembly that belongs to your engine? That judgement is the gate. A score and a quality label are not.
Treat a hit as real prior art only when the assembly belongs to your engine and the summary actually answers your question (the two struck criteria above are unreliable). Then tag it:
| Tag | Meaning |
|---|---|
| ● inherited | The member does the whole job — reuse as-is, bill nothing. |
| ◐ framework-assisted | A base exists; you build on it. |
| ○ custom | Nothing upstream — genuinely new work. |
Record the verdict as reuse-search: found <Type>@<path> — byte-exact, its own line, nothing
appended to it (§ Reporting a miss covers the miss form and why the line must stay pristine).
Sizing effort from these tags — hours and points, not just a symbol — is § Sizing the delta.
Record the hit’s kind alongside the tag. A foundation/package hit is genuinely
importable. A project hit is another project’s own source, indexed for reference — nothing to
install, and reuse means copying the pattern or extracting it first. Tagging a project hit ●
tells the reader to import something that does not exist.
similarity is a ranking signal, not a correctness one. It orders candidates within one query;
it does not transfer across queries, and it cannot tell a right-language hit from a wrong-language
one. Filter by assembly and by the positive test — never by score alone.
When the MCP is absent — reconnect first, degrade second, never fake
Section titled “When the MCP is absent — reconnect first, degrade second, never fake”If mcp__knowledge-retrieval__doc_search is not loaded this session:
claude mcp list | grep -i knowledge(andclaude mcp get knowledge-retrieval).- Not registered or broken → run the kit installer, in the background so nothing blocks:
~/.claude/skills/t1k-mcp-management/scripts/install-knowledge-retrieval.sh - Tell the user it was re-registered and a Claude Code restart is required for the tool to load — the registry is snapshotted at session start.
- Only then degrade to a fallback, and say so in the output (
discovery: fallback).
Never report “nothing found” because the MCP was down. A miss caused by an absent tool is not evidence of absence; reporting it as one turns every subsystem into false greenfield.
Reporting a miss
Section titled “Reporting a miss”A miss is a claim about your search, not about the studio. Every reported miss carries two lines — the verdict, then the scope on a separate adjacent line, never merged into it:
reuse-search: not-found-after-corpus-and-grepscope: <what was actually searched> | swept: <date>reuse-search: is the canonical cross-kit verdict token — it shipped first from theonekit-unity
(PR #496) and is reviewer-gated (t1k-unity-dots-core-reviewer checklist item 14 treats a missing
reuse-search: line as CRITICAL). Keep that line byte-exact and pristine; the scope: line beneath
it is what actually satisfies rules/negative-result-scope.md — reuse-search: alone records the
verdict, not what was swept, so the scope line is not optional and must never be appended to the
gated line above it.
no hit across 21 Cocos assemblies is a finding. greenfield is an unverifiable assertion that
every downstream estimate inherits. rules/negative-result-scope.md treats the bare form as the
single highest-cost planning error.
⛔ A corpus miss is NOT evidence of absence — measured false-absence 20–60%
Section titled “⛔ A corpus miss is NOT evidence of absence — measured false-absence 20–60%”Ten capabilities known to ship were probed in design vocabulary (2026-08-26):
sweep shape found false-absence unfiltered only 4/10 60% com.the1studiofiltered only5/10 50% both passes, union 8/10 20% The two passes are near-disjoint and mutually destructive, and no single configuration exceeded 5/10. Worse, a false negative and a true negative are indistinguishable: every call returns a full page — there is no empty result, even for gibberish — and over the sample the similarity signal ran backwards, with the true negative scoring highest and a false negative near the bottom. Score-gap does not discriminate either; do not build a heuristic on either number.
Two independent causes of a phantom miss, both verified:
- Reachability, not coverage — the type is indexed and simply cannot be ranked by its own name (see the lexical-arm note at the top of this file).
- The member was deleted at extraction — a trailing
//comment on a documented C# field makesdocgen-unity.pydrop it and index a phantom named from the comment text. 65 documented members inunity-dots-libraryalone.AuraEffect.AffectAllies,OnHitEffect.ChanceandAILeash.LeashRadiusall returnnot_foundwhile existing in source.So: a miss downgrades a claim to
unverified, nevergreenfield. Before writing any absence claim about a Unity member, grep the source — and check the declaration line for a trailing comment.
Contribute back — the other half of the sweep
Section titled “Contribute back — the other half of the sweep”The corpus sweep (§ Workflow) only tells you what is already upstream; on its own it says nothing about pushing your own generic work the other direction. That direction has been absent from this skill — every section above looks upstream→down (does upstream have X for me to consume). This section closes it.
Trigger — generic by charter, immediately. Not rule-of-two. If the code you just wrote carries
no project-specific token per rules/library-quality-mandate.md’s naming charter, it belongs
upstream the moment it is written — do not wait for a second consumer to need it first. That
rule’s own framing is why: “a concrete dependency that ships is concrete forever” applies exactly as
hard to not extracting reusable, charter-generic code as it does to hard-coupling a vendor
dependency. Every day it stays local is a day the next project re-solves the same problem instead
of importing it.
Gate — the full five-part pass-test, no lighter variant. Before promoting, the code must clear
ALL FIVE checks rules/library-quality-mandate.md already defines: domain-neutral, data-driven,
tested, charter-conformant, documented. That rule is the SSOT for what each check means — cite it,
do not restate the five items here, or the two copies will drift apart.
Where the corpus sweep comes in — run it BEFORE promoting, not after:
- Hit — upstream already has this or something close to it. Do not promote a rival
implementation; extend or reuse what’s there instead (
rules/development-principles.md§ “SSOT — No Duplicates”). Promoting anyway duplicates the exact thing this skill exists to stop you from duplicating. - Miss, and the code is charter-generic per the trigger above — that is the promote case. Push
it through your kit’s normal contribute-back path (e.g.
/t1k:sync-backfor a.claude/-owned fragment; an upstream PR for a library package).
Treat this as the natural second half of one sweep, not a separate task: every corpus sweep you run already tells you whether to reuse, extend, or promote — decide which while the context is still loaded, not later from memory.
Sizing the delta — the flow, not a general estimator
Section titled “Sizing the delta — the flow, not a general estimator”This sizes ONLY the delta a corpus-sweep result reveals for one need. It is not a general-purpose estimation method; do not use it in place of your team’s normal process, and do not present it as one.
Cite the flow, don’t reinvent it — theonekit-cocos already runs this in production. The
t1k-cocos-playable-preproduction skill (repo The1Studio/theonekit-cocos, private module
playable) carries an estimation-rules.md § 1 defining a two-point Base/Worst-case model driven
by the same ●/◐/○ tags this skill already emits (its own reuse-sweep reference tags identically).
That flow is the SSOT for how a reuse tag becomes an effort number; this section states only the
shape every engine’s estimate follows, not a restatement of Cocos’s numbers as if they were
universal.
The flow (shared, engine-agnostic):
- A reuse tag is a price claim, not decoration — it must cite the corpus hit that grounds it.
An uncited discount defaults to
○. (Same rule as the Cocos reuse sweep’s own justification threshold.) - Estimate Base directly per need — the lean, realistic number, with no rosy floor below it. Base is not derived by multiplying a tag against some hypothetical from-scratch figure; it is the actual estimate for the actual work, informed by what the tag says is left to build.
- Derive Worst-case = Base + a risk premium, and the premium is tag-driven, not uniform —
inherited (
●) work carries the smallest premium (little can go wrong), custom (○) work carries the largest (highest uncertainty). Only the Worst-case side scales with the tag; Base does not. - Report two figures — Base and Worst-case — never a single number.
The values — engine/domain-specific, not baked in here. Cocos’s production numbers (cited, not
asserted as universal): ● → Worst-case ≈ Base (near-flat); ◐ → Worst-case ≈ Base × 1.25; ○ →
Worst-case ≈ Base × 1.4–1.6. No equivalent multiplier set exists yet for Unity or any other
engine — inventing one here would repeat the exact mistake this section replaces. If you need
Unity-specific numbers, that is a gap for the owning Unity kit to fill, following this same flow;
do not improvise multipliers in the meantime and present them as settled.
Units — ideal engineering hours, Cocos’s basis exactly: 8h = dev-day, 5 dev-days = week. No
story points, no Fibonacci — a points layer only one engine used would have been a second contract
wearing the first one’s name, not the shared flow “the same flow, like IoC” asks for. The unit
basis is cited from Cocos’s estimation-rules.md, not restated as independent arithmetic.
Query recipe — measured, not guessed
Section titled “Query recipe — measured, not guessed”Seven rules from a 10-pair A/B plus ~150 probes: lead with the mechanic noun an engineer would type,
include a MECHANISM word, never paste a designer’s player-facing sentence, and read rrf as an arm
counter, not a score. Implementation phrasing beat design phrasing 7 of 10; design won none.
Rules + measurements: references/query-technique.md § 9.
Gotchas
Section titled “Gotchas”- Never call
doc_list_assembliesin a workflow — ~110K chars, it will blow the context. It is a maintenance-only call. (It is also unusable for inventory: 419 of 709 assemblies carry anullassembly_suffixand match nosuffix_filtervalue, so no call sequence enumerates the DOTS gameplay assemblies at all.) doc_get_memberids do not round-trip from source for Unity. Every id referencing a top-levelUnity.Entitiestype carries a bogusThe1Studio.DOTS.Analyzers.Tests.DOTSLIB002…prefix baked into the primary key. The correct cref returnsnot_found; only the corrupt one resolves. Copy ids fromdoc_searchoutput — never construct them.cross_refs.resolved_idis wrong about half the time (6 of 12 measured), resolved by unscoped simple-name match.DamageEvent’s own summary says “UseCreate”, andCreateresolves toDOTSBridges.Analytics.AnalyticsEvent.Create. Verify a cross-ref before following it.siblingsis an alphabetical head of the assembly, not a relatedness set — three unrelated queries intodots-combatreturned byte-identical lists. Noise for the 88% of members in assemblies larger than 31 members.- Reject wrong-engine assemblies by name, never by score. Unity’s
GameFoundation.*is not the Cocos@playablelabs/game-foundationand scores ~0.73 on behaviour queries — above any sane threshold. Score-based filtering lets it straight through. doc_get_member’ssiblingsare assembly-wide, not class members. You get ~30 alphabetically-adjacent members from unrelated classes. To see one class’s real surface, run a seconddoc_searchwithassembly_prefixset instead.- Existence ≠ package name. A hit proves the capability exists upstream; the owning package comes from the folder map or CPM, not from the hit.
- Existence ≠ reuse. The local copy may be ahead of upstream. Run a divergence check before swapping anything out.
- A local symbol name is the worst possible query. It is the one string guaranteed not to appear in another project’s code.
- The corpus is thin outside Unity. A handful of Cocos projects plus the foundation — check
assets/corpus-summary.jsonfor the current count, do not assume it is still three. A Cocos miss is weak evidence of absence and must be reported with its scope.
References
Section titled “References”references/doc-search-contract.md— SSOT: corpus composition, tool signatures and limits, result shape, MCP-absence protocol.references/query-technique.md— SSOT: how to shape a query (HyDE, multi-query + RRF, step-back, decomposition) and how much to over-retrieve, with the retrieval literature each rule comes from.t1k-cocos-base-knowledge-sweep— the Cocos consumer; adds the generated 21-assembly allowlist, a project detector, and the prior-art table its four consumers read.t1k-mcp-management— registration, credentials, auto-install policy for this server.rules/negative-result-scope.md— why a miss must state its scope.rules/library-quality-mandate.md— the five-part pass-test § Contribute back gates on; the zero-tech-debt-budget framing behind the “generic by charter, immediately” trigger.rules/development-principles.md— § “SSOT — No Duplicates”, why a corpus hit blocks promoting a rival implementation.rules/pinned-baseline-test-companion.md— why § Sizing the delta’s multipliers and hours-per-point anchor are stated as defaults with a review trigger, not facts.