@sentropic/track 0.19.4 → 0.20.0
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/index.js +1 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/read/commands.d.ts +4 -4
- package/dist/read/commands.d.ts.map +1 -1
- package/dist/read/commands.js +11 -7
- package/dist/read/commands.js.map +1 -1
- package/dist/read/contract.d.ts +8 -4
- package/dist/read/contract.d.ts.map +1 -1
- package/dist/read/contract.js +1 -1
- package/dist/read/contract.js.map +1 -1
- package/dist/report/directive.d.ts +86 -0
- package/dist/report/directive.d.ts.map +1 -0
- package/dist/report/directive.js +312 -0
- package/dist/report/directive.js.map +1 -0
- package/dist/report/format.d.ts +14 -0
- package/dist/report/format.d.ts.map +1 -1
- package/dist/report/format.js +71 -45
- package/dist/report/format.js.map +1 -1
- package/dist/report/rollup.d.ts +33 -1
- package/dist/report/rollup.d.ts.map +1 -1
- package/dist/report/rollup.js +41 -12
- package/dist/report/rollup.js.map +1 -1
- package/dist/report/status-by-level.js +3 -3
- package/dist/report/status-by-level.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
// preconisation-actionnable (DESIGN LOCKED) — the DIRECTIVE selector. Replaces the constant
|
|
2
|
+
// `préconisation` (which took `leaves[0]` and emitted one frozen phrase per WP) with a DIRECTIVE
|
|
3
|
+
// DERIVED from each item's real state, langue-neutre, and DELEGABLE as-is to a subagent.
|
|
4
|
+
//
|
|
5
|
+
// PURE & ADDITIVE: every fact a directive needs is already on `WpLeaf` (enriched in rollup.ts via
|
|
6
|
+
// `acceptanceStatus` + `effectiveOpenBlockersForItem`) — the selector recomputes NOTHING. No new event,
|
|
7
|
+
// INGEST unchanged. The enums are a GOVERNED vocabulary (additive only, never renamed; an unknown
|
|
8
|
+
// `step.code` degrades to `inspect-fallback` at the renderer — forward-compat, see §3/§7 of the DESIGN).
|
|
9
|
+
// ---- record-only commandHint allowlist (DESIGN §5) -------------------------------------------------
|
|
10
|
+
// `commandHint` = verbs of MEASURE / ATTENTION / FOCUS only. A directive NEVER hints at fabricating an
|
|
11
|
+
// outcome (`item realize <id> done`, `accept … pass|waived`). `affordances` say what is LEGAL; the hint
|
|
12
|
+
// never presumes a write. A runtime guard fails closed so a future edit cannot leak a write/pass verb.
|
|
13
|
+
const SAFE_HINT = /^track (focus|accept run|blocker raise|priority assess|query|report)\b/;
|
|
14
|
+
const FORBIDDEN_HINT = /\b(realize|done|pass|waived)\b/;
|
|
15
|
+
export function assertSafeCommandHint(hint) {
|
|
16
|
+
if (hint === undefined)
|
|
17
|
+
return;
|
|
18
|
+
if (!SAFE_HINT.test(hint) || FORBIDDEN_HINT.test(hint)) {
|
|
19
|
+
throw new Error(`unsafe commandHint (record-only allowlist violated, DESIGN §5): ${hint}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// The LEGAL next writes per step (a curated affordance set — what the human/AI MAY submit, never a
|
|
23
|
+
// presumed write). Mirrors the monotone facade machines coarsely; the facade re-checks legality.
|
|
24
|
+
const AFFORDANCES = {
|
|
25
|
+
'focus-decision': ['decision.outcome'],
|
|
26
|
+
'settle-decision': ['decision.outcome'],
|
|
27
|
+
'resume-engagement': ['blocker.resolve-external'],
|
|
28
|
+
'resolve-external-blocker': ['blocker.resolve', 'blocker.resolve-external'],
|
|
29
|
+
'amend-spec': ['item.spec', 'item.spec-amend'],
|
|
30
|
+
'fix-acceptance': ['acceptance.run'],
|
|
31
|
+
'rerun-acceptance': ['acceptance.run'],
|
|
32
|
+
'finish-increment': ['item.realize'],
|
|
33
|
+
'start-increment': ['item.realize'],
|
|
34
|
+
'prioritize-backlog': ['priority.assess'],
|
|
35
|
+
'inspect-fallback': [],
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Presentation heuristic (NOT a directive field): a decision is "complex enough to warrant a focus
|
|
39
|
+
* session" when it has ≥3 open questions / ≥3 options / any dossier artifact, or simply lacks a
|
|
40
|
+
* recommendation. Drives `focus-decision` vs `settle-decision`. Shared with the renderer (format.ts).
|
|
41
|
+
*/
|
|
42
|
+
export function decisionNeedsFocus(d) {
|
|
43
|
+
return ((d.openQuestionCount ?? 0) >= 3 ||
|
|
44
|
+
(d.optionCount ?? 0) >= 3 ||
|
|
45
|
+
(d.artifacts?.length ?? 0) > 0 ||
|
|
46
|
+
d.hasRecommendation !== true);
|
|
47
|
+
}
|
|
48
|
+
function gateCodeOfDep(b) {
|
|
49
|
+
if (b.scope === 'extra')
|
|
50
|
+
return 'external-dependency'; // (extra deps are engagement-routed; defensive)
|
|
51
|
+
if (b.resolutionRule === 'manual')
|
|
52
|
+
return 'manual-blocker';
|
|
53
|
+
return 'linked-dependency';
|
|
54
|
+
}
|
|
55
|
+
function tierOf(l) {
|
|
56
|
+
const depBlocker = l.openBlockers.find((b) => b.kind === 'dependency');
|
|
57
|
+
const blockerRefs = l.openBlockers.map((b) => b.blockerId);
|
|
58
|
+
// 1. real blocking gate (dependency/manual blocker open) on a NON-in-progress leaf — P1_GATE.
|
|
59
|
+
if (depBlocker !== undefined && l.realization !== 'in-progress') {
|
|
60
|
+
return { order: 10, rank: 'P1_GATE', step: 'resolve-external-blocker', gateCode: gateCodeOfDep(depBlocker), gateRef: depBlocker.blockerId, blockerRefs };
|
|
61
|
+
}
|
|
62
|
+
// 2. acceptance == 'fail' — P2_ACCEPTANCE (fail sub-rank, primes in-progress).
|
|
63
|
+
if (l.acceptance === 'fail') {
|
|
64
|
+
return { order: 20, rank: 'P2_ACCEPTANCE', step: 'fix-acceptance', gateCode: 'acceptance-failed', blockerRefs: [] };
|
|
65
|
+
}
|
|
66
|
+
// 3. in-progress + open dependency blocker (WIP coincé) — P3_IN_PROGRESS.
|
|
67
|
+
if (depBlocker !== undefined && l.realization === 'in-progress') {
|
|
68
|
+
return { order: 30, rank: 'P3_IN_PROGRESS', step: 'finish-increment', gateCode: gateCodeOfDep(depBlocker), gateRef: depBlocker.blockerId, blockerRefs };
|
|
69
|
+
}
|
|
70
|
+
// 4. in-progress (flux — finish before starting new).
|
|
71
|
+
if (l.realization === 'in-progress') {
|
|
72
|
+
return { order: 40, rank: 'P3_IN_PROGRESS', step: 'finish-increment', blockerRefs: [] };
|
|
73
|
+
}
|
|
74
|
+
// 5. acceptance == 'stale' — P2_ACCEPTANCE (stale sub-rank < fail; soft debt, after WIP). D1.
|
|
75
|
+
if (l.acceptance === 'stale') {
|
|
76
|
+
return { order: 50, rank: 'P2_ACCEPTANCE', step: 'rerun-acceptance', gateCode: 'acceptance-stale', blockerRefs: [] };
|
|
77
|
+
}
|
|
78
|
+
// 6. specStatus demands a spec — spec gate.
|
|
79
|
+
if (l.specStatus === 'to-specify') {
|
|
80
|
+
return { order: 60, rank: 'P1_GATE', step: 'amend-spec', gateCode: 'spec-not-ready', blockerRefs: [] };
|
|
81
|
+
}
|
|
82
|
+
// 7. to-do, ordered by WSJF desc (the value proxy lives in the global tie-break).
|
|
83
|
+
if (l.realization === 'to-do') {
|
|
84
|
+
return { order: 70, rank: 'P4_TODO_WSJF', step: 'start-increment', blockerRefs: [] };
|
|
85
|
+
}
|
|
86
|
+
// 8. fallback — NEVER id-only (the facts always carry bucket/realization/acceptance/specStatus).
|
|
87
|
+
return { order: 90, rank: 'P5_FALLBACK', step: 'inspect-fallback', blockerRefs: [] };
|
|
88
|
+
}
|
|
89
|
+
function factsOf(l, blockerRefs) {
|
|
90
|
+
return {
|
|
91
|
+
bucket: l.bucket,
|
|
92
|
+
realization: l.realization,
|
|
93
|
+
acceptance: l.acceptance,
|
|
94
|
+
specStatus: l.specStatus,
|
|
95
|
+
...(l.priority !== undefined ? { wsjf: l.priority } : {}),
|
|
96
|
+
...(l.accountable !== undefined ? { accountable: l.accountable } : {}),
|
|
97
|
+
...(blockerRefs.length > 0 ? { blockerRefs } : {}),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/** Stable directive id (deterministic — no flicker): each (kind,target) yields at most one directive. */
|
|
101
|
+
function directiveId(target) {
|
|
102
|
+
return `${target.kind}:${target.id}`;
|
|
103
|
+
}
|
|
104
|
+
function makeDirective(d) {
|
|
105
|
+
assertSafeCommandHint(d.commandHint);
|
|
106
|
+
return {
|
|
107
|
+
id: directiveId(d.target),
|
|
108
|
+
affordances: d.affordances ?? AFFORDANCES[d.step.code],
|
|
109
|
+
...d,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
// In-WP urgency comparator: order asc, then WSJF desc (undefined LAST), then id (deterministic).
|
|
113
|
+
function leafCompare(a, b) {
|
|
114
|
+
if (a.order !== b.order)
|
|
115
|
+
return a.order - b.order;
|
|
116
|
+
const aw = a.l.priority;
|
|
117
|
+
const bw = b.l.priority;
|
|
118
|
+
if (aw !== bw) {
|
|
119
|
+
if (aw === undefined)
|
|
120
|
+
return 1;
|
|
121
|
+
if (bw === undefined)
|
|
122
|
+
return -1;
|
|
123
|
+
return bw - aw;
|
|
124
|
+
}
|
|
125
|
+
return a.l.id.localeCompare(b.l.id);
|
|
126
|
+
}
|
|
127
|
+
// Global directive comparator (DESIGN §2.B item 8): urgency `order`, then WSJF desc (undefined LAST),
|
|
128
|
+
// then wp.id, then target.id. STRICT determinism — two identical runs yield identical output.
|
|
129
|
+
function directiveCompare(a, b) {
|
|
130
|
+
if (a.order !== b.order)
|
|
131
|
+
return a.order - b.order;
|
|
132
|
+
const aw = a.directive.facts.wsjf;
|
|
133
|
+
const bw = b.directive.facts.wsjf;
|
|
134
|
+
if (aw !== bw) {
|
|
135
|
+
if (aw === undefined)
|
|
136
|
+
return 1;
|
|
137
|
+
if (bw === undefined)
|
|
138
|
+
return -1;
|
|
139
|
+
return bw - aw;
|
|
140
|
+
}
|
|
141
|
+
const aWp = a.directive.scope.wpId ?? '';
|
|
142
|
+
const bWp = b.directive.scope.wpId ?? '';
|
|
143
|
+
if (aWp !== bWp)
|
|
144
|
+
return aWp.localeCompare(bWp);
|
|
145
|
+
return a.directive.target.id.localeCompare(b.directive.target.id);
|
|
146
|
+
}
|
|
147
|
+
/** Is this leaf in the DELEGABLE scope: open, OR done-but-acceptance∈{fail,stale} (the invisible debt). */
|
|
148
|
+
function inDelegableScope(l) {
|
|
149
|
+
if (l.bucket === 'TO-DO' || l.bucket === 'AWAITED')
|
|
150
|
+
return true;
|
|
151
|
+
// A `done` leaf with fail/stale acceptance is the most precious deletable debt (invisible in DONE when
|
|
152
|
+
// requireAccepted=false). `unknown`/`waived`/`n-a` short-circuit (nothing to re-run / intentional waiver).
|
|
153
|
+
return l.bucket === 'DONE' && (l.acceptance === 'fail' || l.acceptance === 'stale');
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Build the DIRECTIVE set over the WP forest + the decision rows (DESIGN §2/§3). Two ORTHOGONAL axes:
|
|
157
|
+
* ROUTAGE (mode, per leaf): open `decision` blocker ⇒ `human-decision` (ref=decisionId); an
|
|
158
|
+
* `engagementRef` on a non-DONE leaf ⇒ `h2a-engagement`; else ⇒ `subagent`.
|
|
159
|
+
* URGENCE (which leaf, on the delegable subset of each WP): the DESIGN §2.B ladder (`tierOf`).
|
|
160
|
+
*
|
|
161
|
+
* Each leaf is attributed to its OWNING node (`node.leaves` — `directLeaves` already stops at sub-WP
|
|
162
|
+
* boundaries) so a directive maps 1:1 to a leaf with no parent/child double-count. One WORK directive per
|
|
163
|
+
* WP node (its most-urgent delegable leaf), PLUS one directive per decision-wait / engagement-wait /
|
|
164
|
+
* pending decision. The returned array is GLOBALLY sorted (deterministic).
|
|
165
|
+
*/
|
|
166
|
+
export function buildDirectives(tree, decisions = []) {
|
|
167
|
+
const decisionById = new Map(decisions.map((d) => [d.id, d]));
|
|
168
|
+
const flat = [];
|
|
169
|
+
const collect = (n) => {
|
|
170
|
+
flat.push(n);
|
|
171
|
+
for (const c of n.children)
|
|
172
|
+
collect(c);
|
|
173
|
+
};
|
|
174
|
+
for (const n of tree)
|
|
175
|
+
collect(n);
|
|
176
|
+
const entries = [];
|
|
177
|
+
const seenDecisionRef = new Set(); // decisionIds already surfaced via a decision-wait leaf
|
|
178
|
+
for (const node of flat) {
|
|
179
|
+
const scope = { wpId: node.id, wpLabel: node.label };
|
|
180
|
+
const work = [];
|
|
181
|
+
for (const l of node.leaves) {
|
|
182
|
+
if (!inDelegableScope(l))
|
|
183
|
+
continue;
|
|
184
|
+
// ROUTAGE — decision wait first, then engagement wait; both leave as their OWN line (not in URGENCE).
|
|
185
|
+
const decisionBlocker = l.openBlockers.find((b) => b.kind === 'decision');
|
|
186
|
+
if (decisionBlocker !== undefined) {
|
|
187
|
+
const decisionId = decisionBlocker.ref ?? '';
|
|
188
|
+
const d = decisionId !== '' ? decisionById.get(decisionId) : undefined;
|
|
189
|
+
const focus = d !== undefined ? decisionNeedsFocus(d) : false;
|
|
190
|
+
entries.push({
|
|
191
|
+
order: 0,
|
|
192
|
+
directive: makeDirective({
|
|
193
|
+
target: { kind: 'item', id: l.id, title: l.title, workspace: l.workspace },
|
|
194
|
+
scope,
|
|
195
|
+
mode: 'human-decision',
|
|
196
|
+
...(decisionId !== '' ? { gate: { code: 'decision-pending', ref: decisionId } } : { gate: { code: 'decision-pending' } }),
|
|
197
|
+
step: { code: focus ? 'focus-decision' : 'settle-decision' },
|
|
198
|
+
rank: 'P1_GATE',
|
|
199
|
+
facts: factsOf(l, decisionId !== '' ? [decisionId] : []),
|
|
200
|
+
...(decisionId !== '' ? { commandHint: `track focus ${decisionId}` } : {}),
|
|
201
|
+
}),
|
|
202
|
+
});
|
|
203
|
+
if (decisionId !== '')
|
|
204
|
+
seenDecisionRef.add(decisionId);
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
const extraEng = l.openBlockers.find((b) => b.engagementRef !== undefined);
|
|
208
|
+
const engRef = extraEng?.engagementRef ?? (l.bucket !== 'DONE' ? l.engagementRef : undefined);
|
|
209
|
+
if (engRef !== undefined) {
|
|
210
|
+
entries.push({
|
|
211
|
+
order: 1,
|
|
212
|
+
directive: makeDirective({
|
|
213
|
+
target: { kind: 'engagement', id: engRef, title: l.title, workspace: l.workspace },
|
|
214
|
+
scope,
|
|
215
|
+
mode: 'h2a-engagement',
|
|
216
|
+
gate: { code: 'engagement-pending', ref: engRef },
|
|
217
|
+
step: { code: 'resume-engagement' },
|
|
218
|
+
rank: 'P1_GATE',
|
|
219
|
+
facts: factsOf(l, extraEng !== undefined ? [extraEng.blockerId] : []),
|
|
220
|
+
}),
|
|
221
|
+
});
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
work.push(l);
|
|
225
|
+
}
|
|
226
|
+
if (work.length === 0)
|
|
227
|
+
continue;
|
|
228
|
+
// Priorité mix (c) (DESIGN §6): when the WP's whole delegable subset is "all to-do, no WSJF, no
|
|
229
|
+
// discriminant", the to-do/WSJF tier degenerates ⇒ the MISSING priority becomes a delegable action.
|
|
230
|
+
const allPlainTodoNoWsjf = work.every((l) => l.realization === 'to-do' &&
|
|
231
|
+
l.specStatus !== 'to-specify' &&
|
|
232
|
+
l.acceptance !== 'fail' &&
|
|
233
|
+
l.acceptance !== 'stale' &&
|
|
234
|
+
l.openBlockers.length === 0 &&
|
|
235
|
+
l.priority === undefined);
|
|
236
|
+
if (allPlainTodoNoWsjf) {
|
|
237
|
+
const rep = [...work].sort((a, b) => a.id.localeCompare(b.id))[0];
|
|
238
|
+
entries.push({
|
|
239
|
+
order: 70,
|
|
240
|
+
directive: makeDirective({
|
|
241
|
+
target: { kind: 'item', id: rep.id, title: rep.title, workspace: rep.workspace },
|
|
242
|
+
scope,
|
|
243
|
+
mode: 'subagent',
|
|
244
|
+
gate: { code: 'priority-missing' },
|
|
245
|
+
step: { code: 'prioritize-backlog' },
|
|
246
|
+
rank: 'P4_TODO_WSJF',
|
|
247
|
+
facts: factsOf(rep, []),
|
|
248
|
+
commandHint: `track priority assess ${rep.id}`,
|
|
249
|
+
}),
|
|
250
|
+
});
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
// Most-urgent delegable leaf of this WP (URGENCE ladder + in-WP tie-break).
|
|
254
|
+
const ranked = work.map((l) => ({ l, ...tierOf(l) }));
|
|
255
|
+
ranked.sort(leafCompare);
|
|
256
|
+
const top = ranked[0];
|
|
257
|
+
entries.push({
|
|
258
|
+
order: top.order,
|
|
259
|
+
directive: makeDirective({
|
|
260
|
+
target: { kind: 'item', id: top.l.id, title: top.l.title, workspace: top.l.workspace },
|
|
261
|
+
scope,
|
|
262
|
+
mode: 'subagent',
|
|
263
|
+
...(top.gateCode !== undefined
|
|
264
|
+
? { gate: { code: top.gateCode, ...(top.gateRef !== undefined ? { ref: top.gateRef } : {}) } }
|
|
265
|
+
: {}),
|
|
266
|
+
step: { code: top.step },
|
|
267
|
+
rank: top.rank,
|
|
268
|
+
facts: factsOf(top.l, top.blockerRefs),
|
|
269
|
+
}),
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
// Pending DecisionRows NOT already surfaced as a decision-wait (a decision blocking a leaf is covered by
|
|
273
|
+
// that leaf's line). A pending decision with no blocked leaf still needs its own human-decision line.
|
|
274
|
+
for (const d of decisions) {
|
|
275
|
+
if (d.outcome !== 'pending')
|
|
276
|
+
continue;
|
|
277
|
+
if (seenDecisionRef.has(d.id))
|
|
278
|
+
continue;
|
|
279
|
+
const focus = decisionNeedsFocus(d);
|
|
280
|
+
entries.push({
|
|
281
|
+
order: 0,
|
|
282
|
+
directive: makeDirective({
|
|
283
|
+
target: { kind: 'decision', id: d.id, title: d.title, workspace: d.workspace },
|
|
284
|
+
scope: {},
|
|
285
|
+
mode: 'human-decision',
|
|
286
|
+
gate: { code: 'decision-pending', ref: d.id },
|
|
287
|
+
step: { code: focus ? 'focus-decision' : 'settle-decision' },
|
|
288
|
+
rank: 'P1_GATE',
|
|
289
|
+
facts: {
|
|
290
|
+
bucket: 'AWAITED',
|
|
291
|
+
realization: d.realization,
|
|
292
|
+
acceptance: 'n/a',
|
|
293
|
+
specStatus: 'n/a',
|
|
294
|
+
...(d.accountable !== undefined ? { accountable: d.accountable } : {}),
|
|
295
|
+
blockerRefs: [d.id],
|
|
296
|
+
},
|
|
297
|
+
commandHint: `track focus ${d.id}`,
|
|
298
|
+
}),
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
entries.sort(directiveCompare);
|
|
302
|
+
return entries.map((e) => e.directive);
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* The flat, prioritized SUBAGENT dispatch queue (DESIGN §4): the directive ids that are delegable to a
|
|
306
|
+
* subagent, in urgency order. `human-decision` / `h2a-engagement` directives are surfaced in `directives[]`
|
|
307
|
+
* but NOT here — they need a human / an h2a peer, not a subagent. Input is already globally sorted.
|
|
308
|
+
*/
|
|
309
|
+
export function dispatchQueueOf(directives) {
|
|
310
|
+
return directives.filter((d) => d.mode === 'subagent' || d.mode === 'local').map((d) => d.id);
|
|
311
|
+
}
|
|
312
|
+
//# sourceMappingURL=directive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directive.js","sourceRoot":"","sources":["../../src/report/directive.ts"],"names":[],"mappings":"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"}
|
package/dist/report/format.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { DecisionRow, Report, ReportRow } from './build.js';
|
|
2
2
|
import type { WpNode } from './rollup.js';
|
|
3
|
+
import { type Directive } from './directive.js';
|
|
3
4
|
export type Format = 'json' | 'text' | 'md';
|
|
4
5
|
export declare function formatReport(report: Report, format: Format): string;
|
|
5
6
|
/**
|
|
@@ -55,7 +56,20 @@ export interface ReportView {
|
|
|
55
56
|
locale: 'fr';
|
|
56
57
|
tables: readonly ReportViewTable[];
|
|
57
58
|
generalRecommendation: string;
|
|
59
|
+
/**
|
|
60
|
+
* preconisation-actionnable (DESIGN §4) — the langue-neutre DIRECTIVES the tables are DERIVED from
|
|
61
|
+
* (machine surface). `dispatchQueue` is the flat, prioritized list of SUBAGENT directive ids (the real
|
|
62
|
+
* delegation payload). Both are additive; the rendered tables + `generalRecommendation` stay back-compat.
|
|
63
|
+
*/
|
|
64
|
+
directives: readonly Directive[];
|
|
65
|
+
dispatchQueue: readonly string[];
|
|
58
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Render ONE directive to a human FR phrase — RENDER-ONLY (no phrase is ever stored as data, DESIGN §3).
|
|
69
|
+
* Maps the langue-neutre `(mode, step, gate)` to a sentence. An UNKNOWN `step.code` (a future vocabulary
|
|
70
|
+
* entry this renderer predates) degrades to the `inspect-fallback` phrasing — forward-compat (DESIGN §7).
|
|
71
|
+
*/
|
|
72
|
+
export declare function directivePhrase(d: Directive): string;
|
|
59
73
|
export declare function buildWpConductorView(tree: readonly WpNode[], decisions?: readonly DecisionRow[]): ReportView;
|
|
60
74
|
export declare function formatWpConductor(tree: readonly WpNode[], format: Format, decisions?: readonly DecisionRow[]): string;
|
|
61
75
|
export declare function formatRows(rows: ReportRow[], format: Format): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/report/format.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAChE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/report/format.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAChE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAIL,KAAK,SAAS,EAEf,MAAM,gBAAgB,CAAA;AAEvB,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;AAoD3C,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAwBnE;AAkFD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CA6CzE;AAaD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,MAAM,GAAE,MAAa,GAAG,MAAM,CAenF;AAED,+GAA+G;AAC/G,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,GAAG,EAAE,MAAM,GAAG,KAAK,CAAA;CACpB;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,QAAQ,CAiB1D;AAwBD;;;;;;;;;GASG;AACH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,SAAS;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACjD,IAAI,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAA;CACxC;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,qBAAqB,CAAA;IAC3B,MAAM,EAAE,IAAI,CAAA;IACZ,MAAM,EAAE,SAAS,eAAe,EAAE,CAAA;IAClC,qBAAqB,EAAE,MAAM,CAAA;IAC7B;;;;OAIG;IACH,UAAU,EAAE,SAAS,SAAS,EAAE,CAAA;IAChC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAA;CACjC;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CA2BpD;AAOD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,GAAE,SAAS,WAAW,EAAO,GAAG,UAAU,CAyDhH;AAoBD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAE,SAAS,WAAW,EAAO,GAAG,MAAM,CAEzH;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAYpE"}
|
package/dist/report/format.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BUCKETS } from './buckets.js';
|
|
2
|
+
import { buildDirectives, decisionNeedsFocus, dispatchQueueOf, } from './directive.js';
|
|
2
3
|
const BACKSLASH = String.fromCharCode(92);
|
|
3
4
|
// Markdown metacharacters escaped in `md` titles so a user title can't inject formatting.
|
|
4
5
|
const MD_META = new Set([
|
|
@@ -80,9 +81,6 @@ function actionDisposition(r) {
|
|
|
80
81
|
return 'terminer ou expliciter blocage';
|
|
81
82
|
return 'exécuter prochain incrément';
|
|
82
83
|
}
|
|
83
|
-
function decisionNeedsFocus(d) {
|
|
84
|
-
return (d.openQuestionCount ?? 0) >= 3 || (d.optionCount ?? 0) >= 3 || (d.artifacts?.length ?? 0) > 0 || d.hasRecommendation !== true;
|
|
85
|
-
}
|
|
86
84
|
function decisionDisposition(d) {
|
|
87
85
|
if (decisionNeedsFocus(d)) {
|
|
88
86
|
return `focus décision HTML conseillé: track focus ${d.id} --format html`;
|
|
@@ -305,60 +303,82 @@ function droppedLeaves(node) {
|
|
|
305
303
|
walk(node);
|
|
306
304
|
return out;
|
|
307
305
|
}
|
|
306
|
+
/**
|
|
307
|
+
* Render ONE directive to a human FR phrase — RENDER-ONLY (no phrase is ever stored as data, DESIGN §3).
|
|
308
|
+
* Maps the langue-neutre `(mode, step, gate)` to a sentence. An UNKNOWN `step.code` (a future vocabulary
|
|
309
|
+
* entry this renderer predates) degrades to the `inspect-fallback` phrasing — forward-compat (DESIGN §7).
|
|
310
|
+
*/
|
|
311
|
+
export function directivePhrase(d) {
|
|
312
|
+
if (d.mode === 'human-decision') {
|
|
313
|
+
const who = d.facts.accountable ?? 'owner';
|
|
314
|
+
return d.step.code === 'focus-decision'
|
|
315
|
+
? `décision (${who}): focus dossier (questions/options) puis trancher outcome`
|
|
316
|
+
: `décision (${who}): trancher outcome`;
|
|
317
|
+
}
|
|
318
|
+
if (d.mode === 'h2a-engagement') {
|
|
319
|
+
return 'engagement (h2a): relancer engagement puis intégrer le retour';
|
|
320
|
+
}
|
|
321
|
+
const mode = d.mode === 'local' ? 'local' : 'subagent';
|
|
322
|
+
const phrase = {
|
|
323
|
+
'focus-decision': `action (${mode}): focus dossier puis trancher outcome`,
|
|
324
|
+
'settle-decision': `action (${mode}): trancher outcome`,
|
|
325
|
+
'resume-engagement': `action (${mode}): relancer engagement puis intégrer le retour`,
|
|
326
|
+
'resolve-external-blocker': `action (${mode}): lever le blocage puis reprendre`,
|
|
327
|
+
'amend-spec': `action (${mode}): spécifier avant de démarrer`,
|
|
328
|
+
'fix-acceptance': `action (${mode}): corriger puis revalider acceptance (fail)`,
|
|
329
|
+
'rerun-acceptance': `action (${mode}): relancer acceptance (stale) sur le commit courant`,
|
|
330
|
+
'finish-increment': `action (${mode}): terminer l'incrément en cours`,
|
|
331
|
+
'start-increment': `action (${mode}): continuer le premier item ouvert puis enregistrer preuve/acceptance`,
|
|
332
|
+
'prioritize-backlog': `action (${mode}): prioriser le backlog (WSJF absent) puis reprendre`,
|
|
333
|
+
'inspect-fallback': `action (${mode}): inspecter l'état puis décider la suite`,
|
|
334
|
+
};
|
|
335
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition — `step.code` may be an UNKNOWN
|
|
336
|
+
// future vocabulary entry (governed/additive enums): fall back rather than render `undefined`.
|
|
337
|
+
return phrase[d.step.code] ?? `action (${mode}): inspecter l'état puis décider la suite`;
|
|
338
|
+
}
|
|
339
|
+
/** The `scope/gate` cell for a directive row: its gate code if any, else the WP label, else `-`. */
|
|
340
|
+
function directiveScopeLabel(d) {
|
|
341
|
+
return d.gate?.code ?? d.scope.wpLabel ?? '-';
|
|
342
|
+
}
|
|
308
343
|
export function buildWpConductorView(tree, decisions = []) {
|
|
309
344
|
const wpName = (n) => `${n.label} · ${clean(stripWpPrefix(n.title))}`;
|
|
310
|
-
const flat = [];
|
|
311
|
-
const collect = (n) => {
|
|
312
|
-
flat.push(n);
|
|
313
|
-
for (const c of n.children)
|
|
314
|
-
collect(c);
|
|
315
|
-
};
|
|
316
|
-
for (const n of tree)
|
|
317
|
-
collect(n);
|
|
318
345
|
const totals = wpTotals(tree);
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
346
|
+
// preconisation-actionnable (DESIGN §4): the DÉCISIONS/ACTIONS table + generalRecommendation are now
|
|
347
|
+
// DERIVED from the directive set (each directive ⇒ one row, phrase rendered, never stored). FAIT/À-FAIRE
|
|
348
|
+
// stay the same rollup-driven tables (unchanged back-compat).
|
|
349
|
+
const directives = buildDirectives(tree, decisions);
|
|
350
|
+
const dispatchQueue = dispatchQueueOf(directives);
|
|
351
|
+
const humanDecisions = directives.filter((d) => d.mode === 'human-decision');
|
|
352
|
+
const focusNeeded = humanDecisions.filter((d) => d.step.code === 'focus-decision').length;
|
|
353
|
+
const generalRecommendation = focusNeeded >= 2 || humanDecisions.length >= 4
|
|
322
354
|
? 'Prévoir un temps de focus HTML pour trancher les décisions accumulées, puis reprendre les WP par premier item ouvert.'
|
|
323
355
|
: 'Avancer par premier item ouvert, enregistrer preuve/acceptance, et escalader uniquement les décisions réellement bloquantes.';
|
|
324
356
|
const doneRows = [
|
|
325
357
|
{ scope: 'global', progress: `${totals.done}/${totals.active} (${pctStr(totals.pct)})`, lastActions: `${totals.done} items faits; poursuivre les WP ouverts` },
|
|
326
358
|
...tree.filter((n) => n.pct === 100).map((n) => ({ scope: wpName(n), progress: `${n.done}/${n.active} (100%)`, lastActions: 'WP clos; preuve/acceptance enregistrée' })),
|
|
327
359
|
];
|
|
328
|
-
const todoRows = tree.filter((n) => n.pct !== 100).map((n) =>
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
360
|
+
const todoRows = tree.filter((n) => n.pct !== 100).map((n) => {
|
|
361
|
+
const open = openLeaves(n);
|
|
362
|
+
const shown = open.slice(0, 2).map((l) => clean(l.title)).join(' / ');
|
|
363
|
+
// NEVER truncate silently: surface the count of items not shown so the report can't read as complete.
|
|
364
|
+
const more = open.length > 2 ? `${shown} (+${open.length - 2} autres)` : shown;
|
|
365
|
+
return { wp: wpName(n), progress: `${n.done}/${n.active} (${pctStr(n.pct)})`, todo: more || 'aucun item ouvert direct' };
|
|
366
|
+
});
|
|
367
|
+
// DÉCISIONS/ACTIONS rows — derived from the directives. Decisions first (capped at 8 + an omission count
|
|
368
|
+
// so the table never reads as complete when it isn't), then engagement/work directives.
|
|
337
369
|
const actionRows = [];
|
|
338
|
-
if (
|
|
370
|
+
if (focusNeeded >= 2 || humanDecisions.length >= 4) {
|
|
339
371
|
actionRows.push({ scope: '-', subject: 'décisions accumulées', recommendation: 'focus (humain+MCP): lancer focus HTML local; retour outcome via vue interactive/MCP' });
|
|
340
372
|
}
|
|
341
|
-
for (const d of
|
|
342
|
-
actionRows.push({ scope: d
|
|
373
|
+
for (const d of humanDecisions.slice(0, 8)) {
|
|
374
|
+
actionRows.push({ scope: directiveScopeLabel(d), subject: clean(d.target.title ?? d.target.id), recommendation: directivePhrase(d) });
|
|
343
375
|
}
|
|
344
|
-
for (const
|
|
345
|
-
|
|
346
|
-
actionRows.push({ scope: wp.label, subject: clean(leaf.title), recommendation: `décision (owner/subagent): ${focus}` });
|
|
376
|
+
for (const d of directives.filter((x) => x.mode !== 'human-decision')) {
|
|
377
|
+
actionRows.push({ scope: directiveScopeLabel(d), subject: clean(d.target.title ?? d.target.id), recommendation: directivePhrase(d) });
|
|
347
378
|
}
|
|
348
|
-
const
|
|
349
|
-
|
|
350
|
-
.
|
|
351
|
-
.map((n) => ({ wp: n, leaves: openLeaves(n).filter((l) => !decisionWaitIds.has(l.id)) }))
|
|
352
|
-
.filter((x) => x.leaves.length > 0);
|
|
353
|
-
for (const { wp, leaves } of candidates) {
|
|
354
|
-
const first = leaves[0];
|
|
355
|
-
const mode = first.awaitedOnDecision === true ? 'human decision' : first.engagementRef !== undefined ? 'h2a/subagent' : 'local/subagent';
|
|
356
|
-
const action = first.awaitedOnDecision === true
|
|
357
|
-
? 'trancher décision bloquante puis relancer WP'
|
|
358
|
-
: first.engagementRef !== undefined
|
|
359
|
-
? 'relancer engagement/subagent et suivre retour'
|
|
360
|
-
: 'continuer premier item ouvert puis enregistrer preuve/acceptance';
|
|
361
|
-
actionRows.push({ scope: wpName(wp), subject: clean(first.title), recommendation: `action (${mode}): ${action}` });
|
|
379
|
+
const omitted = Math.max(0, humanDecisions.length - 8);
|
|
380
|
+
if (omitted > 0) {
|
|
381
|
+
actionRows.push({ scope: '-', subject: `+${omitted} entrées non listées`, recommendation: 'voir `track query` / `track report --flat` pour le détail complet' });
|
|
362
382
|
}
|
|
363
383
|
return {
|
|
364
384
|
kind: 'wp-conductor-report',
|
|
@@ -369,20 +389,26 @@ export function buildWpConductorView(tree, decisions = []) {
|
|
|
369
389
|
{ id: 'decisions-actions', title: 'DÉCISIONS/ACTIONS', columns: [{ id: 'scope', label: 'scope/gate' }, { id: 'subject', label: 'sujet' }, { id: 'recommendation', label: 'préconisation' }], rows: actionRows.length > 0 ? actionRows : [{ scope: '-', subject: 'aucune action ouverte dans les WP actifs', recommendation: '-' }] },
|
|
370
390
|
],
|
|
371
391
|
generalRecommendation,
|
|
392
|
+
directives,
|
|
393
|
+
dispatchQueue,
|
|
372
394
|
};
|
|
373
395
|
}
|
|
374
396
|
function renderReportView(view, format) {
|
|
375
397
|
if (format === 'json')
|
|
376
398
|
return JSON.stringify(view, null, 2) + '\n';
|
|
399
|
+
// User-originated cell content (titles) is escaped per-format: `md` escapes markdown metacharacters so a
|
|
400
|
+
// crafted item title cannot inject formatting (parity with the legacy `formatReport`/`title` path); `text`
|
|
401
|
+
// is clean. The view model itself stays RAW (escaping is a render-only concern).
|
|
402
|
+
const esc = (s) => title(s, format);
|
|
377
403
|
const h = (label) => (format === 'md' ? `## ${label}` : label);
|
|
378
404
|
const lines = [];
|
|
379
405
|
for (const section of view.tables) {
|
|
380
406
|
lines.push(h(section.title));
|
|
381
|
-
lines.push(...table(section.columns.map((c) => c.label), section.rows.map((row) => section.columns.map((c) => row[c.id] ?? ''))));
|
|
407
|
+
lines.push(...table(section.columns.map((c) => c.label), section.rows.map((row) => section.columns.map((c) => esc(row[c.id] ?? '')))));
|
|
382
408
|
lines.push('');
|
|
383
409
|
}
|
|
384
410
|
lines.push(h('RECOMMANDATION'));
|
|
385
|
-
lines.push(view.generalRecommendation);
|
|
411
|
+
lines.push(esc(view.generalRecommendation));
|
|
386
412
|
return lines.join('\n').trimEnd() + '\n';
|
|
387
413
|
}
|
|
388
414
|
export function formatWpConductor(tree, format, decisions = []) {
|