@vimhead.dev/norn-cli 0.1.0-tip.35347037721.1 → 0.1.0-tip.35390859630.1
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/assets/README.md +50 -16
- package/assets/docs/README.md +3 -3
- package/assets/docs/agents.md +12 -1
- package/assets/docs/cli.md +5 -5
- package/assets/docs/composition.md +21 -21
- package/assets/docs/persistence.md +7 -10
- package/assets/docs/projects.md +30 -18
- package/assets/docs/providers.md +1 -1
- package/assets/docs/recovery.md +13 -9
- package/assets/docs/resources.md +4 -19
- package/assets/docs/schemas.md +1 -1
- package/assets/docs/workflows.md +95 -7
- package/assets/examples/agent-then-analysis/README.md +4 -4
- package/assets/examples/agent-then-analysis/input.json +1 -1
- package/assets/examples/agent-then-analysis/norn.project.json +1 -1
- package/assets/examples/agent-then-analysis/plugin.ts +55 -68
- package/assets/examples/caller-selected-continuation/README.md +5 -5
- package/assets/examples/caller-selected-continuation/caller.ts +35 -38
- package/assets/examples/caller-selected-continuation/input.json +2 -2
- package/assets/examples/caller-selected-continuation/norn.project.json +1 -1
- package/assets/examples/caller-selected-continuation/producer.ts +15 -23
- package/assets/examples/coordinating-multiple-agents/README.md +2 -2
- package/assets/examples/coordinating-multiple-agents/input.json +1 -1
- package/assets/examples/coordinating-multiple-agents/norn.project.json +1 -1
- package/assets/examples/coordinating-multiple-agents/plugin.ts +52 -56
- package/assets/examples/coordinating-multiple-agents/queue-adapter.ts +4 -4
- package/assets/examples/getting-started/README.md +26 -0
- package/assets/examples/getting-started/norn.project.json +4 -0
- package/assets/examples/getting-started/plugin.ts +20 -0
- package/assets/examples/minimal-workflow/README.md +8 -8
- package/assets/examples/minimal-workflow/norn.project.json +1 -1
- package/assets/examples/minimal-workflow/plugin.ts +11 -25
- package/assets/examples/shared-state/README.md +10 -2
- package/assets/examples/shared-state/input.json +1 -1
- package/assets/examples/shared-state/norn.project.json +1 -1
- package/assets/examples/shared-state/plugin.ts +36 -41
- package/assets/examples/shared-state/shared-state.ts +75 -0
- package/assets/{packages/sdk/src → examples/shared-state}/state-adapter.ts +17 -16
- package/assets/examples/worktree-development-loop/README.md +6 -7
- package/assets/examples/worktree-development-loop/norn.project.json +1 -1
- package/assets/examples/worktree-development-loop/plugin.ts +6 -26
- package/assets/examples/worktree-development-loop/scope.ts +4 -0
- package/assets/examples/worktree-development-loop/workflows/development-loop/execute.ts +14 -15
- package/assets/examples/worktree-development-loop/workflows/development-loop/index.ts +3 -4
- package/assets/examples/worktree-development-loop/workflows/development-loop/schema.ts +2 -2
- package/assets/examples/worktree-development-loop/workflows/implementation/execute.ts +34 -33
- package/assets/examples/worktree-development-loop/workflows/implementation/index.ts +2 -3
- package/assets/examples/worktree-development-loop/workflows/implementation/schema.ts +7 -3
- package/assets/examples/worktree-development-loop/workflows/planning/execute.ts +23 -16
- package/assets/examples/worktree-development-loop/workflows/planning/index.ts +2 -3
- package/assets/examples/worktree-development-loop/workflows/planning/schema.ts +4 -2
- package/assets/examples/worktree-development-loop/workflows/review/execute.ts +40 -31
- package/assets/examples/worktree-development-loop/workflows/review/index.ts +3 -4
- package/assets/examples/worktree-development-loop/workflows/review/schema.ts +5 -4
- package/assets/examples/worktree-development-loop/workflows/review-router/execute.ts +49 -44
- package/assets/examples/worktree-development-loop/workflows/review-router/index.ts +2 -3
- package/assets/examples/worktree-development-loop/workflows/review-router/schema.ts +4 -3
- package/assets/package.json +1 -1
- package/assets/packages/cli/src/cli.ts +35 -34
- package/assets/packages/cli/src/client.ts +9 -16
- package/assets/packages/cli/src/documentation-intro.ts +1 -1
- package/assets/packages/cli/src/generated-build-info.ts +2 -2
- package/assets/packages/cli/src/internal/agent-response-tool.ts +3 -3
- package/assets/packages/cli/src/internal/engine.ts +38 -62
- package/assets/packages/cli/src/internal/errors.ts +4 -4
- package/assets/packages/cli/src/internal/launch-request.ts +6 -6
- package/assets/packages/cli/src/internal/run-state.ts +31 -21
- package/assets/packages/cli/src/internal/run.ts +2 -5
- package/assets/packages/cli/src/internal/workflow-registry.ts +114 -111
- package/assets/packages/cli/src/workflow-loader.ts +214 -0
- package/assets/packages/core/src/workflow-transition.ts +2 -2
- package/assets/packages/sdk/src/api.ts +133 -289
- package/assets/packages/sdk/src/index.ts +1 -1
- package/assets/packages/sdk/src/schema.ts +3 -3
- package/assets/tests/workflow-ref.test.ts +50 -51
- package/dist/cli.js +33 -32
- package/dist/client.d.ts +3 -4
- package/dist/client.js +3 -8
- package/dist/documentation-intro.js +1 -1
- package/dist/generated-build-info.d.ts +2 -2
- package/dist/generated-build-info.js +2 -2
- package/dist/internal/agent-response-tool.js +3 -3
- package/dist/internal/engine.d.ts +4 -8
- package/dist/internal/engine.js +36 -49
- package/dist/internal/errors.d.ts +3 -3
- package/dist/internal/errors.js +1 -1
- package/dist/internal/launch-request.d.ts +4 -4
- package/dist/internal/launch-request.js +2 -2
- package/dist/internal/run-state.d.ts +9 -8
- package/dist/internal/run-state.js +29 -20
- package/dist/internal/run.d.ts +1 -3
- package/dist/internal/run.js +3 -5
- package/dist/internal/workflow-registry.d.ts +25 -17
- package/dist/internal/workflow-registry.js +107 -72
- package/dist/{plugin-loader.d.ts → workflow-loader.d.ts} +7 -8
- package/dist/workflow-loader.js +235 -0
- package/package.json +3 -3
- package/assets/examples/worktree-development-loop/manifest.ts +0 -26
- package/assets/examples/worktree-development-loop/state.ts +0 -23
- package/assets/examples/worktree-development-loop/workflows/development-loop/declaration.ts +0 -8
- package/assets/examples/worktree-development-loop/workflows/implementation/declaration.ts +0 -8
- package/assets/examples/worktree-development-loop/workflows/planning/declaration.ts +0 -8
- package/assets/examples/worktree-development-loop/workflows/review/declaration.ts +0 -8
- package/assets/examples/worktree-development-loop/workflows/review-router/declaration.ts +0 -12
- package/assets/packages/cli/src/internal/run-resources.ts +0 -23
- package/assets/packages/cli/src/internal/state-store.ts +0 -83
- package/assets/packages/cli/src/plugin-loader.ts +0 -400
- package/dist/internal/run-resources.d.ts +0 -6
- package/dist/internal/run-resources.js +0 -26
- package/dist/internal/state-store.d.ts +0 -23
- package/dist/internal/state-store.js +0 -103
- package/dist/plugin-loader.js +0 -341
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Aleksandr Zub
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/assets/README.md
CHANGED
|
@@ -1,21 +1,55 @@
|
|
|
1
1
|
# Norn
|
|
2
2
|
|
|
3
|
-
Norn is a
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
3
|
+
Norn is a portable runtime for reusable agent-driven and code-driven TypeScript
|
|
4
|
+
workflows. Author them with the SDK, then discover, run, inspect, and recover them
|
|
5
|
+
through the CLI from any harness. Agents run on the bundled
|
|
6
|
+
[Pi coding agent](https://pi.dev); code-only workflows need no model.
|
|
7
|
+
|
|
8
|
+
## Getting started
|
|
9
|
+
|
|
10
|
+
1. [Install Norn](#installation), including agent authentication.
|
|
11
|
+
|
|
12
|
+
2. **Combine an agent with code.** The agent writes a summary; code saves it as an artifact.
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
import { workflow } from "@vimhead.dev/norn";
|
|
16
|
+
import { Type } from "typebox";
|
|
17
|
+
|
|
18
|
+
const summarize = workflow({
|
|
19
|
+
id: "summary.write",
|
|
20
|
+
isEntrypoint: true,
|
|
21
|
+
instructions: "Summarize supplied text and save the result.",
|
|
22
|
+
args: Type.Object({ text: Type.String() }),
|
|
23
|
+
async execute({ args, run }) {
|
|
24
|
+
const summary = await run.agents.prompt({
|
|
25
|
+
label: "summarize",
|
|
26
|
+
tools: [],
|
|
27
|
+
prompt: `Summarize this text in one sentence:\n${args.text}`,
|
|
28
|
+
response: Type.Object({ text: Type.String() }),
|
|
29
|
+
});
|
|
30
|
+
const artifact = await run.artifacts.write("summary.txt", summary.text);
|
|
31
|
+
return run.complete({ artifacts: { summary: artifact } });
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
export default [summarize];
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
[Full example and project configuration](examples/getting-started/README.md)
|
|
39
|
+
|
|
40
|
+
3. **Run it** from the example directory:
|
|
41
|
+
|
|
42
|
+
```sh
|
|
43
|
+
printf '%s\n' '{"args":{"text":"Norn workflows combine agents and code. They run from any harness through the CLI."}}' \
|
|
44
|
+
| norn runs start summary.write
|
|
45
|
+
|
|
46
|
+
norn runs wait <run-id>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Replace `<run-id>` with the ID returned by `start`.
|
|
50
|
+
|
|
51
|
+
See the [documentation index](docs/README.md) for focused references and the
|
|
52
|
+
[SDK types](packages/sdk/src/api.ts) for API details.
|
|
19
53
|
|
|
20
54
|
## Installation
|
|
21
55
|
|
package/assets/docs/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Norn documentation
|
|
2
2
|
|
|
3
|
-
Norn capabilities are ordinary TypeScript
|
|
3
|
+
Norn capabilities are ordinary TypeScript workflows: an agent can write one during a task, register it in that project, exercise it, change it, and retain it for another caller. No generated project hierarchy or separate compilation step is required.
|
|
4
4
|
|
|
5
5
|
## Read by task
|
|
6
6
|
|
|
@@ -11,9 +11,9 @@ Norn capabilities are ordinary TypeScript plugins: an agent can write one during
|
|
|
11
11
|
| Discover contracts or invoke Norn from another harness | [CLI and client](cli.md) | [Create → run → change](../examples/minimal-workflow/README.md) |
|
|
12
12
|
| Configure providers, models, and authentication for Norn agents | [Providers and authentication](providers.md) | — |
|
|
13
13
|
| Delegate work with explicit inputs and structured results | [Norn agents](agents.md) | [Norn agent → saved artifact → analysis](../examples/agent-then-analysis/README.md) |
|
|
14
|
-
| Initialize
|
|
14
|
+
| Initialize resources, attach agent tools, or coordinate file mutations | [Resources and locking](resources.md) | [Explicit shared state](../examples/shared-state/README.md) |
|
|
15
15
|
| Implement a custom resource and adapter to coordinate concurrent agents | [Resource contracts](resources.md) | [Example-local work queue](../examples/coordinating-multiple-agents/README.md) |
|
|
16
|
-
| Retain evidence or choose a filesystem boundary | [
|
|
16
|
+
| Retain evidence or choose a filesystem boundary | [Persistence, artifacts, and workspaces](persistence.md) | [Norn agent → saved artifact → analysis](../examples/agent-then-analysis/README.md) |
|
|
17
17
|
| Reuse a workflow with a caller-selected continuation | [Composition](composition.md) | [Caller-selected continuation](../examples/caller-selected-continuation/README.md) |
|
|
18
18
|
| Repair a failed run without repeating earlier work | [Recovery and gates](recovery.md) | [Analysis-only repair](../examples/agent-then-analysis/README.md#repair-only-the-analysis-step) |
|
|
19
19
|
|
package/assets/docs/agents.md
CHANGED
|
@@ -4,6 +4,17 @@ A Norn agent is a workflow-managed session powered by the bundled, open-source a
|
|
|
4
4
|
|
|
5
5
|
The [Norn agent → saved artifact → analysis example](../examples/agent-then-analysis/README.md) is a complete two-session application. Agent outputs flow through a saved contract, not shared conversation history.
|
|
6
6
|
|
|
7
|
+
## Authoring types
|
|
8
|
+
|
|
9
|
+
Import Pi types used by Norn directly from the SDK:
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import type { CreateAgentSessionOptions, EventBus, PromptOptions, ToolDefinition } from "@vimhead.dev/norn";
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
These are Pi's original types, not Norn-specific copies. Installing the SDK
|
|
16
|
+
installs its Pi dependency automatically; no separate Pi installation is needed.
|
|
17
|
+
|
|
7
18
|
## One prompt or a retained session
|
|
8
19
|
|
|
9
20
|
`run.agents.prompt({ label, prompt, response, ...sessionOptions })` creates a Pi session for one prompt and returns the value described by the response schema, including any codec transformations—not `{ response, raw }`. You do not need to dispose this one-prompt session. See [schema input/output types](schemas.md#codecs-and-inputoutput-types).
|
|
@@ -50,7 +61,7 @@ Successful results and raw attempts are written under `current/logs/agents/`; Pi
|
|
|
50
61
|
|
|
51
62
|
## Prompts, tools, and resource loading
|
|
52
63
|
|
|
53
|
-
The default tool allowlist is `read`, `bash`, `edit`, `write`, plus the response tool. An explicit `tools: []` requests no built-in task tools, but still includes the response tool and any explicitly attached [resource-adapter tools](resources.md#explicit-agent-attachment). `resourceAdapters` is accepted by both session creation and one-shot prompting; omitting it attaches no
|
|
64
|
+
The default tool allowlist is `read`, `bash`, `edit`, `write`, plus the response tool. An explicit `tools: []` requests no built-in task tools, but still includes the response tool and any explicitly attached [resource-adapter tools](resources.md#explicit-agent-attachment). `resourceAdapters` is accepted by both session creation and one-shot prompting; omitting it attaches no resource tools.
|
|
54
65
|
|
|
55
66
|
Each session loads resources for its `cwd` and [Norn configuration](providers.md#norn-configuration). Installed provider extensions register before default-model selection. Both `run.agents.createSession` and `run.agents.prompt` accept per-session `model` and `thinkingLevel` overrides; omitted values use Pi's configured selection and defaults. Discoverable settings, skills, context files, and extensions can therefore affect it. It does **not** inherit the outer conversation or its in-memory tool registrations. Loaded extensions may change active tools; the requested tool list alone is not an adversarial restriction.
|
|
56
67
|
|
package/assets/docs/cli.md
CHANGED
|
@@ -108,7 +108,7 @@ norn commands inspect runs.start
|
|
|
108
108
|
norn help runs start
|
|
109
109
|
```
|
|
110
110
|
|
|
111
|
-
Default workflow listing shows entrypoints; `--all` includes internal steps. Workflow inspection returns instructions,
|
|
111
|
+
Default workflow listing shows entrypoints; `--all` includes internal steps. Workflow inspection returns instructions, args JSON Schema, isolation, gate metadata, workflow/scope configuration schemas and keys, and registration source locations. [Loading diagnostics](projects.md#diagnose-registration) are part of the discovery envelope.
|
|
112
112
|
|
|
113
113
|
Help is text; ordinary results are JSON. `runs logs` emits JSONL events.
|
|
114
114
|
`norn pi [arguments...]` is a passthrough to bundled Pi, preserving Pi's native
|
|
@@ -121,7 +121,7 @@ Commands and schemas from the invoked executable are authoritative when a checko
|
|
|
121
121
|
From inside the target project:
|
|
122
122
|
|
|
123
123
|
```bash
|
|
124
|
-
printf '%s\n' '{"
|
|
124
|
+
printf '%s\n' '{"args":{"name":"Ada"}}' | norn runs start greeting.write
|
|
125
125
|
norn runs wait <run>
|
|
126
126
|
norn runs inspect <run>
|
|
127
127
|
norn runs metrics <run>
|
|
@@ -131,7 +131,7 @@ Start returns `{ "run": ... }` with `id`, `name`, and `path`, after launching a
|
|
|
131
131
|
|
|
132
132
|
A completed capability's outputs are in `run.outcome.metadata`. Artifact refs resolve beneath `<run.path>/current/artifacts/`. The [minimal example](../examples/minimal-workflow/README.md) gives concrete output expectations.
|
|
133
133
|
|
|
134
|
-
Start stdin accepts `
|
|
134
|
+
Start stdin accepts `args` and optional `config`, with config overrides keyed independently by workflow ID or scope ID. Args are JSON, not CLI flags or TOON. For display, a JSON viewer can format a finite result; keep machine artifacts and JSONL events in their native format.
|
|
135
135
|
|
|
136
136
|
| Decision | GOOD | BAD |
|
|
137
137
|
|---|---|---|
|
|
@@ -167,7 +167,7 @@ import { createNornClient } from "@vimhead.dev/norn-cli/client";
|
|
|
167
167
|
const client = createNornClient({ spawnCwd: "/absolute/path/to/project" });
|
|
168
168
|
const started = await client.runs.start({
|
|
169
169
|
workflowId: "greeting.write",
|
|
170
|
-
|
|
170
|
+
args: { name: "Ada" },
|
|
171
171
|
});
|
|
172
172
|
const finished = await client.runs.wait(started.id);
|
|
173
173
|
if (finished.status !== "completed" || finished.health !== "healthy") {
|
|
@@ -178,6 +178,6 @@ console.log(finished.outcome?.metadata);
|
|
|
178
178
|
|
|
179
179
|
The client defaults to its own package's `bin/norn.mjs`. Its optional `executablePath` is a script launched through `process.execPath`, not an arbitrary standalone binary or shell command. Other languages can invoke the CLI directly with cwd, JSON stdin, and parsed stdout.
|
|
180
180
|
|
|
181
|
-
`workflows.list()` and `inspect()` use fresh
|
|
181
|
+
`workflows.list()` and `inspect()` use fresh discovery. `workflows.entries()` retains its loaded catalogue; create a new client to refresh those entries after source edits.
|
|
182
182
|
|
|
183
183
|
Sources: [CLI declarations and handlers](../packages/cli/src/cli.ts), [client API](../packages/cli/src/client.ts).
|
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
## Transfer, not a returning call
|
|
4
4
|
|
|
5
5
|
```ts
|
|
6
|
-
return
|
|
6
|
+
return analyze({ draftArtifact });
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
Return a workflow call to select the next step in the same run. Supply its complete input; TypeScript checks it against the declaration's
|
|
9
|
+
Return a workflow call to select the next step in the same run. Supply its complete input; TypeScript checks it against the declaration's args schema. The target must be registered in the loaded project.
|
|
10
10
|
|
|
11
|
-
This transfers control rather than calling a subroutine: awaiting the declaration does not execute the target or return its eventual result. Steps share run
|
|
11
|
+
This transfers control rather than calling a subroutine: awaiting the declaration does not execute the target or return its eventual result. Steps share run resources and artifacts, not local variables or agent conversations. `run.complete` completes the whole run.
|
|
12
12
|
|
|
13
|
-
For a dynamically selected string ID, use `return run.next(workflowId,
|
|
13
|
+
For a dynamically selected string ID, use `return run.next(workflowId, args)`. The selected target checks its input at runtime. `run.next` accepts IDs, not declarations or reference functions.
|
|
14
14
|
|
|
15
15
|
## Caller-selected workflow reference
|
|
16
16
|
|
|
@@ -18,17 +18,17 @@ The [caller-selected continuation example](../examples/caller-selected-continuat
|
|
|
18
18
|
runs a producer with either of two caller-selected consumers, forwarding caller
|
|
19
19
|
context alongside the producer's results. It needs no model or credentials.
|
|
20
20
|
|
|
21
|
-
A reusable capability can accept a workflow reference whose schema describes the values it contributes. The caller supplies the target and captures the remaining
|
|
21
|
+
A reusable capability can accept a workflow reference whose schema describes the values it contributes. The caller supplies the target and captures the remaining args:
|
|
22
22
|
|
|
23
23
|
```ts
|
|
24
24
|
import { artifactRefSchema, workflowRefSchema } from "@vimhead.dev/norn";
|
|
25
25
|
import { Type } from "typebox";
|
|
26
26
|
|
|
27
|
-
const
|
|
27
|
+
const argsSchema = Type.Object({
|
|
28
28
|
task: Type.String(),
|
|
29
29
|
next: Type.Union([
|
|
30
30
|
workflowRefSchema({
|
|
31
|
-
|
|
31
|
+
args: Type.Object({
|
|
32
32
|
resultArtifact: artifactRefSchema,
|
|
33
33
|
summary: Type.String(),
|
|
34
34
|
}),
|
|
@@ -42,33 +42,33 @@ A caller supplies the target and its own parameters:
|
|
|
42
42
|
|
|
43
43
|
```json
|
|
44
44
|
{
|
|
45
|
-
"
|
|
45
|
+
"args": {
|
|
46
46
|
"task": "Assess this import",
|
|
47
47
|
"next": {
|
|
48
48
|
"workflow": "importer.deliver",
|
|
49
|
-
"
|
|
49
|
+
"forwardArgs": { "batchId": "batch-17" }
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
-
Code uses a declaration's `.id` in the reference payload, not the declaration itself. A bare ID string is shorthand for an object reference with empty `
|
|
55
|
+
Code uses a declaration's `.id` in the reference payload, not the declaration itself. A bare ID string is shorthand for an object reference with empty `forwardArgs`.
|
|
56
56
|
|
|
57
|
-
Inside the workflow, `
|
|
57
|
+
Inside the workflow, `args.next` is a function. Supply only the result fields declared above:
|
|
58
58
|
|
|
59
59
|
```ts
|
|
60
|
-
return
|
|
61
|
-
?
|
|
60
|
+
return args.next
|
|
61
|
+
? args.next({ resultArtifact, summary })
|
|
62
62
|
: run.complete({ summary, artifacts: { result: resultArtifact } });
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
`importer.deliver` receives `batchId` from the caller plus `resultArtifact` and `summary` from the producer. Its
|
|
65
|
+
`importer.deliver` receives `batchId` from the caller plus `resultArtifact` and `summary` from the producer. Its args schema must accept all three. Produced fields replace caller fields with the same name; nested objects are replaced, not deep-merged.
|
|
66
66
|
|
|
67
67
|
Contributions must be JSON objects matching the declared input type. Object-valued records, unions, intersections and codecs are supported. With codecs, supply `StaticEncode` values, just as for a direct workflow call—not transformed `StaticDecode` values.
|
|
68
68
|
|
|
69
|
-
`workflows inspect` shows the contribution contract under `x-norn-workflow-ref.
|
|
69
|
+
`workflows inspect` shows the contribution contract under `x-norn-workflow-ref.contributedArgsSchema`. Use it alongside the target's args schema to check that the combined input fits.
|
|
70
70
|
|
|
71
|
-
When passing a reference as input to another workflow, supply its JSON form shown above, not the function received in `
|
|
71
|
+
When passing a reference as input to another workflow, supply its JSON form shown above, not the function received in `args.next`.
|
|
72
72
|
|
|
73
73
|
## Multiple outcomes and direct targets
|
|
74
74
|
|
|
@@ -77,21 +77,21 @@ References can be nested under ordinary author-selected names with independent c
|
|
|
77
77
|
```ts
|
|
78
78
|
const next = Type.Object({
|
|
79
79
|
success: workflowRefSchema({
|
|
80
|
-
|
|
80
|
+
args: Type.Object({ resultArtifact: artifactRefSchema }),
|
|
81
81
|
}),
|
|
82
82
|
failure: workflowRefSchema({
|
|
83
|
-
|
|
83
|
+
args: Type.Object({ reason: Type.String() }),
|
|
84
84
|
}),
|
|
85
85
|
});
|
|
86
86
|
```
|
|
87
87
|
|
|
88
|
-
An implementation can return `
|
|
88
|
+
An implementation can return `args.next.success({ resultArtifact })`, `args.next.failure({ reason })`, or select its own known target with `manualReviewWorkflow({ task, reason })`. A dynamic target still uses `run.next(selectedId, input)`.
|
|
89
89
|
|
|
90
90
|
These are alternative transitions, not fan-out. `success` and `failure` are not reserved names, and a failure reference does not catch unhandled exceptions automatically.
|
|
91
91
|
|
|
92
92
|
| Decision | GOOD | BAD |
|
|
93
93
|
|---|---|---|
|
|
94
|
-
| IF the caller selects the next step, THEN invoke its reference with the declared contribution. ELSE call a known declaration or use a dynamic ID. | `
|
|
94
|
+
| IF the caller selects the next step, THEN invoke its reference with the declared contribution. ELSE call a known declaration or use a dynamic ID. | `args.next({ resultArtifact })` | Manually reconstruct captured forwarding input. |
|
|
95
95
|
| IF additional caller work follows the result, THEN represent it as the supplied reference. ELSE complete the run. | `assess → caller.deliver` | Expect execution to return to the line following a workflow call. |
|
|
96
96
|
| IF a target schema changes, THEN exercise the assembled input contract. ELSE preserve its existing input contract. | Verify the target accepts captured context and contributed results. | Treat contribution metadata as end-to-end compatibility proof. |
|
|
97
97
|
|
|
@@ -99,7 +99,7 @@ The [worktree development loop](../examples/worktree-development-loop/README.md)
|
|
|
99
99
|
|
|
100
100
|
## Another project or harness
|
|
101
101
|
|
|
102
|
-
Reuse source by explicitly registering it, directly or through [included config](projects.md). There is no required package layout.
|
|
102
|
+
Reuse source by explicitly registering it, directly or through [included config](projects.md). There is no required package layout. Workflow IDs must remain unique within a project; shared scopes follow the [scope declaration contract](workflows.md#shared-scopes-and-configuration). Resources and artifacts belong to the invoking project/run, not the workflow source directory.
|
|
103
103
|
|
|
104
104
|
An external shell, Python program, or agent harness can call the [CLI](cli.md) from the target project directory. The JavaScript client offers the same lifecycle without inventing another orchestration layer. Separate CLI starts create separate runs; connecting their artifact content is a caller responsibility, unlike same-run references.
|
|
105
105
|
|
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Persistence, artifacts, and workspaces
|
|
2
2
|
|
|
3
3
|
## Choose what survives
|
|
4
4
|
|
|
5
5
|
| Value | Lifetime and access |
|
|
6
6
|
|---|---|
|
|
7
|
-
| Local variables /
|
|
8
|
-
| Factory context `state` / `client.state` | In-memory registration state for the loaded project, not a selected run's persisted state. |
|
|
9
|
-
| `run.state` | Per-run, schema-validated JSON shared across steps. `get` requires a value; `getOptional` permits absence; `set` persists it. |
|
|
7
|
+
| Local variables / module memory | Current invocation or executor only; not a resume contract. |
|
|
10
8
|
| `run.resources` data | Per-run data included in checkpoint recovery. Resume reopens handles; closures do not survive. |
|
|
11
9
|
| `run.artifacts` | Text files addressed by `{ path }` relative to this run's artifacts directory. Write content, pass the ref, read and validate at the consumer. |
|
|
12
10
|
| Outcome metadata | Caller-facing summary, artifact/log refs and small data, exposed by run inspection. |
|
|
13
|
-
| Workflow
|
|
11
|
+
| Workflow args | Explicit input to the current/next step, persisted for recovery. |
|
|
14
12
|
|
|
15
|
-
|
|
13
|
+
Use arguments for step inputs, artifacts for retained outputs, and [resources](resources.md) for mutable storage. The [shared-state example](../examples/shared-state/README.md) provides a custom store; Norn has no dedicated application-state API. The [agent example](../examples/agent-then-analysis/plugin.ts) saves a draft artifact and passes its reference explicitly to analysis.
|
|
16
14
|
|
|
17
|
-
Artifact refs are paths, not content hashes, and
|
|
15
|
+
Artifact refs are paths, not content hashes, and writing to the same path replaces its content. An artifact read returns text, so a JSON consumer still needs parsing and schema validation. Separate artifact and resource writes are not one transaction.
|
|
18
16
|
|
|
19
17
|
| Decision | GOOD | BAD |
|
|
20
18
|
|---|---|---|
|
|
@@ -31,7 +29,6 @@ current/
|
|
|
31
29
|
workspace/ working files
|
|
32
30
|
artifacts/ capability evidence and results
|
|
33
31
|
resources/ resource definitions and data
|
|
34
|
-
state.json workflow state values
|
|
35
32
|
run-state.json scheduler state
|
|
36
33
|
manifest.json recorded events
|
|
37
34
|
logs/ command and agent output
|
|
@@ -51,8 +48,8 @@ store/ snapshot manifests and content-addressed objects
|
|
|
51
48
|
| Decision | GOOD | BAD |
|
|
52
49
|
|---|---|---|
|
|
53
50
|
| IF work needs existing project files, THEN declare project isolation or explicitly prepare a copy/worktree inside the run workspace. ELSE use the empty per-run workspace. | A project-mode verifier checks the actual project; an editing workflow prepares its own worktree. | Run `npm test` in an empty workspace and assume the repository is present. |
|
|
54
|
-
| IF rollback must undo a change, THEN keep it in snapshotted run files or separately manage the external effect. ELSE do not promise rollback of that change. | Reconcile a project-root edit or remote delivery explicitly. | Assume snapshots restore project
|
|
51
|
+
| IF rollback must undo a change, THEN keep it in snapshotted run files or separately manage the external effect. ELSE do not promise rollback of that change. | Reconcile a project-root edit or remote delivery explicitly. | Assume snapshots restore project workflow source, remote APIs, or symlink targets. |
|
|
55
52
|
|
|
56
53
|
Snapshots cover `current/`, preserve symlinks as links rather than copying targets, and do not include project-root source. [Recovery](recovery.md) defines when snapshots are taken and how to select a retry boundary.
|
|
57
54
|
|
|
58
|
-
Sources: [
|
|
55
|
+
Sources: [artifacts](../packages/cli/src/internal/artifacts.ts), [run paths](../packages/cli/src/internal/run.ts), [snapshot store](../packages/cli/src/internal/run-store.ts).
|
package/assets/docs/projects.md
CHANGED
|
@@ -8,44 +8,54 @@ norn project init
|
|
|
8
8
|
|
|
9
9
|
Initialization creates `norn.project.json`, `.norn/runs/`, and a run-state exclusion in `.gitignore`. Project discovery walks upward from the invocation directory to the nearest `norn.project.json`.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Register workflow modules explicitly:
|
|
12
12
|
|
|
13
13
|
```json
|
|
14
14
|
{
|
|
15
15
|
"version": 1,
|
|
16
|
-
"
|
|
17
|
-
"config": {
|
|
18
|
-
"example": { "repositoryRoot": "." }
|
|
19
|
-
}
|
|
16
|
+
"workflows": ["./workflows/index.ts"]
|
|
20
17
|
}
|
|
21
18
|
```
|
|
22
19
|
|
|
23
|
-
|
|
20
|
+
Each module default-exports an array of complete [workflow definitions](workflows.md):
|
|
24
21
|
|
|
25
|
-
|
|
22
|
+
```ts
|
|
23
|
+
import { summarize } from "./summarize.ts";
|
|
24
|
+
import { save } from "./save.ts";
|
|
25
|
+
|
|
26
|
+
export default [summarize, save];
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Arrays may contain standalone workflows and workflows from multiple scopes. Only array entries are registered; importing or calling a target does not register it. Include internal transition targets as well as entrypoints. The [minimal example](../examples/minimal-workflow/README.md) needs only its project file and workflow module.
|
|
30
|
+
|
|
31
|
+
The optional `config` object contains independently keyed [workflow and scope configuration](workflows.md#shared-scopes-and-configuration). Omit entries for owners without a config schema.
|
|
32
|
+
|
|
33
|
+
Reusable config files, conventionally `norn.json`, can declare `workflows`, `includes`, and `config`:
|
|
26
34
|
|
|
27
35
|
```json
|
|
28
36
|
{
|
|
29
37
|
"version": 1,
|
|
30
|
-
"
|
|
38
|
+
"workflows": ["./local-workflows.ts"],
|
|
31
39
|
"includes": ["./packages/*/norn.json"]
|
|
32
40
|
}
|
|
33
41
|
```
|
|
34
42
|
|
|
35
|
-
|
|
43
|
+
Workflow and include paths resolve relative to the file declaring them. `*` matches one directory segment. There is no automatic workflow tree scan or inclusion of a sibling `norn.json`. Project config overrides included values; conflicting reusable values are rejected. `version` belongs only in the project file.
|
|
44
|
+
|
|
45
|
+
Workflow IDs must be unique. Workflows can share a scope across modules by importing one scope definition; independent declarations of the same scope ID conflict.
|
|
36
46
|
|
|
37
47
|
## Import and reload
|
|
38
48
|
|
|
39
|
-
|
|
49
|
+
TypeScript modules need no local build. Runtime imports are supplied for `@vimhead.dev/norn`, its `/files` and `/schema` subpaths, `typebox`, `typebox/value`, `typebox/compile`, and `typebox/schema`. Other dependencies need normal package resolution from the workflow module's location.
|
|
40
50
|
|
|
41
|
-
Runtime
|
|
51
|
+
Runtime imports do not configure TypeScript or an editor. A matching `@vimhead.dev/norn` installation provides SDK types; the source checkout's examples are checked by its `tsconfig.json`. A successful runtime import alone is not a type check.
|
|
42
52
|
|
|
43
|
-
New CLI discovery/start/resume invocations load current source; an already executing workflow retains its loaded
|
|
53
|
+
New CLI discovery/start/resume invocations load current source; an already executing workflow retains its loaded definition. Discovery does not invoke workflow execution or gate descriptions. Module-level code still executes during import.
|
|
44
54
|
|
|
45
55
|
| Decision | GOOD | BAD |
|
|
46
56
|
|---|---|---|
|
|
47
|
-
| IF source changes, THEN inspect it through a new invocation before starting or resuming. ELSE use the inspected
|
|
48
|
-
| IF importing a
|
|
57
|
+
| IF source changes, THEN inspect it through a new invocation before starting or resuming. ELSE use the inspected definition. | Edit a workflow, inspect it, then resume. | Assume a running executor hot-reloads edits. |
|
|
58
|
+
| IF importing a module can mutate files or start work, THEN move those effects into workflow execution. ELSE keep import-time definitions. | `execute` launches the command. | `workflows list` starts a delivery from top-level code. |
|
|
49
59
|
|
|
50
60
|
## Diagnose registration
|
|
51
61
|
|
|
@@ -55,12 +65,14 @@ norn workflows list --all
|
|
|
55
65
|
norn workflows inspect example.plan
|
|
56
66
|
```
|
|
57
67
|
|
|
58
|
-
Discovery returns `isComplete` and `diagnostics
|
|
68
|
+
Discovery returns `isComplete` and `diagnostics`, with source paths, stage, message, and schema issues when available. An invalid registration module is excluded as a whole; conflicting workflow IDs or scope declarations exclude the conflicting modules. `import` covers module evaluation as well as syntax/import errors.
|
|
69
|
+
|
|
70
|
+
Workflow inspection exposes argument and configuration schemas, separate workflow/scope config keys, and the registration module and declaring configuration file. The registration module is not necessarily the file containing the implementation.
|
|
59
71
|
|
|
60
|
-
Discovery can exit successfully with an incomplete catalogue. Start, resume, and executable client entries require the entire project to load; otherwise they report `NORN_PROJECT_INVALID`. Malformed project/include configuration
|
|
72
|
+
Discovery can exit successfully with an incomplete catalogue. Start, resume, and executable client entries require the entire project to load; otherwise they report `NORN_PROJECT_INVALID`. Malformed project/include configuration is fatal rather than producing a partial catalogue.
|
|
61
73
|
|
|
62
74
|
| Decision | GOOD | BAD |
|
|
63
75
|
|---|---|---|
|
|
64
|
-
| IF `isComplete` is false, THEN repair or explicitly remove the
|
|
76
|
+
| IF `isComplete` is false, THEN repair or explicitly remove the invalid registration and inspect again. ELSE select from the loaded contracts. | Fix the named config field or default export. | Launch a valid sibling from an incomplete project. |
|
|
65
77
|
|
|
66
|
-
|
|
78
|
+
Next: [write a workflow](workflows.md), [reuse across projects](composition.md).
|
package/assets/docs/providers.md
CHANGED
|
@@ -46,7 +46,7 @@ Finding a configured key or listing a model is not proof that a provider accepts
|
|
|
46
46
|
|
|
47
47
|
## Third-party provider packages
|
|
48
48
|
|
|
49
|
-
Pi provider extensions are separate from Norn workflow
|
|
49
|
+
Pi provider extensions are separate from Norn workflow modules and outer-harness
|
|
50
50
|
adapters. They register providers through Pi's APIs; do not put them in
|
|
51
51
|
`norn.project.json` or install them only in Cursor's plugin marketplace.
|
|
52
52
|
|
package/assets/docs/recovery.md
CHANGED
|
@@ -10,19 +10,19 @@ norn runs checkpoints <run>
|
|
|
10
10
|
|
|
11
11
|
`<run>` is the ID or generated name returned by start. Inspection exposes status, health, current workflow, failure/interruption, and outcome metadata. Logs are newline-delimited events; agent and command evidence is retained in the run's current files. [CLI details](cli.md) explain launch/wait semantics.
|
|
12
12
|
|
|
13
|
-
Checkpoints are taken at run start, successful transitions, gate interruptions, and completion. Failure/stopping does not create a new successful boundary. A transition snapshot contains the saved preceding work and the next step's
|
|
13
|
+
Checkpoints are taken at run start, successful transitions, gate interruptions, and completion. Failure/stopping does not create a new successful boundary. A transition snapshot contains the saved preceding work and the next step's args.
|
|
14
14
|
|
|
15
15
|
| Observed state | Action | GOOD | BAD |
|
|
16
16
|
|---|---|---|---|
|
|
17
|
-
| `failed` or `stopped` | IF execution must continue, THEN repair the cause, select an earlier active checkpoint, rollback, and resume without
|
|
18
|
-
| `interrupted` | IF the declared decision is available within authorization, THEN resume with the permitted
|
|
19
|
-
| `pendingResume` | IF retry is intended, THEN resume with no
|
|
17
|
+
| `failed` or `stopped` | IF execution must continue, THEN repair the cause, select an earlier active checkpoint, rollback, and resume without args. ELSE leave the run inactive. | Retry delivery from the transition after assessment. | Resume a failed run directly or restart all assessments. |
|
|
18
|
+
| `interrupted` | IF the declared decision is available within authorization, THEN resume with the permitted argument patch. ELSE retain the interruption and identify the missing input. | An authorized agent evaluates evidence and supplies the decision. | Assume every gate requires a human or edit protected evidence fields. |
|
|
19
|
+
| `pendingResume` | IF retry is intended, THEN resume with no args. ELSE leave the restored boundary untouched. | `norn runs resume <run> </dev/null`. | Try to override arbitrary saved inputs through resume. |
|
|
20
20
|
| `running` with unhealthy inspection | IF the executor is no longer healthy, THEN inspect ownership and reconcile effects before recovery. ELSE monitor active execution. | Check run health and command evidence before retry. | Start a competing executor or equate stale status with successful delivery. |
|
|
21
21
|
|
|
22
22
|
## Source repair and rollback
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
|
-
# Edit the registered
|
|
25
|
+
# Edit the registered workflow source, then inspect its current contract.
|
|
26
26
|
norn workflows inspect <workflow-id>
|
|
27
27
|
norn runs checkpoints <run>
|
|
28
28
|
norn runs rollback <run> <checkpoint-id>
|
|
@@ -30,7 +30,7 @@ norn runs resume <run> </dev/null
|
|
|
30
30
|
norn runs wait <run>
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
Use the actual `cp_...` ID from checkpoint listing, not an index or invented name. Rollback restores the run's current files and active checkpoint history, then prepares the saved step for resume. A fresh CLI executor loads current
|
|
33
|
+
Use the actual `cp_...` ID from checkpoint listing, not an index or invented name. Rollback restores the run's current files and active checkpoint history, then prepares the saved step for resume. A fresh CLI executor loads current workflow source. It does not restore the source version that created the checkpoint, and saved args/state must remain compatible with the repaired implementation.
|
|
34
34
|
|
|
35
35
|
Rollback restores only [snapshotted files](persistence.md). It does not undo project-root edits, remote deliveries, or other external effects. Re-execution is not an exactly-once guarantee.
|
|
36
36
|
|
|
@@ -41,6 +41,10 @@ Rollback restores only [snapshotted files](persistence.md). It does not undo pro
|
|
|
41
41
|
|
|
42
42
|
The [agent example's repair exercise](../examples/agent-then-analysis/README.md#repair-only-the-analysis-step) demonstrates preserving a live Norn agent result through analysis failure and source repair.
|
|
43
43
|
|
|
44
|
+
## Saved-run compatibility
|
|
45
|
+
|
|
46
|
+
Runs created before the complete-workflow API migration cannot be resumed or rolled back by this alpha. Their saved status remains inspectable, and existing files are preserved. Use the original runtime to continue those runs, or start a new run.
|
|
47
|
+
|
|
44
48
|
## Declared gates
|
|
45
49
|
|
|
46
50
|
A workflow can declare:
|
|
@@ -49,8 +53,8 @@ A workflow can declare:
|
|
|
49
53
|
gate: { enabled: true, fields: ["decision", "notes"] }
|
|
50
54
|
```
|
|
51
55
|
|
|
52
|
-
Its
|
|
56
|
+
Its args schema must include those top-level fields. An optional `gate.describe({ args, config, scope, run })` callback explains the decision, with the same inferred context as `execute`; standalone workflows have no `scope` property. The CLI uses pause mode: a gate interrupts **before** execution, including direct starts of a gated workflow.
|
|
53
57
|
|
|
54
|
-
Resume stdin has the form `{"
|
|
58
|
+
Resume stdin has the form `{"args":{"decision":"accept","notes":"Evidence checked"}}`. With declared `fields`, the patch merges into saved object args and rejects non-gate keys; without `fields`, resume supplies replacement args. The merged/replacement value is schema-validated. A gate is a persisted control boundary, not an automatic human approval mechanism or an authorization system.
|
|
55
59
|
|
|
56
|
-
Sources: [scheduler and resume](../packages/cli/src/internal/engine.ts), [saved state and
|
|
60
|
+
Sources: [scheduler and resume](../packages/cli/src/internal/engine.ts), [saved state and argument patches](../packages/cli/src/internal/run-state.ts), [snapshot restoration](../packages/cli/src/internal/run-store.ts), [CLI lifecycle](../packages/cli/src/cli.ts).
|
package/assets/docs/resources.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Initialization is separate from attachment
|
|
4
4
|
|
|
5
|
-
`run.resources` provides shared resource handles
|
|
5
|
+
`run.resources` provides shared resource handles. The [shared-state example](../examples/shared-state/README.md) demonstrates mutable storage as a custom resource.
|
|
6
6
|
|
|
7
7
|
`run.resources.ensure(definition)` returns a shared handle for that resource across workflow contexts in the current executor. A definition contains `name`, `kind`, JSON `configuration`, and `initialize({directory, files, mode})`. Names are single alphanumeric/underscore/hyphen identifiers starting with an alphanumeric character. Identity/configuration conflicts fail; `configuration` owns format/version compatibility.
|
|
8
8
|
|
|
@@ -17,28 +17,13 @@
|
|
|
17
17
|
|
|
18
18
|
## Explicit agent attachment
|
|
19
19
|
|
|
20
|
-
The [
|
|
21
|
-
|
|
22
|
-
```ts
|
|
23
|
-
resourceAdapters: [StateAdapter({
|
|
24
|
-
state: run.state,
|
|
25
|
-
fields: [
|
|
26
|
-
{ field: manifest.states.source, access: "read" },
|
|
27
|
-
{ field: manifest.states.copiedText, access: "write" },
|
|
28
|
-
],
|
|
29
|
-
})]
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
`StateAdapter` is exported from `@vimhead.dev/norn` and accepts the public workflow-state interface, without a storage path. `read-write` is also supported. This adapter adds `norn_state_list`, `norn_state_get`, and `norn_state_set`, including when `tools: []` is requested. Discovery lists only selected fields and their schemas/permissions. Each operation checks its grant; setting validates against the declared field schema. Unset reads return `isSet:false`.
|
|
33
|
-
|
|
34
|
-
List/get output is serialized JSON in bounded text pages. Requests specify UTF-16 `offset` and `limit` (1–10000); responses include `text`, `nextOffset` and a content `revision`. Pages are not a pinned snapshot. Set operations persist complete field values; get followed by set is not a transaction.
|
|
20
|
+
The [shared-state example](../examples/shared-state/README.md) supplies its own resource and permission-selected adapter. The [queue example](../examples/coordinating-multiple-agents/README.md) supplies a different resource and tool contract. Neither adapter is a built-in SDK state facility.
|
|
35
21
|
|
|
36
22
|
Custom adapters implement `NornAgentResourceAdapter`: a unique name and `bind({runId, label})` returning a `NornAgentResourceBinding` with tools and async `dispose()`. An adapter can expose one or several resource handles; initializing storage does not construct or attach tools. Session creation and one-shot prompting accept adapters through `resourceAdapters`, not through the resource manager or state handle directly. Attached tools are activated with the normal response tool. Duplicate adapter names and collisions with built-ins, the response tool, other adapters or already-loaded extension tools fail. Successful bindings are cleaned up in reverse order on session disposal or later creation failure. An initializer/binder that throws before returning its handle owns cleanup of its partial allocations.
|
|
37
23
|
|
|
38
24
|
| Decision | GOOD | BAD |
|
|
39
25
|
|---|---|---|
|
|
40
|
-
| IF a Norn agent needs
|
|
41
|
-
| IF combining pages, THEN compare their revisions and restart the read when they differ. ELSE use a single returned page as a fragment only. | Re-read a value changed between pages. | Concatenate pages from different revisions. |
|
|
26
|
+
| IF a Norn agent needs resource access, THEN attach an adapter exposing the required operations. ELSE omit the attachment. | A reviewer receives read-only access to a candidate. | Automatically expose every resource to every session. |
|
|
42
27
|
| IF disposing a binding, THEN release session-local handles only. ELSE retain the resource for later sessions. | Close a subscription. | Delete workflow state when its agent exits. |
|
|
43
28
|
|
|
44
29
|
The attachment never exposes internal scheduler/checkpoint control state. It is a cooperative tool boundary, not a sandbox against unrestricted filesystem tools or trusted extensions. [Agent loading](agents.md#prompts-tools-and-resource-loading) owns those limitations.
|
|
@@ -58,4 +43,4 @@ Reads of live command-output logs may return partial streams. File locks do not
|
|
|
58
43
|
| IF a callback holds a lock, THEN finish its short storage operation before prompting a model or taking another lock on the same file. ELSE release it first. | Persist a value and return. | Wait for a model turn while holding a file lock. |
|
|
59
44
|
| IF restoring a checkpoint, THEN restore resource data but not lock ownership. ELSE follow the owning external resource's recovery contract. | Built-in locks live under the run's `locks/`, outside `current/`. | Restore an old owner's lock directory as live ownership. |
|
|
60
45
|
|
|
61
|
-
Sources: [resource contracts](../packages/sdk/src/resources.ts), [resource manager](../packages/cli/src/resources.ts), [adapter contracts](../packages/sdk/src/agent-resource-adapter.ts), [
|
|
46
|
+
Sources: [resource contracts](../packages/sdk/src/resources.ts), [resource manager](../packages/cli/src/resources.ts), [adapter contracts](../packages/sdk/src/agent-resource-adapter.ts), [file coordinator](../packages/sdk/src/files.ts).
|
package/assets/docs/schemas.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# TypeBox schemas
|
|
2
2
|
|
|
3
|
-
The [Norn SDK](../packages/sdk/src/api.ts) accepts native `typebox` 1.x schemas for workflow
|
|
3
|
+
The [Norn SDK](../packages/sdk/src/api.ts) accepts native `typebox` 1.x schemas for workflow args, workflow/scope config, and agent responses. This reference is checked against 1.3.33. [Project loading](projects.md#import-and-reload) describes runtime-provided imports and editor dependency resolution.
|
|
4
4
|
|
|
5
5
|
## TypeScript → TypeBox
|
|
6
6
|
|