instar 0.28.63 → 0.28.64
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.js +0 -0
- package/dist/core/InitiativeDigestJob.d.ts +54 -0
- package/dist/core/InitiativeDigestJob.d.ts.map +1 -0
- package/dist/core/InitiativeDigestJob.js +128 -0
- package/dist/core/InitiativeDigestJob.js.map +1 -0
- package/dist/scheduler/JobLoader.d.ts +6 -1
- package/dist/scheduler/JobLoader.d.ts.map +1 -1
- package/dist/scheduler/JobLoader.js +27 -5
- package/dist/scheduler/JobLoader.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +6 -6
- package/upgrades/0.28.61.md +80 -0
- package/upgrades/0.28.64.md +45 -0
- package/upgrades/NEXT.md +53 -0
- package/upgrades/side-effects/0.28.64.md +175 -0
package/dist/cli.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { InitiativeTracker, Digest } from './InitiativeTracker.js';
|
|
2
|
+
export interface InitiativeDigestJobOptions {
|
|
3
|
+
tracker: InitiativeTracker;
|
|
4
|
+
/** Called with the formatted digest message when there's something to send. */
|
|
5
|
+
sendMessage: (text: string) => Promise<void> | void;
|
|
6
|
+
/** How often to scan. Default: 24 hours. */
|
|
7
|
+
intervalMs?: number;
|
|
8
|
+
/** Don't re-send the same digest within this window. Default: 23h. */
|
|
9
|
+
resendSuppressionMs?: number;
|
|
10
|
+
/**
|
|
11
|
+
* Delay before the first scan. Default: 60s (gives the server time
|
|
12
|
+
* to finish startup so we don't ping during a partial boot).
|
|
13
|
+
*/
|
|
14
|
+
initialDelayMs?: number;
|
|
15
|
+
/** Time source (injectable for tests). */
|
|
16
|
+
now?: () => Date;
|
|
17
|
+
}
|
|
18
|
+
export interface LastSend {
|
|
19
|
+
signature: string;
|
|
20
|
+
at: string;
|
|
21
|
+
}
|
|
22
|
+
export declare class InitiativeDigestJob {
|
|
23
|
+
private readonly tracker;
|
|
24
|
+
private readonly sendMessage;
|
|
25
|
+
private readonly intervalMs;
|
|
26
|
+
private readonly resendSuppressionMs;
|
|
27
|
+
private readonly initialDelayMs;
|
|
28
|
+
private readonly now;
|
|
29
|
+
private lastSend;
|
|
30
|
+
private initialTimer;
|
|
31
|
+
private intervalTimer;
|
|
32
|
+
private running;
|
|
33
|
+
constructor(opts: InitiativeDigestJobOptions);
|
|
34
|
+
start(): void;
|
|
35
|
+
stop(): void;
|
|
36
|
+
/**
|
|
37
|
+
* Run one scan. Exposed for tests and for the manual-trigger API.
|
|
38
|
+
* Returns the digest that was scanned and whether a message was sent.
|
|
39
|
+
*/
|
|
40
|
+
tick(): Promise<{
|
|
41
|
+
digest: Digest;
|
|
42
|
+
sent: boolean;
|
|
43
|
+
suppressedReason?: string;
|
|
44
|
+
}>;
|
|
45
|
+
/**
|
|
46
|
+
* Stable hash of the digest (reason + initiativeId pairs, sorted) so
|
|
47
|
+
* that identical digests produce identical signatures regardless of
|
|
48
|
+
* map iteration order.
|
|
49
|
+
*/
|
|
50
|
+
private signatureOf;
|
|
51
|
+
format(digest: Digest): string;
|
|
52
|
+
getLastSend(): LastSend | null;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=InitiativeDigestJob.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InitiativeDigestJob.d.ts","sourceRoot":"","sources":["../../src/core/InitiativeDigestJob.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAExE,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,iBAAiB,CAAC;IAC3B,+EAA+E;IAC/E,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACpD,4CAA4C;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,0CAA0C;IAC1C,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;CACZ;AAMD,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoB;IAC5C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAyC;IACrE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAa;IACjC,OAAO,CAAC,QAAQ,CAAyB;IACzC,OAAO,CAAC,YAAY,CAA8C;IAClE,OAAO,CAAC,aAAa,CAA+C;IACpE,OAAO,CAAC,OAAO,CAAS;gBAEZ,IAAI,EAAE,0BAA0B;IAS5C,KAAK,IAAI,IAAI;IASb,IAAI,IAAI,IAAI;IAQZ;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAC;QAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IA0BnF;;;;OAIG;IACH,OAAO,CAAC,WAAW;IAQnB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IA4B9B,WAAW,IAAI,QAAQ,GAAG,IAAI;CAG/B"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* InitiativeDigestJob — periodic scan of the InitiativeTracker that
|
|
3
|
+
* pushes a Telegram notification to the user when there are actionable
|
|
4
|
+
* signals (stale / needs-user / next-check-due / ready-to-advance).
|
|
5
|
+
*
|
|
6
|
+
* Quiet by default: an empty digest sends nothing.
|
|
7
|
+
* Idempotent by default: if the exact same digest would be sent again
|
|
8
|
+
* within `resendSuppressionMs`, we skip it to avoid noise.
|
|
9
|
+
*
|
|
10
|
+
* Lives in-process (setInterval-based). Not a JobScheduler Job because
|
|
11
|
+
* we don't want to spawn a fresh Claude session just to check the
|
|
12
|
+
* tracker — this is a direct, deterministic read.
|
|
13
|
+
*/
|
|
14
|
+
import { createHash } from 'node:crypto';
|
|
15
|
+
const DEFAULT_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
16
|
+
const DEFAULT_RESEND_SUPPRESSION_MS = 23 * 60 * 60 * 1000;
|
|
17
|
+
const DEFAULT_INITIAL_DELAY_MS = 60 * 1000;
|
|
18
|
+
export class InitiativeDigestJob {
|
|
19
|
+
tracker;
|
|
20
|
+
sendMessage;
|
|
21
|
+
intervalMs;
|
|
22
|
+
resendSuppressionMs;
|
|
23
|
+
initialDelayMs;
|
|
24
|
+
now;
|
|
25
|
+
lastSend = null;
|
|
26
|
+
initialTimer = null;
|
|
27
|
+
intervalTimer = null;
|
|
28
|
+
running = false;
|
|
29
|
+
constructor(opts) {
|
|
30
|
+
this.tracker = opts.tracker;
|
|
31
|
+
this.sendMessage = opts.sendMessage;
|
|
32
|
+
this.intervalMs = opts.intervalMs ?? DEFAULT_INTERVAL_MS;
|
|
33
|
+
this.resendSuppressionMs = opts.resendSuppressionMs ?? DEFAULT_RESEND_SUPPRESSION_MS;
|
|
34
|
+
this.initialDelayMs = opts.initialDelayMs ?? DEFAULT_INITIAL_DELAY_MS;
|
|
35
|
+
this.now = opts.now ?? (() => new Date());
|
|
36
|
+
}
|
|
37
|
+
start() {
|
|
38
|
+
if (this.running)
|
|
39
|
+
return;
|
|
40
|
+
this.running = true;
|
|
41
|
+
this.initialTimer = setTimeout(() => {
|
|
42
|
+
void this.tick();
|
|
43
|
+
this.intervalTimer = setInterval(() => void this.tick(), this.intervalMs);
|
|
44
|
+
}, this.initialDelayMs);
|
|
45
|
+
}
|
|
46
|
+
stop() {
|
|
47
|
+
this.running = false;
|
|
48
|
+
if (this.initialTimer)
|
|
49
|
+
clearTimeout(this.initialTimer);
|
|
50
|
+
if (this.intervalTimer)
|
|
51
|
+
clearInterval(this.intervalTimer);
|
|
52
|
+
this.initialTimer = null;
|
|
53
|
+
this.intervalTimer = null;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Run one scan. Exposed for tests and for the manual-trigger API.
|
|
57
|
+
* Returns the digest that was scanned and whether a message was sent.
|
|
58
|
+
*/
|
|
59
|
+
async tick() {
|
|
60
|
+
const digest = this.tracker.digest(this.now());
|
|
61
|
+
if (digest.items.length === 0) {
|
|
62
|
+
return { digest, sent: false, suppressedReason: 'no-items' };
|
|
63
|
+
}
|
|
64
|
+
const signature = this.signatureOf(digest);
|
|
65
|
+
if (this.lastSend && this.lastSend.signature === signature) {
|
|
66
|
+
const lastMs = Date.parse(this.lastSend.at);
|
|
67
|
+
const ageMs = this.now().getTime() - lastMs;
|
|
68
|
+
if (Number.isFinite(lastMs) && ageMs < this.resendSuppressionMs) {
|
|
69
|
+
return { digest, sent: false, suppressedReason: 'duplicate-within-window' };
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const text = this.format(digest);
|
|
73
|
+
try {
|
|
74
|
+
await this.sendMessage(text);
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
console.error(`[initiative-digest] send failed: ${err instanceof Error ? err.message : err}`);
|
|
78
|
+
return { digest, sent: false, suppressedReason: 'send-failed' };
|
|
79
|
+
}
|
|
80
|
+
this.lastSend = { signature, at: this.now().toISOString() };
|
|
81
|
+
return { digest, sent: true };
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Stable hash of the digest (reason + initiativeId pairs, sorted) so
|
|
85
|
+
* that identical digests produce identical signatures regardless of
|
|
86
|
+
* map iteration order.
|
|
87
|
+
*/
|
|
88
|
+
signatureOf(digest) {
|
|
89
|
+
const tokens = digest.items
|
|
90
|
+
.map((i) => `${i.reason}:${i.initiativeId}`)
|
|
91
|
+
.sort()
|
|
92
|
+
.join('|');
|
|
93
|
+
return createHash('sha256').update(tokens).digest('hex');
|
|
94
|
+
}
|
|
95
|
+
format(digest) {
|
|
96
|
+
const byReason = new Map();
|
|
97
|
+
for (const item of digest.items) {
|
|
98
|
+
if (!byReason.has(item.reason))
|
|
99
|
+
byReason.set(item.reason, []);
|
|
100
|
+
byReason.get(item.reason).push({ title: item.title, detail: item.detail, id: item.initiativeId });
|
|
101
|
+
}
|
|
102
|
+
const sections = [];
|
|
103
|
+
const order = [
|
|
104
|
+
'needs-user', 'next-check-due', 'ready-to-advance', 'stale',
|
|
105
|
+
];
|
|
106
|
+
const labels = {
|
|
107
|
+
'needs-user': 'Needs you',
|
|
108
|
+
'next-check-due': 'Check-in due',
|
|
109
|
+
'ready-to-advance': 'Ready to advance',
|
|
110
|
+
'stale': 'Stale',
|
|
111
|
+
};
|
|
112
|
+
for (const reason of order) {
|
|
113
|
+
const items = byReason.get(reason);
|
|
114
|
+
if (!items || items.length === 0)
|
|
115
|
+
continue;
|
|
116
|
+
const lines = items.map((i) => ` • ${i.title} — ${i.detail}`);
|
|
117
|
+
sections.push(`*${labels[reason]}:*\n${lines.join('\n')}`);
|
|
118
|
+
}
|
|
119
|
+
const header = digest.items.length === 1
|
|
120
|
+
? '1 initiative needs attention:'
|
|
121
|
+
: `${digest.items.length} initiatives need attention:`;
|
|
122
|
+
return `${header}\n\n${sections.join('\n\n')}`;
|
|
123
|
+
}
|
|
124
|
+
getLastSend() {
|
|
125
|
+
return this.lastSend;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=InitiativeDigestJob.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InitiativeDigestJob.js","sourceRoot":"","sources":["../../src/core/InitiativeDigestJob.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,7 +12,12 @@
|
|
|
12
12
|
import type { JobDefinition } from '../core/types.js';
|
|
13
13
|
/**
|
|
14
14
|
* Load and validate job definitions from a JSON file.
|
|
15
|
-
*
|
|
15
|
+
*
|
|
16
|
+
* Per-entry resilience: invalid entries are logged and skipped, not thrown.
|
|
17
|
+
* One malformed job should not take down the whole scheduler (and with it
|
|
18
|
+
* the HTTP server, dashboard, feedback pipeline, and Telegram poller).
|
|
19
|
+
* Structural errors (missing file, unparseable JSON, non-array root) still
|
|
20
|
+
* throw — those indicate nothing can be loaded at all.
|
|
16
21
|
*
|
|
17
22
|
* Missing file is NOT fatal: treated as "no jobs configured" so a
|
|
18
23
|
* fresh or partially-initialized agent still boots. The scheduler
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JobLoader.d.ts","sourceRoot":"","sources":["../../src/scheduler/JobLoader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,aAAa,EAA0B,MAAM,kBAAkB,CAAC;AAe9E
|
|
1
|
+
{"version":3,"file":"JobLoader.d.ts","sourceRoot":"","sources":["../../src/scheduler/JobLoader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,aAAa,EAA0B,MAAM,kBAAkB,CAAC;AAe9E;;;;;;;;;;;;GAYG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,EAAE,CAkD1D;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAkG9D;AA4CD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAqF9E"}
|
|
@@ -24,7 +24,12 @@ const GROUNDING_EXEMPT_SLUGS = new Set([
|
|
|
24
24
|
]);
|
|
25
25
|
/**
|
|
26
26
|
* Load and validate job definitions from a JSON file.
|
|
27
|
-
*
|
|
27
|
+
*
|
|
28
|
+
* Per-entry resilience: invalid entries are logged and skipped, not thrown.
|
|
29
|
+
* One malformed job should not take down the whole scheduler (and with it
|
|
30
|
+
* the HTTP server, dashboard, feedback pipeline, and Telegram poller).
|
|
31
|
+
* Structural errors (missing file, unparseable JSON, non-array root) still
|
|
32
|
+
* throw — those indicate nothing can be loaded at all.
|
|
28
33
|
*
|
|
29
34
|
* Missing file is NOT fatal: treated as "no jobs configured" so a
|
|
30
35
|
* fresh or partially-initialized agent still boots. The scheduler
|
|
@@ -46,10 +51,27 @@ export function loadJobs(jobsFile) {
|
|
|
46
51
|
if (!Array.isArray(raw)) {
|
|
47
52
|
throw new Error(`Jobs file must contain a JSON array, got ${typeof raw}`);
|
|
48
53
|
}
|
|
49
|
-
const jobs =
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
54
|
+
const jobs = [];
|
|
55
|
+
const skipped = [];
|
|
56
|
+
for (let index = 0; index < raw.length; index++) {
|
|
57
|
+
const job = raw[index];
|
|
58
|
+
try {
|
|
59
|
+
validateJob(job, index);
|
|
60
|
+
jobs.push(job);
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
64
|
+
const slug = job && typeof job === 'object' ? job.slug : undefined;
|
|
65
|
+
skipped.push({ index, slug: typeof slug === 'string' ? slug : undefined, error: message });
|
|
66
|
+
console.error(`[JobLoader] Skipping invalid job at index ${index}` +
|
|
67
|
+
(typeof slug === 'string' ? ` (slug="${slug}")` : '') +
|
|
68
|
+
`: ${message}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (skipped.length > 0) {
|
|
72
|
+
console.warn(`[JobLoader] Loaded ${jobs.length} valid job(s); skipped ${skipped.length} invalid entry(ies). ` +
|
|
73
|
+
`Fix the skipped entries to restore full scheduler coverage.`);
|
|
74
|
+
}
|
|
53
75
|
// Grounding-by-default audit — warn about jobs missing grounding config
|
|
54
76
|
auditGrounding(jobs);
|
|
55
77
|
return jobs;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JobLoader.js","sourceRoot":"","sources":["../../src/scheduler/JobLoader.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"JobLoader.js","sourceRoot":"","sources":["../../src/scheduler/JobLoader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAG9B,MAAM,gBAAgB,GAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;AAC9E,MAAM,YAAY,GAAgB,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AAE9D,yEAAyE;AACzE,MAAM,sBAAsB,GAAwB,IAAI,GAAG,CAAC;IAC1D,cAAc;IACd,gBAAgB;IAChB,gBAAgB;IAChB,cAAc;IACd,qBAAqB;IACrB,UAAU;CACX,CAAC,CAAC;AAEH;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,QAAQ,CAAC,QAAgB;IACvC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,IAAI,CACV,oCAAoC,QAAQ,iCAAiC;YAC7E,8CAA8C,CAC/C,CAAC;QACF,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,GAAY,CAAC;IACjB,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;IACvD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,6BAA6B,QAAQ,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChH,CAAC;IAED,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,4CAA4C,OAAO,GAAG,EAAE,CAAC,CAAC;IAC5E,CAAC;IAED,MAAM,IAAI,GAAoB,EAAE,CAAC;IACjC,MAAM,OAAO,GAA2D,EAAE,CAAC;IAC3E,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QAChD,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC;QACvB,IAAI,CAAC;YACH,WAAW,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,GAAoB,CAAC,CAAC;QAClC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,MAAM,IAAI,GAAG,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAE,GAA+B,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;YAChG,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;YAC3F,OAAO,CAAC,KAAK,CACX,6CAA6C,KAAK,EAAE;gBACpD,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrD,KAAK,OAAO,EAAE,CACf,CAAC;QACJ,CAAC;IACH,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,IAAI,CACV,sBAAsB,IAAI,CAAC,MAAM,0BAA0B,OAAO,CAAC,MAAM,uBAAuB;YAChG,6DAA6D,CAC9D,CAAC;IACJ,CAAC;IAED,wEAAwE;IACxE,cAAc,CAAC,IAAI,CAAC,CAAC;IAErB,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,GAAY,EAAE,KAAc;IACtD,MAAM,MAAM,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;IAE7D,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,qBAAqB,CAAC,CAAC;IAClD,CAAC;IAED,MAAM,CAAC,GAAG,GAA8B,CAAC;IAEzC,yBAAyB;IACzB,KAAK,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,UAAU,CAAC,EAAE,CAAC;QAChE,IAAI,OAAO,CAAC,CAAC,KAAK,CAAC,KAAK,QAAQ,IAAI,CAAE,CAAC,CAAC,KAAK,CAAY,CAAC,IAAI,EAAE,EAAE,CAAC;YACjE,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,MAAM,KAAK,8CAA8C,CAAC,CAAC;QACtF,CAAC;IACH,CAAC;IAED,0DAA0D;IAC1D,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAc,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,mFAAmF,CAAC,CAAC;IAChH,CAAC;IAED,WAAW;IACX,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAuB,CAAC,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CACb,GAAG,MAAM,+BAA+B,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,QAAQ,GAAG,CAC3F,CAAC;IACJ,CAAC;IAED,kEAAkE;IAClE,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAkB,CAAC,EAAE,CAAC;QAC1E,MAAM,IAAI,KAAK,CACb,GAAG,MAAM,4BAA4B,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,KAAK,GAAG,CACjF,CAAC;IACJ,CAAC;IAED,yEAAyE;IACzE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,QAAkB,CAAC,CAAC;QAChD,QAAQ,CAAC,IAAI,EAAE,CAAC;IAClB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,8BAA8B,CAAC,CAAC,QAAQ,MAAM,GAAG,EAAE,CAAC,CAAC;IAChF,CAAC;IAED,0BAA0B;IAC1B,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,+BAA+B,CAAC,CAAC;IAC5D,CAAC;IAED,gBAAgB;IAChB,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,mDAAmD,CAAC,CAAC;IAChF,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,CAAC,OAAkC,CAAC;IAClD,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAc,CAAC,EAAE,CAAC;QACjE,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,uDAAuD,CAAC,CAAC;IACpF,CAAC;IACD,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAE,IAAI,CAAC,KAAgB,CAAC,IAAI,EAAE,EAAE,CAAC;QACrE,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,6BAA6B,CAAC,CAAC;IAC1D,CAAC;IAED,4CAA4C;IAC5C,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7D,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,oDAAoD,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACnG,CAAC;IAED,4CAA4C;IAC5C,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,8DAA8D,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1G,CAAC;IAED,yCAAyC;IACzC,IAAI,CAAC,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;QACnC,IAAI,OAAO,CAAC,CAAC,cAAc,KAAK,SAAS,IAAI,CAAC,CAAC,cAAc,KAAK,UAAU,EAAE,CAAC;YAC7E,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,2EAA2E,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC;QAC3H,CAAC;IACH,CAAC;IAED,yDAAyD;IACzD,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC7B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,mEAAmE,CAAC,CAAC;QAChG,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC3B,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;gBACvC,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,gDAAgD,CAAC,CAAC;YAC7E,CAAC;QACH,CAAC;IACH,CAAC;IAED,mDAAmD;IACnD,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QAC9B,iBAAiB,CAAC,CAAC,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACzC,CAAC;IAED,iDAAiD;IACjD,IAAI,CAAC,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;QACnC,sBAAsB,CAAC,CAAC,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;IACnD,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,iBAAiB,CAAC,SAAkB,EAAE,MAAc;IAC3D,IAAI,CAAC,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,6CAA6C,CAAC,CAAC;IAC1E,CAAC;IAED,MAAM,CAAC,GAAG,SAAoC,CAAC;IAE/C,IAAI,OAAO,CAAC,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,gDAAgD,CAAC,CAAC;IAC7E,CAAC;IAED,IAAI,CAAC,CAAC,sBAAsB,KAAK,SAAS,IAAI,OAAO,CAAC,CAAC,sBAAsB,KAAK,SAAS,EAAE,CAAC;QAC5F,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,kEAAkE,CAAC,CAAC;IAC/F,CAAC;IAED,IAAI,CAAC,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACjC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,kEAAkE,CAAC,CAAC;QAC/F,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,CAAC;YAC/B,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;gBACvC,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,4DAA4D,CAAC,CAAC;YACzF,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QAC9B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,+DAA+D,CAAC,CAAC;QAC5F,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;YAC5B,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;gBACvC,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,yDAAyD,CAAC,CAAC;YACtF,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,QAAiB,EAAE,MAAc;IACtE,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzE,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,uFAAuF,CAAC,CAAC;IACpH,CAAC;IAED,MAAM,CAAC,GAAG,QAAmC,CAAC;IAC9C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAE5B,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,0BAA0B,IAAI,CAAC,MAAM,qBAAqB,CAAC,CAAC;IACvF,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;QACrB,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAChE,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,qBAAqB,GAAG,sBAAsB,CAAC,CAAC;QAC3E,CAAC;QAED,MAAM,CAAC,GAAG,KAAgC,CAAC;QAE3C,kBAAkB;QAClB,IAAI,OAAO,CAAC,CAAC,WAAW,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;YAC1E,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,qBAAqB,GAAG,6DAA6D,CAAC,CAAC;QAClH,CAAC;QACD,IAAI,OAAO,CAAC,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;YACxE,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,qBAAqB,GAAG,4DAA4D,CAAC,CAAC;QACjH,CAAC;QAED,yDAAyD;QACzD,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC3B,MAAM,aAAa,GAAG,CAAC,WAAW,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;YAC1D,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;gBACtE,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,qBAAqB,GAAG,8BAA8B,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;YAChI,CAAC;QACH,CAAC;QAED,kBAAkB;QAClB,IAAI,CAAC,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;YAChC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC;gBAClC,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,qBAAqB,GAAG,0DAA0D,CAAC,CAAC;YAC/G,CAAC;YACD,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;gBAC9B,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;oBAC1B,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,qBAAqB,GAAG,0CAA0C,CAAC,CAAC;gBAC/F,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,CAAC,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;YAChC,IAAI,OAAO,CAAC,CAAC,WAAW,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC;gBACvE,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,qBAAqB,GAAG,mEAAmE,CAAC,CAAC;YACxH,CAAC;YACD,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC;gBACjC,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;oBAC9B,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;wBAC1B,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,qBAAqB,GAAG,0CAA0C,CAAC,CAAC;oBAC/F,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,IAAI,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;YACjE,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,qBAAqB,GAAG,6CAA6C,CAAC,CAAC;QAClG,CAAC;QAED,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;YAC7D,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,qBAAqB,GAAG,sDAAsD,CAAC,CAAC;QAC3G,CAAC;QAED,IAAI,CAAC,CAAC,WAAW,KAAK,SAAS,IAAI,OAAO,CAAC,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;YACrE,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,qBAAqB,GAAG,0DAA0D,CAAC,CAAC;QAC/G,CAAC;QAED,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,IAAI,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;YACjE,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,qBAAqB,GAAG,wDAAwD,CAAC,CAAC;QAC7G,CAAC;QAED,IAAI,CAAC,CAAC,UAAU,KAAK,SAAS,IAAI,OAAO,CAAC,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;YACnE,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,qBAAqB,GAAG,yDAAyD,CAAC,CAAC;QAC9G,CAAC;QAED,IAAI,CAAC,CAAC,YAAY,KAAK,SAAS,IAAI,OAAO,CAAC,CAAC,YAAY,KAAK,QAAQ,EAAE,CAAC;YACvE,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,qBAAqB,GAAG,gDAAgD,CAAC,CAAC;QACrG,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,cAAc,CAAC,IAAqB;IAC3C,MAAM,UAAU,GAAa,EAAE,CAAC;IAEhC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC,GAAG,CAAC,OAAO;YAAE,SAAS;QAC3B,IAAI,sBAAsB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,SAAS;QACnD,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;YACnB,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,IAAI,CACV,gCAAgC,UAAU,CAAC,MAAM,0CAA0C,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;YACpH,wEAAwE,CACzE,CAAC;IACJ,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "./builtin-manifest.schema.json",
|
|
3
3
|
"schemaVersion": 1,
|
|
4
|
-
"generatedAt": "2026-04-
|
|
5
|
-
"instarVersion": "0.28.
|
|
4
|
+
"generatedAt": "2026-04-20T00:31:27.777Z",
|
|
5
|
+
"instarVersion": "0.28.64",
|
|
6
6
|
"entryCount": 186,
|
|
7
7
|
"entries": {
|
|
8
8
|
"hook:session-start": {
|
|
@@ -343,7 +343,7 @@
|
|
|
343
343
|
"id": "skill:autonomous",
|
|
344
344
|
"type": "skill",
|
|
345
345
|
"domain": "skills",
|
|
346
|
-
"sourcePath": ".claude/skills/autonomous/
|
|
346
|
+
"sourcePath": ".claude/skills/autonomous/skill.md",
|
|
347
347
|
"contentHash": "9bc7dc9eddd4e345ed6564eff850898b66358ce309119c3047e6af275cf9070d",
|
|
348
348
|
"since": "2025-01-01"
|
|
349
349
|
},
|
|
@@ -351,7 +351,7 @@
|
|
|
351
351
|
"id": "skill:build",
|
|
352
352
|
"type": "skill",
|
|
353
353
|
"domain": "skills",
|
|
354
|
-
"sourcePath": ".claude/skills/build/
|
|
354
|
+
"sourcePath": ".claude/skills/build/skill.md",
|
|
355
355
|
"contentHash": "5b3557fa3662cf0c7b7bab85a252cc2e567b3fc64a04a92d430374ef1f264ca6",
|
|
356
356
|
"since": "2025-01-01"
|
|
357
357
|
},
|
|
@@ -359,7 +359,7 @@
|
|
|
359
359
|
"id": "skill:secret-setup",
|
|
360
360
|
"type": "skill",
|
|
361
361
|
"domain": "skills",
|
|
362
|
-
"sourcePath": ".claude/skills/secret-setup/
|
|
362
|
+
"sourcePath": ".claude/skills/secret-setup/skill.md",
|
|
363
363
|
"contentHash": "0f4365713d96c98576d19c818701abe96329f3652ed0d8d76ec4e4a1b46dac56",
|
|
364
364
|
"since": "2025-01-01"
|
|
365
365
|
},
|
|
@@ -367,7 +367,7 @@
|
|
|
367
367
|
"id": "skill:setup-wizard",
|
|
368
368
|
"type": "skill",
|
|
369
369
|
"domain": "skills",
|
|
370
|
-
"sourcePath": ".claude/skills/setup-wizard/
|
|
370
|
+
"sourcePath": ".claude/skills/setup-wizard/skill.md",
|
|
371
371
|
"contentHash": "813fd9164514fd11d1bdc67f4dbee02a74679b3ca46bf1b39893c62deb2e58cb",
|
|
372
372
|
"since": "2025-01-01"
|
|
373
373
|
},
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Upgrade Guide — Scheduler reports real exit code for gate skips
|
|
2
|
+
|
|
3
|
+
## What Changed
|
|
4
|
+
|
|
5
|
+
`JobScheduler.runGateAsync` previously surfaced `exit null` for every
|
|
6
|
+
legitimate non-zero gate skip, because it was reading `.status` (the
|
|
7
|
+
synchronous `spawnSync` shape) off an error from the asynchronous
|
|
8
|
+
`util.promisify(child_process.execFile)` call, which exposes exit codes
|
|
9
|
+
on `.code` instead. Every gate-skip event and activity-feed line ended
|
|
10
|
+
up coalesced to `null`, indistinguishable from a process crash or
|
|
11
|
+
signal kill.
|
|
12
|
+
|
|
13
|
+
### Before
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
Job "degradation-digest" skipped — gate returned exit null after 3 attempts
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Agents and operators reading this saw a null exit and assumed the gate
|
|
20
|
+
process had crashed or been killed. This triggered unnecessary
|
|
21
|
+
investigations — most recently, `degradation-digest` looking
|
|
22
|
+
"permanently gated (62 skips, 0 runs)" when the gate was in fact
|
|
23
|
+
exiting 1 by design (no degradation events to digest, nothing to run).
|
|
24
|
+
|
|
25
|
+
### After
|
|
26
|
+
|
|
27
|
+
The skip path now reads `.signal ?? .code ?? .status ?? null`, so:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
Job "degradation-digest" skipped — gate returned exit 1 after 3 attempts
|
|
31
|
+
Job "other-job" skipped — gate returned exit SIGKILL after 3 attempts
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Legitimate non-zero skips report their real exit code. Signal-terminated
|
|
35
|
+
gates surface their signal. `metadata.exitCode` on the `job_gate_skip`
|
|
36
|
+
event is now a `number | string | null` (was `number | null`); consumers
|
|
37
|
+
doing display or non-arithmetic comparisons continue to work unchanged.
|
|
38
|
+
|
|
39
|
+
No decision-point change. The gate still retries up to `gateRetries`
|
|
40
|
+
times, still records to the skip ledger, still emits the same event
|
|
41
|
+
shape. Only the exit-code field is now truthful.
|
|
42
|
+
|
|
43
|
+
## What to Tell Your User
|
|
44
|
+
|
|
45
|
+
Your activity feed will stop saying "gate returned exit null" for
|
|
46
|
+
healthy skips — it will show the real exit code instead, so a legitimate
|
|
47
|
+
skip stops looking like a crash. Nothing changes about when jobs run or
|
|
48
|
+
skip; we just stopped hiding why.
|
|
49
|
+
|
|
50
|
+
## Summary of New Capabilities
|
|
51
|
+
|
|
52
|
+
| Capability | How it shows up |
|
|
53
|
+
|-----------|-----------------|
|
|
54
|
+
| Truthful gate exit codes | Activity feed and `job_gate_skip` events show the real exit code (e.g. `exit 1`) or signal (e.g. `exit SIGKILL`), never `exit null` for non-zero gates |
|
|
55
|
+
| Easier triage of stuck jobs | A job that "keeps skipping" now shows WHY (exit 1 = intentional skip; exit SIGKILL = runtime kill), so operators know whether to investigate |
|
|
56
|
+
|
|
57
|
+
## Evidence
|
|
58
|
+
|
|
59
|
+
- `JobScheduler` unit tests: 35/35 passing before and after the change.
|
|
60
|
+
- Error shape captured in the feedback cluster
|
|
61
|
+
(`cluster-jobscheduler-reports-gate-exit-code-as-null-for-every-legiti`):
|
|
62
|
+
`err.code: 1`, `err.status: undefined` — confirming the root cause.
|
|
63
|
+
- Side-effects review:
|
|
64
|
+
`upgrades/side-effects/scheduler-gate-exit-code.md` covers
|
|
65
|
+
over/under-block (n/a — no block surface), level-of-abstraction fit
|
|
66
|
+
(right layer, pure diagnostic signal), signal-vs-authority compliance
|
|
67
|
+
(pure signal quality, no authority change), interactions,
|
|
68
|
+
external surfaces (activity-feed strings + `metadata.exitCode` type
|
|
69
|
+
widening), and rollback cost (one-line revert).
|
|
70
|
+
|
|
71
|
+
## Deployment Notes
|
|
72
|
+
|
|
73
|
+
No operator action required. Agents pick this up automatically on the
|
|
74
|
+
next AutoUpdater cycle.
|
|
75
|
+
|
|
76
|
+
## Rollback
|
|
77
|
+
|
|
78
|
+
Revert the single commit. `metadata.exitCode` returns to being a
|
|
79
|
+
`number | null`, activity feed returns to showing `exit null` for
|
|
80
|
+
legitimate non-zero skips. No schema or state-file changes.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Upgrade Guide — v0.28.64
|
|
2
|
+
|
|
3
|
+
<!-- bump: patch -->
|
|
4
|
+
|
|
5
|
+
## What Changed
|
|
6
|
+
|
|
7
|
+
**JobLoader per-entry resilience.** `JobLoader.loadJobs` now logs and
|
|
8
|
+
skips invalid job entries instead of throwing on the first one. One
|
|
9
|
+
malformed job (e.g. missing `name`/`priority` or an invalid
|
|
10
|
+
`execute.type`) previously took down the whole scheduler — propagating
|
|
11
|
+
through `JobScheduler.start` and killing the HTTP server before port
|
|
12
|
+
bind, which cascaded to the dashboard, feedback pipeline, attention
|
|
13
|
+
queue, and Telegram poller. Now each bad entry is logged (to
|
|
14
|
+
`console.error` with index + slug + validation error) and skipped;
|
|
15
|
+
valid sibling entries load normally. Structural errors (missing file,
|
|
16
|
+
unparseable JSON, non-array root) still throw — those indicate nothing
|
|
17
|
+
can be loaded at all. `validateJob` is unchanged and still throws on a
|
|
18
|
+
single bad entry, so CLI validators and tests keep their strict
|
|
19
|
+
single-entry semantics.
|
|
20
|
+
|
|
21
|
+
Fixes `cluster-jobloader-crashes-entire-server-on-one-bad-job-supervisor-ci`.
|
|
22
|
+
See `docs/specs/jobloader-per-entry-resilience.md` and
|
|
23
|
+
`upgrades/side-effects/jobloader-per-entry-resilience.md`.
|
|
24
|
+
|
|
25
|
+
## What to Tell Your User
|
|
26
|
+
|
|
27
|
+
- "If one job in my jobs file is broken, the others still run. The broken one gets logged and skipped instead of taking down everything."
|
|
28
|
+
|
|
29
|
+
## Summary of New Capabilities
|
|
30
|
+
|
|
31
|
+
- `JobLoader.loadJobs` skips invalid entries with `console.error` + summary `console.warn` instead of throwing.
|
|
32
|
+
|
|
33
|
+
## Evidence
|
|
34
|
+
|
|
35
|
+
**Reproduction (before the fix).** Reporter electruck, 2026-04-17: commit `a4d7376` in their agent appended a new job to `.instar/jobs.json` missing required `name` and `priority`, with invalid `execute.type: "bash"`. `validateJob` threw on the first missing field; `JobScheduler.start()` propagated the throw; `startServer()` died before binding port 4041. The lifeline supervisor restarted the server 5× — each failure reported as "Server unhealthy" (actually: never started) — then entered long-backoff with no user-visible alert. Ten healthy jobs plus the HTTP API, dashboard, feedback pipeline, attention queue, and Telegram poller all stopped because of one typo.
|
|
36
|
+
|
|
37
|
+
**After the fix.** The same jobs file boots successfully. The malformed entry emits `[JobLoader] Skipping invalid job at index N (slug="contact-proposer"): Job[N]: "name" is required and must be a non-empty string` to `console.error`, followed by a `console.warn` summary `Loaded N valid job(s); skipped 1 invalid entry(ies). Fix the skipped entries to restore full scheduler coverage.` Valid siblings load normally and the scheduler runs.
|
|
38
|
+
|
|
39
|
+
**Unit-test evidence** (`npx vitest run tests/unit/JobLoader.test.ts tests/unit/job-loader-common-blockers.test.ts` at commit `058f1fe`):
|
|
40
|
+
|
|
41
|
+
- New positive test `skips invalid entries and loads valid ones (does not throw)` — writes a jobs file with the exact shape of the failing production entry (`execute.type: "bash"`, missing `name`+`priority`) sandwiched between two valid jobs; asserts the loader returns the two valid jobs and logs the skip. Passes.
|
|
42
|
+
- Updated integration test `commonBlockers validation runs during loadJobs (entry skipped with logged error)` — writes a job with a malformed `commonBlockers.description`; asserts zero valid jobs and the validation message on `console.error`. Passes.
|
|
43
|
+
- Full: 102/102 tests across the two files. All 41 pre-existing `validateJob` throw-tests continue to pass — `validateJob` is byte-identical.
|
|
44
|
+
|
|
45
|
+
**Scope of what changed.** Only `JobLoader.loadJobs` (fail-fast → log-and-skip). `validateJob` and `validateCommonBlockers` unchanged. Structural errors (missing file, unparseable JSON, non-array root) still throw.
|
package/upgrades/NEXT.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Upgrade Guide — vNEXT
|
|
2
|
+
|
|
3
|
+
<!-- bump: patch -->
|
|
4
|
+
<!-- Valid values: patch, minor, major -->
|
|
5
|
+
<!-- patch = bug fixes, refactors, test additions, doc updates -->
|
|
6
|
+
<!-- minor = new features, new APIs, new capabilities (backwards-compatible) -->
|
|
7
|
+
<!-- major = breaking changes to existing APIs or behavior -->
|
|
8
|
+
|
|
9
|
+
## What Changed
|
|
10
|
+
|
|
11
|
+
<!-- Describe what changed technically. What new features, APIs, behavioral changes? -->
|
|
12
|
+
<!-- Write this for the AGENT — they need to understand the system deeply. -->
|
|
13
|
+
|
|
14
|
+
## What to Tell Your User
|
|
15
|
+
|
|
16
|
+
<!-- Write talking points the agent should relay to their user. -->
|
|
17
|
+
<!-- This should be warm, conversational, user-facing — not a changelog. -->
|
|
18
|
+
<!-- Focus on what THEY can now do, not internal plumbing. -->
|
|
19
|
+
<!-- -->
|
|
20
|
+
<!-- PROHIBITED in this section (will fail validation): -->
|
|
21
|
+
<!-- camelCase config keys: silentReject, maxRetries, telegramNotify -->
|
|
22
|
+
<!-- Inline code backtick references like silentReject: false -->
|
|
23
|
+
<!-- Fenced code blocks -->
|
|
24
|
+
<!-- Instructions to edit files or run commands -->
|
|
25
|
+
<!-- -->
|
|
26
|
+
<!-- CORRECT style: "I can turn that on for you" not "set X to false" -->
|
|
27
|
+
<!-- The agent relays this to their user — keep it human. -->
|
|
28
|
+
|
|
29
|
+
- **[Feature name]**: "[Brief, friendly description of what this means for the user]"
|
|
30
|
+
|
|
31
|
+
## Summary of New Capabilities
|
|
32
|
+
|
|
33
|
+
| Capability | How to Use |
|
|
34
|
+
|-----------|-----------|
|
|
35
|
+
| [Capability] | [Endpoint, command, or "automatic"] |
|
|
36
|
+
|
|
37
|
+
## Evidence
|
|
38
|
+
|
|
39
|
+
<!-- REQUIRED if this release claims to fix a bug. -->
|
|
40
|
+
<!-- Unit tests passing is NOT evidence. Provide ONE of: -->
|
|
41
|
+
<!-- (a) Reproduction steps + observed before/after on a live system. -->
|
|
42
|
+
<!-- Include log excerpts, observed command output, or behavior -->
|
|
43
|
+
<!-- description. Make it specific enough that a future reader can -->
|
|
44
|
+
<!-- re-run it and see the same thing. -->
|
|
45
|
+
<!-- (b) "Not reproducible in dev — [concrete reason]" if the failure -->
|
|
46
|
+
<!-- mode truly can't be exercised locally (race conditions, -->
|
|
47
|
+
<!-- event-driven paths requiring external signals, etc). -->
|
|
48
|
+
<!-- -->
|
|
49
|
+
<!-- If this release doesn't claim a bug fix (pure feature / refactor), -->
|
|
50
|
+
<!-- leave this section blank or delete it — it's only enforced when -->
|
|
51
|
+
<!-- "What Changed" describes a fix. -->
|
|
52
|
+
|
|
53
|
+
[Describe reproduction + verified fix, OR "Not reproducible in dev — [concrete reason]"]
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# Side-Effects Review — JobLoader per-entry resilience
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `jobloader-per-entry-resilience`
|
|
4
|
+
**Date:** `2026-04-19`
|
|
5
|
+
**Author:** Dawn (autonomous, instar-bug-fix job AUT-5808-wo)
|
|
6
|
+
**Second-pass reviewer:** not required (LOW risk, per instar-bug-fix grounding)
|
|
7
|
+
|
|
8
|
+
## Summary of the change
|
|
9
|
+
|
|
10
|
+
`loadJobs()` in `src/scheduler/JobLoader.ts` is changed from fail-fast
|
|
11
|
+
(first invalid entry throws and aborts the whole load) to fail-soft at
|
|
12
|
+
the entry level (each invalid entry is logged and skipped; valid entries
|
|
13
|
+
load). Structural errors (missing file, unparseable JSON, non-array
|
|
14
|
+
root) still throw because those indicate nothing can be loaded at all.
|
|
15
|
+
`validateJob` is unchanged and still throws on invalid input — callers
|
|
16
|
+
that want single-entry validation (tests, future CLI validators) are
|
|
17
|
+
unaffected. A new test covers the skip path; all existing tests
|
|
18
|
+
continue to pass.
|
|
19
|
+
|
|
20
|
+
Files touched:
|
|
21
|
+
|
|
22
|
+
- `src/scheduler/JobLoader.ts` — `loadJobs()` body only.
|
|
23
|
+
- `tests/unit/JobLoader.test.ts` — one additional positive test.
|
|
24
|
+
|
|
25
|
+
Decision-point surface: this change has no block/allow authority
|
|
26
|
+
surface; it's a resilience fix on a JSON loader.
|
|
27
|
+
|
|
28
|
+
## Decision-point inventory
|
|
29
|
+
|
|
30
|
+
- `JobLoader.loadJobs()` — **modify** — was: throw on first invalid
|
|
31
|
+
entry; now: log+skip invalid entries, return valid subset.
|
|
32
|
+
- `JobLoader.validateJob()` — **pass-through** — unchanged; still
|
|
33
|
+
throws. Exported so CLI validators / unit tests can reuse it.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 1. Over-block
|
|
38
|
+
|
|
39
|
+
**What legitimate inputs does this change reject that it shouldn't?**
|
|
40
|
+
|
|
41
|
+
No block/allow surface — over-block not applicable. The change does
|
|
42
|
+
the opposite: it *accepts* more inputs (files with some invalid
|
|
43
|
+
entries) than before. Valid entries that were previously rejected
|
|
44
|
+
(because an earlier sibling was invalid) are now accepted.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## 2. Under-block
|
|
49
|
+
|
|
50
|
+
**What failure modes does this still miss?**
|
|
51
|
+
|
|
52
|
+
No block/allow surface — under-block not applicable. Per-entry
|
|
53
|
+
validation is unchanged; `validateJob` still catches the same set of
|
|
54
|
+
malformed shapes it always did. The only difference is whether a catch
|
|
55
|
+
aborts the whole load or only the bad entry.
|
|
56
|
+
|
|
57
|
+
One adjacent concern: a skipped job is a silently-not-running job.
|
|
58
|
+
This is mitigated by `console.error` per skipped entry (with slug and
|
|
59
|
+
error) and a `console.warn` summary (`Loaded N valid job(s); skipped M
|
|
60
|
+
invalid entry(ies)`). Full escalation (attention-queue entry, Telegram
|
|
61
|
+
alert) is Proposal B from the originating feedback cluster and is
|
|
62
|
+
tracked as a separate improvement.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## 3. Level-of-abstraction fit
|
|
67
|
+
|
|
68
|
+
**Is this at the right layer?**
|
|
69
|
+
|
|
70
|
+
Yes. `JobLoader` is a pure loader/validator — it converts bytes on
|
|
71
|
+
disk into a typed array of job definitions. Resilience at this layer
|
|
72
|
+
is the correct place to isolate a malformed entry: every downstream
|
|
73
|
+
consumer (`JobScheduler.start`, `startServer`, the HTTP API, the
|
|
74
|
+
dashboard, the feedback pipeline, the attention queue, the Telegram
|
|
75
|
+
poller) should see the same "valid-only" view and not have to
|
|
76
|
+
implement its own defensive skip. Moving resilience any higher (e.g.,
|
|
77
|
+
wrapping `JobScheduler.start` in a try/catch) would lose the per-entry
|
|
78
|
+
granularity; any lower (e.g., validating inside each consumer) would
|
|
79
|
+
duplicate logic.
|
|
80
|
+
|
|
81
|
+
`validateJob` stays pure and throwing, so future smarter gates (a
|
|
82
|
+
`instar jobs validate` CLI, an editor-time schema check, a staged-diff
|
|
83
|
+
precommit) can reuse it as a plain classifier without re-implementing
|
|
84
|
+
validation.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## 4. Signal vs authority compliance
|
|
89
|
+
|
|
90
|
+
**Required reference:** [docs/signal-vs-authority.md](../../docs/signal-vs-authority.md)
|
|
91
|
+
|
|
92
|
+
**Does this change hold blocking authority with brittle logic?**
|
|
93
|
+
|
|
94
|
+
- [x] No — this change has no block/allow surface.
|
|
95
|
+
|
|
96
|
+
`JobLoader` is a loader, not a gate. It doesn't decide whether a
|
|
97
|
+
message is allowed, whether an outbound action may fire, or whether a
|
|
98
|
+
user may take an action. The "skip invalid entry" path is a local
|
|
99
|
+
recovery, not a policy decision; the one who decides whether a skipped
|
|
100
|
+
entry matters operationally is the human reading `console.error` (and,
|
|
101
|
+
in the future, Proposal B's supervisor escalation).
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## 5. Interactions
|
|
106
|
+
|
|
107
|
+
- **Shadowing:** no other validation runs before `loadJobs`; schedulers
|
|
108
|
+
consume its return value directly. Skipped entries simply don't
|
|
109
|
+
appear in the returned array; downstream code continues to see a
|
|
110
|
+
clean, typed list. No shadowing risk.
|
|
111
|
+
- **Double-fire:** the loader runs once per `loadJobs` call. Skipped
|
|
112
|
+
entries aren't re-processed anywhere else.
|
|
113
|
+
- **Races:** no shared mutable state. Pure function over a filesystem
|
|
114
|
+
read; concurrent reads are safe.
|
|
115
|
+
- **Feedback loops:** none. The loader does not write back to the
|
|
116
|
+
jobs file; there's no loop between "skipped entries" and "future
|
|
117
|
+
loader behavior."
|
|
118
|
+
- **Grounding audit:** `auditGrounding(jobs)` continues to run over
|
|
119
|
+
the valid subset, which is the intended behavior — ungrounded
|
|
120
|
+
warnings apply only to jobs the scheduler is actually trying to run.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## 6. External surfaces
|
|
125
|
+
|
|
126
|
+
- **Other agents on the same machine:** none. This is a per-agent
|
|
127
|
+
loader; each agent loads its own jobs file.
|
|
128
|
+
- **Install base:** existing agents with valid jobs files see
|
|
129
|
+
identical behavior. Agents with a file that currently crashes the
|
|
130
|
+
loader will boot successfully after upgrade with skipped entries
|
|
131
|
+
logged to stderr.
|
|
132
|
+
- **External systems:** none. No Telegram/Slack/GitHub/Cloudflare
|
|
133
|
+
impact.
|
|
134
|
+
- **Persistent state:** none. No database, ledger, or memory-file
|
|
135
|
+
writes.
|
|
136
|
+
- **Timing / runtime:** strictly improves boot reliability under
|
|
137
|
+
malformed config; no regression possible in the positive case.
|
|
138
|
+
- **Stdout/stderr:** new `console.error` lines per skipped entry and a
|
|
139
|
+
summary `console.warn`. Agents that scrape startup logs for errors
|
|
140
|
+
will see new "Skipping invalid job" lines when applicable — this is
|
|
141
|
+
a feature, not a regression: today, those agents see no line at all
|
|
142
|
+
because the whole process dies before logging anything about the
|
|
143
|
+
jobs layer.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## 7. Rollback cost
|
|
148
|
+
|
|
149
|
+
Pure code change. Revert the commit, ship as next patch — no
|
|
150
|
+
persistent state, no data migration, no agent-state repair needed, no
|
|
151
|
+
user-visible regression during the rollback window. Any jobs file
|
|
152
|
+
that previously crashed would go back to crashing; any that loaded
|
|
153
|
+
cleanly would continue to load cleanly.
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Conclusion
|
|
158
|
+
|
|
159
|
+
Low-risk, narrowly-scoped resilience fix on a pure loader. No
|
|
160
|
+
block/allow authority surface, no signal-vs-authority concerns, no
|
|
161
|
+
external state touched. The change captures exactly Proposal A from
|
|
162
|
+
the originating feedback cluster (reporter electruck, 2026-04-17),
|
|
163
|
+
preserves `validateJob` exactly so that Proposal C (CLI validator) can
|
|
164
|
+
reuse it, and leaves Proposal B (supervisor escalation) as a separate
|
|
165
|
+
improvement. Clear to ship.
|
|
166
|
+
|
|
167
|
+
## Evidence pointers
|
|
168
|
+
|
|
169
|
+
- Build: `npm run build` passes (tsc + generate-builtin-manifest.cjs).
|
|
170
|
+
- Tests: `npx vitest run tests/unit/JobLoader.test.ts` — 41 passed
|
|
171
|
+
(40 pre-existing + 1 new "skips invalid entries and loads valid
|
|
172
|
+
ones" test).
|
|
173
|
+
- The new test encodes the exact shape of the failing entry from the
|
|
174
|
+
reporter's incident (`execute.type: "bash"`, missing `name` +
|
|
175
|
+
`priority`) and asserts that sibling valid entries still load.
|