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.
Files changed (112) hide show
  1. package/README.md +2 -1
  2. package/dist/api/chat-turns.d.ts +87 -0
  3. package/dist/api/chat-turns.d.ts.map +1 -0
  4. package/dist/api/chat-turns.js +147 -0
  5. package/dist/api/chat-turns.js.map +1 -0
  6. package/dist/api/eval-sample.d.ts +18 -18
  7. package/dist/api/governance-steering.d.ts +4 -4
  8. package/dist/api/roster-standing.d.ts +42 -0
  9. package/dist/api/roster-standing.d.ts.map +1 -0
  10. package/dist/api/roster-standing.js +54 -0
  11. package/dist/api/roster-standing.js.map +1 -0
  12. package/dist/api/routes.d.ts +61 -3
  13. package/dist/api/routes.d.ts.map +1 -1
  14. package/dist/api/routes.js +171 -42
  15. package/dist/api/routes.js.map +1 -1
  16. package/dist/api/server.d.ts.map +1 -1
  17. package/dist/api/server.js +89 -1
  18. package/dist/api/server.js.map +1 -1
  19. package/dist/api/skills.d.ts.map +1 -1
  20. package/dist/api/skills.js +12 -3
  21. package/dist/api/skills.js.map +1 -1
  22. package/dist/api/testing.d.ts +4 -4
  23. package/dist/campaigns/routes.d.ts +14 -14
  24. package/dist/cli/index.js +23 -3
  25. package/dist/cli/index.js.map +1 -1
  26. package/dist/core/adapter.d.ts +30 -0
  27. package/dist/core/adapter.d.ts.map +1 -1
  28. package/dist/core/adapter.js +66 -2
  29. package/dist/core/adapter.js.map +1 -1
  30. package/dist/core/engine-roster.d.ts +28 -0
  31. package/dist/core/engine-roster.d.ts.map +1 -1
  32. package/dist/core/engine-roster.js +28 -0
  33. package/dist/core/engine-roster.js.map +1 -1
  34. package/dist/core/types.d.ts +9 -0
  35. package/dist/core/types.d.ts.map +1 -1
  36. package/dist/core/types.js +6 -0
  37. package/dist/core/types.js.map +1 -1
  38. package/dist/interactive/bridge-pool.d.ts +2 -2
  39. package/dist/interactive/bridge-pool.d.ts.map +1 -1
  40. package/dist/interactive/bridge-pool.js +19 -4
  41. package/dist/interactive/bridge-pool.js.map +1 -1
  42. package/dist/interactive/bus-subscriber-errors.d.ts +61 -0
  43. package/dist/interactive/bus-subscriber-errors.d.ts.map +1 -0
  44. package/dist/interactive/bus-subscriber-errors.js +85 -0
  45. package/dist/interactive/bus-subscriber-errors.js.map +1 -0
  46. package/dist/interactive/chat-events.d.ts +16 -0
  47. package/dist/interactive/chat-events.d.ts.map +1 -1
  48. package/dist/interactive/chat-events.js +59 -10
  49. package/dist/interactive/chat-events.js.map +1 -1
  50. package/dist/interactive/demo-events.d.ts +66 -0
  51. package/dist/interactive/demo-events.d.ts.map +1 -1
  52. package/dist/interactive/demo-events.js +154 -10
  53. package/dist/interactive/demo-events.js.map +1 -1
  54. package/dist/interactive/doc-delete-routes.js +2 -2
  55. package/dist/interactive/doc-delete-routes.js.map +1 -1
  56. package/dist/interactive/draft-events.d.ts +13 -0
  57. package/dist/interactive/draft-events.d.ts.map +1 -1
  58. package/dist/interactive/draft-events.js +34 -9
  59. package/dist/interactive/draft-events.js.map +1 -1
  60. package/dist/interactive/draft-skill.d.ts +68 -0
  61. package/dist/interactive/draft-skill.d.ts.map +1 -0
  62. package/dist/interactive/draft-skill.js +127 -0
  63. package/dist/interactive/draft-skill.js.map +1 -0
  64. package/dist/interactive/edit-events.d.ts +13 -0
  65. package/dist/interactive/edit-events.d.ts.map +1 -1
  66. package/dist/interactive/edit-events.js +35 -9
  67. package/dist/interactive/edit-events.js.map +1 -1
  68. package/dist/interactive/proxy-routes.d.ts +36 -0
  69. package/dist/interactive/proxy-routes.d.ts.map +1 -1
  70. package/dist/interactive/proxy-routes.js +90 -3
  71. package/dist/interactive/proxy-routes.js.map +1 -1
  72. package/dist/interactive/ws-relay.d.ts +2 -0
  73. package/dist/interactive/ws-relay.d.ts.map +1 -1
  74. package/dist/interactive/ws-relay.js +7 -3
  75. package/dist/interactive/ws-relay.js.map +1 -1
  76. package/dist/projects/activity.d.ts +17 -3
  77. package/dist/projects/activity.d.ts.map +1 -1
  78. package/dist/projects/activity.js +34 -13
  79. package/dist/projects/activity.js.map +1 -1
  80. package/dist/projects/events.d.ts +2 -0
  81. package/dist/projects/events.d.ts.map +1 -1
  82. package/dist/projects/events.js +7 -3
  83. package/dist/projects/events.js.map +1 -1
  84. package/dist/projects/state-home-preflight.d.ts +163 -0
  85. package/dist/projects/state-home-preflight.d.ts.map +1 -0
  86. package/dist/projects/state-home-preflight.js +310 -0
  87. package/dist/projects/state-home-preflight.js.map +1 -0
  88. package/dist/projects/state-home-registry.d.ts +25 -0
  89. package/dist/projects/state-home-registry.d.ts.map +1 -0
  90. package/dist/projects/state-home-registry.js +50 -0
  91. package/dist/projects/state-home-registry.js.map +1 -0
  92. package/dist/qe/gate-events.d.ts +2 -0
  93. package/dist/qe/gate-events.d.ts.map +1 -1
  94. package/dist/qe/gate-events.js +7 -3
  95. package/dist/qe/gate-events.js.map +1 -1
  96. package/dist/skills/base-skill.d.ts +92 -0
  97. package/dist/skills/base-skill.d.ts.map +1 -0
  98. package/dist/skills/base-skill.js +105 -0
  99. package/dist/skills/base-skill.js.map +1 -0
  100. package/dist/skills/runtime.d.ts +43 -1
  101. package/dist/skills/runtime.d.ts.map +1 -1
  102. package/dist/skills/runtime.js +110 -5
  103. package/dist/skills/runtime.js.map +1 -1
  104. package/dist/skills/store.d.ts +11 -0
  105. package/dist/skills/store.d.ts.map +1 -1
  106. package/dist/skills/store.js +16 -0
  107. package/dist/skills/store.js.map +1 -1
  108. package/dist/studio/assets/{index-Clm0MXDF.js → index-DhojBZ1T.js} +91 -91
  109. package/dist/studio/index.html +1 -1
  110. package/dist/studio/testid-inventory.json +51 -3
  111. package/endpoint-manifest.json +2 -1
  112. 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"}
@@ -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;AAIH,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;CACjC;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,CAiDpC"}
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"}
@@ -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: (err, event) => {
161
- log(`[qe-gate-events] handler error on event ${String(event?.event_id ?? '?')}: ${err.message}`);
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":"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"}
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":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAIH,+FAA+F;AAC/F,MAAM,CAAC,MAAM,yBAAyB,GAAG,uBAAuB,CAAC;AAEjE,iGAAiG;AACjG,MAAM,CAAC,MAAM,sBAAsB,GAAG,+BAA+B,CAAC;AAItE,MAAM,CAAC,MAAM,mBAAmB,GAAwB,IAAI,GAAG,CAAkB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;AAEtG;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,oCAAoC,CAAC;AAmCzE,+DAA+D;AAC/D,MAAM,UAAU,qBAAqB,CAAC,GAAuB;IAC3D,OAAO,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACnD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAC9B,MAAuB,EACvB,SAAiC,EACjC,SAAoC;IAEpC,MAAM,IAAI,GAAG,qBAAqB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC/C,IAAI,IAAI,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAC7B,MAAM,OAAO,GAAG,SAAS,KAAK,IAAI,IAAI,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACtE,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAChC,MAAM,GAAG,GAAG,SAAS,EAAE,GAAG,IAAI,IAAI,CAAC;IACnC,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACzE,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;IACnF,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;AACjG,CAAC;AAED,SAAS,cAAc,CAAC,IAAY,EAAE,MAAuB,EAAE,GAAkB,EAAE,SAAkB;IACnG,MAAM,KAAK,GAAG,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,+CAA+C,CAAC,CAAC,CAAC,+BAA+B,GAAG,oBAAoB,CAAC;IACtI,MAAM,MAAM,GAAG,SAAS;QACtB,CAAC,CAAC,yEAAyE;QAC3E,CAAC,CAAC,iGAAiG,CAAC;IACtG,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO;YACL,IAAI,EAAE,mBAAmB;YACzB,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,mBAAmB,IAAI,4FAA4F,KAAK,4FAA4F,MAAM,mFAAmF;SACvT,CAAC;IACJ,CAAC;IACD,OAAO;QACL,IAAI,EAAE,mBAAmB;QACzB,QAAQ,EAAE,SAAS;QACnB,OAAO,EAAE,mBAAmB,IAAI,2FAA2F,KAAK,wDAAwD,MAAM,uEAAuE;KACtQ,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAgC;IAChE,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,CAAC,WAAW,KAAK,IAAI,EAAE,CAAC;QACrD,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;IAC/D,CAAC;SAAM,CAAC;QACN,OAAO,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IAChD,CAAC;AACH,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,iBAAiB,CAAC,OAAgC;IAChE,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,uBAAuB,CAAC;IACrD,IAAI,OAAO,CAAC,OAAO;QAAE,OAAO,qBAAqB,OAAO,CAAC,IAAI,QAAQ,OAAO,CAAC,GAAG,IAAI,GAAG,EAAE,CAAC;IAC1F,OAAO,OAAO,CAAC,MAAM,KAAK,SAAS;QACjC,CAAC,CAAC,qBAAqB,OAAO,CAAC,IAAI,2CAA2C;QAC9E,CAAC,CAAC,qBAAqB,OAAO,CAAC,IAAI,oCAAoC,CAAC;AAC5E,CAAC"}
@@ -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
- export type SkillsHealthFindingKind = 'skills.fallback' | 'skills.blocked' | 'skills.config' | 'skills.source' | 'skills.manifest' | 'skills.stale-rules';
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;AAGjE,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAsD,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAuFlG,0HAA0H;AAC1H,OAAO,EAAE,eAAe,EAAE,CAAC;AAE3B,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,UAAU,GAAG,SAAS,GAAG,cAAc,GAAG,UAAU,CAAC;AAEnG,oKAAoK;AACpK,MAAM,MAAM,uBAAuB,GAAG,iBAAiB,GAAG,gBAAgB,GAAG,eAAe,GAAG,eAAe,GAAG,iBAAiB,GAAG,oBAAoB,CAAC;AAE1J,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,uBAAuB,CAAC;IAC9B,QAAQ,EAAE,SAAS,GAAG,OAAO,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,6EAA6E;AAC7E,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,iBAAiB,CAAC;IACzB,kGAAkG;IAClG,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,kDAAkD;IAClD,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC9C,4FAA4F;IAC5F,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B;;kCAE8B;IAC9B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;CACjC;AAED,mEAAmE;AACnE,wBAAgB,oBAAoB,IAAI,YAAY,CAEnD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG,eAAe,GAAG,MAAM,CAE1F;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,WAAW,CAAC;IACnB,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,8IAA8I;IAC9I,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AAED,qBAAa,aAAa;IACxB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA4B;IAChD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;IAClD,OAAO,CAAC,UAAU,CAAwC;gBAE9C,IAAI,EAAE,oBAAoB;IAMtC;;;;OAIG;IACH,MAAM,IAAI,YAAY;IA+BtB,kIAAkI;IAC5H,KAAK,IAAI,OAAO,CAAC,YAAY,CAAC;IAwFpC,oIAAoI;IACpI,OAAO,CAAC,gBAAgB;IAKxB;;;;OAIG;IACH,OAAO,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAI/B;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAKpC;;;;OAIG;IACH,YAAY,IAAI,YAAY,GAAG,IAAI;IA2DnC,kHAAkH;IAClH,OAAO,CAAC,MAAM;CAIf"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/skills/runtime.ts"],"names":[],"mappings":"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"}
@@ -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
  }