{"record":{"id":"dbcb5cb25c8f7c42","repo":"ruvnet/RuView","slug":"duplicate-brain-id-record-id-dbcb5c","errorCode":null,"errorMessage":"duplicate brain id: ${record.id}","messagePattern":"duplicate brain id: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"harness/ruview/src/brain.js","lineNumber":57,"sourceCode":"  if (INJECTION.test(combined)) errors.push('record contains instruction-like prompt injection');\n  return errors;\n}\n\nexport function loadBrain(path = CORPUS_PATH) {\n  const raw = readFileSync(path, 'utf8').replace(/\\r\\n/g, '\\n');\n  if (Buffer.byteLength(raw) > 1_048_576) throw new Error('brain corpus exceeds 1 MiB');\n  const records = raw.split('\\n').filter(Boolean).map((line, index) => {\n    if (Buffer.byteLength(line) > 16_384) throw new Error(`brain line ${index + 1}: exceeds 16 KiB`);\n    let record;\n    try { record = JSON.parse(line); } catch (error) { throw new Error(`brain line ${index + 1}: ${error.message}`); }\n    const errors = validateBrainRecord(record, { canonical: true });\n    if (errors.length) throw new Error(`brain line ${index + 1}: ${errors.join('; ')}`);\n    return Object.freeze(record);\n  });\n  if (records.length > 1000) throw new Error('brain corpus exceeds 1000 records');\n  const ids = new Set();\n  for (const record of records) {\n    if (ids.has(record.id)) throw new Error(`duplicate brain id: ${record.id}`);\n    ids.add(record.id);\n  }\n  return { records, digest: sha256(raw), bytes: Buffer.byteLength(raw) };\n}\n\nfunction terms(value) {\n  return new Set(String(value).toLowerCase().match(/[a-z0-9][a-z0-9_-]{1,}/g) || []);\n}\n\nexport function searchBrain(query, { limit = 8, path = CORPUS_PATH } = {}) {\n  const wanted = terms(query);\n  if (!wanted.size) return [];\n  const { records, digest } = loadBrain(path);\n  return records.map((record) => {\n    const title = terms(record.title);\n    const body = terms(record.content);\n    const tags = new Set(record.tags.map((tag) => tag.toLowerCase()));\n    let score = 0;","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/ruvnet/RuView/blob/4685618388a5e49fad5b3005806f3bdd6a7c25c3/harness/ruview/src/brain.js#L39-L75","documentation":"Record ids must be unique across the corpus; loadBrain tracks ids in a Set and throws, naming the duplicated id, when a later line reuses one. Ids are lowercase slugs, so independently written lessons about the same topic naturally collide.","triggerScenarios":"Copying an existing record line and editing the content without changing the id, or a git merge/cherry-pick that brings the same record in twice.","commonSituations":"Copy-modify authoring, duplicate records from parallel branches, two contributors adding the same lesson name.","solutions":["Rename the newer record's id to a distinct slug (e.g. append '-ci' or a qualifier)","Locate both occurrences: grep -n '\"id\": \"<duplicated-id>\"' harness/ruview/brain/corpus/core.jsonl","Prefer extending the existing record's content/tags over adding a near-duplicate"],"exampleFix":"// before (line 12 and line 48)\n{\"id\":\"cargo-timeout\", ...}\n{\"id\":\"cargo-timeout\", ...}\n\n// after\n{\"id\":\"cargo-timeout\", ...}\n{\"id\":\"cargo-timeout-ci\", ...}","handlingStrategy":"validation","validationCode":"import { readFileSync } from 'node:fs';\nfunction duplicateIds(path) {\n  const seen = new Set();\n  const dupes = [];\n  for (const line of readFileSync(path, 'utf8').split('\\n')) {\n    if (!line.trim()) continue;\n    const id = JSON.parse(line).id;\n    if (seen.has(id)) dupes.push(id); else seen.add(id);\n  }\n  return dupes;\n}","typeGuard":null,"tryCatchPattern":"try {\n  const brain = loadBrain(path);\n} catch (error) {\n  if (error.message.startsWith('duplicate brain id')) {\n    console.error(`id collision: ${error.message} — rename the newer record`);\n    process.exit(1);\n  }\n  throw error;\n}","preventionTips":["Derive ids from the lesson topic plus a distinguishing qualifier so parallel authors rarely collide","Run a duplicate-id lint (grep/awk over the id field) before committing corpus changes","After merges and cherry-picks, re-scan the corpus for repeated ids"],"tags":["validation","uniqueness","jsonl","brain","ruview"],"backgroundTag":null,"analyzedSha":"4685618388a5e49fad5b3005806f3bdd6a7c25c3","analyzedAt":"2026-08-16T06:09:40.886Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}