@volter/supercode-orchestrator 0.5.155 → 0.5.157
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/board/cli.mjs +10 -2
- package/board/dispatch.mjs +7 -3
- package/board/store.mjs +4 -0
- package/board/ztrack.mjs +13 -4
- package/package.json +2 -2
package/board/cli.mjs
CHANGED
|
@@ -1590,14 +1590,22 @@ async function answerVerbs(root, log) {
|
|
|
1590
1590
|
|
|
1591
1591
|
/** One request to the owner, answered whole: the verb run in the caller's call, its output kept for the answer. A
|
|
1592
1592
|
* verb that takes more than a second is a slow line of its own, with the steps that ended while it ran (its own and,
|
|
1593
|
-
* in this one process, any other call's that held it)
|
|
1593
|
+
* in this one process, any other call's that held it) and what the process used while it ran (`process`): its
|
|
1594
|
+
* processor time beside the line's `ms` says whether the time was computed or waited for, with the major page faults
|
|
1595
|
+
* and the waits (voluntary context switches) and preemptions (involuntary) the kernel counted. */
|
|
1594
1596
|
async function answerOne(root, line) {
|
|
1595
1597
|
const began = performance.now();
|
|
1598
|
+
const before = process.resourceUsage();
|
|
1596
1599
|
let named = null, by = null;
|
|
1597
1600
|
try { return await answerRequest(root, line, (verb, caller) => { named = verb; by = caller; }); }
|
|
1598
1601
|
finally {
|
|
1599
1602
|
const ms = performance.now() - began;
|
|
1600
|
-
if (named
|
|
1603
|
+
if (named && ms > slowLog.SLOW_MS) {
|
|
1604
|
+
const after = process.resourceUsage();
|
|
1605
|
+
const used = { cpu_ms: Math.round((after.userCPUTime + after.systemCPUTime - before.userCPUTime - before.systemCPUTime) / 1000), major_faults: after.majorPageFault - before.majorPageFault,
|
|
1606
|
+
waits: after.voluntaryContextSwitches - before.voluntaryContextSwitches, preempted: after.involuntaryContextSwitches - before.involuntaryContextSwitches };
|
|
1607
|
+
recordSlow({ kind: 'call', name: `owner verb ${named}`, ms, slowest: null, extra: { caller: by, steps: slowLog.stepsWithin?.(began, performance.now()) ?? null, process: used } });
|
|
1608
|
+
}
|
|
1601
1609
|
}
|
|
1602
1610
|
}
|
|
1603
1611
|
|
package/board/dispatch.mjs
CHANGED
|
@@ -838,8 +838,11 @@ async function startCards(board, fleet, lanes, settings, report, entry, effects,
|
|
|
838
838
|
};
|
|
839
839
|
for (const task of everyCard) {
|
|
840
840
|
if (only && task.id !== only) continue;
|
|
841
|
+
// a subtask or a card with a run is never started here, whatever its scope says: no scope is built to learn it (the
|
|
842
|
+
// scope of each of a board's 2,155 unarchived cards, 2,039 of them subtasks or running, was 0.8 s of every round)
|
|
843
|
+
if (task.subtask_of || task.current_run_id) continue;
|
|
841
844
|
const state = scopeFor(task).card;
|
|
842
|
-
if (
|
|
845
|
+
if (state.archived || ['done', 'cancelled'].includes(state.status)) continue;
|
|
843
846
|
if (state.dispatch_hold) { waiting(task, 'dispatch held: an explicit start or verified adoption must release it'); continue; }
|
|
844
847
|
if (workflow.run && state.paused) { waiting(task, `paused: ${state.paused.reason ?? 'manager pause'}`); continue; }
|
|
845
848
|
if (workflow.run && state.blocked_by.length) { waiting(task, `blocked by ${state.blocked_by.map(b => b.id).join(', ')}`); continue; }
|
|
@@ -3087,9 +3090,10 @@ async function activatePullRequestReviews(board, entry, report, effects, { only
|
|
|
3087
3090
|
const eligible = db => {
|
|
3088
3091
|
const task = getTask(db, id);
|
|
3089
3092
|
if (!task) return false;
|
|
3093
|
+
// a status the platform cannot request a review from needs no scope built to say so
|
|
3094
|
+
if (!transitionsFor(entry.workflow, statusOf(db, task), 'request_review').some(t => !t.by || t.by.includes('platform'))) return false;
|
|
3090
3095
|
const scope = scopeOf(db, board, task, { params: entry.params });
|
|
3091
|
-
if (
|
|
3092
|
-
scope.card.dispatch_hold || scope.card.paused || scope.card.blocked_by.length) return false;
|
|
3096
|
+
if (scope.card.dispatch_hold || scope.card.paused || scope.card.blocked_by.length) return false;
|
|
3093
3097
|
// The card's Tasks are its subtasks; an open one holds the review, and says so.
|
|
3094
3098
|
const open = scope.card.subtasks.filter(t => !['done', 'cancelled'].includes(t.status));
|
|
3095
3099
|
return open.length ? open : true;
|
package/board/store.mjs
CHANGED
|
@@ -150,6 +150,10 @@ export function layOut(db, { fresh }) {
|
|
|
150
150
|
db.exec(PUBLICATION_SCHEMA);
|
|
151
151
|
const have = new Set(db.prepare('PRAGMA table_info(supercode_cards)').all().map((c) => c.name));
|
|
152
152
|
for (const [column, type] of Object.entries(OURS_COLUMNS)) if (!have.has(column)) db.exec(`ALTER TABLE supercode_cards ADD COLUMN ${column} ${type}`);
|
|
153
|
+
// A card's subtasks are read by the arc they name, for every scope built (workflow.mjs scopeOf): without this index
|
|
154
|
+
// each read walked every card's row. Laid out here, after the column it names exists on a store of any age and before
|
|
155
|
+
// any statement is prepared; no statement names it, so a store without it is only slower.
|
|
156
|
+
db.exec('CREATE INDEX IF NOT EXISTS idx_supercode_cards_subtask_of ON supercode_cards(subtask_of)');
|
|
153
157
|
const effectColumns = new Set(db.prepare('PRAGMA table_info(supercode_effects)').all().map((c) => c.name));
|
|
154
158
|
for (const [column, type] of Object.entries(EFFECT_COLUMNS)) if (!effectColumns.has(column)) db.exec(`ALTER TABLE supercode_effects ADD COLUMN ${column} ${type}`);
|
|
155
159
|
// what changed is marked by the store itself, whoever writes it (published.mjs)
|
package/board/ztrack.mjs
CHANGED
|
@@ -21,6 +21,15 @@ import * as slowLog from '@volter/supercode-harness-sdk/slow-log';
|
|
|
21
21
|
|
|
22
22
|
/** Run `fn` as a named step of the running command (the slow log names its slowest step). */
|
|
23
23
|
const timedStep = (step, fn) => { const started = performance.now(); try { return fn(); } finally { noteStep(step, performance.now() - started); } };
|
|
24
|
+
// One statement that takes this long is a step of its own, named by its text: a verb that only reads (`show`) runs in
|
|
25
|
+
// no transaction and has no other step, so a hold inside it was a slow line that named no statement (8.7 s on
|
|
26
|
+
// 2026-10-11, where every statement of `show` measures under 80 ms on a copy of the same store).
|
|
27
|
+
const SLOW_STATEMENT_MS = 100;
|
|
28
|
+
const timedStatement = (sql, fn) => {
|
|
29
|
+
const started = performance.now();
|
|
30
|
+
try { return fn(); }
|
|
31
|
+
finally { const ms = performance.now() - started; if (ms >= SLOW_STATEMENT_MS) noteStep(`board statement: ${String(sql).replace(/\s+/g, ' ').trim().slice(0, 120)}`, ms); }
|
|
32
|
+
};
|
|
24
33
|
import { fire, workflowFor } from './workflow.mjs';
|
|
25
34
|
|
|
26
35
|
const require = createRequire(import.meta.url);
|
|
@@ -128,10 +137,10 @@ class ZtrackBoard {
|
|
|
128
137
|
boardErrors: self.errors,
|
|
129
138
|
prepare(sql) {
|
|
130
139
|
return {
|
|
131
|
-
get: (...args) => self.read(() => self.statement(sql).get(...args)),
|
|
132
|
-
all: (...args) => self.read(() => self.statement(sql).all(...args)),
|
|
133
|
-
iterate: (...args) => self.read(() => self.statement(sql).all(...args))[Symbol.iterator](),
|
|
134
|
-
run: (...args) => self.active ? self.noting(() => self.statement(sql).run(...args)) : self.tx(() => self.statement(sql).run(...args)),
|
|
140
|
+
get: (...args) => self.read(() => timedStatement(sql, () => self.statement(sql).get(...args))),
|
|
141
|
+
all: (...args) => self.read(() => timedStatement(sql, () => self.statement(sql).all(...args))),
|
|
142
|
+
iterate: (...args) => self.read(() => timedStatement(sql, () => self.statement(sql).all(...args)))[Symbol.iterator](),
|
|
143
|
+
run: (...args) => self.active ? self.noting(() => timedStatement(sql, () => self.statement(sql).run(...args))) : self.tx(() => timedStatement(sql, () => self.statement(sql).run(...args))),
|
|
135
144
|
};
|
|
136
145
|
},
|
|
137
146
|
exec(sql) { return self.active ? self.noting(() => self.conn.exec(sql)) : self.tx(() => self.conn.exec(sql)); },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volter/supercode-orchestrator",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.157",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The orchestrator runtime over the Volter Harness ontology: one typed operational model whose folder is its serialization, read and written through the harness orchestration doors (docs/ORCHESTRATOR-IR.md)",
|
|
6
6
|
"exports": {
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"check-types": "node scripts/generate-types.mjs --check"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@volter/supercode-harness-sdk": "^0.3.
|
|
27
|
+
"@volter/supercode-harness-sdk": "^0.3.96",
|
|
28
28
|
"@volter/teams": "0.2.65",
|
|
29
29
|
"@volter/ztrack": "^2.4.23",
|
|
30
30
|
"yaml": "^2.9.0"
|