dna-sdk 0.1.0
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/LICENSE +21 -0
- package/README.md +58 -0
- package/dist/adapters/embedding/onnx.d.ts +32 -0
- package/dist/adapters/embedding/onnx.js +51 -0
- package/dist/adapters/filesystem/cache.d.ts +16 -0
- package/dist/adapters/filesystem/cache.js +113 -0
- package/dist/adapters/filesystem/index.d.ts +2 -0
- package/dist/adapters/filesystem/index.js +2 -0
- package/dist/adapters/filesystem/source.d.ts +82 -0
- package/dist/adapters/filesystem/source.js +357 -0
- package/dist/adapters/postgres/index.d.ts +2 -0
- package/dist/adapters/postgres/index.js +2 -0
- package/dist/adapters/postgres/migrations.d.ts +14 -0
- package/dist/adapters/postgres/migrations.js +88 -0
- package/dist/adapters/postgres/source.d.ts +172 -0
- package/dist/adapters/postgres/source.js +569 -0
- package/dist/adapters/resolvers/github.d.ts +12 -0
- package/dist/adapters/resolvers/github.js +47 -0
- package/dist/adapters/resolvers/http.d.ts +22 -0
- package/dist/adapters/resolvers/http.js +145 -0
- package/dist/adapters/resolvers/index.d.ts +3 -0
- package/dist/adapters/resolvers/index.js +3 -0
- package/dist/adapters/resolvers/local.d.ts +24 -0
- package/dist/adapters/resolvers/local.js +132 -0
- package/dist/adapters/search/driver.d.ts +45 -0
- package/dist/adapters/search/driver.js +138 -0
- package/dist/adapters/search/migrations.d.ts +26 -0
- package/dist/adapters/search/migrations.js +58 -0
- package/dist/adapters/search/rrf.d.ts +23 -0
- package/dist/adapters/search/rrf.js +42 -0
- package/dist/adapters/search/sqlite-vec.d.ts +66 -0
- package/dist/adapters/search/sqlite-vec.js +294 -0
- package/dist/bootstrap.d.ts +45 -0
- package/dist/bootstrap.js +134 -0
- package/dist/extensions/agentskills/DOCS.md +18 -0
- package/dist/extensions/agentskills.d.ts +28 -0
- package/dist/extensions/agentskills.js +252 -0
- package/dist/extensions/agentsmd/DOCS.md +18 -0
- package/dist/extensions/agentsmd.d.ts +22 -0
- package/dist/extensions/agentsmd.js +170 -0
- package/dist/extensions/audit/kinds/audit-log.kind.yaml +148 -0
- package/dist/extensions/audit.d.ts +25 -0
- package/dist/extensions/audit.js +62 -0
- package/dist/extensions/automation/kinds/automation.kind.yaml +296 -0
- package/dist/extensions/automation/query.d.ts +49 -0
- package/dist/extensions/automation/query.js +77 -0
- package/dist/extensions/automation/write-guards.d.ts +59 -0
- package/dist/extensions/automation/write-guards.js +153 -0
- package/dist/extensions/automation.d.ts +41 -0
- package/dist/extensions/automation.js +54 -0
- package/dist/extensions/collab.d.ts +16 -0
- package/dist/extensions/collab.js +79 -0
- package/dist/extensions/doc/kinds/doc.kind.yaml +118 -0
- package/dist/extensions/doc.d.ts +25 -0
- package/dist/extensions/doc.js +10 -0
- package/dist/extensions/eval/kinds/eval-baseline.kind.yaml +65 -0
- package/dist/extensions/eval/kinds/eval-case.kind.yaml +140 -0
- package/dist/extensions/eval/kinds/eval-run.kind.yaml +134 -0
- package/dist/extensions/eval/kinds/eval-suite.kind.yaml +87 -0
- package/dist/extensions/eval.d.ts +24 -0
- package/dist/extensions/eval.js +31 -0
- package/dist/extensions/evidence/kinds/evidence.kind.yaml +92 -0
- package/dist/extensions/evidence.d.ts +17 -0
- package/dist/extensions/evidence.js +94 -0
- package/dist/extensions/federation.d.ts +22 -0
- package/dist/extensions/federation.js +173 -0
- package/dist/extensions/guardrails/DOCS.md +20 -0
- package/dist/extensions/guardrails.d.ts +31 -0
- package/dist/extensions/guardrails.js +228 -0
- package/dist/extensions/helix/DOCS-Actor.md +20 -0
- package/dist/extensions/helix/DOCS-Agent.md +20 -0
- package/dist/extensions/helix/DOCS-UseCase.md +20 -0
- package/dist/extensions/helix/layers.d.ts +12 -0
- package/dist/extensions/helix/layers.js +18 -0
- package/dist/extensions/helix/write-guards.d.ts +70 -0
- package/dist/extensions/helix/write-guards.js +172 -0
- package/dist/extensions/helix.d.ts +29 -0
- package/dist/extensions/helix.js +963 -0
- package/dist/extensions/helix_extras.d.ts +124 -0
- package/dist/extensions/helix_extras.js +328 -0
- package/dist/extensions/hooks.d.ts +31 -0
- package/dist/extensions/hooks.js +247 -0
- package/dist/extensions/kinddef/DOCS.md +24 -0
- package/dist/extensions/kinddef.d.ts +40 -0
- package/dist/extensions/kinddef.js +171 -0
- package/dist/extensions/lesson.d.ts +6 -0
- package/dist/extensions/lesson.js +194 -0
- package/dist/extensions/modelreg/kinds/model-profile.kind.yaml +155 -0
- package/dist/extensions/modelreg.d.ts +30 -0
- package/dist/extensions/modelreg.js +38 -0
- package/dist/extensions/recognizer.d.ts +34 -0
- package/dist/extensions/recognizer.js +272 -0
- package/dist/extensions/research.d.ts +32 -0
- package/dist/extensions/research.js +292 -0
- package/dist/extensions/safety.d.ts +33 -0
- package/dist/extensions/safety.js +230 -0
- package/dist/extensions/sdlc/kinds/adr.kind.yaml +136 -0
- package/dist/extensions/sdlc/kinds/archive-proposal.kind.yaml +107 -0
- package/dist/extensions/sdlc/kinds/changelog.kind.yaml +108 -0
- package/dist/extensions/sdlc/kinds/cognitive-policy.kind.yaml +470 -0
- package/dist/extensions/sdlc/kinds/forecast.kind.yaml +125 -0
- package/dist/extensions/sdlc/kinds/insight.kind.yaml +87 -0
- package/dist/extensions/sdlc/kinds/kaizen.kind.yaml +106 -0
- package/dist/extensions/sdlc/kinds/lesson-learned.kind.yaml +270 -0
- package/dist/extensions/sdlc/kinds/narrative.kind.yaml +189 -0
- package/dist/extensions/sdlc/kinds/pattern-insight.kind.yaml +204 -0
- package/dist/extensions/sdlc/kinds/postmortem.kind.yaml +168 -0
- package/dist/extensions/sdlc/kinds/pre-mortem.kind.yaml +145 -0
- package/dist/extensions/sdlc/kinds/prompt-template.kind.yaml +109 -0
- package/dist/extensions/sdlc/kinds/retrospective.kind.yaml +186 -0
- package/dist/extensions/sdlc/kinds/risk-register.kind.yaml +178 -0
- package/dist/extensions/sdlc/kinds/saved-view.kind.yaml +127 -0
- package/dist/extensions/sdlc/kinds/status-report.kind.yaml +129 -0
- package/dist/extensions/sdlc/kinds/synthesis-run.kind.yaml +279 -0
- package/dist/extensions/sdlc/kinds/synthesizer-state.kind.yaml +196 -0
- package/dist/extensions/sdlc/kinds/workflow-event.kind.yaml +195 -0
- package/dist/extensions/sdlc.d.ts +32 -0
- package/dist/extensions/sdlc.js +1318 -0
- package/dist/extensions/soulspec/DOCS.md +19 -0
- package/dist/extensions/soulspec.d.ts +22 -0
- package/dist/extensions/soulspec.js +287 -0
- package/dist/extensions/tenant.d.ts +6 -0
- package/dist/extensions/tenant.js +291 -0
- package/dist/extensions/testkit.d.ts +24 -0
- package/dist/extensions/testkit.js +211 -0
- package/dist/index.d.ts +80 -0
- package/dist/index.js +102 -0
- package/dist/kernel/_text.d.ts +28 -0
- package/dist/kernel/_text.js +42 -0
- package/dist/kernel/bundle-handle.d.ts +83 -0
- package/dist/kernel/bundle-handle.js +184 -0
- package/dist/kernel/capabilities.d.ts +157 -0
- package/dist/kernel/capabilities.js +109 -0
- package/dist/kernel/collaborator-ports.d.ts +91 -0
- package/dist/kernel/collaborator-ports.js +1 -0
- package/dist/kernel/composition-resolver.d.ts +215 -0
- package/dist/kernel/composition-resolver.js +558 -0
- package/dist/kernel/composition.d.ts +10 -0
- package/dist/kernel/composition.js +1 -0
- package/dist/kernel/descriptor-loader.d.ts +13 -0
- package/dist/kernel/descriptor-loader.js +48 -0
- package/dist/kernel/document.d.ts +43 -0
- package/dist/kernel/document.js +71 -0
- package/dist/kernel/embedding.d.ts +28 -0
- package/dist/kernel/embedding.js +78 -0
- package/dist/kernel/errors.d.ts +62 -0
- package/dist/kernel/errors.js +82 -0
- package/dist/kernel/events.d.ts +6 -0
- package/dist/kernel/events.js +21 -0
- package/dist/kernel/evidence-capture.d.ts +69 -0
- package/dist/kernel/evidence-capture.js +138 -0
- package/dist/kernel/fs.d.ts +20 -0
- package/dist/kernel/fs.js +128 -0
- package/dist/kernel/generic-rw.d.ts +33 -0
- package/dist/kernel/generic-rw.js +235 -0
- package/dist/kernel/hooks.d.ts +172 -0
- package/dist/kernel/hooks.js +256 -0
- package/dist/kernel/index.d.ts +624 -0
- package/dist/kernel/index.js +1638 -0
- package/dist/kernel/instance.d.ts +211 -0
- package/dist/kernel/instance.js +487 -0
- package/dist/kernel/kind-registry.d.ts +183 -0
- package/dist/kernel/kind-registry.js +710 -0
- package/dist/kernel/kind_base.d.ts +106 -0
- package/dist/kernel/kind_base.js +244 -0
- package/dist/kernel/layer-resolver.d.ts +48 -0
- package/dist/kernel/layer-resolver.js +284 -0
- package/dist/kernel/lock-manager.d.ts +21 -0
- package/dist/kernel/lock-manager.js +43 -0
- package/dist/kernel/lock.d.ts +38 -0
- package/dist/kernel/lock.js +115 -0
- package/dist/kernel/meta.d.ts +135 -0
- package/dist/kernel/meta.js +817 -0
- package/dist/kernel/models.d.ts +3089 -0
- package/dist/kernel/models.js +764 -0
- package/dist/kernel/navigator.d.ts +36 -0
- package/dist/kernel/navigator.js +132 -0
- package/dist/kernel/port-surface.d.ts +33 -0
- package/dist/kernel/port-surface.js +180 -0
- package/dist/kernel/preview.d.ts +60 -0
- package/dist/kernel/preview.js +54 -0
- package/dist/kernel/prompt-budget.d.ts +39 -0
- package/dist/kernel/prompt-budget.js +43 -0
- package/dist/kernel/prompt-builder.d.ts +25 -0
- package/dist/kernel/prompt-builder.js +237 -0
- package/dist/kernel/protocols.d.ts +751 -0
- package/dist/kernel/protocols.js +493 -0
- package/dist/kernel/reports.d.ts +26 -0
- package/dist/kernel/reports.js +215 -0
- package/dist/kernel/resolver.d.ts +146 -0
- package/dist/kernel/resolver.js +232 -0
- package/dist/kernel/resource.d.ts +57 -0
- package/dist/kernel/resource.js +97 -0
- package/dist/kernel/runtime.d.ts +16 -0
- package/dist/kernel/runtime.js +18 -0
- package/dist/kernel/safety-scanner.d.ts +38 -0
- package/dist/kernel/safety-scanner.js +228 -0
- package/dist/kernel/serialize-to-files.d.ts +29 -0
- package/dist/kernel/serialize-to-files.js +23 -0
- package/dist/kernel/spec-access.d.ts +23 -0
- package/dist/kernel/spec-access.js +40 -0
- package/dist/kernel/studio_ui.d.ts +88 -0
- package/dist/kernel/studio_ui.js +135 -0
- package/dist/kernel/templates.d.ts +77 -0
- package/dist/kernel/templates.js +116 -0
- package/dist/kernel/tool-registry.d.ts +52 -0
- package/dist/kernel/tool-registry.js +89 -0
- package/dist/kernel/write-pipeline.d.ts +65 -0
- package/dist/kernel/write-pipeline.js +271 -0
- package/dist/kernel/writer-helpers.d.ts +24 -0
- package/dist/kernel/writer-helpers.js +42 -0
- package/dist/memory/decay.d.ts +31 -0
- package/dist/memory/decay.js +97 -0
- package/dist/memory/ecphory.d.ts +25 -0
- package/dist/memory/ecphory.js +178 -0
- package/dist/memory/encodingContext.d.ts +21 -0
- package/dist/memory/encodingContext.js +62 -0
- package/dist/memory/index.d.ts +23 -0
- package/dist/memory/index.js +23 -0
- package/dist/memory/memoryType.d.ts +7 -0
- package/dist/memory/memoryType.js +24 -0
- package/dist/memory/policy.d.ts +35 -0
- package/dist/memory/policy.js +35 -0
- package/dist/memory/retrieval.d.ts +21 -0
- package/dist/memory/retrieval.js +145 -0
- package/dist/testing/index.d.ts +8 -0
- package/dist/testing/index.js +8 -0
- package/dist/testing/recordSearchConformance.d.ts +43 -0
- package/dist/testing/recordSearchConformance.js +147 -0
- package/dist/viz/ascii.d.ts +7 -0
- package/dist/viz/ascii.js +60 -0
- package/dist/viz/health.d.ts +8 -0
- package/dist/viz/health.js +161 -0
- package/dist/viz/index.d.ts +10 -0
- package/dist/viz/index.js +10 -0
- package/dist/viz/matrix.d.ts +8 -0
- package/dist/viz/matrix.js +84 -0
- package/dist/viz/mermaid.d.ts +38 -0
- package/dist/viz/mermaid.js +706 -0
- package/package.json +82 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helix-owned write-path guards (s-write-path-despecialize).
|
|
3
|
+
*
|
|
4
|
+
* These rules used to live inline in `Kernel.writeDocument` as
|
|
5
|
+
* `kind === "Agent"` special-cases — extension domain knowledge
|
|
6
|
+
* leaked into the microkernel. They are now `pre_save` VETO hooks
|
|
7
|
+
* registered by `HelixExtension.register` (the Agent owner):
|
|
8
|
+
*
|
|
9
|
+
* - platform-agent fork guard (priority 10) — no per-tenant overlay of a
|
|
10
|
+
* `_lib` Agent (JARVIS 16384 outage, 2026-05-29).
|
|
11
|
+
* - prompt-budget enforcement (priority 20) — an Agent whose instruction
|
|
12
|
+
* exceeds its model's `instruction_token_cap` (read from the
|
|
13
|
+
* ModelProfile registry — never hardcode token caps) is blocked when
|
|
14
|
+
* the model is strict (voice persona / `realtime: true` profile) and
|
|
15
|
+
* warned when it is a chat model (fail-open on unknown model / missing
|
|
16
|
+
* cap / instruction_file).
|
|
17
|
+
* - Kind-Writer contract (priority 30) — a Agent declaring
|
|
18
|
+
* `writes_kind` must satisfy the slot↔schema contract at write time.
|
|
19
|
+
*
|
|
20
|
+
* A throw from a guard vetoes the write (nothing is persisted). The hooks
|
|
21
|
+
* fire for EVERY `kernel.writeDocument` regardless of `skipHooks` — they
|
|
22
|
+
* are integrity gates, not notifications.
|
|
23
|
+
*
|
|
24
|
+
* 1:1 parity with Python dna.extensions.helix.write_guards.
|
|
25
|
+
*/
|
|
26
|
+
import { TenantNotAllowed } from "../../kernel/protocols.js";
|
|
27
|
+
import { DEFAULT_BASE_SCOPE } from "../../kernel/index.js";
|
|
28
|
+
import { evaluateInstructionBudget, PromptBudgetExceededError, } from "../../kernel/prompt-budget.js";
|
|
29
|
+
const KIND = "Agent";
|
|
30
|
+
// Ordered ahead of other extensions' guards (Py: SDLC bitemporal = 40).
|
|
31
|
+
export const PRIORITY_FORK_GUARD = 10;
|
|
32
|
+
export const PRIORITY_PROMPT_BUDGET = 20;
|
|
33
|
+
export const PRIORITY_KIND_WRITER = 30;
|
|
34
|
+
/**
|
|
35
|
+
* Block per-tenant overlays of `_lib` Agents.
|
|
36
|
+
*
|
|
37
|
+
* The `_lib` scope is the shared baseline (jarvis + the 12 transversais);
|
|
38
|
+
* its Agents are edited in git + `dna doc apply --scope _lib` (base
|
|
39
|
+
* only). A per-tenant overlay silently FORKS the persona and shadows the
|
|
40
|
+
* base for that tenant's reads — the root cause of the JARVIS 16384 outage
|
|
41
|
+
* (2026-05-29) and the stale-persona bug (2026-06-14). Veto it loudly.
|
|
42
|
+
*/
|
|
43
|
+
export function platformAgentForkGuard(ctx) {
|
|
44
|
+
if (ctx.scope === DEFAULT_BASE_SCOPE && ctx.kind === KIND && ctx.tenant) {
|
|
45
|
+
throw new TenantNotAllowed(`refusing a per-tenant overlay of the _lib agent ${JSON.stringify(ctx.name)} ` +
|
|
46
|
+
`(tenant=${JSON.stringify(ctx.tenant)}). _lib agents are base-only — ` +
|
|
47
|
+
`edit in git + \`dna doc apply --scope _lib\`. A tenant fork shadows the ` +
|
|
48
|
+
`base persona for that tenant (JARVIS 16384 outage).`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Enforce the Agent instruction budget against the ModelProfile registry.
|
|
53
|
+
*
|
|
54
|
+
* CONTRACT — never hardcode token caps: the cap ALWAYS comes from the
|
|
55
|
+
* ModelProfile registry (`kernel.modelProfile(idOrAlias)` → the
|
|
56
|
+
* `modelreg-model-profile` Kind in `_lib`), never from a literal in code.
|
|
57
|
+
*
|
|
58
|
+
* Three paths (s-tier-a-modelprofile):
|
|
59
|
+
* - VETO — strict model (voice persona, or `realtime: true` profile) and
|
|
60
|
+
* the instruction estimate exceeds `instruction_token_cap`.
|
|
61
|
+
* - WARN — a chat Agent (`spec.model` declared, non-realtime profile)
|
|
62
|
+
* exceeds the cap: tolerated but logged loud.
|
|
63
|
+
* - PASS — no model declared, no profile found, no cap, or within budget.
|
|
64
|
+
* Enforcement is opt-in by DATA: writing a profile with a cap arms it.
|
|
65
|
+
*
|
|
66
|
+
* Fail-open on uncounted text (instruction_file / non-string body).
|
|
67
|
+
* `DNA_PROMPT_BUDGET_ENFORCE=0` downgrades the veto to a warn.
|
|
68
|
+
*
|
|
69
|
+
* 1:1 parity with Python `prompt_budget_guard`.
|
|
70
|
+
*/
|
|
71
|
+
export async function promptBudgetGuard(ctx) {
|
|
72
|
+
if (ctx.kind !== KIND || !ctx.raw || typeof ctx.raw !== "object")
|
|
73
|
+
return;
|
|
74
|
+
const spec = ctx.raw.spec;
|
|
75
|
+
if (!spec || typeof spec !== "object")
|
|
76
|
+
return;
|
|
77
|
+
const s = spec;
|
|
78
|
+
const vp = s.voice_persona;
|
|
79
|
+
const isVoice = vp !== undefined && vp !== null;
|
|
80
|
+
const kernel = ctx.kernel;
|
|
81
|
+
let modelId;
|
|
82
|
+
if (isVoice) {
|
|
83
|
+
const vpModel = vp && typeof vp === "object"
|
|
84
|
+
? vp.model
|
|
85
|
+
: null;
|
|
86
|
+
// s-realtime-model-single-default — the kernel getter reads
|
|
87
|
+
// DNA_VOICE_REALTIME_MODEL at access-time so the cap and the minted
|
|
88
|
+
// voice session can't drift to different realtime models.
|
|
89
|
+
modelId =
|
|
90
|
+
(typeof vpModel === "string" && vpModel) || kernel._DEFAULT_REALTIME_MODEL;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
const declared = s.model;
|
|
94
|
+
if (!declared || typeof declared !== "string") {
|
|
95
|
+
return; // PASS — no model declared, nothing to enforce against.
|
|
96
|
+
}
|
|
97
|
+
modelId = declared;
|
|
98
|
+
}
|
|
99
|
+
const profile = await kernel.modelProfile(modelId);
|
|
100
|
+
let instruction = typeof s.instruction === "string" ? s.instruction : "";
|
|
101
|
+
// v1 limitation: no cheap kernel helper resolves instruction_file here;
|
|
102
|
+
// if the body lives in a file, warn + fail-open (don't block on
|
|
103
|
+
// uncounted text).
|
|
104
|
+
if (!instruction && s.instruction_file) {
|
|
105
|
+
console.warn(`[prompt-budget] agent '${ctx.name}' uses instruction_file; ` +
|
|
106
|
+
`token budget NOT checked (v1 limitation)`);
|
|
107
|
+
}
|
|
108
|
+
const cap = (profile?.spec ?? {})["instruction_token_cap"];
|
|
109
|
+
if (profile === null || typeof cap !== "number" || !instruction) {
|
|
110
|
+
// PASS — enforcement is opt-in: no profile / no cap / uncounted text
|
|
111
|
+
// never blocks. Voice stays LOUD (the outage class this guard exists
|
|
112
|
+
// for); a chat model without a profile is the common case and stays
|
|
113
|
+
// quiet.
|
|
114
|
+
if (isVoice) {
|
|
115
|
+
console.warn(`[prompt-budget] no ModelProfile/cap for model '${modelId}' ` +
|
|
116
|
+
`(agent '${ctx.name}'); cap not enforced`);
|
|
117
|
+
}
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const verdict = evaluateInstructionBudget(instruction, { cap });
|
|
121
|
+
if (!verdict.exceeded)
|
|
122
|
+
return; // PASS — within budget.
|
|
123
|
+
const strict = isVoice || Boolean((profile.spec ?? {})["realtime"]);
|
|
124
|
+
if (strict && process.env.DNA_PROMPT_BUDGET_ENFORCE !== "0") {
|
|
125
|
+
throw new PromptBudgetExceededError({
|
|
126
|
+
modelId,
|
|
127
|
+
estimatedTokens: verdict.estimatedTokens,
|
|
128
|
+
cap,
|
|
129
|
+
agentName: ctx.name,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
// WARN — chat model over budget, or strict veto downgraded by the
|
|
133
|
+
// kill-switch. Loud either way: the cap came from the ModelProfile
|
|
134
|
+
// registry, the fix is trimming the instruction (or updating the
|
|
135
|
+
// profile if the model's real cap changed — never a hardcoded number).
|
|
136
|
+
console.warn(`[prompt-budget] agent '${ctx.name}' instruction is ~` +
|
|
137
|
+
`${verdict.estimatedTokens} tokens, over the ${cap}-token ` +
|
|
138
|
+
`instruction_token_cap of model '${modelId}' (ModelProfile registry)` +
|
|
139
|
+
(strict ? " — VETO downgraded to WARN (DNA_PROMPT_BUDGET_ENFORCE=0)" : "") +
|
|
140
|
+
`. Trim the instruction or move detail to tool-discoverable docs.`);
|
|
141
|
+
}
|
|
142
|
+
export function kindWriterContractGuard(ctx) {
|
|
143
|
+
if (ctx.kind !== KIND || !ctx.raw || typeof ctx.raw !== "object")
|
|
144
|
+
return;
|
|
145
|
+
const spec = ctx.raw.spec;
|
|
146
|
+
if (spec &&
|
|
147
|
+
typeof spec === "object" &&
|
|
148
|
+
(spec.writes_kind ||
|
|
149
|
+
spec.writes_kinds)) {
|
|
150
|
+
// The contract logic is generic (validates against the Kind registry)
|
|
151
|
+
// so it stays a kernel helper; the TRIGGER is Helix-owned.
|
|
152
|
+
ctx.kernel._validateKindWriter(spec);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Wire the Helix write guards as `pre_save` veto hooks. Keys make the
|
|
157
|
+
* registration idempotent (re-loading the extension onto a shared
|
|
158
|
+
* HookRegistry replaces instead of stacking duplicates). Takes the
|
|
159
|
+
* `ExtensionHost` slice (s-dna-extension-host-contract) — registration
|
|
160
|
+
* goes through `kernel.hooks.onVeto` for the `key` idempotency.
|
|
161
|
+
*/
|
|
162
|
+
export function registerWriteGuards(kernel) {
|
|
163
|
+
kernel.hooks.onVeto("pre_save", platformAgentForkGuard, {
|
|
164
|
+
priority: PRIORITY_FORK_GUARD, key: "helix.platform-agent-fork-guard",
|
|
165
|
+
});
|
|
166
|
+
kernel.hooks.onVeto("pre_save", promptBudgetGuard, {
|
|
167
|
+
priority: PRIORITY_PROMPT_BUDGET, key: "helix.prompt-budget",
|
|
168
|
+
});
|
|
169
|
+
kernel.hooks.onVeto("pre_save", kindWriterContractGuard, {
|
|
170
|
+
priority: PRIORITY_KIND_WRITER, key: "helix.kind-writer-contract",
|
|
171
|
+
});
|
|
172
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HelixExtension — Module, Agent, Actor kinds.
|
|
3
|
+
*
|
|
4
|
+
* 1:1 parity with Python dna.v3.extensions.helix.
|
|
5
|
+
*/
|
|
6
|
+
import type { BundleHandle } from "../kernel/bundle-handle.js";
|
|
7
|
+
import type { FSLike } from "../kernel/fs.js";
|
|
8
|
+
import type { Extension, ExtensionHost, ReaderPort, SerializedFile, WriterPort } from "../kernel/protocols.js";
|
|
9
|
+
export declare class AgentReader implements ReaderPort {
|
|
10
|
+
private fs;
|
|
11
|
+
constructor(fs?: FSLike);
|
|
12
|
+
detect(bundle: BundleHandle): boolean;
|
|
13
|
+
read(bundle: BundleHandle): Record<string, unknown>;
|
|
14
|
+
private _parseFrontmatter;
|
|
15
|
+
}
|
|
16
|
+
export declare class AgentWriter implements WriterPort {
|
|
17
|
+
private fs;
|
|
18
|
+
constructor(fs?: FSLike);
|
|
19
|
+
canWrite(raw: Record<string, unknown>): boolean;
|
|
20
|
+
write(bundle: BundleHandle, raw: Record<string, unknown>): void;
|
|
21
|
+
serialize(raw: Record<string, unknown>): SerializedFile[];
|
|
22
|
+
}
|
|
23
|
+
export declare class HelixExtension implements Extension {
|
|
24
|
+
private fs;
|
|
25
|
+
readonly name = "helix";
|
|
26
|
+
readonly version = "1.0.0";
|
|
27
|
+
constructor(fs?: FSLike);
|
|
28
|
+
register(kernel: ExtensionHost): void;
|
|
29
|
+
}
|