Consolidating AI concepts into /ai — dropping the lossy duplicate from /concepts
The /concepts deck carried a derived copy of the 66 AI cards that had lost its model answers, so AI self-attack cards there showed questions with no answer. The copy was byte-identical to the dedicated /ai deck, so removed it and made /ai the single source for AI.
Context
While auditing self-attack coverage, found that /concepts (the CONCEPTS array) actually held 202 cards — 136 real concept cards plus 66 AI cards with ai- prefixed ids and domain: "ai". Those 66 were built at module load by AI_CONCEPTS.map(...), and the map only copied a subset of fields: it kept title/ko/rawEn/explainEn/flow/code/probes but dropped probeAnswers and all the bilingual fields (and pinned the same generic three failureModes on all 66). The dedicated /ai deck (AI_CONCEPTS, 66 cards) had the full data including the model answers.
Verified with a tsx comparison that the two decks are the same content: id stems matched 66/66 (ai-token ↔ token), and title/ko/rawEn/code matched 66/66. The only difference was the missing probeAnswers on the /concepts copy. So on /concepts, 198 AI self-attack questions rendered with no model answer, while the identical questions on /ai had answers.
Options considered
- Generate model answers for the 66
/conceptsAI cards — fills the gap, keeps/conceptsself-contained. Cost: an agent workflow (tokens) to write 198 answers; and it duplicates content that already exists answered on/ai, so two copies to maintain. Reversibility: easy. - Make
/conceptsreuse/ai's answered data — point the AI slot at the fullAI_CONCEPTSobjects instead of the lossy map. Single source, both pages complete. Cost: reconcile id/shape differences (theai-prefix, domain tagging). Reversibility: medium. - Remove the AI domain from
/concepts, consolidate into/ai—/aiis already the dedicated AI deck with full answers; drop the duplicate entirely. Cost:/conceptsno longer lists AI topics (but they're one tab away on/ai). Reversibility: easy — re-add the spread.
Chosen + Why
Option 3. The duplicate was pure cost with no benefit: identical content, lossier, and a second place to keep in sync. /ai is the purpose-built AI deck (full bilingual fields, model answers, learning path), so it should be the single source. No content is lost — every AI topic stays on /ai, answered.
Trade-off accepted
/concepts no longer surfaces AI cards, so someone browsing only /concepts won't see AI topics inline; they have to go to /ai. Accepted because the two are separate tracks anyway and the duplicate was actively misleading (unanswered self-attacks).
Reversibility
Easy (two-way). Re-adding ...aiConcepts to the CONCEPTS spread and the ai domain restores the old behavior in one edit.
Verified by
- tsx audit pre-change: 202 cards, 66
ai-with 0probeAnswers; content match 66/66 vsAI_CONCEPTS. - tsx audit post-change:
CONCEPTS= 136, 0ai-ids, 0domain==="ai",CONCEPT_DOMAINShas noai;AI_CONCEPTSstill 66, all answered. tsc --noEmitclean (after fixing two dangling"ai"references inlib/concept-sparring.ts).next buildclean.- Live (digest match, basic-auth):
/conceptsand/aiboth 200;/conceptsbundle no longer carries the AI token KO text;/aibundle still does.
Discussion artifacts
Owner was asked (with trade-offs) how to handle the duplicate and chose "consolidate into /ai".
Commit
eac1931