wicked-crew 0.7.28 → 0.7.30
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/README.md +12 -1
- package/dist/api/chat-scope.d.ts +210 -0
- package/dist/api/chat-scope.d.ts.map +1 -0
- package/dist/api/chat-scope.js +728 -0
- package/dist/api/chat-scope.js.map +1 -0
- package/dist/api/diagnostics.d.ts +30 -2
- package/dist/api/diagnostics.d.ts.map +1 -1
- package/dist/api/diagnostics.js +73 -5
- package/dist/api/diagnostics.js.map +1 -1
- package/dist/api/governance-health.d.ts +171 -0
- package/dist/api/governance-health.d.ts.map +1 -0
- package/dist/api/governance-health.js +379 -0
- package/dist/api/governance-health.js.map +1 -0
- package/dist/api/open-path.d.ts.map +1 -1
- package/dist/api/open-path.js +2 -1
- package/dist/api/open-path.js.map +1 -1
- package/dist/api/post-hoc-deliver.d.ts +9 -5
- package/dist/api/post-hoc-deliver.d.ts.map +1 -1
- package/dist/api/post-hoc-deliver.js +21 -7
- package/dist/api/post-hoc-deliver.js.map +1 -1
- package/dist/api/routes.d.ts +70 -12
- package/dist/api/routes.d.ts.map +1 -1
- package/dist/api/routes.js +375 -60
- package/dist/api/routes.js.map +1 -1
- package/dist/api/seat-health.d.ts +38 -0
- package/dist/api/seat-health.d.ts.map +1 -1
- package/dist/api/seat-health.js +88 -5
- package/dist/api/seat-health.js.map +1 -1
- package/dist/api/seat-signin.d.ts.map +1 -1
- package/dist/api/seat-signin.js +49 -23
- package/dist/api/seat-signin.js.map +1 -1
- package/dist/api/seat-standing.d.ts +101 -0
- package/dist/api/seat-standing.d.ts.map +1 -0
- package/dist/api/seat-standing.js +138 -0
- package/dist/api/seat-standing.js.map +1 -0
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +37 -0
- package/dist/api/server.js.map +1 -1
- package/dist/campaigns/routes.d.ts +4 -4
- package/dist/cli/governance.d.ts +131 -0
- package/dist/cli/governance.d.ts.map +1 -0
- package/dist/cli/governance.js +354 -0
- package/dist/cli/governance.js.map +1 -0
- package/dist/cli/index.js +102 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/core/adapter.d.ts +99 -1
- package/dist/core/adapter.d.ts.map +1 -1
- package/dist/core/adapter.js +149 -8
- package/dist/core/adapter.js.map +1 -1
- package/dist/core/bridge-path.d.ts +21 -0
- package/dist/core/bridge-path.d.ts.map +1 -1
- package/dist/core/bridge-path.js +37 -0
- package/dist/core/bridge-path.js.map +1 -1
- package/dist/core/bridge-reaper.d.ts.map +1 -1
- package/dist/core/bridge-reaper.js +11 -4
- package/dist/core/bridge-reaper.js.map +1 -1
- package/dist/core/deliver-text.d.ts +184 -0
- package/dist/core/deliver-text.d.ts.map +1 -0
- package/dist/core/deliver-text.js +434 -0
- package/dist/core/deliver-text.js.map +1 -0
- package/dist/core/deliver-triage.d.ts +90 -0
- package/dist/core/deliver-triage.d.ts.map +1 -0
- package/dist/core/deliver-triage.js +106 -0
- package/dist/core/deliver-triage.js.map +1 -0
- package/dist/core/deliver.d.ts +103 -9
- package/dist/core/deliver.d.ts.map +1 -1
- package/dist/core/deliver.js +244 -46
- package/dist/core/deliver.js.map +1 -1
- package/dist/core/estate-mcp-client.d.ts.map +1 -1
- package/dist/core/estate-mcp-client.js +7 -2
- package/dist/core/estate-mcp-client.js.map +1 -1
- package/dist/core/exec.d.ts.map +1 -1
- package/dist/core/exec.js +11 -1
- package/dist/core/exec.js.map +1 -1
- package/dist/core/governance-store.d.ts +219 -0
- package/dist/core/governance-store.d.ts.map +1 -0
- package/dist/core/governance-store.js +290 -0
- package/dist/core/governance-store.js.map +1 -0
- package/dist/core/repoPaths.d.ts +36 -5
- package/dist/core/repoPaths.d.ts.map +1 -1
- package/dist/core/repoPaths.js +46 -4
- package/dist/core/repoPaths.js.map +1 -1
- package/dist/interactive/bridge-pool.d.ts +29 -24
- package/dist/interactive/bridge-pool.d.ts.map +1 -1
- package/dist/interactive/bridge-pool.js +74 -7
- package/dist/interactive/bridge-pool.js.map +1 -1
- package/dist/interactive/chat-events.d.ts.map +1 -1
- package/dist/interactive/chat-events.js +5 -2
- package/dist/interactive/chat-events.js.map +1 -1
- package/dist/interactive/council-outcome.d.ts +28 -0
- package/dist/interactive/council-outcome.d.ts.map +1 -0
- package/dist/interactive/council-outcome.js +57 -0
- package/dist/interactive/council-outcome.js.map +1 -0
- package/dist/interactive/demo-events.d.ts.map +1 -1
- package/dist/interactive/demo-events.js +5 -2
- package/dist/interactive/demo-events.js.map +1 -1
- package/dist/interactive/doc-delete-routes.d.ts.map +1 -1
- package/dist/interactive/doc-delete-routes.js +3 -2
- package/dist/interactive/doc-delete-routes.js.map +1 -1
- package/dist/interactive/draft-events.d.ts.map +1 -1
- package/dist/interactive/draft-events.js +5 -2
- package/dist/interactive/draft-events.js.map +1 -1
- package/dist/interactive/edit-events.d.ts.map +1 -1
- package/dist/interactive/edit-events.js +5 -2
- package/dist/interactive/edit-events.js.map +1 -1
- package/dist/projects/auto-refresh.d.ts +54 -0
- package/dist/projects/auto-refresh.d.ts.map +1 -0
- package/dist/projects/auto-refresh.js +76 -0
- package/dist/projects/auto-refresh.js.map +1 -0
- package/dist/projects/graph-paths.d.ts +4 -2
- package/dist/projects/graph-paths.d.ts.map +1 -1
- package/dist/projects/graph-paths.js +4 -2
- package/dist/projects/graph-paths.js.map +1 -1
- package/dist/projects/graph.d.ts +20 -6
- package/dist/projects/graph.d.ts.map +1 -1
- package/dist/projects/graph.js +40 -13
- package/dist/projects/graph.js.map +1 -1
- package/dist/projects/routes.d.ts.map +1 -1
- package/dist/projects/routes.js +30 -11
- package/dist/projects/routes.js.map +1 -1
- package/dist/projects/state-home.d.ts +6 -0
- package/dist/projects/state-home.d.ts.map +1 -1
- package/dist/projects/state-home.js +9 -1
- package/dist/projects/state-home.js.map +1 -1
- package/dist/skills/guards.d.ts +17 -6
- package/dist/skills/guards.d.ts.map +1 -1
- package/dist/skills/guards.js +42 -15
- package/dist/skills/guards.js.map +1 -1
- package/dist/skills/plugin-source.d.ts.map +1 -1
- package/dist/skills/plugin-source.js +3 -0
- package/dist/skills/plugin-source.js.map +1 -1
- package/dist/skills/refs.d.ts +181 -17
- package/dist/skills/refs.d.ts.map +1 -1
- package/dist/skills/refs.js +345 -26
- package/dist/skills/refs.js.map +1 -1
- package/dist/skills/store.d.ts +22 -1
- package/dist/skills/store.d.ts.map +1 -1
- package/dist/skills/store.js +161 -23
- package/dist/skills/store.js.map +1 -1
- package/dist/studio/assets/index-CWUS9Ump.js +542 -0
- package/dist/studio/assets/{index-CK1uJWs2.css → index-_ydd-jKd.css} +1 -1
- package/dist/studio/index.html +2 -2
- package/dist/studio/testid-inventory.json +567 -6
- package/endpoint-manifest.json +67 -14
- package/package.json +4 -4
- package/dist/studio/assets/index-CdmCMh2f.js +0 -539
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WHERE THE GOVERNANCE STORE LIVES — and where its dead letters go (crew#495, acceptance
|
|
3
|
+
* finding F-022). One pure resolution the CLI, the adapter, the diagnostics route and the tests
|
|
4
|
+
* share, in the shape of `interactive/bus-location.ts`.
|
|
5
|
+
*
|
|
6
|
+
* # The defect
|
|
7
|
+
*
|
|
8
|
+
* The engine's emit seam (`wicked-apps-core::emit::emit_event`) publishes every cross-product
|
|
9
|
+
* `wicked.*` event — the conformance claims and decisions the acceptance gate reads back
|
|
10
|
+
* (`wicked.crew.governance.conformance_recorded`), phase transitions, the steering-rule lifecycle
|
|
11
|
+
* (`wicked.estate.rule.ingested` / `.retired`), council traffic — as an EVENT node on the shared
|
|
12
|
+
* estate store named by `WICKED_ESTATE_DB`. `serve` never set that variable, so on EVERY default
|
|
13
|
+
* install EVERY such event dead-lettered: appended to an NDJSON outbox under the operator's HOME
|
|
14
|
+
* (`~/.something-wicked/wicked-apps/emit-outbox.ndjson`), shared by every daemon on the host, with
|
|
15
|
+
* no timestamp, no origin, and nothing on `/diagnostics` or the console to say so — 3,400+ entries
|
|
16
|
+
* on one host while the home board asserted "Governed 100%".
|
|
17
|
+
*
|
|
18
|
+
* # Resolution, in order
|
|
19
|
+
*
|
|
20
|
+
* 1. `--governance-db` / `WICKED_CREW_GOVERNANCE_DB` — the operator's explicit choice;
|
|
21
|
+
* 2. an inherited `WICKED_ESTATE_DB` — the engine's own variable, honoured as-is (pointing several
|
|
22
|
+
* daemons, or the estate MCP, at ONE shared store is exactly what it exists for);
|
|
23
|
+
* 3. `<core db>.governance/governance.db` — a SIDECAR of the core db, the default. Why a sidecar
|
|
24
|
+
* and not `<state home>/governance.db`: wicked-core embeds crew's state-home registry
|
|
25
|
+
* (`tests/fixtures/state-home-subtrees.json`, core `src/state_home.rs`) as the worker Read
|
|
26
|
+
* fence and REFUSES every launch that meets a top-level entry the registry does not classify.
|
|
27
|
+
* The registry's `core.db` entry is a PREFIX claim (`file-with-sidecars`) that already covers a
|
|
28
|
+
* `core.db.governance/` directory, exactly as it covers core's own `core.db.events/` and crew's
|
|
29
|
+
* `core.db.bus/` (F-043). A new top-level name would need a byte-identical registry change in
|
|
30
|
+
* BOTH repos and a core release before one governed run could start beside it; the sidecar
|
|
31
|
+
* needs neither, and `GET /diagnostics.stores` lists it for free. The prefix claim is spelled
|
|
32
|
+
* for the DEFAULT basename: a `--db` named anything but `core.db` already puts the db itself,
|
|
33
|
+
* its `-wal`/`-shm`, core's own `<db>.events/` and crew's `<db>.bus/` outside the registry —
|
|
34
|
+
* this sidecar is no different, so a daemon that hosts governed runs keeps the default
|
|
35
|
+
* basename (the same residual `interactive/bus-location.ts` documents).
|
|
36
|
+
*
|
|
37
|
+
* Why NOT the core db itself: the single-writer actor holds `core.db` open, and the emit seam opens
|
|
38
|
+
* its OWN connection per emit — pointing it at `core.db` would put a second writer on the actor's
|
|
39
|
+
* store, the one race the single-writer design exists to rule out.
|
|
40
|
+
*
|
|
41
|
+
* # The dead-letter outbox
|
|
42
|
+
*
|
|
43
|
+
* When the store cannot be written (unopenable path, a write error) the engine spools the event to
|
|
44
|
+
* the NDJSON outbox named by `WICKED_APPS_EMIT_DEADLETTER`. An explicit value in the daemon's
|
|
45
|
+
* environment is honoured — it is the engine's own override, and the hermetic test harness relies
|
|
46
|
+
* on it (`tests/setup/hermetic-home.ts`); otherwise the outbox is `<core db>.governance/
|
|
47
|
+
* emit-outbox.ndjson` — under the state home, never under HOME, never shared by two daemons —
|
|
48
|
+
* whichever store won. `GET /diagnostics` folds it (`governance.deadletters`) and raises a
|
|
49
|
+
* `governance.deadletter` finding whenever it holds an entry; `wicked-crew governance replay`
|
|
50
|
+
* drains it back into the store.
|
|
51
|
+
*
|
|
52
|
+
* # Why exporting `WICKED_ESTATE_DB` process-wide is safe
|
|
53
|
+
*
|
|
54
|
+
* The napi engine runs in this process and reads the variable at emit time, so `process.env` is
|
|
55
|
+
* the only channel. The ONLY in-process reader is the emit seam — the actor opens its store by the
|
|
56
|
+
* explicit `--db` path, every governance binding takes its path as an argument. Governed workers
|
|
57
|
+
* never inherit it: core strips it from every spawn (`spawn.rs` `hardened()`, FINDING-067) and
|
|
58
|
+
* re-points a worker's estate channel at the repo's OWN graph (`execute_wrapped.rs`). Crew's own
|
|
59
|
+
* children that would resolve a store from it get the BOOT-TIME value back
|
|
60
|
+
* ({@link childEnvWithBootEstateDb}) — the operator's instruction, not the daemon's sidecar.
|
|
61
|
+
*/
|
|
62
|
+
/** The `serve` / `governance` flag naming the store explicitly. */
|
|
63
|
+
export declare const GOVERNANCE_DB_FLAG = "--governance-db";
|
|
64
|
+
/** The crew-side env override — the flag's environment spelling. */
|
|
65
|
+
export declare const GOVERNANCE_DB_ENV = "WICKED_CREW_GOVERNANCE_DB";
|
|
66
|
+
/** The ENGINE's variable: the shared estate store `wicked-apps-core::emit::emit_event` writes to
|
|
67
|
+
* (`wicked_apps_core::ESTATE_DB_ENV`). Exported by the daemon; never typed out elsewhere. */
|
|
68
|
+
export declare const ESTATE_DB_ENGINE_ENV = "WICKED_ESTATE_DB";
|
|
69
|
+
/** The ENGINE's dead-letter outbox override (`wicked_apps_core::emit::DEADLETTER_ENV`). */
|
|
70
|
+
export declare const EMIT_DEADLETTER_ENGINE_ENV = "WICKED_APPS_EMIT_DEADLETTER";
|
|
71
|
+
/** The ENGINE's optional origin stamp for spooled entries (`wicked_apps_core::emit::ORIGIN_ENV`,
|
|
72
|
+
* wicked-core ≥ the release carrying crew#495's companion): copied verbatim onto every
|
|
73
|
+
* dead-letter record as `origin`, beside the engine's own `ts` (epoch ms) and `pid`. An older
|
|
74
|
+
* engine ignores it — entries then carry no timestamp, which the fold reports honestly. */
|
|
75
|
+
export declare const EMIT_ORIGIN_ENGINE_ENV = "WICKED_APPS_EMIT_ORIGIN";
|
|
76
|
+
/** The sidecar directory's suffix and the two files it holds. */
|
|
77
|
+
export declare const GOVERNANCE_SIDECAR_SUFFIX = ".governance";
|
|
78
|
+
export declare const GOVERNANCE_DB_FILENAME = "governance.db";
|
|
79
|
+
export declare const EMIT_OUTBOX_FILENAME = "emit-outbox.ndjson";
|
|
80
|
+
/**
|
|
81
|
+
* The value of the engine's store variable when THIS PROCESS booted — the operator's instruction,
|
|
82
|
+
* captured before the daemon exports its own resolution over it. Children that resolve a store from
|
|
83
|
+
* the variable are handed this back ({@link childEnvWithBootEstateDb}).
|
|
84
|
+
*/
|
|
85
|
+
export declare const BOOT_ESTATE_DB: string | undefined;
|
|
86
|
+
/** What decided the store — logged at boot and reported on `/diagnostics` so an operator can see which rule won. */
|
|
87
|
+
export type GovernanceStoreSource = 'flag' | 'env-crew' | 'env-estate' | 'core-db-sidecar';
|
|
88
|
+
/** What decided the outbox: the engine's own override in the environment, or the sidecar default. */
|
|
89
|
+
export type GovernanceOutboxSource = 'env' | 'core-db-sidecar';
|
|
90
|
+
export interface GovernanceStoreLocation {
|
|
91
|
+
/** The estate store the engine's emit seam writes to — exported as `WICKED_ESTATE_DB`. An
|
|
92
|
+
* absolute SQLite path, or `:memory:` (the engine's "no shared store"). The emit seam is
|
|
93
|
+
* SQLite-only (`wicked-apps-core::emit::emit_event` → `open_store` → `SqliteStore::open`), so a
|
|
94
|
+
* URL spec is REFUSED at resolution ({@link GovernanceStoreError}) — never handed to an engine
|
|
95
|
+
* that would dead-letter every event and print the spec, credentials included, on stderr. */
|
|
96
|
+
dbPath: string;
|
|
97
|
+
/** What operator-facing surfaces print — the boot log, the readiness line,
|
|
98
|
+
* `/diagnostics.governance.store.path`, `governance replay` output. Equal to `dbPath` for every
|
|
99
|
+
* value the resolver admits; the userinfo redaction ({@link redactStoreSpec}) is defence in depth. */
|
|
100
|
+
displayPath: string;
|
|
101
|
+
source: GovernanceStoreSource;
|
|
102
|
+
/** The dead-letter outbox — exported as `WICKED_APPS_EMIT_DEADLETTER`. */
|
|
103
|
+
outboxPath: string;
|
|
104
|
+
outboxSource: GovernanceOutboxSource;
|
|
105
|
+
/** `<core db>.governance` — created at boot so the engine's first write never fails on a missing parent. */
|
|
106
|
+
sidecarDir: string;
|
|
107
|
+
/** The daemon's core db, absolute — what `governance replay --db` names to reach the SAME sidecar. */
|
|
108
|
+
coreDbPath: string;
|
|
109
|
+
}
|
|
110
|
+
export interface GovernanceStoreInput {
|
|
111
|
+
/** `--governance-db` (flag), or undefined. */
|
|
112
|
+
flagDb?: string | undefined;
|
|
113
|
+
/** `WICKED_CREW_GOVERNANCE_DB`, or undefined/empty. */
|
|
114
|
+
envCrewDb?: string | undefined;
|
|
115
|
+
/** An inherited `WICKED_ESTATE_DB`, or undefined/empty. */
|
|
116
|
+
envEstateDb?: string | undefined;
|
|
117
|
+
/** An inherited `WICKED_APPS_EMIT_DEADLETTER`, or undefined/empty. */
|
|
118
|
+
envOutbox?: string | undefined;
|
|
119
|
+
/** The daemon's core db path (`--db`, or the default under the state home). */
|
|
120
|
+
coreDbPath: string;
|
|
121
|
+
/** The daemon's cross-product bus db (`resolveCrewBus().dbPath`) — refused as a governance store too. */
|
|
122
|
+
busDbPath?: string | undefined;
|
|
123
|
+
}
|
|
124
|
+
/** A governance store the engine could not honour — a boot error, not a warning: the alternative is a
|
|
125
|
+
* daemon that dead-letters 100 % of its governance events (a URL spec on the SQLite-only emit seam)
|
|
126
|
+
* or a second writer on the actor's `core.db` / the bus db (the race the single-writer design
|
|
127
|
+
* exists to rule out). Same shape as `interactive/bus-location.ts`'s `CrewBusError`. */
|
|
128
|
+
export declare class GovernanceStoreError extends Error {
|
|
129
|
+
constructor(message: string);
|
|
130
|
+
}
|
|
131
|
+
/** The sidecar directory the daemon's governance store and outbox live in: `<core db>.governance`. */
|
|
132
|
+
export declare function governanceSidecarDir(coreDbPath: string): string;
|
|
133
|
+
/** The default store: `<core db>.governance/governance.db`. */
|
|
134
|
+
export declare function governanceSidecarDb(coreDbPath: string): string;
|
|
135
|
+
/** The default outbox: `<core db>.governance/emit-outbox.ndjson`. */
|
|
136
|
+
export declare function governanceSidecarOutbox(coreDbPath: string): string;
|
|
137
|
+
/** Whether a store value is a URL spec (`postgres://…`) — something the emit seam cannot open. */
|
|
138
|
+
export declare function isUrlSpec(value: string): boolean;
|
|
139
|
+
/** A store spec the engine parses itself rather than a filesystem path — `:memory:`, and nothing
|
|
140
|
+
* else: the emit seam is SQLite-only, so a URL spec is refused before it gets this far. Left
|
|
141
|
+
* exactly as written, never resolved, never `mkdir`ed for. */
|
|
142
|
+
export declare function isStoreSpec(value: string): boolean;
|
|
143
|
+
/** DEFENCE IN DEPTH: a value safe to print — a URL's credentials become `***` (`postgres://u:p@h/db`
|
|
144
|
+
* → `postgres://***@h/db`); `:memory:` and filesystem paths are returned unchanged. URL specs are
|
|
145
|
+
* refused at resolution, so in practice this is the identity; it stays so that no future rung can
|
|
146
|
+
* print a credential by accident (the refusal message itself uses it). */
|
|
147
|
+
export declare function redactStoreSpec(value: string): string;
|
|
148
|
+
/**
|
|
149
|
+
* The CANONICAL spelling of a path that may not exist yet: the real path of its nearest existing
|
|
150
|
+
* ancestor plus the remaining segments — so a symlink to `core.db` (or to its directory) compares
|
|
151
|
+
* equal to `core.db` itself, which `resolve()` alone (lexical `..` folding) cannot see. Fails
|
|
152
|
+
* closed: anything but "does not exist" while walking up is a {@link GovernanceStoreError}.
|
|
153
|
+
*/
|
|
154
|
+
export declare function canonicalPath(p: string): string;
|
|
155
|
+
/** Resolve the governance store and its outbox for one daemon — pure, so two `--db` inputs can be compared. */
|
|
156
|
+
export declare function resolveGovernanceStore(input: GovernanceStoreInput): GovernanceStoreLocation;
|
|
157
|
+
/**
|
|
158
|
+
* Hand the resolved location to the engine: export the two engine variables into `env` and create
|
|
159
|
+
* the sidecar directory (the engine's SQLite open does not create a missing parent, and a spool
|
|
160
|
+
* into a missing directory is a dead letter that itself fails). Called ONCE per daemon, before the
|
|
161
|
+
* engine exists (`CoreAdapter`'s constructor) — the emit seam reads the variables at emit time,
|
|
162
|
+
* so nothing needs a restart. A library boot that never resolves a location exports nothing, and
|
|
163
|
+
* the hermetic test arming stays exactly as it was.
|
|
164
|
+
*/
|
|
165
|
+
export declare function applyGovernanceStoreEnv(location: GovernanceStoreLocation, env?: NodeJS.ProcessEnv): void;
|
|
166
|
+
/**
|
|
167
|
+
* The origin stamp the engine copies onto every dead-letter record — WHICH daemon spooled it, so a
|
|
168
|
+
* record read months later in a drained outbox still says where it came from. Human-readable on
|
|
169
|
+
* purpose; the port is appended once the daemon has bound (the engine reads the variable at emit
|
|
170
|
+
* time, so the update is seen by the next spool).
|
|
171
|
+
*/
|
|
172
|
+
export declare function emitOrigin(fields: {
|
|
173
|
+
version: string;
|
|
174
|
+
pid: number;
|
|
175
|
+
coreDbPath: string;
|
|
176
|
+
port?: number | undefined;
|
|
177
|
+
}): string;
|
|
178
|
+
/** Export the origin stamp for the engine. */
|
|
179
|
+
export declare function applyEmitOrigin(origin: string, env?: NodeJS.ProcessEnv): void;
|
|
180
|
+
/**
|
|
181
|
+
* The environment for EVERY child crew spawns (git, uv, the estate CLI and MCP, the deliver shell,
|
|
182
|
+
* the interactive bridge, the OS opener, `ps`/`lsof`): the daemon's exported governance store is the
|
|
183
|
+
* in-process engine's business and nobody else's. `WICKED_ESTATE_DB` goes back to whatever the
|
|
184
|
+
* process booted with — the operator's explicit store, or nothing (a newer estate binary handed the
|
|
185
|
+
* daemon's `governance.db` as its graph store could migrate the file's schema past what the engine's
|
|
186
|
+
* vendored store opens) — and crew's own override `WICKED_CREW_GOVERNANCE_DB`, needed only at
|
|
187
|
+
* resolution, is dropped outright. Governed workers are covered separately by core's `hardened()`.
|
|
188
|
+
*/
|
|
189
|
+
export declare function childEnvWithBootEstateDb(env?: NodeJS.ProcessEnv, bootValue?: string | undefined): NodeJS.ProcessEnv;
|
|
190
|
+
/**
|
|
191
|
+
* Where a PRE-FIX engine dead-lettered under HOME — `<HOME | USERPROFILE>/.something-wicked/
|
|
192
|
+
* wicked-apps/emit-outbox.ndjson`, the engine's own default (`emit.rs` `deadletter_path()`), spelled
|
|
193
|
+
* here only so the daemon can TELL the operator it exists (a boot warning and a `/diagnostics`
|
|
194
|
+
* finding with the replay command). Crew never writes it. `null` when no home resolves.
|
|
195
|
+
*/
|
|
196
|
+
export declare function legacyHomeOutboxPath(env?: NodeJS.ProcessEnv): string | null;
|
|
197
|
+
/**
|
|
198
|
+
* Whose dead letters the HOME outbox holds, as far as THIS daemon can tell (F-2R2-006).
|
|
199
|
+
*
|
|
200
|
+
* - `'own'` — this daemon runs in the DEFAULT state home of the HOME the outbox was found under
|
|
201
|
+
* (`<HOME>/.wicked-crew`), so the pre-fix daemons that spooled there were its own
|
|
202
|
+
* earlier versions: the outbox is its prior outbox, and replaying it into this
|
|
203
|
+
* daemon's store is the repair.
|
|
204
|
+
* - `'host'` — this daemon runs in an ISOLATED state home (`--db` elsewhere, a fresh rig, a test
|
|
205
|
+
* harness). A pre-fix engine wrote under HOME regardless of which daemon it served,
|
|
206
|
+
* so the file is shared by every daemon on the host and CANNOT be attributed to this
|
|
207
|
+
* one — it may hold other daemons' dead letters, or (for an isolated daemon that ran
|
|
208
|
+
* since before the fix) some of its own, and nothing in the file says which (the
|
|
209
|
+
* post-fix `origin` stamp, `emitOrigin`, would — a fold over it is the follow-up).
|
|
210
|
+
* Reporting it as a warning with a replay recipe would import a stranger's governance
|
|
211
|
+
* events into this store; it is reported at info with the read-only inspect recipe.
|
|
212
|
+
*
|
|
213
|
+
* `coreDbPath` `null` (no store resolved) is `'host'`: with no state home there is nothing to
|
|
214
|
+
* attribute the file to. Pure — the HOME is read off the outbox path itself
|
|
215
|
+
* (`<HOME>/.something-wicked/wicked-apps/<file>`), never off the process environment.
|
|
216
|
+
*/
|
|
217
|
+
export type LegacyOutboxScope = 'own' | 'host';
|
|
218
|
+
export declare function legacyOutboxScope(coreDbPath: string | null, legacyOutboxPath: string): LegacyOutboxScope;
|
|
219
|
+
//# sourceMappingURL=governance-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"governance-store.d.ts","sourceRoot":"","sources":["../../src/core/governance-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WHERE THE GOVERNANCE STORE LIVES — and where its dead letters go (crew#495, acceptance
|
|
3
|
+
* finding F-022). One pure resolution the CLI, the adapter, the diagnostics route and the tests
|
|
4
|
+
* share, in the shape of `interactive/bus-location.ts`.
|
|
5
|
+
*
|
|
6
|
+
* # The defect
|
|
7
|
+
*
|
|
8
|
+
* The engine's emit seam (`wicked-apps-core::emit::emit_event`) publishes every cross-product
|
|
9
|
+
* `wicked.*` event — the conformance claims and decisions the acceptance gate reads back
|
|
10
|
+
* (`wicked.crew.governance.conformance_recorded`), phase transitions, the steering-rule lifecycle
|
|
11
|
+
* (`wicked.estate.rule.ingested` / `.retired`), council traffic — as an EVENT node on the shared
|
|
12
|
+
* estate store named by `WICKED_ESTATE_DB`. `serve` never set that variable, so on EVERY default
|
|
13
|
+
* install EVERY such event dead-lettered: appended to an NDJSON outbox under the operator's HOME
|
|
14
|
+
* (`~/.something-wicked/wicked-apps/emit-outbox.ndjson`), shared by every daemon on the host, with
|
|
15
|
+
* no timestamp, no origin, and nothing on `/diagnostics` or the console to say so — 3,400+ entries
|
|
16
|
+
* on one host while the home board asserted "Governed 100%".
|
|
17
|
+
*
|
|
18
|
+
* # Resolution, in order
|
|
19
|
+
*
|
|
20
|
+
* 1. `--governance-db` / `WICKED_CREW_GOVERNANCE_DB` — the operator's explicit choice;
|
|
21
|
+
* 2. an inherited `WICKED_ESTATE_DB` — the engine's own variable, honoured as-is (pointing several
|
|
22
|
+
* daemons, or the estate MCP, at ONE shared store is exactly what it exists for);
|
|
23
|
+
* 3. `<core db>.governance/governance.db` — a SIDECAR of the core db, the default. Why a sidecar
|
|
24
|
+
* and not `<state home>/governance.db`: wicked-core embeds crew's state-home registry
|
|
25
|
+
* (`tests/fixtures/state-home-subtrees.json`, core `src/state_home.rs`) as the worker Read
|
|
26
|
+
* fence and REFUSES every launch that meets a top-level entry the registry does not classify.
|
|
27
|
+
* The registry's `core.db` entry is a PREFIX claim (`file-with-sidecars`) that already covers a
|
|
28
|
+
* `core.db.governance/` directory, exactly as it covers core's own `core.db.events/` and crew's
|
|
29
|
+
* `core.db.bus/` (F-043). A new top-level name would need a byte-identical registry change in
|
|
30
|
+
* BOTH repos and a core release before one governed run could start beside it; the sidecar
|
|
31
|
+
* needs neither, and `GET /diagnostics.stores` lists it for free. The prefix claim is spelled
|
|
32
|
+
* for the DEFAULT basename: a `--db` named anything but `core.db` already puts the db itself,
|
|
33
|
+
* its `-wal`/`-shm`, core's own `<db>.events/` and crew's `<db>.bus/` outside the registry —
|
|
34
|
+
* this sidecar is no different, so a daemon that hosts governed runs keeps the default
|
|
35
|
+
* basename (the same residual `interactive/bus-location.ts` documents).
|
|
36
|
+
*
|
|
37
|
+
* Why NOT the core db itself: the single-writer actor holds `core.db` open, and the emit seam opens
|
|
38
|
+
* its OWN connection per emit — pointing it at `core.db` would put a second writer on the actor's
|
|
39
|
+
* store, the one race the single-writer design exists to rule out.
|
|
40
|
+
*
|
|
41
|
+
* # The dead-letter outbox
|
|
42
|
+
*
|
|
43
|
+
* When the store cannot be written (unopenable path, a write error) the engine spools the event to
|
|
44
|
+
* the NDJSON outbox named by `WICKED_APPS_EMIT_DEADLETTER`. An explicit value in the daemon's
|
|
45
|
+
* environment is honoured — it is the engine's own override, and the hermetic test harness relies
|
|
46
|
+
* on it (`tests/setup/hermetic-home.ts`); otherwise the outbox is `<core db>.governance/
|
|
47
|
+
* emit-outbox.ndjson` — under the state home, never under HOME, never shared by two daemons —
|
|
48
|
+
* whichever store won. `GET /diagnostics` folds it (`governance.deadletters`) and raises a
|
|
49
|
+
* `governance.deadletter` finding whenever it holds an entry; `wicked-crew governance replay`
|
|
50
|
+
* drains it back into the store.
|
|
51
|
+
*
|
|
52
|
+
* # Why exporting `WICKED_ESTATE_DB` process-wide is safe
|
|
53
|
+
*
|
|
54
|
+
* The napi engine runs in this process and reads the variable at emit time, so `process.env` is
|
|
55
|
+
* the only channel. The ONLY in-process reader is the emit seam — the actor opens its store by the
|
|
56
|
+
* explicit `--db` path, every governance binding takes its path as an argument. Governed workers
|
|
57
|
+
* never inherit it: core strips it from every spawn (`spawn.rs` `hardened()`, FINDING-067) and
|
|
58
|
+
* re-points a worker's estate channel at the repo's OWN graph (`execute_wrapped.rs`). Crew's own
|
|
59
|
+
* children that would resolve a store from it get the BOOT-TIME value back
|
|
60
|
+
* ({@link childEnvWithBootEstateDb}) — the operator's instruction, not the daemon's sidecar.
|
|
61
|
+
*/
|
|
62
|
+
import { mkdirSync, realpathSync } from 'node:fs';
|
|
63
|
+
import { basename, dirname, join, resolve } from 'node:path';
|
|
64
|
+
import { defaultStateHome } from '../projects/state-home.js';
|
|
65
|
+
/** The `serve` / `governance` flag naming the store explicitly. */
|
|
66
|
+
export const GOVERNANCE_DB_FLAG = '--governance-db';
|
|
67
|
+
/** The crew-side env override — the flag's environment spelling. */
|
|
68
|
+
export const GOVERNANCE_DB_ENV = 'WICKED_CREW_GOVERNANCE_DB';
|
|
69
|
+
/** The ENGINE's variable: the shared estate store `wicked-apps-core::emit::emit_event` writes to
|
|
70
|
+
* (`wicked_apps_core::ESTATE_DB_ENV`). Exported by the daemon; never typed out elsewhere. */
|
|
71
|
+
export const ESTATE_DB_ENGINE_ENV = 'WICKED_ESTATE_DB';
|
|
72
|
+
/** The ENGINE's dead-letter outbox override (`wicked_apps_core::emit::DEADLETTER_ENV`). */
|
|
73
|
+
export const EMIT_DEADLETTER_ENGINE_ENV = 'WICKED_APPS_EMIT_DEADLETTER';
|
|
74
|
+
/** The ENGINE's optional origin stamp for spooled entries (`wicked_apps_core::emit::ORIGIN_ENV`,
|
|
75
|
+
* wicked-core ≥ the release carrying crew#495's companion): copied verbatim onto every
|
|
76
|
+
* dead-letter record as `origin`, beside the engine's own `ts` (epoch ms) and `pid`. An older
|
|
77
|
+
* engine ignores it — entries then carry no timestamp, which the fold reports honestly. */
|
|
78
|
+
export const EMIT_ORIGIN_ENGINE_ENV = 'WICKED_APPS_EMIT_ORIGIN';
|
|
79
|
+
/** The sidecar directory's suffix and the two files it holds. */
|
|
80
|
+
export const GOVERNANCE_SIDECAR_SUFFIX = '.governance';
|
|
81
|
+
export const GOVERNANCE_DB_FILENAME = 'governance.db';
|
|
82
|
+
export const EMIT_OUTBOX_FILENAME = 'emit-outbox.ndjson';
|
|
83
|
+
/**
|
|
84
|
+
* The value of the engine's store variable when THIS PROCESS booted — the operator's instruction,
|
|
85
|
+
* captured before the daemon exports its own resolution over it. Children that resolve a store from
|
|
86
|
+
* the variable are handed this back ({@link childEnvWithBootEstateDb}).
|
|
87
|
+
*/
|
|
88
|
+
export const BOOT_ESTATE_DB = process.env[ESTATE_DB_ENGINE_ENV];
|
|
89
|
+
/** A governance store the engine could not honour — a boot error, not a warning: the alternative is a
|
|
90
|
+
* daemon that dead-letters 100 % of its governance events (a URL spec on the SQLite-only emit seam)
|
|
91
|
+
* or a second writer on the actor's `core.db` / the bus db (the race the single-writer design
|
|
92
|
+
* exists to rule out). Same shape as `interactive/bus-location.ts`'s `CrewBusError`. */
|
|
93
|
+
export class GovernanceStoreError extends Error {
|
|
94
|
+
constructor(message) {
|
|
95
|
+
super(message);
|
|
96
|
+
this.name = 'GovernanceStoreError';
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/** The sidecar directory the daemon's governance store and outbox live in: `<core db>.governance`. */
|
|
100
|
+
export function governanceSidecarDir(coreDbPath) {
|
|
101
|
+
return `${resolve(coreDbPath)}${GOVERNANCE_SIDECAR_SUFFIX}`;
|
|
102
|
+
}
|
|
103
|
+
/** The default store: `<core db>.governance/governance.db`. */
|
|
104
|
+
export function governanceSidecarDb(coreDbPath) {
|
|
105
|
+
return join(governanceSidecarDir(coreDbPath), GOVERNANCE_DB_FILENAME);
|
|
106
|
+
}
|
|
107
|
+
/** The default outbox: `<core db>.governance/emit-outbox.ndjson`. */
|
|
108
|
+
export function governanceSidecarOutbox(coreDbPath) {
|
|
109
|
+
return join(governanceSidecarDir(coreDbPath), EMIT_OUTBOX_FILENAME);
|
|
110
|
+
}
|
|
111
|
+
/** A URL scheme of two or more characters followed by `://` — `postgres://`, `postgresql://`. A
|
|
112
|
+
* single letter before `://` is a Windows drive written with forward slashes (`C://tmp/gov.db`),
|
|
113
|
+
* which is a PATH. */
|
|
114
|
+
const URL_SCHEME_RE = /^[A-Za-z][A-Za-z0-9+.-]+:\/\//;
|
|
115
|
+
/** Whether a store value is a URL spec (`postgres://…`) — something the emit seam cannot open. */
|
|
116
|
+
export function isUrlSpec(value) {
|
|
117
|
+
return URL_SCHEME_RE.test(value);
|
|
118
|
+
}
|
|
119
|
+
/** A store spec the engine parses itself rather than a filesystem path — `:memory:`, and nothing
|
|
120
|
+
* else: the emit seam is SQLite-only, so a URL spec is refused before it gets this far. Left
|
|
121
|
+
* exactly as written, never resolved, never `mkdir`ed for. */
|
|
122
|
+
export function isStoreSpec(value) {
|
|
123
|
+
return value === ':memory:';
|
|
124
|
+
}
|
|
125
|
+
/** The userinfo of a URL spec — everything between `scheme://` and the first `@` before a `/`. */
|
|
126
|
+
const URL_USERINFO_RE = /^([A-Za-z][A-Za-z0-9+.-]+:\/\/)[^/@]*@/;
|
|
127
|
+
/** DEFENCE IN DEPTH: a value safe to print — a URL's credentials become `***` (`postgres://u:p@h/db`
|
|
128
|
+
* → `postgres://***@h/db`); `:memory:` and filesystem paths are returned unchanged. URL specs are
|
|
129
|
+
* refused at resolution, so in practice this is the identity; it stays so that no future rung can
|
|
130
|
+
* print a credential by accident (the refusal message itself uses it). */
|
|
131
|
+
export function redactStoreSpec(value) {
|
|
132
|
+
return isUrlSpec(value) ? value.replace(URL_USERINFO_RE, '$1***@') : value;
|
|
133
|
+
}
|
|
134
|
+
function present(value) {
|
|
135
|
+
if (value === undefined)
|
|
136
|
+
return undefined;
|
|
137
|
+
const trimmed = value.trim();
|
|
138
|
+
return trimmed === '' ? undefined : trimmed;
|
|
139
|
+
}
|
|
140
|
+
/** Spell an explicit store absolute AND normalized (`resolve` also folds `..` segments); relative
|
|
141
|
+
* flags land next to the cwd the operator typed them in, not wherever a later `join` happens to
|
|
142
|
+
* run. `:memory:` is untouched. */
|
|
143
|
+
function absoluteStore(value) {
|
|
144
|
+
return isStoreSpec(value) ? value : resolve(value);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* The CANONICAL spelling of a path that may not exist yet: the real path of its nearest existing
|
|
148
|
+
* ancestor plus the remaining segments — so a symlink to `core.db` (or to its directory) compares
|
|
149
|
+
* equal to `core.db` itself, which `resolve()` alone (lexical `..` folding) cannot see. Fails
|
|
150
|
+
* closed: anything but "does not exist" while walking up is a {@link GovernanceStoreError}.
|
|
151
|
+
*/
|
|
152
|
+
export function canonicalPath(p) {
|
|
153
|
+
const abs = resolve(p);
|
|
154
|
+
let existing = abs;
|
|
155
|
+
const tail = [];
|
|
156
|
+
for (;;) {
|
|
157
|
+
try {
|
|
158
|
+
const real = realpathSync.native(existing);
|
|
159
|
+
return tail.length === 0 ? real : join(real, ...tail);
|
|
160
|
+
}
|
|
161
|
+
catch (err) {
|
|
162
|
+
const code = err.code;
|
|
163
|
+
if (code !== 'ENOENT' && code !== 'ENOTDIR') {
|
|
164
|
+
throw new GovernanceStoreError(`cannot canonicalize ${abs} to check it against the daemon's own stores: ${err.message}`);
|
|
165
|
+
}
|
|
166
|
+
const parent = dirname(existing);
|
|
167
|
+
if (parent === existing)
|
|
168
|
+
return abs; // nothing on the way to the root exists yet
|
|
169
|
+
tail.unshift(basename(existing));
|
|
170
|
+
existing = parent;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/** Resolve the governance store and its outbox for one daemon — pure, so two `--db` inputs can be compared. */
|
|
175
|
+
export function resolveGovernanceStore(input) {
|
|
176
|
+
const sidecarDir = governanceSidecarDir(input.coreDbPath);
|
|
177
|
+
const envOutbox = present(input.envOutbox);
|
|
178
|
+
const outbox = envOutbox !== undefined
|
|
179
|
+
? { outboxPath: resolve(envOutbox), outboxSource: 'env' }
|
|
180
|
+
: { outboxPath: join(sidecarDir, EMIT_OUTBOX_FILENAME), outboxSource: 'core-db-sidecar' };
|
|
181
|
+
const coreDbPath = resolve(input.coreDbPath);
|
|
182
|
+
const busDbPath = present(input.busDbPath) !== undefined ? resolve(input.busDbPath) : undefined;
|
|
183
|
+
const at = (dbPath, source) => ({
|
|
184
|
+
dbPath,
|
|
185
|
+
displayPath: redactStoreSpec(dbPath),
|
|
186
|
+
source,
|
|
187
|
+
sidecarDir,
|
|
188
|
+
coreDbPath,
|
|
189
|
+
...outbox,
|
|
190
|
+
});
|
|
191
|
+
/** An explicit store (flag / env) must be one the engine can honour and must not be a store
|
|
192
|
+
* another writer already owns — refused loudly at boot, never silently dead-lettered. */
|
|
193
|
+
const explicit = (raw, source, how) => {
|
|
194
|
+
if (isUrlSpec(raw)) {
|
|
195
|
+
throw new GovernanceStoreError(`${how} names ${redactStoreSpec(raw)}, but the engine's emit seam stores to SQLite (wicked-apps-core ` +
|
|
196
|
+
'`open_store` → `SqliteStore::open`); a `postgres://` (or any URL) governance store is not supported — ' +
|
|
197
|
+
'every governance event would dead-letter. Name a SQLite file (default: <core db>.governance/governance.db) or `:memory:`.');
|
|
198
|
+
}
|
|
199
|
+
const dbPath = absoluteStore(raw);
|
|
200
|
+
// Compared CANONICALLY (symlinks resolved), so an alias of the core db or the bus db is caught.
|
|
201
|
+
const canonical = canonicalPath(dbPath);
|
|
202
|
+
if (canonical === canonicalPath(coreDbPath)) {
|
|
203
|
+
throw new GovernanceStoreError(`${how} names the daemon's own core db (${coreDbPath}); the single-writer actor holds that store and the emit ` +
|
|
204
|
+
'seam opens its own connection per emit — a second writer there is the race the design rules out. ' +
|
|
205
|
+
'Name a separate SQLite file (default: <core db>.governance/governance.db).');
|
|
206
|
+
}
|
|
207
|
+
if (busDbPath !== undefined && canonical === canonicalPath(busDbPath)) {
|
|
208
|
+
throw new GovernanceStoreError(`${how} names the cross-product bus db (${busDbPath}), which wicked-bus owns; name a separate SQLite file ` +
|
|
209
|
+
'(default: <core db>.governance/governance.db).');
|
|
210
|
+
}
|
|
211
|
+
return at(dbPath, source);
|
|
212
|
+
};
|
|
213
|
+
const flagDb = present(input.flagDb);
|
|
214
|
+
if (flagDb !== undefined)
|
|
215
|
+
return explicit(flagDb, 'flag', GOVERNANCE_DB_FLAG);
|
|
216
|
+
const envCrewDb = present(input.envCrewDb);
|
|
217
|
+
if (envCrewDb !== undefined)
|
|
218
|
+
return explicit(envCrewDb, 'env-crew', GOVERNANCE_DB_ENV);
|
|
219
|
+
const envEstateDb = present(input.envEstateDb);
|
|
220
|
+
if (envEstateDb !== undefined)
|
|
221
|
+
return explicit(envEstateDb, 'env-estate', `an inherited ${ESTATE_DB_ENGINE_ENV}`);
|
|
222
|
+
return at(join(sidecarDir, GOVERNANCE_DB_FILENAME), 'core-db-sidecar');
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Hand the resolved location to the engine: export the two engine variables into `env` and create
|
|
226
|
+
* the sidecar directory (the engine's SQLite open does not create a missing parent, and a spool
|
|
227
|
+
* into a missing directory is a dead letter that itself fails). Called ONCE per daemon, before the
|
|
228
|
+
* engine exists (`CoreAdapter`'s constructor) — the emit seam reads the variables at emit time,
|
|
229
|
+
* so nothing needs a restart. A library boot that never resolves a location exports nothing, and
|
|
230
|
+
* the hermetic test arming stays exactly as it was.
|
|
231
|
+
*/
|
|
232
|
+
export function applyGovernanceStoreEnv(location, env = process.env) {
|
|
233
|
+
mkdirSync(location.sidecarDir, { recursive: true });
|
|
234
|
+
if (!isStoreSpec(location.dbPath))
|
|
235
|
+
mkdirSync(dirname(location.dbPath), { recursive: true });
|
|
236
|
+
mkdirSync(dirname(location.outboxPath), { recursive: true });
|
|
237
|
+
env[ESTATE_DB_ENGINE_ENV] = location.dbPath;
|
|
238
|
+
env[EMIT_DEADLETTER_ENGINE_ENV] = location.outboxPath;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* The origin stamp the engine copies onto every dead-letter record — WHICH daemon spooled it, so a
|
|
242
|
+
* record read months later in a drained outbox still says where it came from. Human-readable on
|
|
243
|
+
* purpose; the port is appended once the daemon has bound (the engine reads the variable at emit
|
|
244
|
+
* time, so the update is seen by the next spool).
|
|
245
|
+
*/
|
|
246
|
+
export function emitOrigin(fields) {
|
|
247
|
+
const port = fields.port !== undefined ? ` port=${fields.port}` : '';
|
|
248
|
+
return `wicked-crew@${fields.version} serve pid=${fields.pid}${port} db=${resolve(fields.coreDbPath)}`;
|
|
249
|
+
}
|
|
250
|
+
/** Export the origin stamp for the engine. */
|
|
251
|
+
export function applyEmitOrigin(origin, env = process.env) {
|
|
252
|
+
env[EMIT_ORIGIN_ENGINE_ENV] = origin;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* The environment for EVERY child crew spawns (git, uv, the estate CLI and MCP, the deliver shell,
|
|
256
|
+
* the interactive bridge, the OS opener, `ps`/`lsof`): the daemon's exported governance store is the
|
|
257
|
+
* in-process engine's business and nobody else's. `WICKED_ESTATE_DB` goes back to whatever the
|
|
258
|
+
* process booted with — the operator's explicit store, or nothing (a newer estate binary handed the
|
|
259
|
+
* daemon's `governance.db` as its graph store could migrate the file's schema past what the engine's
|
|
260
|
+
* vendored store opens) — and crew's own override `WICKED_CREW_GOVERNANCE_DB`, needed only at
|
|
261
|
+
* resolution, is dropped outright. Governed workers are covered separately by core's `hardened()`.
|
|
262
|
+
*/
|
|
263
|
+
export function childEnvWithBootEstateDb(env = process.env, bootValue = BOOT_ESTATE_DB) {
|
|
264
|
+
const out = { ...env };
|
|
265
|
+
if (bootValue === undefined)
|
|
266
|
+
delete out[ESTATE_DB_ENGINE_ENV];
|
|
267
|
+
else
|
|
268
|
+
out[ESTATE_DB_ENGINE_ENV] = bootValue;
|
|
269
|
+
delete out[GOVERNANCE_DB_ENV];
|
|
270
|
+
return out;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Where a PRE-FIX engine dead-lettered under HOME — `<HOME | USERPROFILE>/.something-wicked/
|
|
274
|
+
* wicked-apps/emit-outbox.ndjson`, the engine's own default (`emit.rs` `deadletter_path()`), spelled
|
|
275
|
+
* here only so the daemon can TELL the operator it exists (a boot warning and a `/diagnostics`
|
|
276
|
+
* finding with the replay command). Crew never writes it. `null` when no home resolves.
|
|
277
|
+
*/
|
|
278
|
+
export function legacyHomeOutboxPath(env = process.env) {
|
|
279
|
+
const home = present(env['HOME']) ?? present(env['USERPROFILE']);
|
|
280
|
+
if (home === undefined)
|
|
281
|
+
return null;
|
|
282
|
+
return join(home, '.something-wicked', 'wicked-apps', EMIT_OUTBOX_FILENAME);
|
|
283
|
+
}
|
|
284
|
+
export function legacyOutboxScope(coreDbPath, legacyOutboxPath) {
|
|
285
|
+
if (coreDbPath === null)
|
|
286
|
+
return 'host';
|
|
287
|
+
const home = dirname(dirname(dirname(resolve(legacyOutboxPath))));
|
|
288
|
+
return dirname(resolve(coreDbPath)) === resolve(defaultStateHome(home)) ? 'own' : 'host';
|
|
289
|
+
}
|
|
290
|
+
//# sourceMappingURL=governance-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"governance-store.js","sourceRoot":"","sources":["../../src/core/governance-store.ts"],"names":[],"mappings":"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"}
|
package/dist/core/repoPaths.d.ts
CHANGED
|
@@ -14,16 +14,47 @@
|
|
|
14
14
|
* repo record that this package already reads, and this module is the only thing that touches that
|
|
15
15
|
* field. One producer, one consumer, nothing to keep in step.
|
|
16
16
|
*/
|
|
17
|
-
import type { RepoEntry } from './types.js';
|
|
17
|
+
import type { RepoEntry, RepoFinding } from './types.js';
|
|
18
18
|
/**
|
|
19
19
|
* The ABSOLUTE path of a repo's code graph, as resolved by the engine.
|
|
20
20
|
*
|
|
21
|
-
* Throws
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
21
|
+
* Throws — never falls back to the old hand-join, which is what this module exists to delete (it
|
|
22
|
+
* would restore the exact divergence above and hide it behind a path that looks plausible) — in two
|
|
23
|
+
* DISTINCT situations with different remedies, told apart by the error class:
|
|
24
|
+
*
|
|
25
|
+
* - {@link CodeGraphRootUnresolvableError}: the engine is CURRENT and resolved no repo-graph root
|
|
26
|
+
* (no `WICKED_ESTATE_REPO_GRAPH_ROOT`, no state home, no `HOME`/`USERPROFILE`), so it published an
|
|
27
|
+
* EMPTY `code_graph_db` together with a `code_graph_root_unresolvable` finding (wicked-core#406).
|
|
28
|
+
* The remedy is the daemon's environment; the finding's message says so. Callers that classify
|
|
29
|
+
* "engine too old" must let this one through (`projects/graph.ts assertEngineFresh`).
|
|
30
|
+
* - a plain `Error` naming wicked-core#170: the field is ABSENT (or empty with no such finding),
|
|
31
|
+
* which means the running `wicked-core` addon predates it. The remedy is a rebuild/reinstall.
|
|
32
|
+
*
|
|
33
|
+
* Loud is correct in both: every graph-backed surface would otherwise report an empty repo.
|
|
25
34
|
*/
|
|
26
35
|
export declare function codeGraphDb(repo: RepoEntry): string;
|
|
36
|
+
/** The engine's finding code for "no repo-graph root resolves" (`RepoEntry.findings[]`, wicked-core#406). */
|
|
37
|
+
export declare const CODE_GRAPH_ROOT_UNRESOLVABLE = "code_graph_root_unresolvable";
|
|
38
|
+
/**
|
|
39
|
+
* The ONE HTTP mapping every code-graph consumer shares for a `codeGraphDb()` failure this daemon
|
|
40
|
+
* can classify: **503** for {@link CodeGraphRootUnresolvableError} — a CURRENT engine resolved no
|
|
41
|
+
* repo-graph root, a daemon-environment fault (neither a bad request nor Fastify's generic 500) —
|
|
42
|
+
* and `null` for anything else, which the caller maps itself (501 for the stale-addon case on the
|
|
43
|
+
* project routes; the default elsewhere). Applied on the project-graph routes, the repo surfaces
|
|
44
|
+
* (`/repos/:id/{graph,graph/blast-radius,domain-graph,requirements…}`) and nowhere else.
|
|
45
|
+
*/
|
|
46
|
+
export declare function codeGraphErrorStatus(err: unknown): number | null;
|
|
47
|
+
/**
|
|
48
|
+
* A CURRENT engine resolved no repo-graph root for this repo (wicked-core#406) — see
|
|
49
|
+
* {@link codeGraphDb}. Distinct from the stale-addon `Error` on purpose: `projects/graph.ts` turns
|
|
50
|
+
* every other `codeGraphDb` throw into `ProjectGraphEngineTooOldError` (501, "reinstall the
|
|
51
|
+
* addon"), which is the wrong remedy here; this class is what lets it tell the two apart.
|
|
52
|
+
*/
|
|
53
|
+
export declare class CodeGraphRootUnresolvableError extends Error {
|
|
54
|
+
readonly repoId: string;
|
|
55
|
+
readonly finding: RepoFinding;
|
|
56
|
+
constructor(repoId: string, finding: RepoFinding);
|
|
57
|
+
}
|
|
27
58
|
/**
|
|
28
59
|
* The requirements artifacts a repo's domain extraction writes.
|
|
29
60
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repoPaths.d.ts","sourceRoot":"","sources":["../../src/core/repoPaths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"repoPaths.d.ts","sourceRoot":"","sources":["../../src/core/repoPaths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAanD;AAED,6GAA6G;AAC7G,eAAO,MAAM,4BAA4B,iCAAiC,CAAC;AAE3E;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAEhE;AAED;;;;;GAKG;AACH,qBAAa,8BAA+B,SAAQ,KAAK;IAErD,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,OAAO,EAAE,WAAW;gBADpB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,WAAW;CAKhC;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAEzD;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAE7D"}
|