@manehorizons/cadence-core 1.5.1 → 1.6.1
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.
- package/dist/cli/commands/assumption.d.ts.map +1 -1
- package/dist/cli/commands/assumption.js +2 -1
- package/dist/cli/commands/assumption.js.map +1 -1
- package/dist/cli/commands/decision.d.ts.map +1 -1
- package/dist/cli/commands/decision.js +2 -1
- package/dist/cli/commands/decision.js.map +1 -1
- package/dist/cli/commands/draft-new.d.ts.map +1 -1
- package/dist/cli/commands/draft-new.js +2 -1
- package/dist/cli/commands/draft-new.js.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +15 -7
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/intelligence.d.ts.map +1 -1
- package/dist/cli/commands/intelligence.js +4 -1
- package/dist/cli/commands/intelligence.js.map +1 -1
- package/dist/cli/commands/milestone.js +1 -1
- package/dist/cli/commands/milestone.js.map +1 -1
- package/dist/cli/commands/recommendation.d.ts.map +1 -1
- package/dist/cli/commands/recommendation.js +2 -1
- package/dist/cli/commands/recommendation.js.map +1 -1
- package/dist/cli/commands/spec.d.ts.map +1 -1
- package/dist/cli/commands/spec.js +2 -1
- package/dist/cli/commands/spec.js.map +1 -1
- package/dist/intelligence/context.js +2 -1
- package/dist/intelligence/context.js.map +1 -1
- package/dist/intelligence/inspect.js +2 -1
- package/dist/intelligence/inspect.js.map +1 -1
- package/dist/intelligence/milestone.d.ts.map +1 -1
- package/dist/intelligence/milestone.js +2 -1
- package/dist/intelligence/milestone.js.map +1 -1
- package/dist/intelligence/recommend.d.ts.map +1 -1
- package/dist/intelligence/recommend.js +2 -1
- package/dist/intelligence/recommend.js.map +1 -1
- package/dist/intelligence/render-intelligence-audit.d.ts +1 -1
- package/dist/intelligence/render-intelligence-audit.d.ts.map +1 -1
- package/dist/intelligence/render-intelligence-stats.d.ts +1 -1
- package/dist/intelligence/render-intelligence-stats.d.ts.map +1 -1
- package/dist/intelligence/store/assumptions.d.ts +17 -0
- package/dist/intelligence/store/assumptions.d.ts.map +1 -0
- package/dist/intelligence/store/assumptions.js +63 -0
- package/dist/intelligence/store/assumptions.js.map +1 -0
- package/dist/intelligence/store/audit.d.ts +42 -0
- package/dist/intelligence/store/audit.d.ts.map +1 -0
- package/dist/intelligence/store/audit.js +88 -0
- package/dist/intelligence/store/audit.js.map +1 -0
- package/dist/intelligence/store/decisions.d.ts +19 -0
- package/dist/intelligence/store/decisions.d.ts.map +1 -0
- package/dist/intelligence/store/decisions.js +147 -0
- package/dist/intelligence/store/decisions.js.map +1 -0
- package/dist/intelligence/store/ids.d.ts +6 -0
- package/dist/intelligence/store/ids.d.ts.map +1 -0
- package/dist/intelligence/store/ids.js +44 -0
- package/dist/intelligence/store/ids.js.map +1 -0
- package/dist/intelligence/store/io.d.ts +10 -0
- package/dist/intelligence/store/io.d.ts.map +1 -0
- package/dist/intelligence/store/io.js +70 -0
- package/dist/intelligence/store/io.js.map +1 -0
- package/dist/intelligence/store/milestones.d.ts +4 -0
- package/dist/intelligence/store/milestones.d.ts.map +1 -0
- package/dist/intelligence/store/milestones.js +20 -0
- package/dist/intelligence/store/milestones.js.map +1 -0
- package/dist/intelligence/store/paths.d.ts +11 -0
- package/dist/intelligence/store/paths.d.ts.map +1 -0
- package/dist/intelligence/store/paths.js +42 -0
- package/dist/intelligence/store/paths.js.map +1 -0
- package/dist/intelligence/store/recommendations.d.ts +23 -0
- package/dist/intelligence/store/recommendations.d.ts.map +1 -0
- package/dist/intelligence/store/recommendations.js +115 -0
- package/dist/intelligence/store/recommendations.js.map +1 -0
- package/dist/intelligence/store/reconcile.d.ts +8 -0
- package/dist/intelligence/store/reconcile.d.ts.map +1 -0
- package/dist/intelligence/store/reconcile.js +42 -0
- package/dist/intelligence/store/reconcile.js.map +1 -0
- package/dist/intelligence/store/stats.d.ts +36 -0
- package/dist/intelligence/store/stats.d.ts.map +1 -0
- package/dist/intelligence/store/stats.js +106 -0
- package/dist/intelligence/store/stats.js.map +1 -0
- package/package.json +2 -2
- package/dist/intelligence/store.d.ts +0 -143
- package/dist/intelligence/store.d.ts.map +0 -1
- package/dist/intelligence/store.js +0 -701
- package/dist/intelligence/store.js.map +0 -1
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { nextIntelligenceDecisionId } from './ids.js';
|
|
2
|
+
import { readAssumptionLedger, readEvidenceLedger, readIntelligenceDecisionLedger, readRecommendationLedger, rerenderRecommendationsMdIfPresent, writeIntelligenceDecisionLedger, writeIntelligenceLedgers, } from './io.js';
|
|
3
|
+
import { deriveRecommendationLinks } from './recommendations.js';
|
|
4
|
+
export async function addIntelligenceDecision(root, input) {
|
|
5
|
+
let recLedger = null;
|
|
6
|
+
if (input.recommendationId !== undefined) {
|
|
7
|
+
recLedger = await readRecommendationLedger(root);
|
|
8
|
+
if (!recLedger.recommendations.some((r) => r.id === input.recommendationId)) {
|
|
9
|
+
throw new Error(`unknown recommendation "${input.recommendationId}"`);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
const decLedger = await readIntelligenceDecisionLedger(root);
|
|
13
|
+
const now = new Date();
|
|
14
|
+
// Construct in schema-declaration order so the persisted JSON property
|
|
15
|
+
// order matches what `IntelligenceDecisionLedgerZ.parse(...)` would produce
|
|
16
|
+
// on reconcile. Keeps byte-equality between addIntelligenceDecision writes
|
|
17
|
+
// and reconcile writes (relied on by Slice-17 AC-6).
|
|
18
|
+
const out = {
|
|
19
|
+
id: nextIntelligenceDecisionId(decLedger, now),
|
|
20
|
+
...(input.recommendationId !== undefined ? { recommendationId: input.recommendationId } : {}),
|
|
21
|
+
title: input.title,
|
|
22
|
+
rationale: input.rationale,
|
|
23
|
+
status: 'active',
|
|
24
|
+
decidedAt: now.toISOString(),
|
|
25
|
+
supersedes: [],
|
|
26
|
+
};
|
|
27
|
+
decLedger.decisions.push(out);
|
|
28
|
+
// Slice 31: re-derive supersedes arrays across the whole ledger. New
|
|
29
|
+
// decisions can't be referenced by older ones yet, but pre-Slice-31
|
|
30
|
+
// ledgers being loaded for the first time benefit from the field
|
|
31
|
+
// being populated explicitly on write.
|
|
32
|
+
const derivedDec = deriveDecisionInverseLinks(decLedger);
|
|
33
|
+
await writeIntelligenceDecisionLedger(root, derivedDec);
|
|
34
|
+
if (input.recommendationId !== undefined && recLedger !== null) {
|
|
35
|
+
const asLedger = await readAssumptionLedger(root);
|
|
36
|
+
const evLedger = await readEvidenceLedger(root);
|
|
37
|
+
const derivedRec = deriveRecommendationLinks(recLedger, asLedger, decLedger);
|
|
38
|
+
await writeIntelligenceLedgers(root, derivedRec, evLedger);
|
|
39
|
+
}
|
|
40
|
+
return out;
|
|
41
|
+
}
|
|
42
|
+
const DECISION_TRANSITION_ALLOWED = {
|
|
43
|
+
supersede: ['active'],
|
|
44
|
+
rescind: ['active'],
|
|
45
|
+
reactivate: ['superseded', 'rescinded'],
|
|
46
|
+
};
|
|
47
|
+
const DECISION_TRANSITION_NEXT = {
|
|
48
|
+
supersede: 'superseded',
|
|
49
|
+
rescind: 'rescinded',
|
|
50
|
+
reactivate: 'active',
|
|
51
|
+
};
|
|
52
|
+
function walkSupersededByChain(ledger, startId, forbid) {
|
|
53
|
+
const chain = [];
|
|
54
|
+
const seen = new Set();
|
|
55
|
+
let cursor = startId;
|
|
56
|
+
while (cursor) {
|
|
57
|
+
if (cursor === forbid)
|
|
58
|
+
return { ok: false, chain };
|
|
59
|
+
if (seen.has(cursor))
|
|
60
|
+
return { ok: true, chain };
|
|
61
|
+
seen.add(cursor);
|
|
62
|
+
chain.push(cursor);
|
|
63
|
+
const node = ledger.decisions.find((d) => d.id === cursor);
|
|
64
|
+
cursor = node?.supersededBy;
|
|
65
|
+
}
|
|
66
|
+
return { ok: true, chain };
|
|
67
|
+
}
|
|
68
|
+
// Slice 31: pure helper. For every decision D in the ledger, recompute
|
|
69
|
+
// D.supersedes from current supersededBy values — the inverse-link of
|
|
70
|
+
// Slice 28's edge. Mirrors Slice 11's deriveRecommendationLinks shape
|
|
71
|
+
// but operates within one ledger. Idempotent.
|
|
72
|
+
export function deriveDecisionInverseLinks(ledger) {
|
|
73
|
+
return {
|
|
74
|
+
schemaVersion: 1,
|
|
75
|
+
decisions: ledger.decisions.map((d) => ({
|
|
76
|
+
...d,
|
|
77
|
+
supersedes: ledger.decisions
|
|
78
|
+
.filter((other) => other.supersededBy === d.id)
|
|
79
|
+
.map((other) => other.id),
|
|
80
|
+
})),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
export function applyDecisionTransition(ledger, id, action, by, _now) {
|
|
84
|
+
const target = ledger.decisions.find((d) => d.id === id);
|
|
85
|
+
if (!target)
|
|
86
|
+
return { ok: false, error: `decision ${id} not found` };
|
|
87
|
+
if (!DECISION_TRANSITION_ALLOWED[action].includes(target.status)) {
|
|
88
|
+
return {
|
|
89
|
+
ok: false,
|
|
90
|
+
error: `cannot ${action} decision in status ${target.status}`,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
if (action === 'supersede' && by !== undefined) {
|
|
94
|
+
if (by === id) {
|
|
95
|
+
return {
|
|
96
|
+
ok: false,
|
|
97
|
+
error: 'cannot supersede: decision cannot supersede itself',
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
const replacement = ledger.decisions.find((d) => d.id === by);
|
|
101
|
+
if (!replacement) {
|
|
102
|
+
return {
|
|
103
|
+
ok: false,
|
|
104
|
+
error: `cannot supersede: decision ${by} not found`,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
const walk = walkSupersededByChain(ledger, by, id);
|
|
108
|
+
if (!walk.ok) {
|
|
109
|
+
return {
|
|
110
|
+
ok: false,
|
|
111
|
+
error: `cannot supersede: would create cycle (${[...walk.chain, id].join(' → ')})`,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
const nextStatus = DECISION_TRANSITION_NEXT[action];
|
|
116
|
+
const ledgerOut = {
|
|
117
|
+
schemaVersion: 1,
|
|
118
|
+
decisions: ledger.decisions.map((d) => {
|
|
119
|
+
if (d.id !== id)
|
|
120
|
+
return d;
|
|
121
|
+
const updated = { ...d, status: nextStatus };
|
|
122
|
+
if (action === 'supersede') {
|
|
123
|
+
if (by !== undefined)
|
|
124
|
+
updated.supersededBy = by;
|
|
125
|
+
}
|
|
126
|
+
else if (action === 'reactivate') {
|
|
127
|
+
delete updated.supersededBy;
|
|
128
|
+
}
|
|
129
|
+
return updated;
|
|
130
|
+
}),
|
|
131
|
+
};
|
|
132
|
+
// Slice 31: re-derive supersedes arrays so the returned ledger is fully
|
|
133
|
+
// consistent (target's supersededBy update propagates to the replacement's
|
|
134
|
+
// supersedes array, and reactivate-cleared targets drop out).
|
|
135
|
+
return { ok: true, ledger: deriveDecisionInverseLinks(ledgerOut) };
|
|
136
|
+
}
|
|
137
|
+
export async function runDecisionTransition(root, id, action, by) {
|
|
138
|
+
const ledger = await readIntelligenceDecisionLedger(root);
|
|
139
|
+
const res = applyDecisionTransition(ledger, id, action, by, new Date());
|
|
140
|
+
if (!res.ok)
|
|
141
|
+
return res;
|
|
142
|
+
await writeIntelligenceDecisionLedger(root, res.ledger);
|
|
143
|
+
// Slice 15: propagate status change into RECOMMENDATIONS.md annotated bullets.
|
|
144
|
+
await rerenderRecommendationsMdIfPresent(root);
|
|
145
|
+
return res;
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=decisions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decisions.js","sourceRoot":"","sources":["../../../src/intelligence/store/decisions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { AssumptionLedger, EvidenceLedger, IntelligenceDecisionLedger, RecommendationLedger } from '@manehorizons/cadence-types';
|
|
2
|
+
export declare function nextRecommendationId(ledger: RecommendationLedger, now: Date): string;
|
|
3
|
+
export declare function nextEvidenceId(ledger: EvidenceLedger, now: Date): string;
|
|
4
|
+
export declare function nextAssumptionId(ledger: AssumptionLedger, now: Date): string;
|
|
5
|
+
export declare function nextIntelligenceDecisionId(ledger: IntelligenceDecisionLedger, now: Date): string;
|
|
6
|
+
//# sourceMappingURL=ids.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../../../src/intelligence/store/ids.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACd,0BAA0B,EAC1B,oBAAoB,EACrB,MAAM,6BAA6B,CAAC;AAMrC,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,oBAAoB,EAAE,GAAG,EAAE,IAAI,GAAG,MAAM,CASpF;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,IAAI,GAAG,MAAM,CASxE;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,EAAE,GAAG,EAAE,IAAI,GAAG,MAAM,CAS5E;AAED,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,0BAA0B,EAClC,GAAG,EAAE,IAAI,GACR,MAAM,CASR"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
function slugDate(now) {
|
|
2
|
+
return now.toISOString().slice(0, 10).replaceAll('-', '');
|
|
3
|
+
}
|
|
4
|
+
export function nextRecommendationId(ledger, now) {
|
|
5
|
+
const prefix = `rec-${slugDate(now)}-`;
|
|
6
|
+
const max = ledger.recommendations
|
|
7
|
+
.map((r) => r.id)
|
|
8
|
+
.filter((id) => id.startsWith(prefix))
|
|
9
|
+
.map((id) => Number.parseInt(id.slice(prefix.length), 10))
|
|
10
|
+
.filter((n) => Number.isFinite(n))
|
|
11
|
+
.reduce((a, b) => Math.max(a, b), 0);
|
|
12
|
+
return `${prefix}${String(max + 1).padStart(3, '0')}`;
|
|
13
|
+
}
|
|
14
|
+
export function nextEvidenceId(ledger, now) {
|
|
15
|
+
const prefix = `ev-${slugDate(now)}-`;
|
|
16
|
+
const max = ledger.evidence
|
|
17
|
+
.map((ev) => ev.id)
|
|
18
|
+
.filter((id) => id.startsWith(prefix))
|
|
19
|
+
.map((id) => Number.parseInt(id.slice(prefix.length), 10))
|
|
20
|
+
.filter((n) => Number.isFinite(n))
|
|
21
|
+
.reduce((a, b) => Math.max(a, b), 0);
|
|
22
|
+
return `${prefix}${String(max + 1).padStart(3, '0')}`;
|
|
23
|
+
}
|
|
24
|
+
export function nextAssumptionId(ledger, now) {
|
|
25
|
+
const prefix = `as-${slugDate(now)}-`;
|
|
26
|
+
const max = ledger.assumptions
|
|
27
|
+
.map((a) => a.id)
|
|
28
|
+
.filter((id) => id.startsWith(prefix))
|
|
29
|
+
.map((id) => Number.parseInt(id.slice(prefix.length), 10))
|
|
30
|
+
.filter((n) => Number.isFinite(n))
|
|
31
|
+
.reduce((a, b) => Math.max(a, b), 0);
|
|
32
|
+
return `${prefix}${String(max + 1).padStart(3, '0')}`;
|
|
33
|
+
}
|
|
34
|
+
export function nextIntelligenceDecisionId(ledger, now) {
|
|
35
|
+
const prefix = `dec-${slugDate(now)}-`;
|
|
36
|
+
const max = ledger.decisions
|
|
37
|
+
.map((d) => d.id)
|
|
38
|
+
.filter((id) => id.startsWith(prefix))
|
|
39
|
+
.map((id) => Number.parseInt(id.slice(prefix.length), 10))
|
|
40
|
+
.filter((n) => Number.isFinite(n))
|
|
41
|
+
.reduce((a, b) => Math.max(a, b), 0);
|
|
42
|
+
return `${prefix}${String(max + 1).padStart(3, '0')}`;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=ids.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ids.js","sourceRoot":"","sources":["../../../src/intelligence/store/ids.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type AssumptionLedger, type EvidenceLedger, type IntelligenceDecisionLedger, type RecommendationLedger } from '@manehorizons/cadence-types';
|
|
2
|
+
export declare function readRecommendationLedger(root: string): Promise<RecommendationLedger>;
|
|
3
|
+
export declare function readEvidenceLedger(root: string): Promise<EvidenceLedger>;
|
|
4
|
+
export declare function readAssumptionLedger(root: string): Promise<AssumptionLedger>;
|
|
5
|
+
export declare function readIntelligenceDecisionLedger(root: string): Promise<IntelligenceDecisionLedger>;
|
|
6
|
+
export declare function writeIntelligenceLedgers(root: string, ledger: RecommendationLedger, evidenceLedger: EvidenceLedger): Promise<void>;
|
|
7
|
+
export declare function writeAssumptionLedger(root: string, ledger: AssumptionLedger): Promise<void>;
|
|
8
|
+
export declare function writeIntelligenceDecisionLedger(root: string, ledger: IntelligenceDecisionLedger): Promise<void>;
|
|
9
|
+
export declare function rerenderRecommendationsMdIfPresent(root: string): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=io.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../../../src/intelligence/store/io.ts"],"names":[],"mappings":"AAEA,OAAO,EASL,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,0BAA0B,EAC/B,KAAK,oBAAoB,EAC1B,MAAM,6BAA6B,CAAC;AAgBrC,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAK1F;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAK9E;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAKlF;AAED,wBAAsB,8BAA8B,CAClD,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,0BAA0B,CAAC,CAKrC;AAED,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,oBAAoB,EAC5B,cAAc,EAAE,cAAc,GAC7B,OAAO,CAAC,IAAI,CAAC,CAcf;AAED,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAKjG;AAED,wBAAsB,+BAA+B,CACnD,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,0BAA0B,GACjC,OAAO,CAAC,IAAI,CAAC,CAKf;AAED,wBAAsB,kCAAkC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUpF"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { mkdir, readFile } from 'node:fs/promises';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { AssumptionLedgerZ, EvidenceLedgerZ, IntelligenceDecisionLedgerZ, RecommendationLedgerZ, emptyAssumptionLedger, emptyEvidenceLedger, emptyIntelligenceDecisionLedger, emptyRecommendationLedger, } from '@manehorizons/cadence-types';
|
|
4
|
+
import { atomicWriteJSON, atomicWriteText } from '../../state/atomic-write.js';
|
|
5
|
+
import { renderRecommendationsMd } from '../render.js';
|
|
6
|
+
import { renderAssumptionsMd } from '../render-assumption.js';
|
|
7
|
+
import { renderDecisionsMd } from '../render-decision.js';
|
|
8
|
+
import { assumptionsMdPath, assumptionsPath, decisionsMdPath, decisionsPath, evidencePath, intelligenceDir, recommendationsMdPath, recommendationsPath, } from './paths.js';
|
|
9
|
+
export async function readRecommendationLedger(root) {
|
|
10
|
+
const path = recommendationsPath(root);
|
|
11
|
+
if (!existsSync(path))
|
|
12
|
+
return emptyRecommendationLedger();
|
|
13
|
+
const raw = await readFile(path, 'utf8');
|
|
14
|
+
return RecommendationLedgerZ.parse(JSON.parse(raw));
|
|
15
|
+
}
|
|
16
|
+
export async function readEvidenceLedger(root) {
|
|
17
|
+
const path = evidencePath(root);
|
|
18
|
+
if (!existsSync(path))
|
|
19
|
+
return emptyEvidenceLedger();
|
|
20
|
+
const raw = await readFile(path, 'utf8');
|
|
21
|
+
return EvidenceLedgerZ.parse(JSON.parse(raw));
|
|
22
|
+
}
|
|
23
|
+
export async function readAssumptionLedger(root) {
|
|
24
|
+
const path = assumptionsPath(root);
|
|
25
|
+
if (!existsSync(path))
|
|
26
|
+
return emptyAssumptionLedger();
|
|
27
|
+
const raw = await readFile(path, 'utf8');
|
|
28
|
+
return AssumptionLedgerZ.parse(JSON.parse(raw));
|
|
29
|
+
}
|
|
30
|
+
export async function readIntelligenceDecisionLedger(root) {
|
|
31
|
+
const path = decisionsPath(root);
|
|
32
|
+
if (!existsSync(path))
|
|
33
|
+
return emptyIntelligenceDecisionLedger();
|
|
34
|
+
const raw = await readFile(path, 'utf8');
|
|
35
|
+
return IntelligenceDecisionLedgerZ.parse(JSON.parse(raw));
|
|
36
|
+
}
|
|
37
|
+
export async function writeIntelligenceLedgers(root, ledger, evidenceLedger) {
|
|
38
|
+
const dir = intelligenceDir(root);
|
|
39
|
+
await mkdir(dir, { recursive: true });
|
|
40
|
+
RecommendationLedgerZ.parse(ledger);
|
|
41
|
+
EvidenceLedgerZ.parse(evidenceLedger);
|
|
42
|
+
await atomicWriteJSON(recommendationsPath(root), ledger);
|
|
43
|
+
await atomicWriteJSON(evidencePath(root), evidenceLedger);
|
|
44
|
+
// Read sibling ledgers so the rec MD renders status-annotated link bullets (Slice 15).
|
|
45
|
+
const asLedger = await readAssumptionLedger(root);
|
|
46
|
+
const decLedger = await readIntelligenceDecisionLedger(root);
|
|
47
|
+
await atomicWriteText(recommendationsMdPath(root), renderRecommendationsMd(ledger, evidenceLedger, asLedger, decLedger));
|
|
48
|
+
}
|
|
49
|
+
export async function writeAssumptionLedger(root, ledger) {
|
|
50
|
+
AssumptionLedgerZ.parse(ledger);
|
|
51
|
+
await mkdir(intelligenceDir(root), { recursive: true });
|
|
52
|
+
await atomicWriteJSON(assumptionsPath(root), ledger);
|
|
53
|
+
await atomicWriteText(assumptionsMdPath(root), renderAssumptionsMd(ledger));
|
|
54
|
+
}
|
|
55
|
+
export async function writeIntelligenceDecisionLedger(root, ledger) {
|
|
56
|
+
IntelligenceDecisionLedgerZ.parse(ledger);
|
|
57
|
+
await mkdir(intelligenceDir(root), { recursive: true });
|
|
58
|
+
await atomicWriteJSON(decisionsPath(root), ledger);
|
|
59
|
+
await atomicWriteText(decisionsMdPath(root), renderDecisionsMd(ledger));
|
|
60
|
+
}
|
|
61
|
+
export async function rerenderRecommendationsMdIfPresent(root) {
|
|
62
|
+
if (!existsSync(recommendationsPath(root)))
|
|
63
|
+
return;
|
|
64
|
+
const recLedger = await readRecommendationLedger(root);
|
|
65
|
+
const evLedger = await readEvidenceLedger(root);
|
|
66
|
+
const asLedger = await readAssumptionLedger(root);
|
|
67
|
+
const decLedger = await readIntelligenceDecisionLedger(root);
|
|
68
|
+
await atomicWriteText(recommendationsMdPath(root), renderRecommendationsMd(recLedger, evLedger, asLedger, decLedger));
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=io.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"io.js","sourceRoot":"","sources":["../../../src/intelligence/store/io.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type MilestoneLedger } from '@manehorizons/cadence-types';
|
|
2
|
+
export declare function readMilestoneLedger(root: string): Promise<MilestoneLedger>;
|
|
3
|
+
export declare function writeMilestoneLedger(root: string, ledger: MilestoneLedger): Promise<void>;
|
|
4
|
+
//# sourceMappingURL=milestones.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"milestones.d.ts","sourceRoot":"","sources":["../../../src/intelligence/store/milestones.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,6BAA6B,CAAC;AAKrC,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,eAAe,CAAC,CAK1B;AAED,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC,IAAI,CAAC,CAKf"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { mkdir, readFile } from 'node:fs/promises';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { MilestoneLedgerZ, emptyMilestoneLedger, } from '@manehorizons/cadence-types';
|
|
4
|
+
import { atomicWriteJSON, atomicWriteText } from '../../state/atomic-write.js';
|
|
5
|
+
import { renderMilestonesMd } from '../render-milestone.js';
|
|
6
|
+
import { intelligenceDir, milestonesMdPath, milestonesPath } from './paths.js';
|
|
7
|
+
export async function readMilestoneLedger(root) {
|
|
8
|
+
const path = milestonesPath(root);
|
|
9
|
+
if (!existsSync(path))
|
|
10
|
+
return emptyMilestoneLedger();
|
|
11
|
+
const raw = await readFile(path, 'utf8');
|
|
12
|
+
return MilestoneLedgerZ.parse(JSON.parse(raw));
|
|
13
|
+
}
|
|
14
|
+
export async function writeMilestoneLedger(root, ledger) {
|
|
15
|
+
await mkdir(intelligenceDir(root), { recursive: true });
|
|
16
|
+
MilestoneLedgerZ.parse(ledger);
|
|
17
|
+
await atomicWriteJSON(milestonesPath(root), ledger);
|
|
18
|
+
await atomicWriteText(milestonesMdPath(root), renderMilestonesMd(ledger));
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=milestones.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"milestones.js","sourceRoot":"","sources":["../../../src/intelligence/store/milestones.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EACL,gBAAgB,EAChB,oBAAoB,GAErB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE/E,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,IAAY;IAEZ,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,oBAAoB,EAAE,CAAC;IACrD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACzC,OAAO,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,IAAY,EACZ,MAAuB;IAEvB,MAAM,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACxD,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC/B,MAAM,eAAe,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;IACpD,MAAM,eAAe,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;AAC5E,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare function intelligenceDir(root: string): string;
|
|
2
|
+
export declare function recommendationsPath(root: string): string;
|
|
3
|
+
export declare function evidencePath(root: string): string;
|
|
4
|
+
export declare function assumptionsPath(root: string): string;
|
|
5
|
+
export declare function decisionsPath(root: string): string;
|
|
6
|
+
export declare function recommendationsMdPath(root: string): string;
|
|
7
|
+
export declare function assumptionsMdPath(root: string): string;
|
|
8
|
+
export declare function decisionsMdPath(root: string): string;
|
|
9
|
+
export declare function milestonesPath(root: string): string;
|
|
10
|
+
export declare function milestonesMdPath(root: string): string;
|
|
11
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/intelligence/store/paths.ts"],"names":[],"mappings":"AAaA,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErD"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
const INTELLIGENCE_DIR = '.cadence/intelligence';
|
|
3
|
+
const RECOMMENDATIONS_JSON = 'recommendations.json';
|
|
4
|
+
const EVIDENCE_JSON = 'evidence.json';
|
|
5
|
+
const RECOMMENDATIONS_MD = 'RECOMMENDATIONS.md';
|
|
6
|
+
const ASSUMPTIONS_JSON = 'assumptions.json';
|
|
7
|
+
const DECISIONS_JSON = 'decisions.json';
|
|
8
|
+
const ASSUMPTIONS_MD = 'ASSUMPTIONS.md';
|
|
9
|
+
const DECISIONS_MD = 'DECISIONS.md';
|
|
10
|
+
const MILESTONES_JSON = 'milestones.json';
|
|
11
|
+
const MILESTONES_MD = 'MILESTONES.md';
|
|
12
|
+
export function intelligenceDir(root) {
|
|
13
|
+
return join(root, INTELLIGENCE_DIR);
|
|
14
|
+
}
|
|
15
|
+
export function recommendationsPath(root) {
|
|
16
|
+
return join(intelligenceDir(root), RECOMMENDATIONS_JSON);
|
|
17
|
+
}
|
|
18
|
+
export function evidencePath(root) {
|
|
19
|
+
return join(intelligenceDir(root), EVIDENCE_JSON);
|
|
20
|
+
}
|
|
21
|
+
export function assumptionsPath(root) {
|
|
22
|
+
return join(intelligenceDir(root), ASSUMPTIONS_JSON);
|
|
23
|
+
}
|
|
24
|
+
export function decisionsPath(root) {
|
|
25
|
+
return join(intelligenceDir(root), DECISIONS_JSON);
|
|
26
|
+
}
|
|
27
|
+
export function recommendationsMdPath(root) {
|
|
28
|
+
return join(intelligenceDir(root), RECOMMENDATIONS_MD);
|
|
29
|
+
}
|
|
30
|
+
export function assumptionsMdPath(root) {
|
|
31
|
+
return join(intelligenceDir(root), ASSUMPTIONS_MD);
|
|
32
|
+
}
|
|
33
|
+
export function decisionsMdPath(root) {
|
|
34
|
+
return join(intelligenceDir(root), DECISIONS_MD);
|
|
35
|
+
}
|
|
36
|
+
export function milestonesPath(root) {
|
|
37
|
+
return join(intelligenceDir(root), MILESTONES_JSON);
|
|
38
|
+
}
|
|
39
|
+
export function milestonesMdPath(root) {
|
|
40
|
+
return join(intelligenceDir(root), MILESTONES_MD);
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/intelligence/store/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,gBAAgB,GAAG,uBAAuB,CAAC;AACjD,MAAM,oBAAoB,GAAG,sBAAsB,CAAC;AACpD,MAAM,aAAa,GAAG,eAAe,CAAC;AACtC,MAAM,kBAAkB,GAAG,oBAAoB,CAAC;AAChD,MAAM,gBAAgB,GAAG,kBAAkB,CAAC;AAC5C,MAAM,cAAc,GAAG,gBAAgB,CAAC;AACxC,MAAM,cAAc,GAAG,gBAAgB,CAAC;AACxC,MAAM,YAAY,GAAG,cAAc,CAAC;AACpC,MAAM,eAAe,GAAG,iBAAiB,CAAC;AAC1C,MAAM,aAAa,GAAG,eAAe,CAAC;AAEtC,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,oBAAoB,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,gBAAgB,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,cAAc,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,kBAAkB,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,cAAc,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,eAAe,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC,CAAC;AACpD,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type AssumptionLedger, type IntelligenceDecisionLedger, type Recommendation, type RecommendationLedger, type RecommendationPriority, type RecommendationReadiness } from '@manehorizons/cadence-types';
|
|
2
|
+
export type AddRecommendationInput = {
|
|
3
|
+
title: string;
|
|
4
|
+
summary: string;
|
|
5
|
+
priority: RecommendationPriority;
|
|
6
|
+
readiness: RecommendationReadiness;
|
|
7
|
+
affectedAreas: string[];
|
|
8
|
+
affectedFiles: string[];
|
|
9
|
+
evidenceSummary?: string;
|
|
10
|
+
};
|
|
11
|
+
export declare function addRecommendation(root: string, input: AddRecommendationInput): Promise<Recommendation>;
|
|
12
|
+
export declare function deriveRecommendationLinks(recLedger: RecommendationLedger, asLedger: AssumptionLedger, decLedger: IntelligenceDecisionLedger): RecommendationLedger;
|
|
13
|
+
export type RecommendationTransitionAction = 'convert';
|
|
14
|
+
export type RecommendationTransitionResult = {
|
|
15
|
+
ok: true;
|
|
16
|
+
ledger: RecommendationLedger;
|
|
17
|
+
} | {
|
|
18
|
+
ok: false;
|
|
19
|
+
error: string;
|
|
20
|
+
};
|
|
21
|
+
export declare function applyRecommendationTransition(ledger: RecommendationLedger, id: string, action: RecommendationTransitionAction, toPhase: string, now: Date): RecommendationTransitionResult;
|
|
22
|
+
export declare function runRecommendationTransition(root: string, id: string, action: RecommendationTransitionAction, toPhase: string): Promise<RecommendationTransitionResult>;
|
|
23
|
+
//# sourceMappingURL=recommendations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recommendations.d.ts","sourceRoot":"","sources":["../../../src/intelligence/store/recommendations.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,gBAAgB,EAErB,KAAK,0BAA0B,EAC/B,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,EAC7B,MAAM,6BAA6B,CAAC;AAQrC,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,sBAAsB,CAAC;IACjC,SAAS,EAAE,uBAAuB,CAAC;IACnC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,sBAAsB,GAC5B,OAAO,CAAC,cAAc,CAAC,CAwCzB;AAED,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,oBAAoB,EAC/B,QAAQ,EAAE,gBAAgB,EAC1B,SAAS,EAAE,0BAA0B,GACpC,oBAAoB,CAatB;AAKD,MAAM,MAAM,8BAA8B,GAAG,SAAS,CAAC;AAEvD,MAAM,MAAM,8BAA8B,GACtC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,oBAAoB,CAAA;CAAE,GAC1C;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAgBjC,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,oBAAoB,EAC5B,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,8BAA8B,EACtC,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,IAAI,GACR,8BAA8B,CAoBhC;AAcD,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,8BAA8B,EACtC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,8BAA8B,CAAC,CAczC"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { stat } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { nextEvidenceId, nextRecommendationId } from './ids.js';
|
|
4
|
+
import { readEvidenceLedger, readRecommendationLedger, writeIntelligenceLedgers, } from './io.js';
|
|
5
|
+
export async function addRecommendation(root, input) {
|
|
6
|
+
const ledger = await readRecommendationLedger(root);
|
|
7
|
+
const evidenceLedger = await readEvidenceLedger(root);
|
|
8
|
+
const now = new Date();
|
|
9
|
+
const ts = now.toISOString();
|
|
10
|
+
const recommendationId = nextRecommendationId(ledger, now);
|
|
11
|
+
const evidence = input.evidenceSummary
|
|
12
|
+
? {
|
|
13
|
+
id: nextEvidenceId(evidenceLedger, now),
|
|
14
|
+
recommendationId,
|
|
15
|
+
kind: 'note',
|
|
16
|
+
summary: input.evidenceSummary,
|
|
17
|
+
createdAt: ts,
|
|
18
|
+
}
|
|
19
|
+
: null;
|
|
20
|
+
const rec = {
|
|
21
|
+
id: recommendationId,
|
|
22
|
+
title: input.title,
|
|
23
|
+
summary: input.summary,
|
|
24
|
+
source: 'manual',
|
|
25
|
+
status: 'candidate',
|
|
26
|
+
readiness: input.readiness,
|
|
27
|
+
priority: input.priority,
|
|
28
|
+
leverageScore: 5,
|
|
29
|
+
riskScore: 5,
|
|
30
|
+
confidence: input.evidenceSummary ? 0.7 : 0.4,
|
|
31
|
+
decayState: 'fresh',
|
|
32
|
+
affectedAreas: input.affectedAreas,
|
|
33
|
+
affectedFiles: input.affectedFiles,
|
|
34
|
+
suggestedBackendAction: 'cadence milestone propose',
|
|
35
|
+
evidenceIds: evidence ? [evidence.id] : [],
|
|
36
|
+
assumptionIds: [],
|
|
37
|
+
decisionIds: [],
|
|
38
|
+
createdAt: ts,
|
|
39
|
+
updatedAt: ts,
|
|
40
|
+
};
|
|
41
|
+
if (evidence)
|
|
42
|
+
evidenceLedger.evidence.push(evidence);
|
|
43
|
+
ledger.recommendations.push(rec);
|
|
44
|
+
await writeIntelligenceLedgers(root, ledger, evidenceLedger);
|
|
45
|
+
return rec;
|
|
46
|
+
}
|
|
47
|
+
export function deriveRecommendationLinks(recLedger, asLedger, decLedger) {
|
|
48
|
+
return {
|
|
49
|
+
schemaVersion: 1,
|
|
50
|
+
recommendations: recLedger.recommendations.map((r) => ({
|
|
51
|
+
...r,
|
|
52
|
+
assumptionIds: asLedger.assumptions
|
|
53
|
+
.filter((a) => a.recommendationId === r.id)
|
|
54
|
+
.map((a) => a.id),
|
|
55
|
+
decisionIds: decLedger.decisions
|
|
56
|
+
.filter((d) => d.recommendationId === r.id)
|
|
57
|
+
.map((d) => d.id),
|
|
58
|
+
})),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
const RECOMMENDATION_TRANSITION_ALLOWED = {
|
|
62
|
+
convert: ['candidate', 'accepted'],
|
|
63
|
+
};
|
|
64
|
+
const RECOMMENDATION_TRANSITION_NEXT = {
|
|
65
|
+
convert: 'converted',
|
|
66
|
+
};
|
|
67
|
+
export function applyRecommendationTransition(ledger, id, action, toPhase, now) {
|
|
68
|
+
const target = ledger.recommendations.find((r) => r.id === id);
|
|
69
|
+
if (!target)
|
|
70
|
+
return { ok: false, error: `recommendation ${id} not found` };
|
|
71
|
+
if (!RECOMMENDATION_TRANSITION_ALLOWED[action].includes(target.status)) {
|
|
72
|
+
return {
|
|
73
|
+
ok: false,
|
|
74
|
+
error: `cannot ${action} recommendation in status ${target.status}`,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
const nextStatus = RECOMMENDATION_TRANSITION_NEXT[action];
|
|
78
|
+
const updatedAt = now.toISOString();
|
|
79
|
+
const ledgerOut = {
|
|
80
|
+
schemaVersion: 1,
|
|
81
|
+
recommendations: ledger.recommendations.map((r) => r.id === id
|
|
82
|
+
? { ...r, status: nextStatus, convertedToPhaseId: toPhase, updatedAt }
|
|
83
|
+
: r),
|
|
84
|
+
};
|
|
85
|
+
return { ok: true, ledger: ledgerOut };
|
|
86
|
+
}
|
|
87
|
+
// Slice 34.1: existence check for `.cadence/phases/<phaseId>/` lives in the
|
|
88
|
+
// I/O wrapper deliberately — keeps the pure helper disk-free (per Slice 34
|
|
89
|
+
// Decision Log §10 + §11 architectural principle).
|
|
90
|
+
async function phaseDirectoryExists(root, phaseId) {
|
|
91
|
+
try {
|
|
92
|
+
const s = await stat(join(root, '.cadence/phases', phaseId));
|
|
93
|
+
return s.isDirectory();
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
export async function runRecommendationTransition(root, id, action, toPhase) {
|
|
100
|
+
// FK check FIRST so a missing phase is caught before any ledger read.
|
|
101
|
+
// Mirrors Slice 28's --by precedence: validate FK before applying transition.
|
|
102
|
+
if (!(await phaseDirectoryExists(root, toPhase))) {
|
|
103
|
+
return { ok: false, error: `cannot convert: phase ${toPhase} not found` };
|
|
104
|
+
}
|
|
105
|
+
const ledger = await readRecommendationLedger(root);
|
|
106
|
+
const res = applyRecommendationTransition(ledger, id, action, toPhase, new Date());
|
|
107
|
+
if (!res.ok)
|
|
108
|
+
return res;
|
|
109
|
+
// writeIntelligenceLedgers handles atomic JSON + RECOMMENDATIONS.md re-render
|
|
110
|
+
// (Slice 15 annotated form), so we don't need a separate rerender call.
|
|
111
|
+
const evidenceLedger = await readEvidenceLedger(root);
|
|
112
|
+
await writeIntelligenceLedgers(root, res.ledger, evidenceLedger);
|
|
113
|
+
return res;
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=recommendations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recommendations.js","sourceRoot":"","sources":["../../../src/intelligence/store/recommendations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type IntelligenceReconcileResult = {
|
|
2
|
+
present: boolean;
|
|
3
|
+
recommendations: number;
|
|
4
|
+
assumptions: number;
|
|
5
|
+
decisions: number;
|
|
6
|
+
};
|
|
7
|
+
export declare function runIntelligenceReconcile(root: string): Promise<IntelligenceReconcileResult>;
|
|
8
|
+
//# sourceMappingURL=reconcile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconcile.d.ts","sourceRoot":"","sources":["../../../src/intelligence/store/reconcile.ts"],"names":[],"mappings":"AAyBA,MAAM,MAAM,2BAA2B,GAAG;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,2BAA2B,CAAC,CA+BtC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { mkdir } from 'node:fs/promises';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { atomicWriteText } from '../../state/atomic-write.js';
|
|
4
|
+
import { renderAssumptionsMd } from '../render-assumption.js';
|
|
5
|
+
import { renderDecisionsMd } from '../render-decision.js';
|
|
6
|
+
import { assumptionsMdPath, assumptionsPath, decisionsMdPath, decisionsPath, evidencePath, intelligenceDir, recommendationsPath, } from './paths.js';
|
|
7
|
+
import { readAssumptionLedger, readEvidenceLedger, readIntelligenceDecisionLedger, readRecommendationLedger, writeIntelligenceDecisionLedger, writeIntelligenceLedgers, } from './io.js';
|
|
8
|
+
import { deriveRecommendationLinks } from './recommendations.js';
|
|
9
|
+
import { deriveDecisionInverseLinks } from './decisions.js';
|
|
10
|
+
export async function runIntelligenceReconcile(root) {
|
|
11
|
+
const recExists = existsSync(recommendationsPath(root));
|
|
12
|
+
const evExists = existsSync(evidencePath(root));
|
|
13
|
+
const asExists = existsSync(assumptionsPath(root));
|
|
14
|
+
const decExists = existsSync(decisionsPath(root));
|
|
15
|
+
if (!recExists && !evExists && !asExists && !decExists) {
|
|
16
|
+
return { present: false, recommendations: 0, assumptions: 0, decisions: 0 };
|
|
17
|
+
}
|
|
18
|
+
const recLedger = await readRecommendationLedger(root);
|
|
19
|
+
const evLedger = await readEvidenceLedger(root);
|
|
20
|
+
const asLedger = await readAssumptionLedger(root);
|
|
21
|
+
const decLedger = await readIntelligenceDecisionLedger(root);
|
|
22
|
+
// Re-derive rec link arrays from current subject ledgers (idempotent if already correct).
|
|
23
|
+
const derivedRec = deriveRecommendationLinks(recLedger, asLedger, decLedger);
|
|
24
|
+
// Slice 31: re-derive decision inverse-links (supersedes arrays) from
|
|
25
|
+
// current supersededBy values. Idempotent. Operator's "force re-derive"
|
|
26
|
+
// command fixes any drift introduced by manual JSON edits.
|
|
27
|
+
const derivedDec = deriveDecisionInverseLinks(decLedger);
|
|
28
|
+
// writeIntelligenceLedgers handles atomic JSON + RECOMMENDATIONS.md re-render (Slice 15 annotated form).
|
|
29
|
+
await writeIntelligenceLedgers(root, derivedRec, evLedger);
|
|
30
|
+
await writeIntelligenceDecisionLedger(root, derivedDec);
|
|
31
|
+
// Re-render subject MDs from current ledgers (source-of-truth JSON untouched).
|
|
32
|
+
await mkdir(intelligenceDir(root), { recursive: true });
|
|
33
|
+
await atomicWriteText(assumptionsMdPath(root), renderAssumptionsMd(asLedger));
|
|
34
|
+
await atomicWriteText(decisionsMdPath(root), renderDecisionsMd(derivedDec));
|
|
35
|
+
return {
|
|
36
|
+
present: true,
|
|
37
|
+
recommendations: derivedRec.recommendations.length,
|
|
38
|
+
assumptions: asLedger.assumptions.length,
|
|
39
|
+
decisions: derivedDec.decisions.length,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=reconcile.js.map
|