@telora/daemon 0.16.20 → 0.16.25
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/build-info.json +4 -3
- package/dist/ai-inspection-runner.d.ts.map +1 -1
- package/dist/ai-inspection-runner.js +6 -0
- package/dist/ai-inspection-runner.js.map +1 -1
- package/dist/de-reconciliation.d.ts +62 -0
- package/dist/de-reconciliation.d.ts.map +1 -0
- package/dist/de-reconciliation.js +187 -0
- package/dist/de-reconciliation.js.map +1 -0
- package/dist/de-restatement.d.ts +80 -0
- package/dist/de-restatement.d.ts.map +1 -0
- package/dist/de-restatement.js +158 -0
- package/dist/de-restatement.js.map +1 -0
- package/dist/directive-executor.d.ts +25 -0
- package/dist/directive-executor.d.ts.map +1 -1
- package/dist/directive-executor.js +63 -3
- package/dist/directive-executor.js.map +1 -1
- package/dist/focus-completion.d.ts +39 -1
- package/dist/focus-completion.d.ts.map +1 -1
- package/dist/focus-completion.js +29 -10
- package/dist/focus-completion.js.map +1 -1
- package/dist/focus-loop.d.ts +12 -0
- package/dist/focus-loop.d.ts.map +1 -1
- package/dist/focus-loop.js +22 -5
- package/dist/focus-loop.js.map +1 -1
- package/dist/realign-apply.d.ts +5 -0
- package/dist/realign-apply.d.ts.map +1 -1
- package/dist/realign-apply.js +46 -4
- package/dist/realign-apply.js.map +1 -1
- package/dist/verification-engine.d.ts +8 -0
- package/dist/verification-engine.d.ts.map +1 -1
- package/dist/verification-engine.js +16 -0
- package/dist/verification-engine.js.map +1 -1
- package/package.json +1 -1
package/build-info.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"commitSha": "
|
|
3
|
-
"builtAt": "2026-05-
|
|
2
|
+
"commitSha": "2a258fe0",
|
|
3
|
+
"builtAt": "2026-05-27T13:35:35.632Z",
|
|
4
4
|
"expectedMigrations": [
|
|
5
5
|
"20250829113330_create_org_nodes_table.sql",
|
|
6
6
|
"20250829113402_fix_function_security_search_path.sql",
|
|
@@ -593,6 +593,7 @@
|
|
|
593
593
|
"20260525095445_review_lineage_resume.sql",
|
|
594
594
|
"20260525124226_coding_stage_delivery_index.sql",
|
|
595
595
|
"20260526025901_engine_selection_columns.sql",
|
|
596
|
-
"20260527003010_backfill_review_stage_execution_mode.sql"
|
|
596
|
+
"20260527003010_backfill_review_stage_execution_mode.sql",
|
|
597
|
+
"20260527083414_handle_new_user_skip_personal_org_on_join.sql"
|
|
597
598
|
]
|
|
598
599
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-inspection-runner.d.ts","sourceRoot":"","sources":["../src/ai-inspection-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAErE,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,QAAQ,GAAG,cAAc,CAAC;AAErE,MAAM,MAAM,iBAAiB,GACzB,kBAAkB,GAClB,UAAU,GACV,aAAa,GACb,kBAAkB,GAClB,gBAAgB,CAAC;AAErB,MAAM,WAAW,gBAAgB;IAC/B,yEAAyE;IACzE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,iBAAiB,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,iBAAiB,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,aAAa;IAC5B,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,KAAK,YAAY,CAAC;IACzE,uDAAuD;IACvD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,UAAU,SAAS;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;
|
|
1
|
+
{"version":3,"file":"ai-inspection-runner.d.ts","sourceRoot":"","sources":["../src/ai-inspection-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAErE,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,QAAQ,GAAG,cAAc,CAAC;AAErE,MAAM,MAAM,iBAAiB,GACzB,kBAAkB,GAClB,UAAU,GACV,aAAa,GACb,kBAAkB,GAClB,gBAAgB,CAAC;AAErB,MAAM,WAAW,gBAAgB;IAC/B,yEAAyE;IACzE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,iBAAiB,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,iBAAiB,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,aAAa;IAC5B,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,KAAK,YAAY,CAAC;IACzE,uDAAuD;IACvD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,UAAU,SAAS;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAgED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAsDxE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CAa1F;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,kBAAkB,EAC1B,IAAI,GAAE,aAAkB,GACvB,OAAO,CAAC,gBAAgB,CAAC,CAqF3B"}
|
|
@@ -48,6 +48,12 @@ suggest a correction. Each observation is:
|
|
|
48
48
|
"observed": "what the code shows",
|
|
49
49
|
"suggested_correction": "what the CRT statement should say (or what node should be added)" }
|
|
50
50
|
|
|
51
|
+
For kind "flip_ude_to_de", suggested_correction is NOT a description of the
|
|
52
|
+
contradiction -- it IS the positive restatement of the UDE: the single
|
|
53
|
+
desired-effect sentence the former UDE now reads as. State the resolved,
|
|
54
|
+
desirable outcome (e.g. "operators see at a glance which focuses are blocked"),
|
|
55
|
+
not "the UDE no longer holds".
|
|
56
|
+
|
|
51
57
|
Use 'inconclusive' when the code does not give you enough signal to decide.
|
|
52
58
|
|
|
53
59
|
`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-inspection-runner.js","sourceRoot":"","sources":["../src/ai-inspection-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,KAAK,EAAqB,MAAM,oBAAoB,CAAC;AA0C9D,MAAM,kBAAkB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAEzC,MAAM,sBAAsB,GAAG
|
|
1
|
+
{"version":3,"file":"ai-inspection-runner.js","sourceRoot":"","sources":["../src/ai-inspection-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Desired-effect restatement reconciliation backstop.
|
|
3
|
+
*
|
|
4
|
+
* Runs inside the focus-loop realign phase (NOT a separate opt-out env loop).
|
|
5
|
+
* Each tick it finds desired_effect nodes that lack a positive restatement and
|
|
6
|
+
* authors one via the de-restatement helper, guaranteeing the focus invariant:
|
|
7
|
+
* no desired_effect node carries raw UDE text.
|
|
8
|
+
*
|
|
9
|
+
* Two cases (mirroring the two flip surfaces -- see graph-verification.ts):
|
|
10
|
+
* - OVERLAY: a both-scoped node whose FRT overlay was flipped to
|
|
11
|
+
* desired_effect but whose frt_statement was never authored
|
|
12
|
+
* (frtNodeType='desired_effect' AND needsRestatement(frtStatement)). The
|
|
13
|
+
* positive text is written to frt_statement. This covers UI/agent target
|
|
14
|
+
* flips and the historical nodes left by migration 20260523095104.
|
|
15
|
+
* - BASE: a node already promoted to node_type='desired_effect' whose base
|
|
16
|
+
* statement still equals the pre-flip UDE text (per reality_tree_node_history
|
|
17
|
+
* previous_node_type='undesired_effect'). The positive text is written to
|
|
18
|
+
* statement. This covers verify auto-flips and human-UI base flips.
|
|
19
|
+
*
|
|
20
|
+
* Per-node failures are collected and never abort the pass (mirrors
|
|
21
|
+
* applyRatifiedProposals). Running once backfills historical nodes, so there is
|
|
22
|
+
* no separate one-shot script.
|
|
23
|
+
*
|
|
24
|
+
* @module de-reconciliation
|
|
25
|
+
*/
|
|
26
|
+
import { type RestatementInputs, type RestatementOptions } from './de-restatement.js';
|
|
27
|
+
export type AuthorRestatementFn = (inputs: RestatementInputs, opts?: RestatementOptions) => Promise<string>;
|
|
28
|
+
export interface ReconcileDeps {
|
|
29
|
+
callApi?: <T>(action: string, params?: Record<string, unknown>) => Promise<T>;
|
|
30
|
+
/** Authors a positive desired-effect sentence. Defaults to the de-restatement helper. */
|
|
31
|
+
authorRestatement?: AuthorRestatementFn;
|
|
32
|
+
}
|
|
33
|
+
export interface ReconcileResult {
|
|
34
|
+
/** Nodes that had a positive statement authored + written this pass. */
|
|
35
|
+
authored: number;
|
|
36
|
+
/** Desired-effect nodes that already carried positive text (predicate skip). */
|
|
37
|
+
skipped: number;
|
|
38
|
+
/** Nodes whose authoring/write failed (collected, non-fatal). */
|
|
39
|
+
failed: number;
|
|
40
|
+
errors: string[];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Author frt_statement for an injection's UDE targets that still lack positive
|
|
44
|
+
* text, BEFORE the injection is verified. The edge verify path cannot run the
|
|
45
|
+
* LLM helper, so the daemon authors here first; verify's existing promotion
|
|
46
|
+
* (`if (frt_statement) statement = frt_statement`) then carries the positive
|
|
47
|
+
* text into current reality, closing the gap where a verified former-UDE would
|
|
48
|
+
* otherwise read negatively until the next reconciliation tick.
|
|
49
|
+
*
|
|
50
|
+
* Injection-conditioned on the injection's own statement. Best-effort and
|
|
51
|
+
* idempotent: targets already carrying positive frt_statement are skipped.
|
|
52
|
+
* Used by the daemon verification engine right before verifyInjection.
|
|
53
|
+
*/
|
|
54
|
+
export declare function authorInjectionTargetRestatements(injectionNodeId: string, focusId: string | null, deps?: ReconcileDeps): Promise<ReconcileResult>;
|
|
55
|
+
/**
|
|
56
|
+
* Author positive restatements for every desired_effect node in the focus's
|
|
57
|
+
* active reality tree(s) that still lacks one. Idempotent: a node already
|
|
58
|
+
* carrying positive text is skipped (no write), so a second pass over the same
|
|
59
|
+
* tree performs zero writes.
|
|
60
|
+
*/
|
|
61
|
+
export declare function reconcileDesiredEffectRestatements(focusId: string, deps?: ReconcileDeps): Promise<ReconcileResult>;
|
|
62
|
+
//# sourceMappingURL=de-reconciliation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"de-reconciliation.d.ts","sourceRoot":"","sources":["../src/de-reconciliation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAGH,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACxB,MAAM,qBAAqB,CAAC;AAS7B,MAAM,MAAM,mBAAmB,GAAG,CAChC,MAAM,EAAE,iBAAiB,EACzB,IAAI,CAAC,EAAE,kBAAkB,KACtB,OAAO,CAAC,MAAM,CAAC,CAAC;AAErB,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAC9E,yFAAyF;IACzF,iBAAiB,CAAC,EAAE,mBAAmB,CAAC;CACzC;AAED,MAAM,WAAW,eAAe;IAC9B,wEAAwE;IACxE,QAAQ,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,OAAO,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAYD;;;;;;;;;;;GAWG;AACH,wBAAsB,iCAAiC,CACrD,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,IAAI,GAAE,aAAkB,GACvB,OAAO,CAAC,eAAe,CAAC,CAgD1B;AAmBD;;;;;GAKG;AACH,wBAAsB,kCAAkC,CACtD,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,aAAkB,GACvB,OAAO,CAAC,eAAe,CAAC,CA8E1B"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Desired-effect restatement reconciliation backstop.
|
|
3
|
+
*
|
|
4
|
+
* Runs inside the focus-loop realign phase (NOT a separate opt-out env loop).
|
|
5
|
+
* Each tick it finds desired_effect nodes that lack a positive restatement and
|
|
6
|
+
* authors one via the de-restatement helper, guaranteeing the focus invariant:
|
|
7
|
+
* no desired_effect node carries raw UDE text.
|
|
8
|
+
*
|
|
9
|
+
* Two cases (mirroring the two flip surfaces -- see graph-verification.ts):
|
|
10
|
+
* - OVERLAY: a both-scoped node whose FRT overlay was flipped to
|
|
11
|
+
* desired_effect but whose frt_statement was never authored
|
|
12
|
+
* (frtNodeType='desired_effect' AND needsRestatement(frtStatement)). The
|
|
13
|
+
* positive text is written to frt_statement. This covers UI/agent target
|
|
14
|
+
* flips and the historical nodes left by migration 20260523095104.
|
|
15
|
+
* - BASE: a node already promoted to node_type='desired_effect' whose base
|
|
16
|
+
* statement still equals the pre-flip UDE text (per reality_tree_node_history
|
|
17
|
+
* previous_node_type='undesired_effect'). The positive text is written to
|
|
18
|
+
* statement. This covers verify auto-flips and human-UI base flips.
|
|
19
|
+
*
|
|
20
|
+
* Per-node failures are collected and never abort the pass (mirrors
|
|
21
|
+
* applyRatifiedProposals). Running once backfills historical nodes, so there is
|
|
22
|
+
* no separate one-shot script.
|
|
23
|
+
*
|
|
24
|
+
* @module de-reconciliation
|
|
25
|
+
*/
|
|
26
|
+
import { callApi as defaultCallApi } from './queries/shared.js';
|
|
27
|
+
import { authorRestatement as defaultAuthorRestatement, needsRestatement, } from './de-restatement.js';
|
|
28
|
+
/**
|
|
29
|
+
* Author frt_statement for an injection's UDE targets that still lack positive
|
|
30
|
+
* text, BEFORE the injection is verified. The edge verify path cannot run the
|
|
31
|
+
* LLM helper, so the daemon authors here first; verify's existing promotion
|
|
32
|
+
* (`if (frt_statement) statement = frt_statement`) then carries the positive
|
|
33
|
+
* text into current reality, closing the gap where a verified former-UDE would
|
|
34
|
+
* otherwise read negatively until the next reconciliation tick.
|
|
35
|
+
*
|
|
36
|
+
* Injection-conditioned on the injection's own statement. Best-effort and
|
|
37
|
+
* idempotent: targets already carrying positive frt_statement are skipped.
|
|
38
|
+
* Used by the daemon verification engine right before verifyInjection.
|
|
39
|
+
*/
|
|
40
|
+
export async function authorInjectionTargetRestatements(injectionNodeId, focusId, deps = {}) {
|
|
41
|
+
const callApi = deps.callApi ?? defaultCallApi;
|
|
42
|
+
const author = deps.authorRestatement ?? defaultAuthorRestatement;
|
|
43
|
+
const result = { authored: 0, skipped: 0, failed: 0, errors: [] };
|
|
44
|
+
if (!focusId)
|
|
45
|
+
return result;
|
|
46
|
+
const treesResp = await callApi('reality_tree_list', { focusId });
|
|
47
|
+
const trees = (treesResp.items ?? []).filter((t) => t.status === 'active');
|
|
48
|
+
for (const tree of trees) {
|
|
49
|
+
const [nodesResp, edgesResp] = await Promise.all([
|
|
50
|
+
callApi('reality_tree_node_list', { treeId: tree.id, status: 'active' }),
|
|
51
|
+
callApi('reality_tree_edge_list', { treeId: tree.id }),
|
|
52
|
+
]);
|
|
53
|
+
const nodes = nodesResp.items ?? [];
|
|
54
|
+
const edges = edgesResp.items ?? [];
|
|
55
|
+
const nodeById = new Map(nodes.map((n) => [n.id, n]));
|
|
56
|
+
const injection = nodeById.get(injectionNodeId);
|
|
57
|
+
if (!injection || injection.nodeType !== 'injection')
|
|
58
|
+
continue; // not in this tree
|
|
59
|
+
const injectionStatements = injection.statement.trim() !== '' ? [injection.statement] : undefined;
|
|
60
|
+
for (const e of edges) {
|
|
61
|
+
if (e.edgeType !== 'targets' || e.fromNodeId !== injectionNodeId)
|
|
62
|
+
continue;
|
|
63
|
+
const target = nodeById.get(e.toNodeId);
|
|
64
|
+
if (!target || target.nodeType !== 'undesired_effect')
|
|
65
|
+
continue;
|
|
66
|
+
if (!needsRestatement(target.frtStatement)) {
|
|
67
|
+
result.skipped += 1;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
const text = await author({
|
|
72
|
+
udeStatement: target.statement,
|
|
73
|
+
injectionStatements,
|
|
74
|
+
evidence: target.evidence ?? undefined,
|
|
75
|
+
});
|
|
76
|
+
await callApi('reality_tree_node_update', { nodeId: target.id, frtStatement: text });
|
|
77
|
+
result.authored += 1;
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
result.failed += 1;
|
|
81
|
+
result.errors.push(`pre-verify ${target.id}: ${err.message}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return result; // injection found and processed
|
|
85
|
+
}
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
/** Statements of injection nodes with a live 'targets' edge to the given node. */
|
|
89
|
+
function injectionStatementsTargeting(nodeId, edges, nodeById) {
|
|
90
|
+
const out = [];
|
|
91
|
+
for (const e of edges) {
|
|
92
|
+
if (e.edgeType !== 'targets' || e.toNodeId !== nodeId)
|
|
93
|
+
continue;
|
|
94
|
+
const from = nodeById.get(e.fromNodeId);
|
|
95
|
+
if (from && from.nodeType === 'injection' && from.statement.trim() !== '') {
|
|
96
|
+
out.push(from.statement);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return out;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Author positive restatements for every desired_effect node in the focus's
|
|
103
|
+
* active reality tree(s) that still lacks one. Idempotent: a node already
|
|
104
|
+
* carrying positive text is skipped (no write), so a second pass over the same
|
|
105
|
+
* tree performs zero writes.
|
|
106
|
+
*/
|
|
107
|
+
export async function reconcileDesiredEffectRestatements(focusId, deps = {}) {
|
|
108
|
+
const callApi = deps.callApi ?? defaultCallApi;
|
|
109
|
+
const author = deps.authorRestatement ?? defaultAuthorRestatement;
|
|
110
|
+
const result = { authored: 0, skipped: 0, failed: 0, errors: [] };
|
|
111
|
+
const treesResp = await callApi('reality_tree_list', { focusId });
|
|
112
|
+
const trees = (treesResp.items ?? []).filter((t) => t.status === 'active');
|
|
113
|
+
if (trees.length === 0)
|
|
114
|
+
return result;
|
|
115
|
+
for (const tree of trees) {
|
|
116
|
+
const [nodesResp, edgesResp] = await Promise.all([
|
|
117
|
+
callApi('reality_tree_node_list', { treeId: tree.id, status: 'active' }),
|
|
118
|
+
callApi('reality_tree_edge_list', { treeId: tree.id }),
|
|
119
|
+
]);
|
|
120
|
+
const nodes = nodesResp.items ?? [];
|
|
121
|
+
const edges = edgesResp.items ?? [];
|
|
122
|
+
const nodeById = new Map(nodes.map((n) => [n.id, n]));
|
|
123
|
+
// --- OVERLAY case: frt_node_type flipped to desired_effect, frt_statement unauthored.
|
|
124
|
+
for (const node of nodes) {
|
|
125
|
+
if (node.frtNodeType !== 'desired_effect')
|
|
126
|
+
continue;
|
|
127
|
+
if (!needsRestatement(node.frtStatement)) {
|
|
128
|
+
result.skipped += 1;
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
const injectionStatements = injectionStatementsTargeting(node.id, edges, nodeById);
|
|
132
|
+
try {
|
|
133
|
+
const text = await author({
|
|
134
|
+
udeStatement: node.statement,
|
|
135
|
+
injectionStatements: injectionStatements.length > 0 ? injectionStatements : undefined,
|
|
136
|
+
evidence: node.evidence ?? undefined,
|
|
137
|
+
});
|
|
138
|
+
await callApi('reality_tree_node_update', { nodeId: node.id, frtStatement: text });
|
|
139
|
+
result.authored += 1;
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
result.failed += 1;
|
|
143
|
+
result.errors.push(`overlay ${node.id}: ${err.message}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// --- BASE case: node promoted to desired_effect but base statement still the UDE text.
|
|
147
|
+
const deNodes = nodes.filter((n) => n.nodeType === 'desired_effect');
|
|
148
|
+
for (const node of deNodes) {
|
|
149
|
+
let hist;
|
|
150
|
+
try {
|
|
151
|
+
hist = await callApi('reality_tree_injection_history', {
|
|
152
|
+
nodeId: node.id,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
catch (err) {
|
|
156
|
+
result.failed += 1;
|
|
157
|
+
result.errors.push(`base-history ${node.id}: ${err.message}`);
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
// The flip that turned this node from a UDE into a DE.
|
|
161
|
+
const flip = (hist.history ?? []).find((h) => h.previousNodeType === 'undesired_effect');
|
|
162
|
+
if (!flip)
|
|
163
|
+
continue; // not a UDE->DE flip we can reconcile from history
|
|
164
|
+
if (!needsRestatement(node.statement, flip.previousStatement)) {
|
|
165
|
+
result.skipped += 1;
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
const injectionStatements = flip.injection?.statement?.trim()
|
|
169
|
+
? [flip.injection.statement]
|
|
170
|
+
: [];
|
|
171
|
+
try {
|
|
172
|
+
const text = await author({
|
|
173
|
+
udeStatement: flip.previousStatement ?? node.statement,
|
|
174
|
+
injectionStatements: injectionStatements.length > 0 ? injectionStatements : undefined,
|
|
175
|
+
});
|
|
176
|
+
await callApi('reality_tree_node_update', { nodeId: node.id, statement: text });
|
|
177
|
+
result.authored += 1;
|
|
178
|
+
}
|
|
179
|
+
catch (err) {
|
|
180
|
+
result.failed += 1;
|
|
181
|
+
result.errors.push(`base ${node.id}: ${err.message}`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return result;
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=de-reconciliation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"de-reconciliation.js","sourceRoot":"","sources":["../src/de-reconciliation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Desired-effect restatement helper.
|
|
3
|
+
*
|
|
4
|
+
* Turns a UDE (plus its resolving injection(s)) into one concise,
|
|
5
|
+
* injection-conditioned positive desired-effect sentence. Reuses the same
|
|
6
|
+
* model-invocation pattern as `ai-inspection-runner.ts` -- spawning the
|
|
7
|
+
* `claude` CLI in print mode -- so there is NO new client or secret wiring.
|
|
8
|
+
*
|
|
9
|
+
* Two prompt modes:
|
|
10
|
+
* - injection-conditioned (injectionStatements present): the desired effect
|
|
11
|
+
* is the positive state the UDE BECOMES given those injections; it carries
|
|
12
|
+
* the resolution, it is NOT a naive antonym.
|
|
13
|
+
* - observation-conditioned (no injections): a positive restatement grounded
|
|
14
|
+
* in the evidence/observation of the UDE.
|
|
15
|
+
*
|
|
16
|
+
* Idempotency: callers use `needsRestatement()` to skip nodes that already
|
|
17
|
+
* carry a positive statement (an FRT overlay that is non-null, or a base
|
|
18
|
+
* statement that no longer equals the pre-flip UDE text).
|
|
19
|
+
*
|
|
20
|
+
* @module de-restatement
|
|
21
|
+
*/
|
|
22
|
+
import { type ChildProcess } from 'node:child_process';
|
|
23
|
+
export interface RestatementInputs {
|
|
24
|
+
/** The undesirable-effect statement to restate positively. */
|
|
25
|
+
udeStatement: string;
|
|
26
|
+
/** Resolving injection statement(s). Presence selects injection-conditioned mode. */
|
|
27
|
+
injectionStatements?: string[];
|
|
28
|
+
/** Supporting observation; used in observation-conditioned mode. */
|
|
29
|
+
evidence?: string;
|
|
30
|
+
}
|
|
31
|
+
interface SpawnOpts {
|
|
32
|
+
stdio: ['pipe', 'pipe', 'pipe'];
|
|
33
|
+
}
|
|
34
|
+
export interface RestatementOptions {
|
|
35
|
+
/** Path to the `claude` CLI binary (default: 'claude'). */
|
|
36
|
+
claudeBin?: string;
|
|
37
|
+
/** Timeout in ms; defaults to 2 minutes. */
|
|
38
|
+
timeoutMs?: number;
|
|
39
|
+
/** Override spawn for tests. Defaults to node:child_process spawn. */
|
|
40
|
+
spawnFn?: (cmd: string, args: string[], opts: SpawnOpts) => ChildProcess;
|
|
41
|
+
/**
|
|
42
|
+
* Override the entire model invocation for tests -- bypasses spawning the
|
|
43
|
+
* CLI. Receives the system prompt and user message, returns the raw model
|
|
44
|
+
* text. When omitted, the default spawns the `claude` CLI in print mode.
|
|
45
|
+
*/
|
|
46
|
+
invokeModel?: (systemPrompt: string, userMessage: string) => Promise<string>;
|
|
47
|
+
}
|
|
48
|
+
export declare const RESTATEMENT_SYSTEM_PROMPT = "You restate an undesirable effect (UDE) from a Goldratt reality tree as the single positive desired effect it becomes once resolved.\n\nRules:\n- Output exactly ONE sentence. No preamble, no list, no trailing commentary, no quotes.\n- The desired effect must read as a concrete positive outcome, not a negation of the problem (\"operators can tell...\" is weak; \"operators see at a glance which focuses are blocked and why\" is strong).\n- When resolving injection(s) are provided, the desired effect is the positive state the UDE BECOMES given those injections -- it must carry the resolution the injection delivers, not a naive antonym of the UDE.\n- Keep the subject and domain of the original UDE; only flip its polarity to the resolved, desirable state.";
|
|
49
|
+
/**
|
|
50
|
+
* The system prompt is fixed for both modes (mode is conveyed by the user
|
|
51
|
+
* message). Exposed as a function to mirror `ai-inspection-runner`'s shape
|
|
52
|
+
* and to keep callers from depending on the constant directly.
|
|
53
|
+
*/
|
|
54
|
+
export declare function buildRestatementSystemPrompt(): string;
|
|
55
|
+
/**
|
|
56
|
+
* Build the user message. Injection-conditioned when `injectionStatements`
|
|
57
|
+
* are present, otherwise observation-conditioned.
|
|
58
|
+
*/
|
|
59
|
+
export declare function buildRestatementUserMessage(inputs: RestatementInputs): string;
|
|
60
|
+
/**
|
|
61
|
+
* Idempotency predicate. Returns true when a desired-effect node still needs a
|
|
62
|
+
* positive restatement.
|
|
63
|
+
*
|
|
64
|
+
* - `currentText` is the field a caller would write (frt_statement for the FRT
|
|
65
|
+
* overlay case, statement for the base flip case). Null/blank => needs one.
|
|
66
|
+
* - `originalUdeText`, when supplied (base flip case), is the pre-flip UDE
|
|
67
|
+
* statement. If `currentText` still equals it, the positive text was never
|
|
68
|
+
* authored => needs one.
|
|
69
|
+
*/
|
|
70
|
+
export declare function needsRestatement(currentText: string | null | undefined, originalUdeText?: string | null): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Author the positive desired-effect restatement for a UDE.
|
|
73
|
+
*
|
|
74
|
+
* Returns a single positive sentence. Throws on model-invocation failure;
|
|
75
|
+
* callers (the at-source flip path, the reconciliation backstop) catch and
|
|
76
|
+
* skip so a single failure never aborts the surrounding loop.
|
|
77
|
+
*/
|
|
78
|
+
export declare function authorRestatement(inputs: RestatementInputs, opts?: RestatementOptions): Promise<string>;
|
|
79
|
+
export {};
|
|
80
|
+
//# sourceMappingURL=de-restatement.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"de-restatement.d.ts","sourceRoot":"","sources":["../src/de-restatement.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE9D,MAAM,WAAW,iBAAiB;IAChC,8DAA8D;IAC9D,YAAY,EAAE,MAAM,CAAC;IACrB,qFAAqF;IACrF,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,SAAS;IACjB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,kBAAkB;IACjC,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,KAAK,YAAY,CAAC;IACzE;;;;OAIG;IACH,WAAW,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CAC9E;AAID,eAAO,MAAM,yBAAyB,4vBAMsE,CAAC;AAE7G;;;;GAIG;AACH,wBAAgB,4BAA4B,IAAI,MAAM,CAErD;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAoB7E;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACtC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,GAC9B,OAAO,CAIT;AA0ED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,iBAAiB,EACzB,IAAI,GAAE,kBAAuB,GAC5B,OAAO,CAAC,MAAM,CAAC,CAUjB"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Desired-effect restatement helper.
|
|
3
|
+
*
|
|
4
|
+
* Turns a UDE (plus its resolving injection(s)) into one concise,
|
|
5
|
+
* injection-conditioned positive desired-effect sentence. Reuses the same
|
|
6
|
+
* model-invocation pattern as `ai-inspection-runner.ts` -- spawning the
|
|
7
|
+
* `claude` CLI in print mode -- so there is NO new client or secret wiring.
|
|
8
|
+
*
|
|
9
|
+
* Two prompt modes:
|
|
10
|
+
* - injection-conditioned (injectionStatements present): the desired effect
|
|
11
|
+
* is the positive state the UDE BECOMES given those injections; it carries
|
|
12
|
+
* the resolution, it is NOT a naive antonym.
|
|
13
|
+
* - observation-conditioned (no injections): a positive restatement grounded
|
|
14
|
+
* in the evidence/observation of the UDE.
|
|
15
|
+
*
|
|
16
|
+
* Idempotency: callers use `needsRestatement()` to skip nodes that already
|
|
17
|
+
* carry a positive statement (an FRT overlay that is non-null, or a base
|
|
18
|
+
* statement that no longer equals the pre-flip UDE text).
|
|
19
|
+
*
|
|
20
|
+
* @module de-restatement
|
|
21
|
+
*/
|
|
22
|
+
import { spawn } from 'node:child_process';
|
|
23
|
+
const DEFAULT_TIMEOUT_MS = 2 * 60 * 1000;
|
|
24
|
+
export const RESTATEMENT_SYSTEM_PROMPT = `You restate an undesirable effect (UDE) from a Goldratt reality tree as the single positive desired effect it becomes once resolved.
|
|
25
|
+
|
|
26
|
+
Rules:
|
|
27
|
+
- Output exactly ONE sentence. No preamble, no list, no trailing commentary, no quotes.
|
|
28
|
+
- The desired effect must read as a concrete positive outcome, not a negation of the problem ("operators can tell..." is weak; "operators see at a glance which focuses are blocked and why" is strong).
|
|
29
|
+
- When resolving injection(s) are provided, the desired effect is the positive state the UDE BECOMES given those injections -- it must carry the resolution the injection delivers, not a naive antonym of the UDE.
|
|
30
|
+
- Keep the subject and domain of the original UDE; only flip its polarity to the resolved, desirable state.`;
|
|
31
|
+
/**
|
|
32
|
+
* The system prompt is fixed for both modes (mode is conveyed by the user
|
|
33
|
+
* message). Exposed as a function to mirror `ai-inspection-runner`'s shape
|
|
34
|
+
* and to keep callers from depending on the constant directly.
|
|
35
|
+
*/
|
|
36
|
+
export function buildRestatementSystemPrompt() {
|
|
37
|
+
return RESTATEMENT_SYSTEM_PROMPT;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Build the user message. Injection-conditioned when `injectionStatements`
|
|
41
|
+
* are present, otherwise observation-conditioned.
|
|
42
|
+
*/
|
|
43
|
+
export function buildRestatementUserMessage(inputs) {
|
|
44
|
+
const parts = [`Undesirable effect (UDE):\n${inputs.udeStatement}`];
|
|
45
|
+
const injections = (inputs.injectionStatements ?? []).filter((s) => s && s.trim() !== '');
|
|
46
|
+
if (injections.length > 0) {
|
|
47
|
+
parts.push(`Resolving injection(s):\n${injections.map((s) => `- ${s}`).join('\n')}`);
|
|
48
|
+
parts.push('Write the single positive desired-effect sentence that this UDE BECOMES once the injection(s) above are in place. It must carry the resolution the injection delivers, not a flat negation of the UDE.');
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
if (inputs.evidence && inputs.evidence.trim() !== '') {
|
|
52
|
+
parts.push(`Evidence / observation:\n${inputs.evidence}`);
|
|
53
|
+
}
|
|
54
|
+
parts.push('Write the single positive desired-effect sentence that states the resolved, desirable version of the UDE above.');
|
|
55
|
+
}
|
|
56
|
+
parts.push('Respond with ONE sentence only.');
|
|
57
|
+
return parts.join('\n\n');
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Idempotency predicate. Returns true when a desired-effect node still needs a
|
|
61
|
+
* positive restatement.
|
|
62
|
+
*
|
|
63
|
+
* - `currentText` is the field a caller would write (frt_statement for the FRT
|
|
64
|
+
* overlay case, statement for the base flip case). Null/blank => needs one.
|
|
65
|
+
* - `originalUdeText`, when supplied (base flip case), is the pre-flip UDE
|
|
66
|
+
* statement. If `currentText` still equals it, the positive text was never
|
|
67
|
+
* authored => needs one.
|
|
68
|
+
*/
|
|
69
|
+
export function needsRestatement(currentText, originalUdeText) {
|
|
70
|
+
if (!currentText || currentText.trim() === '')
|
|
71
|
+
return true;
|
|
72
|
+
if (originalUdeText && currentText.trim() === originalUdeText.trim())
|
|
73
|
+
return true;
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
/** Normalize raw model output to one clean sentence (strip fences/quotes, collapse whitespace). */
|
|
77
|
+
function normalizeSentence(raw) {
|
|
78
|
+
let s = raw.trim();
|
|
79
|
+
// Strip code fences if the model wrapped the answer.
|
|
80
|
+
s = s.replace(/```[a-zA-Z]*\s*/g, '').replace(/```/g, '').trim();
|
|
81
|
+
// Collapse all internal whitespace (incl. newlines) to single spaces.
|
|
82
|
+
s = s.replace(/\s+/g, ' ').trim();
|
|
83
|
+
// Strip a single layer of surrounding quotes/backticks.
|
|
84
|
+
s = s.replace(/^["'`]+/, '').replace(/["'`]+$/, '').trim();
|
|
85
|
+
return s;
|
|
86
|
+
}
|
|
87
|
+
/** Default model invocation: spawn the `claude` CLI in print mode and return stdout. */
|
|
88
|
+
function invokeClaudeCli(systemPrompt, userMessage, opts) {
|
|
89
|
+
const claudeBin = opts.claudeBin ?? 'claude';
|
|
90
|
+
const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
91
|
+
const spawnFn = opts.spawnFn ?? ((cmd, args, sopts) => spawn(cmd, args, sopts));
|
|
92
|
+
const args = [
|
|
93
|
+
'--print',
|
|
94
|
+
'--output-format', 'text',
|
|
95
|
+
'--bare',
|
|
96
|
+
'--no-session-persistence',
|
|
97
|
+
'--system-prompt', systemPrompt,
|
|
98
|
+
];
|
|
99
|
+
return new Promise((resolve, reject) => {
|
|
100
|
+
let child;
|
|
101
|
+
try {
|
|
102
|
+
child = spawnFn(claudeBin, args, { stdio: ['pipe', 'pipe', 'pipe'] });
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
reject(new Error(`de-restatement spawn failed: ${err.message}`));
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
let stdout = '';
|
|
109
|
+
let stderr = '';
|
|
110
|
+
child.stdout?.on('data', (chunk) => { stdout += chunk.toString('utf8'); });
|
|
111
|
+
child.stderr?.on('data', (chunk) => { stderr += chunk.toString('utf8'); });
|
|
112
|
+
const timer = setTimeout(() => {
|
|
113
|
+
try {
|
|
114
|
+
child.kill('SIGKILL');
|
|
115
|
+
}
|
|
116
|
+
catch { /* ignore */ }
|
|
117
|
+
}, timeoutMs);
|
|
118
|
+
child.on('error', (err) => {
|
|
119
|
+
clearTimeout(timer);
|
|
120
|
+
reject(new Error(`de-restatement spawn error: ${err.message}`));
|
|
121
|
+
});
|
|
122
|
+
child.on('close', (code) => {
|
|
123
|
+
clearTimeout(timer);
|
|
124
|
+
if (code !== 0) {
|
|
125
|
+
reject(new Error(`de-restatement exited ${code}: ${stderr.slice(-2000)}`));
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
resolve(stdout);
|
|
129
|
+
});
|
|
130
|
+
try {
|
|
131
|
+
child.stdin?.write(userMessage);
|
|
132
|
+
child.stdin?.end();
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
clearTimeout(timer);
|
|
136
|
+
reject(new Error(`de-restatement stdin write failed: ${err.message}`));
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Author the positive desired-effect restatement for a UDE.
|
|
142
|
+
*
|
|
143
|
+
* Returns a single positive sentence. Throws on model-invocation failure;
|
|
144
|
+
* callers (the at-source flip path, the reconciliation backstop) catch and
|
|
145
|
+
* skip so a single failure never aborts the surrounding loop.
|
|
146
|
+
*/
|
|
147
|
+
export async function authorRestatement(inputs, opts = {}) {
|
|
148
|
+
const systemPrompt = buildRestatementSystemPrompt();
|
|
149
|
+
const userMessage = buildRestatementUserMessage(inputs);
|
|
150
|
+
const invoke = opts.invokeModel ?? ((sys, msg) => invokeClaudeCli(sys, msg, opts));
|
|
151
|
+
const raw = await invoke(systemPrompt, userMessage);
|
|
152
|
+
const sentence = normalizeSentence(raw);
|
|
153
|
+
if (sentence === '') {
|
|
154
|
+
throw new Error('de-restatement produced empty output');
|
|
155
|
+
}
|
|
156
|
+
return sentence;
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=de-restatement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"de-restatement.js","sourceRoot":"","sources":["../src/de-restatement.ts"],"names":[],"mappings":"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"}
|
|
@@ -164,6 +164,31 @@ export declare function resolveFocusStageName(input: {
|
|
|
164
164
|
}>;
|
|
165
165
|
reviewRequestedAt: string | null;
|
|
166
166
|
}): string;
|
|
167
|
+
/**
|
|
168
|
+
* Decide whether to re-fire a focus's review-stage directive even though the
|
|
169
|
+
* edge-trigger (lastProcessedStages) already marked the stage processed.
|
|
170
|
+
*
|
|
171
|
+
* The edge-trigger fires a stage directive exactly once per stage entry. For
|
|
172
|
+
* the review stage that is normally correct -- a clean review completes, clears
|
|
173
|
+
* review_requested_at, and the focus leaves the review phase. But if the review
|
|
174
|
+
* team never spawned or was killed (e.g. a lifecycle SIGTERM) before routing,
|
|
175
|
+
* the focus stays in the review stage with review_requested_at still set and the
|
|
176
|
+
* directive never re-fires: a silent stuck focus (the founding bug of this focus).
|
|
177
|
+
*
|
|
178
|
+
* A focus STILL in the review stage with review_requested_at set is provably
|
|
179
|
+
* stranded -- any completed review clears review_requested_at and moves the
|
|
180
|
+
* phase. So when no review team is running, re-firing the directive is the
|
|
181
|
+
* self-healing recovery: it respawns the review team. Once a team is running the
|
|
182
|
+
* active-team guard suppresses the re-fire, and a successful review auto-approves
|
|
183
|
+
* and leaves the stage -- so the re-fire is bounded, not a per-poll spin.
|
|
184
|
+
*
|
|
185
|
+
* Pure and exported for unit testing.
|
|
186
|
+
*/
|
|
187
|
+
export declare function shouldRefireStrandedReview(input: {
|
|
188
|
+
stageName: string | undefined;
|
|
189
|
+
reviewRequestedAt: string | null;
|
|
190
|
+
hasActiveTeam: boolean;
|
|
191
|
+
}): boolean;
|
|
167
192
|
/**
|
|
168
193
|
* Synchronize `product_focuses.current_workflow_stage_id` with the focus's
|
|
169
194
|
* authoritative stage. The authoritative stage is taken from `focus.stage`
|