wicked-crew 0.3.1 → 0.4.0
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/api/elicitation-cache.d.ts +93 -0
- package/dist/api/elicitation-cache.d.ts.map +1 -0
- package/dist/api/elicitation-cache.js +128 -0
- package/dist/api/elicitation-cache.js.map +1 -0
- package/dist/api/evidence.d.ts +37 -38
- package/dist/api/evidence.d.ts.map +1 -1
- package/dist/api/evidence.js +40 -36
- package/dist/api/evidence.js.map +1 -1
- package/dist/api/gate-cache.d.ts +29 -13
- package/dist/api/gate-cache.d.ts.map +1 -1
- package/dist/api/gate-cache.js +82 -36
- package/dist/api/gate-cache.js.map +1 -1
- package/dist/api/requirements.d.ts +66 -0
- package/dist/api/requirements.d.ts.map +1 -0
- package/dist/api/requirements.js +328 -0
- package/dist/api/requirements.js.map +1 -0
- package/dist/api/routes.d.ts +2 -1
- package/dist/api/routes.d.ts.map +1 -1
- package/dist/api/routes.js +494 -34
- package/dist/api/routes.js.map +1 -1
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +13 -6
- package/dist/api/server.js.map +1 -1
- package/dist/core/adapter.d.ts +94 -6
- package/dist/core/adapter.d.ts.map +1 -1
- package/dist/core/adapter.js +386 -86
- package/dist/core/adapter.js.map +1 -1
- package/dist/core/exec.d.ts +37 -0
- package/dist/core/exec.d.ts.map +1 -0
- package/dist/core/exec.js +97 -0
- package/dist/core/exec.js.map +1 -0
- package/dist/core/repoPaths.d.ts +37 -0
- package/dist/core/repoPaths.d.ts.map +1 -0
- package/dist/core/repoPaths.js +48 -0
- package/dist/core/repoPaths.js.map +1 -0
- package/dist/core/types.d.ts +81 -2
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/studio/assets/index-Ci_R6ARr.js +423 -0
- package/dist/studio/assets/index-Dio_c1Q3.css +32 -0
- package/dist/studio/index.html +2 -2
- package/package.json +14 -13
- package/dist/studio/assets/index-BCcaLGxk.js +0 -420
- package/dist/studio/assets/index-vsyAOtPq.css +0 -32
package/dist/api/gate-cache.js
CHANGED
|
@@ -1,46 +1,92 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* When a gate was observed, ISO-8601.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
* A replayed log entry carries the engine's own capture-time `ts`; a live frame does not, and for
|
|
5
|
+
* one of those "now" IS the observation time. Using `ts` when it is there is not a nicety: studio
|
|
6
|
+
* sorts the open-gate list newest-first on this field, so stamping a replay with `Date.now()` would
|
|
7
|
+
* collapse every rebuilt gate to the restart instant and scramble their order.
|
|
8
|
+
*/
|
|
9
|
+
function observedAt(event) {
|
|
10
|
+
return new Date(typeof event.ts === 'number' ? event.ts : Date.now()).toISOString();
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* The one rule that turns an event into a cache mutation.
|
|
14
|
+
*
|
|
15
|
+
* Shared verbatim by the live stream and by durable replay so a rebuilt gate cannot disagree with
|
|
16
|
+
* what the live stream would have produced from the same events. Two hand-written folds would be
|
|
17
|
+
* free to drift, and the drift would only ever show up after a restart — the exact condition nobody
|
|
18
|
+
* exercises.
|
|
19
|
+
*/
|
|
20
|
+
function fold(entries, event) {
|
|
21
|
+
const session = typeof event.session === 'string' ? event.session : undefined;
|
|
22
|
+
if (session === undefined)
|
|
23
|
+
return;
|
|
24
|
+
switch (event.type) {
|
|
25
|
+
case 'awaitingHuman':
|
|
26
|
+
if (typeof event.ord === 'number' && typeof event.prompt === 'string') {
|
|
27
|
+
entries.set(session, {
|
|
28
|
+
ord: event.ord,
|
|
29
|
+
prompt: event.prompt,
|
|
30
|
+
lifecycle: 'open',
|
|
31
|
+
receivedAt: observedAt(event),
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
break;
|
|
35
|
+
case 'resumed':
|
|
36
|
+
case 'sessionCompleted':
|
|
37
|
+
case 'runCancelled':
|
|
38
|
+
case 'sessionFailed':
|
|
39
|
+
entries.delete(session);
|
|
40
|
+
break;
|
|
41
|
+
default:
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Gate-prompt cache over a durable log (DES-STUDIO-001 §3.3).
|
|
47
|
+
*
|
|
48
|
+
* The prompt is keyed by runId — a paused run has exactly one open gate, before `unit_ix`. Entries
|
|
49
|
+
* are pruned on any resumed/terminal event for the run, and re-checked against `sessionsDetail()`
|
|
50
|
+
* on every list reconcile, so the cache can neither leak nor go stale.
|
|
11
51
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
52
|
+
* That self-healing claim was true and beside the point until FINDING-051: every path here was
|
|
53
|
+
* prune-only, so a daemon restart dropped the map and **nothing could put an entry back**. A parked
|
|
54
|
+
* run then kept holding the operator without being able to say what it was asking. The prompt was
|
|
55
|
+
* never actually lost — core records `awaitingHuman` to the event log (core#139) — it was simply
|
|
56
|
+
* never read. `rebuild` is that read, which demotes this map to what it was always meant to be: a
|
|
57
|
+
* latency optimisation, not the system of record.
|
|
58
|
+
*
|
|
59
|
+
* NOTE: the full HITL lifecycle from §3.3 (advisory / hard-expiry timers, append-only message log,
|
|
60
|
+
* auto-cancel-on-expiry, synthesized `gateLifecycle` frames) is a deliberate follow-on. This
|
|
61
|
+
* increment caches only the prompt so a late-joining browser can render the gate; `lifecycle` is
|
|
62
|
+
* always `open`.
|
|
16
63
|
*/
|
|
17
64
|
export class GateCache {
|
|
18
65
|
entries = new Map();
|
|
19
|
-
/** Fold one CoreEvent into the cache. */
|
|
66
|
+
/** Fold one live CoreEvent into the cache. */
|
|
20
67
|
ingest(event) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
68
|
+
fold(this.entries, event);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Rebuild one run's gate from its durable event history and adopt the result (FINDING-051).
|
|
72
|
+
*
|
|
73
|
+
* `events` is the run's log oldest-first. Folding all of it yields the last `awaitingHuman` not
|
|
74
|
+
* followed by a resumed/terminal event — i.e. an open gate, or nothing.
|
|
75
|
+
*
|
|
76
|
+
* Deliberately does NOT cross-check the run's live status first: that costs a `sessionsDetail()`
|
|
77
|
+
* on a read path, and the write side is already guarded — approving a run that has moved on is
|
|
78
|
+
* refused by the `status === 'awaiting_human'` check on `POST /runs/:id/gate`. So the worst a
|
|
79
|
+
* stale replay can do is show a prompt that then declines to be approved, and `reconcile` drops
|
|
80
|
+
* it on the next list. The failure mode is a confusing read, never a bad write.
|
|
81
|
+
*/
|
|
82
|
+
rebuild(runId, events) {
|
|
83
|
+
const replayed = new Map();
|
|
84
|
+
for (const event of events)
|
|
85
|
+
fold(replayed, event);
|
|
86
|
+
const entry = replayed.get(runId);
|
|
87
|
+
if (entry)
|
|
88
|
+
this.entries.set(runId, entry);
|
|
89
|
+
return entry;
|
|
44
90
|
}
|
|
45
91
|
/** The cached open gate for a run, if any. */
|
|
46
92
|
get(runId) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gate-cache.js","sourceRoot":"","sources":["../../src/api/gate-cache.ts"],"names":[],"mappings":"AAcA
|
|
1
|
+
{"version":3,"file":"gate-cache.js","sourceRoot":"","sources":["../../src/api/gate-cache.ts"],"names":[],"mappings":"AAcA;;;;;;;GAOG;AACH,SAAS,UAAU,CAAC,KAAgB;IAClC,OAAO,IAAI,IAAI,CAAC,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;AACtF,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,IAAI,CAAC,OAAoC,EAAE,KAAgB;IAClE,MAAM,OAAO,GAAG,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IAC9E,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO;IAClC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,eAAe;YAClB,IAAI,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ,IAAI,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;gBACtE,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE;oBACnB,GAAG,EAAE,KAAK,CAAC,GAAG;oBACd,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,SAAS,EAAE,MAAM;oBACjB,UAAU,EAAE,UAAU,CAAC,KAAK,CAAC;iBAC9B,CAAC,CAAC;YACL,CAAC;YACD,MAAM;QACR,KAAK,SAAS,CAAC;QACf,KAAK,kBAAkB,CAAC;QACxB,KAAK,cAAc,CAAC;QACpB,KAAK,eAAe;YAClB,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACxB,MAAM;QACR;YACE,MAAM;IACV,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,OAAO,SAAS;IACH,OAAO,GAAG,IAAI,GAAG,EAA0B,CAAC;IAE7D,8CAA8C;IAC9C,MAAM,CAAC,KAAgB;QACrB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC5B,CAAC;IAED;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,KAAa,EAAE,MAAmB;QACxC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA0B,CAAC;QACnD,KAAK,MAAM,KAAK,IAAI,MAAM;YAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAClD,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAClC,IAAI,KAAK;YAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC1C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,8CAA8C;IAC9C,GAAG,CAAC,KAAa;QACf,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IAED,8FAA8F;IAC9F,SAAS,CAAC,KAAoB;QAC5B,MAAM,QAAQ,GAAG,IAAI,GAAG,CACtB,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,gBAAgB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CACpF,CAAC;QACF,KAAK,MAAM,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YAC1C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { RepoEntry } from '../core/types.js';
|
|
2
|
+
export interface RequirementOverride {
|
|
3
|
+
title?: string | undefined;
|
|
4
|
+
notes?: string | undefined;
|
|
5
|
+
status?: string | undefined;
|
|
6
|
+
risk?: boolean | undefined;
|
|
7
|
+
}
|
|
8
|
+
export type RequirementCategory = 'functional' | 'config-data';
|
|
9
|
+
/** Product-functional requirements come from CODE; statements extracted from
|
|
10
|
+
* lockfiles, manifests, data fixtures, and docs are honest observations about
|
|
11
|
+
* those assets but are NOT product behavior — they class as config-data so the
|
|
12
|
+
* default view can focus on the product. */
|
|
13
|
+
export declare function categoryOf(file: string): RequirementCategory;
|
|
14
|
+
export interface RequirementSummary {
|
|
15
|
+
key: string;
|
|
16
|
+
domain: string;
|
|
17
|
+
reqId: string;
|
|
18
|
+
title: string;
|
|
19
|
+
category: RequirementCategory;
|
|
20
|
+
/** First business-rule statement — the requirement's actual content (empty when none). */
|
|
21
|
+
statement: string;
|
|
22
|
+
status: string;
|
|
23
|
+
risk: boolean;
|
|
24
|
+
riskSource: 'operator' | 'data' | null;
|
|
25
|
+
edited: boolean;
|
|
26
|
+
}
|
|
27
|
+
export interface RequirementDetail extends RequirementSummary {
|
|
28
|
+
description: string;
|
|
29
|
+
notes: string;
|
|
30
|
+
sourceTitle: string;
|
|
31
|
+
ruleCount: number;
|
|
32
|
+
componentCount: number;
|
|
33
|
+
validationCount: number;
|
|
34
|
+
errorPathCount: number;
|
|
35
|
+
businessRules: unknown[];
|
|
36
|
+
legacyComponents: unknown[];
|
|
37
|
+
}
|
|
38
|
+
export interface RequirementsQuery {
|
|
39
|
+
q?: string | undefined;
|
|
40
|
+
risk?: 'risk' | 'no-risk' | undefined;
|
|
41
|
+
domain?: string | undefined;
|
|
42
|
+
category?: RequirementCategory | undefined;
|
|
43
|
+
offset: number;
|
|
44
|
+
limit: number;
|
|
45
|
+
}
|
|
46
|
+
export interface RequirementsPage {
|
|
47
|
+
total: number;
|
|
48
|
+
corpus: number;
|
|
49
|
+
offset: number;
|
|
50
|
+
limit: number;
|
|
51
|
+
items: RequirementSummary[];
|
|
52
|
+
/**
|
|
53
|
+
* Which of the two sources served this corpus. The module header explains why that
|
|
54
|
+
* matters operationally — the artifact is an evidence-gated snapshot that can lag the
|
|
55
|
+
* live store by hours, and a UI serving stale placeholder titles while the store held
|
|
56
|
+
* thousands of validated statements is an observed failure, not a hypothetical. Without
|
|
57
|
+
* this the caller cannot tell which one it is looking at. (FINDING-065)
|
|
58
|
+
*/
|
|
59
|
+
source: 'store' | 'artifact';
|
|
60
|
+
}
|
|
61
|
+
/** Tokenized AND-match: every whitespace-separated term must appear in the haystack. */
|
|
62
|
+
export declare function listRequirements(repo: RepoEntry, query: RequirementsQuery): Promise<RequirementsPage | null>;
|
|
63
|
+
export declare function getRequirement(repo: RepoEntry, key: string): Promise<RequirementDetail | null>;
|
|
64
|
+
/** Merge a patch into the overrides sidecar (atomic write) and return the fresh detail. */
|
|
65
|
+
export declare function patchRequirement(repo: RepoEntry, key: string, patch: RequirementOverride): Promise<RequirementDetail | null>;
|
|
66
|
+
//# sourceMappingURL=requirements.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requirements.d.ts","sourceRoot":"","sources":["../../src/api/requirements.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAmBlD,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC5B;AAED,MAAM,MAAM,mBAAmB,GAAG,YAAY,GAAG,aAAa,CAAC;AAE/D;;;4CAG4C;AAC5C,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,CAM5D;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,0FAA0F;IAC1F,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAAC;IACvC,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;IAC3D,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,OAAO,EAAE,CAAC;IACzB,gBAAgB,EAAE,OAAO,EAAE,CAAC;CAC7B;AAoQD,MAAM,WAAW,iBAAiB;IAChC,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,QAAQ,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAC;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B;;;;;;OAMG;IACH,MAAM,EAAE,OAAO,GAAG,UAAU,CAAC;CAC9B;AAED,wFAAwF;AACxF,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,SAAS,EACf,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAyBlC;AAED,wBAAsB,cAAc,CAClC,IAAI,EAAE,SAAS,EACf,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAmBnC;AAED,2FAA2F;AAC3F,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,SAAS,EACf,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAmBnC"}
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* REQUIREMENTS SERVICE — server-side search + operator overrides over the LIVE
|
|
3
|
+
* estate store, with the `requirements_graph.json` artifact as fallback.
|
|
4
|
+
*
|
|
5
|
+
* Why the store is primary: the artifact is an evidence-gated SNAPSHOT — it only
|
|
6
|
+
* regenerates when `wicked-core domain-graph` passes its coverage bar, so mid-extraction
|
|
7
|
+
* it can lag the store by hours (observed: a UI serving day-old placeholder titles while
|
|
8
|
+
* the store held thousands of validated statements). Requirements content lives in
|
|
9
|
+
* estate (`nodes.requirement` + RULE-* annotations); the UI reads that truth directly
|
|
10
|
+
* (read-only `node:sqlite`) and falls back to the artifact for repos without a store
|
|
11
|
+
* or on runtimes without the sqlite builtin.
|
|
12
|
+
*
|
|
13
|
+
* Why server-side: 15k+ requirements — shipping them to the browser for JS-side
|
|
14
|
+
* filtering is not search. The daemon builds a flat index (cached, invalidated on
|
|
15
|
+
* store/artifact mtime with a small TTL guard against WAL-churn thrash), and queries
|
|
16
|
+
* run here: tokenized AND-match over id/domain/title/statements, risk + domain
|
|
17
|
+
* filters, offset/limit pagination.
|
|
18
|
+
*
|
|
19
|
+
* Why an OVERRIDES sidecar: the artifact is DERIVED (regenerated from the estate
|
|
20
|
+
* store), so operator edits written into it would be clobbered on the next
|
|
21
|
+
* `domain-graph` run. Edits live in `requirements_overrides.json` beside the artifact,
|
|
22
|
+
* keyed `domain::reqId`, and are merged at read time — the overlay survives
|
|
23
|
+
* regeneration and keeps provenance honest (`riskSource: operator` vs `data`).
|
|
24
|
+
*/
|
|
25
|
+
import { readFile, writeFile, rename, mkdir, stat } from 'node:fs/promises';
|
|
26
|
+
import { dirname } from 'node:path';
|
|
27
|
+
import { codeGraphDb, requirementsGraph, requirementsOverrides } from '../core/repoPaths.js';
|
|
28
|
+
/** Product-functional requirements come from CODE; statements extracted from
|
|
29
|
+
* lockfiles, manifests, data fixtures, and docs are honest observations about
|
|
30
|
+
* those assets but are NOT product behavior — they class as config-data so the
|
|
31
|
+
* default view can focus on the product. */
|
|
32
|
+
export function categoryOf(file) {
|
|
33
|
+
const f = file.toLowerCase();
|
|
34
|
+
const base = f.slice(f.lastIndexOf('/') + 1);
|
|
35
|
+
if (/\.(json|ya?ml|lock|toml|ini|env|md|mdx|txt|csv)$/.test(base))
|
|
36
|
+
return 'config-data';
|
|
37
|
+
if (base.includes('pnpm-lock') || base.includes('package-lock'))
|
|
38
|
+
return 'config-data';
|
|
39
|
+
return 'functional';
|
|
40
|
+
}
|
|
41
|
+
const RISK_RE = /risk/i;
|
|
42
|
+
const RISK_PREFIX = '[RISK]';
|
|
43
|
+
/** WAL churn during extraction touches the db every few seconds — don't rebuild a
|
|
44
|
+
* 15k-row index per keystroke; a fresh-enough index is authoritative for this long. */
|
|
45
|
+
const REBUILD_TTL_MS = 5_000;
|
|
46
|
+
// Paths come from `repoPaths` — this module used to spell the code-graph path itself, which is
|
|
47
|
+
// one of the five copies FINDING-069 was made of. It takes the whole `RepoEntry` rather than a
|
|
48
|
+
// root path for exactly that reason: a bare string is an invitation to re-derive.
|
|
49
|
+
async function mtimeMs(path) {
|
|
50
|
+
try {
|
|
51
|
+
return (await stat(path)).mtimeMs;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return -1;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async function readOverrides(repo) {
|
|
58
|
+
try {
|
|
59
|
+
const raw = await readFile(requirementsOverrides(repo), 'utf8');
|
|
60
|
+
const parsed = JSON.parse(raw);
|
|
61
|
+
return typeof parsed === 'object' && parsed !== null
|
|
62
|
+
? parsed
|
|
63
|
+
: {};
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return {};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const cache = new Map();
|
|
70
|
+
let tmpSeq = 0;
|
|
71
|
+
/** Lazily resolved sqlite builtin — absent on older Node runtimes → artifact fallback. */
|
|
72
|
+
let sqliteMod;
|
|
73
|
+
async function sqlite() {
|
|
74
|
+
if (sqliteMod === undefined) {
|
|
75
|
+
try {
|
|
76
|
+
const name = 'node:sqlite';
|
|
77
|
+
sqliteMod = (await import(name));
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
sqliteMod = null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return sqliteMod;
|
|
84
|
+
}
|
|
85
|
+
/** Build the index from the LIVE estate store (read-only). Returns null when the
|
|
86
|
+
* store can't serve (no db, no sqlite builtin, schema mismatch) — caller falls back. */
|
|
87
|
+
async function buildStoreIndex(repo, sourceMtime, ovMtime) {
|
|
88
|
+
const mod = await sqlite();
|
|
89
|
+
if (mod === null)
|
|
90
|
+
return null;
|
|
91
|
+
const overrides = await readOverrides(repo);
|
|
92
|
+
let db = null;
|
|
93
|
+
const entries = [];
|
|
94
|
+
const byKey = new Map();
|
|
95
|
+
try {
|
|
96
|
+
db = new mod.DatabaseSync(codeGraphDb(repo), { readOnly: true });
|
|
97
|
+
const rules = new Map();
|
|
98
|
+
for (const r of db
|
|
99
|
+
.prepare("SELECT node_sym, value, confidence FROM annotations WHERE key LIKE 'RULE-%'")
|
|
100
|
+
.all()) {
|
|
101
|
+
const list = rules.get(r.node_sym) ?? [];
|
|
102
|
+
list.push({ statement: r.value ?? '', confidence: r.confidence });
|
|
103
|
+
rules.set(r.node_sym, list);
|
|
104
|
+
}
|
|
105
|
+
const rows = db
|
|
106
|
+
.prepare(`SELECT n.symbol AS sid, s.sym AS sym, n.name, n.file, n.requirement,
|
|
107
|
+
n.requirement_validated AS validated
|
|
108
|
+
FROM nodes n JOIN symbols s ON s.sid = n.symbol
|
|
109
|
+
WHERE n.requirement IS NOT NULL AND n.requirement != ''`)
|
|
110
|
+
.all();
|
|
111
|
+
for (const row of rows) {
|
|
112
|
+
const key = row.sym;
|
|
113
|
+
const ov = overrides[key];
|
|
114
|
+
const file = row.file ?? '';
|
|
115
|
+
const slash = file.lastIndexOf('/');
|
|
116
|
+
const domain = slash > 0 ? file.slice(0, slash) : '(root)';
|
|
117
|
+
const dataRisk = row.requirement.startsWith(RISK_PREFIX);
|
|
118
|
+
const risk = ov?.risk !== undefined ? ov.risk : dataRisk;
|
|
119
|
+
const riskSource = ov?.risk !== undefined ? 'operator' : dataRisk ? 'data' : null;
|
|
120
|
+
const title = ov?.title ?? (row.name !== null && row.name !== '' ? row.name : key);
|
|
121
|
+
const nodeRules = rules.get(row.sid) ?? [];
|
|
122
|
+
const summary = {
|
|
123
|
+
key,
|
|
124
|
+
domain,
|
|
125
|
+
reqId: key,
|
|
126
|
+
title,
|
|
127
|
+
category: categoryOf(file),
|
|
128
|
+
statement: row.requirement,
|
|
129
|
+
status: ov?.status ?? (row.validated === 1 ? 'validated' : 'active'),
|
|
130
|
+
risk,
|
|
131
|
+
riskSource,
|
|
132
|
+
edited: ov !== undefined,
|
|
133
|
+
};
|
|
134
|
+
const source = {
|
|
135
|
+
title,
|
|
136
|
+
description: file,
|
|
137
|
+
status: summary.status,
|
|
138
|
+
legacy_components: file === '' ? [] : [file],
|
|
139
|
+
business_rules: nodeRules,
|
|
140
|
+
};
|
|
141
|
+
const haystack = `${key} ${domain} ${title} ${row.requirement} ${nodeRules.map((r) => r.statement).join(' ')} ${ov?.notes ?? ''}`.toLowerCase();
|
|
142
|
+
const entry = { summary, haystack, source };
|
|
143
|
+
entries.push(entry);
|
|
144
|
+
byKey.set(key, entry);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
return null; // schema drift or unreadable store — artifact fallback
|
|
149
|
+
}
|
|
150
|
+
finally {
|
|
151
|
+
db?.close();
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
entries,
|
|
155
|
+
byKey,
|
|
156
|
+
sourceMtimeMs: sourceMtime,
|
|
157
|
+
fromStore: true,
|
|
158
|
+
overridesMtimeMs: ovMtime,
|
|
159
|
+
builtAtMs: Date.now(),
|
|
160
|
+
total: entries.length,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
async function buildIndex(repo) {
|
|
164
|
+
const db = codeGraphDb(repo);
|
|
165
|
+
const [dbMtime, walMtime, artMtime, ovMtime] = await Promise.all([
|
|
166
|
+
mtimeMs(db),
|
|
167
|
+
mtimeMs(`${db}-wal`),
|
|
168
|
+
mtimeMs(requirementsGraph(repo)),
|
|
169
|
+
mtimeMs(requirementsOverrides(repo)),
|
|
170
|
+
]);
|
|
171
|
+
const storeMtime = Math.max(dbMtime, walMtime);
|
|
172
|
+
const cached = cache.get(repo.root_path);
|
|
173
|
+
// TTL applies ONLY to store-built indexes: extraction WAL churn changes the db
|
|
174
|
+
// mtime every few seconds and must not trigger a rebuild per request. Artifact
|
|
175
|
+
// mtime changes only on regen, so artifact-built indexes always mtime-check.
|
|
176
|
+
if (cached?.fromStore === true && Date.now() - cached.builtAtMs < REBUILD_TTL_MS)
|
|
177
|
+
return cached;
|
|
178
|
+
if (storeMtime >= 0) {
|
|
179
|
+
if (cached && cached.sourceMtimeMs === storeMtime && cached.overridesMtimeMs === ovMtime) {
|
|
180
|
+
cached.builtAtMs = Date.now();
|
|
181
|
+
return cached;
|
|
182
|
+
}
|
|
183
|
+
const fromStore = await buildStoreIndex(repo, storeMtime, ovMtime);
|
|
184
|
+
if (fromStore !== null) {
|
|
185
|
+
cache.set(repo.root_path, fromStore);
|
|
186
|
+
return fromStore;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
if (artMtime < 0)
|
|
190
|
+
return null; // no store, no artifact — requirements not generated yet
|
|
191
|
+
if (cached && cached.sourceMtimeMs === artMtime && cached.overridesMtimeMs === ovMtime) {
|
|
192
|
+
return cached;
|
|
193
|
+
}
|
|
194
|
+
const raw = await readFile(requirementsGraph(repo), 'utf8');
|
|
195
|
+
const graph = JSON.parse(raw);
|
|
196
|
+
const overrides = await readOverrides(repo);
|
|
197
|
+
const entries = [];
|
|
198
|
+
const byKey = new Map();
|
|
199
|
+
for (const [domain, dom] of Object.entries(graph.domains ?? {})) {
|
|
200
|
+
for (const [reqId, req] of Object.entries(dom.requirements ?? {})) {
|
|
201
|
+
const key = `${domain}::${reqId}`;
|
|
202
|
+
const ov = overrides[key];
|
|
203
|
+
// Data-derived risk: any business rule whose serialized form names risk (the
|
|
204
|
+
// extraction harness's RESOLVED-or-RISK floor surfaces here at current fidelity).
|
|
205
|
+
const dataRisk = (req.business_rules ?? []).some((r) => RISK_RE.test(JSON.stringify(r)));
|
|
206
|
+
const risk = ov?.risk !== undefined ? ov.risk : dataRisk;
|
|
207
|
+
const riskSource = ov?.risk !== undefined ? 'operator' : dataRisk ? 'data' : null;
|
|
208
|
+
const title = ov?.title ?? req.title ?? reqId;
|
|
209
|
+
const statements = (req.business_rules ?? [])
|
|
210
|
+
.map((r) => {
|
|
211
|
+
const st = r.statement;
|
|
212
|
+
return typeof st === 'string' ? st.trim() : '';
|
|
213
|
+
})
|
|
214
|
+
.filter((st) => st !== '');
|
|
215
|
+
const firstComponent = (req.legacy_components ?? []).find((c) => typeof c === 'string');
|
|
216
|
+
const summary = {
|
|
217
|
+
key,
|
|
218
|
+
domain,
|
|
219
|
+
reqId,
|
|
220
|
+
title,
|
|
221
|
+
category: categoryOf(firstComponent ?? ''),
|
|
222
|
+
statement: statements[0] ?? '',
|
|
223
|
+
status: ov?.status ?? req.status ?? 'active',
|
|
224
|
+
risk,
|
|
225
|
+
riskSource,
|
|
226
|
+
edited: ov !== undefined,
|
|
227
|
+
};
|
|
228
|
+
// Statements are part of the haystack: searching the requirements means
|
|
229
|
+
// searching the actual rule text, not just titles and ids.
|
|
230
|
+
const haystack = `${reqId} ${domain} ${title} ${req.description ?? ''} ${statements.join(' ')} ${ov?.notes ?? ''}`.toLowerCase();
|
|
231
|
+
const entry = { summary, haystack, source: req };
|
|
232
|
+
entries.push(entry);
|
|
233
|
+
byKey.set(key, entry);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
const index = {
|
|
237
|
+
entries,
|
|
238
|
+
byKey,
|
|
239
|
+
sourceMtimeMs: artMtime,
|
|
240
|
+
fromStore: false,
|
|
241
|
+
overridesMtimeMs: ovMtime,
|
|
242
|
+
builtAtMs: Date.now(),
|
|
243
|
+
total: entries.length,
|
|
244
|
+
};
|
|
245
|
+
cache.set(repo.root_path, index);
|
|
246
|
+
return index;
|
|
247
|
+
}
|
|
248
|
+
/** Tokenized AND-match: every whitespace-separated term must appear in the haystack. */
|
|
249
|
+
export async function listRequirements(repo, query) {
|
|
250
|
+
const index = await buildIndex(repo);
|
|
251
|
+
if (index === null)
|
|
252
|
+
return null;
|
|
253
|
+
const terms = (query.q ?? '')
|
|
254
|
+
.toLowerCase()
|
|
255
|
+
.split(/\s+/)
|
|
256
|
+
.filter((t) => t.length > 0);
|
|
257
|
+
const domainFilter = query.domain?.toLowerCase();
|
|
258
|
+
const matched = [];
|
|
259
|
+
for (const e of index.entries) {
|
|
260
|
+
if (query.category !== undefined && e.summary.category !== query.category)
|
|
261
|
+
continue;
|
|
262
|
+
if (query.risk === 'risk' && !e.summary.risk)
|
|
263
|
+
continue;
|
|
264
|
+
if (query.risk === 'no-risk' && e.summary.risk)
|
|
265
|
+
continue;
|
|
266
|
+
if (domainFilter !== undefined && !e.summary.domain.toLowerCase().includes(domainFilter))
|
|
267
|
+
continue;
|
|
268
|
+
if (terms.length > 0 && !terms.every((t) => e.haystack.includes(t)))
|
|
269
|
+
continue;
|
|
270
|
+
matched.push(e.summary);
|
|
271
|
+
}
|
|
272
|
+
return {
|
|
273
|
+
total: matched.length,
|
|
274
|
+
corpus: index.total,
|
|
275
|
+
offset: query.offset,
|
|
276
|
+
limit: query.limit,
|
|
277
|
+
items: matched.slice(query.offset, query.offset + query.limit),
|
|
278
|
+
source: index.fromStore ? 'store' : 'artifact',
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
export async function getRequirement(repo, key) {
|
|
282
|
+
const index = await buildIndex(repo);
|
|
283
|
+
const entry = index?.byKey.get(key);
|
|
284
|
+
if (index === null || entry === undefined)
|
|
285
|
+
return null;
|
|
286
|
+
const overrides = await readOverrides(repo);
|
|
287
|
+
const ov = overrides[key];
|
|
288
|
+
const src = entry.source;
|
|
289
|
+
return {
|
|
290
|
+
...entry.summary,
|
|
291
|
+
description: src.description ?? '',
|
|
292
|
+
notes: ov?.notes ?? '',
|
|
293
|
+
sourceTitle: src.title ?? entry.summary.reqId,
|
|
294
|
+
ruleCount: (src.business_rules ?? []).length,
|
|
295
|
+
componentCount: (src.legacy_components ?? []).length,
|
|
296
|
+
validationCount: (src.validations ?? []).length,
|
|
297
|
+
errorPathCount: (src.error_paths ?? []).length,
|
|
298
|
+
businessRules: (src.business_rules ?? []).slice(0, 10),
|
|
299
|
+
legacyComponents: (src.legacy_components ?? []).slice(0, 10),
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
/** Merge a patch into the overrides sidecar (atomic write) and return the fresh detail. */
|
|
303
|
+
export async function patchRequirement(repo, key, patch) {
|
|
304
|
+
const index = await buildIndex(repo);
|
|
305
|
+
if (index === null || !index.byKey.has(key))
|
|
306
|
+
return null;
|
|
307
|
+
const overrides = await readOverrides(repo);
|
|
308
|
+
const next = { ...overrides[key] };
|
|
309
|
+
if (patch.title !== undefined)
|
|
310
|
+
next.title = patch.title;
|
|
311
|
+
if (patch.notes !== undefined)
|
|
312
|
+
next.notes = patch.notes;
|
|
313
|
+
if (patch.status !== undefined)
|
|
314
|
+
next.status = patch.status;
|
|
315
|
+
if (patch.risk !== undefined)
|
|
316
|
+
next.risk = patch.risk;
|
|
317
|
+
overrides[key] = next;
|
|
318
|
+
const path = requirementsOverrides(repo);
|
|
319
|
+
await mkdir(dirname(path), { recursive: true });
|
|
320
|
+
// Collision-proof temp name: pid alone can collide for concurrent in-process
|
|
321
|
+
// patches; a monotonic per-process counter disambiguates.
|
|
322
|
+
const tmp = `${path}.tmp-${process.pid}-${++tmpSeq}`;
|
|
323
|
+
await writeFile(tmp, JSON.stringify(overrides, null, 2), 'utf8');
|
|
324
|
+
await rename(tmp, path);
|
|
325
|
+
cache.delete(repo.root_path); // next read rebuilds with the new overrides
|
|
326
|
+
return getRequirement(repo, key);
|
|
327
|
+
}
|
|
328
|
+
//# sourceMappingURL=requirements.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requirements.js","sourceRoot":"","sources":["../../src/api/requirements.ts"],"names":[],"mappings":"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"}
|
package/dist/api/routes.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { FastifyInstance } from 'fastify';
|
|
2
2
|
import { CoreAdapter } from '../core/adapter.js';
|
|
3
3
|
import type { GateCache } from './gate-cache.js';
|
|
4
|
+
import type { ElicitationCache } from './elicitation-cache.js';
|
|
4
5
|
/**
|
|
5
6
|
* The daemon REST surface. Every endpoint is a thin wrapper over one adapter /
|
|
6
7
|
* core-ts call (DES-STUDIO-001 §2). `session`/`phase` nouns are now `run`/`unit`.
|
|
7
8
|
*/
|
|
8
|
-
export declare function registerRoutes(app: FastifyInstance, adapter: CoreAdapter, gateCache: GateCache): void;
|
|
9
|
+
export declare function registerRoutes(app: FastifyInstance, adapter: CoreAdapter, gateCache: GateCache, elicitationCache: ElicitationCache): void;
|
|
9
10
|
//# sourceMappingURL=routes.d.ts.map
|
package/dist/api/routes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/api/routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/api/routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAQ/C,OAAO,EAAwB,WAAW,EAA+B,MAAM,oBAAoB,CAAC;AAEpG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AA6I/D;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,eAAe,EACpB,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,SAAS,EACpB,gBAAgB,EAAE,gBAAgB,GACjC,IAAI,CAw+BN"}
|