wicked-crew 0.9.5 → 0.9.6

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.
Files changed (50) hide show
  1. package/dist/api/delivery-assurance.d.ts.map +1 -1
  2. package/dist/api/delivery-assurance.js +3 -0
  3. package/dist/api/delivery-assurance.js.map +1 -1
  4. package/dist/api/routes.d.ts.map +1 -1
  5. package/dist/api/routes.js +17 -3
  6. package/dist/api/routes.js.map +1 -1
  7. package/dist/api/server.d.ts +6 -0
  8. package/dist/api/server.d.ts.map +1 -1
  9. package/dist/api/server.js +28 -0
  10. package/dist/api/server.js.map +1 -1
  11. package/dist/core/adapter.d.ts.map +1 -1
  12. package/dist/core/adapter.js +8 -0
  13. package/dist/core/adapter.js.map +1 -1
  14. package/dist/core/council-settings.d.ts +18 -0
  15. package/dist/core/council-settings.d.ts.map +1 -0
  16. package/dist/core/council-settings.js +37 -0
  17. package/dist/core/council-settings.js.map +1 -0
  18. package/dist/learn/routes.d.ts +42 -0
  19. package/dist/learn/routes.d.ts.map +1 -0
  20. package/dist/learn/routes.js +87 -0
  21. package/dist/learn/routes.js.map +1 -0
  22. package/dist/learn/schedule-store.d.ts +41 -0
  23. package/dist/learn/schedule-store.d.ts.map +1 -0
  24. package/dist/learn/schedule-store.js +137 -0
  25. package/dist/learn/schedule-store.js.map +1 -0
  26. package/dist/learn/scheduler.d.ts +71 -0
  27. package/dist/learn/scheduler.d.ts.map +1 -0
  28. package/dist/learn/scheduler.js +222 -0
  29. package/dist/learn/scheduler.js.map +1 -0
  30. package/dist/learn/topics.d.ts +14 -0
  31. package/dist/learn/topics.d.ts.map +1 -0
  32. package/dist/learn/topics.js +95 -0
  33. package/dist/learn/topics.js.map +1 -0
  34. package/dist/projects/graph.d.ts +14 -0
  35. package/dist/projects/graph.d.ts.map +1 -1
  36. package/dist/projects/graph.js +41 -2
  37. package/dist/projects/graph.js.map +1 -1
  38. package/dist/projects/state-home-registry.d.ts.map +1 -1
  39. package/dist/projects/state-home-registry.js +2 -0
  40. package/dist/projects/state-home-registry.js.map +1 -1
  41. package/dist/studio/assets/index-C0ZMi_8d.js +583 -0
  42. package/dist/studio/assets/index-DYLo25MW.css +32 -0
  43. package/dist/studio/editors/wicked-page/editor.json +1 -1
  44. package/dist/studio/editors/wicked-page/index.html +1 -1
  45. package/dist/studio/index.html +2 -2
  46. package/dist/studio/testid-inventory.json +494 -36
  47. package/endpoint-manifest.json +55 -1
  48. package/package.json +3 -3
  49. package/dist/studio/assets/index-BGfFmWw4.css +0 -32
  50. package/dist/studio/assets/index-U8MkVhYB.js +0 -567
@@ -0,0 +1,137 @@
1
+ /**
2
+ * The learn schedule (DES-learn-workflow §5): a durable record per learned topic saying how often
3
+ * the daemon re-runs the `learn` workflow on it. Crew is the single source of truth for a
4
+ * schedule; the topic's files in the repository do not repeat it.
5
+ *
6
+ * Same storage posture as `projects/settings.ts`: a small JSON map in the daemon's state home
7
+ * (`learn-schedules.json`, following `--db`; `WICKED_CREW_LEARN_SCHEDULES` overrides), written
8
+ * atomically (tmp + rename), read tolerantly per row (a malformed row is dropped, never the map).
9
+ */
10
+ import { mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
11
+ import { dirname, join } from 'node:path';
12
+ import { crewStateHome } from '../projects/state-home.js';
13
+ export const LEARN_SLUG = /^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$/;
14
+ export const MIN_EVERY_HOURS = 24;
15
+ export const MAX_EVERY_HOURS = 2160;
16
+ const HOUR_MS = 3_600_000;
17
+ const OUTCOMES = new Set(['launched', 'refused', 'completed', 'failed', 'cancelled']);
18
+ export function scheduleId(repoRef, slug) {
19
+ return `${repoRef}:${slug}`;
20
+ }
21
+ export function defaultSchedulesPath(env = process.env) {
22
+ return env['WICKED_CREW_LEARN_SCHEDULES'] ?? join(crewStateHome(), 'learn-schedules.json');
23
+ }
24
+ const str = (v) => typeof v === 'string';
25
+ const strOrNull = (v) => v === null || typeof v === 'string';
26
+ /** A row as read from disk, or `null` when it is malformed. */
27
+ function parseRow(id, raw) {
28
+ if (typeof raw !== 'object' || raw === null)
29
+ return null;
30
+ const r = raw;
31
+ if (!str(r['repoRef']) || !str(r['slug']) || !LEARN_SLUG.test(r['slug']) || !str(r['topic']))
32
+ return null;
33
+ if (id !== scheduleId(r['repoRef'], r['slug']))
34
+ return null;
35
+ const every = r['everyHours'];
36
+ if (typeof every !== 'number' || !Number.isInteger(every) || every < MIN_EVERY_HOURS || every > MAX_EVERY_HOURS)
37
+ return null;
38
+ if (typeof r['enabled'] !== 'boolean' || !str(r['nextDueAt']) || Number.isNaN(Date.parse(r['nextDueAt'])))
39
+ return null;
40
+ const outcome = r['lastOutcome'];
41
+ return {
42
+ id,
43
+ repoRef: r['repoRef'],
44
+ slug: r['slug'],
45
+ topic: r['topic'],
46
+ ...(str(r['projectId']) ? { projectId: r['projectId'] } : {}),
47
+ everyHours: every,
48
+ enabled: r['enabled'],
49
+ nextDueAt: r['nextDueAt'],
50
+ lastRunId: strOrNull(r['lastRunId']) ? r['lastRunId'] : null,
51
+ lastRunAt: strOrNull(r['lastRunAt']) ? r['lastRunAt'] : null,
52
+ lastOutcome: str(outcome) && OUTCOMES.has(outcome) ? outcome : null,
53
+ failures: typeof r['failures'] === 'number' && r['failures'] >= 0 ? Math.floor(r['failures']) : 0,
54
+ lastError: strOrNull(r['lastError']) ? r['lastError'] : null,
55
+ indexedTree: strOrNull(r['indexedTree']) ? r['indexedTree'] : null,
56
+ createdAt: str(r['createdAt']) ? r['createdAt'] : r['nextDueAt'],
57
+ updatedAt: str(r['updatedAt']) ? r['updatedAt'] : r['nextDueAt'],
58
+ };
59
+ }
60
+ export class LearnScheduleStore {
61
+ path;
62
+ rows = new Map();
63
+ constructor(path) {
64
+ this.path = path ?? defaultSchedulesPath();
65
+ try {
66
+ const parsed = JSON.parse(readFileSync(this.path, 'utf8'));
67
+ for (const [id, raw] of Object.entries(parsed?.schedules ?? {})) {
68
+ const row = parseRow(id, raw);
69
+ if (row !== null)
70
+ this.rows.set(id, row);
71
+ }
72
+ }
73
+ catch {
74
+ // Missing or malformed: start empty (no schedule fires), never fail the boot.
75
+ }
76
+ }
77
+ list() {
78
+ return [...this.rows.values()].sort((a, b) => a.nextDueAt.localeCompare(b.nextDueAt) || a.id.localeCompare(b.id));
79
+ }
80
+ get(id) {
81
+ const row = this.rows.get(id);
82
+ return row === undefined ? undefined : { ...row };
83
+ }
84
+ /** Create or update. A new row is first due one interval from now; an update keeps its run
85
+ * history and moves `nextDueAt` only when the interval changed. */
86
+ put(input, now) {
87
+ const id = scheduleId(input.repoRef, input.slug);
88
+ const prev = this.rows.get(id);
89
+ const iso = now.toISOString();
90
+ const due = new Date(now.getTime() + input.everyHours * HOUR_MS).toISOString();
91
+ const row = {
92
+ id,
93
+ repoRef: input.repoRef,
94
+ slug: input.slug,
95
+ topic: input.topic,
96
+ ...(input.projectId !== undefined ? { projectId: input.projectId } : {}),
97
+ everyHours: input.everyHours,
98
+ enabled: input.enabled ?? prev?.enabled ?? true,
99
+ nextDueAt: prev === undefined || prev.everyHours !== input.everyHours ? due : prev.nextDueAt,
100
+ lastRunId: prev?.lastRunId ?? null,
101
+ lastRunAt: prev?.lastRunAt ?? null,
102
+ lastOutcome: prev?.lastOutcome ?? null,
103
+ failures: prev?.failures ?? 0,
104
+ lastError: prev?.lastError ?? null,
105
+ indexedTree: prev?.indexedTree ?? null,
106
+ createdAt: prev?.createdAt ?? iso,
107
+ updatedAt: iso,
108
+ };
109
+ this.rows.set(id, row);
110
+ this.persist();
111
+ return { ...row };
112
+ }
113
+ /** Merge a patch into an existing row (the scheduler's bookkeeping). `undefined` when unknown. */
114
+ update(id, patch, now) {
115
+ const prev = this.rows.get(id);
116
+ if (prev === undefined)
117
+ return undefined;
118
+ const row = { ...prev, ...patch, updatedAt: now.toISOString() };
119
+ this.rows.set(id, row);
120
+ this.persist();
121
+ return { ...row };
122
+ }
123
+ delete(id) {
124
+ const had = this.rows.delete(id);
125
+ if (had)
126
+ this.persist();
127
+ return had;
128
+ }
129
+ persist() {
130
+ mkdirSync(dirname(this.path), { recursive: true });
131
+ const tmp = `${this.path}.tmp-${process.pid}`;
132
+ writeFileSync(tmp, JSON.stringify({ schedules: Object.fromEntries(this.rows) }, null, 2), 'utf8');
133
+ renameSync(tmp, this.path);
134
+ }
135
+ }
136
+ export const HOURS = HOUR_MS;
137
+ //# sourceMappingURL=schedule-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedule-store.js","sourceRoot":"","sources":["../../src/learn/schedule-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * The learn schedule's tick (DES-learn-workflow §5.3). Once a minute:
3
+ *
4
+ * 1. RECONCILE — a schedule's last run that reached a terminal status records its outcome.
5
+ * 2. INDEX — a topic whose MERGED knowledge changed (`git fetch origin <default>`, then
6
+ * `git rev-parse origin/<default>:.wicked/knowledge/<slug>`; the checkout's working copy is never read)
7
+ * moved) is re-indexed into the estate knowledge store by garden's `scripts/learn/index.py`,
8
+ * spawned OUTSIDE any run (its env carries no run markers, so the estate opens writable), one
9
+ * spawn per sweep. Indexing reads the registered checkout, never an open pull request.
10
+ * 3. LAUNCH — at most ONE due schedule launches the `learn` workflow, and only while no schedule's
11
+ * run is still open and no run on the daemon is executing (one governed run at a time). The
12
+ * launch delivers a pull request behind the engine's human deliver gate; nothing auto-merges.
13
+ * A refused launch backs off exponentially (capped at a day); missed intervals coalesce.
14
+ *
15
+ * Never throws; a slow sweep never stacks (`sweeping`).
16
+ */
17
+ import type { CoreAdapter } from '../core/adapter.js';
18
+ import type { Actor, CoreEvent } from '../core/types.js';
19
+ import type { AuditLog } from '../api/audit.js';
20
+ import { type RunTimingIndex } from '../api/run-timing-index.js';
21
+ import { type LearnSchedule, type LearnScheduleStore } from './schedule-store.js';
22
+ export declare const LEARN_WORKFLOW = "learn";
23
+ export declare const LEARN_SCHEDULE_ACTOR: Actor;
24
+ export declare const DEFAULT_LEARN_SWEEP_MS = 60000;
25
+ /** How long a launched run the daemon no longer lists keeps the schedule's slot (48 h). */
26
+ export declare const STALE_LAUNCH_MS: number;
27
+ /** The env a governed unit carries; the index spawn drops every one so estate opens writable. */
28
+ export declare const RUN_MARKER_ENV: string[];
29
+ export interface ExecResult {
30
+ code: number;
31
+ stdout: string;
32
+ stderr: string;
33
+ }
34
+ export type Exec = (cmd: string, args: string[], opts: {
35
+ cwd?: string;
36
+ env?: NodeJS.ProcessEnv;
37
+ timeoutMs: number;
38
+ }) => Promise<ExecResult>;
39
+ export declare const defaultExec: Exec;
40
+ export interface LearnSchedulerDeps {
41
+ store: LearnScheduleStore;
42
+ adapter: Pick<CoreAdapter, 'listRepos' | 'sessionsDetail' | 'seatsForWorkflow' | 'launchRun'>;
43
+ audit: AuditLog;
44
+ runTimingIndex: RunTimingIndex;
45
+ fileRun: (runId: string, projectId: string) => void;
46
+ broadcast: (frame: CoreEvent) => void;
47
+ log: (msg: string) => void;
48
+ now?: () => Date;
49
+ exec?: Exec;
50
+ env?: NodeJS.ProcessEnv;
51
+ }
52
+ /** The garden launcher: `$WICKED_GARDEN_ROOT/scripts/wicked-garden` when set, else `wicked-garden` on PATH. */
53
+ export declare function gardenLauncher(env: NodeJS.ProcessEnv): string;
54
+ /** `env` without the governed-run markers. */
55
+ export declare function unmarkedEnv(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
56
+ export declare function refreshProblem(row: LearnSchedule): string;
57
+ export declare class LearnScheduler {
58
+ private readonly deps;
59
+ private timer;
60
+ private sweeping;
61
+ constructor(deps: LearnSchedulerDeps);
62
+ start(intervalMs?: number): void;
63
+ stop(): void;
64
+ private now;
65
+ /** One sweep. Never throws. */
66
+ sweep(): Promise<void>;
67
+ private reconcile;
68
+ private indexOne;
69
+ private launchOne;
70
+ }
71
+ //# sourceMappingURL=scheduler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../src/learn/scheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACpF,OAAO,EAAS,KAAK,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzF,eAAO,MAAM,cAAc,UAAU,CAAC;AACtC,eAAO,MAAM,oBAAoB,EAAE,KAAmE,CAAC;AACvG,eAAO,MAAM,sBAAsB,QAAS,CAAC;AAC7C,2FAA2F;AAC3F,eAAO,MAAM,eAAe,QAAa,CAAC;AAI1C,iGAAiG;AACjG,eAAO,MAAM,cAAc,UAA4G,CAAC;AAExI,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AACD,MAAM,MAAM,IAAI,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;AAE5I,eAAO,MAAM,WAAW,EAAE,IAOtB,CAAC;AAEL,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,kBAAkB,CAAC;IAC1B,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,WAAW,GAAG,gBAAgB,GAAG,kBAAkB,GAAG,WAAW,CAAC,CAAC;IAC9F,KAAK,EAAE,QAAQ,CAAC;IAChB,cAAc,EAAE,cAAc,CAAC;IAC/B,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,SAAS,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;IACtC,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IACjB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAED,+GAA+G;AAC/G,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAG7D;AAED,8CAA8C;AAC9C,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAIrE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAMzD;AAED,qBAAa,cAAc;IAIb,OAAO,CAAC,QAAQ,CAAC,IAAI;IAHjC,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,QAAQ,CAAS;gBAEI,IAAI,EAAE,kBAAkB;IAErD,KAAK,CAAC,UAAU,SAAyB,GAAG,IAAI;IAMhD,IAAI,IAAI,IAAI;IAKZ,OAAO,CAAC,GAAG;IAIX,+BAA+B;IACzB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAkB5B,OAAO,CAAC,SAAS;YAUH,QAAQ;YAkCR,SAAS;CA6ExB"}
@@ -0,0 +1,222 @@
1
+ /**
2
+ * The learn schedule's tick (DES-learn-workflow §5.3). Once a minute:
3
+ *
4
+ * 1. RECONCILE — a schedule's last run that reached a terminal status records its outcome.
5
+ * 2. INDEX — a topic whose MERGED knowledge changed (`git fetch origin <default>`, then
6
+ * `git rev-parse origin/<default>:.wicked/knowledge/<slug>`; the checkout's working copy is never read)
7
+ * moved) is re-indexed into the estate knowledge store by garden's `scripts/learn/index.py`,
8
+ * spawned OUTSIDE any run (its env carries no run markers, so the estate opens writable), one
9
+ * spawn per sweep. Indexing reads the registered checkout, never an open pull request.
10
+ * 3. LAUNCH — at most ONE due schedule launches the `learn` workflow, and only while no schedule's
11
+ * run is still open and no run on the daemon is executing (one governed run at a time). The
12
+ * launch delivers a pull request behind the engine's human deliver gate; nothing auto-merges.
13
+ * A refused launch backs off exponentially (capped at a day); missed intervals coalesce.
14
+ *
15
+ * Never throws; a slow sweep never stacks (`sweeping`).
16
+ */
17
+ import { execFile } from 'node:child_process';
18
+ import { randomUUID } from 'node:crypto';
19
+ import { childEnvWithBootEstateDb } from '../core/governance-store.js';
20
+ import { recordRunLaunched } from '../api/run-timing-index.js';
21
+ import { HOURS } from './schedule-store.js';
22
+ export const LEARN_WORKFLOW = 'learn';
23
+ export const LEARN_SCHEDULE_ACTOR = { id: 'learn-schedule', kind: 'system', trust: 'operator' };
24
+ export const DEFAULT_LEARN_SWEEP_MS = 60_000;
25
+ /** How long a launched run the daemon no longer lists keeps the schedule's slot (48 h). */
26
+ export const STALE_LAUNCH_MS = 48 * HOURS;
27
+ /** A run that holds the host: one governed run at a time (a run parked on a human is not busy). */
28
+ const BUSY = new Set(['planning', 'distributing', 'executing']);
29
+ const TERMINAL = new Set(['completed', 'failed', 'cancelled']);
30
+ /** The env a governed unit carries; the index spawn drops every one so estate opens writable. */
31
+ export const RUN_MARKER_ENV = ['WICKED_RUN_ID', 'WICKED_GATE_SCOPE', 'WICKED_WRITE_ROOTS', 'WICKED_GOVERNED', 'WICKED_ESTATE_READONLY'];
32
+ export const defaultExec = (cmd, args, opts) => new Promise((resolve) => {
33
+ // crew#495: a child never inherits a daemon-exported governance store.
34
+ execFile(cmd, args, { cwd: opts.cwd, env: childEnvWithBootEstateDb(opts.env ?? process.env), timeout: opts.timeoutMs, maxBuffer: 4 * 1024 * 1024 }, (err, stdout, stderr) => {
35
+ const code = err === null ? 0 : typeof err.code === 'number' ? (err.code) : 1;
36
+ resolve({ code, stdout: String(stdout), stderr: String(stderr) });
37
+ });
38
+ });
39
+ /** The garden launcher: `$WICKED_GARDEN_ROOT/scripts/wicked-garden` when set, else `wicked-garden` on PATH. */
40
+ export function gardenLauncher(env) {
41
+ const root = env['WICKED_GARDEN_ROOT'];
42
+ return root !== undefined && root !== '' ? `${root.replace(/\/+$/, '')}/scripts/wicked-garden` : 'wicked-garden';
43
+ }
44
+ /** `env` without the governed-run markers. */
45
+ export function unmarkedEnv(env) {
46
+ const out = { ...env };
47
+ for (const k of RUN_MARKER_ENV)
48
+ delete out[k];
49
+ return out;
50
+ }
51
+ export function refreshProblem(row) {
52
+ return (`Refresh learn topic "${row.topic}" (.wicked/knowledge/${row.slug}/): re-research what changed since the ` +
53
+ `topic's refreshed_at and propose only changes (confirm, supersede, contradict, retire) per the ` +
54
+ `wicked-garden-learn skill's refresh rules.`);
55
+ }
56
+ export class LearnScheduler {
57
+ deps;
58
+ timer = null;
59
+ sweeping = false;
60
+ constructor(deps) {
61
+ this.deps = deps;
62
+ }
63
+ start(intervalMs = DEFAULT_LEARN_SWEEP_MS) {
64
+ if (this.timer !== null)
65
+ return;
66
+ this.timer = setInterval(() => void this.sweep(), intervalMs);
67
+ this.timer.unref?.();
68
+ }
69
+ stop() {
70
+ if (this.timer !== null)
71
+ clearInterval(this.timer);
72
+ this.timer = null;
73
+ }
74
+ now() {
75
+ return this.deps.now?.() ?? new Date();
76
+ }
77
+ /** One sweep. Never throws. */
78
+ async sweep() {
79
+ if (this.sweeping)
80
+ return;
81
+ this.sweeping = true;
82
+ try {
83
+ const rows = this.deps.store.list();
84
+ if (rows.length === 0)
85
+ return;
86
+ const views = await this.deps.adapter.sessionsDetail();
87
+ const status = new Map(views.map((v) => [v.session.id, v.session.status]));
88
+ this.reconcile(rows, status);
89
+ await this.indexOne(this.deps.store.list());
90
+ await this.launchOne(this.deps.store.list(), status);
91
+ }
92
+ catch (err) {
93
+ this.deps.log(`[learn-schedule] sweep failed: ${err instanceof Error ? err.message : String(err)}`);
94
+ }
95
+ finally {
96
+ this.sweeping = false;
97
+ }
98
+ }
99
+ reconcile(rows, status) {
100
+ for (const row of rows) {
101
+ if (row.lastRunId === null || row.lastOutcome !== 'launched')
102
+ continue;
103
+ const s = status.get(row.lastRunId);
104
+ if (s !== undefined && TERMINAL.has(s)) {
105
+ this.deps.store.update(row.id, { lastOutcome: s }, this.now());
106
+ }
107
+ }
108
+ }
109
+ async indexOne(rows) {
110
+ const exec = this.deps.exec ?? defaultExec;
111
+ const env = this.deps.env ?? process.env;
112
+ const repos = await this.deps.adapter.listRepos();
113
+ for (const row of rows) {
114
+ if (!row.enabled)
115
+ continue;
116
+ const repo = repos.find((r) => r.id === row.repoRef);
117
+ if (repo === undefined || !repo.root_path)
118
+ continue;
119
+ // What MERGED: the remote default branch, fetched (a run's pull request merges there; the
120
+ // registered checkout itself is never pulled or modified, only its remote-tracking ref moves).
121
+ const branch = repo.default_branch || 'main';
122
+ const ref = `origin/${branch}`;
123
+ const fetched = await exec('git', ['-C', repo.root_path, 'fetch', '--quiet', 'origin', `${branch}:refs/remotes/origin/${branch}`], { timeoutMs: 30_000 });
124
+ // A failed fetch keeps the last fetched origin/<default> (codex r1): never the checkout's HEAD,
125
+ // which may be an unmerged branch. No remote-tracking ref at all: nothing merged to index.
126
+ if (fetched.code !== 0)
127
+ this.deps.log(`[learn-schedule] fetch of ${ref} for ${row.id} failed; using the last fetched ${ref}`);
128
+ const tree = await exec('git', ['-C', repo.root_path, 'rev-parse', `${ref}:.wicked/knowledge/${row.slug}`], { timeoutMs: 5_000 });
129
+ const sha = tree.code === 0 ? tree.stdout.trim() : '';
130
+ if (sha === '' || sha === row.indexedTree)
131
+ continue;
132
+ const res = await exec(gardenLauncher(env), ['run', 'scripts/learn/index.py', '--repo', repo.root_path, '--ref', ref, '--name', repo.name, '--slug', row.slug], { cwd: repo.root_path, env: unmarkedEnv(env), timeoutMs: 120_000 });
133
+ if (res.code === 0) {
134
+ this.deps.store.update(row.id, { indexedTree: sha }, this.now());
135
+ this.deps.log(`[learn-schedule] indexed ${row.id} at tree ${sha.slice(0, 12)}`);
136
+ }
137
+ else {
138
+ this.deps.log(`[learn-schedule] index of ${row.id} failed (exit ${res.code}): ${(res.stderr || res.stdout).slice(0, 300)}`);
139
+ }
140
+ return; // one index spawn per sweep
141
+ }
142
+ }
143
+ async launchOne(rows, status) {
144
+ const now = this.now();
145
+ // A launched run the list does not show (yet) counts as OPEN — never launch a second refresh
146
+ // on a guess — unless it was launched over STALE_LAUNCH_MS ago (archived or lost: stop waiting).
147
+ const open = rows.some((r) => {
148
+ if (r.lastRunId === null || r.lastOutcome !== 'launched')
149
+ return false;
150
+ const s = status.get(r.lastRunId);
151
+ if (s !== undefined)
152
+ return !TERMINAL.has(s);
153
+ return r.lastRunAt !== null && now.getTime() - Date.parse(r.lastRunAt) < STALE_LAUNCH_MS;
154
+ });
155
+ if (open)
156
+ return;
157
+ if ([...status.values()].some((s) => BUSY.has(s)))
158
+ return;
159
+ const due = rows
160
+ .filter((r) => r.enabled && Date.parse(r.nextDueAt) <= now.getTime())
161
+ .sort((a, b) => a.nextDueAt.localeCompare(b.nextDueAt))[0];
162
+ if (due === undefined)
163
+ return;
164
+ let runId;
165
+ try {
166
+ const clisJson = JSON.stringify(await this.deps.adapter.seatsForWorkflow(LEARN_WORKFLOW));
167
+ // Re-read right before the launch (codex r1): the index spawn and the seat read above can take
168
+ // minutes, and another surface may have started a run meanwhile.
169
+ const fresh = await this.deps.adapter.sessionsDetail();
170
+ if (fresh.some((v) => BUSY.has(v.session.status)))
171
+ return;
172
+ runId = await this.deps.adapter.launchRun({
173
+ problem: refreshProblem(due),
174
+ sessionId: randomUUID(),
175
+ clisJson,
176
+ workflow: LEARN_WORKFLOW,
177
+ repoRef: due.repoRef,
178
+ deliver: 'pr',
179
+ ...(due.projectId !== undefined ? { projectId: due.projectId } : {}),
180
+ });
181
+ }
182
+ catch (err) {
183
+ const failures = due.failures + 1;
184
+ const message = err instanceof Error ? err.message : String(err);
185
+ this.deps.store.update(due.id, {
186
+ failures,
187
+ lastOutcome: 'refused',
188
+ lastError: message.slice(0, 500),
189
+ nextDueAt: new Date(now.getTime() + Math.min(2 ** failures, 24) * HOURS).toISOString(),
190
+ }, now);
191
+ this.deps.log(`[learn-schedule] ${due.id} launch refused (${failures}): ${message}`);
192
+ return;
193
+ }
194
+ // The launch happened: record it FIRST, so a failure in the bookkeeping below can never
195
+ // misreport it as refused or free the slot for a second refresh (codex r1).
196
+ this.deps.store.update(due.id, {
197
+ lastRunId: runId,
198
+ lastRunAt: now.toISOString(),
199
+ lastOutcome: 'launched',
200
+ failures: 0,
201
+ lastError: null,
202
+ nextDueAt: new Date(now.getTime() + due.everyHours * HOURS).toISOString(),
203
+ }, now);
204
+ try {
205
+ recordRunLaunched(this.deps.audit, this.deps.runTimingIndex, LEARN_SCHEDULE_ACTOR, runId, {
206
+ workflow: LEARN_WORKFLOW,
207
+ repoRef: due.repoRef,
208
+ deliver: 'pr',
209
+ learnSchedule: due.id,
210
+ ...(due.projectId !== undefined ? { projectId: due.projectId } : {}),
211
+ });
212
+ if (due.projectId !== undefined)
213
+ this.deps.fileRun(runId, due.projectId);
214
+ this.deps.broadcast({ type: 'learnRefreshLaunched', session: runId, schedule: due.id });
215
+ }
216
+ catch (err) {
217
+ this.deps.log(`[learn-schedule] ${due.id} launched ${runId}, but its bookkeeping failed: ${err instanceof Error ? err.message : String(err)}`);
218
+ }
219
+ this.deps.log(`[learn-schedule] ${due.id} due → learn ${runId}`);
220
+ }
221
+ }
222
+ //# sourceMappingURL=scheduler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../src/learn/scheduler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * The learned topics of a registered repository (DES-learn-workflow §2, §6), read from its checkout's
3
+ * `.wicked/knowledge/<slug>/` (topic.json + claims.jsonl): what studio's learn page shows — each
4
+ * topic's claim counts by status and how stale its active claims are. Read-only and bounded: at
5
+ * most MAX_TOPICS topics and MAX_CLAIMS_BYTES of claims per topic; a malformed file is reported on
6
+ * the topic (`problem`), never thrown.
7
+ */
8
+ import type { LearnTopic } from 'wicked-crew-api-types';
9
+ export type { LearnTopic };
10
+ /** One topic's summary. `staleAfterDays`: an active claim not re-verified for longer counts as stale. */
11
+ export declare function readTopic(dir: string, slug: string, staleAfterDays: number, now: Date): Promise<LearnTopic>;
12
+ /** Every topic under `<root>/.wicked/knowledge/`, sorted by slug. An absent dir is an empty list. */
13
+ export declare function readTopics(root: string, staleAfterDays: (slug: string) => number, now: Date): Promise<LearnTopic[]>;
14
+ //# sourceMappingURL=topics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"topics.d.ts","sourceRoot":"","sources":["../../src/learn/topics.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGxD,YAAY,EAAE,UAAU,EAAE,CAAC;AAU3B,yGAAyG;AACzG,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC,CAiDjH;AAED,qGAAqG;AACrG,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,EAAE,GAAG,EAAE,IAAI,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAUzH"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * The learned topics of a registered repository (DES-learn-workflow §2, §6), read from its checkout's
3
+ * `.wicked/knowledge/<slug>/` (topic.json + claims.jsonl): what studio's learn page shows — each
4
+ * topic's claim counts by status and how stale its active claims are. Read-only and bounded: at
5
+ * most MAX_TOPICS topics and MAX_CLAIMS_BYTES of claims per topic; a malformed file is reported on
6
+ * the topic (`problem`), never thrown.
7
+ */
8
+ import { readdir, readFile, stat } from 'node:fs/promises';
9
+ import { join } from 'node:path';
10
+ import { LEARN_SLUG } from './schedule-store.js';
11
+ const MAX_TOPICS = 200;
12
+ const MAX_CLAIMS_BYTES = 2 * 1024 * 1024;
13
+ const DAY_MS = 86_400_000;
14
+ function iso(v) {
15
+ return typeof v === 'string' && !Number.isNaN(Date.parse(v)) ? v : null;
16
+ }
17
+ /** One topic's summary. `staleAfterDays`: an active claim not re-verified for longer counts as stale. */
18
+ export async function readTopic(dir, slug, staleAfterDays, now) {
19
+ const topic = {
20
+ slug,
21
+ title: slug,
22
+ kind: 'topic',
23
+ refreshedAt: null,
24
+ claims: { active: 0, superseded: 0, contradicted: 0, retired: 0 },
25
+ oldestVerifiedAt: null,
26
+ staleActive: 0,
27
+ sources: 0,
28
+ problem: null,
29
+ };
30
+ try {
31
+ const meta = JSON.parse(await readFile(join(dir, 'topic.json'), 'utf8'));
32
+ if (typeof meta['title'] === 'string' && meta['title'].trim() !== '')
33
+ topic.title = meta['title'];
34
+ if (meta['kind'] === 'event')
35
+ topic.kind = 'event';
36
+ topic.refreshedAt = iso(meta['refreshed_at']) ?? iso(meta['created_at']);
37
+ }
38
+ catch {
39
+ topic.problem = 'topic.json is missing or does not parse';
40
+ }
41
+ try {
42
+ const path = join(dir, 'claims.jsonl');
43
+ if ((await stat(path)).size > MAX_CLAIMS_BYTES)
44
+ throw new Error('too large');
45
+ const urls = new Set();
46
+ let oldest = null;
47
+ for (const line of (await readFile(path, 'utf8')).split('\n')) {
48
+ if (line.trim() === '')
49
+ continue;
50
+ let c;
51
+ try {
52
+ c = JSON.parse(line);
53
+ }
54
+ catch {
55
+ topic.problem ??= 'claims.jsonl has a line that does not parse';
56
+ continue;
57
+ }
58
+ const status = c['status'];
59
+ if (status === 'active' || status === 'superseded' || status === 'contradicted' || status === 'retired')
60
+ topic.claims[status] += 1;
61
+ if (Array.isArray(c['sources']))
62
+ for (const s of c['sources'])
63
+ if (s && typeof s.url === 'string')
64
+ urls.add(s.url);
65
+ if (status !== 'active')
66
+ continue;
67
+ const verified = iso(c['last_verified']) ?? iso(c['first_seen']);
68
+ const t = verified === null ? null : Date.parse(verified);
69
+ if (t !== null && (oldest === null || t < oldest))
70
+ oldest = t;
71
+ if (t === null || now.getTime() - t > staleAfterDays * DAY_MS)
72
+ topic.staleActive += 1;
73
+ }
74
+ topic.sources = urls.size;
75
+ topic.oldestVerifiedAt = oldest === null ? null : new Date(oldest).toISOString();
76
+ }
77
+ catch {
78
+ topic.problem ??= 'claims.jsonl is missing or unreadable';
79
+ }
80
+ return topic;
81
+ }
82
+ /** Every topic under `<root>/.wicked/knowledge/`, sorted by slug. An absent dir is an empty list. */
83
+ export async function readTopics(root, staleAfterDays, now) {
84
+ const base = join(root, '.wicked', 'knowledge');
85
+ let names;
86
+ try {
87
+ names = (await readdir(base, { withFileTypes: true })).filter((d) => d.isDirectory() && LEARN_SLUG.test(d.name)).map((d) => d.name);
88
+ }
89
+ catch {
90
+ return [];
91
+ }
92
+ names.sort();
93
+ return Promise.all(names.slice(0, MAX_TOPICS).map((slug) => readTopic(join(base, slug), slug, staleAfterDays(slug), now)));
94
+ }
95
+ //# sourceMappingURL=topics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"topics.js","sourceRoot":"","sources":["../../src/learn/topics.ts"],"names":[],"mappings":"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"}
@@ -201,6 +201,20 @@ export declare function attributeHits(raw: unknown, labels: Map<string, string>)
201
201
  hits: ProjectGraphHit[];
202
202
  byRepo: ProjectGraphRepoCount[];
203
203
  };
204
+ /**
205
+ * `wicked-estate blast-radius --json`, EVERY page of it (operator ruling "full graph"; estate#279,
206
+ * wicked-estate 0.28.0+). estate pages a wide answer: a page names the rest with `next_cursor`
207
+ * (null on the last page), and `--cursor` returns the next rows of the SAME answer. The pages'
208
+ * `dependents` are joined; every other field is the LAST page's, so once every page is in,
209
+ * `truncated_dependents` says only what the walk itself cut (and `next_cursor` is null). A cursor
210
+ * still unread at the page cap is left on the answer with that page's `truncated_dependents`, so
211
+ * the unread rows read as cut, never as absent. An estate that does not page sends no
212
+ * `next_cursor`: one call, its JSON unchanged. Shared by the repo route and the project route.
213
+ */
214
+ export declare function readBlastRadiusPages(exe: string, name: string, dbPath: string, opts: {
215
+ timeout: number;
216
+ cwd?: string;
217
+ }): Promise<Record<string, unknown>>;
204
218
  /** Dependents of a symbol across every member repo, each hit attributed to the repo it is in. */
205
219
  export declare function projectBlastRadius(q: Extract<Queryable, {
206
220
  ok: true;
@@ -1 +1 @@
1
- {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../src/projects/graph.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../src/projects/graph.ts"],"names":[],"mappings":"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"}