@kodax-ai/kodax 0.7.77 → 0.7.78
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/CHANGELOG.md +176 -4
- package/README.md +200 -64
- package/README_CN.md +153 -49
- package/config-templates/config.example.jsonc +114 -32
- package/dist/chunks/agent-ASP4MS3X.js +2 -0
- package/dist/chunks/argument-completer-JYQ7FX3W.js +2 -0
- package/dist/chunks/{chunk-XSA37BVM.js → chunk-2CFHBKRE.js} +1 -1
- package/dist/chunks/chunk-35PPHOQ2.js +292 -0
- package/dist/chunks/chunk-43QNNDHR.js +29 -0
- package/dist/chunks/chunk-5BNQXXGY.js +1 -0
- package/dist/chunks/chunk-5GO6FH7L.js +458 -0
- package/dist/chunks/{chunk-FSXI4MAV.js → chunk-5NDCSFOP.js} +14 -14
- package/dist/chunks/{chunk-3DD4QEBH.js → chunk-6FOJVETH.js} +10 -10
- package/dist/chunks/chunk-6XM4B6K2.js +48 -0
- package/dist/chunks/chunk-6YZUE6NC.js +240 -0
- package/dist/chunks/{chunk-HORNWBYR.js → chunk-7OEBJGHK.js} +1 -1
- package/dist/chunks/{chunk-OAMKECRG.js → chunk-KQLQYHWU.js} +205 -200
- package/dist/chunks/{chunk-IQT4RPCE.js → chunk-NXO6GWSY.js} +2 -2
- package/dist/chunks/chunk-T2XZTLYE.js +316 -0
- package/dist/chunks/chunk-TQDBTTIM.js +348 -0
- package/dist/chunks/{chunk-FNW2XUL5.js → chunk-UID7BLAB.js} +1 -1
- package/dist/chunks/chunk-VAT2QYXM.js +765 -0
- package/dist/chunks/chunk-YAZQTC2L.js +5 -0
- package/dist/chunks/chunk-YVRYHC4C.js +655 -0
- package/dist/chunks/{chunk-EH7AOMJ7.js → chunk-Z3KFRTSB.js} +1 -1
- package/dist/chunks/compaction-config-BQSSIWK5.js +2 -0
- package/dist/chunks/{construction-bootstrap-RPRL3L7R.js → construction-bootstrap-VQLQGWPY.js} +1 -1
- package/dist/chunks/{dist-FDSOIR35.js → dist-BFT5YIGU.js} +1 -1
- package/dist/chunks/dist-PCFE24YP.js +2 -0
- package/dist/chunks/host-UTFXCYYM.js +2 -0
- package/dist/chunks/run-manager-PJU3WIFJ.js +2 -0
- package/dist/chunks/utils-SID4HW2Q.js +2 -0
- package/dist/index.d.ts +18 -17
- package/dist/index.js +6 -6
- package/dist/kodax_cli.js +1751 -1352
- package/dist/kodax_resume.js +17 -17
- package/dist/runtime-worker.js +1680 -1299
- package/dist/sandbox-workspace-session.js +563 -0
- package/dist/sdk-a2a.d.ts +16 -16
- package/dist/sdk-a2a.js +8 -8
- package/dist/sdk-agent.d.ts +275 -60
- package/dist/sdk-agent.js +1 -1
- package/dist/sdk-coding.d.ts +33 -165
- package/dist/sdk-coding.js +1 -1
- package/dist/sdk-experimental-memory.d.ts +2 -2
- package/dist/sdk-experimental-memory.js +1 -1
- package/dist/sdk-llm.d.ts +2 -1
- package/dist/sdk-llm.js +1 -1
- package/dist/sdk-mcp.js +1 -1
- package/dist/sdk-media.js +1 -1
- package/dist/sdk-repl.d.ts +67 -25
- package/dist/sdk-repl.js +2 -2
- package/dist/sdk-runtime.d.ts +194 -147
- package/dist/sdk-runtime.js +1 -1
- package/dist/sdk-sandbox.d.ts +93 -0
- package/dist/sdk-sandbox.js +2 -0
- package/dist/sdk-session.d.ts +6 -7
- package/dist/sdk-session.js +1 -1
- package/dist/sdk-skills.d.ts +2 -2
- package/dist/sdk-skills.js +1 -1
- package/dist/semantic-worker.js +15 -15
- package/dist/types-chunks/{bash-prefix-extractor.d-pZdu6qt7.d.ts → bash-prefix-extractor.d-uAe2Oqda.d.ts} +126 -8
- package/dist/types-chunks/{capsule.d-CxCm1KZz.d.ts → capsule.d-BlSv9l3V.d.ts} +1 -1
- package/dist/types-chunks/{guardrail.d-CJx9RRd3.d.ts → guardrail.d-BRE_ErEj.d.ts} +1 -1
- package/dist/types-chunks/{guardrail.d-B0PwAZVR.d.ts → guardrail.d-CXDYRgZ3.d.ts} +200 -34
- package/dist/types-chunks/{history-retrieval.d-B__aEN62.d.ts → history-retrieval.d-DtCy7x64.d.ts} +1 -1
- package/dist/types-chunks/{integration-config.d-ojG4swOP.d.ts → integration-config.d-BNowXE8k.d.ts} +23 -8
- package/dist/types-chunks/{public-api.d--fF88JrC.d.ts → public-api.d-B3AohsxN.d.ts} +36 -7
- package/dist/types-chunks/{commands.d-BccESAMV.d.ts → repl.d-Ie_ZXb_U.d.ts} +89 -78
- package/dist/types-chunks/{side-query.d-5JvXhuOZ.d.ts → resolver.d-iAQ9ocLB.d.ts} +3 -66
- package/dist/types-chunks/{run-manager.d-B47hIqnI.d.ts → run-manager.d-D1twIhF9.d.ts} +1 -1
- package/dist/types-chunks/{sdk-session-CLWf8Adb.d.ts → sdk-session-DB9KksIx.d.ts} +2 -2
- package/dist/types-chunks/side-query.d-DTuLPcC5.d.ts +77 -0
- package/dist/types-chunks/{types-LanCEDj8.d.ts → types-D3g6XUQr.d.ts} +41 -2
- package/dist/types-chunks/{types.d-RdWRfUEs.d.ts → types.d-BA-Jwpfs.d.ts} +459 -7
- package/dist/types-chunks/{types.d-CODuyyqy.d.ts → types.d-BH0ZkTGf.d.ts} +1 -1
- package/dist/types-chunks/{types.d-DCQVBqVn.d.ts → types.d-BbtGlKZu.d.ts} +25 -3
- package/dist/types-chunks/{types.d-DCsKM8aT.d.ts → types.d-DVDTIfB_.d.ts} +2 -2
- package/dist/types-chunks/{utils.d-CDduqbFw.d.ts → utils.d-CVp6bFl9.d.ts} +22 -6
- package/docs/SDK_EMBEDDER_GUIDE.md +399 -55
- package/package.json +8 -1
- package/dist/chunks/agent-NGSWFE73.js +0 -2
- package/dist/chunks/argument-completer-WGGZPEEO.js +0 -2
- package/dist/chunks/chunk-27QLRH3D.js +0 -5
- package/dist/chunks/chunk-2MQPVY6P.js +0 -770
- package/dist/chunks/chunk-6WAPVAGQ.js +0 -74
- package/dist/chunks/chunk-AOENDSVN.js +0 -448
- package/dist/chunks/chunk-HV2GMZUZ.js +0 -343
- package/dist/chunks/chunk-JS2BHGJP.js +0 -158
- package/dist/chunks/chunk-ON2WG2LG.js +0 -622
- package/dist/chunks/chunk-RUGAAHTF.js +0 -321
- package/dist/chunks/chunk-TGCG7U2W.js +0 -37
- package/dist/chunks/compaction-config-BE7VYWH6.js +0 -2
- package/dist/chunks/dist-ZZBNVTKU.js +0 -2
- package/dist/chunks/host-QAKQVC4A.js +0 -2
- package/dist/chunks/run-manager-N4UFWA2D.js +0 -2
- package/dist/chunks/utils-AUHCI4D5.js +0 -2
- package/dist/types-chunks/center-types.d-BBT122uJ.d.ts +0 -91
|
@@ -56,6 +56,11 @@ interface SkillMetadata {
|
|
|
56
56
|
argumentHint?: string;
|
|
57
57
|
path: string;
|
|
58
58
|
source: ResolvedSkillSource;
|
|
59
|
+
readonly learned?: {
|
|
60
|
+
readonly capabilityId: string;
|
|
61
|
+
readonly revision: number;
|
|
62
|
+
readonly fingerprint: string;
|
|
63
|
+
};
|
|
59
64
|
/** If true, exclude from system prompt; still invokable by explicit slash forms. */
|
|
60
65
|
disableModelInvocation: boolean;
|
|
61
66
|
}
|
|
@@ -204,7 +209,22 @@ interface SkillPathsConfig {
|
|
|
204
209
|
userPaths: string[];
|
|
205
210
|
pluginPaths: string[];
|
|
206
211
|
builtinPath: string;
|
|
212
|
+
/**
|
|
213
|
+
* Deprecated loose-file path. It remains in the public shape for source
|
|
214
|
+
* compatibility but is intentionally not discovered without a manifest.
|
|
215
|
+
*/
|
|
207
216
|
learnedPath?: string;
|
|
217
|
+
learnedArea?: LearnedSkillDiscoveryConfig;
|
|
218
|
+
}
|
|
219
|
+
interface LearnedSkillDiscoveryConfig {
|
|
220
|
+
readonly rootDir: string;
|
|
221
|
+
readonly expectedScope: {
|
|
222
|
+
readonly configHomeHash: string;
|
|
223
|
+
readonly tenantHash: string;
|
|
224
|
+
readonly projectHash: string;
|
|
225
|
+
};
|
|
226
|
+
readonly testingBindings?: Readonly<Record<string, string>>;
|
|
227
|
+
readonly now?: string;
|
|
208
228
|
}
|
|
209
229
|
/**
|
|
210
230
|
* Get default skill discovery paths
|
|
@@ -215,13 +235,15 @@ interface SkillPathsConfig {
|
|
|
215
235
|
* 3. User - ~/.agents/skills/ (AgentSkills standard)
|
|
216
236
|
* 4. Plugin - (dynamic)
|
|
217
237
|
* 5. Builtin - packages/skills/src/builtin/
|
|
218
|
-
*
|
|
238
|
+
* Learned Skills are supplied separately through a record-gated Learned Area
|
|
239
|
+
* and never through a loose directory.
|
|
219
240
|
*/
|
|
220
241
|
declare function getDefaultSkillPaths(projectRoot?: string): SkillPathsConfig;
|
|
221
242
|
/**
|
|
222
243
|
* All skill paths in priority order (highest to lowest)
|
|
223
244
|
*
|
|
224
|
-
* Priority: Project > User > Plugin > Builtin
|
|
245
|
+
* Priority: Project > User > Plugin > Builtin. Record-gated Learned Skills
|
|
246
|
+
* are appended by discovery after these formal sources.
|
|
225
247
|
* - Project: Project-specific skills override everything else
|
|
226
248
|
* - User: User preferences (~/.kodax/ and ~/.agents/)
|
|
227
249
|
* - Plugin: Third-party plugins
|
|
@@ -234,4 +256,4 @@ declare function getSkillPathsFlat(config: SkillPathsConfig): Array<{
|
|
|
234
256
|
}>;
|
|
235
257
|
|
|
236
258
|
export { getDefaultSkillPaths as m, getSkillPathsFlat as n };
|
|
237
|
-
export type { ISkillRegistry as I, ResolvedSkillSource as R, Skill as S, IVariableResolver as a, SkillArtifact as b, SkillContext as c, SkillDynamicContextExecutor as d, SkillFile as e, SkillFrontmatter as f, SkillHook as g, SkillHooks as h, SkillMetadata as i, SkillPathsConfig as j, SkillResult as k, SkillSource as l };
|
|
259
|
+
export type { ISkillRegistry as I, LearnedSkillDiscoveryConfig as L, ResolvedSkillSource as R, Skill as S, IVariableResolver as a, SkillArtifact as b, SkillContext as c, SkillDynamicContextExecutor as d, SkillFile as e, SkillFrontmatter as f, SkillHook as g, SkillHooks as h, SkillMetadata as i, SkillPathsConfig as j, SkillResult as k, SkillSource as l };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { a9 as KodaXWireReasoningEffort, a1 as KodaXToolDefinition, a3 as KodaXToolResultContentItem, k as KodaXMessage } from './types.d-DIpZJKUl.js';
|
|
2
2
|
import { K as KodaXBaseProvider } from './base.d-4e74xDdy.js';
|
|
3
3
|
import { C as CapabilityKind, a as CapabilityProvider } from './capability.d-K664nHOS.js';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { bF as KodaXJsonValue, bt as KodaXExtensionSessionRecord, bv as KodaXExtensionStore } from './types.d-BA-Jwpfs.js';
|
|
5
|
+
import { aP as KodaXToolExecutionContext, bx as ToolSideEffect } from './bash-prefix-extractor.d-uAe2Oqda.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* KodaX Constructed-World types (FEATURE_087, v0.7.28).
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { k as KodaXMessage, F as KodaXReasoningMode, d as KodaXCustomProviderConfig, p as KodaXProviderCapabilityProfile } from './types.d-DIpZJKUl.js';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { d as AgentsFile,
|
|
2
|
+
import { c3 as KodaXSessionUiHistoryItem, bU as KodaXSessionLineage, bL as KodaXSessionArtifactLedgerEntry, bu as KodaXExtensionSessionState, bt as KodaXExtensionSessionRecord, b$ as KodaXSessionRuntimeInfo, e$ as WorkflowProcessSource } from './types.d-BA-Jwpfs.js';
|
|
3
|
+
import { O as KodaXContextTokenSnapshot, as as KodaXSkillDynamicContextPolicy, t as KodaXAgentMode, a8 as KodaXRepoIntelligenceMode, a1 as KodaXOptions, at as KodaXSkillInvocationContext } from './bash-prefix-extractor.d-uAe2Oqda.js';
|
|
4
|
+
import { d as AgentsFile, s as AutoModeStats, J as KodaXMcpServersConfig } from './guardrail.d-CXDYRgZ3.js';
|
|
5
5
|
import * as readline from 'readline';
|
|
6
|
-
import { R as PermissionMode, L as LearningBinding, E as LearningSurfaceSnapshot } from './public-api.d
|
|
6
|
+
import { R as PermissionMode, L as LearningBinding, E as LearningSurfaceSnapshot } from './public-api.d-B3AohsxN.js';
|
|
7
7
|
import { SpawnSyncReturns } from 'child_process';
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -310,6 +310,22 @@ interface CommandCallbacks {
|
|
|
310
310
|
rewindSession?: (selector?: string) => Promise<SessionRewindStatus>;
|
|
311
311
|
getCostReport?: () => string | null;
|
|
312
312
|
getRuntimeStatus?: () => Promise<RuntimeSurfaceStatus | undefined>;
|
|
313
|
+
/** Canonical host parser used by `/setup` for the root-owned A2A schema. */
|
|
314
|
+
validateSetupA2AConfig?: (value: unknown) => unknown;
|
|
315
|
+
/** Root-owned sandbox activation because ASRT is distributed by the host package. */
|
|
316
|
+
prepareSetupSandbox?: () => Promise<{
|
|
317
|
+
readonly status: 'ready' | 'cancelled' | 'unavailable';
|
|
318
|
+
readonly lines: readonly string[];
|
|
319
|
+
}>;
|
|
320
|
+
/** Explicit read-only `/sandbox` probe. Ordinary startup never calls it. */
|
|
321
|
+
inspectSandbox?: () => Promise<{
|
|
322
|
+
readonly ready: boolean;
|
|
323
|
+
readonly platform: string;
|
|
324
|
+
readonly version: string;
|
|
325
|
+
readonly backend: string;
|
|
326
|
+
readonly diagnostics: readonly string[];
|
|
327
|
+
readonly guidance: readonly string[];
|
|
328
|
+
}>;
|
|
313
329
|
learning?: LearningBinding;
|
|
314
330
|
getLearningSummary?: () => Promise<LearningSurfaceSnapshot>;
|
|
315
331
|
openLearningCenter?: (nameOrSlug?: string) => Promise<void>;
|
|
@@ -364,7 +380,7 @@ interface CommandDefinition {
|
|
|
364
380
|
aliases?: string[];
|
|
365
381
|
description: string;
|
|
366
382
|
usage?: string;
|
|
367
|
-
detailedHelp?: () => void;
|
|
383
|
+
detailedHelp?: (args?: readonly string[]) => void;
|
|
368
384
|
handler: CommandHandler;
|
|
369
385
|
source?: CommandSource;
|
|
370
386
|
priority?: CommandPriority;
|
|
@@ -406,7 +422,7 @@ interface Command {
|
|
|
406
422
|
description: string;
|
|
407
423
|
usage?: string;
|
|
408
424
|
handler: CommandHandler;
|
|
409
|
-
detailedHelp?: () => void;
|
|
425
|
+
detailedHelp?: (args?: readonly string[]) => void;
|
|
410
426
|
source?: CommandSource;
|
|
411
427
|
priority?: CommandPriority;
|
|
412
428
|
location?: 'user' | 'project' | 'path';
|
|
@@ -33,8 +33,12 @@ are NOT obvious from inspecting the type definitions alone:
|
|
|
33
33
|
23. [Shared Coder daemon for Space and IDE hosts](#23-shared-coder-daemon-for-space-and-ide-hosts-feature_269-v0769)
|
|
34
34
|
24. [Runtime-owned Auto Mode and plan-approval bridges](#24-runtime-owned-auto-mode-and-plan-approval-bridges-v0772v0773)
|
|
35
35
|
25. [Always-on context compaction and bounded transcript recovery](#25-always-on-context-compaction-and-bounded-transcript-recovery-v0774)
|
|
36
|
-
26. [Agent mailbox control versus SDK event telemetry](#26-agent-mailbox-control-versus-sdk-event-telemetry-v0774)
|
|
37
|
-
27. [Windows GUI background subprocess visibility](#27-windows-gui-background-subprocess-visibility-v0775)
|
|
36
|
+
26. [Agent mailbox control versus SDK event telemetry](#26-agent-mailbox-control-versus-sdk-event-telemetry-v0774)
|
|
37
|
+
27. [Windows GUI background subprocess visibility](#27-windows-gui-background-subprocess-visibility-v0775)
|
|
38
|
+
28. [Host-configurable Shell Execution Contract](#28-host-configurable-shell-execution-contract-v0777)
|
|
39
|
+
29. [Evidence-gated background Skill learning](#29-evidence-gated-background-skill-learning-feature_263-v0778)
|
|
40
|
+
30. [Standalone sandbox SDK](#30-standalone-sandbox-sdk-v0778)
|
|
41
|
+
- [Learned Skill promotion reference](#learned-skill-promotion-reference-v0778)
|
|
38
42
|
|
|
39
43
|
§1–§3 (and the Phase-7/8 MCP-popout surface in §1) land in v0.7.42
|
|
40
44
|
under FEATURE_186 (see [ADR-032](ADR.md#adr-032-sdk-embedder-surface-closure-feature_186-v0742)).
|
|
@@ -3695,12 +3699,16 @@ const server = createKodaXA2AServer({
|
|
|
3695
3699
|
},
|
|
3696
3700
|
});
|
|
3697
3701
|
|
|
3698
|
-
// Development only: the built-in listener refuses non-loopback hosts.
|
|
3699
|
-
const localBaseUrl = await server.listen({ hostname: '127.0.0.1', port: 0 });
|
|
3700
|
-
```
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3702
|
+
// Development only: the built-in listener refuses non-loopback hosts.
|
|
3703
|
+
const localBaseUrl = await server.listen({ hostname: '127.0.0.1', port: 0 });
|
|
3704
|
+
```
|
|
3705
|
+
|
|
3706
|
+
The listener also refuses an explicit port blocked by WHATWG Fetch clients.
|
|
3707
|
+
With `port: 0`, it retries ephemeral allocation rather than returning a URL
|
|
3708
|
+
that Fetch would reject before connecting.
|
|
3709
|
+
|
|
3710
|
+
Production hosts route `GET /.well-known/agent-card.json` and canonical
|
|
3711
|
+
JSON-RPC `POST /a2a` to `server.handle(request)` behind their own TLS
|
|
3704
3712
|
terminator. `POST /` remains an accepted compatibility alias. `listen()` waits for durable recovery before
|
|
3705
3713
|
it resolves. A host that wires `handle()` directly may explicitly await
|
|
3706
3714
|
`server.whenReady()` before it starts accepting traffic; `handle()` also waits
|
|
@@ -3784,10 +3792,14 @@ SDK does not relaunch the GUI or silently fall back to an inline Runtime.
|
|
|
3784
3792
|
```ts
|
|
3785
3793
|
import { connectKodaXRuntime } from '@kodax-ai/kodax/runtime';
|
|
3786
3794
|
|
|
3787
|
-
const runtime = await connectKodaXRuntime({
|
|
3788
|
-
profile: 'coder',
|
|
3789
|
-
autoStart: true,
|
|
3790
|
-
|
|
3795
|
+
const runtime = await connectKodaXRuntime({
|
|
3796
|
+
profile: 'coder',
|
|
3797
|
+
autoStart: true,
|
|
3798
|
+
// Opt in only when this product remains the visible owner of the daemon.
|
|
3799
|
+
// If the product crashes, the daemon stops after its final client is gone
|
|
3800
|
+
// and governed work becomes idle.
|
|
3801
|
+
daemonOrphanExitMs: 30_000,
|
|
3802
|
+
homeDir: coderRuntimeBaseDir, // owns <coderRuntimeBaseDir>/.kodax
|
|
3791
3803
|
clientInfo: {
|
|
3792
3804
|
name: 'kodax-space',
|
|
3793
3805
|
version: '0.1.32',
|
|
@@ -3819,10 +3831,10 @@ const runtime = await connectKodaXRuntime({
|
|
|
3819
3831
|
sharedSessionSettings: 1,
|
|
3820
3832
|
durableRecoveryQueries: 1,
|
|
3821
3833
|
daemonManagement: 1,
|
|
3822
|
-
runtimeAutoModeGuardrail:
|
|
3823
|
-
},
|
|
3824
|
-
});
|
|
3825
|
-
```
|
|
3834
|
+
runtimeAutoModeGuardrail: 4,
|
|
3835
|
+
},
|
|
3836
|
+
});
|
|
3837
|
+
```
|
|
3826
3838
|
|
|
3827
3839
|
Requirements are server facts, not authorization requests. Check
|
|
3828
3840
|
`runtime.grantedScopes` before enabling controls. Missing capabilities or
|
|
@@ -3832,21 +3844,35 @@ Coder. Products that depend on same-Run delivery should require
|
|
|
3832
3844
|
(for example, SA execution) still return `unsupported_capability`; do not
|
|
3833
3845
|
silently substitute `delivery:'after_turn'` unless that is the user's intent.
|
|
3834
3846
|
|
|
3835
|
-
The
|
|
3836
|
-
`autoStart: true
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3847
|
+
The SDK requires `runtimeAutoModeGuardrail:4` automatically for ordinary
|
|
3848
|
+
`autoStart: true`. Supplying `daemonOrphanExitMs` additionally requires the
|
|
3849
|
+
dedicated `daemonOrphanExit:1` capability and passes the option only when
|
|
3850
|
+
spawning a new daemon. It does not silently reinterpret an already-running
|
|
3851
|
+
persistent daemon: the SDK uses the normal fenced capability-upgrade path and
|
|
3852
|
+
replaces it only when preflight proves that doing so is safe. After the daemon
|
|
3853
|
+
has observed a logical client, final-client detach arms the requested grace
|
|
3854
|
+
period; a new client cancels it, and active/queued runs, Workflow, Agent turns,
|
|
3855
|
+
pending permission/user input, or other governed work defer exit until
|
|
3856
|
+
preflight is idle. Omit the option for CLI-style daemons that are intentionally
|
|
3857
|
+
persistent.
|
|
3858
|
+
|
|
3859
|
+
An embedder can inspect `KODAX_RUNTIME_SDK_CAPABILITIES.daemonOrphanExit`
|
|
3860
|
+
before calling an auto-start API. This prevents an older SDK from spawning a
|
|
3861
|
+
persistent daemon and only then discovering that it cannot honor the requested
|
|
3862
|
+
lifecycle policy. The connected daemon capability remains the authoritative
|
|
3863
|
+
check that the current host actually enabled the policy.
|
|
3864
|
+
|
|
3865
|
+
When a healthy profile daemon is too old, the SDK first requires
|
|
3866
|
+
`daemonManagement:1`, takes a revision/owner-policy fenced preflight, and
|
|
3867
|
+
replaces it only when no active or queued run, Workflow, Agent turn, pending
|
|
3868
|
+
permission/user input, or other logical client exists. A busy or still-older
|
|
3869
|
+
daemon is never stopped: the connection rejects with
|
|
3870
|
+
`RuntimeDaemonCapabilityUpgradeError`, whose `recoverable` and
|
|
3871
|
+
`restartRequired` fields are `true` and whose optional `preflight` explains the
|
|
3872
|
+
blockers. Attach-only connections never mutate daemon ownership and must request
|
|
3873
|
+
the exact capabilities they depend on. Capability requirements are minimum
|
|
3874
|
+
versions: v4 satisfies v1-v3, v3 satisfies v1/v2, v2 satisfies v1, and an older
|
|
3875
|
+
daemon never satisfies a newer requirement.
|
|
3850
3876
|
|
|
3851
3877
|
The `coderFeatureMatrix` capability reports daemon availability for managed
|
|
3852
3878
|
runs, transcript/session operations, Todo projection, managed tasks, Workflow,
|
|
@@ -4076,9 +4102,11 @@ Write/Edit content may differ). Generic extension calls can receive only an
|
|
|
4076
4102
|
exact in-memory Session grant. Raw command/argv data is not stored in the
|
|
4077
4103
|
matcher; grants and audit contain only its fingerprint plus a bounded,
|
|
4078
4104
|
secret-redacted operator label. Clients must not keep separate persistent
|
|
4079
|
-
permission rule stores. Runtime capability `runtimeAutoModeGuardrail`
|
|
4080
|
-
opaque concrete-grant contract
|
|
4081
|
-
|
|
4105
|
+
permission rule stores. Runtime capability `runtimeAutoModeGuardrail` v4
|
|
4106
|
+
advertises this opaque concrete-grant contract plus the intent-aligned
|
|
4107
|
+
retry/Accept-edits behavior that never changes the engine to rules. Embedded,
|
|
4108
|
+
Worker, and daemon hosts all report `fallbackPersistsEngine:false`; restart or
|
|
4109
|
+
upgrade an older daemon instead of falling back to a client-side alias.
|
|
4082
4110
|
|
|
4083
4111
|
### Broker a Space keychain credential
|
|
4084
4112
|
|
|
@@ -4357,9 +4385,9 @@ engine/denial/breaker state per Session. It reuses bounded context-specific
|
|
|
4357
4385
|
guardrails across turns while provider/model, repository boundary, execution
|
|
4358
4386
|
directory, classifier model, and timeout remain the same. Updating one of
|
|
4359
4387
|
those inputs selects a new context guardrail by design without copying stale
|
|
4360
|
-
state from a queued turn. Active runs, queued runs, explicit settings updates,
|
|
4361
|
-
and
|
|
4362
|
-
|
|
4388
|
+
state from a queued turn. Active runs, queued runs, explicit settings updates,
|
|
4389
|
+
and explicit engine changes merge through the same Session mutation queue.
|
|
4390
|
+
Classifier infrastructure failures do not mutate the engine to rules.
|
|
4363
4391
|
|
|
4364
4392
|
### What an embedder should expect
|
|
4365
4393
|
|
|
@@ -4369,16 +4397,22 @@ The Runtime's execution order is fixed:
|
|
|
4369
4397
|
Runtime Auto Mode guardrail -> host permission bridge only for escalate -> tool execution
|
|
4370
4398
|
```
|
|
4371
4399
|
|
|
4372
|
-
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
|
|
4400
|
+
Exactly modeled ordinary reads and workspace/system-temp mutations are admitted
|
|
4401
|
+
before classifier latency, independent of sandbox readiness. Other calls are
|
|
4402
|
+
reviewed against the latest genuine user request, bounded user-only intent
|
|
4403
|
+
evidence, and exact operation facts. Consequently, an LLM/rules `allow` does
|
|
4404
|
+
not create a pending permission request just because a host installed a static
|
|
4405
|
+
approval hook. Classifier concerns, critical deterministic matches, and rules
|
|
4406
|
+
concerns use the existing shared
|
|
4407
|
+
`runtime.permissions` flow, so another authorized client may render and answer
|
|
4408
|
+
it. Hosts should subscribe to permission events to display such a request, but
|
|
4409
|
+
must not treat a missing request as an error for a safe tool call.
|
|
4410
|
+
|
|
4411
|
+
The classifier deadline remains 20 seconds by default and includes connection
|
|
4412
|
+
setup, provider Retry-After/backoff, inference, and stream completion. KodaX
|
|
4413
|
+
retries one timeout/provider/response-contract failure once; a second failure
|
|
4414
|
+
uses the Accept-edits safety boundary and never switches to Auto[rules].
|
|
4415
|
+
KodaX does not solve timeouts by extending that deadline indefinitely. Before the
|
|
4382
4416
|
provider call it removes assistant prose/thinking and image paths, limits each
|
|
4383
4417
|
tool result to 2 KiB and the serialized permission-relevant transcript to
|
|
4384
4418
|
8 KiB, then enforces 16 KiB action and 32 KiB total-prompt ceilings plus a
|
|
@@ -4405,14 +4439,21 @@ session repository safety boundary, whereas relative operands resolve from the
|
|
|
4405
4439
|
validated `executionCwd`. In particular, quoted Python/JavaScript/regexp source
|
|
4406
4440
|
inside a shell command is not a path operand.
|
|
4407
4441
|
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4442
|
+
Every Runtime permission request has a deadline. If the host does not answer,
|
|
4443
|
+
the current operation is not executed and the guardrail returns a stable
|
|
4444
|
+
`approval_timeout` result telling the main model to try a safer, narrower, or
|
|
4445
|
+
reversible approach, or stop and wait for explicit user approval. A timeout is
|
|
4446
|
+
not serialized as an ordinary user rejection.
|
|
4447
|
+
|
|
4448
|
+
The user-level `.kodax` directory is a credential/configuration boundary, not
|
|
4449
|
+
an ordinary project path. Direct shell mutations, output redirects, and
|
|
4450
|
+
recognized nested-shell payloads whose target is provably beneath that
|
|
4451
|
+
directory are identified before LLM classification and routed to permission
|
|
4452
|
+
approval rather than permanently policy-blocked. The check is segment-safe and
|
|
4453
|
+
Windows case-insensitive. KodaX deliberately does not scan arbitrary
|
|
4454
|
+
quoted language source for path-looking substrings: doing so would turn Python,
|
|
4455
|
+
JavaScript, YAML, and regular expressions into false Tier-0 matches. Trusted
|
|
4456
|
+
configuration changes should use the KodaX config CLI or SDK configuration API.
|
|
4416
4457
|
|
|
4417
4458
|
### 0.7.x source compatibility
|
|
4418
4459
|
|
|
@@ -4773,6 +4814,309 @@ for cross-project, cache, cancellation, credential, and Windows argv checks.
|
|
|
4773
4814
|
|
|
4774
4815
|
---
|
|
4775
4816
|
|
|
4817
|
+
## 29. Evidence-gated background Skill learning (FEATURE_263, v0.7.78)
|
|
4818
|
+
|
|
4819
|
+
F263 completes the existing Learning Center rather than introducing a second
|
|
4820
|
+
queue or client-owned Skill store. Episode review runs after durable foreground
|
|
4821
|
+
completion and stays off the active Run's latency path. A correction, failure,
|
|
4822
|
+
or verifier result is Memory evidence first; it does not itself authorize a
|
|
4823
|
+
Skill mutation.
|
|
4824
|
+
|
|
4825
|
+
A low-risk declarative Skill can enter automatic project-scoped testing only
|
|
4826
|
+
after an explicit preserve-as-Skill request with verified terminal evidence,
|
|
4827
|
+
or repeated independent root episodes plus independent verified artifact
|
|
4828
|
+
evidence. The owner writes an immutable revision and its canonical capability
|
|
4829
|
+
record before discovery can expose it. Formal/builtin/plugin/human Skills keep
|
|
4830
|
+
precedence and cannot be shadowed. Protected/formal changes, user-global
|
|
4831
|
+
promotion, and Extension authoring remain explicit user actions.
|
|
4832
|
+
|
|
4833
|
+
Hosts that require this behavior should negotiate both Runtime capabilities:
|
|
4834
|
+
|
|
4835
|
+
```ts
|
|
4836
|
+
const runtime = await createKodaXRuntime({
|
|
4837
|
+
mode: 'daemon',
|
|
4838
|
+
requirements: {
|
|
4839
|
+
learningCenter: 1,
|
|
4840
|
+
skillLearningLoop: 1,
|
|
4841
|
+
},
|
|
4842
|
+
clientInfo: {
|
|
4843
|
+
name: 'my-host',
|
|
4844
|
+
instanceId: stableClientId,
|
|
4845
|
+
instanceSecret: keychainSecret,
|
|
4846
|
+
},
|
|
4847
|
+
});
|
|
4848
|
+
|
|
4849
|
+
const snapshot = await runtime.learning.getSnapshot();
|
|
4850
|
+
const page = await runtime.learning.list({ limit: 50 });
|
|
4851
|
+
|
|
4852
|
+
for await (const event of runtime.learning.subscribe({
|
|
4853
|
+
afterRevision: snapshot.revision,
|
|
4854
|
+
})) {
|
|
4855
|
+
renderLearningEvent(event);
|
|
4856
|
+
}
|
|
4857
|
+
```
|
|
4858
|
+
|
|
4859
|
+
`runtime.learning` is the authoritative host surface:
|
|
4860
|
+
|
|
4861
|
+
| Need | API |
|
|
4862
|
+
|---|---|
|
|
4863
|
+
| Render inventory or one exact record | `list()` / `get()` |
|
|
4864
|
+
| Render client-specific badges | `getSnapshot()` |
|
|
4865
|
+
| Replay or follow durable lifecycle events | `events()` / `subscribe()` |
|
|
4866
|
+
| Clear or defer only this client's notice | `acknowledge()` / `snooze()` |
|
|
4867
|
+
| Explicitly control a learned revision | `reject()` / `disable()` / `rollback()` / `review()` / `trust()` |
|
|
4868
|
+
| Promote to the user scope | `promote(nameOrSlugOrId, 'user')` |
|
|
4869
|
+
|
|
4870
|
+
Do not scan learned files and infer activation from their presence. Discovery
|
|
4871
|
+
requires the canonical record, matching project identity, lifecycle,
|
|
4872
|
+
fingerprint, regular-file checks, formal-name policy, and exact revision.
|
|
4873
|
+
Testing admission permits one concurrent root binding and at most three
|
|
4874
|
+
exact-revision invocations. Promotion requires independently verified success;
|
|
4875
|
+
failed or inconclusive canaries return to Ready/attention. A Run retains the
|
|
4876
|
+
revision it captured at admission, so rollback or replacement affects future
|
|
4877
|
+
bindings without mutating an in-flight prompt.
|
|
4878
|
+
|
|
4879
|
+
Learning Center notification state is client-specific, but capability
|
|
4880
|
+
lifecycle and project canary state are owner-global. Renderer code should
|
|
4881
|
+
receive sanitized records/events through host IPC; it should not receive
|
|
4882
|
+
daemon credentials or mutate files directly. Inline, Worker, and daemon
|
|
4883
|
+
facades expose the same learning methods. A host missing `skillLearningLoop:1`
|
|
4884
|
+
may still support the older Ready/manual Learning Center surface, but must not
|
|
4885
|
+
claim the complete F263 project-canary contract.
|
|
4886
|
+
|
|
4887
|
+
---
|
|
4888
|
+
|
|
4889
|
+
## 30. Standalone sandbox SDK (v0.7.78)
|
|
4890
|
+
|
|
4891
|
+
ASRT containment is a public SDK capability, not an Auto[LLM]-only
|
|
4892
|
+
implementation detail. Import the dedicated subpath when a host needs to
|
|
4893
|
+
sandbox its own commands or scripts:
|
|
4894
|
+
|
|
4895
|
+
```ts
|
|
4896
|
+
import {
|
|
4897
|
+
activateKodaXSandbox,
|
|
4898
|
+
doctorKodaXSandbox,
|
|
4899
|
+
getKodaXSandboxCapability,
|
|
4900
|
+
getKodaXSandboxSetupGuidance,
|
|
4901
|
+
runKodaXSandboxed,
|
|
4902
|
+
} from '@kodax-ai/kodax/sandbox';
|
|
4903
|
+
|
|
4904
|
+
const capability = getKodaXSandboxCapability();
|
|
4905
|
+
const doctor = await doctorKodaXSandbox({ refresh: true });
|
|
4906
|
+
|
|
4907
|
+
if (!doctor.ready) {
|
|
4908
|
+
showSandboxInfo(getKodaXSandboxSetupGuidance(doctor));
|
|
4909
|
+
// Call only from an explicit setup/onboarding action. On Windows this may
|
|
4910
|
+
// display UAC; ordinary SDK calls never invoke it automatically.
|
|
4911
|
+
const activation = await activateKodaXSandbox();
|
|
4912
|
+
if (activation.status !== 'ready') {
|
|
4913
|
+
showSandboxInfo(activation.guidance);
|
|
4914
|
+
}
|
|
4915
|
+
}
|
|
4916
|
+
```
|
|
4917
|
+
|
|
4918
|
+
Platform behavior:
|
|
4919
|
+
|
|
4920
|
+
- Windows uses the pinned ASRT restricted-user/WFP setup. The parent terminal
|
|
4921
|
+
does not need to be elevated; the one-time installer requests UAC itself.
|
|
4922
|
+
- macOS uses Seatbelt through `sandbox-exec` and requires ripgrep. Guide users
|
|
4923
|
+
to `brew install ripgrep` when doctor reports it missing.
|
|
4924
|
+
- Linux uses bubblewrap and requires `bubblewrap`, `socat`, and `ripgrep`.
|
|
4925
|
+
Present the emitted `apt`/`dnf`/`pacman` guidance; do not run `sudo` or a
|
|
4926
|
+
package manager silently.
|
|
4927
|
+
|
|
4928
|
+
Do not call `activateKodaXSandbox()` during ordinary Runtime startup, tool
|
|
4929
|
+
execution, or a background permission check. KodaX's own first-run/setup UI
|
|
4930
|
+
checks once; a declined UAC prompt or missing dependency is reported there and
|
|
4931
|
+
is not repeatedly surfaced until the user runs setup again.
|
|
4932
|
+
|
|
4933
|
+
### Run a host-owned command with an explicit policy
|
|
4934
|
+
|
|
4935
|
+
```ts
|
|
4936
|
+
import os from 'node:os';
|
|
4937
|
+
import path from 'node:path';
|
|
4938
|
+
import { runKodaXSandboxed } from '@kodax-ai/kodax/sandbox';
|
|
4939
|
+
|
|
4940
|
+
const result = await runKodaXSandboxed({
|
|
4941
|
+
command: process.execPath,
|
|
4942
|
+
args: ['scripts/generate-report.mjs'],
|
|
4943
|
+
cwd: projectDirectory,
|
|
4944
|
+
filesystem: {
|
|
4945
|
+
allowRead: [projectDirectory, process.execPath],
|
|
4946
|
+
allowWrite: [projectDirectory, os.tmpdir()],
|
|
4947
|
+
denyRead: [path.join(os.homedir(), '.ssh')],
|
|
4948
|
+
denyWrite: [path.join(projectDirectory, '.git', 'config')],
|
|
4949
|
+
},
|
|
4950
|
+
network: {
|
|
4951
|
+
mode: 'allowlist',
|
|
4952
|
+
origins: ['https://api.example.com'],
|
|
4953
|
+
},
|
|
4954
|
+
// false by default: start with KodaX's minimal execution environment.
|
|
4955
|
+
inheritEnvironment: false,
|
|
4956
|
+
env: { REPORT_FORMAT: 'pdf' },
|
|
4957
|
+
timeoutMs: 120_000,
|
|
4958
|
+
maxOutputBytes: 2 * 1024 * 1024,
|
|
4959
|
+
});
|
|
4960
|
+
|
|
4961
|
+
if (result.status === 'unavailable') {
|
|
4962
|
+
// The command was NOT run. Decide explicitly whether your product should
|
|
4963
|
+
// wait for setup, reject the operation, or use its own non-sandbox path.
|
|
4964
|
+
showSandboxInfo(getKodaXSandboxSetupGuidance(result.doctor));
|
|
4965
|
+
} else if (result.exitCode !== 0) {
|
|
4966
|
+
throw new Error(result.stderr || `sandboxed command exited ${result.exitCode}`);
|
|
4967
|
+
}
|
|
4968
|
+
```
|
|
4969
|
+
|
|
4970
|
+
The generic executor supports network `allow`, `deny`, and exact HTTP(S)
|
|
4971
|
+
origin `allowlist` modes plus filesystem policy roots, environment inheritance,
|
|
4972
|
+
timeout, cancellation, and bounded output. ASRT permits ordinary reads by
|
|
4973
|
+
default: `denyRead` removes access and a more specific `allowRead` carves access
|
|
4974
|
+
back. `allowWrite` defines the writable roots, while `denyWrite` removes
|
|
4975
|
+
subtrees and always takes precedence over `allowWrite`. The HTTP(S) `origins`
|
|
4976
|
+
are normalized to the hostname/port pair enforced by ASRT's network proxy. It
|
|
4977
|
+
never silently runs without containment: sandbox unavailability is the typed
|
|
4978
|
+
`{ status: 'unavailable', sandboxed: false, doctor }` result.
|
|
4979
|
+
|
|
4980
|
+
KodaX's own local workspace-shell policy supplies a stricter `denyRead` set
|
|
4981
|
+
than the generic SDK default: common home credential locations, sensitive
|
|
4982
|
+
private-key/environment filenames, and the complete resolved agent home are
|
|
4983
|
+
denied. Home-local executable search paths nested below those roots are not
|
|
4984
|
+
re-granted. This policy belongs to KodaX's command adapter; a standalone SDK
|
|
4985
|
+
host must declare the sensitive paths required by its own threat boundary.
|
|
4986
|
+
|
|
4987
|
+
`command` and `args` remain separate process arguments. On Windows KodaX uses
|
|
4988
|
+
an encoded bootstrap followed by `shell: false`, so `%VAR%`, `&`, embedded
|
|
4989
|
+
quotes, and spaces are not expanded or re-parsed by the host shell. The
|
|
4990
|
+
explicit environment policy is overlaid into ASRT's fresh restricted-user
|
|
4991
|
+
environment; ASRT-owned proxy, CA, and Git safety variables retain precedence.
|
|
4992
|
+
`timeoutMs` covers the complete broker lifecycle, including ASRT
|
|
4993
|
+
initialization, the command, and cleanup. Windows ACL initialization on a cold
|
|
4994
|
+
path can take tens of seconds, so do not reuse a classifier-scale 20–30 second
|
|
4995
|
+
deadline unless that early cancellation is intentional.
|
|
4996
|
+
|
|
4997
|
+
This is intentionally different from KodaX's local permission fallback. When
|
|
4998
|
+
ASRT is unavailable, Auto[LLM] still makes the same deterministic/LLM/user
|
|
4999
|
+
permission decision and an admitted local shell may use the ordinary execution
|
|
5000
|
+
path; only OS containment is absent. The same local fallback applies when
|
|
5001
|
+
ASRT preparation or backend initialization fails before the target process
|
|
5002
|
+
starts. KodaX never retries after the target has started, so a sandbox fault
|
|
5003
|
+
cannot duplicate command side effects. Remote A2A admitted Skill scripts
|
|
5004
|
+
retain their stronger isolation contract and do not fall back to an
|
|
5005
|
+
unsandboxed script. Embedded and daemon Runtime capability metadata expose
|
|
5006
|
+
`sandboxRuntime` with the platform backend, ASRT version, supported control
|
|
5007
|
+
dimensions, elevation behavior, and fallback semantics.
|
|
5008
|
+
|
|
5009
|
+
Local workspace commands reuse one long-lived ASRT session per canonical
|
|
5010
|
+
workspace. Session-level ACL/WFP initialization is warmed once; the owner
|
|
5011
|
+
coordinates short wrap/cleanup RPCs without locking across the target process
|
|
5012
|
+
lifetime, so concurrent and background targets do not block later preparation.
|
|
5013
|
+
Per-command target attestation and fallback remain independent. Session reset
|
|
5014
|
+
happens only after an idle drain or host-process shutdown, never on the
|
|
5015
|
+
interactive command critical path. A cold first command may still wait for
|
|
5016
|
+
platform initialization, but later commands must not repeatedly pay that
|
|
5017
|
+
setup/reset cost. Abort signals and the command deadline cover that prepare
|
|
5018
|
+
wait; a cancelled/timed-out prepare never starts the target or changes to the
|
|
5019
|
+
ordinary fallback path. Explicit
|
|
5020
|
+
Windows system-temp operations that ASRT cannot safely ACL-manage are not
|
|
5021
|
+
selected for containment and keep the already-approved normal execution path.
|
|
5022
|
+
|
|
5023
|
+
An unhealthy session fails the current prepare immediately so the host can use
|
|
5024
|
+
its normal permission fallback. Cleanup continues out of band. On Windows the
|
|
5025
|
+
owner first closes its command input and allows up to 130 seconds for ASRT
|
|
5026
|
+
0.0.65's two serial ACL cleanup helpers to finish; only then may process-tree
|
|
5027
|
+
termination be forced. The failed workspace session is not replaced until
|
|
5028
|
+
that bounded cleanup settles, preventing a replacement from racing stale ACL
|
|
5029
|
+
recovery. macOS and Linux use the same EOF-first sequence with a shorter
|
|
5030
|
+
bounded termination grace.
|
|
5031
|
+
|
|
5032
|
+
Runtime event streams may also contain one terminal `tool.sandbox` observation
|
|
5033
|
+
associated with the tool ID. `applied` is emitted only after the in-sandbox
|
|
5034
|
+
bootstrap confirms that the real target process reached Node's `spawn` event;
|
|
5035
|
+
wrapper startup alone is not sufficient. Before that handshake, a local
|
|
5036
|
+
backend failure may fall back to normal execution. After it, KodaX never
|
|
5037
|
+
restarts the target:
|
|
5038
|
+
|
|
5039
|
+
```ts
|
|
5040
|
+
runtime.events.subscribe({ sessionId: session.id, type: 'tool.sandbox' }, (event) => {
|
|
5041
|
+
if (event.type !== 'tool.sandbox') return;
|
|
5042
|
+
const { observation } = event.payload.update;
|
|
5043
|
+
// observation.state: 'applied' | 'fallback' | 'not_selected'
|
|
5044
|
+
diagnostics.recordSandboxRoute(observation);
|
|
5045
|
+
});
|
|
5046
|
+
```
|
|
5047
|
+
|
|
5048
|
+
This event is optional diagnostics, not conversation content. It is never added
|
|
5049
|
+
to model-visible messages. Default consumer UX should not render it in startup
|
|
5050
|
+
output, command cards, notifications, or conversation history; expose it only
|
|
5051
|
+
in an explicit advanced diagnostics view. KodaX's own Ink REPL does not
|
|
5052
|
+
subscribe to the event and refreshes human-readable status only when the user
|
|
5053
|
+
runs `/sandbox`. Explicit JSON output and SDK subscriptions retain the
|
|
5054
|
+
structured event for professional diagnostics. `/sandbox` is read-only and
|
|
5055
|
+
never activates the backend or requests elevation.
|
|
5056
|
+
|
|
5057
|
+
---
|
|
5058
|
+
|
|
5059
|
+
## Learned Skill promotion reference (v0.7.78)
|
|
5060
|
+
|
|
5061
|
+
Promotion is the explicit transfer of one immutable, reviewed `ready` or
|
|
5062
|
+
`active_learned` Skill revision into the formal user catalog. It is not the
|
|
5063
|
+
evidence-driven `testing -> active_learned` canary transition. The public named
|
|
5064
|
+
service type is exported from the Runtime SDK:
|
|
5065
|
+
|
|
5066
|
+
```ts
|
|
5067
|
+
import {
|
|
5068
|
+
createKodaXRuntime,
|
|
5069
|
+
type RuntimeLearningService,
|
|
5070
|
+
} from '@kodax-ai/kodax/runtime';
|
|
5071
|
+
|
|
5072
|
+
const runtime = await createKodaXRuntime({
|
|
5073
|
+
requirements: {
|
|
5074
|
+
learningCenter: 1,
|
|
5075
|
+
skillLearningLoop: 1,
|
|
5076
|
+
},
|
|
5077
|
+
});
|
|
5078
|
+
|
|
5079
|
+
const learning: RuntimeLearningService = runtime.learning;
|
|
5080
|
+
const record = await learning.get('normalize-release-notes');
|
|
5081
|
+
|
|
5082
|
+
try {
|
|
5083
|
+
await learning.promote(record.capabilityId, 'user');
|
|
5084
|
+
} finally {
|
|
5085
|
+
await runtime.close();
|
|
5086
|
+
}
|
|
5087
|
+
```
|
|
5088
|
+
|
|
5089
|
+
`name`, `slug`, and exact `capabilityId` are accepted. Exact IDs are preferred
|
|
5090
|
+
when multiple projects expose the same display name or slug. `'user'` is the
|
|
5091
|
+
only supported scope. Daemon clients need the server-issued
|
|
5092
|
+
`learning:control` scope; advertising a client capability does not grant it.
|
|
5093
|
+
Inline, Worker, and daemon facades carry the same v2 learned-record shape and
|
|
5094
|
+
promotion method.
|
|
5095
|
+
|
|
5096
|
+
The Runtime verifies the source is a regular non-symlink file inside the exact
|
|
5097
|
+
project Learned Area and that its content still matches the recorded
|
|
5098
|
+
fingerprint. It then creates the configured user Skill destination—normally
|
|
5099
|
+
`~/.kodax/skills/<slug>/SKILL.md`—with atomic exclusive-publish semantics.
|
|
5100
|
+
Existing identical content is idempotent; the final path appears only after the
|
|
5101
|
+
complete temporary file is synced. Different formal content returns an
|
|
5102
|
+
`action_failed` error and is never overwritten. On success the canonical
|
|
5103
|
+
project record changes to `promoted_user`.
|
|
5104
|
+
|
|
5105
|
+
Terminal users can inspect the same contract with:
|
|
5106
|
+
|
|
5107
|
+
```text
|
|
5108
|
+
/learn promote --help
|
|
5109
|
+
/learn help promote
|
|
5110
|
+
/help learn promote
|
|
5111
|
+
```
|
|
5112
|
+
|
|
5113
|
+
The canonical command is
|
|
5114
|
+
`/learn promote <name|slug|capability-id> --scope user`; omitting the scope is a
|
|
5115
|
+
backward-compatible shorthand for the same user scope. Unknown, duplicate, or
|
|
5116
|
+
unsupported options fail before the Runtime mutation.
|
|
5117
|
+
|
|
5118
|
+
---
|
|
5119
|
+
|
|
4776
5120
|
## See also
|
|
4777
5121
|
|
|
4778
5122
|
- [README.md](../README.md) — end-user CLI quick start
|