cohorte 3.0.0-dev.5 → 3.0.0-dev.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/assets/manifest.json +16 -6
  2. package/assets/prompts/agents/brainstormer.md +3 -0
  3. package/assets/prompts/agents/spec-author.md +3 -0
  4. package/assets/schemas/commands.schema.json +7 -0
  5. package/assets/schemas/config.schema.json +22 -0
  6. package/dist/bundle-manifest.json +72 -48
  7. package/dist/chunks/align-ds-r_X_1aQ_.mjs +93 -0
  8. package/dist/chunks/align-ds-r_X_1aQ_.mjs.map +1 -0
  9. package/dist/chunks/audit-B4ZWQ_DI.mjs +179 -0
  10. package/dist/chunks/audit-B4ZWQ_DI.mjs.map +1 -0
  11. package/dist/chunks/brainstorm-DasVwI1D.mjs +123 -0
  12. package/dist/chunks/brainstorm-DasVwI1D.mjs.map +1 -0
  13. package/dist/chunks/build-crOld8gE.mjs +19 -0
  14. package/dist/chunks/build-crOld8gE.mjs.map +1 -0
  15. package/dist/chunks/{catalogue-B5uFqfzJ.mjs → catalogue-IaCJdfB8.mjs} +4 -4
  16. package/dist/chunks/{catalogue-B5uFqfzJ.mjs.map → catalogue-IaCJdfB8.mjs.map} +1 -1
  17. package/dist/chunks/{compose-CKo_q39e.mjs → compose-DRKjQcn0.mjs} +42 -23
  18. package/dist/chunks/compose-DRKjQcn0.mjs.map +1 -0
  19. package/dist/chunks/{config-DefHA2Lw.mjs → config-Cqu5XQoP.mjs} +2 -2
  20. package/dist/chunks/{config-DefHA2Lw.mjs.map → config-Cqu5XQoP.mjs.map} +1 -1
  21. package/dist/chunks/{contract-BkMjU1kR.mjs → contract-DjssDPpS.mjs} +66 -26
  22. package/dist/chunks/contract-DjssDPpS.mjs.map +1 -0
  23. package/dist/chunks/{diff-D_0hBwHl.mjs → diff-Qw0II0sj.mjs} +2 -2
  24. package/dist/chunks/{diff-D_0hBwHl.mjs.map → diff-Qw0II0sj.mjs.map} +1 -1
  25. package/dist/chunks/{discover-BJMwXyGL.mjs → discover-BZPolSZG.mjs} +2 -2
  26. package/dist/chunks/{discover-BJMwXyGL.mjs.map → discover-BZPolSZG.mjs.map} +1 -1
  27. package/dist/chunks/{doctor-CginW8y8.mjs → doctor-DcDFPvQM.mjs} +6 -6
  28. package/dist/chunks/{doctor-CginW8y8.mjs.map → doctor-DcDFPvQM.mjs.map} +1 -1
  29. package/dist/chunks/fix-B_oGzGVn.mjs +82 -0
  30. package/dist/chunks/fix-B_oGzGVn.mjs.map +1 -0
  31. package/dist/chunks/fleet-yWHQY2ya.mjs +297 -0
  32. package/dist/chunks/fleet-yWHQY2ya.mjs.map +1 -0
  33. package/dist/chunks/{init-CP6puNbE.mjs → init--FxxkrcT.mjs} +2 -2
  34. package/dist/chunks/{init-CP6puNbE.mjs.map → init--FxxkrcT.mjs.map} +1 -1
  35. package/dist/chunks/intake-Dd1KVXnO.mjs +12 -0
  36. package/dist/chunks/intake-Dd1KVXnO.mjs.map +1 -0
  37. package/dist/chunks/loop-BWsUpyus.mjs +212 -0
  38. package/dist/chunks/loop-BWsUpyus.mjs.map +1 -0
  39. package/dist/chunks/{migrate-DybihKzZ.mjs → migrate-DuYCAbE3.mjs} +2 -2
  40. package/dist/chunks/{migrate-DybihKzZ.mjs.map → migrate-DuYCAbE3.mjs.map} +1 -1
  41. package/dist/chunks/obsidian-BHLkXx_H.mjs +235 -0
  42. package/dist/chunks/obsidian-BHLkXx_H.mjs.map +1 -0
  43. package/dist/chunks/patch-sAgVqjpx.mjs +50 -0
  44. package/dist/chunks/patch-sAgVqjpx.mjs.map +1 -0
  45. package/dist/chunks/{policy-Clypo20s.mjs → policy-Du7WVBFX.mjs} +4 -4
  46. package/dist/chunks/{policy-Clypo20s.mjs.map → policy-Du7WVBFX.mjs.map} +1 -1
  47. package/dist/chunks/{reconcile-czNaLOP6.mjs → reconcile-BHn66X3C.mjs} +3 -3
  48. package/dist/chunks/{reconcile-czNaLOP6.mjs.map → reconcile-BHn66X3C.mjs.map} +1 -1
  49. package/dist/chunks/refactor-CoNoqLZr.mjs +153 -0
  50. package/dist/chunks/refactor-CoNoqLZr.mjs.map +1 -0
  51. package/dist/chunks/retro-Dr-2RTNN.mjs +78 -0
  52. package/dist/chunks/retro-Dr-2RTNN.mjs.map +1 -0
  53. package/dist/chunks/review-ZsBqp3vZ.mjs +35 -0
  54. package/dist/chunks/review-ZsBqp3vZ.mjs.map +1 -0
  55. package/dist/chunks/{run-CgTWYlcd.mjs → run-NGAxdsIX.mjs} +28 -5
  56. package/dist/chunks/run-NGAxdsIX.mjs.map +1 -0
  57. package/dist/chunks/{schema-C9QbUW4H.mjs → schema-Bq9qtgsd.mjs} +9 -4
  58. package/dist/chunks/schema-Bq9qtgsd.mjs.map +1 -0
  59. package/dist/chunks/ship-BizfUe62.mjs +140 -0
  60. package/dist/chunks/ship-BizfUe62.mjs.map +1 -0
  61. package/dist/chunks/spec-C2h3U64g.mjs +65 -0
  62. package/dist/chunks/spec-C2h3U64g.mjs.map +1 -0
  63. package/dist/chunks/spec-path-tptqR7W8.mjs +10 -0
  64. package/dist/chunks/spec-path-tptqR7W8.mjs.map +1 -0
  65. package/dist/chunks/{src-r0ECB1UJ.mjs → src-Bfr1yzsn.mjs} +3 -3
  66. package/dist/chunks/{src-r0ECB1UJ.mjs.map → src-Bfr1yzsn.mjs.map} +1 -1
  67. package/dist/chunks/{src-DZazJCp1.mjs → src-CPW2_Ons.mjs} +101 -17
  68. package/dist/chunks/src-CPW2_Ons.mjs.map +1 -0
  69. package/dist/chunks/{src-CmFjh4M0.mjs → src-DNsLSxgm.mjs} +2 -2
  70. package/dist/chunks/{src-CmFjh4M0.mjs.map → src-DNsLSxgm.mjs.map} +1 -1
  71. package/dist/chunks/{src-DcU4IXMe.mjs → src-DbS9gkJy.mjs} +2 -2
  72. package/dist/chunks/{src-DcU4IXMe.mjs.map → src-DbS9gkJy.mjs.map} +1 -1
  73. package/dist/chunks/{src-s7YRvk0t.mjs → src-yi5whv3n.mjs} +4 -2
  74. package/dist/chunks/src-yi5whv3n.mjs.map +1 -0
  75. package/dist/chunks/update-pipeline-Du-Gu1Pl.mjs +56 -0
  76. package/dist/chunks/update-pipeline-Du-Gu1Pl.mjs.map +1 -0
  77. package/dist/cli.mjs +29 -18
  78. package/dist/cli.mjs.map +1 -1
  79. package/package.json +1 -1
  80. package/dist/chunks/brainstorm-BwKA6yZP.mjs +0 -7
  81. package/dist/chunks/brainstorm-BwKA6yZP.mjs.map +0 -1
  82. package/dist/chunks/compose-CKo_q39e.mjs.map +0 -1
  83. package/dist/chunks/contract-BkMjU1kR.mjs.map +0 -1
  84. package/dist/chunks/fix-D4Tj8RVA.mjs +0 -18
  85. package/dist/chunks/fix-D4Tj8RVA.mjs.map +0 -1
  86. package/dist/chunks/review-BDdjb6kB.mjs +0 -17
  87. package/dist/chunks/review-BDdjb6kB.mjs.map +0 -1
  88. package/dist/chunks/run-CgTWYlcd.mjs.map +0 -1
  89. package/dist/chunks/schema-C9QbUW4H.mjs.map +0 -1
  90. package/dist/chunks/ship-DTuLGoaJ.mjs +0 -19
  91. package/dist/chunks/ship-DTuLGoaJ.mjs.map +0 -1
  92. package/dist/chunks/spec-Bq0P3jVh.mjs +0 -20
  93. package/dist/chunks/spec-Bq0P3jVh.mjs.map +0 -1
  94. package/dist/chunks/src-DZazJCp1.mjs.map +0 -1
  95. package/dist/chunks/src-s7YRvk0t.mjs.map +0 -1
@@ -1,7 +1,7 @@
1
1
  import { n as sha256Hex, t as canonicalJson } from "./canonical-C8UxeEmB.mjs";
2
2
  import "./src-Cu3TxNob.mjs";
3
3
  import "./contract-bQ9FJl4N.mjs";
4
- import { r as specContentSha256, s as DEFAULT_CONFIG } from "./schema-C9QbUW4H.mjs";
4
+ import { r as specContentSha256, s as DEFAULT_CONFIG } from "./schema-Bq9qtgsd.mjs";
5
5
  import { createHash } from "node:crypto";
6
6
  import { appendFile, copyFile, cp, lstat, mkdir, readFile, readdir, rename, rm, stat, unlink, writeFile } from "node:fs/promises";
7
7
  import { dirname, join, relative, resolve, sep } from "node:path";
@@ -925,4 +925,4 @@ async function applyReconcile(options) {
925
925
  //#endregion
926
926
  export { applyV2Import as a, rollbackV2Import as c, planInit as i, deriveDesiredState as l, planReconcile as n, exportV2 as o, applyInit as r, planV2Import as s, applyReconcile as t };
927
927
 
928
- //# sourceMappingURL=src-CmFjh4M0.mjs.map
928
+ //# sourceMappingURL=src-DNsLSxgm.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"src-CmFjh4M0.mjs","names":[],"sources":["../../../../packages/project-model/src/desired/index.ts","../../../../packages/project-model/src/drift/index.ts","../../../../packages/project-model/src/import-v2/index.ts","../../../../packages/project-model/src/init/index.ts","../../../../packages/project-model/src/reconcile/index.ts"],"sourcesContent":["import { canonicalJson, type JsonValue, sha256Hex } from '@cohorte/base';\nimport type { CohorteConfig } from '@cohorte/config/schema';\nimport { stringify } from 'yaml';\nimport type { DesiredState, ProjectModel } from '../contract.ts';\n\nexport interface DesiredStateInput {\n model: ProjectModel;\n config: CohorteConfig;\n cohorteVersion: string;\n /** skill id -> version */\n skills: Readonly<Record<string, string>>;\n}\n\nexport function deriveDesiredState(input: DesiredStateInput): DesiredState {\n const modelYaml = stringify(input.model);\n const generatedArtifacts = new Map<string, string>();\n for (const path of input.model.generatedArtifacts.value) {\n const relative = path.replace(/^\\.cohorte\\//u, '');\n if (relative === 'manifest.yaml' || relative === 'project.yaml') continue;\n generatedArtifacts.set(\n relative,\n canonicalJson({\n path: relative,\n model: input.model,\n config: input.config,\n skills: input.skills,\n } as unknown as JsonValue),\n );\n }\n const manifest = {\n schemaVersion: 1,\n cohorteVersion: input.cohorteVersion,\n createdWith: input.cohorteVersion,\n protocol: { min: '3.0', max: '3.x' },\n stateSchemaVersion: 1,\n generated: [\n {\n path: 'project.yaml',\n templateId: 'project-model/v1',\n templateSha256: sha256Hex(modelYaml),\n renderedSha256: sha256Hex(modelYaml),\n },\n {\n path: '.gitignore',\n templateId: 'cohorte/gitignore/v1',\n templateSha256: sha256Hex('state/\\nruns/\\n'),\n renderedSha256: sha256Hex('state/\\nruns/\\n'),\n },\n {\n path: 'generated/.gitkeep',\n templateId: 'cohorte/generated-dir/v1',\n templateSha256: sha256Hex(''),\n renderedSha256: sha256Hex(''),\n },\n ...[...generatedArtifacts.keys()].map((path) => ({\n path,\n templateId: path,\n templateSha256: sha256Hex(generatedArtifacts.get(path) as string),\n renderedSha256: sha256Hex(generatedArtifacts.get(path) as string),\n })),\n ],\n };\n const manifestYaml = stringify(manifest);\n const builtin: Record<string, string> = {\n 'manifest.yaml': manifestYaml,\n 'project.yaml': modelYaml,\n 'config.yaml': 'schemaVersion: 1\\n',\n 'ownership.yaml': 'surfaces: {}\\n',\n '.gitignore': 'state/\\nruns/\\n',\n 'generated/.gitkeep': '',\n };\n const files = new Set([...Object.keys(builtin), ...generatedArtifacts.keys()]);\n const stateFiles = [...files].sort().map((path) => ({\n path,\n class: path === 'config.yaml' || path === 'ownership.yaml' ? ('human' as const) : ('generated' as const),\n sha256: sha256Hex(builtin[path] ?? generatedArtifacts.get(path) ?? ''),\n content: builtin[path] ?? generatedArtifacts.get(path) ?? '',\n ...(input.skills[path] === undefined ? {} : { templateId: path }),\n }));\n return { cohorteVersion: input.cohorteVersion, files: stateFiles };\n}\n","import { readdir, readFile } from 'node:fs/promises';\nimport { join, relative } from 'node:path';\nimport { type Clock, sha256Hex } from '@cohorte/base';\nimport { parse } from 'yaml';\nimport type { ActualState, DesiredState, DriftEntry, DriftReport } from '../contract.ts';\n\nexport async function readActualState(root: string): Promise<ActualState> {\n const stateRoot = join(root, '.cohorte');\n let manifest = null;\n try {\n manifest = parse(await readFile(join(stateRoot, 'manifest.yaml'), 'utf8')) as ActualState['manifest'];\n } catch {\n return { manifest: null, files: [] };\n }\n const files: ActualState['files'] = [];\n const visit = async (dir: string): Promise<void> => {\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {\n if (entry.name === 'state' || entry.name === 'runs') continue;\n const path = join(dir, entry.name);\n if (entry.isDirectory()) await visit(path);\n else if (entry.isFile()) {\n const bytes = await readFile(path);\n const relativePath = relative(stateRoot, path).split('\\\\').join('/');\n const generated =\n relativePath === 'manifest.yaml'\n ? { path: relativePath, templateId: 'cohorte/manifest/v1', renderedSha256: sha256Hex(bytes) }\n : manifest?.generated.find((item) => item.path === relativePath);\n files.push({\n path: relativePath,\n class: generated ? 'generated' : 'human',\n sha256: sha256Hex(bytes),\n ...(generated?.templateId ? { templateId: generated.templateId } : {}),\n });\n }\n }\n } catch {\n return;\n }\n };\n await visit(stateRoot);\n return { manifest, files };\n}\n\nexport function diffStates(desired: DesiredState, actual: ActualState, clock: Clock): DriftReport {\n const desiredByPath = new Map(desired.files.map((file) => [file.path, file]));\n const actualByPath = new Map(actual.files.map((file) => [file.path, file]));\n const recorded = new Map((actual.manifest?.generated ?? []).map((file) => [file.path, file.renderedSha256]));\n const paths = [...new Set([...desiredByPath.keys(), ...actualByPath.keys()])].sort();\n const entries = paths.flatMap((path): DriftEntry[] => {\n const expected = desiredByPath.get(path);\n const found = actualByPath.get(path);\n const recordedSha256 = recorded.get(path);\n if (!found && expected)\n return [\n {\n target: path,\n class: expected.class,\n diff: 'absent' as const,\n desiredSha256: expected.sha256,\n ...(recordedSha256 ? { recordedSha256 } : {}),\n detail: 'desired file is absent',\n },\n ];\n if (found && !expected)\n return [\n {\n target: path,\n class: found.class,\n diff: found.class === 'generated' ? ('potential-deletion' as const) : ('unknown' as const),\n actualSha256: found.sha256,\n ...(recordedSha256 ? { recordedSha256 } : {}),\n detail: 'file exists but is not desired',\n },\n ];\n if (!found || !expected) throw new Error('unreachable drift entry');\n if (found.sha256 === expected.sha256) return [];\n if (found.class === 'human')\n return [\n {\n target: path,\n class: found.class,\n diff: 'human-change' as const,\n desiredSha256: expected.sha256,\n actualSha256: found.sha256,\n ...(recordedSha256 ? { recordedSha256 } : {}),\n detail: 'content changed in a human-owned file',\n },\n ];\n if (recordedSha256 === undefined || found.sha256 === recordedSha256)\n return [\n {\n target: path,\n class: expected.class,\n diff: 'expected-change' as const,\n desiredSha256: expected.sha256,\n actualSha256: found.sha256,\n ...(recordedSha256 ? { recordedSha256 } : {}),\n detail: 'generated content differs from the previous render',\n },\n ];\n return [\n {\n target: path,\n class: found.class,\n diff: 'conflict' as const,\n desiredSha256: expected.sha256,\n actualSha256: found.sha256,\n recordedSha256,\n detail: 'content changed since the recorded render',\n },\n ];\n });\n return { schemaVersion: 1, generatedAt: clock.now(), entries };\n}\n","import { createHash } from 'node:crypto';\nimport { cp, lstat, mkdir, readdir, readFile, rename, rm, stat, writeFile } from 'node:fs/promises';\nimport { dirname, join, relative, resolve, sep } from 'node:path';\nimport { canonicalJson, sha256Hex } from '@cohorte/base';\nimport { DEFAULT_CONFIG, type Spec, specContentSha256 } from '@cohorte/config/schema';\nimport { parse, stringify } from 'yaml';\nimport type { ProjectModel } from '../contract.ts';\n\nconst FORMAT = 'cohorte-v2-export';\nconst MAX_FILE_BYTES = 10 * 1024 * 1024;\nconst SKIP_DIRS = new Set(['.git', 'node_modules', '.build', 'dist', 'coverage', '.cohorte']);\nconst SECRET =\n /(^|[/\\\\])(?:\\.env(?:\\..*)?|credentials?(?:\\..*)?|secrets?(?:\\..*)?|.*token.*|.*password.*|.*api[-_]?key.*)$/iu;\n\nexport interface V2ExportFile {\n path: string;\n sha256: string;\n bytes: number;\n kind: 'config' | 'spec' | 'history' | 'marker';\n}\n\nexport interface V2ExportManifest {\n format: typeof FORMAT;\n version: 1;\n sourceVersion: string | null;\n createdAt: string;\n projectRootDigest: string;\n files: V2ExportFile[];\n excluded: Array<{ path: string; reason: string }>;\n warnings: V2ImportWarning[];\n}\n\nexport interface V2ImportWarning {\n code: string;\n path?: string;\n message: string;\n blocking: boolean;\n}\n\nexport interface V2ExportOptions {\n root: string;\n destination: string;\n now?: string;\n}\n\nexport interface V2ExportResult {\n bundleRoot: string;\n manifest: V2ExportManifest;\n checksumsPath: string;\n}\n\nexport interface V2ImportFile {\n path: string;\n content: string;\n action: 'create' | 'replace' | 'keep' | 'conflict';\n reason: string;\n}\n\nexport interface V2ImportPlan {\n bundleRoot: string;\n projectRoot: string;\n sourceVersion: string | null;\n files: V2ImportFile[];\n warnings: V2ImportWarning[];\n conflicts: string[];\n sourceDigest: string;\n targetDigest: string;\n}\n\nexport interface V2ImportOptions {\n model?: ProjectModel;\n}\n\nexport interface V2ImportReport {\n reportId: string;\n status: 'applied' | 'rolled-back';\n bundleRoot: string;\n projectRoot: string;\n backupRoot: string;\n sourceDigest: string;\n targetDigest: string;\n files: string[];\n warnings: V2ImportWarning[];\n createdAt: string;\n}\n\nexport const V2_IMPORT_FAULT_POINTS = [\n 'before-backup',\n 'after-backup',\n 'after-stage',\n 'before-rename',\n 'after-rename',\n 'before-report',\n] as const;\n\nexport type V2ImportFaultPoint = (typeof V2_IMPORT_FAULT_POINTS)[number];\n\ninterface BundleInput {\n manifest: V2ExportManifest;\n files: Map<string, string>;\n sourceDigest: string;\n}\n\nfunction normalisePath(value: string): string {\n const path = value.replaceAll('\\\\', '/');\n if (!path || path.startsWith('/') || path.split('/').some((part) => part === '..' || part === ''))\n throw new Error(`configuration/import-invalid: unsafe relative path ${JSON.stringify(value)}`);\n return path;\n}\n\nasync function walk(root: string, current = root): Promise<string[]> {\n const entries = await readdir(current, { withFileTypes: true });\n const result: string[] = [];\n for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {\n if (entry.isDirectory() && SKIP_DIRS.has(entry.name)) continue;\n const absolute = join(current, entry.name);\n const rel = relative(root, absolute).split(sep).join('/');\n if (entry.isSymbolicLink()) throw new Error(`configuration/import-symlink: refusing symbolic link ${rel}`);\n if (entry.isDirectory()) result.push(...(await walk(root, absolute)));\n else if (entry.isFile()) result.push(rel);\n }\n return result.sort();\n}\n\nfunction fileKind(path: string): V2ExportFile['kind'] {\n if (path === 'PIPELINE.md' || path === 'cohorte.config.yaml' || path.startsWith('profile/')) return 'config';\n if (path.startsWith('specs/')) return path.startsWith('specs/reports/') ? 'history' : 'spec';\n return 'marker';\n}\n\nfunction warning(code: string, message: string, path?: string, blocking = false): V2ImportWarning {\n return { code, message, ...(path === undefined ? {} : { path }), blocking };\n}\n\nasync function digestFiles(root: string, files: string[]): Promise<string> {\n const hash = createHash('sha256');\n for (const path of files) {\n hash.update(path);\n hash.update(await readFile(join(root, path)));\n }\n return hash.digest('hex');\n}\n\nfunction sourceVersion(pipeline: string | undefined): string | null {\n const match = pipeline?.match(/(?:version|core_version)\\s*[:=]\\s*[\"']?([0-9]+\\.[0-9]+\\.[0-9]+)/iu);\n return match?.[1] ?? null;\n}\n\nexport async function exportV2(options: V2ExportOptions): Promise<V2ExportResult> {\n const root = resolve(options.root);\n const destination = resolve(options.destination);\n const all = await walk(root);\n const files: V2ExportFile[] = [];\n const excluded: V2ExportManifest['excluded'] = [];\n const warnings: V2ImportWarning[] = [];\n for (const path of all) {\n if (SECRET.test(path)) {\n excluded.push({ path, reason: 'sensitive-path' });\n warnings.push(warning('sensitive-excluded', 'sensitive file excluded from export', path));\n continue;\n }\n const info = await stat(join(root, path));\n if (info.size > MAX_FILE_BYTES) {\n excluded.push({ path, reason: 'file-too-large' });\n warnings.push(warning('file-too-large', `file exceeds ${MAX_FILE_BYTES} bytes`, path, true));\n continue;\n }\n const content = await readFile(join(root, path));\n files.push({ path, sha256: sha256Hex(content), bytes: content.byteLength, kind: fileKind(path) });\n }\n const selected = files.map((file) => file.path);\n const pipeline = all.includes('PIPELINE.md') ? await readFile(join(root, 'PIPELINE.md'), 'utf8') : undefined;\n const manifest: V2ExportManifest = {\n format: FORMAT,\n version: 1,\n sourceVersion: sourceVersion(pipeline),\n createdAt: options.now ?? new Date().toISOString(),\n projectRootDigest: await digestFiles(root, selected),\n files,\n excluded,\n warnings,\n };\n await rm(destination, { recursive: true, force: true });\n await mkdir(join(destination, 'files'), { recursive: true, mode: 0o700 });\n for (const file of files) {\n const target = join(destination, 'files', file.path);\n await mkdir(dirname(target), { recursive: true, mode: 0o700 });\n await writeFile(target, await readFile(join(root, file.path)), { mode: 0o600 });\n }\n await writeFile(join(destination, 'manifest.json'), `${JSON.stringify(manifest, null, 2)}\\n`, { mode: 0o600 });\n const checksums = files\n .map((file) => `${file.sha256} files/${file.path}`)\n .concat(`${sha256Hex(canonicalJson(manifest as never))} manifest.json`)\n .join('\\n');\n const checksumsPath = join(destination, 'checksums.sha256');\n await writeFile(checksumsPath, `${checksums}\\n`, { mode: 0o600 });\n return { bundleRoot: destination, manifest, checksumsPath };\n}\n\nasync function readBundle(bundleRoot: string): Promise<BundleInput> {\n const root = resolve(bundleRoot);\n const manifestPath = join(root, 'manifest.json');\n const manifestInfo = await lstat(manifestPath);\n if (!manifestInfo.isFile() || manifestInfo.isSymbolicLink())\n throw new Error('security/import-invalid: manifest must be a regular file');\n const manifestText = await readFile(manifestPath, 'utf8');\n const manifest = JSON.parse(manifestText) as V2ExportManifest;\n if (manifest.format !== FORMAT || manifest.version !== 1)\n throw new Error('configuration/import-invalid: unsupported V2 export format');\n const files = new Map<string, string>();\n const expectedChecksums = new Map<string, string>();\n const checksums = await readFile(join(root, 'checksums.sha256'), 'utf8');\n for (const line of checksums\n .split('\\n')\n .map((item) => item.trim())\n .filter(Boolean)) {\n const match = line.match(/^([0-9a-f]{64}) {2}(.+)$/u);\n if (!match?.[1] || !match[2]) throw new Error('security/import-invalid: malformed checksums file');\n expectedChecksums.set(match[2], match[1]);\n }\n if (expectedChecksums.get('manifest.json') !== sha256Hex(canonicalJson(manifest as never)))\n throw new Error('security/import-checksum-mismatch: manifest.json');\n for (const entry of manifest.files) {\n const path = normalisePath(entry.path);\n if (files.has(path)) throw new Error(`configuration/import-invalid: duplicate path ${path}`);\n const filePath = join(root, 'files', path);\n const info = await lstat(filePath);\n if (!info.isFile() || info.isSymbolicLink())\n throw new Error(`security/import-invalid: symlink or non-file ${path}`);\n const content = await readFile(filePath, 'utf8');\n if (sha256Hex(content) !== entry.sha256) throw new Error(`security/import-checksum-mismatch: ${path}`);\n if (expectedChecksums.get(`files/${path}`) !== entry.sha256)\n throw new Error(`security/import-checksum-mismatch: files/${path}`);\n files.set(path, content);\n }\n const sourceDigest = await digestFiles(join(root, 'files'), [...files.keys()]);\n if (sourceDigest !== manifest.projectRootDigest)\n throw new Error('security/import-checksum-mismatch: project root digest does not match manifest');\n return { manifest, files, sourceDigest };\n}\n\nfunction pipelineBlock(input: string | undefined): Record<string, unknown> {\n const match = input?.match(/```ya?ml\\s+pipeline-profile\\s*\\n([\\s\\S]*?)\\n```/iu);\n if (!match?.[1]) return {};\n try {\n const parsed = parse(match[1]) as unknown;\n return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? (parsed as Record<string, unknown>) : {};\n } catch {\n return {};\n }\n}\n\nfunction rule(id: string, program: string, decision: 'allow' | 'ask' | 'deny') {\n return { id, program, decision, replay: 'idempotent' as const, network: false, origin: 'project-config' as const };\n}\n\nfunction mapConfig(\n input: string | undefined,\n pipeline: string | undefined,\n model: ProjectModel | undefined,\n): { config: string; ownership: string; warnings: V2ImportWarning[] } {\n const warnings: V2ImportWarning[] = [];\n let document: Record<string, unknown> = {};\n if (input !== undefined) {\n try {\n const parsed = parse(input) as unknown;\n if (parsed && typeof parsed === 'object') document = parsed as Record<string, unknown>;\n } catch {\n warnings.push(warning('config-invalid-yaml', 'V2 configuration is not valid YAML', 'cohorte.config.yaml', true));\n }\n }\n const profile = pipelineBlock(pipeline);\n if (profile.name === undefined)\n warnings.push(warning('config-project-id-missing', 'project id needs human confirmation'));\n if (document.kanban !== undefined)\n warnings.push(warning('kanban-not-imported', 'Kanban links remain external and are not synchronized'));\n const id = typeof profile.name === 'string' ? profile.name : 'imported-project';\n const vcs = (profile.vcs ?? {}) as Record<string, unknown>;\n const commands = (profile.commands ?? {}) as Record<string, unknown>;\n const gate = (profile.gate ?? {}) as Record<string, unknown>;\n const defaultBranch =\n typeof vcs.default_branch === 'string' ? vcs.default_branch : DEFAULT_CONFIG.project.defaultBranch;\n const branchPrefix =\n typeof vcs.feature_branch_prefix === 'string' ? vcs.feature_branch_prefix : DEFAULT_CONFIG.git.branchPrefix;\n const migrated = structuredClone(DEFAULT_CONFIG);\n migrated.project = { ...migrated.project, id, defaultBranch, protectedBranches: [defaultBranch] };\n migrated.git = { ...migrated.git, branchPrefix };\n migrated.checks = {\n ...migrated.checks,\n ...(typeof commands.test === 'string' ? { test: commands.test.split(/\\s+/u) } : {}),\n ...(typeof commands.lint === 'string' ? { lint: commands.lint.split(/\\s+/u) } : {}),\n ...(typeof commands.typecheck === 'string' ? { typecheck: commands.typecheck.split(/\\s+/u) } : {}),\n };\n const deny = Array.isArray(gate.deny) ? gate.deny.filter((v): v is string => typeof v === 'string') : [];\n const ask = Array.isArray(gate.ask) ? gate.ask.filter((v): v is string => typeof v === 'string') : [];\n migrated.policy.commands = {\n allow: [],\n ask: ask.map((value, index) => rule(`v2-ask-${index}`, value.split(/\\s+/u)[0] ?? value, 'ask')),\n deny: deny.map((value, index) => rule(`v2-deny-${index}`, value.split(/\\s+/u)[0] ?? value, 'deny')),\n };\n warnings.push(\n warning('runtime-review-required', 'V2 runtime adapters are not migrated; review the current runtime selection'),\n );\n const surfaces = Object.fromEntries(\n Object.entries(model?.surfaces ?? {}).map(([key, value]) => [\n key,\n { paths: value.paths.value, owners: ['implementer'], reviewers: ['reviewer'] },\n ]),\n );\n return {\n config: stringify(migrated),\n ownership: stringify({ surfaces }),\n warnings,\n };\n}\n\nfunction section(markdown: string, number: string, fallback: string): string {\n const match = markdown.match(new RegExp(`^##\\\\s+${number}\\\\.?.*?\\\\n([\\\\s\\\\S]*?)(?=^##\\\\s+|$)`, 'imu'));\n return match?.[1]?.trim() ?? fallback;\n}\n\nfunction bullets(text: string): string[] {\n return text\n .split('\\n')\n .map((line) => line.match(/^\\s*(?:[-*]|\\d+[.)])\\s+(.*)$/u)?.[1]?.trim())\n .filter((value): value is string => Boolean(value));\n}\n\nfunction importedSpec(path: string, markdown: string): { id: string; content: string; warning?: V2ImportWarning } {\n const front = markdown.match(/^---\\s*\\n([\\s\\S]*?)\\n---/u);\n const metadata = front?.[1] ? (parse(front[1]) as Record<string, unknown>) : {};\n const filename = path.split('/').pop()?.replace(/\\.md$/iu, '') ?? 'imported-spec';\n const id =\n String(metadata.feature_id ?? filename)\n .toLowerCase()\n .replace(/[^a-z0-9]+/gu, '-')\n .replace(/^-|-$/gu, '')\n .slice(0, 48) || 'imported-spec';\n const heading = markdown.match(/^#\\s+(.+)$/mu)?.[1]?.trim();\n const title = String(metadata.title ?? heading ?? id);\n const rawStatus = String(metadata.status ?? 'draft');\n const status = rawStatus === 'draft' ? 'draft' : 'frozen';\n const acceptance = bullets(section(markdown, '9', ''));\n const openQuestions = bullets(section(markdown, '10', ''));\n const surfaces: Record<string, { tasks: string[] }> = {};\n const surfaceSection = section(markdown, '6', '');\n for (const match of surfaceSection.matchAll(/^###\\s+([^\\n]+)\\n([\\s\\S]*?)(?=^###\\s+|$)/gmu)) {\n const key =\n match[1]\n ?.trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/gu, '-')\n .replace(/^-|-$/gu, '') || 'shared';\n surfaces[key] = { tasks: bullets(match[2] ?? '') };\n }\n if (Object.keys(surfaces).length === 0)\n surfaces.shared = { tasks: ['Review imported V2 specification and assign implementation tasks.'] };\n const body = {\n id,\n kind: 'feature' as const,\n status,\n title,\n acceptance: acceptance.length ? acceptance : [`Review imported V2 specification: ${title}`],\n surfaces,\n openQuestions: [...openQuestions, ...(rawStatus === 'draft' ? [] : [`Original V2 status: ${rawStatus}`])],\n } as Spec;\n if (status === 'frozen') return { id, content: stringify({ ...body, sha256: specContentSha256(body) }) };\n return {\n id,\n content: stringify(body),\n ...(rawStatus === 'draft'\n ? {}\n : { warning: warning('spec-status-normalized', `V2 status ${rawStatus} was normalized to frozen`, path) }),\n };\n}\n\nexport async function planV2Import(\n bundleRoot: string,\n projectRoot: string,\n options: V2ImportOptions = {},\n): Promise<V2ImportPlan> {\n const bundle = await readBundle(bundleRoot);\n const modelSource = bundle.files.get('PIPELINE.md');\n const mapped = mapConfig(bundle.files.get('cohorte.config.yaml'), modelSource, options.model);\n const projectContent = options.model === undefined ? undefined : stringify(options.model);\n const generated =\n projectContent === undefined\n ? []\n : [\n {\n path: 'project.yaml',\n templateId: 'project-model/v1',\n templateSha256: sha256Hex(projectContent),\n renderedSha256: sha256Hex(projectContent),\n },\n ];\n const manifestContent = stringify({\n schemaVersion: 1,\n cohorteVersion: '3.0.0',\n createdWith: 'v2-import',\n protocol: { min: '3.0', max: '3.x' },\n stateSchemaVersion: 1,\n generated,\n });\n const convertedSpecs = bundle.manifest.files\n .filter((entry) => entry.kind === 'spec')\n .map((entry) => ({ entry, converted: importedSpec(entry.path, bundle.files.get(entry.path) ?? '') }));\n const specWarnings = convertedSpecs.flatMap(({ converted }) => (converted.warning ? [converted.warning] : []));\n const files: V2ImportFile[] = [\n { path: '.cohorte/manifest.yaml', content: manifestContent, action: 'create', reason: 'V3 migration marker' },\n { path: '.cohorte/.gitignore', content: 'state/\\nruns/\\n', action: 'create', reason: 'protect V3 local state' },\n { path: '.cohorte/config.yaml', content: mapped.config, action: 'create', reason: 'mapped V2 configuration' },\n {\n path: '.cohorte/ownership.yaml',\n content: mapped.ownership,\n action: 'create',\n reason: 'new V3 ownership document',\n },\n ...(options.model === undefined\n ? []\n : [\n {\n path: '.cohorte/project.yaml',\n content: projectContent ?? '',\n action: 'create' as const,\n reason: 'deterministic V3 project model generated during import',\n },\n ]),\n ...(modelSource === undefined\n ? []\n : [\n {\n path: '.cohorte/import-source/PIPELINE.md',\n content: modelSource,\n action: 'create' as const,\n reason: 'preserve V2 source',\n },\n ]),\n ...convertedSpecs.map(({ entry, converted }) => ({\n path: `.cohorte/specs/${converted.id}.yaml`,\n content: converted.content,\n action: 'create' as const,\n reason: `convert V2 Markdown specification ${entry.path} to native schema`,\n })),\n ...bundle.manifest.files\n .filter((entry) => entry.kind === 'history')\n .map((entry) => ({\n path: `.cohorte/artifacts/v2-history/${normalisePath(entry.path).replace(/^specs\\/reports\\//u, '')}`,\n content: bundle.files.get(entry.path) ?? '',\n action: 'create' as const,\n reason: 'import V2 historical artifact',\n })),\n ];\n const currentDigest = await digestProject(projectRoot);\n const conflicts: string[] = [];\n for (const file of files) {\n try {\n const currentPath = join(projectRoot, file.path);\n const info = await lstat(currentPath);\n if (info.isSymbolicLink()) {\n file.action = 'conflict';\n file.reason = 'target is a symbolic link';\n conflicts.push(file.path);\n continue;\n }\n const current = await readFile(currentPath, 'utf8');\n if (current !== file.content) {\n file.action = 'conflict';\n file.reason = 'target exists with different content';\n conflicts.push(file.path);\n } else file.action = 'keep';\n } catch {\n /* create */\n }\n }\n return {\n bundleRoot: resolve(bundleRoot),\n projectRoot: resolve(projectRoot),\n sourceVersion: bundle.manifest.sourceVersion,\n files,\n warnings: [...bundle.manifest.warnings, ...mapped.warnings, ...specWarnings],\n conflicts,\n sourceDigest: bundle.sourceDigest,\n targetDigest: currentDigest,\n };\n}\n\nasync function digestProject(root: string): Promise<string> {\n const paths = (await walk(root)).filter((path) => !path.startsWith('.cohorte/import-preview/'));\n return digestFiles(root, paths);\n}\n\nexport async function applyV2Import(\n plan: V2ImportPlan,\n options: {\n confirm: boolean;\n backupRoot: string;\n now?: string;\n fault?: (point: V2ImportFaultPoint) => void;\n },\n): Promise<V2ImportReport> {\n if (plan.conflicts.length) throw new Error(`configuration/import-conflict: ${plan.conflicts.join(', ')}`);\n if (plan.warnings.some((item) => item.blocking))\n throw new Error('configuration/import-blocked: resolve blocking warnings first');\n if (!options.confirm) throw new Error('configuration/import-confirmation-required: rerun with explicit confirmation');\n if ((await digestProject(plan.projectRoot)) !== plan.targetDigest)\n throw new Error('configuration/import-project-changed: project changed since preview');\n const id = sha256Hex(`${plan.sourceDigest}:${plan.targetDigest}:${options.now ?? new Date().toISOString()}`).slice(\n 0,\n 16,\n );\n const backupRoot = resolve(options.backupRoot, `cohorte-v2-${id}`);\n const stage = join(backupRoot, '.stage');\n const reportPath = join(plan.projectRoot, '.cohorte', 'import-reports', `${id}.json`);\n const existing: string[] = [];\n let mutated = false;\n const restore = async () => {\n await rm(stage, { recursive: true, force: true });\n await rm(reportPath, { force: true });\n if (!mutated) return;\n for (const file of plan.files) {\n if (file.action === 'keep') continue;\n const target = join(plan.projectRoot, file.path);\n const backup = join(backupRoot, file.path);\n try {\n await stat(backup);\n await mkdir(dirname(target), { recursive: true, mode: 0o700 });\n await cp(backup, target, { recursive: true, verbatimSymlinks: true });\n } catch {\n await rm(target, { recursive: true, force: true });\n }\n }\n };\n try {\n options.fault?.('before-backup');\n await mkdir(backupRoot, { recursive: true, mode: 0o700 });\n for (const file of plan.files) {\n try {\n await lstat(join(plan.projectRoot, file.path));\n existing.push(file.path);\n await mkdir(dirname(join(backupRoot, file.path)), { recursive: true, mode: 0o700 });\n await cp(join(plan.projectRoot, file.path), join(backupRoot, file.path), {\n recursive: true,\n verbatimSymlinks: true,\n });\n } catch {\n /* new file */\n }\n }\n options.fault?.('after-backup');\n await mkdir(stage, { recursive: true, mode: 0o700 });\n for (const file of plan.files) {\n if (file.action === 'keep') continue;\n const target = join(stage, file.path);\n await mkdir(dirname(target), { recursive: true, mode: 0o700 });\n await writeFile(target, file.content, { mode: 0o600 });\n }\n options.fault?.('after-stage');\n options.fault?.('before-rename');\n for (const file of plan.files) {\n if (file.action === 'keep') continue;\n const target = join(plan.projectRoot, file.path);\n await mkdir(dirname(target), { recursive: true, mode: 0o700 });\n mutated = true;\n await rename(join(stage, file.path), target);\n }\n options.fault?.('after-rename');\n await rm(stage, { recursive: true, force: true });\n } catch (error) {\n await restore();\n throw error;\n }\n const report: V2ImportReport = {\n reportId: id,\n status: 'applied',\n bundleRoot: plan.bundleRoot,\n projectRoot: plan.projectRoot,\n backupRoot,\n sourceDigest: plan.sourceDigest,\n targetDigest: plan.targetDigest,\n files: plan.files.filter((file) => file.action !== 'keep').map((file) => file.path),\n warnings: plan.warnings,\n createdAt: options.now ?? new Date().toISOString(),\n };\n try {\n options.fault?.('before-report');\n await mkdir(dirname(reportPath), { recursive: true, mode: 0o700 });\n await writeFile(reportPath, `${JSON.stringify({ ...report, existing }, null, 2)}\\n`, { mode: 0o600 });\n } catch (error) {\n await restore();\n throw error;\n }\n return report;\n}\n\nexport async function rollbackV2Import(report: V2ImportReport): Promise<V2ImportReport> {\n for (const path of report.files) {\n const backup = join(report.backupRoot, path);\n try {\n await stat(backup);\n await mkdir(dirname(join(report.projectRoot, path)), { recursive: true, mode: 0o700 });\n await cp(backup, join(report.projectRoot, path), { recursive: true, verbatimSymlinks: true });\n } catch {\n await rm(join(report.projectRoot, path), { recursive: true, force: true });\n }\n }\n return { ...report, status: 'rolled-back' };\n}\n\nexport function projectModelFromV2(bundle: V2ExportResult, model: ProjectModel): string {\n return stringify({\n ...model,\n provenance: { ...model.provenance, toolVersion: `v2-import:${bundle.manifest.sourceVersion ?? 'unknown'}` },\n });\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { sha256Hex } from '@cohorte/base';\nimport { stringify } from 'yaml';\nimport type { InitPlan, ProjectModel } from '../contract.ts';\n\nexport interface PlanInitOptions {\n root: string;\n model: ProjectModel;\n cohorteVersion: string;\n /** refused in V3.0: `configuration/phase-not-available` */\n semantic?: boolean;\n}\n\nexport async function planInit(options: PlanInitOptions): Promise<InitPlan> {\n if (options.semantic) throw new Error('configuration/phase-not-available: semantic init is not available in V3.0');\n const root = options.root;\n const modelYaml = stringify(options.model);\n const files = [\n { path: 'project.yaml', class: 'generated' as const, content: modelYaml, templateId: 'project-model/v1' },\n { path: 'config.yaml', class: 'human' as const, content: 'schemaVersion: 1\\n' },\n { path: 'ownership.yaml', class: 'human' as const, content: 'surfaces: {}\\n' },\n {\n path: '.gitignore',\n class: 'generated' as const,\n content: 'state/\\nruns/\\n',\n templateId: 'cohorte/gitignore/v1',\n },\n {\n path: 'generated/.gitkeep',\n class: 'generated' as const,\n content: '',\n templateId: 'cohorte/generated-dir/v1',\n },\n ];\n const initFiles: InitPlan['files'] = [];\n for (const file of files) {\n let exists = false;\n try {\n await readFile(join(root, '.cohorte', file.path));\n exists = true;\n } catch {\n /* create */\n }\n const renderedSha256 = sha256Hex(file.content);\n initFiles.push({\n path: file.path,\n action: exists ? 'keep-existing' : 'create',\n class: file.class,\n content: file.content,\n ...(file.templateId === undefined ? {} : { templateId: file.templateId }),\n ...(file.class === 'generated' ? { templateSha256: renderedSha256, renderedSha256 } : {}),\n });\n }\n const generated = initFiles\n .filter((file) => file.class === 'generated')\n .map((file) => ({\n path: file.path,\n templateId: file.templateId ?? 'builtin',\n templateSha256: file.templateSha256 ?? sha256Hex(file.content),\n renderedSha256: file.renderedSha256 ?? sha256Hex(file.content),\n }));\n return {\n projectRoot: root,\n model: options.model,\n files: initFiles,\n manifest: {\n schemaVersion: 1,\n cohorteVersion: options.cohorteVersion,\n createdWith: options.cohorteVersion,\n protocol: { min: '3.0', max: '3.x' },\n stateSchemaVersion: 1,\n generated,\n },\n warnings: [],\n };\n}\n\nexport async function applyInit(plan: InitPlan): Promise<{ written: string[]; kept: string[] }> {\n await mkdir(join(plan.projectRoot, '.cohorte'), { recursive: true, mode: 0o700 });\n const written: string[] = [];\n const kept: string[] = [];\n for (const file of plan.files) {\n const target = join(plan.projectRoot, '.cohorte', file.path);\n if (file.action === 'keep-existing') {\n kept.push(file.path);\n continue;\n }\n await mkdir(join(target, '..'), { recursive: true, mode: 0o700 });\n await writeFile(target, file.content, { mode: 0o600 });\n written.push(file.path);\n }\n const manifestPath = join(plan.projectRoot, '.cohorte', 'manifest.yaml');\n try {\n await readFile(manifestPath);\n kept.push('manifest.yaml');\n } catch {\n await writeFile(manifestPath, stringify(plan.manifest), { mode: 0o600 });\n written.push('manifest.yaml');\n }\n return { written, kept };\n}\n","import { appendFile, copyFile, mkdir, readFile, unlink, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { type Clock, sha256Hex } from '@cohorte/base';\nimport { DEFAULT_CONFIG } from '@cohorte/config/schema';\nimport { parse } from 'yaml';\nimport type { DesiredState, ReconcilePlan, RepositoryScanner } from '../contract.ts';\nimport { deriveDesiredState } from '../desired/index.ts';\nimport { diffStates, readActualState } from '../drift/index.ts';\n\nexport interface PlanReconcileOptions {\n root: string;\n /** injected: this area never imports the scan area */\n scan: RepositoryScanner;\n cohorteVersion: string;\n clock: Clock;\n}\n\nexport interface ApplyReconcileOptions {\n root: string;\n plan: ReconcilePlan;\n desired: DesiredState;\n backup?: boolean;\n clock: Clock;\n}\n\n/** READ-ONLY. */\nexport async function planReconcile(options: PlanReconcileOptions): Promise<ReconcilePlan> {\n const model = await options.scan(options.root);\n // `provenance.generatedAt` is metadata, not project content. Reuse the\n // previous generated timestamp so a read-only reconcile is stable; changed\n // model fields still alter the rendered project and manifest hashes.\n let stableModel = model;\n try {\n const actual = parse(await readFile(join(options.root, '.cohorte', 'project.yaml'), 'utf8')) as {\n provenance?: { generatedAt?: unknown };\n };\n const generatedAt = actual.provenance?.generatedAt;\n const stableGeneratedAt =\n generatedAt instanceof Date\n ? generatedAt.toISOString()\n : typeof generatedAt === 'string'\n ? generatedAt\n : undefined;\n if (stableGeneratedAt !== undefined) {\n stableModel = {\n ...model,\n provenance: {\n ...model.provenance,\n generatedAt: stableGeneratedAt as typeof model.provenance.generatedAt,\n },\n };\n }\n } catch {\n /* an uninitialised or malformed project is represented by the normal drift entries */\n }\n const desired = deriveDesiredState({\n model: stableModel,\n config: DEFAULT_CONFIG,\n cohorteVersion: options.cohorteVersion,\n skills: {},\n });\n const actual = await readActualState(options.root);\n const drift = diffStates(desired, actual, options.clock);\n const operations = drift.entries.map((entry) => {\n const op =\n entry.diff === 'absent'\n ? 'create'\n : entry.diff === 'expected-change'\n ? 'replace'\n : entry.diff === 'potential-deletion'\n ? 'delete'\n : entry.diff === 'unknown'\n ? 'keep'\n : 'ask';\n return { op, target: entry.target, diff: entry.diff, reason: entry.detail } as const;\n });\n return {\n schemaVersion: 1,\n cohorteVersion: options.cohorteVersion,\n generatedAt: drift.generatedAt,\n drift,\n operations,\n conflicts: drift.entries.filter((entry) => entry.diff === 'conflict').map((entry) => entry.target),\n applyAvailable: true,\n };\n}\n\n/** Apply only create/replace/delete operations authorized by a conflict-free plan. */\nexport async function applyReconcile(options: ApplyReconcileOptions): Promise<{\n applied: string[];\n skipped: string[];\n backupDir?: string;\n journal: string;\n}> {\n if (options.plan.conflicts.length > 0)\n throw new Error(`conflict/reconcile-human-edit: ${options.plan.conflicts.join(', ')}`);\n const desiredByPath = new Map(options.desired.files.map((file) => [file.path, file]));\n const backupDir = options.backup\n ? join(options.root, '.cohorte', 'reconcile-backups', options.clock.now().replaceAll(':', ''))\n : undefined;\n const journal = join(options.root, '.cohorte', 'reconcile.log');\n await mkdir(join(options.root, '.cohorte'), { recursive: true, mode: 0o700 });\n const applied: string[] = [];\n const skipped: string[] = [];\n for (const operation of options.plan.operations) {\n if (operation.op !== 'create' && operation.op !== 'replace' && operation.op !== 'delete') {\n skipped.push(operation.target);\n continue;\n }\n const target = join(options.root, '.cohorte', operation.target);\n if (!target.startsWith(`${join(options.root, '.cohorte')}/`)) throw new Error('security/path-outside-grant');\n const existing = await readFile(target).catch(() => undefined);\n const drift = options.plan.drift.entries.find((entry) => entry.target === operation.target);\n const actualSha256 = existing === undefined ? undefined : sha256Hex(existing);\n if (actualSha256 !== drift?.actualSha256)\n throw new Error(`conflict/reconcile-race: ${operation.target} changed after the plan was generated`);\n if (existing !== undefined && backupDir) {\n const backupPath = join(backupDir, operation.target);\n await mkdir(dirname(backupPath), { recursive: true });\n await copyFile(target, backupPath);\n }\n if (operation.op === 'delete') await unlink(target).catch(() => undefined);\n else {\n const file = desiredByPath.get(operation.target);\n if (file?.content === undefined) throw new Error(`configuration/reconcile-content-missing: ${operation.target}`);\n await mkdir(dirname(target), { recursive: true });\n await writeFile(target, file.content, 'utf8');\n }\n applied.push(operation.target);\n await appendFile(\n journal,\n `${JSON.stringify({ at: options.clock.now(), op: operation.op, target: operation.target })}\\n`,\n );\n }\n return { applied, skipped, ...(backupDir ? { backupDir } : {}), journal };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"src-DNsLSxgm.mjs","names":[],"sources":["../../../../packages/project-model/src/desired/index.ts","../../../../packages/project-model/src/drift/index.ts","../../../../packages/project-model/src/import-v2/index.ts","../../../../packages/project-model/src/init/index.ts","../../../../packages/project-model/src/reconcile/index.ts"],"sourcesContent":["import { canonicalJson, type JsonValue, sha256Hex } from '@cohorte/base';\nimport type { CohorteConfig } from '@cohorte/config/schema';\nimport { stringify } from 'yaml';\nimport type { DesiredState, ProjectModel } from '../contract.ts';\n\nexport interface DesiredStateInput {\n model: ProjectModel;\n config: CohorteConfig;\n cohorteVersion: string;\n /** skill id -> version */\n skills: Readonly<Record<string, string>>;\n}\n\nexport function deriveDesiredState(input: DesiredStateInput): DesiredState {\n const modelYaml = stringify(input.model);\n const generatedArtifacts = new Map<string, string>();\n for (const path of input.model.generatedArtifacts.value) {\n const relative = path.replace(/^\\.cohorte\\//u, '');\n if (relative === 'manifest.yaml' || relative === 'project.yaml') continue;\n generatedArtifacts.set(\n relative,\n canonicalJson({\n path: relative,\n model: input.model,\n config: input.config,\n skills: input.skills,\n } as unknown as JsonValue),\n );\n }\n const manifest = {\n schemaVersion: 1,\n cohorteVersion: input.cohorteVersion,\n createdWith: input.cohorteVersion,\n protocol: { min: '3.0', max: '3.x' },\n stateSchemaVersion: 1,\n generated: [\n {\n path: 'project.yaml',\n templateId: 'project-model/v1',\n templateSha256: sha256Hex(modelYaml),\n renderedSha256: sha256Hex(modelYaml),\n },\n {\n path: '.gitignore',\n templateId: 'cohorte/gitignore/v1',\n templateSha256: sha256Hex('state/\\nruns/\\n'),\n renderedSha256: sha256Hex('state/\\nruns/\\n'),\n },\n {\n path: 'generated/.gitkeep',\n templateId: 'cohorte/generated-dir/v1',\n templateSha256: sha256Hex(''),\n renderedSha256: sha256Hex(''),\n },\n ...[...generatedArtifacts.keys()].map((path) => ({\n path,\n templateId: path,\n templateSha256: sha256Hex(generatedArtifacts.get(path) as string),\n renderedSha256: sha256Hex(generatedArtifacts.get(path) as string),\n })),\n ],\n };\n const manifestYaml = stringify(manifest);\n const builtin: Record<string, string> = {\n 'manifest.yaml': manifestYaml,\n 'project.yaml': modelYaml,\n 'config.yaml': 'schemaVersion: 1\\n',\n 'ownership.yaml': 'surfaces: {}\\n',\n '.gitignore': 'state/\\nruns/\\n',\n 'generated/.gitkeep': '',\n };\n const files = new Set([...Object.keys(builtin), ...generatedArtifacts.keys()]);\n const stateFiles = [...files].sort().map((path) => ({\n path,\n class: path === 'config.yaml' || path === 'ownership.yaml' ? ('human' as const) : ('generated' as const),\n sha256: sha256Hex(builtin[path] ?? generatedArtifacts.get(path) ?? ''),\n content: builtin[path] ?? generatedArtifacts.get(path) ?? '',\n ...(input.skills[path] === undefined ? {} : { templateId: path }),\n }));\n return { cohorteVersion: input.cohorteVersion, files: stateFiles };\n}\n","import { readdir, readFile } from 'node:fs/promises';\nimport { join, relative } from 'node:path';\nimport { type Clock, sha256Hex } from '@cohorte/base';\nimport { parse } from 'yaml';\nimport type { ActualState, DesiredState, DriftEntry, DriftReport } from '../contract.ts';\n\nexport async function readActualState(root: string): Promise<ActualState> {\n const stateRoot = join(root, '.cohorte');\n let manifest = null;\n try {\n manifest = parse(await readFile(join(stateRoot, 'manifest.yaml'), 'utf8')) as ActualState['manifest'];\n } catch {\n return { manifest: null, files: [] };\n }\n const files: ActualState['files'] = [];\n const visit = async (dir: string): Promise<void> => {\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {\n if (entry.name === 'state' || entry.name === 'runs') continue;\n const path = join(dir, entry.name);\n if (entry.isDirectory()) await visit(path);\n else if (entry.isFile()) {\n const bytes = await readFile(path);\n const relativePath = relative(stateRoot, path).split('\\\\').join('/');\n const generated =\n relativePath === 'manifest.yaml'\n ? { path: relativePath, templateId: 'cohorte/manifest/v1', renderedSha256: sha256Hex(bytes) }\n : manifest?.generated.find((item) => item.path === relativePath);\n files.push({\n path: relativePath,\n class: generated ? 'generated' : 'human',\n sha256: sha256Hex(bytes),\n ...(generated?.templateId ? { templateId: generated.templateId } : {}),\n });\n }\n }\n } catch {\n return;\n }\n };\n await visit(stateRoot);\n return { manifest, files };\n}\n\nexport function diffStates(desired: DesiredState, actual: ActualState, clock: Clock): DriftReport {\n const desiredByPath = new Map(desired.files.map((file) => [file.path, file]));\n const actualByPath = new Map(actual.files.map((file) => [file.path, file]));\n const recorded = new Map((actual.manifest?.generated ?? []).map((file) => [file.path, file.renderedSha256]));\n const paths = [...new Set([...desiredByPath.keys(), ...actualByPath.keys()])].sort();\n const entries = paths.flatMap((path): DriftEntry[] => {\n const expected = desiredByPath.get(path);\n const found = actualByPath.get(path);\n const recordedSha256 = recorded.get(path);\n if (!found && expected)\n return [\n {\n target: path,\n class: expected.class,\n diff: 'absent' as const,\n desiredSha256: expected.sha256,\n ...(recordedSha256 ? { recordedSha256 } : {}),\n detail: 'desired file is absent',\n },\n ];\n if (found && !expected)\n return [\n {\n target: path,\n class: found.class,\n diff: found.class === 'generated' ? ('potential-deletion' as const) : ('unknown' as const),\n actualSha256: found.sha256,\n ...(recordedSha256 ? { recordedSha256 } : {}),\n detail: 'file exists but is not desired',\n },\n ];\n if (!found || !expected) throw new Error('unreachable drift entry');\n if (found.sha256 === expected.sha256) return [];\n if (found.class === 'human')\n return [\n {\n target: path,\n class: found.class,\n diff: 'human-change' as const,\n desiredSha256: expected.sha256,\n actualSha256: found.sha256,\n ...(recordedSha256 ? { recordedSha256 } : {}),\n detail: 'content changed in a human-owned file',\n },\n ];\n if (recordedSha256 === undefined || found.sha256 === recordedSha256)\n return [\n {\n target: path,\n class: expected.class,\n diff: 'expected-change' as const,\n desiredSha256: expected.sha256,\n actualSha256: found.sha256,\n ...(recordedSha256 ? { recordedSha256 } : {}),\n detail: 'generated content differs from the previous render',\n },\n ];\n return [\n {\n target: path,\n class: found.class,\n diff: 'conflict' as const,\n desiredSha256: expected.sha256,\n actualSha256: found.sha256,\n recordedSha256,\n detail: 'content changed since the recorded render',\n },\n ];\n });\n return { schemaVersion: 1, generatedAt: clock.now(), entries };\n}\n","import { createHash } from 'node:crypto';\nimport { cp, lstat, mkdir, readdir, readFile, rename, rm, stat, writeFile } from 'node:fs/promises';\nimport { dirname, join, relative, resolve, sep } from 'node:path';\nimport { canonicalJson, sha256Hex } from '@cohorte/base';\nimport { DEFAULT_CONFIG, type Spec, specContentSha256 } from '@cohorte/config/schema';\nimport { parse, stringify } from 'yaml';\nimport type { ProjectModel } from '../contract.ts';\n\nconst FORMAT = 'cohorte-v2-export';\nconst MAX_FILE_BYTES = 10 * 1024 * 1024;\nconst SKIP_DIRS = new Set(['.git', 'node_modules', '.build', 'dist', 'coverage', '.cohorte']);\nconst SECRET =\n /(^|[/\\\\])(?:\\.env(?:\\..*)?|credentials?(?:\\..*)?|secrets?(?:\\..*)?|.*token.*|.*password.*|.*api[-_]?key.*)$/iu;\n\nexport interface V2ExportFile {\n path: string;\n sha256: string;\n bytes: number;\n kind: 'config' | 'spec' | 'history' | 'marker';\n}\n\nexport interface V2ExportManifest {\n format: typeof FORMAT;\n version: 1;\n sourceVersion: string | null;\n createdAt: string;\n projectRootDigest: string;\n files: V2ExportFile[];\n excluded: Array<{ path: string; reason: string }>;\n warnings: V2ImportWarning[];\n}\n\nexport interface V2ImportWarning {\n code: string;\n path?: string;\n message: string;\n blocking: boolean;\n}\n\nexport interface V2ExportOptions {\n root: string;\n destination: string;\n now?: string;\n}\n\nexport interface V2ExportResult {\n bundleRoot: string;\n manifest: V2ExportManifest;\n checksumsPath: string;\n}\n\nexport interface V2ImportFile {\n path: string;\n content: string;\n action: 'create' | 'replace' | 'keep' | 'conflict';\n reason: string;\n}\n\nexport interface V2ImportPlan {\n bundleRoot: string;\n projectRoot: string;\n sourceVersion: string | null;\n files: V2ImportFile[];\n warnings: V2ImportWarning[];\n conflicts: string[];\n sourceDigest: string;\n targetDigest: string;\n}\n\nexport interface V2ImportOptions {\n model?: ProjectModel;\n}\n\nexport interface V2ImportReport {\n reportId: string;\n status: 'applied' | 'rolled-back';\n bundleRoot: string;\n projectRoot: string;\n backupRoot: string;\n sourceDigest: string;\n targetDigest: string;\n files: string[];\n warnings: V2ImportWarning[];\n createdAt: string;\n}\n\nexport const V2_IMPORT_FAULT_POINTS = [\n 'before-backup',\n 'after-backup',\n 'after-stage',\n 'before-rename',\n 'after-rename',\n 'before-report',\n] as const;\n\nexport type V2ImportFaultPoint = (typeof V2_IMPORT_FAULT_POINTS)[number];\n\ninterface BundleInput {\n manifest: V2ExportManifest;\n files: Map<string, string>;\n sourceDigest: string;\n}\n\nfunction normalisePath(value: string): string {\n const path = value.replaceAll('\\\\', '/');\n if (!path || path.startsWith('/') || path.split('/').some((part) => part === '..' || part === ''))\n throw new Error(`configuration/import-invalid: unsafe relative path ${JSON.stringify(value)}`);\n return path;\n}\n\nasync function walk(root: string, current = root): Promise<string[]> {\n const entries = await readdir(current, { withFileTypes: true });\n const result: string[] = [];\n for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {\n if (entry.isDirectory() && SKIP_DIRS.has(entry.name)) continue;\n const absolute = join(current, entry.name);\n const rel = relative(root, absolute).split(sep).join('/');\n if (entry.isSymbolicLink()) throw new Error(`configuration/import-symlink: refusing symbolic link ${rel}`);\n if (entry.isDirectory()) result.push(...(await walk(root, absolute)));\n else if (entry.isFile()) result.push(rel);\n }\n return result.sort();\n}\n\nfunction fileKind(path: string): V2ExportFile['kind'] {\n if (path === 'PIPELINE.md' || path === 'cohorte.config.yaml' || path.startsWith('profile/')) return 'config';\n if (path.startsWith('specs/')) return path.startsWith('specs/reports/') ? 'history' : 'spec';\n return 'marker';\n}\n\nfunction warning(code: string, message: string, path?: string, blocking = false): V2ImportWarning {\n return { code, message, ...(path === undefined ? {} : { path }), blocking };\n}\n\nasync function digestFiles(root: string, files: string[]): Promise<string> {\n const hash = createHash('sha256');\n for (const path of files) {\n hash.update(path);\n hash.update(await readFile(join(root, path)));\n }\n return hash.digest('hex');\n}\n\nfunction sourceVersion(pipeline: string | undefined): string | null {\n const match = pipeline?.match(/(?:version|core_version)\\s*[:=]\\s*[\"']?([0-9]+\\.[0-9]+\\.[0-9]+)/iu);\n return match?.[1] ?? null;\n}\n\nexport async function exportV2(options: V2ExportOptions): Promise<V2ExportResult> {\n const root = resolve(options.root);\n const destination = resolve(options.destination);\n const all = await walk(root);\n const files: V2ExportFile[] = [];\n const excluded: V2ExportManifest['excluded'] = [];\n const warnings: V2ImportWarning[] = [];\n for (const path of all) {\n if (SECRET.test(path)) {\n excluded.push({ path, reason: 'sensitive-path' });\n warnings.push(warning('sensitive-excluded', 'sensitive file excluded from export', path));\n continue;\n }\n const info = await stat(join(root, path));\n if (info.size > MAX_FILE_BYTES) {\n excluded.push({ path, reason: 'file-too-large' });\n warnings.push(warning('file-too-large', `file exceeds ${MAX_FILE_BYTES} bytes`, path, true));\n continue;\n }\n const content = await readFile(join(root, path));\n files.push({ path, sha256: sha256Hex(content), bytes: content.byteLength, kind: fileKind(path) });\n }\n const selected = files.map((file) => file.path);\n const pipeline = all.includes('PIPELINE.md') ? await readFile(join(root, 'PIPELINE.md'), 'utf8') : undefined;\n const manifest: V2ExportManifest = {\n format: FORMAT,\n version: 1,\n sourceVersion: sourceVersion(pipeline),\n createdAt: options.now ?? new Date().toISOString(),\n projectRootDigest: await digestFiles(root, selected),\n files,\n excluded,\n warnings,\n };\n await rm(destination, { recursive: true, force: true });\n await mkdir(join(destination, 'files'), { recursive: true, mode: 0o700 });\n for (const file of files) {\n const target = join(destination, 'files', file.path);\n await mkdir(dirname(target), { recursive: true, mode: 0o700 });\n await writeFile(target, await readFile(join(root, file.path)), { mode: 0o600 });\n }\n await writeFile(join(destination, 'manifest.json'), `${JSON.stringify(manifest, null, 2)}\\n`, { mode: 0o600 });\n const checksums = files\n .map((file) => `${file.sha256} files/${file.path}`)\n .concat(`${sha256Hex(canonicalJson(manifest as never))} manifest.json`)\n .join('\\n');\n const checksumsPath = join(destination, 'checksums.sha256');\n await writeFile(checksumsPath, `${checksums}\\n`, { mode: 0o600 });\n return { bundleRoot: destination, manifest, checksumsPath };\n}\n\nasync function readBundle(bundleRoot: string): Promise<BundleInput> {\n const root = resolve(bundleRoot);\n const manifestPath = join(root, 'manifest.json');\n const manifestInfo = await lstat(manifestPath);\n if (!manifestInfo.isFile() || manifestInfo.isSymbolicLink())\n throw new Error('security/import-invalid: manifest must be a regular file');\n const manifestText = await readFile(manifestPath, 'utf8');\n const manifest = JSON.parse(manifestText) as V2ExportManifest;\n if (manifest.format !== FORMAT || manifest.version !== 1)\n throw new Error('configuration/import-invalid: unsupported V2 export format');\n const files = new Map<string, string>();\n const expectedChecksums = new Map<string, string>();\n const checksums = await readFile(join(root, 'checksums.sha256'), 'utf8');\n for (const line of checksums\n .split('\\n')\n .map((item) => item.trim())\n .filter(Boolean)) {\n const match = line.match(/^([0-9a-f]{64}) {2}(.+)$/u);\n if (!match?.[1] || !match[2]) throw new Error('security/import-invalid: malformed checksums file');\n expectedChecksums.set(match[2], match[1]);\n }\n if (expectedChecksums.get('manifest.json') !== sha256Hex(canonicalJson(manifest as never)))\n throw new Error('security/import-checksum-mismatch: manifest.json');\n for (const entry of manifest.files) {\n const path = normalisePath(entry.path);\n if (files.has(path)) throw new Error(`configuration/import-invalid: duplicate path ${path}`);\n const filePath = join(root, 'files', path);\n const info = await lstat(filePath);\n if (!info.isFile() || info.isSymbolicLink())\n throw new Error(`security/import-invalid: symlink or non-file ${path}`);\n const content = await readFile(filePath, 'utf8');\n if (sha256Hex(content) !== entry.sha256) throw new Error(`security/import-checksum-mismatch: ${path}`);\n if (expectedChecksums.get(`files/${path}`) !== entry.sha256)\n throw new Error(`security/import-checksum-mismatch: files/${path}`);\n files.set(path, content);\n }\n const sourceDigest = await digestFiles(join(root, 'files'), [...files.keys()]);\n if (sourceDigest !== manifest.projectRootDigest)\n throw new Error('security/import-checksum-mismatch: project root digest does not match manifest');\n return { manifest, files, sourceDigest };\n}\n\nfunction pipelineBlock(input: string | undefined): Record<string, unknown> {\n const match = input?.match(/```ya?ml\\s+pipeline-profile\\s*\\n([\\s\\S]*?)\\n```/iu);\n if (!match?.[1]) return {};\n try {\n const parsed = parse(match[1]) as unknown;\n return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? (parsed as Record<string, unknown>) : {};\n } catch {\n return {};\n }\n}\n\nfunction rule(id: string, program: string, decision: 'allow' | 'ask' | 'deny') {\n return { id, program, decision, replay: 'idempotent' as const, network: false, origin: 'project-config' as const };\n}\n\nfunction mapConfig(\n input: string | undefined,\n pipeline: string | undefined,\n model: ProjectModel | undefined,\n): { config: string; ownership: string; warnings: V2ImportWarning[] } {\n const warnings: V2ImportWarning[] = [];\n let document: Record<string, unknown> = {};\n if (input !== undefined) {\n try {\n const parsed = parse(input) as unknown;\n if (parsed && typeof parsed === 'object') document = parsed as Record<string, unknown>;\n } catch {\n warnings.push(warning('config-invalid-yaml', 'V2 configuration is not valid YAML', 'cohorte.config.yaml', true));\n }\n }\n const profile = pipelineBlock(pipeline);\n if (profile.name === undefined)\n warnings.push(warning('config-project-id-missing', 'project id needs human confirmation'));\n if (document.kanban !== undefined)\n warnings.push(warning('kanban-not-imported', 'Kanban links remain external and are not synchronized'));\n const id = typeof profile.name === 'string' ? profile.name : 'imported-project';\n const vcs = (profile.vcs ?? {}) as Record<string, unknown>;\n const commands = (profile.commands ?? {}) as Record<string, unknown>;\n const gate = (profile.gate ?? {}) as Record<string, unknown>;\n const defaultBranch =\n typeof vcs.default_branch === 'string' ? vcs.default_branch : DEFAULT_CONFIG.project.defaultBranch;\n const branchPrefix =\n typeof vcs.feature_branch_prefix === 'string' ? vcs.feature_branch_prefix : DEFAULT_CONFIG.git.branchPrefix;\n const migrated = structuredClone(DEFAULT_CONFIG);\n migrated.project = { ...migrated.project, id, defaultBranch, protectedBranches: [defaultBranch] };\n migrated.git = { ...migrated.git, branchPrefix };\n migrated.checks = {\n ...migrated.checks,\n ...(typeof commands.test === 'string' ? { test: commands.test.split(/\\s+/u) } : {}),\n ...(typeof commands.lint === 'string' ? { lint: commands.lint.split(/\\s+/u) } : {}),\n ...(typeof commands.typecheck === 'string' ? { typecheck: commands.typecheck.split(/\\s+/u) } : {}),\n };\n const deny = Array.isArray(gate.deny) ? gate.deny.filter((v): v is string => typeof v === 'string') : [];\n const ask = Array.isArray(gate.ask) ? gate.ask.filter((v): v is string => typeof v === 'string') : [];\n migrated.policy.commands = {\n allow: [],\n ask: ask.map((value, index) => rule(`v2-ask-${index}`, value.split(/\\s+/u)[0] ?? value, 'ask')),\n deny: deny.map((value, index) => rule(`v2-deny-${index}`, value.split(/\\s+/u)[0] ?? value, 'deny')),\n };\n warnings.push(\n warning('runtime-review-required', 'V2 runtime adapters are not migrated; review the current runtime selection'),\n );\n const surfaces = Object.fromEntries(\n Object.entries(model?.surfaces ?? {}).map(([key, value]) => [\n key,\n { paths: value.paths.value, owners: ['implementer'], reviewers: ['reviewer'] },\n ]),\n );\n return {\n config: stringify(migrated),\n ownership: stringify({ surfaces }),\n warnings,\n };\n}\n\nfunction section(markdown: string, number: string, fallback: string): string {\n const match = markdown.match(new RegExp(`^##\\\\s+${number}\\\\.?.*?\\\\n([\\\\s\\\\S]*?)(?=^##\\\\s+|$)`, 'imu'));\n return match?.[1]?.trim() ?? fallback;\n}\n\nfunction bullets(text: string): string[] {\n return text\n .split('\\n')\n .map((line) => line.match(/^\\s*(?:[-*]|\\d+[.)])\\s+(.*)$/u)?.[1]?.trim())\n .filter((value): value is string => Boolean(value));\n}\n\nfunction importedSpec(path: string, markdown: string): { id: string; content: string; warning?: V2ImportWarning } {\n const front = markdown.match(/^---\\s*\\n([\\s\\S]*?)\\n---/u);\n const metadata = front?.[1] ? (parse(front[1]) as Record<string, unknown>) : {};\n const filename = path.split('/').pop()?.replace(/\\.md$/iu, '') ?? 'imported-spec';\n const id =\n String(metadata.feature_id ?? filename)\n .toLowerCase()\n .replace(/[^a-z0-9]+/gu, '-')\n .replace(/^-|-$/gu, '')\n .slice(0, 48) || 'imported-spec';\n const heading = markdown.match(/^#\\s+(.+)$/mu)?.[1]?.trim();\n const title = String(metadata.title ?? heading ?? id);\n const rawStatus = String(metadata.status ?? 'draft');\n const status = rawStatus === 'draft' ? 'draft' : 'frozen';\n const acceptance = bullets(section(markdown, '9', ''));\n const openQuestions = bullets(section(markdown, '10', ''));\n const surfaces: Record<string, { tasks: string[] }> = {};\n const surfaceSection = section(markdown, '6', '');\n for (const match of surfaceSection.matchAll(/^###\\s+([^\\n]+)\\n([\\s\\S]*?)(?=^###\\s+|$)/gmu)) {\n const key =\n match[1]\n ?.trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/gu, '-')\n .replace(/^-|-$/gu, '') || 'shared';\n surfaces[key] = { tasks: bullets(match[2] ?? '') };\n }\n if (Object.keys(surfaces).length === 0)\n surfaces.shared = { tasks: ['Review imported V2 specification and assign implementation tasks.'] };\n const body = {\n id,\n kind: 'feature' as const,\n status,\n title,\n acceptance: acceptance.length ? acceptance : [`Review imported V2 specification: ${title}`],\n surfaces,\n openQuestions: [...openQuestions, ...(rawStatus === 'draft' ? [] : [`Original V2 status: ${rawStatus}`])],\n } as Spec;\n if (status === 'frozen') return { id, content: stringify({ ...body, sha256: specContentSha256(body) }) };\n return {\n id,\n content: stringify(body),\n ...(rawStatus === 'draft'\n ? {}\n : { warning: warning('spec-status-normalized', `V2 status ${rawStatus} was normalized to frozen`, path) }),\n };\n}\n\nexport async function planV2Import(\n bundleRoot: string,\n projectRoot: string,\n options: V2ImportOptions = {},\n): Promise<V2ImportPlan> {\n const bundle = await readBundle(bundleRoot);\n const modelSource = bundle.files.get('PIPELINE.md');\n const mapped = mapConfig(bundle.files.get('cohorte.config.yaml'), modelSource, options.model);\n const projectContent = options.model === undefined ? undefined : stringify(options.model);\n const generated =\n projectContent === undefined\n ? []\n : [\n {\n path: 'project.yaml',\n templateId: 'project-model/v1',\n templateSha256: sha256Hex(projectContent),\n renderedSha256: sha256Hex(projectContent),\n },\n ];\n const manifestContent = stringify({\n schemaVersion: 1,\n cohorteVersion: '3.0.0',\n createdWith: 'v2-import',\n protocol: { min: '3.0', max: '3.x' },\n stateSchemaVersion: 1,\n generated,\n });\n const convertedSpecs = bundle.manifest.files\n .filter((entry) => entry.kind === 'spec')\n .map((entry) => ({ entry, converted: importedSpec(entry.path, bundle.files.get(entry.path) ?? '') }));\n const specWarnings = convertedSpecs.flatMap(({ converted }) => (converted.warning ? [converted.warning] : []));\n const files: V2ImportFile[] = [\n { path: '.cohorte/manifest.yaml', content: manifestContent, action: 'create', reason: 'V3 migration marker' },\n { path: '.cohorte/.gitignore', content: 'state/\\nruns/\\n', action: 'create', reason: 'protect V3 local state' },\n { path: '.cohorte/config.yaml', content: mapped.config, action: 'create', reason: 'mapped V2 configuration' },\n {\n path: '.cohorte/ownership.yaml',\n content: mapped.ownership,\n action: 'create',\n reason: 'new V3 ownership document',\n },\n ...(options.model === undefined\n ? []\n : [\n {\n path: '.cohorte/project.yaml',\n content: projectContent ?? '',\n action: 'create' as const,\n reason: 'deterministic V3 project model generated during import',\n },\n ]),\n ...(modelSource === undefined\n ? []\n : [\n {\n path: '.cohorte/import-source/PIPELINE.md',\n content: modelSource,\n action: 'create' as const,\n reason: 'preserve V2 source',\n },\n ]),\n ...convertedSpecs.map(({ entry, converted }) => ({\n path: `.cohorte/specs/${converted.id}.yaml`,\n content: converted.content,\n action: 'create' as const,\n reason: `convert V2 Markdown specification ${entry.path} to native schema`,\n })),\n ...bundle.manifest.files\n .filter((entry) => entry.kind === 'history')\n .map((entry) => ({\n path: `.cohorte/artifacts/v2-history/${normalisePath(entry.path).replace(/^specs\\/reports\\//u, '')}`,\n content: bundle.files.get(entry.path) ?? '',\n action: 'create' as const,\n reason: 'import V2 historical artifact',\n })),\n ];\n const currentDigest = await digestProject(projectRoot);\n const conflicts: string[] = [];\n for (const file of files) {\n try {\n const currentPath = join(projectRoot, file.path);\n const info = await lstat(currentPath);\n if (info.isSymbolicLink()) {\n file.action = 'conflict';\n file.reason = 'target is a symbolic link';\n conflicts.push(file.path);\n continue;\n }\n const current = await readFile(currentPath, 'utf8');\n if (current !== file.content) {\n file.action = 'conflict';\n file.reason = 'target exists with different content';\n conflicts.push(file.path);\n } else file.action = 'keep';\n } catch {\n /* create */\n }\n }\n return {\n bundleRoot: resolve(bundleRoot),\n projectRoot: resolve(projectRoot),\n sourceVersion: bundle.manifest.sourceVersion,\n files,\n warnings: [...bundle.manifest.warnings, ...mapped.warnings, ...specWarnings],\n conflicts,\n sourceDigest: bundle.sourceDigest,\n targetDigest: currentDigest,\n };\n}\n\nasync function digestProject(root: string): Promise<string> {\n const paths = (await walk(root)).filter((path) => !path.startsWith('.cohorte/import-preview/'));\n return digestFiles(root, paths);\n}\n\nexport async function applyV2Import(\n plan: V2ImportPlan,\n options: {\n confirm: boolean;\n backupRoot: string;\n now?: string;\n fault?: (point: V2ImportFaultPoint) => void;\n },\n): Promise<V2ImportReport> {\n if (plan.conflicts.length) throw new Error(`configuration/import-conflict: ${plan.conflicts.join(', ')}`);\n if (plan.warnings.some((item) => item.blocking))\n throw new Error('configuration/import-blocked: resolve blocking warnings first');\n if (!options.confirm) throw new Error('configuration/import-confirmation-required: rerun with explicit confirmation');\n if ((await digestProject(plan.projectRoot)) !== plan.targetDigest)\n throw new Error('configuration/import-project-changed: project changed since preview');\n const id = sha256Hex(`${plan.sourceDigest}:${plan.targetDigest}:${options.now ?? new Date().toISOString()}`).slice(\n 0,\n 16,\n );\n const backupRoot = resolve(options.backupRoot, `cohorte-v2-${id}`);\n const stage = join(backupRoot, '.stage');\n const reportPath = join(plan.projectRoot, '.cohorte', 'import-reports', `${id}.json`);\n const existing: string[] = [];\n let mutated = false;\n const restore = async () => {\n await rm(stage, { recursive: true, force: true });\n await rm(reportPath, { force: true });\n if (!mutated) return;\n for (const file of plan.files) {\n if (file.action === 'keep') continue;\n const target = join(plan.projectRoot, file.path);\n const backup = join(backupRoot, file.path);\n try {\n await stat(backup);\n await mkdir(dirname(target), { recursive: true, mode: 0o700 });\n await cp(backup, target, { recursive: true, verbatimSymlinks: true });\n } catch {\n await rm(target, { recursive: true, force: true });\n }\n }\n };\n try {\n options.fault?.('before-backup');\n await mkdir(backupRoot, { recursive: true, mode: 0o700 });\n for (const file of plan.files) {\n try {\n await lstat(join(plan.projectRoot, file.path));\n existing.push(file.path);\n await mkdir(dirname(join(backupRoot, file.path)), { recursive: true, mode: 0o700 });\n await cp(join(plan.projectRoot, file.path), join(backupRoot, file.path), {\n recursive: true,\n verbatimSymlinks: true,\n });\n } catch {\n /* new file */\n }\n }\n options.fault?.('after-backup');\n await mkdir(stage, { recursive: true, mode: 0o700 });\n for (const file of plan.files) {\n if (file.action === 'keep') continue;\n const target = join(stage, file.path);\n await mkdir(dirname(target), { recursive: true, mode: 0o700 });\n await writeFile(target, file.content, { mode: 0o600 });\n }\n options.fault?.('after-stage');\n options.fault?.('before-rename');\n for (const file of plan.files) {\n if (file.action === 'keep') continue;\n const target = join(plan.projectRoot, file.path);\n await mkdir(dirname(target), { recursive: true, mode: 0o700 });\n mutated = true;\n await rename(join(stage, file.path), target);\n }\n options.fault?.('after-rename');\n await rm(stage, { recursive: true, force: true });\n } catch (error) {\n await restore();\n throw error;\n }\n const report: V2ImportReport = {\n reportId: id,\n status: 'applied',\n bundleRoot: plan.bundleRoot,\n projectRoot: plan.projectRoot,\n backupRoot,\n sourceDigest: plan.sourceDigest,\n targetDigest: plan.targetDigest,\n files: plan.files.filter((file) => file.action !== 'keep').map((file) => file.path),\n warnings: plan.warnings,\n createdAt: options.now ?? new Date().toISOString(),\n };\n try {\n options.fault?.('before-report');\n await mkdir(dirname(reportPath), { recursive: true, mode: 0o700 });\n await writeFile(reportPath, `${JSON.stringify({ ...report, existing }, null, 2)}\\n`, { mode: 0o600 });\n } catch (error) {\n await restore();\n throw error;\n }\n return report;\n}\n\nexport async function rollbackV2Import(report: V2ImportReport): Promise<V2ImportReport> {\n for (const path of report.files) {\n const backup = join(report.backupRoot, path);\n try {\n await stat(backup);\n await mkdir(dirname(join(report.projectRoot, path)), { recursive: true, mode: 0o700 });\n await cp(backup, join(report.projectRoot, path), { recursive: true, verbatimSymlinks: true });\n } catch {\n await rm(join(report.projectRoot, path), { recursive: true, force: true });\n }\n }\n return { ...report, status: 'rolled-back' };\n}\n\nexport function projectModelFromV2(bundle: V2ExportResult, model: ProjectModel): string {\n return stringify({\n ...model,\n provenance: { ...model.provenance, toolVersion: `v2-import:${bundle.manifest.sourceVersion ?? 'unknown'}` },\n });\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { sha256Hex } from '@cohorte/base';\nimport { stringify } from 'yaml';\nimport type { InitPlan, ProjectModel } from '../contract.ts';\n\nexport interface PlanInitOptions {\n root: string;\n model: ProjectModel;\n cohorteVersion: string;\n /** refused in V3.0: `configuration/phase-not-available` */\n semantic?: boolean;\n}\n\nexport async function planInit(options: PlanInitOptions): Promise<InitPlan> {\n if (options.semantic) throw new Error('configuration/phase-not-available: semantic init is not available in V3.0');\n const root = options.root;\n const modelYaml = stringify(options.model);\n const files = [\n { path: 'project.yaml', class: 'generated' as const, content: modelYaml, templateId: 'project-model/v1' },\n { path: 'config.yaml', class: 'human' as const, content: 'schemaVersion: 1\\n' },\n { path: 'ownership.yaml', class: 'human' as const, content: 'surfaces: {}\\n' },\n {\n path: '.gitignore',\n class: 'generated' as const,\n content: 'state/\\nruns/\\n',\n templateId: 'cohorte/gitignore/v1',\n },\n {\n path: 'generated/.gitkeep',\n class: 'generated' as const,\n content: '',\n templateId: 'cohorte/generated-dir/v1',\n },\n ];\n const initFiles: InitPlan['files'] = [];\n for (const file of files) {\n let exists = false;\n try {\n await readFile(join(root, '.cohorte', file.path));\n exists = true;\n } catch {\n /* create */\n }\n const renderedSha256 = sha256Hex(file.content);\n initFiles.push({\n path: file.path,\n action: exists ? 'keep-existing' : 'create',\n class: file.class,\n content: file.content,\n ...(file.templateId === undefined ? {} : { templateId: file.templateId }),\n ...(file.class === 'generated' ? { templateSha256: renderedSha256, renderedSha256 } : {}),\n });\n }\n const generated = initFiles\n .filter((file) => file.class === 'generated')\n .map((file) => ({\n path: file.path,\n templateId: file.templateId ?? 'builtin',\n templateSha256: file.templateSha256 ?? sha256Hex(file.content),\n renderedSha256: file.renderedSha256 ?? sha256Hex(file.content),\n }));\n return {\n projectRoot: root,\n model: options.model,\n files: initFiles,\n manifest: {\n schemaVersion: 1,\n cohorteVersion: options.cohorteVersion,\n createdWith: options.cohorteVersion,\n protocol: { min: '3.0', max: '3.x' },\n stateSchemaVersion: 1,\n generated,\n },\n warnings: [],\n };\n}\n\nexport async function applyInit(plan: InitPlan): Promise<{ written: string[]; kept: string[] }> {\n await mkdir(join(plan.projectRoot, '.cohorte'), { recursive: true, mode: 0o700 });\n const written: string[] = [];\n const kept: string[] = [];\n for (const file of plan.files) {\n const target = join(plan.projectRoot, '.cohorte', file.path);\n if (file.action === 'keep-existing') {\n kept.push(file.path);\n continue;\n }\n await mkdir(join(target, '..'), { recursive: true, mode: 0o700 });\n await writeFile(target, file.content, { mode: 0o600 });\n written.push(file.path);\n }\n const manifestPath = join(plan.projectRoot, '.cohorte', 'manifest.yaml');\n try {\n await readFile(manifestPath);\n kept.push('manifest.yaml');\n } catch {\n await writeFile(manifestPath, stringify(plan.manifest), { mode: 0o600 });\n written.push('manifest.yaml');\n }\n return { written, kept };\n}\n","import { appendFile, copyFile, mkdir, readFile, unlink, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { type Clock, sha256Hex } from '@cohorte/base';\nimport { DEFAULT_CONFIG } from '@cohorte/config/schema';\nimport { parse } from 'yaml';\nimport type { DesiredState, ReconcilePlan, RepositoryScanner } from '../contract.ts';\nimport { deriveDesiredState } from '../desired/index.ts';\nimport { diffStates, readActualState } from '../drift/index.ts';\n\nexport interface PlanReconcileOptions {\n root: string;\n /** injected: this area never imports the scan area */\n scan: RepositoryScanner;\n cohorteVersion: string;\n clock: Clock;\n}\n\nexport interface ApplyReconcileOptions {\n root: string;\n plan: ReconcilePlan;\n desired: DesiredState;\n backup?: boolean;\n clock: Clock;\n}\n\n/** READ-ONLY. */\nexport async function planReconcile(options: PlanReconcileOptions): Promise<ReconcilePlan> {\n const model = await options.scan(options.root);\n // `provenance.generatedAt` is metadata, not project content. Reuse the\n // previous generated timestamp so a read-only reconcile is stable; changed\n // model fields still alter the rendered project and manifest hashes.\n let stableModel = model;\n try {\n const actual = parse(await readFile(join(options.root, '.cohorte', 'project.yaml'), 'utf8')) as {\n provenance?: { generatedAt?: unknown };\n };\n const generatedAt = actual.provenance?.generatedAt;\n const stableGeneratedAt =\n generatedAt instanceof Date\n ? generatedAt.toISOString()\n : typeof generatedAt === 'string'\n ? generatedAt\n : undefined;\n if (stableGeneratedAt !== undefined) {\n stableModel = {\n ...model,\n provenance: {\n ...model.provenance,\n generatedAt: stableGeneratedAt as typeof model.provenance.generatedAt,\n },\n };\n }\n } catch {\n /* an uninitialised or malformed project is represented by the normal drift entries */\n }\n const desired = deriveDesiredState({\n model: stableModel,\n config: DEFAULT_CONFIG,\n cohorteVersion: options.cohorteVersion,\n skills: {},\n });\n const actual = await readActualState(options.root);\n const drift = diffStates(desired, actual, options.clock);\n const operations = drift.entries.map((entry) => {\n const op =\n entry.diff === 'absent'\n ? 'create'\n : entry.diff === 'expected-change'\n ? 'replace'\n : entry.diff === 'potential-deletion'\n ? 'delete'\n : entry.diff === 'unknown'\n ? 'keep'\n : 'ask';\n return { op, target: entry.target, diff: entry.diff, reason: entry.detail } as const;\n });\n return {\n schemaVersion: 1,\n cohorteVersion: options.cohorteVersion,\n generatedAt: drift.generatedAt,\n drift,\n operations,\n conflicts: drift.entries.filter((entry) => entry.diff === 'conflict').map((entry) => entry.target),\n applyAvailable: true,\n };\n}\n\n/** Apply only create/replace/delete operations authorized by a conflict-free plan. */\nexport async function applyReconcile(options: ApplyReconcileOptions): Promise<{\n applied: string[];\n skipped: string[];\n backupDir?: string;\n journal: string;\n}> {\n if (options.plan.conflicts.length > 0)\n throw new Error(`conflict/reconcile-human-edit: ${options.plan.conflicts.join(', ')}`);\n const desiredByPath = new Map(options.desired.files.map((file) => [file.path, file]));\n const backupDir = options.backup\n ? join(options.root, '.cohorte', 'reconcile-backups', options.clock.now().replaceAll(':', ''))\n : undefined;\n const journal = join(options.root, '.cohorte', 'reconcile.log');\n await mkdir(join(options.root, '.cohorte'), { recursive: true, mode: 0o700 });\n const applied: string[] = [];\n const skipped: string[] = [];\n for (const operation of options.plan.operations) {\n if (operation.op !== 'create' && operation.op !== 'replace' && operation.op !== 'delete') {\n skipped.push(operation.target);\n continue;\n }\n const target = join(options.root, '.cohorte', operation.target);\n if (!target.startsWith(`${join(options.root, '.cohorte')}/`)) throw new Error('security/path-outside-grant');\n const existing = await readFile(target).catch(() => undefined);\n const drift = options.plan.drift.entries.find((entry) => entry.target === operation.target);\n const actualSha256 = existing === undefined ? undefined : sha256Hex(existing);\n if (actualSha256 !== drift?.actualSha256)\n throw new Error(`conflict/reconcile-race: ${operation.target} changed after the plan was generated`);\n if (existing !== undefined && backupDir) {\n const backupPath = join(backupDir, operation.target);\n await mkdir(dirname(backupPath), { recursive: true });\n await copyFile(target, backupPath);\n }\n if (operation.op === 'delete') await unlink(target).catch(() => undefined);\n else {\n const file = desiredByPath.get(operation.target);\n if (file?.content === undefined) throw new Error(`configuration/reconcile-content-missing: ${operation.target}`);\n await mkdir(dirname(target), { recursive: true });\n await writeFile(target, file.content, 'utf8');\n }\n applied.push(operation.target);\n await appendFile(\n journal,\n `${JSON.stringify({ at: options.clock.now(), op: operation.op, target: operation.target })}\\n`,\n );\n }\n return { applied, skipped, ...(backupDir ? { backupDir } : {}), journal };\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { n as sha256Hex, t as canonicalJson } from "./canonical-C8UxeEmB.mjs";
2
2
  import "./src-Cu3TxNob.mjs";
3
- import { i as Ownership, n as frozenSpecProblems, o as CohorteConfig, r as specContentSha256, s as DEFAULT_CONFIG, t as Spec } from "./schema-C9QbUW4H.mjs";
3
+ import { i as Ownership, n as frozenSpecProblems, o as CohorteConfig, r as specContentSha256, s as DEFAULT_CONFIG, t as Spec } from "./schema-Bq9qtgsd.mjs";
4
4
  import { Compile } from "typebox/compile";
5
5
  import { readFile } from "node:fs/promises";
6
6
  import { dirname, join, resolve } from "node:path";
@@ -114,4 +114,4 @@ async function freezeSpec(file) {
114
114
  //#endregion
115
115
  export { resolveConfig as i, loadConfig as n, loadSpec as r, freezeSpec as t };
116
116
 
117
- //# sourceMappingURL=src-DcU4IXMe.mjs.map
117
+ //# sourceMappingURL=src-DbS9gkJy.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"src-DcU4IXMe.mjs","names":[],"sources":["../../../../packages/config/src/load/index.ts"],"sourcesContent":["// Configuration loading and trust resolution (PLAN U2.09).\n\nimport { readFile } from 'node:fs/promises';\nimport { dirname, join, resolve } from 'node:path';\nimport { canonicalJson, type JsonValue, type Sha256, sha256Hex } from '@cohorte/base';\nimport { Compile } from 'typebox/compile';\nimport { parse } from 'yaml';\nimport {\n CohorteConfig,\n type CohorteConfig as CohorteConfigType,\n DEFAULT_CONFIG,\n type FrozenSpec as FrozenSpecType,\n frozenSpecProblems,\n Ownership,\n type Ownership as OwnershipType,\n Spec,\n type Spec as SpecType,\n specContentSha256,\n type TrustStore,\n} from '../schema/index.ts';\n\nexport interface LoadConfigOptions {\n /** any directory inside the project: the loader walks up to `.cohorte/` */\n cwd: string;\n /** the user's home: `~/.cohorte/config.yaml` is the user layer. Injected, never read from the environment here. */\n home: string;\n /** the CLI-flag layer, already shaped like a partial config document */\n flags?: JsonValue;\n}\n\n/** The four layers of DESIGN 2.10, UNMERGED: shipped defaults < user file < project file < CLI flags. */\nexport interface LoadedConfig {\n projectRoot: string;\n layers: { defaults: CohorteConfig; user?: JsonValue; project?: JsonValue; flags?: JsonValue };\n ownership: Ownership;\n}\n\nexport interface ResolveConfigOptions {\n trustStore: TrustStore;\n projectKeyId: string;\n /** `--trust-project-config`: consent form `cli-flag` for every loosening key of the project file */\n trustProjectConfig?: boolean;\n}\n\nexport interface ConfigTrust {\n policySha256: Sha256;\n loosenedKeys: string[];\n grantedBy: 'none-needed' | 'user-config' | 'cli-flag' | 'trust-record';\n}\n\nexport type ResolvedConfig =\n | { status: 'resolved'; config: CohorteConfig; sha256: Sha256; trust: ConfigTrust; warnings: string[] }\n /** the caller fails closed with `security/project-policy-untrusted` */\n | {\n status: 'untrusted';\n policySha256: Sha256;\n loosenedKeys: string[];\n diff: { pointer: string; trusted?: JsonValue; requested: JsonValue }[];\n };\n\nconst readYaml = async (file: string): Promise<JsonValue | undefined> => {\n try {\n const value: unknown = parse(await readFile(file, 'utf8'));\n return value === undefined ? undefined : (value as JsonValue);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return undefined;\n throw new Error(\n `configuration/invalid: cannot read ${file}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n};\n\nconst merge = (left: JsonValue, right: JsonValue): JsonValue => {\n if (\n typeof left !== 'object' ||\n left === null ||\n Array.isArray(left) ||\n typeof right !== 'object' ||\n right === null ||\n Array.isArray(right)\n )\n return structuredClone(right);\n const output: Record<string, JsonValue> = structuredClone(left);\n for (const [key, value] of Object.entries(right as Record<string, JsonValue>)) {\n const existing = output[key];\n output[key] = existing === undefined ? structuredClone(value) : merge(existing, value);\n }\n return output;\n};\n\nconst findProjectRoot = async (cwd: string): Promise<string> => {\n let current = resolve(cwd);\n while (true) {\n try {\n const value = await readYaml(join(current, '.cohorte', 'config.yaml'));\n if (value !== undefined) return current;\n } catch {\n /* continue to the parent so a malformed nested file is still reported by the selected root */\n }\n const parent = dirname(current);\n if (parent === current) return resolve(cwd);\n current = parent;\n }\n};\n\nexport async function loadConfig(options: LoadConfigOptions): Promise<LoadedConfig> {\n const projectRoot = await findProjectRoot(options.cwd);\n const project = await readYaml(join(projectRoot, '.cohorte', 'config.yaml'));\n const user = await readYaml(join(options.home, '.cohorte', 'config.yaml'));\n const ownershipDocument = (await readYaml(join(projectRoot, '.cohorte', 'ownership.yaml'))) ?? { surfaces: {} };\n const ownershipCheck = Compile(Ownership).Check(ownershipDocument);\n if (!ownershipCheck) throw new Error('configuration/ownership-invalid: ownership.yaml does not match its schema');\n return {\n projectRoot,\n layers: {\n defaults: DEFAULT_CONFIG,\n ...(user === undefined ? {} : { user }),\n ...(project === undefined ? {} : { project }),\n ...(options.flags === undefined ? {} : { flags: options.flags }),\n },\n ownership: ownershipDocument as OwnershipType,\n };\n}\n\nexport async function resolveConfig(loaded: LoadedConfig, options: ResolveConfigOptions): Promise<ResolvedConfig> {\n const layers: JsonValue[] = [loaded.layers.defaults as unknown as JsonValue];\n if (loaded.layers.user !== undefined) layers.push(loaded.layers.user);\n if (loaded.layers.project !== undefined) layers.push(loaded.layers.project);\n if (loaded.layers.flags !== undefined) layers.push(loaded.layers.flags);\n const [defaults, ...overrides] = layers;\n if (defaults === undefined) throw new Error('configuration/policy-invalid: defaults are missing');\n const merged = overrides.reduce(merge, defaults);\n if (!Compile(CohorteConfig).Check(merged))\n throw new Error('configuration/policy-invalid: merged configuration does not match its schema');\n const config = merged as unknown as CohorteConfigType;\n const project = loaded.layers.project;\n const loosenedKeys: string[] = [];\n if (project && typeof project === 'object' && !Array.isArray(project)) {\n for (const [key, value] of Object.entries(project)) {\n const pointer = `/${key}`;\n if (value !== undefined) loosenedKeys.push(pointer);\n }\n }\n const policySha256 = sha256Hex(\n canonicalJson({ project: project ?? {}, ownership: loaded.ownership as unknown as JsonValue }),\n );\n const trust =\n loosenedKeys.length === 0 ? undefined : await options.trustStore.lookup(options.projectKeyId, policySha256);\n if (loosenedKeys.length > 0 && !options.trustProjectConfig && trust === undefined)\n return {\n status: 'untrusted',\n policySha256,\n loosenedKeys,\n diff: loosenedKeys.map((pointer) => ({\n pointer,\n requested:\n project && typeof project === 'object' && !Array.isArray(project)\n ? (project[pointer.slice(1)] ?? null)\n : null,\n })),\n };\n return {\n status: 'resolved',\n config,\n sha256: sha256Hex(canonicalJson(config as unknown as JsonValue)),\n trust: {\n policySha256,\n loosenedKeys,\n grantedBy: loosenedKeys.length === 0 ? 'none-needed' : options.trustProjectConfig ? 'cli-flag' : 'trust-record',\n },\n warnings: [],\n };\n}\n\nexport async function loadSpec(file: string): Promise<SpecType> {\n const value = await readYaml(file);\n if (value === undefined || !Compile(Spec).Check(value)) throw new Error(`validation/spec: invalid spec ${file}`);\n const spec = value as unknown as SpecType;\n if (frozenSpecProblems(spec).length > 0) throw new Error(`validation/spec: frozen spec ${spec.id} was edited`);\n return spec;\n}\n\n/** Immutable once frozen: freezing an already frozen spec is a no-op, freezing an edited one is an error. */\nexport async function freezeSpec(file: string): Promise<FrozenSpecType> {\n const spec = await loadSpec(file);\n if (spec.status === 'frozen') return spec;\n return { ...spec, status: 'frozen', sha256: specContentSha256(spec) };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"src-DbS9gkJy.mjs","names":[],"sources":["../../../../packages/config/src/load/index.ts"],"sourcesContent":["// Configuration loading and trust resolution (PLAN U2.09).\n\nimport { readFile } from 'node:fs/promises';\nimport { dirname, join, resolve } from 'node:path';\nimport { canonicalJson, type JsonValue, type Sha256, sha256Hex } from '@cohorte/base';\nimport { Compile } from 'typebox/compile';\nimport { parse } from 'yaml';\nimport {\n CohorteConfig,\n type CohorteConfig as CohorteConfigType,\n DEFAULT_CONFIG,\n type FrozenSpec as FrozenSpecType,\n frozenSpecProblems,\n Ownership,\n type Ownership as OwnershipType,\n Spec,\n type Spec as SpecType,\n specContentSha256,\n type TrustStore,\n} from '../schema/index.ts';\n\nexport interface LoadConfigOptions {\n /** any directory inside the project: the loader walks up to `.cohorte/` */\n cwd: string;\n /** the user's home: `~/.cohorte/config.yaml` is the user layer. Injected, never read from the environment here. */\n home: string;\n /** the CLI-flag layer, already shaped like a partial config document */\n flags?: JsonValue;\n}\n\n/** The four layers of DESIGN 2.10, UNMERGED: shipped defaults < user file < project file < CLI flags. */\nexport interface LoadedConfig {\n projectRoot: string;\n layers: { defaults: CohorteConfig; user?: JsonValue; project?: JsonValue; flags?: JsonValue };\n ownership: Ownership;\n}\n\nexport interface ResolveConfigOptions {\n trustStore: TrustStore;\n projectKeyId: string;\n /** `--trust-project-config`: consent form `cli-flag` for every loosening key of the project file */\n trustProjectConfig?: boolean;\n}\n\nexport interface ConfigTrust {\n policySha256: Sha256;\n loosenedKeys: string[];\n grantedBy: 'none-needed' | 'user-config' | 'cli-flag' | 'trust-record';\n}\n\nexport type ResolvedConfig =\n | { status: 'resolved'; config: CohorteConfig; sha256: Sha256; trust: ConfigTrust; warnings: string[] }\n /** the caller fails closed with `security/project-policy-untrusted` */\n | {\n status: 'untrusted';\n policySha256: Sha256;\n loosenedKeys: string[];\n diff: { pointer: string; trusted?: JsonValue; requested: JsonValue }[];\n };\n\nconst readYaml = async (file: string): Promise<JsonValue | undefined> => {\n try {\n const value: unknown = parse(await readFile(file, 'utf8'));\n return value === undefined ? undefined : (value as JsonValue);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return undefined;\n throw new Error(\n `configuration/invalid: cannot read ${file}: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n};\n\nconst merge = (left: JsonValue, right: JsonValue): JsonValue => {\n if (\n typeof left !== 'object' ||\n left === null ||\n Array.isArray(left) ||\n typeof right !== 'object' ||\n right === null ||\n Array.isArray(right)\n )\n return structuredClone(right);\n const output: Record<string, JsonValue> = structuredClone(left);\n for (const [key, value] of Object.entries(right as Record<string, JsonValue>)) {\n const existing = output[key];\n output[key] = existing === undefined ? structuredClone(value) : merge(existing, value);\n }\n return output;\n};\n\nconst findProjectRoot = async (cwd: string): Promise<string> => {\n let current = resolve(cwd);\n while (true) {\n try {\n const value = await readYaml(join(current, '.cohorte', 'config.yaml'));\n if (value !== undefined) return current;\n } catch {\n /* continue to the parent so a malformed nested file is still reported by the selected root */\n }\n const parent = dirname(current);\n if (parent === current) return resolve(cwd);\n current = parent;\n }\n};\n\nexport async function loadConfig(options: LoadConfigOptions): Promise<LoadedConfig> {\n const projectRoot = await findProjectRoot(options.cwd);\n const project = await readYaml(join(projectRoot, '.cohorte', 'config.yaml'));\n const user = await readYaml(join(options.home, '.cohorte', 'config.yaml'));\n const ownershipDocument = (await readYaml(join(projectRoot, '.cohorte', 'ownership.yaml'))) ?? { surfaces: {} };\n const ownershipCheck = Compile(Ownership).Check(ownershipDocument);\n if (!ownershipCheck) throw new Error('configuration/ownership-invalid: ownership.yaml does not match its schema');\n return {\n projectRoot,\n layers: {\n defaults: DEFAULT_CONFIG,\n ...(user === undefined ? {} : { user }),\n ...(project === undefined ? {} : { project }),\n ...(options.flags === undefined ? {} : { flags: options.flags }),\n },\n ownership: ownershipDocument as OwnershipType,\n };\n}\n\nexport async function resolveConfig(loaded: LoadedConfig, options: ResolveConfigOptions): Promise<ResolvedConfig> {\n const layers: JsonValue[] = [loaded.layers.defaults as unknown as JsonValue];\n if (loaded.layers.user !== undefined) layers.push(loaded.layers.user);\n if (loaded.layers.project !== undefined) layers.push(loaded.layers.project);\n if (loaded.layers.flags !== undefined) layers.push(loaded.layers.flags);\n const [defaults, ...overrides] = layers;\n if (defaults === undefined) throw new Error('configuration/policy-invalid: defaults are missing');\n const merged = overrides.reduce(merge, defaults);\n if (!Compile(CohorteConfig).Check(merged))\n throw new Error('configuration/policy-invalid: merged configuration does not match its schema');\n const config = merged as unknown as CohorteConfigType;\n const project = loaded.layers.project;\n const loosenedKeys: string[] = [];\n if (project && typeof project === 'object' && !Array.isArray(project)) {\n for (const [key, value] of Object.entries(project)) {\n const pointer = `/${key}`;\n if (value !== undefined) loosenedKeys.push(pointer);\n }\n }\n const policySha256 = sha256Hex(\n canonicalJson({ project: project ?? {}, ownership: loaded.ownership as unknown as JsonValue }),\n );\n const trust =\n loosenedKeys.length === 0 ? undefined : await options.trustStore.lookup(options.projectKeyId, policySha256);\n if (loosenedKeys.length > 0 && !options.trustProjectConfig && trust === undefined)\n return {\n status: 'untrusted',\n policySha256,\n loosenedKeys,\n diff: loosenedKeys.map((pointer) => ({\n pointer,\n requested:\n project && typeof project === 'object' && !Array.isArray(project)\n ? (project[pointer.slice(1)] ?? null)\n : null,\n })),\n };\n return {\n status: 'resolved',\n config,\n sha256: sha256Hex(canonicalJson(config as unknown as JsonValue)),\n trust: {\n policySha256,\n loosenedKeys,\n grantedBy: loosenedKeys.length === 0 ? 'none-needed' : options.trustProjectConfig ? 'cli-flag' : 'trust-record',\n },\n warnings: [],\n };\n}\n\nexport async function loadSpec(file: string): Promise<SpecType> {\n const value = await readYaml(file);\n if (value === undefined || !Compile(Spec).Check(value)) throw new Error(`validation/spec: invalid spec ${file}`);\n const spec = value as unknown as SpecType;\n if (frozenSpecProblems(spec).length > 0) throw new Error(`validation/spec: frozen spec ${spec.id} was edited`);\n return spec;\n}\n\n/** Immutable once frozen: freezing an already frozen spec is a no-op, freezing an edited one is an error. */\nexport async function freezeSpec(file: string): Promise<FrozenSpecType> {\n const spec = await loadSpec(file);\n if (spec.status === 'frozen') return spec;\n return { ...spec, status: 'frozen', sha256: specContentSha256(spec) };\n}\n"],"mappings":"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"}
@@ -1159,6 +1159,8 @@ const CommandAuth = Type.Object({
1159
1159
  const StartPayload = Type.Object({
1160
1160
  profile: PipelineProfile,
1161
1161
  spec: Type.Optional(Type.Union([Type.Object({ id: SpecId }), Type.Object({ path: Type.String() })])),
1162
+ /** Optional surface scope used by fix/refactor follow-up runs. Omitted means the full ownership plan. */
1163
+ surfaces: Type.Optional(Type.Array(SurfaceId)),
1162
1164
  reviewTarget: Type.Optional(Type.Union([
1163
1165
  Type.Object({ ref: Type.String() }),
1164
1166
  Type.Object({
@@ -2111,6 +2113,6 @@ const isDurableEventType = (type) => isEventType(type) && EVENTS[type].durabilit
2111
2113
  */
2112
2114
  const catalogue = bindCatalogue(EVENTS);
2113
2115
  //#endregion
2114
- export { compileSchema as a, AgentOutput as c, EscalationPolicy as d, HALTED_STATES as f, ClosedEnum as g, TERMINAL_STATES as h, canonicalCommandBody as i, ACTIVE_PIPELINE_STATES as l, SUSPENDED_STATES as m, isDurableEventType as n, toStrictSchema as o, PipelineProfile as p, CONTROLLER_EXIT_CODES as r, compareOrder as s, catalogue as t, ActivePipelineState as u };
2116
+ export { ClosedEnum as _, compileSchema as a, AgentOutput as c, ActivePipelineState as d, EscalationPolicy as f, TERMINAL_STATES as g, SUSPENDED_STATES as h, canonicalCommandBody as i, ReviewResult as l, PipelineProfile as m, isDurableEventType as n, toStrictSchema as o, HALTED_STATES as p, CONTROLLER_EXIT_CODES as r, compareOrder as s, catalogue as t, ACTIVE_PIPELINE_STATES as u };
2115
2117
 
2116
- //# sourceMappingURL=src-s7YRvk0t.mjs.map
2118
+ //# sourceMappingURL=src-yi5whv3n.mjs.map