wicked-crew 0.7.32 → 0.7.34
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 +2 -1
- package/dist/api/chat-turns.d.ts +87 -0
- package/dist/api/chat-turns.d.ts.map +1 -0
- package/dist/api/chat-turns.js +147 -0
- package/dist/api/chat-turns.js.map +1 -0
- package/dist/api/eval-sample.d.ts +18 -18
- package/dist/api/governance-steering.d.ts +4 -4
- package/dist/api/roster-standing.d.ts +42 -0
- package/dist/api/roster-standing.d.ts.map +1 -0
- package/dist/api/roster-standing.js +54 -0
- package/dist/api/roster-standing.js.map +1 -0
- package/dist/api/routes.d.ts +61 -3
- package/dist/api/routes.d.ts.map +1 -1
- package/dist/api/routes.js +171 -42
- package/dist/api/routes.js.map +1 -1
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +89 -1
- package/dist/api/server.js.map +1 -1
- package/dist/api/skills.d.ts.map +1 -1
- package/dist/api/skills.js +12 -3
- package/dist/api/skills.js.map +1 -1
- package/dist/api/testing.d.ts +4 -4
- package/dist/campaigns/routes.d.ts +14 -14
- package/dist/cli/index.js +23 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/core/adapter.d.ts +30 -0
- package/dist/core/adapter.d.ts.map +1 -1
- package/dist/core/adapter.js +66 -2
- package/dist/core/adapter.js.map +1 -1
- package/dist/core/engine-roster.d.ts +28 -0
- package/dist/core/engine-roster.d.ts.map +1 -1
- package/dist/core/engine-roster.js +28 -0
- package/dist/core/engine-roster.js.map +1 -1
- package/dist/core/types.d.ts +9 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +6 -0
- package/dist/core/types.js.map +1 -1
- package/dist/interactive/bridge-pool.d.ts +2 -2
- package/dist/interactive/bridge-pool.d.ts.map +1 -1
- package/dist/interactive/bridge-pool.js +19 -4
- package/dist/interactive/bridge-pool.js.map +1 -1
- package/dist/interactive/bus-subscriber-errors.d.ts +61 -0
- package/dist/interactive/bus-subscriber-errors.d.ts.map +1 -0
- package/dist/interactive/bus-subscriber-errors.js +85 -0
- package/dist/interactive/bus-subscriber-errors.js.map +1 -0
- package/dist/interactive/chat-events.d.ts +16 -0
- package/dist/interactive/chat-events.d.ts.map +1 -1
- package/dist/interactive/chat-events.js +59 -10
- package/dist/interactive/chat-events.js.map +1 -1
- package/dist/interactive/demo-events.d.ts +66 -0
- package/dist/interactive/demo-events.d.ts.map +1 -1
- package/dist/interactive/demo-events.js +154 -10
- package/dist/interactive/demo-events.js.map +1 -1
- package/dist/interactive/doc-delete-routes.js +2 -2
- package/dist/interactive/doc-delete-routes.js.map +1 -1
- package/dist/interactive/draft-events.d.ts +13 -0
- package/dist/interactive/draft-events.d.ts.map +1 -1
- package/dist/interactive/draft-events.js +34 -9
- package/dist/interactive/draft-events.js.map +1 -1
- package/dist/interactive/draft-skill.d.ts +68 -0
- package/dist/interactive/draft-skill.d.ts.map +1 -0
- package/dist/interactive/draft-skill.js +127 -0
- package/dist/interactive/draft-skill.js.map +1 -0
- package/dist/interactive/edit-events.d.ts +13 -0
- package/dist/interactive/edit-events.d.ts.map +1 -1
- package/dist/interactive/edit-events.js +35 -9
- package/dist/interactive/edit-events.js.map +1 -1
- package/dist/interactive/proxy-routes.d.ts +36 -0
- package/dist/interactive/proxy-routes.d.ts.map +1 -1
- package/dist/interactive/proxy-routes.js +90 -3
- package/dist/interactive/proxy-routes.js.map +1 -1
- package/dist/interactive/ws-relay.d.ts +2 -0
- package/dist/interactive/ws-relay.d.ts.map +1 -1
- package/dist/interactive/ws-relay.js +7 -3
- package/dist/interactive/ws-relay.js.map +1 -1
- package/dist/projects/activity.d.ts +17 -3
- package/dist/projects/activity.d.ts.map +1 -1
- package/dist/projects/activity.js +34 -13
- package/dist/projects/activity.js.map +1 -1
- package/dist/projects/events.d.ts +2 -0
- package/dist/projects/events.d.ts.map +1 -1
- package/dist/projects/events.js +7 -3
- package/dist/projects/events.js.map +1 -1
- package/dist/projects/state-home-preflight.d.ts +163 -0
- package/dist/projects/state-home-preflight.d.ts.map +1 -0
- package/dist/projects/state-home-preflight.js +310 -0
- package/dist/projects/state-home-preflight.js.map +1 -0
- package/dist/projects/state-home-registry.d.ts +25 -0
- package/dist/projects/state-home-registry.d.ts.map +1 -0
- package/dist/projects/state-home-registry.js +50 -0
- package/dist/projects/state-home-registry.js.map +1 -0
- package/dist/qe/gate-events.d.ts +2 -0
- package/dist/qe/gate-events.d.ts.map +1 -1
- package/dist/qe/gate-events.js +7 -3
- package/dist/qe/gate-events.js.map +1 -1
- package/dist/skills/base-skill.d.ts +92 -0
- package/dist/skills/base-skill.d.ts.map +1 -0
- package/dist/skills/base-skill.js +105 -0
- package/dist/skills/base-skill.js.map +1 -0
- package/dist/skills/runtime.d.ts +43 -1
- package/dist/skills/runtime.d.ts.map +1 -1
- package/dist/skills/runtime.js +110 -5
- package/dist/skills/runtime.js.map +1 -1
- package/dist/skills/store.d.ts +11 -0
- package/dist/skills/store.d.ts.map +1 -1
- package/dist/skills/store.js +16 -0
- package/dist/skills/store.js.map +1 -1
- package/dist/studio/assets/{index-Clm0MXDF.js → index-DhojBZ1T.js} +91 -91
- package/dist/studio/index.html +1 -1
- package/dist/studio/testid-inventory.json +51 -3
- package/endpoint-manifest.json +2 -1
- package/package.json +4 -4
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The TOP-LEVEL names of the daemon state home, as crew's `src/` knows them (wicked-core#411 /
|
|
3
|
+
* crew#497).
|
|
4
|
+
*
|
|
5
|
+
* The registry of record is `tests/fixtures/state-home-subtrees.json` — the file wicked-core
|
|
6
|
+
* embeds to build the worker Read fence (design v3.1 §1) and crew mirrors byte for byte. It lives
|
|
7
|
+
* under `tests/` so `src/` cannot read it, yet the daemon needs the same classification at BOOT
|
|
8
|
+
* to say, before anyone launches, that an entry under its state home is one the fence will refuse
|
|
9
|
+
* every worker launch over (`state-home-preflight.ts`). The engine answers that question itself
|
|
10
|
+
* once the addon carries `Core.preflightStateHome`; on an older addon crew classifies with THIS
|
|
11
|
+
* list. Same doctrine as `skills/root-names.ts` for the skills root's children: `src/` carries the
|
|
12
|
+
* names, `tests/state-home-subtrees.test.ts` asserts they equal the fixture, so the two cannot
|
|
13
|
+
* drift without a red test.
|
|
14
|
+
*
|
|
15
|
+
* `names` are exact top-level names; `prefixes` cover a file and its sidecars (`core.db`,
|
|
16
|
+
* `core.db-wal`, `core.db.events`, …). Nothing here is enumerated at runtime to BUILD a rule —
|
|
17
|
+
* that is core's fail-closed contract; crew only REPORTS what core would refuse.
|
|
18
|
+
*/
|
|
19
|
+
/** Exact top-level names the registry classifies. */
|
|
20
|
+
export const STATE_HOME_ENTRY_NAMES = [
|
|
21
|
+
'skills',
|
|
22
|
+
'audit.log',
|
|
23
|
+
'evals',
|
|
24
|
+
'project-graphs',
|
|
25
|
+
'repo-graphs',
|
|
26
|
+
'project-settings.json',
|
|
27
|
+
'interactive-chat-ledger.json',
|
|
28
|
+
'interactive-chats',
|
|
29
|
+
'interactive-demo-ledger.json',
|
|
30
|
+
'interactive-demos',
|
|
31
|
+
'interactive-draft-ledger.json',
|
|
32
|
+
'interactive-drafts',
|
|
33
|
+
'interactive-edit-ledger.json',
|
|
34
|
+
'interactive-edits',
|
|
35
|
+
// Placed by an OPERATOR variable, never by a `join(<state home>, …)` in src/ (the `env` field
|
|
36
|
+
// on the fixture entry): registered so a pre-existing placement is fenced rather than refusing
|
|
37
|
+
// every launch; `assertWickedRootsOutsideStateHome` refuses to BOOT with the variable pointed
|
|
38
|
+
// there (state-home-preflight.ts).
|
|
39
|
+
'workflows',
|
|
40
|
+
'steering-inbox',
|
|
41
|
+
'interactive',
|
|
42
|
+
];
|
|
43
|
+
/** Top-level PREFIXES the registry classifies (a file and its sidecars). */
|
|
44
|
+
export const STATE_HOME_ENTRY_PREFIXES = ['bus.db', 'core.db', 'daemon-'];
|
|
45
|
+
/** Is `topLevel` a name the registry classifies? */
|
|
46
|
+
export function isRegisteredStateHomeEntry(topLevel) {
|
|
47
|
+
return (STATE_HOME_ENTRY_NAMES.includes(topLevel) ||
|
|
48
|
+
STATE_HOME_ENTRY_PREFIXES.some((p) => topLevel.startsWith(p)));
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=state-home-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-home-registry.js","sourceRoot":"","sources":["../../src/projects/state-home-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,qDAAqD;AACrD,MAAM,CAAC,MAAM,sBAAsB,GAA0B;IAC3D,QAAQ;IACR,WAAW;IACX,OAAO;IACP,gBAAgB;IAChB,aAAa;IACb,uBAAuB;IACvB,8BAA8B;IAC9B,mBAAmB;IACnB,8BAA8B;IAC9B,mBAAmB;IACnB,+BAA+B;IAC/B,oBAAoB;IACpB,8BAA8B;IAC9B,mBAAmB;IACnB,8FAA8F;IAC9F,+FAA+F;IAC/F,8FAA8F;IAC9F,mCAAmC;IACnC,WAAW;IACX,gBAAgB;IAChB,aAAa;CACd,CAAC;AAEF,4EAA4E;AAC5E,MAAM,CAAC,MAAM,yBAAyB,GAA0B,CAAC,QAAQ,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;AAEjG,oDAAoD;AACpD,MAAM,UAAU,0BAA0B,CAAC,QAAgB;IACzD,OAAO,CACL,sBAAsB,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACzC,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAC9D,CAAC;AACJ,CAAC"}
|
package/dist/qe/gate-events.d.ts
CHANGED
|
@@ -88,6 +88,8 @@ export interface QeGateSubscriberOptions {
|
|
|
88
88
|
pollIntervalMs?: number;
|
|
89
89
|
/** Diagnostics sink (default: console.error). */
|
|
90
90
|
log?: (message: string) => void;
|
|
91
|
+
/** Error-level logger for connection-fatal subscriber errors (the /diagnostics ring folds it); defaults to `log`. */
|
|
92
|
+
logError?: (message: string) => void;
|
|
91
93
|
}
|
|
92
94
|
/** Handle for a running subscription. */
|
|
93
95
|
export interface QeGateSubscription {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gate-events.d.ts","sourceRoot":"","sources":["../../src/qe/gate-events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;
|
|
1
|
+
{"version":3,"file":"gate-events.d.ts","sourceRoot":"","sources":["../../src/qe/gate-events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAKH,8EAA8E;AAC9E,eAAO,MAAM,mBAAmB,2FAItB,CAAC;AAEX,gEAAgE;AAChE,eAAO,MAAM,oBAAoB,+BAA+B,CAAC;AAEjE;;;GAGG;AACH,eAAO,MAAM,aAAa,iBAAiB,CAAC;AAE5C,yEAAyE;AACzE,eAAO,MAAM,aAAa,gBAAgB,CAAC;AAE3C,qEAAqE;AACrE,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,4EAA4E;IAC5E,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,8EAA8E;IAC9E,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,yEAAyE;IACzE,UAAU,EAAE,MAAM,CAAC;CACpB;AAUD;;;;;;;GAOG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAuC;IAC7D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuC;IACjE,OAAO,CAAC,WAAW,CAA+B;IAElD;;;;OAIG;IACH,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,SAA2B,GAAG,OAAO;IAoC3F,gDAAgD;IAChD,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS;IAInD,8DAA8D;IAC9D,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS;IAIzD,kEAAkE;IAClE,MAAM,IAAI,gBAAgB,GAAG,SAAS;IAItC,6EAA6E;IAC7E,IAAI,IAAI,MAAM;CAGf;AAED,iDAAiD;AACjD,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iDAAiD;IACjD,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,qHAAqH;IACrH,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAED,yCAAyC;AACzC,MAAM,WAAW,kBAAkB;IACjC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC9B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,WAAW,EAClB,IAAI,GAAE,uBAA4B,GACjC,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAmDpC"}
|
package/dist/qe/gate-events.js
CHANGED
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
* cache is a freshness signal — the ledger stays the system of record for the
|
|
22
22
|
* gate decision, so a lost or replayed event can never flip a verdict.
|
|
23
23
|
*/
|
|
24
|
+
import { busSubscriberErrorReporter } from '../interactive/bus-subscriber-errors.js';
|
|
24
25
|
/** The gate-result event types (the old gate.mjs wire contract, verbatim). */
|
|
25
26
|
export const QE_GATE_EVENT_TYPES = [
|
|
26
27
|
'wicked.qe.gate.passed',
|
|
@@ -157,9 +158,12 @@ export async function startQeGateSubscriber(cache, opts = {}) {
|
|
|
157
158
|
handler: (event) => {
|
|
158
159
|
cache.ingest(event.event_type, event.payload);
|
|
159
160
|
},
|
|
160
|
-
onError: (
|
|
161
|
-
|
|
162
|
-
|
|
161
|
+
onError: busSubscriberErrorReporter({
|
|
162
|
+
describe: (err, event) => `[qe-gate-events] handler error on event ${String(event?.event_id ?? '?')}: ${err.message}`,
|
|
163
|
+
log,
|
|
164
|
+
logError: opts.logError,
|
|
165
|
+
pollIntervalMs: opts.pollIntervalMs ?? 5000,
|
|
166
|
+
}),
|
|
163
167
|
});
|
|
164
168
|
return {
|
|
165
169
|
stop: () => sub.stop(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gate-events.js","sourceRoot":"","sources":["../../src/qe/gate-events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;
|
|
1
|
+
{"version":3,"file":"gate-events.js","sourceRoot":"","sources":["../../src/qe/gate-events.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The BASE skill posture (crew#554 — the launcher half of wicked-core#468).
|
|
3
|
+
*
|
|
4
|
+
* The engine prepends ONE role-keyed discipline directive to EVERY agent unit's prompt —
|
|
5
|
+
* `Invoke your skill "<base>" … and follow its §<role> section` — when a base skill is in force:
|
|
6
|
+
* the workflow def's `base_skill_ref`, else the engine-config default `WICKED_BASE_SKILL_REF`.
|
|
7
|
+
* It is GATED AT INTAKE: a launch whose handed skills snapshot lacks the skill is refused before
|
|
8
|
+
* any unit is planned (`SkillsError::BaseSkillRefused`). Crew is the launcher, so crew owns the
|
|
9
|
+
* default (`SystemSettings.baseSkillRef`, shipped as `wicked-garden-governed-worker`) and must
|
|
10
|
+
* decide what a snapshot WITHOUT the skill means:
|
|
11
|
+
*
|
|
12
|
+
* `baseSkillPolicy: 'warn'` (default) — export the env ONLY when the published generation
|
|
13
|
+
* holds the skill; otherwise leave it unset (runs proceed without
|
|
14
|
+
* the directive) and raise a `skills.base-skill` WARNING. A fresh
|
|
15
|
+
* install lacks the skill until the garden that ships it is
|
|
16
|
+
* installed and published — a visible warning, never a dead Send.
|
|
17
|
+
* `baseSkillPolicy: 'require'` — export the env whatever the generation holds; the engine
|
|
18
|
+
* refuses every launch at intake until a generation with the skill
|
|
19
|
+
* is published. The finding is an ERROR that says so.
|
|
20
|
+
*
|
|
21
|
+
* Pure: the posture is a function of the configured default, the published generation's skill
|
|
22
|
+
* rows and the editor catalog — the runtime applies it to `process.env` (engine-env.ts) and
|
|
23
|
+
* reports it (`GET /health.baseSkill`, `GET /diagnostics.skills.baseSkill`, the publish/refresh
|
|
24
|
+
* results). `gen` here is the generation the NEXT launch is judged against; the generation a
|
|
25
|
+
* RUNNING unit was handed is that unit's `skillsSnapshotHanded.gen`, joined with its
|
|
26
|
+
* `unitDispatched.baseSkill {name, role}` frame.
|
|
27
|
+
*/
|
|
28
|
+
import type { SkillsHealthFinding } from './runtime.js';
|
|
29
|
+
/** The engine-config variable wicked-core reads at intake (`workflow::BASE_SKILL_REF_ENV`). */
|
|
30
|
+
export declare const BASE_SKILL_REF_ENGINE_ENV = "WICKED_BASE_SKILL_REF";
|
|
31
|
+
/** The shipped default: the cross-CLI discipline skill wicked-garden publishes (garden#1131). */
|
|
32
|
+
export declare const DEFAULT_BASE_SKILL_REF = "wicked-garden-governed-worker";
|
|
33
|
+
export type BaseSkillPolicy = 'warn' | 'require';
|
|
34
|
+
export declare const BASE_SKILL_POLICIES: ReadonlySet<string>;
|
|
35
|
+
/**
|
|
36
|
+
* What a base skill NAME may look like once trimmed: empty (off) or a frontmatter skill name —
|
|
37
|
+
* lowercase letters, digits, `-`, `_`, `:`, `.` (the `wicked-garden-<dir>` convention and the
|
|
38
|
+
* `wicked-garden:<dir>` plugin spelling), ≤ 128 chars. The PUT /settings boundary and the
|
|
39
|
+
* hand-edited settings.json read both hold to it, so the engine is never handed whitespace, a path
|
|
40
|
+
* or a sentence as `WICKED_BASE_SKILL_REF` (which would refuse every launch by a name nobody typed).
|
|
41
|
+
*/
|
|
42
|
+
export declare const BASE_SKILL_REF_SHAPE: RegExp;
|
|
43
|
+
/** What the settings store says: the skill name (`''` = off) and the missing-skill policy. */
|
|
44
|
+
export interface BaseSkillConfig {
|
|
45
|
+
ref: string;
|
|
46
|
+
policy: BaseSkillPolicy;
|
|
47
|
+
}
|
|
48
|
+
/** The published generation the engine is handed, reduced to what the posture needs. */
|
|
49
|
+
export interface PublishedSkills {
|
|
50
|
+
gen: number;
|
|
51
|
+
/** Frontmatter names of every skill row in the generation's `snapshot.json`. */
|
|
52
|
+
skills: ReadonlyArray<string>;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The base skill in force for the next launch — `null` when the setting is off (`''`).
|
|
56
|
+
* Additive on every surface that carries it (api-types declares it as optional).
|
|
57
|
+
*/
|
|
58
|
+
export interface BaseSkillPosture {
|
|
59
|
+
/** The frontmatter name the engine is (or would be) handed. */
|
|
60
|
+
name: string;
|
|
61
|
+
policy: BaseSkillPolicy;
|
|
62
|
+
/** The published generation the engine is handed holds the skill — the intake admission will pass. */
|
|
63
|
+
present: boolean;
|
|
64
|
+
/** The editor catalog holds the skill enabled — a publish would hand it (`present` after the next publish). */
|
|
65
|
+
inCatalog: boolean;
|
|
66
|
+
/** The generation judged, or `null` when nothing is published (fallback / blocked / config-error / disabled). */
|
|
67
|
+
gen: number | null;
|
|
68
|
+
/** What `WICKED_BASE_SKILL_REF` is exported as: the name, or `null` = unset (the engine runs without a base skill). */
|
|
69
|
+
engineInput: string | null;
|
|
70
|
+
/** The `skills.base-skill` finding when the generation lacks the skill; `null` when it holds it. */
|
|
71
|
+
finding: SkillsHealthFinding | null;
|
|
72
|
+
}
|
|
73
|
+
/** Trim the configured name; `''`/blank is "no base skill". */
|
|
74
|
+
export declare function normalizeBaseSkillRef(ref: string | undefined): string;
|
|
75
|
+
/**
|
|
76
|
+
* Compute the posture. `published` is `null` when no verified generation is exported (the engine
|
|
77
|
+
* either falls back to the live plugin or refuses — either way the base skill is not KNOWN to be
|
|
78
|
+
* handed, so it counts as absent); `inCatalog` answers whether the editor manifest holds the
|
|
79
|
+
* skill enabled (what a publish would hand).
|
|
80
|
+
*/
|
|
81
|
+
export declare function baseSkillPosture(config: BaseSkillConfig, published: PublishedSkills | null, inCatalog: (name: string) => boolean): BaseSkillPosture | null;
|
|
82
|
+
/**
|
|
83
|
+
* Apply a posture to THIS process's environment. The engine reads `WICKED_BASE_SKILL_REF` at
|
|
84
|
+
* INTAKE (plan time) per launch — never cached — so applying it at boot, after every publish /
|
|
85
|
+
* refresh and on every settings change is the whole mechanism: no daemon or engine restart.
|
|
86
|
+
* Crew OWNS the variable while the seam is live: a value the process booted with is overwritten
|
|
87
|
+
* (the setting is the source of truth; `baseSkillRef: ""` deletes it).
|
|
88
|
+
*/
|
|
89
|
+
export declare function applyBaseSkillEnv(posture: BaseSkillPosture | null): void;
|
|
90
|
+
/** The one-line disclosure a composer / run header renders: `discipline skill: <name> gen N`. */
|
|
91
|
+
export declare function describeBaseSkill(posture: BaseSkillPosture | null): string;
|
|
92
|
+
//# sourceMappingURL=base-skill.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-skill.d.ts","sourceRoot":"","sources":["../../src/skills/base-skill.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAExD,+FAA+F;AAC/F,eAAO,MAAM,yBAAyB,0BAA0B,CAAC;AAEjE,iGAAiG;AACjG,eAAO,MAAM,sBAAsB,kCAAkC,CAAC;AAEtE,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,SAAS,CAAC;AAEjD,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAAC,MAAM,CAAiD,CAAC;AAEtG;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,QAAuC,CAAC;AAEzE,8FAA8F;AAC9F,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,eAAe,CAAC;CACzB;AAED,wFAAwF;AACxF,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,gFAAgF;IAChF,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CAC/B;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,CAAC;IACxB,sGAAsG;IACtG,OAAO,EAAE,OAAO,CAAC;IACjB,+GAA+G;IAC/G,SAAS,EAAE,OAAO,CAAC;IACnB,iHAAiH;IACjH,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,uHAAuH;IACvH,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,oGAAoG;IACpG,OAAO,EAAE,mBAAmB,GAAG,IAAI,CAAC;CACrC;AAED,+DAA+D;AAC/D,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAErE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,eAAe,EACvB,SAAS,EAAE,eAAe,GAAG,IAAI,EACjC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GACnC,gBAAgB,GAAG,IAAI,CASzB;AAqBD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,GAAG,IAAI,CAMxE;AAED,iGAAiG;AACjG,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,GAAG,MAAM,CAM1E"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The BASE skill posture (crew#554 — the launcher half of wicked-core#468).
|
|
3
|
+
*
|
|
4
|
+
* The engine prepends ONE role-keyed discipline directive to EVERY agent unit's prompt —
|
|
5
|
+
* `Invoke your skill "<base>" … and follow its §<role> section` — when a base skill is in force:
|
|
6
|
+
* the workflow def's `base_skill_ref`, else the engine-config default `WICKED_BASE_SKILL_REF`.
|
|
7
|
+
* It is GATED AT INTAKE: a launch whose handed skills snapshot lacks the skill is refused before
|
|
8
|
+
* any unit is planned (`SkillsError::BaseSkillRefused`). Crew is the launcher, so crew owns the
|
|
9
|
+
* default (`SystemSettings.baseSkillRef`, shipped as `wicked-garden-governed-worker`) and must
|
|
10
|
+
* decide what a snapshot WITHOUT the skill means:
|
|
11
|
+
*
|
|
12
|
+
* `baseSkillPolicy: 'warn'` (default) — export the env ONLY when the published generation
|
|
13
|
+
* holds the skill; otherwise leave it unset (runs proceed without
|
|
14
|
+
* the directive) and raise a `skills.base-skill` WARNING. A fresh
|
|
15
|
+
* install lacks the skill until the garden that ships it is
|
|
16
|
+
* installed and published — a visible warning, never a dead Send.
|
|
17
|
+
* `baseSkillPolicy: 'require'` — export the env whatever the generation holds; the engine
|
|
18
|
+
* refuses every launch at intake until a generation with the skill
|
|
19
|
+
* is published. The finding is an ERROR that says so.
|
|
20
|
+
*
|
|
21
|
+
* Pure: the posture is a function of the configured default, the published generation's skill
|
|
22
|
+
* rows and the editor catalog — the runtime applies it to `process.env` (engine-env.ts) and
|
|
23
|
+
* reports it (`GET /health.baseSkill`, `GET /diagnostics.skills.baseSkill`, the publish/refresh
|
|
24
|
+
* results). `gen` here is the generation the NEXT launch is judged against; the generation a
|
|
25
|
+
* RUNNING unit was handed is that unit's `skillsSnapshotHanded.gen`, joined with its
|
|
26
|
+
* `unitDispatched.baseSkill {name, role}` frame.
|
|
27
|
+
*/
|
|
28
|
+
/** The engine-config variable wicked-core reads at intake (`workflow::BASE_SKILL_REF_ENV`). */
|
|
29
|
+
export const BASE_SKILL_REF_ENGINE_ENV = 'WICKED_BASE_SKILL_REF';
|
|
30
|
+
/** The shipped default: the cross-CLI discipline skill wicked-garden publishes (garden#1131). */
|
|
31
|
+
export const DEFAULT_BASE_SKILL_REF = 'wicked-garden-governed-worker';
|
|
32
|
+
export const BASE_SKILL_POLICIES = new Set(['warn', 'require']);
|
|
33
|
+
/**
|
|
34
|
+
* What a base skill NAME may look like once trimmed: empty (off) or a frontmatter skill name —
|
|
35
|
+
* lowercase letters, digits, `-`, `_`, `:`, `.` (the `wicked-garden-<dir>` convention and the
|
|
36
|
+
* `wicked-garden:<dir>` plugin spelling), ≤ 128 chars. The PUT /settings boundary and the
|
|
37
|
+
* hand-edited settings.json read both hold to it, so the engine is never handed whitespace, a path
|
|
38
|
+
* or a sentence as `WICKED_BASE_SKILL_REF` (which would refuse every launch by a name nobody typed).
|
|
39
|
+
*/
|
|
40
|
+
export const BASE_SKILL_REF_SHAPE = /^(?:[a-z0-9][a-z0-9._:-]{0,127})?$/;
|
|
41
|
+
/** Trim the configured name; `''`/blank is "no base skill". */
|
|
42
|
+
export function normalizeBaseSkillRef(ref) {
|
|
43
|
+
return typeof ref === 'string' ? ref.trim() : '';
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Compute the posture. `published` is `null` when no verified generation is exported (the engine
|
|
47
|
+
* either falls back to the live plugin or refuses — either way the base skill is not KNOWN to be
|
|
48
|
+
* handed, so it counts as absent); `inCatalog` answers whether the editor manifest holds the
|
|
49
|
+
* skill enabled (what a publish would hand).
|
|
50
|
+
*/
|
|
51
|
+
export function baseSkillPosture(config, published, inCatalog) {
|
|
52
|
+
const name = normalizeBaseSkillRef(config.ref);
|
|
53
|
+
if (name === '')
|
|
54
|
+
return null;
|
|
55
|
+
const present = published !== null && published.skills.includes(name);
|
|
56
|
+
const catalog = inCatalog(name);
|
|
57
|
+
const gen = published?.gen ?? null;
|
|
58
|
+
const engineInput = config.policy === 'require' || present ? name : null;
|
|
59
|
+
const finding = present ? null : missingFinding(name, config.policy, gen, catalog);
|
|
60
|
+
return { name, policy: config.policy, present, inCatalog: catalog, gen, engineInput, finding };
|
|
61
|
+
}
|
|
62
|
+
function missingFinding(name, policy, gen, inCatalog) {
|
|
63
|
+
const where = gen === null ? 'no published snapshot is handed to the engine' : `the published snapshot (gen ${gen}) does not hold it`;
|
|
64
|
+
const remedy = inCatalog
|
|
65
|
+
? 'it is in the catalog — POST /skills/publish hands it to the next launch'
|
|
66
|
+
: 'install a wicked-garden that ships it, POST /skills/refresh-baseline, then POST /skills/publish';
|
|
67
|
+
if (policy === 'require') {
|
|
68
|
+
return {
|
|
69
|
+
kind: 'skills.base-skill',
|
|
70
|
+
severity: 'error',
|
|
71
|
+
message: `the base skill "${name}" (baseSkillRef — the role-keyed discipline every governed unit follows) is REQUIRED but ${where}: the engine refuses every launch at intake until a generation holding it is published — ${remedy}; or set baseSkillPolicy "warn" to run without the discipline directive meanwhile`,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
kind: 'skills.base-skill',
|
|
76
|
+
severity: 'warning',
|
|
77
|
+
message: `the base skill "${name}" (baseSkillRef — the role-keyed discipline every governed unit follows) is not handed: ${where}, so runs proceed WITHOUT the discipline directive — ${remedy}; set baseSkillPolicy "require" to refuse such runs at intake instead`,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Apply a posture to THIS process's environment. The engine reads `WICKED_BASE_SKILL_REF` at
|
|
82
|
+
* INTAKE (plan time) per launch — never cached — so applying it at boot, after every publish /
|
|
83
|
+
* refresh and on every settings change is the whole mechanism: no daemon or engine restart.
|
|
84
|
+
* Crew OWNS the variable while the seam is live: a value the process booted with is overwritten
|
|
85
|
+
* (the setting is the source of truth; `baseSkillRef: ""` deletes it).
|
|
86
|
+
*/
|
|
87
|
+
export function applyBaseSkillEnv(posture) {
|
|
88
|
+
if (posture !== null && posture.engineInput !== null) {
|
|
89
|
+
process.env[BASE_SKILL_REF_ENGINE_ENV] = posture.engineInput;
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
delete process.env[BASE_SKILL_REF_ENGINE_ENV];
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/** The one-line disclosure a composer / run header renders: `discipline skill: <name> gen N`. */
|
|
96
|
+
export function describeBaseSkill(posture) {
|
|
97
|
+
if (posture === null)
|
|
98
|
+
return 'discipline skill: off';
|
|
99
|
+
if (posture.present)
|
|
100
|
+
return `discipline skill: ${posture.name} gen ${posture.gen ?? '?'}`;
|
|
101
|
+
return posture.policy === 'require'
|
|
102
|
+
? `discipline skill: ${posture.name} MISSING — runs will be refused at intake`
|
|
103
|
+
: `discipline skill: ${posture.name} MISSING — runs proceed without it`;
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=base-skill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-skill.js","sourceRoot":"","sources":["../../src/skills/base-skill.ts"],"names":[],"mappings":"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"}
|
package/dist/skills/runtime.d.ts
CHANGED
|
@@ -73,13 +73,15 @@
|
|
|
73
73
|
*/
|
|
74
74
|
import type { LaunchNotice } from '../core/adapter.js';
|
|
75
75
|
import type { CoreEvent } from '../core/types.js';
|
|
76
|
+
import { type BaseSkillPolicy, type BaseSkillPosture } from './base-skill.js';
|
|
76
77
|
import { REFUSED_DIRNAME } from './root-names.js';
|
|
77
78
|
import { type SkillsStore } from './store.js';
|
|
78
79
|
/** The refusal sentinel directory name — from the ONE table of root names (design v3.5 §2); re-exported for the tests. */
|
|
79
80
|
export { REFUSED_DIRNAME };
|
|
80
81
|
export type SkillsHealthState = 'published' | 'fallback' | 'blocked' | 'config-error' | 'disabled';
|
|
81
82
|
/** `skills.stale-rules` (F-083) is emitted ahead of its `wicked-crew-api-types` declaration — the next api-types cut adds it to `DiagnosticsSkillsFinding.kind`. */
|
|
82
|
-
|
|
83
|
+
/** `skills.base-skill` (crew#554): the configured base skill is not in the published generation — a warning under `baseSkillPolicy: 'warn'`, an error under `'require'`. */
|
|
84
|
+
export type SkillsHealthFindingKind = 'skills.fallback' | 'skills.blocked' | 'skills.config' | 'skills.source' | 'skills.manifest' | 'skills.stale-rules' | 'skills.base-skill';
|
|
83
85
|
export interface SkillsHealthFinding {
|
|
84
86
|
kind: SkillsHealthFindingKind;
|
|
85
87
|
severity: 'warning' | 'error';
|
|
@@ -102,6 +104,11 @@ export interface SkillsHealth {
|
|
|
102
104
|
* `null` when `disabled`. */
|
|
103
105
|
stateHome: string | null;
|
|
104
106
|
findings: SkillsHealthFinding[];
|
|
107
|
+
/** The BASE skill posture (crew#554 / core#468): the role-keyed discipline skill the engine is
|
|
108
|
+
* handed as `WICKED_BASE_SKILL_REF` for the next launch, judged against `current` — or `null`
|
|
109
|
+
* when the setting is off (`baseSkillRef: ""`) or the seam is `disabled`. Its finding (when the
|
|
110
|
+
* generation lacks the skill) also rides `findings`. Additive. */
|
|
111
|
+
baseSkill: BaseSkillPosture | null;
|
|
105
112
|
}
|
|
106
113
|
/** The `skills` block a daemon booted WITHOUT the seam reports. */
|
|
107
114
|
export declare function disabledSkillsHealth(): SkillsHealth;
|
|
@@ -122,13 +129,48 @@ export declare class SkillsRuntime {
|
|
|
122
129
|
private readonly log;
|
|
123
130
|
private readonly bootSnapshot;
|
|
124
131
|
private lastHealth;
|
|
132
|
+
/** The base skill setting (crew#554) — `null` until `configureBaseSkill` runs (boot reads settings.json first). */
|
|
133
|
+
private baseSkillConfig;
|
|
134
|
+
private lastBaseSkill;
|
|
135
|
+
/** The last `skills.base-skill` message logged — the seam says a finding once per change, not per re-export. */
|
|
136
|
+
private lastBaseSkillLogged;
|
|
125
137
|
constructor(opts: SkillsRuntimeOptions);
|
|
138
|
+
/**
|
|
139
|
+
* Take the base skill setting (crew#554 — `SystemSettings.baseSkillRef` / `baseSkillPolicy`) and
|
|
140
|
+
* apply it NOW: at boot (before `apply`, so the ladder's outcome re-judges it) and on every
|
|
141
|
+
* `PUT /settings` that changes it. `baseSkillRef: ""` (or blank) is OFF — the engine variable is
|
|
142
|
+
* deleted. Answers the posture applied.
|
|
143
|
+
*/
|
|
144
|
+
configureBaseSkill(settings: {
|
|
145
|
+
baseSkillRef?: string | undefined;
|
|
146
|
+
baseSkillPolicy?: BaseSkillPolicy | undefined;
|
|
147
|
+
}): BaseSkillPosture | null;
|
|
148
|
+
/** The base skill posture the engine is handed right now — `null` when off or unconfigured. */
|
|
149
|
+
baseSkill(): BaseSkillPosture | null;
|
|
150
|
+
/**
|
|
151
|
+
* Re-judge the base skill against the CURRENT published generation and the editor catalog, and
|
|
152
|
+
* export (or delete) `WICKED_BASE_SKILL_REF` accordingly (base-skill.ts). Called by every ladder
|
|
153
|
+
* outcome (`record`), after every publish, after a baseline refresh (the catalog moved, so
|
|
154
|
+
* `inCatalog` did) and on a settings change. Never throws: a generation whose metadata will not
|
|
155
|
+
* re-read counts as "nothing known to be handed" — under `warn` that unsets the variable and
|
|
156
|
+
* warns; under `require` the engine refuses at intake, which is the policy's whole point.
|
|
157
|
+
*/
|
|
158
|
+
refreshBaseSkill(): BaseSkillPosture | null;
|
|
126
159
|
/**
|
|
127
160
|
* The seam's last outcome (diagnostics) — plus the live `skills.source` warning when the current
|
|
128
161
|
* baseline is the installer copy (design v3.6). Only a seeded root (`published` / `blocked`) has a
|
|
129
162
|
* current baseline to judge; the other rungs have no manifest, or one their own finding condemns.
|
|
130
163
|
*/
|
|
164
|
+
/**
|
|
165
|
+
* Does the PUBLISHED snapshot the engine is handed hold (and enable) skill `name`? The interactive
|
|
166
|
+
* seams gate their `skill_ref` on this (interactive/draft-skill.ts): the engine refuses a run whose
|
|
167
|
+
* `skill_ref` the snapshot lacks, so a seam must know before it stamps. `false` on every non-published
|
|
168
|
+
* state (fallback, blocked, config-error, disabled) and on an unreadable manifest — never a guess.
|
|
169
|
+
*/
|
|
170
|
+
holdsSkill(name: string): boolean;
|
|
131
171
|
health(): SkillsHealth;
|
|
172
|
+
/** The reported block carries the base skill posture and its finding (crew#554) — the seam's one answer to "is the discipline skill handed". */
|
|
173
|
+
private withBaseSkill;
|
|
132
174
|
/** Boot entry point. Never throws; never fails open (module header). Idempotent: a seeded, published root is only re-verified. */
|
|
133
175
|
apply(): Promise<SkillsHealth>;
|
|
134
176
|
/** Say once, at boot, that the current baseline is the installer copy (design v3.6) — the finding itself persists in `health()`. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/skills/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwEG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,SAAS,EAAiB,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/skills/runtime.ts"],"names":[],"mappings":"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"}
|
package/dist/skills/runtime.js
CHANGED
|
@@ -73,6 +73,7 @@
|
|
|
73
73
|
*/
|
|
74
74
|
import { join } from 'node:path';
|
|
75
75
|
import { applySkillsSnapshotEnv, BOOT_SKILLS_SNAPSHOT, canonicalCrewStateHome, SKILLS_SNAPSHOT_ENGINE_ENV } from './engine-env.js';
|
|
76
|
+
import { applyBaseSkillEnv, BASE_SKILL_REF_ENGINE_ENV, baseSkillPosture, normalizeBaseSkillRef } from './base-skill.js';
|
|
76
77
|
import { SKILLS_SOURCE_ENV } from './plugin-source.js';
|
|
77
78
|
import { REFUSED_DIRNAME } from './root-names.js';
|
|
78
79
|
import { SkillsSourceUnavailableError } from './store.js';
|
|
@@ -159,7 +160,7 @@ function staleRulesFinding(current, rederived) {
|
|
|
159
160
|
export { REFUSED_DIRNAME };
|
|
160
161
|
/** The `skills` block a daemon booted WITHOUT the seam reports. */
|
|
161
162
|
export function disabledSkillsHealth() {
|
|
162
|
-
return { state: 'disabled', root: null, current: null, engineInput: null, stateHome: null, findings: [] };
|
|
163
|
+
return { state: 'disabled', root: null, current: null, engineInput: null, stateHome: null, findings: [], baseSkill: null };
|
|
163
164
|
}
|
|
164
165
|
/**
|
|
165
166
|
* The path the engine input is pointed at when the daemon has NO valid snapshot to offer and must
|
|
@@ -174,20 +175,107 @@ export class SkillsRuntime {
|
|
|
174
175
|
log;
|
|
175
176
|
bootSnapshot;
|
|
176
177
|
lastHealth = disabledSkillsHealth();
|
|
178
|
+
/** The base skill setting (crew#554) — `null` until `configureBaseSkill` runs (boot reads settings.json first). */
|
|
179
|
+
baseSkillConfig = null;
|
|
180
|
+
lastBaseSkill = null;
|
|
181
|
+
/** The last `skills.base-skill` message logged — the seam says a finding once per change, not per re-export. */
|
|
182
|
+
lastBaseSkillLogged = null;
|
|
177
183
|
constructor(opts) {
|
|
178
184
|
this.store = opts.store;
|
|
179
185
|
this.log = opts.log;
|
|
180
186
|
this.bootSnapshot = 'bootSnapshot' in opts ? opts.bootSnapshot : BOOT_SKILLS_SNAPSHOT;
|
|
181
187
|
}
|
|
188
|
+
/**
|
|
189
|
+
* Take the base skill setting (crew#554 — `SystemSettings.baseSkillRef` / `baseSkillPolicy`) and
|
|
190
|
+
* apply it NOW: at boot (before `apply`, so the ladder's outcome re-judges it) and on every
|
|
191
|
+
* `PUT /settings` that changes it. `baseSkillRef: ""` (or blank) is OFF — the engine variable is
|
|
192
|
+
* deleted. Answers the posture applied.
|
|
193
|
+
*/
|
|
194
|
+
configureBaseSkill(settings) {
|
|
195
|
+
this.baseSkillConfig = { ref: normalizeBaseSkillRef(settings.baseSkillRef), policy: settings.baseSkillPolicy ?? 'warn' };
|
|
196
|
+
return this.refreshBaseSkill();
|
|
197
|
+
}
|
|
198
|
+
/** The base skill posture the engine is handed right now — `null` when off or unconfigured. */
|
|
199
|
+
baseSkill() {
|
|
200
|
+
return this.lastBaseSkill;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Re-judge the base skill against the CURRENT published generation and the editor catalog, and
|
|
204
|
+
* export (or delete) `WICKED_BASE_SKILL_REF` accordingly (base-skill.ts). Called by every ladder
|
|
205
|
+
* outcome (`record`), after every publish, after a baseline refresh (the catalog moved, so
|
|
206
|
+
* `inCatalog` did) and on a settings change. Never throws: a generation whose metadata will not
|
|
207
|
+
* re-read counts as "nothing known to be handed" — under `warn` that unsets the variable and
|
|
208
|
+
* warns; under `require` the engine refuses at intake, which is the policy's whole point.
|
|
209
|
+
*/
|
|
210
|
+
refreshBaseSkill() {
|
|
211
|
+
const config = this.baseSkillConfig;
|
|
212
|
+
if (config === null)
|
|
213
|
+
return null;
|
|
214
|
+
let published = null;
|
|
215
|
+
if (this.lastHealth.state === 'published') {
|
|
216
|
+
try {
|
|
217
|
+
published = this.store.currentSnapshotSkills();
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
published = null;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
const inCatalog = (name) => {
|
|
224
|
+
try {
|
|
225
|
+
const entry = this.store.manifest().skills[name];
|
|
226
|
+
return entry !== undefined && entry.enabled;
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
const posture = baseSkillPosture(config, published, inCatalog);
|
|
233
|
+
applyBaseSkillEnv(posture);
|
|
234
|
+
this.lastBaseSkill = posture;
|
|
235
|
+
const message = posture?.finding?.message ?? null;
|
|
236
|
+
// Say it once per CHANGE, and only once the ladder has run: before `apply` the seam is
|
|
237
|
+
// `disabled` by construction, so a boot-order judgement ("no published snapshot") would log a
|
|
238
|
+
// warning the first ladder outcome contradicts a moment later. The variable is still applied.
|
|
239
|
+
const settled = this.lastHealth.state !== 'disabled';
|
|
240
|
+
if (settled && message !== this.lastBaseSkillLogged) {
|
|
241
|
+
if (message !== null) {
|
|
242
|
+
this.log(`[skills] skills.base-skill: ${message} (${BASE_SKILL_REF_ENGINE_ENV} ${posture?.engineInput === null ? 'unset' : `= ${posture?.engineInput}`})`);
|
|
243
|
+
}
|
|
244
|
+
else if (this.lastBaseSkillLogged !== null && posture !== null) {
|
|
245
|
+
this.log(`[skills] skills.base-skill: cleared — "${posture.name}" is handed from generation ${posture.gen ?? '?'} (${BASE_SKILL_REF_ENGINE_ENV} = ${posture.name})`);
|
|
246
|
+
}
|
|
247
|
+
this.lastBaseSkillLogged = message;
|
|
248
|
+
}
|
|
249
|
+
return posture;
|
|
250
|
+
}
|
|
182
251
|
/**
|
|
183
252
|
* The seam's last outcome (diagnostics) — plus the live `skills.source` warning when the current
|
|
184
253
|
* baseline is the installer copy (design v3.6). Only a seeded root (`published` / `blocked`) has a
|
|
185
254
|
* current baseline to judge; the other rungs have no manifest, or one their own finding condemns.
|
|
186
255
|
*/
|
|
256
|
+
/**
|
|
257
|
+
* Does the PUBLISHED snapshot the engine is handed hold (and enable) skill `name`? The interactive
|
|
258
|
+
* seams gate their `skill_ref` on this (interactive/draft-skill.ts): the engine refuses a run whose
|
|
259
|
+
* `skill_ref` the snapshot lacks, so a seam must know before it stamps. `false` on every non-published
|
|
260
|
+
* state (fallback, blocked, config-error, disabled) and on an unreadable manifest — never a guess.
|
|
261
|
+
*/
|
|
262
|
+
holdsSkill(name) {
|
|
263
|
+
if (this.lastHealth.state !== 'published')
|
|
264
|
+
return false;
|
|
265
|
+
try {
|
|
266
|
+
const entry = this.store.manifest().skills[name];
|
|
267
|
+
return entry !== undefined && entry.enabled;
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
187
273
|
health() {
|
|
188
274
|
const base = this.lastHealth;
|
|
275
|
+
// The base skill posture rides EVERY state (crew#554): under fallback / config-error nothing is
|
|
276
|
+
// known to be handed, which is exactly what the operator must see beside the ladder's finding.
|
|
189
277
|
if (base.state !== 'published' && base.state !== 'blocked')
|
|
190
|
-
return base;
|
|
278
|
+
return this.withBaseSkill(base);
|
|
191
279
|
let manifest;
|
|
192
280
|
try {
|
|
193
281
|
manifest = this.store.manifest();
|
|
@@ -198,7 +286,7 @@ export class SkillsRuntime {
|
|
|
198
286
|
// never touches the engine input: whatever is exported stays exported until a restart re-runs
|
|
199
287
|
// the ladder, and the finding says so.
|
|
200
288
|
const cause = err instanceof Error ? err.message : String(err);
|
|
201
|
-
return {
|
|
289
|
+
return this.withBaseSkill({
|
|
202
290
|
state: 'config-error',
|
|
203
291
|
root: base.root,
|
|
204
292
|
current: null,
|
|
@@ -211,10 +299,17 @@ export class SkillsRuntime {
|
|
|
211
299
|
message: `manifest.json cannot be read: ${cause} — the skills store is unusable (every /skills request fails) until it is fixed; ${SKILLS_SNAPSHOT_ENGINE_ENV} still exports what the last boot or publish set (${base.engineInput ?? 'unset'}) until the daemon restarts`,
|
|
212
300
|
},
|
|
213
301
|
],
|
|
214
|
-
|
|
302
|
+
baseSkill: null,
|
|
303
|
+
});
|
|
215
304
|
}
|
|
216
305
|
const source = sourceFinding(manifest);
|
|
217
|
-
return source === null ? base : { ...base, findings: [...base.findings, source] };
|
|
306
|
+
return this.withBaseSkill(source === null ? base : { ...base, findings: [...base.findings, source] });
|
|
307
|
+
}
|
|
308
|
+
/** The reported block carries the base skill posture and its finding (crew#554) — the seam's one answer to "is the discipline skill handed". */
|
|
309
|
+
withBaseSkill(health) {
|
|
310
|
+
const posture = this.lastBaseSkill;
|
|
311
|
+
const findings = posture?.finding === null || posture?.finding === undefined ? health.findings : [...health.findings, posture.finding];
|
|
312
|
+
return { ...health, findings, baseSkill: posture };
|
|
218
313
|
}
|
|
219
314
|
/** Boot entry point. Never throws; never fails open (module header). Idempotent: a seeded, published root is only re-verified. */
|
|
220
315
|
async apply() {
|
|
@@ -243,6 +338,7 @@ export class SkillsRuntime {
|
|
|
243
338
|
engineInput: '',
|
|
244
339
|
stateHome: canonicalCrewStateHome(),
|
|
245
340
|
findings: [{ kind: 'skills.config', severity: 'error', message: detail }],
|
|
341
|
+
baseSkill: null,
|
|
246
342
|
});
|
|
247
343
|
}
|
|
248
344
|
this.log(restored === undefined
|
|
@@ -255,6 +351,7 @@ export class SkillsRuntime {
|
|
|
255
351
|
engineInput: restored ?? null,
|
|
256
352
|
stateHome: canonicalCrewStateHome(),
|
|
257
353
|
findings: [{ kind: 'skills.fallback', severity: 'warning', message }],
|
|
354
|
+
baseSkill: null,
|
|
258
355
|
});
|
|
259
356
|
}
|
|
260
357
|
const refusal = refusalPath(root, 'skills.config');
|
|
@@ -267,6 +364,7 @@ export class SkillsRuntime {
|
|
|
267
364
|
engineInput: refusal,
|
|
268
365
|
stateHome: canonicalCrewStateHome(),
|
|
269
366
|
findings: [{ kind: 'skills.config', severity: 'error', message }],
|
|
367
|
+
baseSkill: null,
|
|
270
368
|
});
|
|
271
369
|
}
|
|
272
370
|
if (ready.seeded)
|
|
@@ -288,6 +386,7 @@ export class SkillsRuntime {
|
|
|
288
386
|
engineInput: refusal,
|
|
289
387
|
stateHome: canonicalCrewStateHome(),
|
|
290
388
|
findings: [{ kind: 'skills.blocked', severity: 'error', message }],
|
|
389
|
+
baseSkill: null,
|
|
291
390
|
});
|
|
292
391
|
this.logSourceWarning(blocked);
|
|
293
392
|
return blocked;
|
|
@@ -354,10 +453,12 @@ export class SkillsRuntime {
|
|
|
354
453
|
engineInput: refusal,
|
|
355
454
|
stateHome: canonicalCrewStateHome(),
|
|
356
455
|
findings: [{ kind: 'skills.config', severity: 'error', message }],
|
|
456
|
+
baseSkill: null,
|
|
357
457
|
});
|
|
358
458
|
}
|
|
359
459
|
if (current === null) {
|
|
360
460
|
this.store.live.exported(null);
|
|
461
|
+
this.refreshBaseSkill();
|
|
361
462
|
return null;
|
|
362
463
|
}
|
|
363
464
|
applySkillsSnapshotEnv(current.path);
|
|
@@ -396,11 +497,15 @@ export class SkillsRuntime {
|
|
|
396
497
|
engineInput: current.path,
|
|
397
498
|
stateHome: canonicalCrewStateHome(),
|
|
398
499
|
findings: stale === null ? [] : [stale],
|
|
500
|
+
baseSkill: null,
|
|
399
501
|
});
|
|
400
502
|
}
|
|
401
503
|
/** Store the ladder's outcome; answer it as `health()` reports it (the live `skills.source` warning included). */
|
|
402
504
|
record(health) {
|
|
403
505
|
this.lastHealth = health;
|
|
506
|
+
// The base skill is judged against THIS outcome (crew#554): a generation just published (or
|
|
507
|
+
// refused) changes what the engine is handed, so the variable follows the ladder every time.
|
|
508
|
+
this.refreshBaseSkill();
|
|
404
509
|
return this.health();
|
|
405
510
|
}
|
|
406
511
|
}
|