@cleocode/contracts 2026.6.11 → 2026.6.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/operation-def.test.js +2 -1
- package/dist/__tests__/operation-def.test.js.map +1 -1
- package/dist/__tests__/sealed-credential.test.d.ts +19 -0
- package/dist/__tests__/sealed-credential.test.d.ts.map +1 -0
- package/dist/__tests__/sealed-credential.test.js +74 -0
- package/dist/__tests__/sealed-credential.test.js.map +1 -0
- package/dist/__tests__/skill-executor-contract.test.js +3 -0
- package/dist/__tests__/skill-executor-contract.test.js.map +1 -1
- package/dist/acceptance-gate.d.ts +2 -3
- package/dist/acceptance-gate.d.ts.map +1 -1
- package/dist/boundary.d.ts.map +1 -1
- package/dist/boundary.js +1 -19
- package/dist/boundary.js.map +1 -1
- package/dist/config.d.ts +102 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/data-accessor.d.ts +21 -1
- package/dist/data-accessor.d.ts.map +1 -1
- package/dist/data-accessor.js.map +1 -1
- package/dist/dispatch/identity.d.ts +1 -1
- package/dist/dispatch/identity.d.ts.map +1 -1
- package/dist/dispatch/identity.js +5 -0
- package/dist/dispatch/identity.js.map +1 -1
- package/dist/dispatch/operations-registry.d.ts.map +1 -1
- package/dist/dispatch/operations-registry.js +46 -168
- package/dist/dispatch/operations-registry.js.map +1 -1
- package/dist/docs/read.d.ts +2 -2
- package/dist/index.d.ts +12 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/lease-ipc/__tests__/freeze.test.d.ts +15 -0
- package/dist/lease-ipc/__tests__/freeze.test.d.ts.map +1 -0
- package/dist/lease-ipc/__tests__/freeze.test.js +221 -0
- package/dist/lease-ipc/__tests__/freeze.test.js.map +1 -0
- package/dist/lease-ipc/index.d.ts +17 -0
- package/dist/lease-ipc/index.d.ts.map +1 -0
- package/dist/lease-ipc/index.js +16 -0
- package/dist/lease-ipc/index.js.map +1 -0
- package/dist/lease-ipc/messages.d.ts +754 -0
- package/dist/lease-ipc/messages.d.ts.map +1 -0
- package/dist/lease-ipc/messages.js +383 -0
- package/dist/lease-ipc/messages.js.map +1 -0
- package/dist/lease-ipc/version.d.ts +41 -0
- package/dist/lease-ipc/version.d.ts.map +1 -0
- package/dist/lease-ipc/version.js +43 -0
- package/dist/lease-ipc/version.js.map +1 -0
- package/dist/llm/interfaces.d.ts +23 -0
- package/dist/llm/interfaces.d.ts.map +1 -1
- package/dist/llm/sealed-credential.d.ts +164 -0
- package/dist/llm/sealed-credential.d.ts.map +1 -0
- package/dist/llm/sealed-credential.js +43 -0
- package/dist/llm/sealed-credential.js.map +1 -0
- package/dist/llm/system-of-use.d.ts +383 -0
- package/dist/llm/system-of-use.d.ts.map +1 -0
- package/dist/llm/system-of-use.js +238 -0
- package/dist/llm/system-of-use.js.map +1 -0
- package/dist/llm/system-resolver.d.ts +45 -11
- package/dist/llm/system-resolver.d.ts.map +1 -1
- package/dist/llm/system-resolver.js +14 -7
- package/dist/llm/system-resolver.js.map +1 -1
- package/dist/operations/__tests__/ensures-schema-registry.test.d.ts +17 -0
- package/dist/operations/__tests__/ensures-schema-registry.test.d.ts.map +1 -0
- package/dist/operations/__tests__/ensures-schema-registry.test.js +113 -0
- package/dist/operations/__tests__/ensures-schema-registry.test.js.map +1 -0
- package/dist/operations/ensures-schema-registry.d.ts +172 -0
- package/dist/operations/ensures-schema-registry.d.ts.map +1 -0
- package/dist/operations/ensures-schema-registry.js +226 -0
- package/dist/operations/ensures-schema-registry.js.map +1 -0
- package/dist/operations/llm.d.ts +101 -9
- package/dist/operations/llm.d.ts.map +1 -1
- package/dist/operations/validate.d.ts +1 -12
- package/dist/operations/validate.d.ts.map +1 -1
- package/dist/operations/validate.js +1 -1
- package/dist/playbook.d.ts +60 -0
- package/dist/playbook.d.ts.map +1 -1
- package/dist/session.d.ts +11 -0
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js.map +1 -1
- package/dist/templates/manifest.d.ts +1 -1
- package/dist/tools/agent-tools.d.ts +231 -0
- package/dist/tools/agent-tools.d.ts.map +1 -0
- package/dist/tools/agent-tools.js +25 -0
- package/dist/tools/agent-tools.js.map +1 -0
- package/dist/tools/atomic.d.ts +19 -0
- package/dist/tools/atomic.d.ts.map +1 -1
- package/dist/tools/atomic.js +17 -0
- package/dist/tools/atomic.js.map +1 -1
- package/dist/tools/index.d.ts +2 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/skill-executor.d.ts +7 -0
- package/dist/tools/skill-executor.d.ts.map +1 -1
- package/dist/tools/web-tools.d.ts +217 -0
- package/dist/tools/web-tools.d.ts.map +1 -0
- package/dist/tools/web-tools.js +31 -0
- package/dist/tools/web-tools.js.map +1 -0
- package/package.json +6 -2
- package/src/__tests__/__snapshots__/operations-registry.test.ts.snap +1 -1
- package/src/__tests__/operation-def.test.ts +2 -1
- package/src/__tests__/sealed-credential.test.ts +100 -0
- package/src/__tests__/skill-executor-contract.test.ts +3 -0
- package/src/acceptance-gate.ts +2 -3
- package/src/boundary.ts +1 -20
- package/src/config.ts +104 -0
- package/src/data-accessor.ts +22 -1
- package/src/dispatch/identity.ts +5 -0
- package/src/dispatch/operations-registry.ts +51 -170
- package/src/index.ts +103 -24
- package/src/lease-ipc/__tests__/freeze.test.ts +246 -0
- package/src/lease-ipc/index.ts +63 -0
- package/src/lease-ipc/messages.ts +471 -0
- package/src/lease-ipc/version.ts +46 -0
- package/src/llm/interfaces.ts +23 -0
- package/src/llm/sealed-credential.ts +166 -0
- package/src/llm/system-of-use.ts +503 -0
- package/src/llm/system-resolver.ts +46 -11
- package/src/operations/__tests__/ensures-schema-registry.test.ts +169 -0
- package/src/operations/ensures-schema-registry.ts +260 -0
- package/src/operations/llm.ts +105 -8
- package/src/operations/validate.ts +1 -14
- package/src/playbook.ts +61 -0
- package/src/session.ts +11 -0
- package/src/tools/agent-tools.ts +270 -0
- package/src/tools/atomic.ts +21 -0
- package/src/tools/index.ts +46 -0
- package/src/tools/skill-executor.ts +7 -0
- package/src/tools/web-tools.ts +247 -0
- package/dist/tessera.d.ts +0 -32
- package/dist/tessera.d.ts.map +0 -1
- package/dist/tessera.js +0 -11
- package/dist/tessera.js.map +0 -1
- package/dist/warp-chain.d.ts +0 -129
- package/dist/warp-chain.d.ts.map +0 -1
- package/dist/warp-chain.js +0 -13
- package/dist/warp-chain.js.map +0 -1
- package/src/tessera.ts +0 -35
- package/src/warp-chain.ts +0 -185
|
@@ -102,7 +102,8 @@ describe('dispatch/operation-def contracts', () => {
|
|
|
102
102
|
expect(CANONICAL_DOMAINS.length).toBeGreaterThan(0);
|
|
103
103
|
// T9954 — snapshot the current count so accidental additions/removals
|
|
104
104
|
// trip this test and force an explicit human review.
|
|
105
|
-
|
|
105
|
+
// T11889-D — +1 for the new 'selfimprove' domain (self-dogfooding loop verb).
|
|
106
|
+
expect(CANONICAL_DOMAINS.length).toBe(24);
|
|
106
107
|
});
|
|
107
108
|
|
|
108
109
|
it('CANONICAL_DOMAINS contains the four sentinel newly-promoted domains', () => {
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type + purity tests for the E10 sealed credential handle (T11752).
|
|
3
|
+
*
|
|
4
|
+
* Pins the {@link SealedCredential} / {@link DecryptedToken} contract so that:
|
|
5
|
+
* - `SealedCredential` is exactly `{ provider, account, fetch }` with
|
|
6
|
+
* `fetch: () => Promise<DecryptedToken>` (AC1).
|
|
7
|
+
* - `ResolvedLLM` carries a sealed-credential-typed field (AC2).
|
|
8
|
+
* - `DecryptedToken` is a *branded* string — a plain `string` is NOT
|
|
9
|
+
* assignable to it, so the secret cannot be silently fabricated and a
|
|
10
|
+
* `DecryptedToken` cannot leak into an arbitrary `string` sink without an
|
|
11
|
+
* explicit `.value` read (the "never serialized" invariant, AC2).
|
|
12
|
+
* - The module is types-only (no runtime export), satisfying contracts
|
|
13
|
+
* purity (Gate 10 · AC3).
|
|
14
|
+
*
|
|
15
|
+
* @task T11752
|
|
16
|
+
* @epic T11746
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { describe, expect, expectTypeOf, it } from 'vitest';
|
|
20
|
+
import type { ProviderId } from '../llm/provider-id.js';
|
|
21
|
+
import type { DecryptedToken, SealedCredential } from '../llm/sealed-credential.js';
|
|
22
|
+
import type { ResolvedLLM } from '../operations/llm.js';
|
|
23
|
+
|
|
24
|
+
describe('SealedCredential shape (AC1)', () => {
|
|
25
|
+
it('is exactly { provider, account, tokenPreview, fetch } — pins the field set', () => {
|
|
26
|
+
expectTypeOf<keyof SealedCredential>().toEqualTypeOf<
|
|
27
|
+
'provider' | 'account' | 'tokenPreview' | 'fetch'
|
|
28
|
+
>();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('provider is a ProviderId', () => {
|
|
32
|
+
expectTypeOf<SealedCredential['provider']>().toEqualTypeOf<ProviderId>();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('account is a plain (loggable) string', () => {
|
|
36
|
+
expectTypeOf<SealedCredential['account']>().toEqualTypeOf<string>();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('tokenPreview is a plain (loggable, non-secret) string (T11754)', () => {
|
|
40
|
+
expectTypeOf<SealedCredential['tokenPreview']>().toEqualTypeOf<string>();
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('fetch resolves to a DecryptedToken (never a bare string)', () => {
|
|
44
|
+
expectTypeOf<SealedCredential['fetch']>().toEqualTypeOf<() => Promise<DecryptedToken>>();
|
|
45
|
+
expectTypeOf<ReturnType<SealedCredential['fetch']>>().resolves.toEqualTypeOf<DecryptedToken>();
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('all fields are readonly (a handle cannot be mutated in place)', () => {
|
|
49
|
+
// Removing `readonly` from any field would make this fail to compile.
|
|
50
|
+
expectTypeOf<SealedCredential>().toEqualTypeOf<{
|
|
51
|
+
readonly provider: ProviderId;
|
|
52
|
+
readonly account: string;
|
|
53
|
+
readonly tokenPreview: string;
|
|
54
|
+
readonly fetch: () => Promise<DecryptedToken>;
|
|
55
|
+
}>();
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
describe('DecryptedToken branding (AC2 — never serialized / never fabricated)', () => {
|
|
60
|
+
it('is NOT assignable from a plain string (nominal brand)', () => {
|
|
61
|
+
// A plain string lacks the phantom `__decryptedToken` brand, so it cannot
|
|
62
|
+
// be passed where a DecryptedToken is required.
|
|
63
|
+
expectTypeOf<string>().not.toMatchTypeOf<DecryptedToken>();
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('is NOT a plain string sink (must read .value explicitly to serialize)', () => {
|
|
67
|
+
expectTypeOf<DecryptedToken>().not.toEqualTypeOf<string>();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('exposes a readonly plaintext .value of type string', () => {
|
|
71
|
+
expectTypeOf<DecryptedToken['value']>().toEqualTypeOf<string>();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('carries the phantom brand marker (compile-time only)', () => {
|
|
75
|
+
expectTypeOf<DecryptedToken['__decryptedToken']>().toEqualTypeOf<'DecryptedToken'>();
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
describe('ResolvedLLM.sealedCredential (AC2 · T11753)', () => {
|
|
80
|
+
it('is the required (non-optional) canonical credential surface', () => {
|
|
81
|
+
// T11753 promotes the field from optional to required: the resolver ALWAYS
|
|
82
|
+
// populates it (a handle when a credential resolved, `null` otherwise).
|
|
83
|
+
expectTypeOf<ResolvedLLM['sealedCredential']>().toEqualTypeOf<SealedCredential | null>();
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('the inline credential metadata carries NO plaintext apiKey (T11753)', () => {
|
|
87
|
+
// The secret-bearing `apiKey` field is structurally removed from the inline
|
|
88
|
+
// credential — the plaintext crosses ONLY through `sealedCredential.fetch()`.
|
|
89
|
+
type Cred = NonNullable<ResolvedLLM['credential']>;
|
|
90
|
+
expectTypeOf<Cred>().not.toHaveProperty('apiKey');
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
describe('contracts purity (AC3) — sealed-credential is types-only', () => {
|
|
95
|
+
it('the module exposes no runtime exports (no decrypt logic in contracts)', async () => {
|
|
96
|
+
const mod = await import('../llm/sealed-credential.js');
|
|
97
|
+
// A pure type module compiles to an empty ESM namespace at runtime.
|
|
98
|
+
expect(Object.keys(mod)).toHaveLength(0);
|
|
99
|
+
});
|
|
100
|
+
});
|
|
@@ -43,6 +43,9 @@ const fakeTools: GuardedToolSurface = {
|
|
|
43
43
|
async executeShell(_input): Promise<ExecuteShellResult> {
|
|
44
44
|
return { stdout: '', stderr: '', code: 0 };
|
|
45
45
|
},
|
|
46
|
+
async executePty(_input) {
|
|
47
|
+
return { stdout: '', stderr: '', code: 0, mode: 'spawn', ptyFellBack: false };
|
|
48
|
+
},
|
|
46
49
|
async runGit(_input): Promise<ExecuteShellResult> {
|
|
47
50
|
return { stdout: '', stderr: '', code: 0 };
|
|
48
51
|
},
|
package/src/acceptance-gate.ts
CHANGED
|
@@ -325,9 +325,8 @@ export type GateResultDetails =
|
|
|
325
325
|
* Persisted to `lifecycle_gate_results` and summarised in
|
|
326
326
|
* `task.verification.gateResults`.
|
|
327
327
|
*
|
|
328
|
-
* NOTE: Named `AcceptanceGateResult` (not `GateResult`)
|
|
329
|
-
*
|
|
330
|
-
* WarpChain LOOM-gate evaluation outcomes.
|
|
328
|
+
* NOTE: Named `AcceptanceGateResult` (not `GateResult`) for historical
|
|
329
|
+
* clarity — it describes acceptance-criterion gate outcomes specifically.
|
|
331
330
|
*/
|
|
332
331
|
export interface AcceptanceGateResult {
|
|
333
332
|
/** Zero-based index in the task's acceptance array. */
|
package/src/boundary.ts
CHANGED
|
@@ -266,25 +266,6 @@ export const BOUNDARY_REGISTRY: readonly BoundaryEntry[] = [
|
|
|
266
266
|
rationale:
|
|
267
267
|
'napi binding shim for cant-core + cant-runtime. Loaded via packages/cant/src/native-loader.ts and packages/core/src/system/dependencies.ts. Internal-only — shipped via per-platform packages/cant-napi-* npm packages, not crates.io. cant-router bindings removed (E8 T11432).',
|
|
268
268
|
},
|
|
269
|
-
{
|
|
270
|
-
module: 'cant-router',
|
|
271
|
-
intent: 'cpu-bound',
|
|
272
|
-
rustCore: 'crates/cant-router',
|
|
273
|
-
canonicalHome: 'cleocode',
|
|
274
|
-
perfBudget: {
|
|
275
|
-
latency_p50_ms: 5,
|
|
276
|
-
latency_p99_ms: 50,
|
|
277
|
-
},
|
|
278
|
-
safetyBudget: {
|
|
279
|
-
panic_unwind: 'forbidden',
|
|
280
|
-
root_escape: 'forbidden',
|
|
281
|
-
},
|
|
282
|
-
amendments: [],
|
|
283
|
-
rationale:
|
|
284
|
-
'Cant Router (984 LOC) — RETIRED from cant-napi dep-set (E8 T11432: zero live TS consumers). ' +
|
|
285
|
-
'Preserved in the workspace for reference; not linked into the published napi binary. ' +
|
|
286
|
-
'publish=false. Relocation/deletion tracked in T11432.',
|
|
287
|
-
},
|
|
288
269
|
{
|
|
289
270
|
module: 'cant-runtime',
|
|
290
271
|
intent: 'cpu-bound',
|
|
@@ -368,7 +349,7 @@ export const BOUNDARY_REGISTRY: readonly BoundaryEntry[] = [
|
|
|
368
349
|
},
|
|
369
350
|
amendments: [],
|
|
370
351
|
rationale:
|
|
371
|
-
'Internal Rust test harness
|
|
352
|
+
'Internal Rust test harness over lafs-core/cleo-conduit-core/cant-core. publish=false intentional — test code never ships.',
|
|
372
353
|
},
|
|
373
354
|
{
|
|
374
355
|
module: 'lafs-core',
|
package/src/config.ts
CHANGED
|
@@ -475,6 +475,29 @@ export interface LlmProfileTuning {
|
|
|
475
475
|
temperature?: number;
|
|
476
476
|
}
|
|
477
477
|
|
|
478
|
+
/**
|
|
479
|
+
* Capability lane a named profile occupies — the hermes "global-base +
|
|
480
|
+
* granular-override" tiering model (E9 · T11745 · T11748).
|
|
481
|
+
*
|
|
482
|
+
* A profile's `tier` is a coarse capability hint a runner can use to pick the
|
|
483
|
+
* right lane for a turn independently of the role/system axis:
|
|
484
|
+
*
|
|
485
|
+
* | Tier | Meaning |
|
|
486
|
+
* |--------------|------------------------------------------------------------------|
|
|
487
|
+
* | `prime` | The flagship reasoning lane — orchestration / hard turns. |
|
|
488
|
+
* | `aux` | The auxiliary lane — cheap background subsystems (the hermes |
|
|
489
|
+
* | | `_AUX_TASKS` default model bucket; see {@link LlmProfileConfig.defaultAuxModel}). |
|
|
490
|
+
* | `background` | The lowest lane — fire-and-forget background work (titles, etc.). |
|
|
491
|
+
*
|
|
492
|
+
* Advisory metadata only: it does NOT alter the provider/model resolution
|
|
493
|
+
* chain in {@link LlmConfig} — it lets callers and diagnostics reason about
|
|
494
|
+
* which lane a profile belongs to without re-deriving it from the model id.
|
|
495
|
+
*
|
|
496
|
+
* @task T11748
|
|
497
|
+
* @epic T11745
|
|
498
|
+
*/
|
|
499
|
+
export type LlmProfileTier = 'prime' | 'aux' | 'background';
|
|
500
|
+
|
|
478
501
|
/**
|
|
479
502
|
* A named, reusable LLM profile.
|
|
480
503
|
*
|
|
@@ -503,6 +526,67 @@ export interface LlmProfileConfig {
|
|
|
503
526
|
credentialLabel?: string;
|
|
504
527
|
/** Optional tuning parameters (max tokens, temperature). */
|
|
505
528
|
params?: LlmProfileTuning;
|
|
529
|
+
/**
|
|
530
|
+
* Optional capability lane this profile occupies (see {@link LlmProfileTier}).
|
|
531
|
+
*
|
|
532
|
+
* Advisory metadata only — does NOT participate in provider/model resolution.
|
|
533
|
+
* Lets callers/diagnostics reason about a profile's lane (prime/aux/background)
|
|
534
|
+
* without re-deriving it from the model id. The hermes tiering model.
|
|
535
|
+
*
|
|
536
|
+
* @task T11748
|
|
537
|
+
*/
|
|
538
|
+
tier?: LlmProfileTier;
|
|
539
|
+
/**
|
|
540
|
+
* Optional default auxiliary model for this profile — the hermes
|
|
541
|
+
* `auxiliary.defaultModel` analog (E9 · T11748).
|
|
542
|
+
*
|
|
543
|
+
* When this profile is a `prime`/global-base binding, `defaultAuxModel` names
|
|
544
|
+
* the cheaper model an aux-tier subsystem should use instead of {@link model}
|
|
545
|
+
* when it has no more-specific binding. Advisory metadata; consumers that want
|
|
546
|
+
* an aux-tier model read this rather than re-selecting a profile.
|
|
547
|
+
*
|
|
548
|
+
* @task T11748
|
|
549
|
+
*/
|
|
550
|
+
defaultAuxModel?: string;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* A per-system LLM binding — the granular override half of the hermes
|
|
555
|
+
* "global-base + granular-override" model (E9 · T11745 · T11748).
|
|
556
|
+
*
|
|
557
|
+
* A {@link LlmConfig.systems} entry pins the provider/model (or a named
|
|
558
|
+
* {@link LlmProfileConfig}) for ONE encoded system-of-use key (e.g.
|
|
559
|
+
* `'sentient'`, `'tool:web-search'`, `'skill:ct-cleo'`). It is consulted in the
|
|
560
|
+
* resolution chain AFTER an explicit role/argument override but BEFORE the
|
|
561
|
+
* global {@link LlmConfig.defaultProfile} — giving each subsystem a targeted
|
|
562
|
+
* override without touching the global base.
|
|
563
|
+
*
|
|
564
|
+
* Either `profile` (a key of {@link LlmConfig.profiles}) OR an inline
|
|
565
|
+
* `provider` + `model` tuple supplies the binding; `profile` wins when both are
|
|
566
|
+
* present. An entry that supplies neither a resolvable `profile` nor a complete
|
|
567
|
+
* `provider`+`model` tuple is structurally incomplete and is skipped (resolution
|
|
568
|
+
* falls through to the next tier) — never an error.
|
|
569
|
+
*
|
|
570
|
+
* @task T11748
|
|
571
|
+
* @epic T11745
|
|
572
|
+
*/
|
|
573
|
+
export interface SystemBinding {
|
|
574
|
+
/**
|
|
575
|
+
* Optional reference to a named profile in {@link LlmConfig.profiles}. When
|
|
576
|
+
* set and resolvable, the named profile's provider/model/credentialLabel win
|
|
577
|
+
* over this entry's inline `provider`/`model`.
|
|
578
|
+
*/
|
|
579
|
+
profile?: string;
|
|
580
|
+
/** Inline LLM provider transport for this system (used when `profile` absent). */
|
|
581
|
+
provider?: LlmProviderTransport;
|
|
582
|
+
/** Inline full model identifier for this system (used when `profile` absent). */
|
|
583
|
+
model?: string;
|
|
584
|
+
/**
|
|
585
|
+
* Optional credential label pinning this system to a specific credential pool
|
|
586
|
+
* entry. When omitted, the standard priority-based credential resolution
|
|
587
|
+
* applies (or the resolved profile's `credentialLabel`).
|
|
588
|
+
*/
|
|
589
|
+
credentialLabel?: string;
|
|
506
590
|
}
|
|
507
591
|
|
|
508
592
|
/**
|
|
@@ -559,6 +643,26 @@ export interface LlmConfig {
|
|
|
559
643
|
* @task T11617
|
|
560
644
|
*/
|
|
561
645
|
defaultProfile?: string;
|
|
646
|
+
/**
|
|
647
|
+
* Per-system-of-use LLM overrides — the granular-override half of the hermes
|
|
648
|
+
* "global-base + granular-override" model (E9 · T11745 · T11748).
|
|
649
|
+
*
|
|
650
|
+
* Keyed by an encoded system-of-use key: a flat role-mapped label
|
|
651
|
+
* (`'sentient'`, `'memory'`, …) or an open-axis key
|
|
652
|
+
* (`'tool:<name>'` / `'skill:<name>'` / `'cantbook:<node>'` /
|
|
653
|
+
* `'spawn-unit:<id>'`). Each value is a {@link SystemBinding}.
|
|
654
|
+
*
|
|
655
|
+
* Resolution priority for a system-of-use call:
|
|
656
|
+
* explicit-arg (role override) → `systems[key]` → `defaultProfile` →
|
|
657
|
+
* implicit fallback.
|
|
658
|
+
*
|
|
659
|
+
* `systems[key]` is consulted AFTER any explicit role/argument override but
|
|
660
|
+
* BEFORE the global {@link defaultProfile}, so a subsystem can be pointed at a
|
|
661
|
+
* targeted model without disturbing the global base.
|
|
662
|
+
*
|
|
663
|
+
* @task T11748
|
|
664
|
+
*/
|
|
665
|
+
systems?: Record<string, SystemBinding>;
|
|
562
666
|
}
|
|
563
667
|
|
|
564
668
|
/** SignalDock transport mode. */
|
package/src/data-accessor.ts
CHANGED
|
@@ -468,9 +468,30 @@ export interface DataAccessor {
|
|
|
468
468
|
|
|
469
469
|
// ---- Fine-grained session operations ----
|
|
470
470
|
|
|
471
|
-
/**
|
|
471
|
+
/**
|
|
472
|
+
* Get the currently active session (status='active', most recent).
|
|
473
|
+
*
|
|
474
|
+
* SCAN-meaning: answers "is there any active session?" — NOT "who am I".
|
|
475
|
+
* Identity-meaning callers MUST use {@link DataAccessor.resolveCurrentSession}
|
|
476
|
+
* (T11640), which resolves the caller's OWN session via the
|
|
477
|
+
* connection-handle → `CLEO_SESSION_ID` → most-recent-active precedence.
|
|
478
|
+
*/
|
|
472
479
|
getActiveSession(): Promise<Session | null>;
|
|
473
480
|
|
|
481
|
+
/**
|
|
482
|
+
* Resolve the CALLER's current session (T11640 · Epic T11638).
|
|
483
|
+
*
|
|
484
|
+
* Identity-meaning resolution for accessor-based consumers, mirroring the
|
|
485
|
+
* standalone `resolveCurrentSession` in `@cleocode/core`. Precedence:
|
|
486
|
+
* 1. daemon connection handle (the connection bound at accept-time),
|
|
487
|
+
* 2. env-named session (`CLEO_SESSION_ID`),
|
|
488
|
+
* 3. most-recent-active row (legacy single-process fallback).
|
|
489
|
+
*
|
|
490
|
+
* Use this — NOT {@link DataAccessor.getActiveSession} — anywhere the meaning
|
|
491
|
+
* is "the session of whoever issued THIS request".
|
|
492
|
+
*/
|
|
493
|
+
resolveCurrentSession(): Promise<Session | null>;
|
|
494
|
+
|
|
474
495
|
/** Upsert a single session (targeted write). */
|
|
475
496
|
upsertSingleSession(session: Session): Promise<void>;
|
|
476
497
|
|
package/src/dispatch/identity.ts
CHANGED
|
@@ -99,6 +99,11 @@ export const CANONICAL_DOMAINS = [
|
|
|
99
99
|
// T11373: 'cleo attention add|show|list' (alias 'jot') — Tier-2 scope-keyed
|
|
100
100
|
// working-memory buffer (Epic T11288 · Saga T11283).
|
|
101
101
|
'attention',
|
|
102
|
+
// T11889 (T11889-D): 'cleo selfimprove run' — the self-dogfooding loop verb.
|
|
103
|
+
// Boots ONE sandbox → replays a canned scenario → diffs vs golden → on a
|
|
104
|
+
// regression emits ONE leased `selfimprove_dhq` row + ONE DRAFT PR. Default
|
|
105
|
+
// OFF (requires --execute); the engine lives in CORE (P5 self-improvement spec).
|
|
106
|
+
'selfimprove',
|
|
102
107
|
] as const;
|
|
103
108
|
|
|
104
109
|
/**
|
|
@@ -1462,37 +1462,6 @@ export const OPERATIONS: OperationDef[] = [
|
|
|
1462
1462
|
requiredParams: [],
|
|
1463
1463
|
params: [],
|
|
1464
1464
|
},
|
|
1465
|
-
// T5405: WarpChain pipeline operations
|
|
1466
|
-
{
|
|
1467
|
-
gateway: 'query',
|
|
1468
|
-
domain: 'pipeline',
|
|
1469
|
-
operation: 'chain.show',
|
|
1470
|
-
description: 'pipeline.chain.show (query) — get chain definition by ID',
|
|
1471
|
-
tier: 2,
|
|
1472
|
-
idempotent: true,
|
|
1473
|
-
sessionRequired: false,
|
|
1474
|
-
requiredParams: ['chainId'],
|
|
1475
|
-
params: [
|
|
1476
|
-
{
|
|
1477
|
-
name: 'chainId',
|
|
1478
|
-
type: 'string',
|
|
1479
|
-
required: true,
|
|
1480
|
-
description: 'chainId parameter',
|
|
1481
|
-
cli: { positional: true },
|
|
1482
|
-
},
|
|
1483
|
-
] satisfies ParamDef[],
|
|
1484
|
-
},
|
|
1485
|
-
{
|
|
1486
|
-
gateway: 'query',
|
|
1487
|
-
domain: 'pipeline',
|
|
1488
|
-
operation: 'chain.list',
|
|
1489
|
-
description: 'pipeline.chain.list (query) — list all chain definitions',
|
|
1490
|
-
tier: 2,
|
|
1491
|
-
idempotent: true,
|
|
1492
|
-
sessionRequired: false,
|
|
1493
|
-
requiredParams: [],
|
|
1494
|
-
params: [],
|
|
1495
|
-
},
|
|
1496
1465
|
{
|
|
1497
1466
|
gateway: 'query',
|
|
1498
1467
|
domain: 'check',
|
|
@@ -1690,26 +1659,6 @@ export const OPERATIONS: OperationDef[] = [
|
|
|
1690
1659
|
},
|
|
1691
1660
|
],
|
|
1692
1661
|
},
|
|
1693
|
-
// T5405: WarpChain validation query
|
|
1694
|
-
{
|
|
1695
|
-
gateway: 'query',
|
|
1696
|
-
domain: 'check',
|
|
1697
|
-
operation: 'chain.validate',
|
|
1698
|
-
description: 'check.chain.validate (query) — validate a WarpChain definition',
|
|
1699
|
-
tier: 2,
|
|
1700
|
-
idempotent: true,
|
|
1701
|
-
sessionRequired: false,
|
|
1702
|
-
requiredParams: ['chain'],
|
|
1703
|
-
params: [
|
|
1704
|
-
{
|
|
1705
|
-
name: 'chain',
|
|
1706
|
-
type: 'string',
|
|
1707
|
-
required: true,
|
|
1708
|
-
description: 'chain parameter',
|
|
1709
|
-
cli: { positional: true },
|
|
1710
|
-
},
|
|
1711
|
-
] satisfies ParamDef[],
|
|
1712
|
-
},
|
|
1713
1662
|
// T646: Canon drift detection — CI gate
|
|
1714
1663
|
{
|
|
1715
1664
|
gateway: 'query',
|
|
@@ -4248,77 +4197,6 @@ export const OPERATIONS: OperationDef[] = [
|
|
|
4248
4197
|
{ name: 'force', type: 'boolean', required: false, description: 'Required safety flag' },
|
|
4249
4198
|
],
|
|
4250
4199
|
},
|
|
4251
|
-
// T5405: WarpChain pipeline mutate operations
|
|
4252
|
-
{
|
|
4253
|
-
gateway: 'mutate',
|
|
4254
|
-
domain: 'pipeline',
|
|
4255
|
-
operation: 'chain.add',
|
|
4256
|
-
description: 'pipeline.chain.add (mutate) — store a validated chain definition',
|
|
4257
|
-
tier: 2,
|
|
4258
|
-
idempotent: false,
|
|
4259
|
-
sessionRequired: false,
|
|
4260
|
-
requiredParams: ['chain'],
|
|
4261
|
-
params: [
|
|
4262
|
-
{
|
|
4263
|
-
name: 'chain',
|
|
4264
|
-
type: 'string',
|
|
4265
|
-
required: true,
|
|
4266
|
-
description: 'chain parameter',
|
|
4267
|
-
cli: { positional: true },
|
|
4268
|
-
},
|
|
4269
|
-
] satisfies ParamDef[],
|
|
4270
|
-
},
|
|
4271
|
-
{
|
|
4272
|
-
gateway: 'mutate',
|
|
4273
|
-
domain: 'pipeline',
|
|
4274
|
-
operation: 'chain.instantiate',
|
|
4275
|
-
description: 'pipeline.chain.instantiate (mutate) — create chain instance for epic',
|
|
4276
|
-
tier: 2,
|
|
4277
|
-
idempotent: false,
|
|
4278
|
-
sessionRequired: false,
|
|
4279
|
-
requiredParams: ['chainId', 'epicId'],
|
|
4280
|
-
params: [
|
|
4281
|
-
{
|
|
4282
|
-
name: 'chainId',
|
|
4283
|
-
type: 'string',
|
|
4284
|
-
required: true,
|
|
4285
|
-
description: 'chainId parameter',
|
|
4286
|
-
cli: { positional: true },
|
|
4287
|
-
},
|
|
4288
|
-
{
|
|
4289
|
-
name: 'epicId',
|
|
4290
|
-
type: 'string',
|
|
4291
|
-
required: true,
|
|
4292
|
-
description: 'epicId parameter',
|
|
4293
|
-
cli: { positional: true },
|
|
4294
|
-
},
|
|
4295
|
-
] satisfies ParamDef[],
|
|
4296
|
-
},
|
|
4297
|
-
{
|
|
4298
|
-
gateway: 'mutate',
|
|
4299
|
-
domain: 'pipeline',
|
|
4300
|
-
operation: 'chain.advance',
|
|
4301
|
-
description: 'pipeline.chain.advance (mutate) — advance instance to next stage',
|
|
4302
|
-
tier: 2,
|
|
4303
|
-
idempotent: false,
|
|
4304
|
-
sessionRequired: false,
|
|
4305
|
-
requiredParams: ['instanceId', 'nextStage'],
|
|
4306
|
-
params: [
|
|
4307
|
-
{
|
|
4308
|
-
name: 'instanceId',
|
|
4309
|
-
type: 'string',
|
|
4310
|
-
required: true,
|
|
4311
|
-
description: 'instanceId parameter',
|
|
4312
|
-
cli: { positional: true },
|
|
4313
|
-
},
|
|
4314
|
-
{
|
|
4315
|
-
name: 'nextStage',
|
|
4316
|
-
type: 'string',
|
|
4317
|
-
required: true,
|
|
4318
|
-
description: 'nextStage parameter',
|
|
4319
|
-
},
|
|
4320
|
-
] satisfies ParamDef[],
|
|
4321
|
-
},
|
|
4322
4200
|
{
|
|
4323
4201
|
gateway: 'mutate',
|
|
4324
4202
|
domain: 'check',
|
|
@@ -6603,54 +6481,6 @@ export const OPERATIONS: OperationDef[] = [
|
|
|
6603
6481
|
},
|
|
6604
6482
|
] satisfies ParamDef[],
|
|
6605
6483
|
},
|
|
6606
|
-
// orchestrate — tessera template operations (T5411)
|
|
6607
|
-
// tessera.show removed — merged into tessera.list via optional id param (T5615)
|
|
6608
|
-
{
|
|
6609
|
-
gateway: 'query',
|
|
6610
|
-
domain: 'orchestrate',
|
|
6611
|
-
operation: 'tessera.list',
|
|
6612
|
-
description:
|
|
6613
|
-
'orchestrate.tessera.list (query) — list Tessera templates; absorbs tessera.show via optional id param',
|
|
6614
|
-
tier: 1,
|
|
6615
|
-
idempotent: true,
|
|
6616
|
-
sessionRequired: false,
|
|
6617
|
-
requiredParams: [],
|
|
6618
|
-
params: [
|
|
6619
|
-
{
|
|
6620
|
-
name: 'id',
|
|
6621
|
-
type: 'string',
|
|
6622
|
-
required: false,
|
|
6623
|
-
description: 'Optional template ID for single-item lookup (replaces tessera.show)',
|
|
6624
|
-
},
|
|
6625
|
-
],
|
|
6626
|
-
},
|
|
6627
|
-
{
|
|
6628
|
-
gateway: 'mutate',
|
|
6629
|
-
domain: 'orchestrate',
|
|
6630
|
-
operation: 'tessera.instantiate',
|
|
6631
|
-
description:
|
|
6632
|
-
'orchestrate.tessera.instantiate (mutate) — instantiate a Tessera template into a chain instance',
|
|
6633
|
-
tier: 1,
|
|
6634
|
-
idempotent: false,
|
|
6635
|
-
sessionRequired: false,
|
|
6636
|
-
requiredParams: ['templateId', 'epicId'],
|
|
6637
|
-
params: [
|
|
6638
|
-
{
|
|
6639
|
-
name: 'templateId',
|
|
6640
|
-
type: 'string',
|
|
6641
|
-
required: true,
|
|
6642
|
-
description: 'templateId parameter',
|
|
6643
|
-
cli: { positional: true },
|
|
6644
|
-
},
|
|
6645
|
-
{
|
|
6646
|
-
name: 'epicId',
|
|
6647
|
-
type: 'string',
|
|
6648
|
-
required: true,
|
|
6649
|
-
description: 'epicId parameter',
|
|
6650
|
-
cli: { positional: true },
|
|
6651
|
-
},
|
|
6652
|
-
] satisfies ParamDef[],
|
|
6653
|
-
},
|
|
6654
6484
|
// orchestrate — Wave 7a dispatch ops (T408, T409, T410, T415)
|
|
6655
6485
|
{
|
|
6656
6486
|
gateway: 'query',
|
|
@@ -8956,4 +8786,55 @@ export const OPERATIONS: OperationDef[] = [
|
|
|
8956
8786
|
},
|
|
8957
8787
|
] satisfies ParamDef[],
|
|
8958
8788
|
},
|
|
8789
|
+
|
|
8790
|
+
// ── selfimprove mutate: run (T11889 / T11889-D — the self-dogfooding loop) ──
|
|
8791
|
+
// Boots ONE sandbox → replays the named canned scenario → diffs result
|
|
8792
|
+
// envelopes vs the golden → on a regression emits ONE leased `selfimprove_dhq`
|
|
8793
|
+
// row and opens ONE DRAFT PR. The walking skeleton's default scenario is
|
|
8794
|
+
// query-only so the in-process replay never mutates. DEFAULT OFF: without
|
|
8795
|
+
// `execute` the loop runs DRY-RUN (replay + diff + report; NO DB write, NO PR).
|
|
8796
|
+
// The CORE engine (`runSelfImprove`) owns boot/replay/diff/persist/egress +
|
|
8797
|
+
// the budget + circuit-breaker; the dispatch handler is a thin delegate that
|
|
8798
|
+
// supplies the in-process `ReplayDispatch` port (Gate-6). `sessionRequired`
|
|
8799
|
+
// links each run to its origin session for provenance.
|
|
8800
|
+
{
|
|
8801
|
+
gateway: 'mutate',
|
|
8802
|
+
domain: 'selfimprove',
|
|
8803
|
+
operation: 'run',
|
|
8804
|
+
description:
|
|
8805
|
+
'selfimprove.run (mutate) — boot ONE sandbox, replay a canned dogfood scenario, diff vs golden; on regression emit ONE leased selfimprove_dhq row + ONE DRAFT PR. Default OFF — requires --execute (else DRY-RUN). Budget-capped + circuit-broken (T11889 / T11889-D).',
|
|
8806
|
+
tier: 2,
|
|
8807
|
+
idempotent: false,
|
|
8808
|
+
sessionRequired: true,
|
|
8809
|
+
requiredParams: ['scenario'],
|
|
8810
|
+
params: [
|
|
8811
|
+
{
|
|
8812
|
+
name: 'scenario',
|
|
8813
|
+
type: 'string',
|
|
8814
|
+
required: true,
|
|
8815
|
+
description: 'Canned dogfood scenario name to replay (e.g. dhq-replay-find)',
|
|
8816
|
+
},
|
|
8817
|
+
{
|
|
8818
|
+
name: 'execute',
|
|
8819
|
+
type: 'boolean',
|
|
8820
|
+
required: false,
|
|
8821
|
+
description:
|
|
8822
|
+
'Permit mutation (leased DHQ UPSERT) + egress (draft PR). DEFAULT false ⇒ DRY-RUN (replay + diff + report only — no DB write, no PR).',
|
|
8823
|
+
},
|
|
8824
|
+
{
|
|
8825
|
+
name: 'dryRun',
|
|
8826
|
+
type: 'boolean',
|
|
8827
|
+
required: false,
|
|
8828
|
+
description:
|
|
8829
|
+
'Force DRY-RUN explicitly (no DB write, no PR). Equivalent to omitting --execute; the loop is default-OFF.',
|
|
8830
|
+
},
|
|
8831
|
+
{
|
|
8832
|
+
name: 'backend',
|
|
8833
|
+
type: 'string',
|
|
8834
|
+
required: false,
|
|
8835
|
+
description:
|
|
8836
|
+
"Confinement backend preference: 'gondolin' (micro-VM; degrades to the in-process guarded env when VM infra is absent — the CI path) | 'guarded'. Default: gondolin.",
|
|
8837
|
+
},
|
|
8838
|
+
] satisfies ParamDef[],
|
|
8839
|
+
},
|
|
8959
8840
|
];
|