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,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Automation-owned write-path guards (s-tier-a-automation).
|
|
3
|
+
*
|
|
4
|
+
* One `pre_save` VETO hook that makes an Automation write *fully valid or
|
|
5
|
+
* not persisted*, covering what is Automation's OWN:
|
|
6
|
+
*
|
|
7
|
+
* - **Semantics the schema cannot express:**
|
|
8
|
+
*
|
|
9
|
+
* - **cron expression** (`on.type: cron`) — parsed by a zero-dependency
|
|
10
|
+
* 5-field validator (documented decision: a cron lib would be a
|
|
11
|
+
* runtime dep for one field; the grammar below covers the standard
|
|
12
|
+
* crontab core — `*`, numbers, ranges, lists, steps — and rejects the
|
|
13
|
+
* rest loudly. Name aliases like `JAN`/`MON` are NOT supported.)
|
|
14
|
+
* - **hook name** (`on.type: hook`) — must belong to the kernel's typed
|
|
15
|
+
* hook vocabulary `KNOWN_HOOK_NAMES` (s-dna-typed-hook-names). The
|
|
16
|
+
* HookRegistry itself tolerates custom names (warn-once), but an
|
|
17
|
+
* Automation is DATA a host executor dispatches on: a misspelled hook
|
|
18
|
+
* would be declared, listed, and silently never fire — so here the
|
|
19
|
+
* unknown name is a veto, not a warning.
|
|
20
|
+
*
|
|
21
|
+
* The Python twin has one extra FIRST step this side does not need: PyYAML
|
|
22
|
+
* reads a bare `on:` key as boolean `True` (YAML 1.1), so the Py guard
|
|
23
|
+
* heals a top-level `True` spec key back to `"on"` before validating.
|
|
24
|
+
* js-yaml keeps `on` a string — no trap, no step.
|
|
25
|
+
*
|
|
26
|
+
* Schema SHAPE at write time (originally this guard's step 1) is no longer
|
|
27
|
+
* Automation-specific: `s-write-path-validation` (i-008) generalized it —
|
|
28
|
+
* `WritePipeline.write` validates every doc's spec against the Kind's
|
|
29
|
+
* declared `schema()` after the veto hooks run. This guard keeps only the
|
|
30
|
+
* semantics JSON Schema cannot express.
|
|
31
|
+
*
|
|
32
|
+
* A throw from the guard vetoes the write (nothing is persisted). The hook
|
|
33
|
+
* fires for EVERY `kernel.writeDocument` regardless of `skipHooks` — it is
|
|
34
|
+
* an integrity gate, not a notification. 1:1 parity with Python
|
|
35
|
+
* `dna.extensions.automation.write_guards`.
|
|
36
|
+
*/
|
|
37
|
+
import { KNOWN_HOOK_NAMES } from "../../kernel/hooks.js";
|
|
38
|
+
const KIND = "Automation";
|
|
39
|
+
// After helix (10/20/30) and SDLC bitemporal (40).
|
|
40
|
+
export const PRIORITY_TRIGGER_GUARD = 50;
|
|
41
|
+
// [label, lo, hi] per cron field, in order. dow accepts 0-7 (0 and 7 both
|
|
42
|
+
// mean Sunday, matching crontab).
|
|
43
|
+
const CRON_FIELDS = [
|
|
44
|
+
["minute", 0, 59],
|
|
45
|
+
["hour", 0, 23],
|
|
46
|
+
["day-of-month", 1, 31],
|
|
47
|
+
["month", 1, 12],
|
|
48
|
+
["day-of-week", 0, 7],
|
|
49
|
+
];
|
|
50
|
+
function cronError(expr, detail) {
|
|
51
|
+
return new Error(`invalid cron expression ${JSON.stringify(expr)}: ${detail}. Expected ` +
|
|
52
|
+
`5 whitespace-separated fields 'min hour dom mon dow' (e.g. ` +
|
|
53
|
+
`'0 10 * * 1,3,5'); each field is '*', a number, a range 'a-b', a ` +
|
|
54
|
+
`list 'a,b,c' or a step '*/n' / 'a-b/n'. Name aliases (JAN/MON) ` +
|
|
55
|
+
`are not supported.`);
|
|
56
|
+
}
|
|
57
|
+
const DIGITS = /^\d+$/;
|
|
58
|
+
/**
|
|
59
|
+
* Validate a 5-field cron expression. Throws on the first problem
|
|
60
|
+
* (didactic message); returns void when valid.
|
|
61
|
+
*/
|
|
62
|
+
export function validateCronExpression(expr) {
|
|
63
|
+
const fields = expr.split(/\s+/).filter((f) => f.length > 0);
|
|
64
|
+
if (fields.length !== 5) {
|
|
65
|
+
throw cronError(expr, `expected 5 fields, got ${fields.length}`);
|
|
66
|
+
}
|
|
67
|
+
for (let i = 0; i < 5; i++) {
|
|
68
|
+
const value = fields[i];
|
|
69
|
+
const [label, lo, hi] = CRON_FIELDS[i];
|
|
70
|
+
for (const item of value.split(",")) {
|
|
71
|
+
if (!item)
|
|
72
|
+
throw cronError(expr, `empty list item in ${label} field`);
|
|
73
|
+
const slash = item.indexOf("/");
|
|
74
|
+
const base = slash === -1 ? item : item.slice(0, slash);
|
|
75
|
+
if (slash !== -1) {
|
|
76
|
+
const step = item.slice(slash + 1);
|
|
77
|
+
if (!DIGITS.test(step) || parseInt(step, 10) < 1) {
|
|
78
|
+
throw cronError(expr, `step '/${step}' in ${label} field must be a positive integer`);
|
|
79
|
+
}
|
|
80
|
+
if (base === "") {
|
|
81
|
+
throw cronError(expr, `step without a base in ${label} field`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (base === "*")
|
|
85
|
+
continue;
|
|
86
|
+
const dash = base.indexOf("-");
|
|
87
|
+
const bounds = dash === -1
|
|
88
|
+
? [base]
|
|
89
|
+
: [base.slice(0, dash), base.slice(dash + 1)];
|
|
90
|
+
for (const bound of bounds) {
|
|
91
|
+
if (!DIGITS.test(bound)) {
|
|
92
|
+
throw cronError(expr, `${JSON.stringify(bound)} in ${label} field is not a number`);
|
|
93
|
+
}
|
|
94
|
+
const n = parseInt(bound, 10);
|
|
95
|
+
if (n < lo || n > hi) {
|
|
96
|
+
throw cronError(expr, `${n} out of range ${lo}-${hi} for ${label}`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (dash !== -1 && parseInt(bounds[0], 10) > parseInt(bounds[1], 10)) {
|
|
100
|
+
throw cronError(expr, `inverted range ${JSON.stringify(base)} in ${label} field`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Veto an Automation write that is not fully valid.
|
|
107
|
+
*
|
|
108
|
+
* Checks the semantics JSON Schema cannot express (cron grammar,
|
|
109
|
+
* hook-name vocabulary). Schema SHAPE is validated by the kernel's
|
|
110
|
+
* generic write-path step (s-write-path-validation, i-008), which runs
|
|
111
|
+
* after the veto hooks — this guard no longer duplicates it.
|
|
112
|
+
*/
|
|
113
|
+
export function automationTriggerGuard(ctx) {
|
|
114
|
+
if (ctx.kind !== KIND || typeof ctx.raw !== "object" || ctx.raw === null) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const spec = ctx.raw.spec;
|
|
118
|
+
if (typeof spec !== "object" || spec === null)
|
|
119
|
+
return;
|
|
120
|
+
// Semantics the schema cannot express (shape itself is the kernel's
|
|
121
|
+
// generic write-path validation, which runs after the veto hooks).
|
|
122
|
+
const on = spec.on;
|
|
123
|
+
if (typeof on !== "object" || on === null)
|
|
124
|
+
return;
|
|
125
|
+
const onType = on.type;
|
|
126
|
+
if (onType === "cron") {
|
|
127
|
+
const cron = on.cron;
|
|
128
|
+
if (typeof cron === "string")
|
|
129
|
+
validateCronExpression(cron);
|
|
130
|
+
}
|
|
131
|
+
else if (onType === "hook") {
|
|
132
|
+
const hook = on.hook;
|
|
133
|
+
if (typeof hook === "string" && !KNOWN_HOOK_NAMES.includes(hook)) {
|
|
134
|
+
throw new Error(`Automation ${JSON.stringify(ctx.name)} declares on.hook=` +
|
|
135
|
+
`${JSON.stringify(hook)}, which is not a kernel lifecycle hook. ` +
|
|
136
|
+
`Known hooks: ${JSON.stringify([...KNOWN_HOOK_NAMES].sort())}. A ` +
|
|
137
|
+
`misspelled hook would be declared but never fire — fix the name ` +
|
|
138
|
+
`(the vocabulary is typed: HookName in kernel/hooks).`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Wire the Automation write guard as a `pre_save` veto hook.
|
|
144
|
+
*
|
|
145
|
+
* The key makes the registration idempotent (re-loading the extension
|
|
146
|
+
* onto a shared HookRegistry replaces instead of stacking duplicates).
|
|
147
|
+
*/
|
|
148
|
+
export function registerWriteGuards(kernel) {
|
|
149
|
+
kernel.hooks.onVeto("pre_save", automationTriggerGuard, {
|
|
150
|
+
priority: PRIORITY_TRIGGER_GUARD,
|
|
151
|
+
key: "automation.trigger-guard",
|
|
152
|
+
});
|
|
153
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AutomationExtension — declarative background automation as data.
|
|
3
|
+
*
|
|
4
|
+
* 1:1 parity with Python `dna.extensions.automation`.
|
|
5
|
+
*
|
|
6
|
+
* Registers 1 Kind, from a descriptor (F3 — record Kinds are data, not
|
|
7
|
+
* classes):
|
|
8
|
+
*
|
|
9
|
+
* - Automation (`dna-automation`) — one doc declares WHEN background
|
|
10
|
+
* work fires (`on: {type: cron|hook|tool, ...}`) and WHAT runs
|
|
11
|
+
* (`runner: {kind: agent|tool, ref}` + `agent_directive` / `input` /
|
|
12
|
+
* result templating / spoken copy / `safety`). Tier A port from the
|
|
13
|
+
* internal SDK's automation extension (s-tier-a-automation) —
|
|
14
|
+
* upstream, this Kind unified an async-tool / bus-event / cron trio
|
|
15
|
+
* and killed hardcoded dispatch: adding or retargeting an automation
|
|
16
|
+
* is writing one YAML, zero deploy.
|
|
17
|
+
*
|
|
18
|
+
* What travels vs what does not (honest evolution):
|
|
19
|
+
*
|
|
20
|
+
* - The DECLARATION travels: the Kind (descriptor), write-time
|
|
21
|
+
* validation (`automation/write-guards.ts`: 5-field cron parse + hook
|
|
22
|
+
* names against the kernel's typed `KNOWN_HOOK_NAMES` vocabulary) and
|
|
23
|
+
* the query helpers (`automationsFor` / `triggerKey`) a host executor
|
|
24
|
+
* reads.
|
|
25
|
+
* - EXECUTION does not: the SDK has no scheduler, bus or worker. The
|
|
26
|
+
* host reads Automation docs via the query helpers and runs them —
|
|
27
|
+
* the same declare-here/execute-in-the-host pattern as the CLI's
|
|
28
|
+
* `register_post_transition_hook`. The runner contract + a minimal
|
|
29
|
+
* example live in docs/concepts/builtin-kinds.md.
|
|
30
|
+
*
|
|
31
|
+
* Inheritable ⇒ never TENANTED: Automation is an inheritable `_lib`
|
|
32
|
+
* default (it is in `DEFAULT_INHERITABLE_KINDS_V1`) → tenancy PERMISSIVE
|
|
33
|
+
* (no `tenant_scope` in the descriptor): base writable in `_lib` +
|
|
34
|
+
* per-tenant override via overlay.
|
|
35
|
+
*/
|
|
36
|
+
import type { ExtensionHost, Extension } from "../kernel/protocols.js";
|
|
37
|
+
export declare class AutomationExtension implements Extension {
|
|
38
|
+
name: string;
|
|
39
|
+
version: string;
|
|
40
|
+
register(kernel: ExtensionHost): void;
|
|
41
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AutomationExtension — declarative background automation as data.
|
|
3
|
+
*
|
|
4
|
+
* 1:1 parity with Python `dna.extensions.automation`.
|
|
5
|
+
*
|
|
6
|
+
* Registers 1 Kind, from a descriptor (F3 — record Kinds are data, not
|
|
7
|
+
* classes):
|
|
8
|
+
*
|
|
9
|
+
* - Automation (`dna-automation`) — one doc declares WHEN background
|
|
10
|
+
* work fires (`on: {type: cron|hook|tool, ...}`) and WHAT runs
|
|
11
|
+
* (`runner: {kind: agent|tool, ref}` + `agent_directive` / `input` /
|
|
12
|
+
* result templating / spoken copy / `safety`). Tier A port from the
|
|
13
|
+
* internal SDK's automation extension (s-tier-a-automation) —
|
|
14
|
+
* upstream, this Kind unified an async-tool / bus-event / cron trio
|
|
15
|
+
* and killed hardcoded dispatch: adding or retargeting an automation
|
|
16
|
+
* is writing one YAML, zero deploy.
|
|
17
|
+
*
|
|
18
|
+
* What travels vs what does not (honest evolution):
|
|
19
|
+
*
|
|
20
|
+
* - The DECLARATION travels: the Kind (descriptor), write-time
|
|
21
|
+
* validation (`automation/write-guards.ts`: 5-field cron parse + hook
|
|
22
|
+
* names against the kernel's typed `KNOWN_HOOK_NAMES` vocabulary) and
|
|
23
|
+
* the query helpers (`automationsFor` / `triggerKey`) a host executor
|
|
24
|
+
* reads.
|
|
25
|
+
* - EXECUTION does not: the SDK has no scheduler, bus or worker. The
|
|
26
|
+
* host reads Automation docs via the query helpers and runs them —
|
|
27
|
+
* the same declare-here/execute-in-the-host pattern as the CLI's
|
|
28
|
+
* `register_post_transition_hook`. The runner contract + a minimal
|
|
29
|
+
* example live in docs/concepts/builtin-kinds.md.
|
|
30
|
+
*
|
|
31
|
+
* Inheritable ⇒ never TENANTED: Automation is an inheritable `_lib`
|
|
32
|
+
* default (it is in `DEFAULT_INHERITABLE_KINDS_V1`) → tenancy PERMISSIVE
|
|
33
|
+
* (no `tenant_scope` in the descriptor): base writable in `_lib` +
|
|
34
|
+
* per-tenant override via overlay.
|
|
35
|
+
*/
|
|
36
|
+
import { loadDescriptors } from "../kernel/descriptor-loader.js";
|
|
37
|
+
import { registerWriteGuards } from "./automation/write-guards.js";
|
|
38
|
+
export class AutomationExtension {
|
|
39
|
+
name = "automation";
|
|
40
|
+
version = "1.0.0";
|
|
41
|
+
register(kernel) {
|
|
42
|
+
// F3: Automation ships as kinds/automation.kind.yaml package data
|
|
43
|
+
// (byte-identical Py↔TS mirror), registered through the SAME funnel as
|
|
44
|
+
// per-scope KindDefinitions (plane lint + digest idempotency + builtin
|
|
45
|
+
// conflict marker).
|
|
46
|
+
for (const raw of loadDescriptors(import.meta.url, "automation/kinds")) {
|
|
47
|
+
kernel.kindFromDescriptor(raw);
|
|
48
|
+
}
|
|
49
|
+
// Write-time semantic validation the JSON Schema cannot express: cron
|
|
50
|
+
// expression parse + hook-name vocabulary (pre_save veto, helix
|
|
51
|
+
// write-guards pattern).
|
|
52
|
+
registerWriteGuards(kernel);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CollabExtension — collaboration primitives (Comment Kind).
|
|
3
|
+
*
|
|
4
|
+
* Registers 1 KindPort:
|
|
5
|
+
* - Comment (collab-comment) — a remark or status change attached to any document
|
|
6
|
+
*
|
|
7
|
+
* Comments can be attached to any target document via `target_ref`.
|
|
8
|
+
* They enable audit trails, discussions, and status-change history.
|
|
9
|
+
* 1:1 parity with Python.
|
|
10
|
+
*/
|
|
11
|
+
import type { ExtensionHost, Extension } from "../kernel/protocols.js";
|
|
12
|
+
export declare class CollabExtension implements Extension {
|
|
13
|
+
readonly name = "collab";
|
|
14
|
+
readonly version = "1.0.0";
|
|
15
|
+
register(kernel: ExtensionHost): void;
|
|
16
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CollabExtension — collaboration primitives (Comment Kind).
|
|
3
|
+
*
|
|
4
|
+
* Registers 1 KindPort:
|
|
5
|
+
* - Comment (collab-comment) — a remark or status change attached to any document
|
|
6
|
+
*
|
|
7
|
+
* Comments can be attached to any target document via `target_ref`.
|
|
8
|
+
* They enable audit trails, discussions, and status-change history.
|
|
9
|
+
* 1:1 parity with Python.
|
|
10
|
+
*/
|
|
11
|
+
import { KindBase } from "../kernel/kind_base.js";
|
|
12
|
+
import { SD } from "../kernel/protocols.js";
|
|
13
|
+
const API_VERSION = "github.com/ruinosus/dna/collab/v1";
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// CommentKind
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
class CommentKind extends KindBase {
|
|
18
|
+
apiVersion = API_VERSION;
|
|
19
|
+
kind = "Comment";
|
|
20
|
+
alias = "collab-comment";
|
|
21
|
+
origin = "github.com/ruinosus/dna/collab";
|
|
22
|
+
isPromptTarget = false;
|
|
23
|
+
promptTargetPriority = 0;
|
|
24
|
+
flattenInContext = false;
|
|
25
|
+
storage = SD.yaml("comments");
|
|
26
|
+
graphStyle = { fill: "#F59E0B", stroke: "#D97706", textColor: "#fff" };
|
|
27
|
+
asciiIcon = "💬";
|
|
28
|
+
displayLabel = "Comments";
|
|
29
|
+
docs = "";
|
|
30
|
+
// Comment can point to ANY kind via target_ref — no typed dep filter
|
|
31
|
+
// because target can be Finding, EvalCase, Agent, etc.
|
|
32
|
+
depFilters() { return {}; }
|
|
33
|
+
schema() {
|
|
34
|
+
return {
|
|
35
|
+
type: "object",
|
|
36
|
+
required: ["target_ref", "author", "body", "type", "created_at"],
|
|
37
|
+
additionalProperties: true,
|
|
38
|
+
properties: {
|
|
39
|
+
target_ref: { type: "string", description: "Kind:name of the target document" },
|
|
40
|
+
author: { type: "string" },
|
|
41
|
+
body: { type: "string" },
|
|
42
|
+
type: {
|
|
43
|
+
type: "string",
|
|
44
|
+
enum: ["note", "status_change", "assignment", "system"],
|
|
45
|
+
default: "note",
|
|
46
|
+
},
|
|
47
|
+
created_at: { type: "string", format: "date-time" },
|
|
48
|
+
// Fields when type=status_change:
|
|
49
|
+
from_status: { type: "string" },
|
|
50
|
+
to_status: { type: "string" },
|
|
51
|
+
// Fields when type=assignment:
|
|
52
|
+
assignee: { type: "string" },
|
|
53
|
+
// Edits/attachments (future):
|
|
54
|
+
edited_at: { type: "string" },
|
|
55
|
+
attachments: { type: "array", items: { type: "string" } },
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
summary(doc) {
|
|
60
|
+
const spec = (doc.spec ?? {});
|
|
61
|
+
const body = spec.body ?? "";
|
|
62
|
+
return {
|
|
63
|
+
target_ref: spec.target_ref ?? "",
|
|
64
|
+
author: spec.author ?? "",
|
|
65
|
+
type: spec.type ?? "note",
|
|
66
|
+
body_preview: body ? body.slice(0, 80) : "",
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// ---------------------------------------------------------------------------
|
|
71
|
+
// Extension
|
|
72
|
+
// ---------------------------------------------------------------------------
|
|
73
|
+
export class CollabExtension {
|
|
74
|
+
name = "collab";
|
|
75
|
+
version = "1.0.0";
|
|
76
|
+
register(kernel) {
|
|
77
|
+
kernel.kind(new CommentKind());
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Doc — one page of in-product documentation (record plane, authored content).
|
|
2
|
+
#
|
|
3
|
+
# Tier A port from the internal SDK's doc extension (s-tier-a-doc-kind). What
|
|
4
|
+
# travels is the CORE: a Doc is structured content — a markdown ``body`` plus
|
|
5
|
+
# sidebar metadata (icon / subtitle / summary / order / locale / enabled),
|
|
6
|
+
# Diátaxis ``kind_of`` and a free-form ``category`` — exactly the corpus
|
|
7
|
+
# ``dna docs list/show`` reads. The authoring shape is preserved: a bundle
|
|
8
|
+
# ``docs/<name>/DOC.md`` (YAML frontmatter + markdown body), handled entirely
|
|
9
|
+
# by the generic bundle machinery (``body_field: body``) — no custom
|
|
10
|
+
# reader/writer, no class. ``tags`` is a DNA addition (free-form labels),
|
|
11
|
+
# not an upstream field.
|
|
12
|
+
#
|
|
13
|
+
# Deliberately NOT ported (coupled to the upstream product's help-center
|
|
14
|
+
# service, not to the Kind):
|
|
15
|
+
# - ``data_sections`` + ``live_diagrams`` (the ``<!-- DATA: … -->`` /
|
|
16
|
+
# ``<!-- LIVE: … -->`` body placeholders) — resolved by upstream service
|
|
17
|
+
# endpoints (live kernel-introspection tables + server-rendered
|
|
18
|
+
# diagrams) that have no DNA equivalent;
|
|
19
|
+
# - ``spec.assets`` (sibling sub-markdown/drawio files lifted into the
|
|
20
|
+
# spec) — a UI rendering concern; sibling files still live in the
|
|
21
|
+
# bundle directory, they are just not aggregated into the document;
|
|
22
|
+
# - the ``featured`` landing-page curation flag, the "blank Doc" template
|
|
23
|
+
# scaffold, and the widget-hint ``ui_schema`` bag — upstream product
|
|
24
|
+
# UX; hosts can derive forms from the JSON Schema below.
|
|
25
|
+
#
|
|
26
|
+
# PARITY-CRITICAL package data: byte-identical mirror under both runtimes'
|
|
27
|
+
# doc/kinds/ (tests/test_descriptor_hash_parity.py enforces).
|
|
28
|
+
#
|
|
29
|
+
# tenant_scope intentionally NOT declared — permissive (base doc + optional
|
|
30
|
+
# per-tenant overlay). Docs are shared per-scope content a tenant may
|
|
31
|
+
# legitimately override; the máxima "inheritable ⇒ never tenanted" holds.
|
|
32
|
+
apiVersion: github.com/ruinosus/dna/core/v1
|
|
33
|
+
kind: KindDefinition
|
|
34
|
+
metadata:
|
|
35
|
+
name: doc
|
|
36
|
+
spec:
|
|
37
|
+
target_api_version: github.com/ruinosus/dna/doc/v1
|
|
38
|
+
target_kind: Doc
|
|
39
|
+
alias: dna-doc
|
|
40
|
+
origin: github.com/ruinosus/dna/doc
|
|
41
|
+
plane: record
|
|
42
|
+
prompt_target: false
|
|
43
|
+
flatten_in_context: false
|
|
44
|
+
prompt_target_priority: 0
|
|
45
|
+
storage:
|
|
46
|
+
type: bundle
|
|
47
|
+
container: docs
|
|
48
|
+
marker: DOC.md
|
|
49
|
+
body_field: body
|
|
50
|
+
spec_defaults:
|
|
51
|
+
order: 999
|
|
52
|
+
locale: pt-BR
|
|
53
|
+
enabled: true
|
|
54
|
+
schema:
|
|
55
|
+
type: object
|
|
56
|
+
required:
|
|
57
|
+
- body
|
|
58
|
+
additionalProperties: false
|
|
59
|
+
properties:
|
|
60
|
+
body:
|
|
61
|
+
type: string
|
|
62
|
+
description: Markdown body of the page — the DOC.md content below the
|
|
63
|
+
frontmatter.
|
|
64
|
+
icon:
|
|
65
|
+
type: string
|
|
66
|
+
description: Emoji or short string shown next to the title.
|
|
67
|
+
subtitle:
|
|
68
|
+
type: string
|
|
69
|
+
description: One-line subtitle shown under the title.
|
|
70
|
+
summary:
|
|
71
|
+
type: string
|
|
72
|
+
description: 1-2 sentences for the topic header card / previews.
|
|
73
|
+
order:
|
|
74
|
+
type: integer
|
|
75
|
+
description: Sort order in the sidebar (ascending).
|
|
76
|
+
locale:
|
|
77
|
+
type: string
|
|
78
|
+
description: Content locale (e.g. pt-BR, en). ``dna docs`` filters
|
|
79
|
+
on it.
|
|
80
|
+
enabled:
|
|
81
|
+
type: boolean
|
|
82
|
+
description: If false, the page is hidden from listings.
|
|
83
|
+
kind_of:
|
|
84
|
+
enum:
|
|
85
|
+
- tutorial
|
|
86
|
+
- how_to
|
|
87
|
+
- reference
|
|
88
|
+
- explanation
|
|
89
|
+
- null
|
|
90
|
+
description: Diátaxis classification (learning- / task- /
|
|
91
|
+
information- / understanding-oriented). Null = uncategorized.
|
|
92
|
+
category:
|
|
93
|
+
type:
|
|
94
|
+
- string
|
|
95
|
+
- 'null'
|
|
96
|
+
description: Free-form sidebar grouping (e.g. "Getting started").
|
|
97
|
+
Null falls back to a flat list.
|
|
98
|
+
tags:
|
|
99
|
+
type: array
|
|
100
|
+
items:
|
|
101
|
+
type: string
|
|
102
|
+
description: Free-form labels for filtering and search.
|
|
103
|
+
describe:
|
|
104
|
+
path: subtitle
|
|
105
|
+
description_fallback_field: subtitle
|
|
106
|
+
graph_style:
|
|
107
|
+
fill: '#0EA5E9'
|
|
108
|
+
stroke: '#0284C7'
|
|
109
|
+
text_color: '#fff'
|
|
110
|
+
ascii_icon: 📘
|
|
111
|
+
display_label: Docs
|
|
112
|
+
docs: A Doc is one page of in-product documentation. The marker is
|
|
113
|
+
``docs/<name>/DOC.md`` — YAML frontmatter (icon, subtitle, summary,
|
|
114
|
+
order, locale, enabled, kind_of, category, tags) plus a markdown body
|
|
115
|
+
that lands in ``spec.body``. The page title is ``metadata.description``.
|
|
116
|
+
``kind_of`` follows Diátaxis (tutorial/how_to/reference/explanation);
|
|
117
|
+
``category`` groups the sidebar; ``locale`` lets one corpus serve
|
|
118
|
+
multiple languages. This is the Kind behind ``dna docs list/show``.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DocExtension — the in-product documentation Kind.
|
|
3
|
+
*
|
|
4
|
+
* Registers 1 Kind:
|
|
5
|
+
* - Doc (dna-doc) — one page of in-product documentation: a markdown
|
|
6
|
+
* `body` + sidebar metadata (icon/subtitle/summary/order/locale/
|
|
7
|
+
* enabled/kind_of/category/tags). The corpus `dna docs list/show`
|
|
8
|
+
* reads is made of these.
|
|
9
|
+
*
|
|
10
|
+
* Pure descriptor extension (F3): the Kind is data — `doc/kinds/
|
|
11
|
+
* doc.kind.yaml` — synthesized via `kernel.kindFromDescriptor`; the
|
|
12
|
+
* bundle storage (`docs/<name>/DOC.md`, frontmatter + markdown body) is
|
|
13
|
+
* handled by the generic reader/writer machinery. No models, no port
|
|
14
|
+
* class. 1:1 parity with Python (the descriptor file is byte-identical
|
|
15
|
+
* package data — see tests/descriptor-hash-parity.test.ts).
|
|
16
|
+
*
|
|
17
|
+
* Tier A port from the internal SDK's doc extension (s-tier-a-doc-kind);
|
|
18
|
+
* see the descriptor header for the honest subset notes.
|
|
19
|
+
*/
|
|
20
|
+
import type { Extension, ExtensionHost } from "../kernel/protocols.js";
|
|
21
|
+
export declare class DocExtension implements Extension {
|
|
22
|
+
readonly name = "doc";
|
|
23
|
+
readonly version = "1.0.0";
|
|
24
|
+
register(kernel: ExtensionHost): void;
|
|
25
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { loadDescriptors } from "../kernel/descriptor-loader.js";
|
|
2
|
+
export class DocExtension {
|
|
3
|
+
name = "doc";
|
|
4
|
+
version = "1.0.0";
|
|
5
|
+
register(kernel) {
|
|
6
|
+
for (const raw of loadDescriptors(import.meta.url, "doc/kinds")) {
|
|
7
|
+
kernel.kindFromDescriptor(raw);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# EvalBaseline — pinned "known good" EvalRun for a suite (record plane).
|
|
2
|
+
#
|
|
3
|
+
# Tier B port from the internal SDK's eval extension (s-dna-eval-kit).
|
|
4
|
+
# Same semantics as upstream: a pointer to one EvalRun pinned as the
|
|
5
|
+
# reference for a suite; future runs are compared against it to detect
|
|
6
|
+
# regressions (a case that passed in the baseline and fails now). One
|
|
7
|
+
# baseline per suite by convention (`dna eval pin` names it
|
|
8
|
+
# baseline-<suite>). The upstream status field (approved/candidate) did
|
|
9
|
+
# not travel — a local-first workflow pins exactly one reference.
|
|
10
|
+
#
|
|
11
|
+
# tenant_scope intentionally NOT declared — permissive (base + per-tenant
|
|
12
|
+
# overlay), the Evidence/Automation precedent.
|
|
13
|
+
#
|
|
14
|
+
# PARITY-CRITICAL package data: byte-identical mirror under both runtimes'
|
|
15
|
+
# eval/kinds/ (tests/test_descriptor_hash_parity.py enforces).
|
|
16
|
+
apiVersion: github.com/ruinosus/dna/core/v1
|
|
17
|
+
kind: KindDefinition
|
|
18
|
+
metadata:
|
|
19
|
+
name: eval-baseline
|
|
20
|
+
spec:
|
|
21
|
+
target_api_version: github.com/ruinosus/dna/eval/v1
|
|
22
|
+
target_kind: EvalBaseline
|
|
23
|
+
alias: eval-eval-baseline
|
|
24
|
+
origin: github.com/ruinosus/dna/eval
|
|
25
|
+
plane: record
|
|
26
|
+
prompt_target: false
|
|
27
|
+
flatten_in_context: false
|
|
28
|
+
prompt_target_priority: 0
|
|
29
|
+
storage:
|
|
30
|
+
type: yaml
|
|
31
|
+
container: eval-baselines
|
|
32
|
+
schema:
|
|
33
|
+
type: object
|
|
34
|
+
required:
|
|
35
|
+
- suite
|
|
36
|
+
- run_name
|
|
37
|
+
additionalProperties: false
|
|
38
|
+
properties:
|
|
39
|
+
suite:
|
|
40
|
+
type: string
|
|
41
|
+
description: Name of the EvalSuite this baseline belongs to.
|
|
42
|
+
run_name:
|
|
43
|
+
type: string
|
|
44
|
+
description: Name of the pinned EvalRun document.
|
|
45
|
+
pinned_at:
|
|
46
|
+
type: string
|
|
47
|
+
format: date-time
|
|
48
|
+
label:
|
|
49
|
+
type: string
|
|
50
|
+
description: Human note on why this run is the reference.
|
|
51
|
+
describe: '{suite} → {run_name}'
|
|
52
|
+
summary:
|
|
53
|
+
suite: ''
|
|
54
|
+
run_name: ''
|
|
55
|
+
graph_style:
|
|
56
|
+
fill: '#F59E0B'
|
|
57
|
+
stroke: '#D97706'
|
|
58
|
+
text_color: '#fff'
|
|
59
|
+
ascii_icon: 📌
|
|
60
|
+
display_label: Eval Baselines
|
|
61
|
+
docs: An EvalBaseline pins one EvalRun as the "known good" reference
|
|
62
|
+
for an EvalSuite. `dna eval run <suite> --baseline <name>` compares
|
|
63
|
+
the fresh run against the pinned run and reports regressions (passed
|
|
64
|
+
→ now failing), improvements and unchanged cases — with an exit code
|
|
65
|
+
a user's CI can gate on. Pin with `dna eval pin <run>`.
|