@cleocode/contracts 2026.5.111 → 2026.5.113

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 (118) hide show
  1. package/dist/__tests__/cli-meta-suggested-next.test.d.ts +21 -0
  2. package/dist/__tests__/cli-meta-suggested-next.test.d.ts.map +1 -0
  3. package/dist/__tests__/cli-meta-suggested-next.test.js +70 -0
  4. package/dist/__tests__/cli-meta-suggested-next.test.js.map +1 -0
  5. package/dist/__tests__/evidence-atom-schema.test.d.ts +16 -0
  6. package/dist/__tests__/evidence-atom-schema.test.d.ts.map +1 -0
  7. package/dist/__tests__/evidence-atom-schema.test.js +394 -0
  8. package/dist/__tests__/evidence-atom-schema.test.js.map +1 -0
  9. package/dist/config/__tests__/manifest.test.d.ts +13 -0
  10. package/dist/config/__tests__/manifest.test.d.ts.map +1 -0
  11. package/dist/config/__tests__/manifest.test.js +143 -0
  12. package/dist/config/__tests__/manifest.test.js.map +1 -0
  13. package/dist/config/manifest.d.ts +158 -0
  14. package/dist/config/manifest.d.ts.map +1 -0
  15. package/dist/config/manifest.js +123 -0
  16. package/dist/config/manifest.js.map +1 -0
  17. package/dist/docs/__tests__/provenance.test.d.ts +14 -0
  18. package/dist/docs/__tests__/provenance.test.d.ts.map +1 -0
  19. package/dist/docs/__tests__/provenance.test.js +579 -0
  20. package/dist/docs/__tests__/provenance.test.js.map +1 -0
  21. package/dist/docs/provenance.d.ts +731 -0
  22. package/dist/docs/provenance.d.ts.map +1 -0
  23. package/dist/docs/provenance.js +258 -0
  24. package/dist/docs/provenance.js.map +1 -0
  25. package/dist/docs-taxonomy.d.ts +24 -0
  26. package/dist/docs-taxonomy.d.ts.map +1 -1
  27. package/dist/docs-taxonomy.js +27 -0
  28. package/dist/docs-taxonomy.js.map +1 -1
  29. package/dist/doctor.d.ts +101 -0
  30. package/dist/doctor.d.ts.map +1 -1
  31. package/dist/errors.d.ts +4 -0
  32. package/dist/errors.d.ts.map +1 -1
  33. package/dist/errors.js +4 -0
  34. package/dist/errors.js.map +1 -1
  35. package/dist/evidence-atom-schema.d.ts +407 -0
  36. package/dist/evidence-atom-schema.d.ts.map +1 -0
  37. package/dist/evidence-atom-schema.js +505 -0
  38. package/dist/evidence-atom-schema.js.map +1 -0
  39. package/dist/exit-codes.d.ts +37 -0
  40. package/dist/exit-codes.d.ts.map +1 -1
  41. package/dist/exit-codes.js +37 -0
  42. package/dist/exit-codes.js.map +1 -1
  43. package/dist/index.d.ts +13 -2
  44. package/dist/index.d.ts.map +1 -1
  45. package/dist/index.js +8 -1
  46. package/dist/index.js.map +1 -1
  47. package/dist/invariants/__tests__/adr-056-release.test.d.ts +16 -0
  48. package/dist/invariants/__tests__/adr-056-release.test.d.ts.map +1 -0
  49. package/dist/invariants/__tests__/adr-056-release.test.js +88 -0
  50. package/dist/invariants/__tests__/adr-056-release.test.js.map +1 -0
  51. package/dist/invariants/__tests__/adr-070-orchestration.test.d.ts +22 -0
  52. package/dist/invariants/__tests__/adr-070-orchestration.test.d.ts.map +1 -0
  53. package/dist/invariants/__tests__/adr-070-orchestration.test.js +151 -0
  54. package/dist/invariants/__tests__/adr-070-orchestration.test.js.map +1 -0
  55. package/dist/invariants/__tests__/registry.test.d.ts +14 -0
  56. package/dist/invariants/__tests__/registry.test.d.ts.map +1 -0
  57. package/dist/invariants/__tests__/registry.test.js +113 -0
  58. package/dist/invariants/__tests__/registry.test.js.map +1 -0
  59. package/dist/invariants/adr-056-release.d.ts +42 -0
  60. package/dist/invariants/adr-056-release.d.ts.map +1 -0
  61. package/dist/invariants/adr-056-release.js +143 -0
  62. package/dist/invariants/adr-056-release.js.map +1 -0
  63. package/dist/invariants/adr-070-orchestration.d.ts +73 -0
  64. package/dist/invariants/adr-070-orchestration.d.ts.map +1 -0
  65. package/dist/invariants/adr-070-orchestration.js +290 -0
  66. package/dist/invariants/adr-070-orchestration.js.map +1 -0
  67. package/dist/invariants/adr-073-saga.d.ts +32 -0
  68. package/dist/invariants/adr-073-saga.d.ts.map +1 -0
  69. package/dist/invariants/adr-073-saga.js +155 -0
  70. package/dist/invariants/adr-073-saga.js.map +1 -0
  71. package/dist/invariants/index.d.ts +162 -0
  72. package/dist/invariants/index.d.ts.map +1 -0
  73. package/dist/invariants/index.js +118 -0
  74. package/dist/invariants/index.js.map +1 -0
  75. package/dist/operations/__tests__/input-contract.test.d.ts +20 -0
  76. package/dist/operations/__tests__/input-contract.test.d.ts.map +1 -0
  77. package/dist/operations/__tests__/input-contract.test.js +158 -0
  78. package/dist/operations/__tests__/input-contract.test.js.map +1 -0
  79. package/dist/operations/docs.d.ts +16 -0
  80. package/dist/operations/docs.d.ts.map +1 -1
  81. package/dist/operations/input-contract.d.ts +267 -0
  82. package/dist/operations/input-contract.d.ts.map +1 -0
  83. package/dist/operations/input-contract.js +29 -0
  84. package/dist/operations/input-contract.js.map +1 -0
  85. package/dist/templates/__tests__/manifest.test.d.ts +18 -0
  86. package/dist/templates/__tests__/manifest.test.d.ts.map +1 -0
  87. package/dist/templates/__tests__/manifest.test.js +123 -0
  88. package/dist/templates/__tests__/manifest.test.js.map +1 -0
  89. package/dist/templates/manifest.d.ts +186 -0
  90. package/dist/templates/manifest.d.ts.map +1 -0
  91. package/dist/templates/manifest.js +165 -0
  92. package/dist/templates/manifest.js.map +1 -0
  93. package/package.json +2 -2
  94. package/src/__tests__/cli-meta-suggested-next.test.ts +76 -0
  95. package/src/__tests__/evidence-atom-schema.test.ts +499 -0
  96. package/src/config/__tests__/manifest.test.ts +176 -0
  97. package/src/config/manifest.ts +218 -0
  98. package/src/docs/__tests__/__snapshots__/provenance.test.ts.snap +252 -0
  99. package/src/docs/__tests__/provenance.test.ts +648 -0
  100. package/src/docs/provenance.ts +601 -0
  101. package/src/docs-taxonomy.ts +55 -0
  102. package/src/doctor.ts +111 -0
  103. package/src/errors.ts +4 -0
  104. package/src/evidence-atom-schema.ts +628 -0
  105. package/src/exit-codes.ts +39 -0
  106. package/src/index.ts +129 -0
  107. package/src/invariants/__tests__/adr-056-release.test.ts +102 -0
  108. package/src/invariants/__tests__/adr-070-orchestration.test.ts +186 -0
  109. package/src/invariants/__tests__/registry.test.ts +136 -0
  110. package/src/invariants/adr-056-release.ts +154 -0
  111. package/src/invariants/adr-070-orchestration.ts +317 -0
  112. package/src/invariants/adr-073-saga.ts +167 -0
  113. package/src/invariants/index.ts +222 -0
  114. package/src/operations/__tests__/input-contract.test.ts +188 -0
  115. package/src/operations/docs.ts +16 -0
  116. package/src/operations/input-contract.ts +301 -0
  117. package/src/templates/__tests__/manifest.test.ts +140 -0
  118. package/src/templates/manifest.ts +208 -0
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Tests for the ConfigManifest contract (T9876 / Saga T9855 / ADR-076).
3
+ *
4
+ * Covers:
5
+ * - Schema round-trip for each of the 4 built-in entries.
6
+ * - Merge-precedence invariant (project > global > defaults).
7
+ * - Metadata-scope isolation (NOT in the merge chain).
8
+ * - {@link DriftDetection} exhaustiveness via a `never` fallback switch.
9
+ *
10
+ * @task T9876
11
+ */
12
+ import { describe, expect, it } from 'vitest';
13
+ import { CLEO_CONFIG_MANIFEST, CONFIG_MANIFEST_ENTRIES, configManifestEntrySchema, GLOBAL_CLEO_CONFIG_MANIFEST, PROJECT_CONTEXT_MANIFEST, PROJECT_INFO_MANIFEST, } from '../manifest.js';
14
+ describe('ConfigManifest built-in entries', () => {
15
+ const builtins = [
16
+ ['PROJECT_INFO_MANIFEST', PROJECT_INFO_MANIFEST],
17
+ ['PROJECT_CONTEXT_MANIFEST', PROJECT_CONTEXT_MANIFEST],
18
+ ['CLEO_CONFIG_MANIFEST', CLEO_CONFIG_MANIFEST],
19
+ ['GLOBAL_CLEO_CONFIG_MANIFEST', GLOBAL_CLEO_CONFIG_MANIFEST],
20
+ ];
21
+ for (const [name, entry] of builtins) {
22
+ it(`${name} validates against configManifestEntrySchema`, () => {
23
+ const parsed = configManifestEntrySchema.parse(entry);
24
+ expect(parsed.id).toBe(entry.id);
25
+ expect(parsed.scope).toBe(entry.scope);
26
+ expect(parsed.path).toBe(entry.path);
27
+ expect(parsed.mergePrecedence).toBe(entry.mergePrecedence);
28
+ expect(parsed.driftDetection).toBe(entry.driftDetection);
29
+ });
30
+ }
31
+ it('CONFIG_MANIFEST_ENTRIES contains all 4 built-in entries', () => {
32
+ const ids = CONFIG_MANIFEST_ENTRIES.map((e) => e.id).sort();
33
+ expect(ids).toEqual([
34
+ 'cleo-config-global',
35
+ 'cleo-config-project',
36
+ 'project-context',
37
+ 'project-info',
38
+ ]);
39
+ });
40
+ it('CONFIG_MANIFEST_ENTRIES is frozen', () => {
41
+ expect(Object.isFrozen(CONFIG_MANIFEST_ENTRIES)).toBe(true);
42
+ });
43
+ });
44
+ describe('Merge-precedence invariant (project > global > defaults)', () => {
45
+ it('project precedence > global precedence (higher wins)', () => {
46
+ expect(CLEO_CONFIG_MANIFEST.mergePrecedence).toBeGreaterThan(GLOBAL_CLEO_CONFIG_MANIFEST.mergePrecedence);
47
+ });
48
+ it('canonical precedence values: project=20, global=10, metadata=0', () => {
49
+ expect(CLEO_CONFIG_MANIFEST.mergePrecedence).toBe(20);
50
+ expect(GLOBAL_CLEO_CONFIG_MANIFEST.mergePrecedence).toBe(10);
51
+ expect(PROJECT_INFO_MANIFEST.mergePrecedence).toBe(0);
52
+ expect(PROJECT_CONTEXT_MANIFEST.mergePrecedence).toBe(0);
53
+ });
54
+ it('cascade-resolver sort order yields global then project (project wins)', () => {
55
+ const cascadeEntries = CONFIG_MANIFEST_ENTRIES.filter((e) => e.scope === 'global' || e.scope === 'project')
56
+ .slice() // copy before sort — array is frozen
57
+ .sort((a, b) => a.mergePrecedence - b.mergePrecedence);
58
+ expect(cascadeEntries.map((e) => e.scope)).toEqual(['global', 'project']);
59
+ });
60
+ });
61
+ describe('Metadata-scope isolation', () => {
62
+ it('metadata entries are NOT in the cascade merge chain', () => {
63
+ const cascadeScopes = CONFIG_MANIFEST_ENTRIES.filter((e) => e.scope !== 'metadata').map((e) => e.scope);
64
+ expect(cascadeScopes).toEqual(expect.arrayContaining(['global', 'project']));
65
+ expect(cascadeScopes).not.toContain('metadata');
66
+ });
67
+ it('all metadata entries have mergePrecedence 0 (separate channel)', () => {
68
+ const metadataEntries = CONFIG_MANIFEST_ENTRIES.filter((e) => e.scope === 'metadata');
69
+ expect(metadataEntries.length).toBeGreaterThan(0);
70
+ for (const e of metadataEntries) {
71
+ expect(e.mergePrecedence).toBe(0);
72
+ }
73
+ });
74
+ });
75
+ describe('DriftDetection exhaustiveness (type-level)', () => {
76
+ it('switch over DriftDetection covers all variants with never fallback', () => {
77
+ const describe_ = (d) => {
78
+ switch (d) {
79
+ case 'schema-validate':
80
+ return 'schema-validate';
81
+ case 'staleness-gate':
82
+ return 'staleness-gate';
83
+ case 'value-diff':
84
+ return 'value-diff';
85
+ case 'none':
86
+ return 'none';
87
+ default: {
88
+ // If a new variant is added without updating this switch, TS will
89
+ // refuse to assign it to `never` at compile time.
90
+ const _exhaustive = d;
91
+ return _exhaustive;
92
+ }
93
+ }
94
+ };
95
+ expect(describe_('schema-validate')).toBe('schema-validate');
96
+ expect(describe_('staleness-gate')).toBe('staleness-gate');
97
+ expect(describe_('value-diff')).toBe('value-diff');
98
+ expect(describe_('none')).toBe('none');
99
+ });
100
+ });
101
+ describe('configManifestEntrySchema rejects invalid input', () => {
102
+ it('rejects empty id', () => {
103
+ const result = configManifestEntrySchema.safeParse({
104
+ id: '',
105
+ scope: 'project',
106
+ path: '.cleo/config.json',
107
+ mergePrecedence: 20,
108
+ driftDetection: 'schema-validate',
109
+ });
110
+ expect(result.success).toBe(false);
111
+ });
112
+ it('rejects unknown scope', () => {
113
+ const result = configManifestEntrySchema.safeParse({
114
+ id: 'x',
115
+ scope: 'workspace',
116
+ path: '.cleo/x.json',
117
+ mergePrecedence: 0,
118
+ driftDetection: 'none',
119
+ });
120
+ expect(result.success).toBe(false);
121
+ });
122
+ it('rejects negative mergePrecedence', () => {
123
+ const result = configManifestEntrySchema.safeParse({
124
+ id: 'x',
125
+ scope: 'project',
126
+ path: '.cleo/x.json',
127
+ mergePrecedence: -1,
128
+ driftDetection: 'none',
129
+ });
130
+ expect(result.success).toBe(false);
131
+ });
132
+ it('rejects unknown driftDetection variant', () => {
133
+ const result = configManifestEntrySchema.safeParse({
134
+ id: 'x',
135
+ scope: 'project',
136
+ path: '.cleo/x.json',
137
+ mergePrecedence: 0,
138
+ driftDetection: 'sha-compare',
139
+ });
140
+ expect(result.success).toBe(false);
141
+ });
142
+ });
143
+ //# sourceMappingURL=manifest.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.test.js","sourceRoot":"","sources":["../../../src/config/__tests__/manifest.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,158 @@
1
+ /**
2
+ * ConfigManifest contract — declarative registry of every config-like file CLEO
3
+ * reads, writes, or merges, with its scope, schema, merge precedence, and the
4
+ * drift-detection strategy applied to it.
5
+ *
6
+ * Foundation for the CORE SSoT config registry (T9878) and the `resolveCleoConfig`
7
+ * cascade resolver. Built-in entries cover the four canonical CLEO files:
8
+ *
9
+ * - `~/.cleo/config.json` (`global`, precedence 10)
10
+ * - `<project>/.cleo/config.json` (`project`, precedence 20)
11
+ * - `<project>/.cleo/project-info.json` (`metadata`, separate channel)
12
+ * - `<project>/.cleo/project-context.json` (`metadata`, separate channel)
13
+ *
14
+ * Merge semantics: higher `mergePrecedence` wins. The `metadata` scope is
15
+ * intentionally OUTSIDE the project ↔ global merge chain — those files are
16
+ * read-only consumer state and must NEVER be merged into resolved CleoConfig.
17
+ *
18
+ * @task T9876
19
+ * @saga T9855
20
+ * @adr 076
21
+ */
22
+ import { type ZodTypeAny, z } from 'zod';
23
+ /**
24
+ * Cascade-participating scopes for the project ↔ global merge chain.
25
+ *
26
+ * - `'global'` — `~/.cleo/config.json` (precedence 10)
27
+ * - `'project'` — `<project>/.cleo/config.json` (precedence 20, higher wins)
28
+ *
29
+ * Note: `'metadata'` is NOT part of this union — metadata-scoped files are
30
+ * read-only consumer state and live on a separate channel. See
31
+ * {@link ConfigManifestScope} for the full union including metadata.
32
+ *
33
+ * @task T9876
34
+ */
35
+ export type ConfigScope = 'global' | 'project';
36
+ /**
37
+ * Full scope union covering cascade scopes AND the read-only `metadata`
38
+ * channel used by `project-info.json` and `project-context.json`.
39
+ *
40
+ * Metadata-scoped entries are NEVER merged into the resolved CleoConfig —
41
+ * they are surfaced separately as consumer state and validated only for
42
+ * schema conformance / staleness.
43
+ *
44
+ * @task T9876
45
+ */
46
+ export type ConfigManifestScope = ConfigScope | 'metadata';
47
+ /**
48
+ * Drift-detection strategy applied to a manifest entry.
49
+ *
50
+ * - `'schema-validate'` — Re-parse the file's contents against {@link ConfigManifestEntry.schema}
51
+ * on read. Any parse error is reported as drift.
52
+ * - `'staleness-gate'` — Compare the file's `detectedAt` (or equivalent freshness key)
53
+ * against a freshness threshold. Stale files are flagged but not rejected.
54
+ * - `'value-diff'` — Diff the file's resolved values against the manifest's
55
+ * `defaults` baseline and report changed keys. Useful for invariant tracking.
56
+ * - `'none'` — No drift detection. Entry is informational-only.
57
+ *
58
+ * @task T9876
59
+ */
60
+ export type DriftDetection = 'schema-validate' | 'staleness-gate' | 'value-diff' | 'none';
61
+ /**
62
+ * A single registry entry describing one config-like file CLEO is aware of.
63
+ *
64
+ * `mergePrecedence` orders entries within the SAME scope channel. Across
65
+ * channels, the cascade-resolver consumes entries with `scope` in
66
+ * {@link ConfigScope} (global/project) and merges by ascending precedence
67
+ * (higher wins). Metadata entries are surfaced separately.
68
+ *
69
+ * @task T9876
70
+ */
71
+ export interface ConfigManifestEntry {
72
+ /** Stable identifier for the entry (e.g. `'cleo-config-project'`). */
73
+ id: string;
74
+ /** Where the file lives in the precedence hierarchy. */
75
+ scope: ConfigManifestScope;
76
+ /** Absolute or `~`-rooted path to the file on disk. */
77
+ path: string;
78
+ /**
79
+ * Optional Zod schema used by the `'schema-validate'` drift detector to
80
+ * re-parse the file's contents. `null` disables schema validation even when
81
+ * `driftDetection === 'schema-validate'` (advisory-only mode).
82
+ */
83
+ schema?: ZodTypeAny | null;
84
+ /**
85
+ * Numeric merge precedence within the cascade. Higher wins.
86
+ *
87
+ * Canonical values:
88
+ * - `0` — defaults / metadata (NOT part of the merge chain)
89
+ * - `10` — global
90
+ * - `20` — project
91
+ */
92
+ mergePrecedence: number;
93
+ /** Drift-detection strategy to apply to this entry. */
94
+ driftDetection: DriftDetection;
95
+ /** Optional default values used as the baseline for `'value-diff'` drift detection. */
96
+ defaults?: Record<string, unknown>;
97
+ }
98
+ /**
99
+ * Manifest entry for `<project>/.cleo/project-info.json`.
100
+ *
101
+ * Metadata channel (NOT part of the merge cascade). Schema-validated on
102
+ * read because the file is consumer state with a stable shape.
103
+ *
104
+ * @task T9876
105
+ */
106
+ export declare const PROJECT_INFO_MANIFEST: ConfigManifestEntry;
107
+ /**
108
+ * Manifest entry for `<project>/.cleo/project-context.json`.
109
+ *
110
+ * Metadata channel. Staleness-gated because the file is regenerated by
111
+ * project-detection scans and consumers care about freshness, not exact shape.
112
+ *
113
+ * @task T9876
114
+ */
115
+ export declare const PROJECT_CONTEXT_MANIFEST: ConfigManifestEntry;
116
+ /**
117
+ * Manifest entry for `<project>/.cleo/config.json` (project-scoped CleoConfig).
118
+ *
119
+ * Project scope; precedence 20 — wins over global. Schema-validated.
120
+ *
121
+ * @task T9876
122
+ */
123
+ export declare const CLEO_CONFIG_MANIFEST: ConfigManifestEntry;
124
+ /**
125
+ * Manifest entry for `~/.cleo/config.json` (global CleoConfig).
126
+ *
127
+ * Global scope; precedence 10 — loses to project. Schema-validated.
128
+ *
129
+ * @task T9876
130
+ */
131
+ export declare const GLOBAL_CLEO_CONFIG_MANIFEST: ConfigManifestEntry;
132
+ /**
133
+ * Frozen registry of all built-in manifest entries shipped with the contracts
134
+ * package. Order is informational only — consumers MUST sort by
135
+ * `mergePrecedence` when applying the cascade.
136
+ *
137
+ * @task T9876
138
+ */
139
+ export declare const CONFIG_MANIFEST_ENTRIES: readonly ConfigManifestEntry[];
140
+ /**
141
+ * Zod schema for {@link ConfigManifestEntry}.
142
+ *
143
+ * Treats `schema` as `unknown` because `ZodTypeAny` instances cannot be
144
+ * validated through Zod itself without infinite recursion — schema-shape
145
+ * checking is the responsibility of the consumer that constructs the entry.
146
+ *
147
+ * @task T9876
148
+ */
149
+ export declare const configManifestEntrySchema: z.ZodObject<{
150
+ id: z.ZodString;
151
+ scope: z.ZodUnion<readonly [z.ZodLiteral<"global">, z.ZodLiteral<"project">, z.ZodLiteral<"metadata">]>;
152
+ path: z.ZodString;
153
+ schema: z.ZodOptional<z.ZodUnknown>;
154
+ mergePrecedence: z.ZodNumber;
155
+ driftDetection: z.ZodUnion<readonly [z.ZodLiteral<"schema-validate">, z.ZodLiteral<"staleness-gate">, z.ZodLiteral<"value-diff">, z.ZodLiteral<"none">]>;
156
+ defaults: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
157
+ }, z.core.$strip>;
158
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/config/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,KAAK,UAAU,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMzC;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE/C;;;;;;;;;GASG;AACH,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG,UAAU,CAAC;AAE3D;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,cAAc,GAAG,iBAAiB,GAAG,gBAAgB,GAAG,YAAY,GAAG,MAAM,CAAC;AAM1F;;;;;;;;;GASG;AACH,MAAM,WAAW,mBAAmB;IAClC,sEAAsE;IACtE,EAAE,EAAE,MAAM,CAAC;IACX,wDAAwD;IACxD,KAAK,EAAE,mBAAmB,CAAC;IAC3B,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,MAAM,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC3B;;;;;;;OAOG;IACH,eAAe,EAAE,MAAM,CAAC;IACxB,uDAAuD;IACvD,cAAc,EAAE,cAAc,CAAC;IAC/B,uFAAuF;IACvF,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAMD;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,EAAE,mBAMnC,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,EAAE,mBAMtC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,EAAE,mBAMlC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,EAAE,mBAMzC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,EAAE,SAAS,mBAAmB,EAKhE,CAAC;AAMH;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;iBAapC,CAAC"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * ConfigManifest contract — declarative registry of every config-like file CLEO
3
+ * reads, writes, or merges, with its scope, schema, merge precedence, and the
4
+ * drift-detection strategy applied to it.
5
+ *
6
+ * Foundation for the CORE SSoT config registry (T9878) and the `resolveCleoConfig`
7
+ * cascade resolver. Built-in entries cover the four canonical CLEO files:
8
+ *
9
+ * - `~/.cleo/config.json` (`global`, precedence 10)
10
+ * - `<project>/.cleo/config.json` (`project`, precedence 20)
11
+ * - `<project>/.cleo/project-info.json` (`metadata`, separate channel)
12
+ * - `<project>/.cleo/project-context.json` (`metadata`, separate channel)
13
+ *
14
+ * Merge semantics: higher `mergePrecedence` wins. The `metadata` scope is
15
+ * intentionally OUTSIDE the project ↔ global merge chain — those files are
16
+ * read-only consumer state and must NEVER be merged into resolved CleoConfig.
17
+ *
18
+ * @task T9876
19
+ * @saga T9855
20
+ * @adr 076
21
+ */
22
+ import { z } from 'zod';
23
+ // ───────────────────────────────────────────────────────────────────────────
24
+ // Built-in manifest entries (4 canonical CLEO files)
25
+ // ───────────────────────────────────────────────────────────────────────────
26
+ /**
27
+ * Manifest entry for `<project>/.cleo/project-info.json`.
28
+ *
29
+ * Metadata channel (NOT part of the merge cascade). Schema-validated on
30
+ * read because the file is consumer state with a stable shape.
31
+ *
32
+ * @task T9876
33
+ */
34
+ export const PROJECT_INFO_MANIFEST = {
35
+ id: 'project-info',
36
+ scope: 'metadata',
37
+ path: '.cleo/project-info.json',
38
+ mergePrecedence: 0,
39
+ driftDetection: 'schema-validate',
40
+ };
41
+ /**
42
+ * Manifest entry for `<project>/.cleo/project-context.json`.
43
+ *
44
+ * Metadata channel. Staleness-gated because the file is regenerated by
45
+ * project-detection scans and consumers care about freshness, not exact shape.
46
+ *
47
+ * @task T9876
48
+ */
49
+ export const PROJECT_CONTEXT_MANIFEST = {
50
+ id: 'project-context',
51
+ scope: 'metadata',
52
+ path: '.cleo/project-context.json',
53
+ mergePrecedence: 0,
54
+ driftDetection: 'staleness-gate',
55
+ };
56
+ /**
57
+ * Manifest entry for `<project>/.cleo/config.json` (project-scoped CleoConfig).
58
+ *
59
+ * Project scope; precedence 20 — wins over global. Schema-validated.
60
+ *
61
+ * @task T9876
62
+ */
63
+ export const CLEO_CONFIG_MANIFEST = {
64
+ id: 'cleo-config-project',
65
+ scope: 'project',
66
+ path: '.cleo/config.json',
67
+ mergePrecedence: 20,
68
+ driftDetection: 'schema-validate',
69
+ };
70
+ /**
71
+ * Manifest entry for `~/.cleo/config.json` (global CleoConfig).
72
+ *
73
+ * Global scope; precedence 10 — loses to project. Schema-validated.
74
+ *
75
+ * @task T9876
76
+ */
77
+ export const GLOBAL_CLEO_CONFIG_MANIFEST = {
78
+ id: 'cleo-config-global',
79
+ scope: 'global',
80
+ path: '~/.cleo/config.json',
81
+ mergePrecedence: 10,
82
+ driftDetection: 'schema-validate',
83
+ };
84
+ /**
85
+ * Frozen registry of all built-in manifest entries shipped with the contracts
86
+ * package. Order is informational only — consumers MUST sort by
87
+ * `mergePrecedence` when applying the cascade.
88
+ *
89
+ * @task T9876
90
+ */
91
+ export const CONFIG_MANIFEST_ENTRIES = Object.freeze([
92
+ PROJECT_INFO_MANIFEST,
93
+ PROJECT_CONTEXT_MANIFEST,
94
+ GLOBAL_CLEO_CONFIG_MANIFEST,
95
+ CLEO_CONFIG_MANIFEST,
96
+ ]);
97
+ // ───────────────────────────────────────────────────────────────────────────
98
+ // Runtime validation schema
99
+ // ───────────────────────────────────────────────────────────────────────────
100
+ /**
101
+ * Zod schema for {@link ConfigManifestEntry}.
102
+ *
103
+ * Treats `schema` as `unknown` because `ZodTypeAny` instances cannot be
104
+ * validated through Zod itself without infinite recursion — schema-shape
105
+ * checking is the responsibility of the consumer that constructs the entry.
106
+ *
107
+ * @task T9876
108
+ */
109
+ export const configManifestEntrySchema = z.object({
110
+ id: z.string().min(1),
111
+ scope: z.union([z.literal('global'), z.literal('project'), z.literal('metadata')]),
112
+ path: z.string().min(1),
113
+ schema: z.unknown().optional(),
114
+ mergePrecedence: z.number().int().nonnegative(),
115
+ driftDetection: z.union([
116
+ z.literal('schema-validate'),
117
+ z.literal('staleness-gate'),
118
+ z.literal('value-diff'),
119
+ z.literal('none'),
120
+ ]),
121
+ defaults: z.record(z.string(), z.unknown()).optional(),
122
+ });
123
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/config/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAmB,CAAC,EAAE,MAAM,KAAK,CAAC;AAyFzC,8EAA8E;AAC9E,qDAAqD;AACrD,8EAA8E;AAE9E;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAwB;IACxD,EAAE,EAAE,cAAc;IAClB,KAAK,EAAE,UAAU;IACjB,IAAI,EAAE,yBAAyB;IAC/B,eAAe,EAAE,CAAC;IAClB,cAAc,EAAE,iBAAiB;CAClC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAwB;IAC3D,EAAE,EAAE,iBAAiB;IACrB,KAAK,EAAE,UAAU;IACjB,IAAI,EAAE,4BAA4B;IAClC,eAAe,EAAE,CAAC;IAClB,cAAc,EAAE,gBAAgB;CACjC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAwB;IACvD,EAAE,EAAE,qBAAqB;IACzB,KAAK,EAAE,SAAS;IAChB,IAAI,EAAE,mBAAmB;IACzB,eAAe,EAAE,EAAE;IACnB,cAAc,EAAE,iBAAiB;CAClC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAwB;IAC9D,EAAE,EAAE,oBAAoB;IACxB,KAAK,EAAE,QAAQ;IACf,IAAI,EAAE,qBAAqB;IAC3B,eAAe,EAAE,EAAE;IACnB,cAAc,EAAE,iBAAiB;CAClC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAmC,MAAM,CAAC,MAAM,CAAC;IACnF,qBAAqB;IACrB,wBAAwB;IACxB,2BAA2B;IAC3B,oBAAoB;CACrB,CAAC,CAAC;AAEH,8EAA8E;AAC9E,4BAA4B;AAC5B,8EAA8E;AAE9E;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACrB,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IAClF,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC9B,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IAC/C,cAAc,EAAE,CAAC,CAAC,KAAK,CAAC;QACtB,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC;QAC5B,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC;QAC3B,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC;QACvB,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;KAClB,CAAC;IACF,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE;CACvD,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Unit + snapshot tests for the Docs Provenance Graph contract (T10166).
3
+ *
4
+ * Coverage:
5
+ * - Round-trip Zod parse for each node variant + edge variant + envelope.
6
+ * - Discriminator rejection for unknown `kind` / `relation` / lifecycle values.
7
+ * - Type-guard narrowing for all five node variants.
8
+ * - Snapshot test for a typical-sized graph (5 docs, 8 tasks, 4 decisions,
9
+ * 2 sessions) — locks the wire shape consumed by the renderer.
10
+ *
11
+ * @task T10166
12
+ */
13
+ export {};
14
+ //# sourceMappingURL=provenance.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provenance.test.d.ts","sourceRoot":"","sources":["../../../src/docs/__tests__/provenance.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}