{"record":{"id":"9ee0a08b9cb36592","repo":"thedotmack/claude-mem","slug":"refusing-ccs-align-write-to-profile-md","errorCode":null,"errorMessage":"Refusing CCS Align write to profile.md","messagePattern":"Refusing CCS Align write to profile\\.md","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/services/integrations/CcsAlignMiddleCache.ts","lineNumber":286,"sourceCode":"    }\n  }\n  return { excludedObsIds, excludedToolUseIds };\n}\n\n/**\n * Refuse any write that escapes the seat-owned CCS Align root, targets\n * `profile.md`, or lands inside an `agents/.../memory/log` tree (that is the\n * #3931 pusher's seam, never Align's). Shape copied from\n * `assertSafeAwarenessLogPath` (#3931).\n */\nexport function assertSafeMiddleCachePath(dataRoot: string, viewerId: string, filePath: string): void {\n  const expectedRoot = path.resolve(ccsAlignViewerDir(dataRoot, viewerId));\n  const resolved = path.resolve(filePath);\n  if (!resolved.startsWith(expectedRoot + path.sep) && resolved !== expectedRoot) {\n    throw new Error('Refusing CCS Align write outside the seat-owned ccs-align root');\n  }\n  if (path.basename(resolved) === 'profile.md') {\n    throw new Error('Refusing CCS Align write to profile.md');\n  }\n  if (/(^|[\\\\/])agents[\\\\/].*[\\\\/]memory[\\\\/]log([\\\\/]|$)/.test(resolved)) {\n    throw new Error('Refusing CCS Align write into agents/**/memory/log (that seam belongs to #3931)');\n  }\n}\n\nexport function buildCcsAlignRecord(obs: CcsAlignObservationInput, now: Date = new Date()): CcsAlignMiddleRecord {\n  return {\n    v: RECORD_VERSION,\n    id: obs.id,\n    type: obs.type,\n    title: obs.title ?? null,\n    created_at: obs.created_at ?? null,\n    project: obs.project ?? null,\n    agent_id: obs.agent_id ?? null,\n    source: obs.source ?? 'worker',\n    line: formatCcsAlignLine(obs, now),\n  };","sourceCodeStart":268,"sourceCodeEnd":304,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d8bc9755e74915e5c3b999181e10a67c889bce2a/src/services/integrations/CcsAlignMiddleCache.ts#L268-L304","documentation":"assertSafeMiddleCachePath() additionally forbids writing to any file named profile.md within the ccs-align root. profile.md is a protected, separately-owned artifact (the awareness-log seam, cf. assertSafeAwarenessLogPath); landing observations over it would corrupt data managed by another subsystem, so the guard throws unconditionally on that basename.","triggerScenarios":"landObservationsInMiddleCache() passes a filePath whose path.basename() is 'profile.md' — e.g. the cache filename was derived from a profile/observations key, or a constant pointed at profile.md instead of an observations file.","commonSituations":"A config or map keyed by file type routes profile data through the observation-write path; a filename template like '<name>.md' is fed 'profile'; two features share a file-naming convention and one targets the protected profile artifact.","solutions":["Change the target filename to a non-reserved name (e.g. observations.md) before calling landObservationsInMiddleCache.","Route profile.md writes through the dedicated profile/awareness API instead of the middle-cache writer.","Add a caller-side check: if (path.basename(filePath) === 'profile.md') skip or rename."],"exampleFix":"// before\nconst target = path.join(cacheDir, 'profile.md');\n\n// after\nconst target = path.join(cacheDir, 'observations.md');","handlingStrategy":"validation","validationCode":"import path from 'path';\nif (path.basename(targetPath) === 'profile.md') {\n  throw new Error('profile.md is protected; use the profile API');\n}","typeGuard":null,"tryCatchPattern":"try {\n  landObservationsInMiddleCache(dataRoot, viewerId, filePath, observations);\n} catch (err) {\n  if (err instanceof Error && err.message.includes('profile.md')) {\n    // route through the profile-update API instead of the cache writer\n  } else throw err;\n}","preventionTips":["Keep a single RESERVED_FILENAMES constant ('profile.md') checked by all writers in this subsystem.","Never build target filenames from unvalidated keys or templates.","Route profile content through its dedicated API, never the observation writer."],"tags":["filesystem","protected-file","validation"],"backgroundTag":"path-traversal-blocked","analyzedSha":"d8bc9755e74915e5c3b999181e10a67c889bce2a","analyzedAt":"2026-09-17T16:40:26.182Z","contentChangedAt":"2026-09-17T16:40:26.182Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}