@archmax-ai/harness 0.0.0 → 0.2.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.
Files changed (143) hide show
  1. package/README.md +64 -47
  2. package/dist/agent.d.ts +0 -11
  3. package/dist/agent.js.map +1 -1
  4. package/dist/assembly/compose.js +3 -5
  5. package/dist/assembly/compose.js.map +1 -1
  6. package/dist/assembly/delegation-registry.js +4 -2
  7. package/dist/assembly/delegation-registry.js.map +1 -1
  8. package/dist/assembly/index.d.ts +1 -1
  9. package/dist/assembly/index.js +0 -1
  10. package/dist/assembly/index.js.map +1 -1
  11. package/dist/authoring-skill/archmax-harness/README.md +24 -18
  12. package/dist/authoring-skill/archmax-harness/SKILL.md +7 -1
  13. package/dist/authoring-skill/archmax-harness/references/backend-integration.md +66 -11
  14. package/dist/authoring-skill/archmax-harness/references/cases.md +1 -1
  15. package/dist/authoring-skill/archmax-harness/references/hook-and-test-scripts.md +2 -2
  16. package/dist/authoring-skill/archmax-harness/references/wiring.md +1 -1
  17. package/dist/authoring-skill/archmax-harness/references/workflow-schema.md +66 -20
  18. package/dist/authoring-skill/archmax-harness/references/workflow-yaml.md +14 -4
  19. package/dist/cli/bootstrap.d.ts +7 -3
  20. package/dist/cli/bootstrap.js.map +1 -1
  21. package/dist/cli/state-flow.js +3 -3
  22. package/dist/cli/state-flow.js.map +1 -1
  23. package/dist/cli/turn.d.ts +9 -4
  24. package/dist/cli/turn.js +36 -9
  25. package/dist/cli/turn.js.map +1 -1
  26. package/dist/cli.js +9 -10
  27. package/dist/cli.js.map +1 -1
  28. package/dist/core/events.d.ts +4 -9
  29. package/dist/core/events.js +5 -5
  30. package/dist/core/events.js.map +1 -1
  31. package/dist/core/workspace-context.d.ts +0 -2
  32. package/dist/core/workspace-context.js +0 -2
  33. package/dist/core/workspace-context.js.map +1 -1
  34. package/dist/core/zones.d.ts +0 -2
  35. package/dist/core/zones.js +0 -2
  36. package/dist/core/zones.js.map +1 -1
  37. package/dist/env.d.ts +0 -2
  38. package/dist/env.js +0 -2
  39. package/dist/env.js.map +1 -1
  40. package/dist/index.d.ts +15 -13
  41. package/dist/index.js +18 -7
  42. package/dist/index.js.map +1 -1
  43. package/dist/machine/machine.d.ts +9 -0
  44. package/dist/machine/machine.js +13 -0
  45. package/dist/machine/machine.js.map +1 -1
  46. package/dist/machine/signature.d.ts +104 -0
  47. package/dist/machine/signature.js +210 -0
  48. package/dist/machine/signature.js.map +1 -0
  49. package/dist/machine/spec-schema.d.ts +158 -8
  50. package/dist/machine/spec-schema.js +78 -6
  51. package/dist/machine/spec-schema.js.map +1 -1
  52. package/dist/machine/triggers.d.ts +6 -2
  53. package/dist/machine/triggers.js +7 -2
  54. package/dist/machine/triggers.js.map +1 -1
  55. package/dist/machine/types.d.ts +7 -1
  56. package/dist/machine/types.js.map +1 -1
  57. package/dist/machine/variables.d.ts +2 -0
  58. package/dist/machine/variables.js +4 -0
  59. package/dist/machine/variables.js.map +1 -1
  60. package/dist/public/spec.d.ts +20 -3
  61. package/dist/public/spec.js +18 -2
  62. package/dist/public/spec.js.map +1 -1
  63. package/dist/sandbox/executor.js.map +1 -1
  64. package/dist/sessions/resolve.d.ts +0 -2
  65. package/dist/sessions/resolve.js +1 -4
  66. package/dist/sessions/resolve.js.map +1 -1
  67. package/dist/sessions/resume.d.ts +4 -8
  68. package/dist/sessions/resume.js +10 -5
  69. package/dist/sessions/resume.js.map +1 -1
  70. package/dist/sessions/summary.d.ts +0 -2
  71. package/dist/sessions/summary.js +1 -1
  72. package/dist/sessions/summary.js.map +1 -1
  73. package/dist/testing/assertions.js +1 -5
  74. package/dist/testing/assertions.js.map +1 -1
  75. package/dist/testing/case-document.d.ts +1 -7
  76. package/dist/testing/case-document.js.map +1 -1
  77. package/dist/testing/case-schema.d.ts +2 -2
  78. package/dist/testing/case-schema.js +8 -21
  79. package/dist/testing/case-schema.js.map +1 -1
  80. package/dist/testing/driver.d.ts +4 -2
  81. package/dist/testing/driver.js +1 -1
  82. package/dist/testing/driver.js.map +1 -1
  83. package/dist/testing/grade.d.ts +2 -2
  84. package/dist/testing/grade.js +1 -1
  85. package/dist/testing/interpreter.d.ts +4 -2
  86. package/dist/testing/interpreter.js.map +1 -1
  87. package/dist/testing/runner.d.ts +13 -9
  88. package/dist/testing/runner.js +0 -1
  89. package/dist/testing/runner.js.map +1 -1
  90. package/dist/testing/target.d.ts +4 -2
  91. package/dist/workflow/control-tools.d.ts +7 -2
  92. package/dist/workflow/control-tools.js +27 -2
  93. package/dist/workflow/control-tools.js.map +1 -1
  94. package/dist/workflow/governance.js +28 -19
  95. package/dist/workflow/governance.js.map +1 -1
  96. package/dist/workflow/middleware.js +5 -10
  97. package/dist/workflow/middleware.js.map +1 -1
  98. package/dist/workflow/on-error.js +0 -1
  99. package/dist/workflow/on-error.js.map +1 -1
  100. package/dist/workflow/parks.js +9 -13
  101. package/dist/workflow/parks.js.map +1 -1
  102. package/dist/workflow/paths.d.ts +0 -1
  103. package/dist/workflow/paths.js +0 -1
  104. package/dist/workflow/paths.js.map +1 -1
  105. package/dist/workflow/prompt-cache.d.ts +0 -2
  106. package/dist/workflow/prompt-cache.js +0 -7
  107. package/dist/workflow/prompt-cache.js.map +1 -1
  108. package/dist/workflow/render-prompt.js +28 -7
  109. package/dist/workflow/render-prompt.js.map +1 -1
  110. package/dist/workflow/session-artifacts.d.ts +1 -3
  111. package/dist/workflow/session-artifacts.js +1 -2
  112. package/dist/workflow/session-artifacts.js.map +1 -1
  113. package/dist/workflow/session-view.d.ts +1 -1
  114. package/dist/workflow/signature-checks.d.ts +22 -0
  115. package/dist/workflow/signature-checks.js +52 -0
  116. package/dist/workflow/signature-checks.js.map +1 -0
  117. package/dist/workflow/state.d.ts +2 -14
  118. package/dist/workflow/state.js +3 -10
  119. package/dist/workflow/state.js.map +1 -1
  120. package/dist/workflow/sub-workflow.d.ts +23 -16
  121. package/dist/workflow/sub-workflow.js +78 -14
  122. package/dist/workflow/sub-workflow.js.map +1 -1
  123. package/dist/workflow/tool-service.js +3 -5
  124. package/dist/workflow/tool-service.js.map +1 -1
  125. package/dist/workflow/turn-boundary.js +5 -6
  126. package/dist/workflow/turn-boundary.js.map +1 -1
  127. package/dist/workflow/workflow-tools.d.ts +17 -9
  128. package/dist/workflow/workflow-tools.js +30 -17
  129. package/dist/workflow/workflow-tools.js.map +1 -1
  130. package/package.json +5 -4
  131. package/skills/archmax-harness/README.md +82 -0
  132. package/skills/archmax-harness/SKILL.md +247 -0
  133. package/skills/archmax-harness/references/backend-integration.md +681 -0
  134. package/skills/archmax-harness/references/cases.md +41 -0
  135. package/skills/archmax-harness/references/diagnostics.md +51 -0
  136. package/skills/archmax-harness/references/hook-and-test-scripts.md +1070 -0
  137. package/skills/archmax-harness/references/hooks-and-scripts.md +82 -0
  138. package/skills/archmax-harness/references/wiring.md +101 -0
  139. package/skills/archmax-harness/references/workflow-schema.md +1677 -0
  140. package/skills/archmax-harness/references/workflow-yaml.md +251 -0
  141. package/dist/behaviour/support.d.ts +0 -232
  142. package/dist/behaviour/support.js +0 -339
  143. package/dist/behaviour/support.js.map +0 -1
@@ -0,0 +1,247 @@
1
+ ---
2
+ name: archmax-harness
3
+ description: >-
4
+ Build with the @archmax-ai/harness runtime for LangChain Deep Agents. Use this
5
+ whenever you are designing, editing or fixing a workflow state machine (a
6
+ workflow.yaml with states, transitions, lifecycle hooks, tool and skill
7
+ governance, grading rubrics, scripts, cases, or skill bundles), OR wiring the
8
+ @archmax-ai/harness npm package into a backend service — assembling an agent with
9
+ createAgent, running a workflow, resuming human-in-the-loop states, or
10
+ streaming lifecycle events / session artifacts so a frontend can visualize a
11
+ run. Trigger this skill for phrases like "design a workflow", "author a
12
+ workflow.yaml", "add a state/transition/hook", "archmax validate fails", "run
13
+ an agent workflow from my worker", or "integrate @archmax-ai/harness" even when the
14
+ runtime is not named explicitly.
15
+ ---
16
+
17
+ # Building with @archmax-ai/harness
18
+
19
+ The archmax harness is a thin, governed runtime over
20
+ [LangChain Deep Agents](https://docs.langchain.com/oss/javascript/deepagents/overview):
21
+ one Deep Agent per workflow, moved by a declarative state machine
22
+ (`workflow.yaml`). It holds no use-case logic — a **workspace** supplies it.
23
+ Runtime contract: `runtime: { engine: archmax-harness, version: "2" }` in every spec.
24
+
25
+ **Read by task, not by curiosity.** This file holds the procedure, the
26
+ workspace layout and the commands. Load exactly the short reference your next
27
+ file needs, once, and nothing else:
28
+
29
+ | You are about to… | Load |
30
+ | --- | --- |
31
+ | write or edit `workflow.yaml` | [`references/workflow-yaml.md`](references/workflow-yaml.md) — every key, machine rules, governance |
32
+ | write a script — a skill's `scripts/*.js` (`archmax_run`) or a `hooks/*.js` gate | [`references/hooks-and-scripts.md`](references/hooks-and-scripts.md); sequence the skill case with the *Script playbook* below |
33
+ | write or fix a case (`tests/*.test.yaml`) | [`references/cases.md`](references/cases.md) |
34
+ | fix what `archmax validate` / `archmax test` reported | [`references/diagnostics.md`](references/diagnostics.md) |
35
+ | embed the package in a service | [`references/wiring.md`](references/wiring.md) |
36
+
37
+ The long references — `workflow-schema.md`, `hook-and-test-scripts.md`,
38
+ `backend-integration.md` — are exhaustive; open a **section** of one only when
39
+ the short reference says so or a field's exact semantics are in doubt. Do
40
+ **not** read the SDK source, do not `ls`/`glob` a workspace to discover its
41
+ layout (it is fixed, below), and do not re-read a file already in context.
42
+ Naming note: this authoring skill is not a workspace's `skills/<slug>/` bundle;
43
+ they share a file format and nothing else.
44
+
45
+ ---
46
+
47
+ ## Authoring
48
+
49
+ ### Procedure
50
+
51
+ **Build a workflow.** Design the whole file set first, write each file once,
52
+ then verify. Do not write a file, validate, and discover the next file.
53
+
54
+ 1. **Sketch the graph**: states (kebab-case slugs), the start state carrying
55
+ `triggers: { manual: }` (plus any host trigger ids that enter there),
56
+ terminal states (no `transitions`), the edges between them — and for each
57
+ edge, the *condition* under which it is taken. That condition is the edge's
58
+ required `description`, and it is the only thing the agent will know about
59
+ where the edge leads. If something outside the session calls the workflow
60
+ (another workflow, a host's MCP tool or form), give its trigger a
61
+ `description` for the caller and a `requires`/`returns` signature, typing an
62
+ entry (`{ name, type, description }`; `string` `integer` `number` `boolean`
63
+ `date` `date-time` `object` `array`) where the caller must build or read the
64
+ value. The runtime holds typed entries at start, at `archmax_set_variables`
65
+ and at completion ([`references/workflow-schema.md`](references/workflow-schema.md)).
66
+ 2. **Decide the file set** from the sketch: `workflow.yaml` always; one
67
+ `hooks/<check>.js` per *deterministic* gate; one inline `rubric:` per
68
+ *judgment* gate (tone, completeness); cases — one happy path per branch,
69
+ one per hook veto path, one `decide:` per human state; a
70
+ `skills/<capability>/` bundle only for data, an `archmax_run` script, or
71
+ guidance two or more states share identically; `AGENTS.md` only for a
72
+ workspace-wide persona.
73
+ 3. **Write `workflow.yaml`** from the skeleton in [`references/workflow-yaml.md`](references/workflow-yaml.md). Each state's behaviour
74
+ goes inline in its `instructions`; run-wide rules once in the top-level
75
+ `instructions`; nothing about the machine itself (the platform prompt and
76
+ the disclosed edges already say it, and prose is billed on every call), and
77
+ nothing about the date: every model call opens with the current date and time
78
+ in UTC (rounded down to ten minutes, with the host's zone named), so date
79
+ arithmetic ("due in 30 days") needs no authored `today`.
80
+ Never describe another state in a state's `instructions` or in an edge's
81
+ `description`: the agent is shown the active state's edges and nothing else
82
+ of the graph, so a routing condition parked in the *target's* `summary` or
83
+ `instructions` is invisible to the state that has to route on it. Name
84
+ a model (`settings.model`, or `model:` on one state) only where the work
85
+ differs in kind — a small model on mechanical states, the default on
86
+ drafting, judgement and heavy-routing ones.
87
+ 4. **Write hooks, rubrics, cases** — description first (a hook's JSDoc, a
88
+ case's `title` + `description`), then the body, and never leave the two
89
+ disagreeing. Before writing a case, settle what to mock ([`references/cases.md`](references/cases.md)).
90
+ 5. **Verify**: `archmax validate <slug>` → fix every error (and every warning
91
+ you can) → `archmax test <slug>`. Never call a workflow done without a clean
92
+ `validate`.
93
+
94
+ **Fix a workflow.** Diagnose from the tool, not by reading everything.
95
+
96
+ 1. Run `archmax validate <slug>` (offline, instant). Every diagnostic names
97
+ the file, the field path and the fix; map it with the
98
+ [`references/diagnostics.md`](references/diagnostics.md).
99
+ 2. Read **only** the files the diagnostics name. Edit once. Re-validate.
100
+ 3. When clean, `archmax test <slug> [filter]`. Read the failing case's verdict
101
+ line: a **structural** miss (`reachedState`, `parked`, `succeeded`,
102
+ `trail`) is a routing or governance defect — fix the routing state's
103
+ `instructions`, the transition `description`s, or the `tools`/`skills`
104
+ grants; a **content** miss (`reply`, `calledTool`, `grade`) is an
105
+ `instructions` defect in the state that answered; a veto reason quoted in
106
+ the reply is the hook or rubric speaking — fix what it names. Change the
107
+ case only when it asserts something the spec never promised.
108
+ 4. A `grade` miss is the one non-deterministic assertion: re-run that case
109
+ once before calling it a regression. Re-run with `--verbose` for raw
110
+ events only when the verdict line is not enough.
111
+
112
+ Budget: one validate, one edit pass, one validate, one test. If you are on
113
+ your fourth read of a file, you are guessing — reread the relevant reference
114
+ instead.
115
+
116
+ **Shapes come from tools, not from research.** Before naming any field of a
117
+ tool's result or a trigger's payload — in `instructions`, a `${{…}}` guard, a
118
+ hook — ask the host: a platform embedding this runtime typically exposes
119
+ describe-style tools (a tool's input and output schema, a trigger's payload
120
+ schema and sample) and a way to sample or invoke once with a narrow input. Call
121
+ those first; fall back to a recorded session's variables (`archmax sessions <id>`)
122
+ only when no such tool exists. Reading more files never reveals what a live
123
+ system returns.
124
+
125
+ ### Script playbook (a skill's `scripts/<x>.js`)
126
+
127
+ Deterministic work the model triggers with `archmax_run`. In order:
128
+
129
+ 1. **Shapes first.** Trigger payload and tool I/O from the host's describe/sample
130
+ tools; the variables a run actually carries from `archmax sessions <id>`.
131
+ Guessing a field name here costs a whole run (above).
132
+ 2. **Write it.** `skills/<cap>/scripts/<x>.js`: JSDoc, then the body. Input is the
133
+ global `args` — `args.<param>` from the model plus `args.variables`, a read-only
134
+ snapshot — and the **last expression** is the result. Contract:
135
+ [`references/hooks-and-scripts.md`](references/hooks-and-scripts.md).
136
+ 3. **Land the result in a variable.** Return structured data, and name the variable
137
+ in the calling state's `requires:`. A script may not call
138
+ `archmax_set_variables`, so `requires` is what makes the model record the return;
139
+ unrecorded, the result lives in one tool message and is gone.
140
+ 4. **Announce it in the skill.** The `SKILL.md` `description` says *when* to run it;
141
+ the body says the script's path, its arguments, and the variable its result
142
+ lands in. A script nothing points at is never reached.
143
+ 5. **Grant it.** The calling state allows `{ tool: archmax_run, paths:
144
+ ["skills/<cap>/scripts/**"] }` plus every tool the script itself calls. Then
145
+ `archmax validate`.
146
+
147
+ ### Reference a variable, never retype it
148
+
149
+ `${{name}}` / `${{a.b.-1.c}}` resolves against the run's variables in a
150
+ `tools.allow` glob **and inside any text argument the model writes** — mid-string,
151
+ repeatable, matched literally. The transcript keeps the reference and only the tool
152
+ sees the value, so a stored value costs its tokens once instead of on every later
153
+ model call. Step 3 is what puts a value there to reference.
154
+
155
+ A state that must emit something already stored is told to interpolate it:
156
+
157
+ ```yaml
158
+ instructions: >-
159
+ Send the reply with gmail__send. Quote the customer's message by writing
160
+ ${{inbound.text}} in the body rather than retyping it.
161
+ ```
162
+
163
+ Exact — a retyped copy truncates and drifts, a reference cannot — and it agrees by
164
+ construction with a guard on the same variable. Not available in scripts, which
165
+ read `args.variables`. To write the characters literally: `$${{name}}`.
166
+
167
+ ### Workspace layout (complete — nothing else exists)
168
+
169
+ ```
170
+ <workspace root>/
171
+ AGENTS.md # optional persona; prompt layer 1
172
+ workflows/<slug>/ # AUTHORING PLANE — runtime reads it, the agent CANNOT
173
+ workflow.yaml # the machine (required, canonical)
174
+ WORKFLOW.md # optional plain-markdown addendum, NO frontmatter
175
+ hooks/<check>.js # lifecycle hook scripts, run by the runtime
176
+ tests/<case>.test.yaml # one case per file; fixtures beside them (`from:`)
177
+ skills/<capability>/ # AGENT PLANE — mounted read-only, enabled per state by slug
178
+ SKILL.md # frontmatter (name = directory slug, description) + body
179
+ scripts/<script>.js # archmax_run sources, run by the agent
180
+ assets/<file> # read-only inputs
181
+ references/<topic>.md # optional deeper material
182
+ .env # ARCHMAX_* model config (never mounted)
183
+ sessions/<sessionId>/ # the run; the agent's workspace ROOT (never authored)
184
+ scratchpad/ # agent-visible `scratchpad/…`: the session's always-writable
185
+ # area (a host-wired writable mount is another place to write)
186
+ large_tool_results/ conversation_history/ # runtime offload, agent reads only
187
+ checkpoints/ artifacts/ # runtime-internal
188
+ ```
189
+
190
+ Rules that follow:
191
+
192
+ - **The agent cannot read `workflows/**`** — its spec, hooks, rubrics and
193
+ cases have no route in its workspace. Never point `instructions`,
194
+ `evidence` or a case `workspace:` at one (`validate` errors). Text the agent
195
+ needs goes in a skill bundle.
196
+ - **Placement**: a hook is the guard, a runtime script is the tool; they
197
+ never share a file or a directory.
198
+
199
+ | Script | Runs on | Lives at | Wired as |
200
+ | --- | --- | --- | --- |
201
+ | Hook | runtime authority, at `before`/`after` | `workflows/<slug>/hooks/<x>.js` | `before: { script: hooks/<x>.js }` (workflow-relative, confined to `hooks/`) |
202
+ | Runtime script | the model's authority, via `archmax_run` | `skills/<cap>/scripts/<x>.js` | enabling the skill; narrow with `{ tool: archmax_run, paths: ["skills/<cap>/scripts/**"] }` |
203
+
204
+ `archmax_run` is confined to skill bundles by a non-overridable rule
205
+ (`script.skill-only`): a script in `scratchpad/` or `hooks/` is unrunnable.
206
+ - **Paths have no leading slash** (`skills/order-data/assets/orders.json`,
207
+ `scratchpad/refund.json`); never author a `run/` prefix. `scratchpad/` is
208
+ writable in every state regardless of `tools.allow`, so an allow entry
209
+ inside it narrows nothing (warning); to govern *where* a result lands, name
210
+ a non-reserved run path (`reports/*.json`) and allow it.
211
+ - **Guidance has three homes, one per rule**: every workflow → `AGENTS.md`;
212
+ the whole run → top-level `instructions` (`|-` literal block, since `>-`
213
+ folds paragraphs together); one state's turn → that state's `instructions`
214
+ (`>-` is fine). Pasting a paragraph into a second state means hoist it.
215
+ Never one `skills/<state>/` per state.
216
+ - **Every `.js` you author opens with a JSDoc block**: title line, blank
217
+ line, then what it reads, the sequence of checks, and the condition for each
218
+ verdict (hook) or what it computes and returns (script). Admin UIs show this
219
+ instead of the code. No `@specification` tag, no sidecar key.
220
+
221
+ ### Verify (CLI)
222
+
223
+ ```bash
224
+ archmax validate [workflow] [--json] # offline; run after every structural edit
225
+ archmax test [workflow] [filter] [--json] # cases; filter = case-id substring
226
+ archmax run <workflow> "<prompt>" [--session <id>] [--trigger <id>] [--variables '<json>']
227
+ archmax sessions [session] [--json] # list, or one session's variables (value + locked)
228
+ archmax decide <session> --to <state> [--comment "…"] # resume a human state
229
+ archmax reply <session> "<message>" # message a parked run; it stays parked
230
+ archmax deliver <session> --trigger <id> [--variables '<json>'] # resume an archmax_wait
231
+ ```
232
+
233
+ `<workflow>` may be omitted when the workspace has one. Global `--root <dir>`
234
+ (cwd default; `.env` loads from it), `--verbose` for raw events. Results on
235
+ stdout, narration on stderr. Exit 0 done/parked, 1 failure, 2 usage. Dev from
236
+ the SDK checkout: `npm run dev -- <command…>`.
237
+
238
+ ---
239
+
240
+
241
+ ---
242
+
243
+ ## Done when
244
+
245
+ - Authoring: `archmax validate` clean, `archmax test` passing, every `.js`
246
+ opens with its JSDoc, every case has `title` + `description`.
247
+ - Wiring: the snippet compiles against the installed package's exports.