@telora/daemon 0.24.55 → 0.24.56
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 +5 -3
- package/dist/prd/controller-shared.d.ts +27 -31
- package/dist/prd/controller-shared.d.ts.map +1 -1
- package/dist/prd/controller-shared.js +26 -41
- package/dist/prd/controller-shared.js.map +1 -1
- package/dist/queries/tower/tower-state.d.ts +2 -0
- package/dist/queries/tower/tower-state.d.ts.map +1 -1
- package/dist/queries/tower/tower-state.js +6 -0
- package/dist/queries/tower/tower-state.js.map +1 -1
- package/dist/tower/focus-landed.d.ts +32 -1
- package/dist/tower/focus-landed.d.ts.map +1 -1
- package/dist/tower/focus-landed.js +67 -12
- package/dist/tower/focus-landed.js.map +1 -1
- package/dist/tower/tower-graph.d.ts +6 -2
- package/dist/tower/tower-graph.d.ts.map +1 -1
- package/dist/tower/tower-graph.js +8 -5
- package/dist/tower/tower-graph.js.map +1 -1
- package/dist/tower/tower-verdicts.d.ts.map +1 -1
- package/dist/tower/tower-verdicts.js +2 -1
- package/dist/tower/tower-verdicts.js.map +1 -1
- package/docs/runbook-tower.md +26 -5
- package/package.json +2 -2
package/build-info.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"commitSha": "
|
|
3
|
-
"builtAt": "2026-10-
|
|
2
|
+
"commitSha": "d06a52391",
|
|
3
|
+
"builtAt": "2026-10-27T15:25:03.204Z",
|
|
4
4
|
"expectedMigrations": [
|
|
5
5
|
"20250829113330_create_org_nodes_table.sql",
|
|
6
6
|
"20250829113402_fix_function_security_search_path.sql",
|
|
@@ -909,6 +909,8 @@
|
|
|
909
909
|
"20261026112934_qa_fail_reopens_prd_overcome.sql",
|
|
910
910
|
"20261026113712_qa_fail_reopens_done_prd.sql",
|
|
911
911
|
"20261026120918_qa_failed_overcome_clear_guard.sql",
|
|
912
|
-
"20261026120922_done_prd_play_role_recovered.sql"
|
|
912
|
+
"20261026120922_done_prd_play_role_recovered.sql",
|
|
913
|
+
"20261027121340_in_progress_request_answered_without_focus_is_delivered.sql",
|
|
914
|
+
"20261027125510_focus_tower_edges_refuse_same_prd_depends_on.sql"
|
|
913
915
|
]
|
|
914
916
|
}
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared PRD-controller types + pure helpers.
|
|
3
|
+
*
|
|
4
|
+
* The PrdControllerDeps injection interface, the tick result shapes, the pure
|
|
5
|
+
* completion/arm-role helpers, and the done-sweep constants: the LEAF of the
|
|
6
|
+
* controller family, so
|
|
7
|
+
* prd/done-sweep.ts and prd/controller.ts can both depend on these without a
|
|
8
|
+
* cycle (this module imports neither).
|
|
9
|
+
*
|
|
10
|
+
* History: docs/daemon/history-platform.md (prd/controller-shared.ts).
|
|
11
|
+
*/
|
|
12
|
+
import { type FocusQaStanding } from '../tower/focus-landed.js';
|
|
1
13
|
import type { FocusBranchContainment } from '../git/focus-branch-containment.js';
|
|
2
14
|
import type { Prd, PrtNode, PrtEdge, Pathway } from '../queries/prd/prd.js';
|
|
3
15
|
import type { FileEscalationInput } from '../nexus/file-escalation.js';
|
|
@@ -41,43 +53,27 @@ export declare const DONE_SWEEP_MAX_ATTEMPTS = 3;
|
|
|
41
53
|
export declare function resolveArmRoleIdFromPrd(prd: Prd): string | null;
|
|
42
54
|
/**
|
|
43
55
|
* Compute the set of focus ids that have LANDED -- the completion bridge's
|
|
44
|
-
* signal,
|
|
56
|
+
* signal, judged by the SAME rule the tower holds a depends_on successor on
|
|
45
57
|
* (tower/focus-landed.ts judgeFocusLanded): at least one delivery, every
|
|
46
|
-
* non-cancelled delivery done, and the focus branch
|
|
47
|
-
* A focus with zero deliveries (freshly materialized,
|
|
48
|
-
* a focus whose containment git could not answer is
|
|
58
|
+
* non-cancelled delivery done, no failed or unreadable QA, and the focus branch
|
|
59
|
+
* contained in integration. A focus with zero deliveries (freshly materialized,
|
|
60
|
+
* never run) is not landed; a focus whose containment git could not answer is
|
|
61
|
+
* not counted this tick.
|
|
49
62
|
*
|
|
50
|
-
* `containment` is the focus's branch containment
|
|
51
|
-
*
|
|
52
|
-
* PURE.
|
|
63
|
+
* `containment` is the focus's branch containment and `qa` its QA standing,
|
|
64
|
+
* each read by the caller for every focus it passes; a focus missing from `qa`
|
|
65
|
+
* carries no QA report ('not_reported'). PURE.
|
|
53
66
|
*/
|
|
54
67
|
export declare function computeCompletedFocusIds(deliveries: Array<{
|
|
55
68
|
focusId: string;
|
|
56
69
|
executionStatus: string;
|
|
57
|
-
}>, containment: ReadonlyMap<string, FocusBranchContainment>): Set<string>;
|
|
58
|
-
/**
|
|
59
|
-
* Whether a QA read holds a focus OUT of the landed set: its QA state is
|
|
60
|
-
* failed, or could not be read (fail closed -- a failed verdict must never be
|
|
61
|
-
* overwritten on an unproven read). PURE.
|
|
62
|
-
*
|
|
63
|
-
* WHY QA-FAILED IS NOT LANDED. A person's failed verdict leaves every delivery
|
|
64
|
-
* done and the branch merged -- exactly the landed facts -- so without this the
|
|
65
|
-
* completion bridge would re-clear the overcome the verdict reopened, and the
|
|
66
|
-
* limbo self-heal would finalize the focus straight back to complete over it.
|
|
67
|
-
* qa_state stays failed until the team armed AFTER the fail finishes (the
|
|
68
|
-
* enter_focus_qa_on_team_finish trigger moves it to awaiting), so "work
|
|
69
|
-
* finished after the failed verdict" is precisely qa_state leaving failed; from
|
|
70
|
-
* then on the focus lands, clears and finalizes like any other.
|
|
71
|
-
* QA still gates nothing on the pass side: awaiting, passed and never-QA'd foci
|
|
72
|
-
* land on their delivery and branch facts alone (docs/DECISIONS.md 2026-10-26).
|
|
73
|
-
*/
|
|
74
|
-
export declare function qaHoldsFocusUnlanded(read: FocusQaStandingRead): boolean;
|
|
70
|
+
}>, containment: ReadonlyMap<string, FocusBranchContainment>, qa: ReadonlyMap<string, FocusQaStanding>): Set<string>;
|
|
75
71
|
/**
|
|
76
|
-
* Load the deliveries and branch containment of each focus and
|
|
77
|
-
* that have LANDED (computeCompletedFocusIds).
|
|
78
|
-
* focus whose deliveries could have landed,
|
|
79
|
-
*
|
|
80
|
-
*
|
|
72
|
+
* Load the deliveries, QA standing and branch containment of each focus and
|
|
73
|
+
* return those that have LANDED (computeCompletedFocusIds). QA is read only for
|
|
74
|
+
* a focus whose deliveries could have landed, and containment only for one whose
|
|
75
|
+
* deliveries and QA could have, so a running focus costs no QA read and no git.
|
|
76
|
+
* With no QA reader bound the focus's QA is 'not_reported'.
|
|
81
77
|
*/
|
|
82
78
|
export declare function loadLandedFocusIds(focusIds: readonly string[], deps: Pick<PrdControllerDeps, 'loadFocusDeliveries' | 'readFocusBranchContainment' | 'loadFocusQa'>): Promise<Set<string>>;
|
|
83
79
|
/**
|
|
@@ -278,7 +274,7 @@ export interface PrdControllerDeps {
|
|
|
278
274
|
loadFocusOperatorStop?: (focusId: string) => Promise<string | null>;
|
|
279
275
|
/**
|
|
280
276
|
* The focus's human QA standing (product-api focus_qa_get); never throws.
|
|
281
|
-
* A QA-failed focus is not landed (
|
|
277
|
+
* A QA-failed focus is not landed (tower/focus-landed.ts), is armed by the
|
|
282
278
|
* frontier only once work has been scoped since the failed verdict, and its
|
|
283
279
|
* scoping run is handed the cases the person did not pass
|
|
284
280
|
* (prd/frontier-arming.ts). Optional; bound at the composition root. When
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller-shared.d.ts","sourceRoot":"","sources":["../../src/prd/controller-shared.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"controller-shared.d.ts","sourceRoot":"","sources":["../../src/prd/controller-shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,8 +16,7 @@
|
|
|
16
16
|
*
|
|
17
17
|
* History: docs/daemon/history-platform.md (prd/controller-shared.ts).
|
|
18
18
|
*/
|
|
19
|
-
import { judgeFocusLanded } from '../tower/focus-landed.js';
|
|
20
|
-
import { QA_STATE } from '@telora/daemon-core';
|
|
19
|
+
import { judgeFocusLanded, qaStandingOfRead } from '../tower/focus-landed.js';
|
|
21
20
|
/**
|
|
22
21
|
* Steward cadence: the minimum interval between proactive steward monitoring
|
|
23
22
|
* runs for a Played PRD -- the "runs on a cadence" path of the AC. 15 minutes
|
|
@@ -55,17 +54,18 @@ export function resolveArmRoleIdFromPrd(prd) {
|
|
|
55
54
|
}
|
|
56
55
|
/**
|
|
57
56
|
* Compute the set of focus ids that have LANDED -- the completion bridge's
|
|
58
|
-
* signal,
|
|
57
|
+
* signal, judged by the SAME rule the tower holds a depends_on successor on
|
|
59
58
|
* (tower/focus-landed.ts judgeFocusLanded): at least one delivery, every
|
|
60
|
-
* non-cancelled delivery done, and the focus branch
|
|
61
|
-
* A focus with zero deliveries (freshly materialized,
|
|
62
|
-
* a focus whose containment git could not answer is
|
|
59
|
+
* non-cancelled delivery done, no failed or unreadable QA, and the focus branch
|
|
60
|
+
* contained in integration. A focus with zero deliveries (freshly materialized,
|
|
61
|
+
* never run) is not landed; a focus whose containment git could not answer is
|
|
62
|
+
* not counted this tick.
|
|
63
63
|
*
|
|
64
|
-
* `containment` is the focus's branch containment
|
|
65
|
-
*
|
|
66
|
-
* PURE.
|
|
64
|
+
* `containment` is the focus's branch containment and `qa` its QA standing,
|
|
65
|
+
* each read by the caller for every focus it passes; a focus missing from `qa`
|
|
66
|
+
* carries no QA report ('not_reported'). PURE.
|
|
67
67
|
*/
|
|
68
|
-
export function computeCompletedFocusIds(deliveries, containment) {
|
|
68
|
+
export function computeCompletedFocusIds(deliveries, containment, qa) {
|
|
69
69
|
const byFocus = new Map();
|
|
70
70
|
for (const d of deliveries) {
|
|
71
71
|
if (!d.focusId) {
|
|
@@ -77,50 +77,35 @@ export function computeCompletedFocusIds(deliveries, containment) {
|
|
|
77
77
|
}
|
|
78
78
|
const complete = new Set();
|
|
79
79
|
for (const [focusId, statuses] of byFocus) {
|
|
80
|
-
|
|
80
|
+
const landed = judgeFocusLanded(statuses, containment.get(focusId) ?? 'unknown', qa.get(focusId) ?? 'not_reported');
|
|
81
|
+
if (landed === 'landed')
|
|
81
82
|
complete.add(focusId);
|
|
82
|
-
}
|
|
83
83
|
}
|
|
84
84
|
return complete;
|
|
85
85
|
}
|
|
86
86
|
/**
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
* done and the branch merged -- exactly the landed facts -- so without this the
|
|
93
|
-
* completion bridge would re-clear the overcome the verdict reopened, and the
|
|
94
|
-
* limbo self-heal would finalize the focus straight back to complete over it.
|
|
95
|
-
* qa_state stays failed until the team armed AFTER the fail finishes (the
|
|
96
|
-
* enter_focus_qa_on_team_finish trigger moves it to awaiting), so "work
|
|
97
|
-
* finished after the failed verdict" is precisely qa_state leaving failed; from
|
|
98
|
-
* then on the focus lands, clears and finalizes like any other.
|
|
99
|
-
* QA still gates nothing on the pass side: awaiting, passed and never-QA'd foci
|
|
100
|
-
* land on their delivery and branch facts alone (docs/DECISIONS.md 2026-10-26).
|
|
101
|
-
*/
|
|
102
|
-
export function qaHoldsFocusUnlanded(read) {
|
|
103
|
-
return read.kind === 'unreadable' || read.state === QA_STATE.FAILED;
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Load the deliveries and branch containment of each focus and return those
|
|
107
|
-
* that have LANDED (computeCompletedFocusIds). Containment is read only for a
|
|
108
|
-
* focus whose deliveries could have landed, so a running focus costs no git.
|
|
109
|
-
* A focus a person failed at QA is not landed (qaHoldsFocusUnlanded); its QA is
|
|
110
|
-
* read only once its deliveries could have landed.
|
|
87
|
+
* Load the deliveries, QA standing and branch containment of each focus and
|
|
88
|
+
* return those that have LANDED (computeCompletedFocusIds). QA is read only for
|
|
89
|
+
* a focus whose deliveries could have landed, and containment only for one whose
|
|
90
|
+
* deliveries and QA could have, so a running focus costs no QA read and no git.
|
|
91
|
+
* With no QA reader bound the focus's QA is 'not_reported'.
|
|
111
92
|
*/
|
|
112
93
|
export async function loadLandedFocusIds(focusIds, deps) {
|
|
113
94
|
const focusDeliveries = [];
|
|
114
95
|
const containment = new Map();
|
|
96
|
+
const qa = new Map();
|
|
115
97
|
for (const fid of focusIds) {
|
|
116
98
|
const ds = await deps.loadFocusDeliveries(fid);
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
99
|
+
const statuses = ds.map((d) => d.executionStatus);
|
|
100
|
+
if (judgeFocusLanded(statuses, 'contained', 'not_reported') === 'landed') {
|
|
101
|
+
const standing = deps.loadFocusQa ? qaStandingOfRead(await deps.loadFocusQa(fid)) : 'not_reported';
|
|
102
|
+
qa.set(fid, standing);
|
|
103
|
+
if (judgeFocusLanded(statuses, 'contained', standing) === 'landed') {
|
|
104
|
+
containment.set(fid, await deps.readFocusBranchContainment(fid));
|
|
105
|
+
}
|
|
121
106
|
}
|
|
122
107
|
focusDeliveries.push(...ds);
|
|
123
108
|
}
|
|
124
|
-
return computeCompletedFocusIds(focusDeliveries, containment);
|
|
109
|
+
return computeCompletedFocusIds(focusDeliveries, containment, qa);
|
|
125
110
|
}
|
|
126
111
|
//# sourceMappingURL=controller-shared.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller-shared.js","sourceRoot":"","sources":["../../src/prd/controller-shared.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,uEAAuE;AACvE,4EAA4E;AAC5E,qEAAqE;AACrE,8DAA8D;AAC9D,yGAAyG;AACzG,gBAAgB;AAEhB;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"controller-shared.js","sourceRoot":"","sources":["../../src/prd/controller-shared.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,uEAAuE;AACvE,4EAA4E;AAC5E,qEAAqE;AACrE,8DAA8D;AAC9D,yGAAyG;AACzG,gBAAgB;AAEhB;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAwB,MAAM,0BAA0B,CAAC;AAUpG;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,0BAA0B,CAAC;AAEnE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC;AAEzC;;;;;;;;GAQG;AACH,MAAM,UAAU,uBAAuB,CAAC,GAAQ;IAC9C,OAAO,GAAG,CAAC,mBAAmB,IAAI,IAAI,CAAC;AACzC,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,wBAAwB,CACtC,UAA+D,EAC/D,WAAwD,EACxD,EAAwC;IAExC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC5C,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;YACf,SAAS;QACX,CAAC;QACD,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAC9C,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACnC,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IACnC,KAAK,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,OAAO,EAAE,CAAC;QAC1C,MAAM,MAAM,GAAG,gBAAgB,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,SAAS,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,cAAc,CAAC,CAAC;QACpH,IAAI,MAAM,KAAK,QAAQ;YAAE,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,QAA2B,EAC3B,IAAmG;IAEnG,MAAM,eAAe,GAAwD,EAAE,CAAC;IAChF,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkC,CAAC;IAC9D,MAAM,EAAE,GAAG,IAAI,GAAG,EAA2B,CAAC;IAC9C,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;QAC/C,MAAM,QAAQ,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;QAClD,IAAI,gBAAgB,CAAC,QAAQ,EAAE,WAAW,EAAE,cAAc,CAAC,KAAK,QAAQ,EAAE,CAAC;YACzE,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,gBAAgB,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC;YACnG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;YACtB,IAAI,gBAAgB,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC,KAAK,QAAQ,EAAE,CAAC;gBACnE,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,IAAI,CAAC,0BAA0B,CAAC,GAAG,CAAC,CAAC,CAAC;YACnE,CAAC;QACH,CAAC;QACD,eAAe,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,wBAAwB,CAAC,eAAe,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC;AACpE,CAAC"}
|
|
@@ -33,6 +33,8 @@ declare const TowerStateSchema: z.ZodObject<{
|
|
|
33
33
|
branchName: z.ZodDefault<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
|
|
34
34
|
mergeCommitShas: z.ZodPipe<z.ZodDefault<z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString>>>>, z.ZodTransform<readonly string[] | "unknown", string[] | null>>;
|
|
35
35
|
deliveryStatuses: z.ZodArray<z.ZodString>;
|
|
36
|
+
qaState: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
37
|
+
qaReadFailed: z.ZodOptional<z.ZodBoolean>;
|
|
36
38
|
}, z.core.$loose>>>>;
|
|
37
39
|
}, z.core.$loose>;
|
|
38
40
|
/** One product's tower inputs: its limit and its armed, active foci in rank order. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tower-state.d.ts","sourceRoot":"","sources":["../../../src/queries/tower/tower-state.ts"],"names":[],"mappings":"AAKA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"tower-state.d.ts","sourceRoot":"","sources":["../../../src/queries/tower/tower-state.ts"],"names":[],"mappings":"AAKA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAoCxB,QAAA,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAON,CAAC;AAEjB,sFAAsF;AACtF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEjE,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAEjF;AAOD,yFAAyF;AACzF,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,aAAa,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,GACnE,OAAO,CAAC,IAAI,CAAC,CAQf;AAUD,+FAA+F;AAC/F,MAAM,WAAW,gBAAgB;IAC/B,yDAAyD;IACzD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,kFAAkF;IAClF,eAAe,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;CAChD;AAED,kEAAkE;AAClE,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAI1G"}
|
|
@@ -34,6 +34,12 @@ const TowerGraphFocusSchema = z.object({
|
|
|
34
34
|
mergeCommitShas: z.array(z.string()).nullable().optional().default(null)
|
|
35
35
|
.transform((v) => v ?? 'unknown'),
|
|
36
36
|
deliveryStatuses: z.array(z.string()),
|
|
37
|
+
// product_focuses.qa_state (null = never QA'd), kept raw: ABSENT (undefined)
|
|
38
|
+
// is an API older than the field, which is not the same answer as null.
|
|
39
|
+
// qaReadFailed = the API's QA read failed (unreadable: holds). The LANDED
|
|
40
|
+
// rule's input is derived from both by tower/focus-landed.ts qaStandingOfWire.
|
|
41
|
+
qaState: z.string().nullable().optional(),
|
|
42
|
+
qaReadFailed: z.boolean().optional(),
|
|
37
43
|
}).passthrough();
|
|
38
44
|
const TowerStateSchema = z.object({
|
|
39
45
|
productId: z.string(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tower-state.js","sourceRoot":"","sources":["../../../src/queries/tower/tower-state.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,2DAA2D;AAC3D,4DAA4D;AAC5D,gBAAgB;AAEhB;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEpE,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAC/D,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;CACnD,CAAC,CAAC,WAAW,EAAE,CAAC;AAEjB,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IACxC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;CACrB,CAAC,CAAC,WAAW,EAAE,CAAC;AAEjB,yFAAyF;AACzF,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAC1D,8EAA8E;IAC9E,eAAe,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;SACrE,SAAS,CAAC,CAAC,CAAC,EAAiC,EAAE,CAAC,CAAC,IAAI,SAAS,CAAC;IAClE,gBAAgB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"tower-state.js","sourceRoot":"","sources":["../../../src/queries/tower/tower-state.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,35 @@
|
|
|
1
1
|
import type { FocusBranchContainment } from '../git/focus-branch-containment.js';
|
|
2
|
+
import type { FocusQaStandingRead } from '../queries/qa-packets/focus-qa-failure.js';
|
|
2
3
|
export type FocusLanded = 'landed' | 'not_landed' | 'unknown';
|
|
3
|
-
|
|
4
|
+
/**
|
|
5
|
+
* A focus's QA standing as the LANDED rule reads it: `failed` (a person failed
|
|
6
|
+
* it), `unreadable` (the read failed, or answered a state this daemon does not
|
|
7
|
+
* know), `not_failed` (awaiting, passed, or never QA'd), `not_reported` (the
|
|
8
|
+
* reader carries no QA; see the header).
|
|
9
|
+
*/
|
|
10
|
+
export type FocusQaStanding = 'failed' | 'unreadable' | 'not_failed' | 'not_reported';
|
|
11
|
+
/** Whether a QA standing holds the focus out of landed. PURE. */
|
|
12
|
+
export declare function qaHoldsUnlanded(qa: FocusQaStanding): boolean;
|
|
13
|
+
/** The LANDED rule's QA input from a stored qa_state (null = never QA'd). An unknown value is unreadable. PURE. */
|
|
14
|
+
export declare function qaStandingOfState(state: string | null): FocusQaStanding;
|
|
15
|
+
/**
|
|
16
|
+
* The LANDED rule's QA input from daemon_get_tower_state's graph focus.
|
|
17
|
+
* `qaReadFailed` is the API saying its QA read failed: 'unreadable', which holds
|
|
18
|
+
* the successor exactly as the PRD frontier holds on an unreadable read. The API
|
|
19
|
+
* reads QA apart from the rest of the graph so that failure reaches this rule
|
|
20
|
+
* instead of failing the whole graph read (which the tower fails open on).
|
|
21
|
+
* An ABSENT qaState (and no qaReadFailed) is an API older than the field:
|
|
22
|
+
* 'not_reported', judged on delivery and branch facts alone -- the tower's rule
|
|
23
|
+
* before QA was an input -- so a new daemon against an old API holds no
|
|
24
|
+
* successor it did not hold before. Reading absent as unreadable instead would
|
|
25
|
+
* hold every depends_on successor in the product until the API ships. A value
|
|
26
|
+
* this daemon does not know is 'unreadable'. PURE.
|
|
27
|
+
*/
|
|
28
|
+
export declare function qaStandingOfWire(focus: {
|
|
29
|
+
qaState?: string | null | undefined;
|
|
30
|
+
qaReadFailed?: boolean | undefined;
|
|
31
|
+
}): FocusQaStanding;
|
|
32
|
+
/** The LANDED rule's QA input from the PRD controller's focus_qa_get read. PURE. */
|
|
33
|
+
export declare function qaStandingOfRead(read: FocusQaStandingRead): FocusQaStanding;
|
|
34
|
+
export declare function judgeFocusLanded(deliveryStatuses: readonly string[], branch: FocusBranchContainment, qa: FocusQaStanding): FocusLanded;
|
|
4
35
|
//# sourceMappingURL=focus-landed.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"focus-landed.d.ts","sourceRoot":"","sources":["../../src/tower/focus-landed.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"focus-landed.d.ts","sourceRoot":"","sources":["../../src/tower/focus-landed.ts"],"names":[],"mappings":"AA+CA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AACjF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2CAA2C,CAAC;AAErF,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,YAAY,GAAG,SAAS,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,YAAY,GAAG,YAAY,GAAG,cAAc,CAAC;AAEtF,iEAAiE;AACjE,wBAAgB,eAAe,CAAC,EAAE,EAAE,eAAe,GAAG,OAAO,CAE5D;AAED,mHAAmH;AACnH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,eAAe,CAIvE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAAE,GAAG,eAAe,CAGpI;AAED,oFAAoF;AACpF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,mBAAmB,GAAG,eAAe,CAE3E;AAED,wBAAgB,gBAAgB,CAC9B,gBAAgB,EAAE,SAAS,MAAM,EAAE,EACnC,MAAM,EAAE,sBAAsB,EAC9B,EAAE,EAAE,eAAe,GAClB,WAAW,CAeb"}
|
|
@@ -1,30 +1,83 @@
|
|
|
1
1
|
// PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
|
|
2
|
-
// Pinned by: packages/daemon/src/
|
|
2
|
+
// Pinned by: packages/daemon/src/prd/prd-controller-qa-failed.test.ts,
|
|
3
|
+
// packages/daemon/src/tower/focus-landed.test.ts
|
|
3
4
|
// PINNED-BY-END
|
|
4
5
|
/**
|
|
5
6
|
* LANDED: the ONE definition of "this focus's work has landed", judged by the
|
|
6
|
-
* daemon with no human close. Shared by the tower (a
|
|
7
|
-
* until its predecessor has landed) and the PRD
|
|
8
|
-
* (prd/controller-shared.ts
|
|
9
|
-
* disagree about whether a focus is finished.
|
|
7
|
+
* daemon with no human close. Shared by the tower (tower/tower-graph.ts: a
|
|
8
|
+
* depends_on successor waits until its predecessor has landed) and the PRD
|
|
9
|
+
* frontier's completion signal (prd/controller-shared.ts loadLandedFocusIds),
|
|
10
|
+
* so the two can never disagree about whether a focus is finished. Each caller
|
|
11
|
+
* supplies the same three inputs; neither applies a check of its own.
|
|
10
12
|
*
|
|
11
13
|
* A focus has LANDED when
|
|
12
14
|
* 1. it has at least one delivery, and
|
|
13
15
|
* 2. every non-cancelled delivery is done, at least one of them (a focus whose
|
|
14
16
|
* every delivery was cancelled landed nothing), and
|
|
15
|
-
* 3.
|
|
17
|
+
* 3. no person has failed it at QA, and its QA could be read: a failed verdict
|
|
18
|
+
* leaves every delivery done and the branch merged -- exactly the landed
|
|
19
|
+
* facts -- so without this the rework the verdict sent the focus back for
|
|
20
|
+
* would be built on, by a tower successor or a PRD successor alike
|
|
21
|
+
* (the ruling: docs/DECISIONS.md, "A failed QA on a PRD focus sends it
|
|
22
|
+
* back through the PRD"). qa_state stays failed until the team
|
|
23
|
+
* armed after the fail finishes; from then on the focus lands like any
|
|
24
|
+
* other. QA gates nothing on the pass side: awaiting, passed and never-QA'd
|
|
25
|
+
* foci land on their delivery and branch facts alone. And
|
|
26
|
+
* 4. its branch tip is contained in the integration branch -- or the branch is
|
|
16
27
|
* gone AND the focus's merge record names a merge commit integration
|
|
17
28
|
* contains (the daemon removes a branch only after merging it, and records
|
|
18
29
|
* the merge; git/focus-branch-containment.ts). A gone branch with no such
|
|
19
30
|
* record is unproven: unknown.
|
|
20
31
|
*
|
|
21
|
-
* NOT_LANDED when any of those is definitely false
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
32
|
+
* NOT_LANDED when any of those is definitely false -- an unreadable QA included
|
|
33
|
+
* (fail closed: a failed verdict must never be overwritten on an unproven read).
|
|
34
|
+
* UNKNOWN when 1-3 hold but git could not answer 4: never read as landed and
|
|
35
|
+
* never as not landed -- the tower leaves the dependent focus's verdict
|
|
36
|
+
* unavailable (fail open), and the PRD frontier does not clear the obstacle
|
|
37
|
+
* this tick.
|
|
38
|
+
*
|
|
39
|
+
* NOT_REPORTED is not a QA answer: it is a reader that carries no QA at all (an
|
|
40
|
+
* API older than the field, or a PRD controller with no QA reader bound), and
|
|
41
|
+
* the rule then judges 1, 2 and 4 alone -- exactly what it judged before QA was
|
|
42
|
+
* an input. It is distinct from UNREADABLE (a read that was made and failed),
|
|
43
|
+
* which holds.
|
|
44
|
+
*/
|
|
45
|
+
import { DELIVERY_STATUS, QA_STATE } from '@telora/daemon-core';
|
|
46
|
+
/** Whether a QA standing holds the focus out of landed. PURE. */
|
|
47
|
+
export function qaHoldsUnlanded(qa) {
|
|
48
|
+
return qa === 'failed' || qa === 'unreadable';
|
|
49
|
+
}
|
|
50
|
+
/** The LANDED rule's QA input from a stored qa_state (null = never QA'd). An unknown value is unreadable. PURE. */
|
|
51
|
+
export function qaStandingOfState(state) {
|
|
52
|
+
if (state === null || state === QA_STATE.AWAITING || state === QA_STATE.PASSED)
|
|
53
|
+
return 'not_failed';
|
|
54
|
+
if (state === QA_STATE.FAILED)
|
|
55
|
+
return 'failed';
|
|
56
|
+
return 'unreadable';
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* The LANDED rule's QA input from daemon_get_tower_state's graph focus.
|
|
60
|
+
* `qaReadFailed` is the API saying its QA read failed: 'unreadable', which holds
|
|
61
|
+
* the successor exactly as the PRD frontier holds on an unreadable read. The API
|
|
62
|
+
* reads QA apart from the rest of the graph so that failure reaches this rule
|
|
63
|
+
* instead of failing the whole graph read (which the tower fails open on).
|
|
64
|
+
* An ABSENT qaState (and no qaReadFailed) is an API older than the field:
|
|
65
|
+
* 'not_reported', judged on delivery and branch facts alone -- the tower's rule
|
|
66
|
+
* before QA was an input -- so a new daemon against an old API holds no
|
|
67
|
+
* successor it did not hold before. Reading absent as unreadable instead would
|
|
68
|
+
* hold every depends_on successor in the product until the API ships. A value
|
|
69
|
+
* this daemon does not know is 'unreadable'. PURE.
|
|
25
70
|
*/
|
|
26
|
-
|
|
27
|
-
|
|
71
|
+
export function qaStandingOfWire(focus) {
|
|
72
|
+
if (focus.qaReadFailed === true)
|
|
73
|
+
return 'unreadable';
|
|
74
|
+
return focus.qaState === undefined ? 'not_reported' : qaStandingOfState(focus.qaState);
|
|
75
|
+
}
|
|
76
|
+
/** The LANDED rule's QA input from the PRD controller's focus_qa_get read. PURE. */
|
|
77
|
+
export function qaStandingOfRead(read) {
|
|
78
|
+
return read.kind === 'unreadable' ? 'unreadable' : qaStandingOfState(read.state);
|
|
79
|
+
}
|
|
80
|
+
export function judgeFocusLanded(deliveryStatuses, branch, qa) {
|
|
28
81
|
if (deliveryStatuses.length === 0)
|
|
29
82
|
return 'not_landed';
|
|
30
83
|
const live = deliveryStatuses.filter((s) => s !== DELIVERY_STATUS.CANCELLED);
|
|
@@ -32,6 +85,8 @@ export function judgeFocusLanded(deliveryStatuses, branch) {
|
|
|
32
85
|
return 'not_landed';
|
|
33
86
|
if (!live.every((s) => s === DELIVERY_STATUS.DONE))
|
|
34
87
|
return 'not_landed';
|
|
88
|
+
if (qaHoldsUnlanded(qa))
|
|
89
|
+
return 'not_landed';
|
|
35
90
|
switch (branch) {
|
|
36
91
|
case 'contained':
|
|
37
92
|
case 'merged_removed':
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"focus-landed.js","sourceRoot":"","sources":["../../src/tower/focus-landed.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,
|
|
1
|
+
{"version":3,"file":"focus-landed.js","sourceRoot":"","sources":["../../src/tower/focus-landed.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,uEAAuE;AACvE,mDAAmD;AACnD,gBAAgB;AAEhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAchE,iEAAiE;AACjE,MAAM,UAAU,eAAe,CAAC,EAAmB;IACjD,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,KAAK,YAAY,CAAC;AAChD,CAAC;AAED,mHAAmH;AACnH,MAAM,UAAU,iBAAiB,CAAC,KAAoB;IACpD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,QAAQ,CAAC,QAAQ,IAAI,KAAK,KAAK,QAAQ,CAAC,MAAM;QAAE,OAAO,YAAY,CAAC;IACpG,IAAI,KAAK,KAAK,QAAQ,CAAC,MAAM;QAAE,OAAO,QAAQ,CAAC;IAC/C,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAkF;IACjH,IAAI,KAAK,CAAC,YAAY,KAAK,IAAI;QAAE,OAAO,YAAY,CAAC;IACrD,OAAO,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,iBAAiB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AACzF,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,gBAAgB,CAAC,IAAyB;IACxD,OAAO,IAAI,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACnF,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,gBAAmC,EACnC,MAA8B,EAC9B,EAAmB;IAEnB,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,YAAY,CAAC;IACvD,MAAM,IAAI,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,eAAe,CAAC,SAAS,CAAC,CAAC;IAC7E,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,YAAY,CAAC;IAC3C,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,eAAe,CAAC,IAAI,CAAC;QAAE,OAAO,YAAY,CAAC;IACxE,IAAI,eAAe,CAAC,EAAE,CAAC;QAAE,OAAO,YAAY,CAAC;IAC7C,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,WAAW,CAAC;QACjB,KAAK,gBAAgB;YACnB,OAAO,QAAQ,CAAC;QAClB,KAAK,eAAe;YAClB,OAAO,YAAY,CAAC;QACtB,KAAK,SAAS;YACZ,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC"}
|
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
* which other foci, and which cannot be judged at all.
|
|
5
5
|
*
|
|
6
6
|
* depends_on (from -> to): `to` waits until `from` has LANDED
|
|
7
|
-
* (tower/focus-landed.ts, the definition the PRD frontier shares
|
|
7
|
+
* (tower/focus-landed.ts, the definition the PRD frontier shares -- QA
|
|
8
|
+
* included: a predecessor a person failed at QA has not landed, though its
|
|
9
|
+
* deliveries are done and its branch merged). A
|
|
8
10
|
* predecessor that has definitely not landed holds the successor with
|
|
9
11
|
* `waits_on`; one whose landed state git could not answer -- with none
|
|
10
12
|
* definitely unlanded -- leaves the successor UNAVAILABLE (no verdict, fail
|
|
@@ -13,7 +15,9 @@
|
|
|
13
15
|
* tower-verdicts.ts holds whichever is reached second while the first runs or
|
|
14
16
|
* is cleared.
|
|
15
17
|
*
|
|
16
|
-
* Git is read only for a predecessor whose deliveries say it could have
|
|
18
|
+
* Git is read only for a predecessor whose deliveries and QA say it could have
|
|
19
|
+
* landed. A successor already running keeps running whatever its predecessor's
|
|
20
|
+
* QA says: the slot rule (tower-verdicts.ts) never stops a live team.
|
|
17
21
|
*/
|
|
18
22
|
import type { FocusBranchContainment } from '../git/focus-branch-containment.js';
|
|
19
23
|
import type { TowerProductState } from '../queries/tower/tower-state.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tower-graph.d.ts","sourceRoot":"","sources":["../../src/tower/tower-graph.ts"],"names":[],"mappings":"AAMA
|
|
1
|
+
{"version":3,"file":"tower-graph.d.ts","sourceRoot":"","sources":["../../src/tower/tower-graph.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AACjF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAEzE,OAAO,KAAK,EAA4C,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAEvG,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,iBAAiB,EAAE,SAAS,GAAG,UAAU,GAAG,qBAAqB,CAAC,CAAC;AAEvG,wBAAgB,eAAe,CAC7B,KAAK,EAAE,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,OAAO,GAAG,WAAW,CAAC,EAC9D,aAAa,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,KAAK,sBAAsB,GACvF,gBAAgB,CA6ClB"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// packages/daemon/src/tower/tower-arm-admission.test.ts, packages/daemon/src/tower/tower-pass.test.ts,
|
|
4
4
|
// packages/daemon/src/tower/tower-state-ingestion.test.ts
|
|
5
5
|
// PINNED-BY-END
|
|
6
|
-
import { judgeFocusLanded } from './focus-landed.js';
|
|
6
|
+
import { judgeFocusLanded, qaStandingOfWire } from './focus-landed.js';
|
|
7
7
|
export function judgeTowerGraph(state, containmentOf) {
|
|
8
8
|
const info = new Map(state.graphFoci.map((f) => [f.focusId, f]));
|
|
9
9
|
const landedCache = new Map();
|
|
@@ -15,10 +15,13 @@ export function judgeTowerGraph(state, containmentOf) {
|
|
|
15
15
|
let result;
|
|
16
16
|
if (!f)
|
|
17
17
|
result = 'unknown';
|
|
18
|
-
else
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
else {
|
|
19
|
+
const qa = qaStandingOfWire(f);
|
|
20
|
+
if (judgeFocusLanded(f.deliveryStatuses, 'contained', qa) !== 'landed')
|
|
21
|
+
result = 'not_landed';
|
|
22
|
+
else
|
|
23
|
+
result = judgeFocusLanded(f.deliveryStatuses, containmentOf(f), qa);
|
|
24
|
+
}
|
|
22
25
|
landedCache.set(focusId, result);
|
|
23
26
|
return result;
|
|
24
27
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tower-graph.js","sourceRoot":"","sources":["../../src/tower/tower-graph.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,6DAA6D;AAC7D,yGAAyG;AACzG,4DAA4D;AAC5D,gBAAgB;
|
|
1
|
+
{"version":3,"file":"tower-graph.js","sourceRoot":"","sources":["../../src/tower/tower-graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tower-verdicts.d.ts","sourceRoot":"","sources":["../../src/tower/tower-verdicts.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tower-verdicts.d.ts","sourceRoot":"","sources":["../../src/tower/tower-verdicts.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAML,KAAK,SAAS,EACd,KAAK,YAAY,EAElB,MAAM,qBAAqB,CAAC;AAE7B,8CAA8C;AAC9C,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,4DAA4D;IAC5D,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,2CAA2C;AAC3C,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,4DAA4D;AAC5D,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,SAAS,eAAe,EAAE,CAAC;IACjC,iEAAiE;IACjE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,iDAAiD;IACjD,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACtC,sFAAsF;IACtF,eAAe,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IAC5C,0EAA0E;IAC1E,OAAO,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;IACxD,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC,CAAC;IAC1D,gFAAgF;IAChF,mBAAmB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC1C,IAAI,EAAE,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAChC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,4EAA4E;AAC5E,MAAM,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC,CAAC;AAyC7D,2DAA2D;AAC3D,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,iBAAiB,GAAG,aAAa,CAkD5E;AAED,2DAA2D;AAC3D,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;CAC9B;AAOD;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,SAAS,eAAe,EAAE,EAChC,QAAQ,EAAE,aAAa,EACvB,0BAA0B,EAAE,SAAS,MAAM,EAAE,EAC7C,KAAK,EAAE,MAAM,EACb,QAAQ,GAAE,MAAiC,GAC1C,iBAAiB,EAAE,CAgBrB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
|
|
2
|
-
// Pinned by: packages/daemon/src/tower/
|
|
2
|
+
// Pinned by: packages/daemon/src/tower/focus-landed.test.ts, packages/daemon/src/tower/tower-pass.test.ts,
|
|
3
|
+
// packages/daemon/src/tower/tower-verdicts.test.ts
|
|
3
4
|
// PINNED-BY-END
|
|
4
5
|
/**
|
|
5
6
|
* The tower's verdict computation for ONE product -- pure (inputs in, verdicts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tower-verdicts.js","sourceRoot":"","sources":["../../src/tower/tower-verdicts.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,
|
|
1
|
+
{"version":3,"file":"tower-verdicts.js","sourceRoot":"","sources":["../../src/tower/tower-verdicts.ts"],"names":[],"mappings":"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"}
|
package/docs/runbook-tower.md
CHANGED
|
@@ -51,9 +51,17 @@ itself, is refused):
|
|
|
51
51
|
LANDED. A `depends_on` edge that would close a cycle is refused at the write,
|
|
52
52
|
and the refusal names the cycle (`UI -> Schema -> API -> UI`). The refusal is
|
|
53
53
|
atomic: a database trigger serializes each product's `depends_on` writes, so
|
|
54
|
-
two concurrent writes can never close a cycle between them.
|
|
54
|
+
two concurrent writes can never close a cycle between them. A `depends_on`
|
|
55
|
+
edge between two foci of ONE PRD (both named by overcome nodes of one
|
|
56
|
+
`prd_id`) is refused too, naming the PRD and both foci: the PRD's
|
|
57
|
+
prerequisite tree orders its own foci, and a tower edge could only repeat
|
|
58
|
+
that order or contradict it -- deadlocking both. The database refuses it
|
|
59
|
+
(`focus_tower_edges_refuse_same_prd`), so no writer can store one. Not
|
|
60
|
+
refused (a recorded limit): a cycle spanning two or more PRDs through two or
|
|
61
|
+
more tower edges.
|
|
55
62
|
- **`excludes`** (mutual): the two foci are never cleared together -- e.g. both
|
|
56
63
|
rewrite the same files, fixtures or migration journal. Stored once per pair.
|
|
64
|
+
Allowed between two foci of one PRD: it never orders them.
|
|
57
65
|
|
|
58
66
|
Every edge carries **provenance** (`declared` -- written by a human or an agent
|
|
59
67
|
over MCP; `inferred` and `observed` are reserved for the follow-on focus that
|
|
@@ -74,7 +82,18 @@ A focus has LANDED -- judged by the daemon, no human close -- when:
|
|
|
74
82
|
1. it has at least one delivery, and
|
|
75
83
|
2. every non-cancelled delivery is `done` (at least one: a focus whose every
|
|
76
84
|
delivery was cancelled landed nothing), and
|
|
77
|
-
3. its
|
|
85
|
+
3. no person has failed it at QA, and its QA could be read: a failed verdict
|
|
86
|
+
leaves every delivery done and the branch merged, so without this a
|
|
87
|
+
`depends_on` successor would start on the work QA rejected. `qa_state` stays
|
|
88
|
+
`failed` until the team armed after the fail finishes. QA gates nothing on
|
|
89
|
+
the pass side -- awaiting, passed and never-QA'd foci land on 1, 2 and 4
|
|
90
|
+
alone (docs/DECISIONS.md 2026-10-26). The product-api reads QA apart from
|
|
91
|
+
the rest of the graph, so a QA read that fails reaches the rule as
|
|
92
|
+
unreadable (`qaReadFailed`) and HOLDS the successor, rather than failing the
|
|
93
|
+
whole graph read, which the tower fails open on. An API older than the field
|
|
94
|
+
sends no QA state; the daemon then judges 1, 2 and 4 alone, as it did before
|
|
95
|
+
QA was read, and
|
|
96
|
+
4. its branch tip is contained in the integration branch
|
|
78
97
|
(`git rev-list --count <integration>..<branch>` reads 0; no checkout) -- or
|
|
79
98
|
the branch is gone AND the focus's merge record (`focus_merges`, written by
|
|
80
99
|
the daemon when it merges) names a merge commit integration contains. The
|
|
@@ -82,9 +101,11 @@ A focus has LANDED -- judged by the daemon, no human close -- when:
|
|
|
82
101
|
A branch that is gone with no such record (a hand-deleted branch, a legacy
|
|
83
102
|
focus that never recorded one) is unproven: unknown, never landed.
|
|
84
103
|
|
|
85
|
-
The PRD frontier's completion signal is this same rule
|
|
86
|
-
`
|
|
87
|
-
landed.
|
|
104
|
+
The PRD frontier's completion signal is this same rule, QA included
|
|
105
|
+
(`prd/controller-shared.ts` `loadLandedFocusIds`, calling
|
|
106
|
+
`tower/focus-landed.ts` `judgeFocusLanded`): a frontier overcome clears only when
|
|
107
|
+
its focus has landed. A successor already running when its predecessor fails QA
|
|
108
|
+
keeps running: the tower never stops a live team. A landed check git cannot answer (integration unreadable, a ref or
|
|
88
109
|
containment read that errored, an unreadable or missing merge record) is UNKNOWN: the tower leaves the dependent focus's verdict unavailable (fail
|
|
89
110
|
open) rather than holding it, and the PRD frontier waits a tick.
|
|
90
111
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@telora/daemon",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.56",
|
|
4
4
|
"description": "Agent orchestration daemon for Telora - spawns and manages Claude Code instances",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"//testRunner": "Uses Node.js built-in test runner (node:test) via tsx for TypeScript support. The root package uses Vitest; this is a deliberate choice for the daemon package to avoid framework dependencies. Test files live beside the modules they exercise (owner-directory layout); the runner discovers them recursively.",
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@telora/daemon-core": "^0.3.3",
|
|
44
|
-
"@telora/mcp-products": "^0.23.
|
|
44
|
+
"@telora/mcp-products": "^0.23.21",
|
|
45
45
|
"commander": "^14.0.3",
|
|
46
46
|
"yaml": "^2.4.0",
|
|
47
47
|
"zod": "^4.3.6"
|