{"record":{"id":"287202a584766fc0","repo":"stablyai/orca","slug":"refusing-to-copy-a-config-template-from-the-primar","errorCode":null,"errorMessage":"Refusing to copy a config template from the primary ~/.codex","messagePattern":"Refusing to copy a config template from the primary ~/\\.codex","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"config/scripts/run-codex-real-account-validation.mjs","lineNumber":149,"sourceCode":"    onboarding: { flowVersion: 2, closedAt: 1, outcome: 'completed', lastCompletedStep: 3 },\n    ui: { contextualToursAutoEligible: false, projectOrderManualDefaultNoticeDismissed: true }\n  }\n  await writeFile(\n    path.join(layout.userDataDir, 'orca-data.json'),\n    `${JSON.stringify(profile, null, 2)}\\n`\n  )\n}\n\nasync function installCodexConfigTemplate(layout, templatePath) {\n  if (!templatePath) {\n    return\n  }\n  const resolvedTemplate = await realpath(path.resolve(templatePath))\n  const primaryCodexHome = path.join(layout.primaryHome, '.codex')\n  // Why: validation must never bootstrap itself from the user's live Codex\n  // configuration, even when a caller passes that path accidentally.\n  if (isWithin(resolvedTemplate, primaryCodexHome)) {\n    throw new Error('Refusing to copy a config template from the primary ~/.codex')\n  }\n  await mkdir(path.join(layout.homeDir, '.codex'), { recursive: true, mode: 0o700 })\n  await copyFile(resolvedTemplate, path.join(layout.homeDir, '.codex', 'config.toml'))\n}\n\nasync function fingerprintFile(filePath) {\n  try {\n    const stat = await lstat(filePath)\n    if (!stat.isFile()) {\n      return { exists: true, type: stat.isSymbolicLink() ? 'symlink' : 'other' }\n    }\n    const contents = await readFile(filePath)\n    return {\n      exists: true,\n      type: 'file',\n      size: stat.size,\n      mtimeMs: stat.mtimeMs,\n      sha256: createHash('sha256').update(contents).digest('hex')","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/config/scripts/run-codex-real-account-validation.mjs#L131-L167","documentation":"Thrown by the Codex validation harness when --config-template points to a file inside the primary ~/.codex directory. The harness copies the template into the disposable home's ~/.codex/config.toml, and bootstrapping from the user's live Codex config would contaminate the validation boundary. The check uses realpath on the template and isWithin() against primaryHome/.codex.","triggerScenarios":"Passing --config-template ~/.codex/config.toml or any path that resolves (after symlinks) inside the primary ~/.codex directory. The codex-lb scenario requires a template, so this guard commonly pairs with that scenario.","commonSituations":"A developer points the template at their real Codex config by accident, or a symlink inside ~/.codex resolves the template path.","solutions":["Create a config template outside ~/.codex (e.g. in the repo or /tmp) and pass that path.","If you need a copy of your config, copy it out first: `cp ~/.codex/config.toml /tmp/codex-template.toml` then pass --config-template=/tmp/codex-template.toml."],"exampleFix":"// before\nnode config/scripts/run-codex-real-account-validation.mjs --scenario codex-lb --config-template ~/.codex/config.toml\n// after\ncp ~/.codex/config.toml /tmp/codex-lb-template.toml\nnode config/scripts/run-codex-real-account-validation.mjs --scenario codex-lb --config-template /tmp/codex-lb-template.toml","handlingStrategy":"validation","validationCode":"const resolvedTemplate = await realpath(path.resolve(templatePath))\nconst primaryCodexHome = path.join(primaryHome, '.codex')\nif (isWithin(resolvedTemplate, primaryCodexHome)) {\n  throw new Error('Config template must be outside the primary ~/.codex')\n}","typeGuard":"function isOutsidePrimaryCodex(templateReal, primaryCodexHome) {\n  return !isWithin(templateReal, primaryCodexHome)\n}","tryCatchPattern":null,"preventionTips":["Always copy the template out of ~/.codex before referencing it.","Use realpath on the template path so symlinked paths cannot bypass the check."],"tags":["security","containment","validation","config-isolation"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}