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,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FederationExtension — Phase 14r MCP Federation (schema v2, 2026-07-07).
|
|
3
|
+
*
|
|
4
|
+
* Declares the `MCPFederation` Kind: an external MCP server whose tools
|
|
5
|
+
* DNA agents consume via `Agent.spec.mcp_servers` (primary,
|
|
6
|
+
* s-mcp-servers-on-agent) or via the DNA-as-MCP-server proxy
|
|
7
|
+
* (legacy Phase 14r direction). Transports: stdio | streamable_http.
|
|
8
|
+
* Auth carries env-var NAMES only — never secret values.
|
|
9
|
+
*
|
|
10
|
+
* Schema v2 is fully backward-compatible with v1 docs: `transport`
|
|
11
|
+
* defaults to `stdio` and every new field is optional.
|
|
12
|
+
*
|
|
13
|
+
* 1:1 parity with python/dna/extensions/federation/__init__.py.
|
|
14
|
+
* The TS SDK ships schema/Kind parity only — the agent runtime (and the
|
|
15
|
+
* MCP client) is Python-only by design (spec §3).
|
|
16
|
+
*/
|
|
17
|
+
import { KindBase } from "../kernel/kind_base.js";
|
|
18
|
+
import { SD } from "../kernel/protocols.js";
|
|
19
|
+
const API_VERSION = "github.com/ruinosus/dna/federation/v1";
|
|
20
|
+
class MCPFederationKind extends KindBase {
|
|
21
|
+
apiVersion = API_VERSION;
|
|
22
|
+
kind = "MCPFederation";
|
|
23
|
+
alias = "federation-mcp";
|
|
24
|
+
origin = "github.com/ruinosus/dna/federation";
|
|
25
|
+
isPromptTarget = false;
|
|
26
|
+
promptTargetPriority = 0;
|
|
27
|
+
flattenInContext = false;
|
|
28
|
+
storage = SD.yaml("federations");
|
|
29
|
+
graphStyle = { fill: "#F97316", stroke: "#EA580C", textColor: "#fff" };
|
|
30
|
+
asciiIcon = "🛰️";
|
|
31
|
+
displayLabel = "MCP Federations";
|
|
32
|
+
docs = "An MCPFederation declares an external MCP server whose tools DNA " +
|
|
33
|
+
"agents consume: a Agent lists the doc's name in " +
|
|
34
|
+
"spec.mcp_servers and the harness loads the remote tools as " +
|
|
35
|
+
"first-class agent tools (zero code, zero deploy). Transports: " +
|
|
36
|
+
"stdio (command/args/env/cwd) or streamable_http (url). Auth " +
|
|
37
|
+
"carries env-var NAMES only — never secret values. allowed_tools " +
|
|
38
|
+
"bounds what any agent can get; enabled: false is the declarative " +
|
|
39
|
+
"kill-switch. Docs in _lib/federations/ are inherited by every " +
|
|
40
|
+
"scope. Also consumed by the DNA-as-MCP-server proxy (Phase 14r).";
|
|
41
|
+
dependencies() { return null; }
|
|
42
|
+
schema() {
|
|
43
|
+
// v2 (spec 2026-07-07-mcp-first-tools-design.md §5.1). Back-compat:
|
|
44
|
+
// every v1 doc (required command, stdio implied) stays valid —
|
|
45
|
+
// transport defaults to stdio and command is enforced for stdio
|
|
46
|
+
// (resp. url for streamable_http) via allOf/if-then instead of a
|
|
47
|
+
// top-level required: [command].
|
|
48
|
+
return {
|
|
49
|
+
type: "object",
|
|
50
|
+
additionalProperties: true,
|
|
51
|
+
properties: {
|
|
52
|
+
transport: {
|
|
53
|
+
type: "string",
|
|
54
|
+
enum: ["stdio", "streamable_http"],
|
|
55
|
+
default: "stdio",
|
|
56
|
+
description: "How to reach the server: stdio subprocess (default, v1) or Streamable HTTP.",
|
|
57
|
+
},
|
|
58
|
+
url: {
|
|
59
|
+
type: "string",
|
|
60
|
+
description: "Server endpoint. Required when transport=streamable_http.",
|
|
61
|
+
},
|
|
62
|
+
command: {
|
|
63
|
+
type: "string",
|
|
64
|
+
description: "Executable to run (resolved via PATH). Required when transport=stdio.",
|
|
65
|
+
},
|
|
66
|
+
args: { type: "array", items: { type: "string" }, default: [] },
|
|
67
|
+
env: {
|
|
68
|
+
type: "object",
|
|
69
|
+
additionalProperties: { type: "string" },
|
|
70
|
+
default: {},
|
|
71
|
+
description: "Extra env vars merged onto os.environ for the subprocess.",
|
|
72
|
+
},
|
|
73
|
+
cwd: {
|
|
74
|
+
type: ["string", "null"],
|
|
75
|
+
description: "Working directory; null = scope dir.",
|
|
76
|
+
},
|
|
77
|
+
tool_prefix: {
|
|
78
|
+
type: "string",
|
|
79
|
+
description: "Prepended to every proxied tool name (e.g. 'graphify_').",
|
|
80
|
+
default: "",
|
|
81
|
+
},
|
|
82
|
+
enabled: {
|
|
83
|
+
type: "boolean",
|
|
84
|
+
default: true,
|
|
85
|
+
description: "Disable without deleting the doc — declarative kill-switch, no deploy.",
|
|
86
|
+
},
|
|
87
|
+
allowed_tools: {
|
|
88
|
+
type: "array",
|
|
89
|
+
items: { type: "string" },
|
|
90
|
+
default: [],
|
|
91
|
+
description: "Server-level allowlist of remote tool names (pre-prefix). Empty = all.",
|
|
92
|
+
},
|
|
93
|
+
timeout_s: {
|
|
94
|
+
type: "integer",
|
|
95
|
+
default: 30,
|
|
96
|
+
description: "Per-call timeout default (seconds). Per-agent entry may override.",
|
|
97
|
+
},
|
|
98
|
+
auth: {
|
|
99
|
+
type: "object",
|
|
100
|
+
additionalProperties: false,
|
|
101
|
+
description: "Auth by env-var NAME — the value is read from the process env at connect time and never stored in docs, logs, or events.",
|
|
102
|
+
properties: {
|
|
103
|
+
kind: {
|
|
104
|
+
type: "string",
|
|
105
|
+
enum: ["none", "bearer_env", "header_env"],
|
|
106
|
+
default: "none",
|
|
107
|
+
},
|
|
108
|
+
env: {
|
|
109
|
+
type: "string",
|
|
110
|
+
description: "Name of the env var holding the secret value.",
|
|
111
|
+
},
|
|
112
|
+
header: {
|
|
113
|
+
type: "string",
|
|
114
|
+
description: "Header to carry the value (header_env only; bearer_env implies Authorization: Bearer).",
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
propagate_tenant: {
|
|
119
|
+
type: "boolean",
|
|
120
|
+
default: true,
|
|
121
|
+
description: "HTTP transport: stamp X-DNA-Tenant-Effective / X-DNA-Scope / X-DNA-Agent headers.",
|
|
122
|
+
},
|
|
123
|
+
health_check: {
|
|
124
|
+
type: "object",
|
|
125
|
+
additionalProperties: true,
|
|
126
|
+
properties: {
|
|
127
|
+
interval_s: { type: "integer", default: 30 },
|
|
128
|
+
timeout_s: { type: "integer", default: 5 },
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
tags: { type: "array", items: { type: "string" }, default: [] },
|
|
132
|
+
},
|
|
133
|
+
allOf: [
|
|
134
|
+
{
|
|
135
|
+
// NOTE: required: [transport] inside the `if` is load-bearing —
|
|
136
|
+
// without it an absent `transport` matches the const vacuously
|
|
137
|
+
// and v1 docs would be forced to carry `url`.
|
|
138
|
+
if: {
|
|
139
|
+
properties: { transport: { const: "streamable_http" } },
|
|
140
|
+
required: ["transport"],
|
|
141
|
+
},
|
|
142
|
+
then: { required: ["url"] },
|
|
143
|
+
else: { required: ["command"] },
|
|
144
|
+
},
|
|
145
|
+
],
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
describe(doc) {
|
|
149
|
+
const spec = (doc.spec ?? {});
|
|
150
|
+
const transport = spec.transport || "stdio";
|
|
151
|
+
const target = (transport === "streamable_http" ? spec.url : spec.command) ?? "?";
|
|
152
|
+
const prefix = spec.tool_prefix ?? "";
|
|
153
|
+
return `${target || "?"} (${prefix || "no-prefix"})`;
|
|
154
|
+
}
|
|
155
|
+
summary(doc) {
|
|
156
|
+
const spec = (doc.spec ?? {});
|
|
157
|
+
return {
|
|
158
|
+
transport: spec.transport || "stdio",
|
|
159
|
+
url: spec.url ?? "",
|
|
160
|
+
command: spec.command ?? "",
|
|
161
|
+
tool_prefix: spec.tool_prefix ?? "",
|
|
162
|
+
enabled: spec.enabled ?? true,
|
|
163
|
+
tags: spec.tags ?? [],
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
export class FederationExtension {
|
|
168
|
+
name = "federation";
|
|
169
|
+
version = "1.0.0";
|
|
170
|
+
register(kernel) {
|
|
171
|
+
kernel.kind(new MCPFederationKind());
|
|
172
|
+
}
|
|
173
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Guardrail
|
|
2
|
+
|
|
3
|
+
A Guardrail declares a hard safety, compliance, or policy rule that must be
|
|
4
|
+
enforced on every turn of an agent's conversation. It is stored as a bundle
|
|
5
|
+
rooted on a `GUARDRAIL.md` marker file.
|
|
6
|
+
|
|
7
|
+
Unlike Skills (which are on-demand procedural know-how), Guardrails are
|
|
8
|
+
flattened directly into the agent's system prompt so the rules are always in
|
|
9
|
+
view. Each Guardrail carries a `severity` (`low`, `medium`, `high`, `critical`)
|
|
10
|
+
and a list of `rules` that the Agent template renders inline.
|
|
11
|
+
|
|
12
|
+
**Helix-native kind — not guardrails.ai.** This is not a binding for the
|
|
13
|
+
`guardrails.ai` runtime validator library. It is inspired by the tripwire /
|
|
14
|
+
input-output guardrail pattern from the OpenAI Agents SDK
|
|
15
|
+
(https://openai.github.io/openai-agents-python/guardrails/) but implemented
|
|
16
|
+
natively as a composable document kind. No external runtime is required;
|
|
17
|
+
enforcement is purely prompt-level.
|
|
18
|
+
|
|
19
|
+
**Composition:** referenced by Agents via `dep_filters.guardrails`
|
|
20
|
+
(alias `guardrails-guardrail`).
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GuardrailExtension — Guardrail kind + GuardrailReader + GuardrailWriter.
|
|
3
|
+
*
|
|
4
|
+
* 1:1 parity with Python dna.v3.extensions.guardrails.
|
|
5
|
+
*/
|
|
6
|
+
import type { BundleHandle } from "../kernel/bundle-handle.js";
|
|
7
|
+
import type { FSLike } from "../kernel/fs.js";
|
|
8
|
+
import type { ExtensionHost, Extension, ReaderPort, SerializedFile, WriterPort } from "../kernel/protocols.js";
|
|
9
|
+
export declare class GuardrailReader implements ReaderPort {
|
|
10
|
+
private fs;
|
|
11
|
+
constructor(fs?: FSLike);
|
|
12
|
+
detect(bundle: BundleHandle): boolean;
|
|
13
|
+
read(bundle: BundleHandle): Record<string, unknown>;
|
|
14
|
+
}
|
|
15
|
+
export declare class GuardrailWriter implements WriterPort {
|
|
16
|
+
private fs;
|
|
17
|
+
constructor(fs?: FSLike);
|
|
18
|
+
canWrite(raw: Record<string, unknown>): boolean;
|
|
19
|
+
/** Shared by write()/serialize() so the two surfaces cannot drift
|
|
20
|
+
* (s-dna-rw-roundtrip-suite). */
|
|
21
|
+
private entries;
|
|
22
|
+
serialize(raw: Record<string, unknown>): SerializedFile[];
|
|
23
|
+
write(bundle: BundleHandle, raw: Record<string, unknown>): void;
|
|
24
|
+
}
|
|
25
|
+
export declare class GuardrailExtension implements Extension {
|
|
26
|
+
private fs;
|
|
27
|
+
readonly name = "guardrails";
|
|
28
|
+
readonly version = "1.0.0";
|
|
29
|
+
constructor(fs?: FSLike);
|
|
30
|
+
register(kernel: ExtensionHost): void;
|
|
31
|
+
}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GuardrailExtension — Guardrail kind + GuardrailReader + GuardrailWriter.
|
|
3
|
+
*
|
|
4
|
+
* 1:1 parity with Python dna.v3.extensions.guardrails.
|
|
5
|
+
*/
|
|
6
|
+
import yaml from "js-yaml";
|
|
7
|
+
import { nodeFS } from "../kernel/fs.js";
|
|
8
|
+
import { KindBase } from "../kernel/kind_base.js";
|
|
9
|
+
import { GuardrailSchema, GuardrailSpecSchema, zodSpecToJsonSchema } from "../kernel/models.js";
|
|
10
|
+
import { SD } from "../kernel/protocols.js";
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// GuardrailKind
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
class GuardrailKind extends KindBase {
|
|
15
|
+
apiVersion = "github.com/ruinosus/dna/v1";
|
|
16
|
+
kind = "Guardrail";
|
|
17
|
+
alias = "guardrails-guardrail";
|
|
18
|
+
isSchemaAffecting = true;
|
|
19
|
+
origin = "github.com/ruinosus/dna/guardrails";
|
|
20
|
+
isPromptTarget = false;
|
|
21
|
+
promptTargetPriority = 0;
|
|
22
|
+
flattenInContext = false;
|
|
23
|
+
descriptionFallbackField = "instruction";
|
|
24
|
+
storage = SD.bundle("guardrails", "GUARDRAIL.md", "list", "rules");
|
|
25
|
+
graphStyle = { fill: "#EF4444", stroke: "#DC2626", textColor: "#fff" };
|
|
26
|
+
asciiIcon = "🛡️";
|
|
27
|
+
displayLabel = "Guardrails";
|
|
28
|
+
_sourceUrl = import.meta.url;
|
|
29
|
+
docs = "A Guardrail declares a hard safety, compliance, or policy rule " +
|
|
30
|
+
"enforced on every agent turn. Stored as a bundle rooted on " +
|
|
31
|
+
"GUARDRAIL.md. Flattened directly into the system prompt — helix- " +
|
|
32
|
+
"native, inspired by OpenAI Agents SDK tripwires, not guardrails.ai.";
|
|
33
|
+
uiSchema = {
|
|
34
|
+
instruction: {
|
|
35
|
+
widget: "markdown",
|
|
36
|
+
label: "GUARDRAIL.md",
|
|
37
|
+
help: "Prose body explaining the intent behind the rule set.",
|
|
38
|
+
height: 280,
|
|
39
|
+
order: 10,
|
|
40
|
+
},
|
|
41
|
+
rules: {
|
|
42
|
+
widget: "list-markdown",
|
|
43
|
+
label: "Rules",
|
|
44
|
+
help: "Individual directives the agent must follow every turn.",
|
|
45
|
+
order: 20,
|
|
46
|
+
},
|
|
47
|
+
severity: {
|
|
48
|
+
widget: "select",
|
|
49
|
+
label: "Severity",
|
|
50
|
+
help: "warn lets the turn continue; error fails the turn; hard refuses to answer.",
|
|
51
|
+
order: 30,
|
|
52
|
+
},
|
|
53
|
+
scope: {
|
|
54
|
+
widget: "select",
|
|
55
|
+
label: "Scope",
|
|
56
|
+
help: "input guards the user prompt; output guards the agent response; both runs on each side.",
|
|
57
|
+
order: 40,
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
schema() { return zodSpecToJsonSchema(GuardrailSpecSchema); }
|
|
61
|
+
parse(raw) {
|
|
62
|
+
return GuardrailSchema.parse(raw);
|
|
63
|
+
}
|
|
64
|
+
summary(doc) {
|
|
65
|
+
const spec = (doc.spec ?? {});
|
|
66
|
+
return {
|
|
67
|
+
severity: typeof spec.severity === "string" ? spec.severity : "warn",
|
|
68
|
+
scope: typeof spec.scope === "string" ? spec.scope : "both",
|
|
69
|
+
rules: Array.isArray(spec.rules) ? spec.rules.length : 0,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
preview(doc) {
|
|
73
|
+
const spec = (doc.spec ?? {});
|
|
74
|
+
const blocks = [];
|
|
75
|
+
const instruction = typeof spec.instruction === "string" ? spec.instruction : "";
|
|
76
|
+
if (instruction) {
|
|
77
|
+
blocks.push({ kind: "markdown", title: "GUARDRAIL.md", body: instruction });
|
|
78
|
+
}
|
|
79
|
+
const rules = spec.rules;
|
|
80
|
+
if (Array.isArray(rules) && rules.length > 0) {
|
|
81
|
+
blocks.push({
|
|
82
|
+
kind: "markdown",
|
|
83
|
+
title: "Rules",
|
|
84
|
+
body: rules
|
|
85
|
+
.map((r) => `- ${typeof r === "string" ? r : JSON.stringify(r)}`)
|
|
86
|
+
.join("\n"),
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
const meta = [];
|
|
90
|
+
if (typeof spec.severity === "string")
|
|
91
|
+
meta.push({ label: "severity", value: spec.severity });
|
|
92
|
+
if (typeof spec.scope === "string")
|
|
93
|
+
meta.push({ label: "scope", value: spec.scope });
|
|
94
|
+
if (meta.length > 0) {
|
|
95
|
+
blocks.push({ kind: "fields", title: "Policy", fields: meta });
|
|
96
|
+
}
|
|
97
|
+
if (blocks.length === 0) {
|
|
98
|
+
return [{ kind: "empty", title: "Guardrail (empty)" }];
|
|
99
|
+
}
|
|
100
|
+
return blocks;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// ---------------------------------------------------------------------------
|
|
104
|
+
// GuardrailReader
|
|
105
|
+
// ---------------------------------------------------------------------------
|
|
106
|
+
function parseFrontmatter(text) {
|
|
107
|
+
const match = text.match(/^---\n([\s\S]*?)---\n?/);
|
|
108
|
+
if (!match)
|
|
109
|
+
return {};
|
|
110
|
+
try {
|
|
111
|
+
const parsed = yaml.load(match[1]);
|
|
112
|
+
return typeof parsed === "object" && parsed !== null ? parsed : {};
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return {};
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
export class GuardrailReader {
|
|
119
|
+
fs;
|
|
120
|
+
constructor(fs = nodeFS) {
|
|
121
|
+
this.fs = fs;
|
|
122
|
+
}
|
|
123
|
+
detect(bundle) {
|
|
124
|
+
const path = bundle.path ?? "";
|
|
125
|
+
return this.fs.exists(`${path}/GUARDRAIL.md`);
|
|
126
|
+
}
|
|
127
|
+
read(bundle) {
|
|
128
|
+
const path = bundle.path ?? "";
|
|
129
|
+
const guardrailMd = this.fs.readFile(`${path}/GUARDRAIL.md`);
|
|
130
|
+
const metadata = parseFrontmatter(guardrailMd);
|
|
131
|
+
const name = String(metadata.name || "") || path.split("/").pop() || "";
|
|
132
|
+
const description = String(metadata.desc || metadata.description || "");
|
|
133
|
+
const severity = String(metadata.severity || "warn");
|
|
134
|
+
const scope = String(metadata.scope || "both");
|
|
135
|
+
// Extract body (after frontmatter)
|
|
136
|
+
const body = guardrailMd.replace(/^---\n[\s\S]*?---\n?/, "").trim();
|
|
137
|
+
// Parse rules from body: lines starting with "- "
|
|
138
|
+
const bodyRules = [];
|
|
139
|
+
for (const line of body.split("\n")) {
|
|
140
|
+
const trimmed = line.trimStart();
|
|
141
|
+
if (trimmed.startsWith("- ")) {
|
|
142
|
+
bodyRules.push(trimmed.slice(2).trim());
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// Rules can come from frontmatter (YAML list) or body (markdown list)
|
|
146
|
+
const frontmatterRules = metadata.rules;
|
|
147
|
+
let rules;
|
|
148
|
+
if (Array.isArray(frontmatterRules) && frontmatterRules.length > 0) {
|
|
149
|
+
rules = frontmatterRules.map(String);
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
rules = bodyRules;
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
apiVersion: "github.com/ruinosus/dna/v1",
|
|
156
|
+
kind: "Guardrail",
|
|
157
|
+
metadata: { name, description },
|
|
158
|
+
spec: { rules, severity, scope },
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// ---------------------------------------------------------------------------
|
|
163
|
+
// GuardrailWriter
|
|
164
|
+
// ---------------------------------------------------------------------------
|
|
165
|
+
export class GuardrailWriter {
|
|
166
|
+
fs;
|
|
167
|
+
constructor(fs = nodeFS) {
|
|
168
|
+
this.fs = fs;
|
|
169
|
+
}
|
|
170
|
+
canWrite(raw) {
|
|
171
|
+
return raw.kind === "Guardrail";
|
|
172
|
+
}
|
|
173
|
+
/** Shared by write()/serialize() so the two surfaces cannot drift
|
|
174
|
+
* (s-dna-rw-roundtrip-suite). */
|
|
175
|
+
entries(raw, defaultName) {
|
|
176
|
+
const spec = raw.spec ?? {};
|
|
177
|
+
const meta = raw.metadata ?? {};
|
|
178
|
+
const name = meta.name || defaultName;
|
|
179
|
+
const description = meta.description ?? "";
|
|
180
|
+
const severity = spec.severity ?? "warn";
|
|
181
|
+
const scope = spec.scope ?? "both";
|
|
182
|
+
const rules = spec.rules ?? [];
|
|
183
|
+
// Build frontmatter lines
|
|
184
|
+
const fmLines = [];
|
|
185
|
+
fmLines.push(`name: ${name}`);
|
|
186
|
+
if (description)
|
|
187
|
+
fmLines.push(`desc: ${description}`);
|
|
188
|
+
// Only write severity/scope if non-default
|
|
189
|
+
if (severity !== "warn")
|
|
190
|
+
fmLines.push(`severity: ${severity}`);
|
|
191
|
+
if (scope !== "both")
|
|
192
|
+
fmLines.push(`scope: ${scope}`);
|
|
193
|
+
const frontmatter = fmLines.join("\n");
|
|
194
|
+
// Build body: rules as "- " lines
|
|
195
|
+
const bodyLines = rules.map((r) => `- ${r}`);
|
|
196
|
+
const body = bodyLines.join("\n");
|
|
197
|
+
const content = body
|
|
198
|
+
? `---\n${frontmatter}\n---\n\n${body}\n`
|
|
199
|
+
: `---\n${frontmatter}\n---\n`;
|
|
200
|
+
return [{ relativePath: "GUARDRAIL.md", content }];
|
|
201
|
+
}
|
|
202
|
+
serialize(raw) {
|
|
203
|
+
return this.entries(raw, "");
|
|
204
|
+
}
|
|
205
|
+
write(bundle, raw) {
|
|
206
|
+
const path = bundle.path ?? "";
|
|
207
|
+
this.fs.mkdir(path);
|
|
208
|
+
for (const f of this.entries(raw, path.split("/").pop() || "")) {
|
|
209
|
+
this.fs.writeFile(`${path}/${f.relativePath}`, f.content ?? "");
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
// ---------------------------------------------------------------------------
|
|
214
|
+
// Extension
|
|
215
|
+
// ---------------------------------------------------------------------------
|
|
216
|
+
export class GuardrailExtension {
|
|
217
|
+
fs;
|
|
218
|
+
name = "guardrails";
|
|
219
|
+
version = "1.0.0";
|
|
220
|
+
constructor(fs = nodeFS) {
|
|
221
|
+
this.fs = fs;
|
|
222
|
+
}
|
|
223
|
+
register(kernel) {
|
|
224
|
+
kernel.kind(new GuardrailKind());
|
|
225
|
+
kernel.reader(new GuardrailReader(this.fs));
|
|
226
|
+
kernel.writer(new GuardrailWriter(this.fs));
|
|
227
|
+
}
|
|
228
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Actor
|
|
2
|
+
|
|
3
|
+
An Actor is a UML-canonical participant in the system — a human user, an
|
|
4
|
+
external system, or a time/schedule trigger. Actors describe WHO or WHAT
|
|
5
|
+
initiates or collaborates with agents, separating role identity from the
|
|
6
|
+
agents that fulfill that role. Canonical api version:
|
|
7
|
+
`github.com/ruinosus/dna/v1`.
|
|
8
|
+
|
|
9
|
+
**Actor types.** The `actorType` field disambiguates:
|
|
10
|
+
- `human` — a person or role (e.g. "support specialist", "admin")
|
|
11
|
+
- `system` — an upstream service or external system triggering behavior
|
|
12
|
+
- `time` — a scheduled or cron-like trigger
|
|
13
|
+
|
|
14
|
+
**Composition.** Actors are referenced by UseCases (as `primary_actor` and
|
|
15
|
+
`supporting_actors`) and by Agents through `dep_filters.actors`.
|
|
16
|
+
Actors are NOT prompt targets on their own — they are structural metadata
|
|
17
|
+
that lets manifests document and wire the cast of characters around an
|
|
18
|
+
agent without embedding role descriptions in prompts.
|
|
19
|
+
|
|
20
|
+
**Storage.** Flat YAML file at `actors/<name>.yaml`.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Agent
|
|
2
|
+
|
|
3
|
+
A Agent is the primary prompt target in a helix manifest — it is
|
|
4
|
+
what actually runs when a user (or another agent) talks to the system. It
|
|
5
|
+
carries an `instruction` (the agent's main prompt, usually a bundled
|
|
6
|
+
`AGENT.md`), a `model` to call, and `dep_filters` that declare which Soul,
|
|
7
|
+
Skills, Guardrails, and Actors it composes with.
|
|
8
|
+
|
|
9
|
+
**Prompt assembly.** Every turn the kernel builds the agent's system prompt
|
|
10
|
+
by rendering the `prompt_template`: the instruction body comes first, then
|
|
11
|
+
the Soul content (flattened in full), then each Guardrail (name, severity,
|
|
12
|
+
and rules). Skills are deliberately NOT flattened — they are exposed via
|
|
13
|
+
Agent Skills progressive disclosure so the context window stays lean.
|
|
14
|
+
|
|
15
|
+
**Priority.** `prompt_target_priority = 10` means Agent wins over
|
|
16
|
+
other prompt-target kinds when the harness has to pick one to run.
|
|
17
|
+
|
|
18
|
+
**Storage.** Bundle-based: `agents/<name>/AGENT.md` with optional
|
|
19
|
+
`scripts/`, `references/`, and `assets/` subdirectories. Canonical api
|
|
20
|
+
version: `github.com/ruinosus/dna/v1`.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# UseCase
|
|
2
|
+
|
|
3
|
+
A UseCase is a UML-canonical use case document: a goal-oriented interaction
|
|
4
|
+
between one or more Actors and the system. It composes a primary actor,
|
|
5
|
+
supporting actors, and the agent(s) that fulfill the goal, then carries the
|
|
6
|
+
classical UML fields: `preconditions`, `main_flow`, `alternate_flows`,
|
|
7
|
+
`postconditions`, and `success_criteria`. Canonical api version:
|
|
8
|
+
`github.com/ruinosus/dna/v1`.
|
|
9
|
+
|
|
10
|
+
**Not a prompt target.** A UseCase is purely declarative — it documents how
|
|
11
|
+
the manifest's agents and actors are meant to work together to achieve a
|
|
12
|
+
business goal. It is structural composition metadata, consumed by tooling
|
|
13
|
+
(navigators, doc generators, validators) rather than by the LLM directly.
|
|
14
|
+
|
|
15
|
+
**When to use.** Reach for UseCases when a helix manifest is complex
|
|
16
|
+
enough that the relationship between actors and agents is non-obvious, or
|
|
17
|
+
when you need machine-readable traceability from requirements to the agents
|
|
18
|
+
that implement them.
|
|
19
|
+
|
|
20
|
+
**Storage.** Flat YAML file at `use_cases/<name>.yaml`.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DEPRECATED shim — DefaultLayerResolver moved into the kernel.
|
|
3
|
+
*
|
|
4
|
+
* Layer resolution is a core kernel responsibility
|
|
5
|
+
* (s-invert-layer-resolver-dep, 2026-07-07): the kernel must work with
|
|
6
|
+
* zero extensions loaded, so the resolver now lives at
|
|
7
|
+
* `src/kernel/layer-resolver.ts`. This module reexports the old public
|
|
8
|
+
* names for external importers and emits a DeprecationWarning on import.
|
|
9
|
+
*
|
|
10
|
+
* @deprecated Import from `dna-sdk/kernel/layer-resolver` instead.
|
|
11
|
+
*/
|
|
12
|
+
export { DefaultLayerResolver, deepMerge, mergeTimelineArrays, type LayerSource, } from "../../kernel/layer-resolver.js";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DEPRECATED shim — DefaultLayerResolver moved into the kernel.
|
|
3
|
+
*
|
|
4
|
+
* Layer resolution is a core kernel responsibility
|
|
5
|
+
* (s-invert-layer-resolver-dep, 2026-07-07): the kernel must work with
|
|
6
|
+
* zero extensions loaded, so the resolver now lives at
|
|
7
|
+
* `src/kernel/layer-resolver.ts`. This module reexports the old public
|
|
8
|
+
* names for external importers and emits a DeprecationWarning on import.
|
|
9
|
+
*
|
|
10
|
+
* @deprecated Import from `dna-sdk/kernel/layer-resolver` instead.
|
|
11
|
+
*/
|
|
12
|
+
export { DefaultLayerResolver, deepMerge, mergeTimelineArrays, } from "../../kernel/layer-resolver.js";
|
|
13
|
+
// Node/Bun idiomatic import-time deprecation (parity with the Python
|
|
14
|
+
// shim's warnings.warn(DeprecationWarning)).
|
|
15
|
+
if (typeof process !== "undefined" && typeof process.emitWarning === "function") {
|
|
16
|
+
process.emitWarning("extensions/helix/layers is deprecated — import DefaultLayerResolver/" +
|
|
17
|
+
"deepMerge from kernel/layer-resolver instead (s-invert-layer-resolver-dep).", "DeprecationWarning");
|
|
18
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
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 type { PreSaveContext } from "../../kernel/hooks.js";
|
|
27
|
+
import type { ExtensionHost } from "../../kernel/protocols.js";
|
|
28
|
+
export declare const PRIORITY_FORK_GUARD = 10;
|
|
29
|
+
export declare const PRIORITY_PROMPT_BUDGET = 20;
|
|
30
|
+
export declare const PRIORITY_KIND_WRITER = 30;
|
|
31
|
+
/**
|
|
32
|
+
* Block per-tenant overlays of `_lib` Agents.
|
|
33
|
+
*
|
|
34
|
+
* The `_lib` scope is the shared baseline (jarvis + the 12 transversais);
|
|
35
|
+
* its Agents are edited in git + `dna doc apply --scope _lib` (base
|
|
36
|
+
* only). A per-tenant overlay silently FORKS the persona and shadows the
|
|
37
|
+
* base for that tenant's reads — the root cause of the JARVIS 16384 outage
|
|
38
|
+
* (2026-05-29) and the stale-persona bug (2026-06-14). Veto it loudly.
|
|
39
|
+
*/
|
|
40
|
+
export declare function platformAgentForkGuard(ctx: PreSaveContext): void;
|
|
41
|
+
/**
|
|
42
|
+
* Enforce the Agent instruction budget against the ModelProfile registry.
|
|
43
|
+
*
|
|
44
|
+
* CONTRACT — never hardcode token caps: the cap ALWAYS comes from the
|
|
45
|
+
* ModelProfile registry (`kernel.modelProfile(idOrAlias)` → the
|
|
46
|
+
* `modelreg-model-profile` Kind in `_lib`), never from a literal in code.
|
|
47
|
+
*
|
|
48
|
+
* Three paths (s-tier-a-modelprofile):
|
|
49
|
+
* - VETO — strict model (voice persona, or `realtime: true` profile) and
|
|
50
|
+
* the instruction estimate exceeds `instruction_token_cap`.
|
|
51
|
+
* - WARN — a chat Agent (`spec.model` declared, non-realtime profile)
|
|
52
|
+
* exceeds the cap: tolerated but logged loud.
|
|
53
|
+
* - PASS — no model declared, no profile found, no cap, or within budget.
|
|
54
|
+
* Enforcement is opt-in by DATA: writing a profile with a cap arms it.
|
|
55
|
+
*
|
|
56
|
+
* Fail-open on uncounted text (instruction_file / non-string body).
|
|
57
|
+
* `DNA_PROMPT_BUDGET_ENFORCE=0` downgrades the veto to a warn.
|
|
58
|
+
*
|
|
59
|
+
* 1:1 parity with Python `prompt_budget_guard`.
|
|
60
|
+
*/
|
|
61
|
+
export declare function promptBudgetGuard(ctx: PreSaveContext): Promise<void>;
|
|
62
|
+
export declare function kindWriterContractGuard(ctx: PreSaveContext): void;
|
|
63
|
+
/**
|
|
64
|
+
* Wire the Helix write guards as `pre_save` veto hooks. Keys make the
|
|
65
|
+
* registration idempotent (re-loading the extension onto a shared
|
|
66
|
+
* HookRegistry replaces instead of stacking duplicates). Takes the
|
|
67
|
+
* `ExtensionHost` slice (s-dna-extension-host-contract) — registration
|
|
68
|
+
* goes through `kernel.hooks.onVeto` for the `key` idempotency.
|
|
69
|
+
*/
|
|
70
|
+
export declare function registerWriteGuards(kernel: ExtensionHost): void;
|