{"record":{"id":"34647dcb4dbbbd16","repo":"affaan-m/ECC","slug":"project-memory-gitignore-does-not-contain-the-req","errorCode":null,"errorMessage":"Project memory .gitignore does not contain the required fail-closed rules.","messagePattern":"Project memory \\.gitignore does not contain the required fail-closed rules\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/memory-vault.js","lineNumber":257,"sourceCode":"  if (operationError) throw operationError;\n  if (cleanupError) throw cleanupError;\n}\n\nfunction ensureProjectScopeIgnored(roots, scope) {\n  if (scope !== 'project') return;\n  const root = roots.project;\n  const ignorePath = path.join(root, '.gitignore');\n  try {\n    writeCreateOnlyTextFile(ignorePath, PROJECT_MEMORY_GITIGNORE, root);\n  } catch (error) {\n    if (!error || error.code !== 'EEXIST') throw error;\n    const existing = readRegularTextFile(ignorePath, {\n      label: 'project memory .gitignore',\n      maxBytes: MAX_DOCUMENT_BYTES,\n      trustedRoot: root,\n    });\n    if (existing !== PROJECT_MEMORY_GITIGNORE) {\n      throw new Error(\n        'Project memory .gitignore does not contain the required fail-closed rules.'\n      );\n    }\n  }\n}\n\nfunction normalizeScopes(scopes = MEMORY_SCOPES) {\n  const values = Array.isArray(scopes) ? scopes : [scopes];\n  return uniqueStrings(values, {\n    label: 'scopes',\n    limit: MEMORY_SCOPES.length,\n    validator: value => validateEnum(value, MEMORY_SCOPES, 'memory scope'),\n  });\n}\n\nfunction initializeVault(options = {}) {\n  const roots = options.roots || resolveVaultRoots(options);\n  const scopes = normalizeScopes(options.scopes || DEFAULT_RECALL_SCOPES);","sourceCodeStart":239,"sourceCodeEnd":275,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/memory-vault.js#L239-L275","documentation":"ensureProjectScopeIgnored verifies that the project memory directory's .gitignore exactly matches the library's required fail-closed content (PROJECT_MEMORY_GITIGNORE). If a pre-existing .gitignore differs at all, it throws this error rather than silently overwriting user content. This guarantees project-scope memories are never committed to git.","triggerScenarios":"Calling saveMemory or directories for a project-scoped memory when a .gitignore already exists in the project memory directory but its content differs from the canonical PROJECT_MEMORY_GITIGNORE string.","commonSituations":"A user or tool manually edited the vault .gitignore (added comments, different rules); an older library version wrote a different .gitignore format and the library was upgraded; a formatter normalized the file (trailing newline changes).","solutions":["Delete the existing .gitignore in the project memory directory so the library recreates it with the required rules.","Or replace its content with the exact canonical PROJECT_MEMORY_GITIGNORE text.","Check git history of the vault to see what changed and restore the canonical content."],"exampleFix":"// before (edited .gitignore)\n# my notes\n*\n// after\ncat scripts/lib/memory-vault.js | grep -A5 PROJECT_MEMORY_GITIGNORE  # copy exact content into the vault .gitignore, or: rm <vault>/project/.gitignore","handlingStrategy":"validation","validationCode":"const expected = PROJECT_MEMORY_GITIGNORE; // canonical content from the library\nconst current = fs.readFileSync(path.join(vaultProjectDir, '.gitignore'), 'utf8');\nif (current !== expected) fs.writeFileSync(path.join(vaultProjectDir, '.gitignore'), expected);","typeGuard":null,"tryCatchPattern":"try {\n  saveMemory(memory);\n} catch (err) {\n  if (err.message.includes('fail-closed rules')) {\n    // restore canonical .gitignore, then retry the save\n  } else throw err;\n}","preventionTips":["Never hand-edit .gitignore files inside the memory vault.","After upgrading the library, let it recreate vault config files.","Treat the vault directory as library-managed; modify only via APIs.","Add a CI check comparing vault .gitignore to the canonical constant if the vault is shared."],"tags":["gitignore","validation","memory-vault"],"backgroundTag":"invalid-config-value","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}