@archmax-ai/harness 1.0.1 → 2.0.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 (94) hide show
  1. package/README.md +167 -165
  2. package/dist/agent.d.ts +2 -2
  3. package/dist/agent.js +2 -2
  4. package/dist/assembly/compose.js +5 -3
  5. package/dist/assembly/compose.js.map +1 -1
  6. package/dist/authoring-skill/archmax-harness/README.md +13 -15
  7. package/dist/authoring-skill/archmax-harness/SKILL.md +174 -261
  8. package/dist/authoring-skill/archmax-harness/references/backend-integration.md +244 -764
  9. package/dist/authoring-skill/archmax-harness/references/cases.md +178 -53
  10. package/dist/authoring-skill/archmax-harness/references/code-states-and-scripts.md +211 -100
  11. package/dist/authoring-skill/archmax-harness/references/diagnostics.md +57 -78
  12. package/dist/authoring-skill/archmax-harness/references/workflow-schema.md +614 -1977
  13. package/dist/core/attachments.d.ts +2 -0
  14. package/dist/core/attachments.js +2 -1
  15. package/dist/core/attachments.js.map +1 -1
  16. package/dist/core/deepagents.d.ts +1 -2
  17. package/dist/core/deepagents.js +1 -2
  18. package/dist/core/deepagents.js.map +1 -1
  19. package/dist/core/file-operations.d.ts +6 -0
  20. package/dist/core/file-operations.js +29 -0
  21. package/dist/core/file-operations.js.map +1 -1
  22. package/dist/index.d.ts +5 -1
  23. package/dist/index.js +4 -0
  24. package/dist/index.js.map +1 -1
  25. package/dist/kernel/kernel.js +2 -2
  26. package/dist/kernel/kernel.js.map +1 -1
  27. package/dist/machine/lint-spec.js +6 -5
  28. package/dist/machine/lint-spec.js.map +1 -1
  29. package/dist/machine/machine.d.ts +8 -10
  30. package/dist/machine/machine.js +11 -12
  31. package/dist/machine/machine.js.map +1 -1
  32. package/dist/machine/signature-pattern.d.ts +24 -0
  33. package/dist/machine/signature-pattern.js +67 -0
  34. package/dist/machine/signature-pattern.js.map +1 -0
  35. package/dist/machine/signature.d.ts +137 -35
  36. package/dist/machine/signature.js +476 -25
  37. package/dist/machine/signature.js.map +1 -1
  38. package/dist/machine/spec-schema.d.ts +203 -5
  39. package/dist/machine/spec-schema.js +209 -51
  40. package/dist/machine/spec-schema.js.map +1 -1
  41. package/dist/machine/tool-names.d.ts +24 -34
  42. package/dist/machine/tool-names.js +43 -63
  43. package/dist/machine/tool-names.js.map +1 -1
  44. package/dist/machine/types.d.ts +11 -10
  45. package/dist/machine/types.js.map +1 -1
  46. package/dist/public/spec.d.ts +10 -6
  47. package/dist/public/spec.js +9 -5
  48. package/dist/public/spec.js.map +1 -1
  49. package/dist/validate/validate.js +3 -3
  50. package/dist/validate/validate.js.map +1 -1
  51. package/dist/workflow/automated.js +6 -1
  52. package/dist/workflow/automated.js.map +1 -1
  53. package/dist/workflow/control-tools.js +3 -3
  54. package/dist/workflow/control-tools.js.map +1 -1
  55. package/dist/workflow/file-values.d.ts +4 -1
  56. package/dist/workflow/file-values.js +2 -0
  57. package/dist/workflow/file-values.js.map +1 -1
  58. package/dist/workflow/grader-state.d.ts +2 -2
  59. package/dist/workflow/grader-state.js +5 -15
  60. package/dist/workflow/grader-state.js.map +1 -1
  61. package/dist/workflow/middleware.d.ts +2 -0
  62. package/dist/workflow/middleware.js +3 -26
  63. package/dist/workflow/middleware.js.map +1 -1
  64. package/dist/workflow/on-error.js +0 -1
  65. package/dist/workflow/on-error.js.map +1 -1
  66. package/dist/workflow/parks.js +0 -1
  67. package/dist/workflow/parks.js.map +1 -1
  68. package/dist/workflow/render-prompt.d.ts +4 -5
  69. package/dist/workflow/render-prompt.js +31 -29
  70. package/dist/workflow/render-prompt.js.map +1 -1
  71. package/dist/workflow/signature-checks.d.ts +8 -3
  72. package/dist/workflow/signature-checks.js +17 -4
  73. package/dist/workflow/signature-checks.js.map +1 -1
  74. package/dist/workflow/state.d.ts +0 -9
  75. package/dist/workflow/state.js +0 -3
  76. package/dist/workflow/state.js.map +1 -1
  77. package/dist/workflow/sub-workflow.js +4 -1
  78. package/dist/workflow/sub-workflow.js.map +1 -1
  79. package/dist/workflow/turn-boundary.js +0 -1
  80. package/dist/workflow/turn-boundary.js.map +1 -1
  81. package/package.json +2 -2
  82. package/skills/archmax-harness/README.md +13 -15
  83. package/skills/archmax-harness/SKILL.md +174 -261
  84. package/skills/archmax-harness/references/backend-integration.md +244 -764
  85. package/skills/archmax-harness/references/cases.md +178 -53
  86. package/skills/archmax-harness/references/code-states-and-scripts.md +211 -100
  87. package/skills/archmax-harness/references/diagnostics.md +57 -78
  88. package/skills/archmax-harness/references/workflow-schema.md +614 -1977
  89. package/dist/authoring-skill/archmax-harness/references/code-state-and-test-scripts.md +0 -1424
  90. package/dist/authoring-skill/archmax-harness/references/wiring.md +0 -119
  91. package/dist/authoring-skill/archmax-harness/references/workflow-yaml.md +0 -399
  92. package/skills/archmax-harness/references/code-state-and-test-scripts.md +0 -1424
  93. package/skills/archmax-harness/references/wiring.md +0 -119
  94. package/skills/archmax-harness/references/workflow-yaml.md +0 -399
@@ -1,86 +1,65 @@
1
- # `archmax validate` diagnostics → fix
1
+ # Diagnostics
2
2
 
3
- Load this when `validate` or `test` reports something you cannot fix from the
4
- message alone. Migrations for removed keys in full:
5
- [`workflow-schema.md`](workflow-schema.md#removed-keys-you-may-meet-in-an-older-workflow).
3
+ Load this when `archmax validate` or `archmax test` reports something the message alone
4
+ does not fix. Every diagnostic names the file and the field. Fix errors first, then
5
+ every warning you can.
6
6
 
7
- ## Diagnostics
7
+ ## `archmax validate`
8
8
 
9
- `validate` output names file and field. The recurring ones:
10
-
11
- | Diagnostic says | Fix |
9
+ | The diagnostic says | Fix |
12
10
  | --- | --- |
13
- | unknown key `<k>` (anywhere) | Misspelling, or a removed key — see the table below; `metadata` is the only free slot |
14
- | `name:` / `description:` at root | Rename to `title:` / `instructions:` (reread the text as direction, delete narration) |
15
- | `policy:` or root `skills.allow:` | Move to `tools.forbid_always` / `skills.allow_always` + state lists |
16
- | Workflow slug / state key not kebab-case, or empty | Rename the directory or key; update every `to`, `on_error`, `reachedState` |
17
- | transitions to / on_error routes to undefined state | Fix the slug or add the state |
18
- | no start state / multiple states declare trigger | Exactly one state per trigger id declares it under `triggers:` |
19
- | `Unrecognized key: "before"` / `"after"` (on a state) or `"extensions"` (at the root) | Hooks are removed — rewrite each as a state: a `before` check → a **code state in front** of the state (the trigger's entry, or the target of the edge into it); an `after` check → a **code state behind** it (the state's transition points at it, and it advances onward or back with the reason); a `rubric:` → a **grader state** behind it with an edge back. `max_iterations` has no successor: count rounds from the trail. Move `workflows/<slug>/hooks/*.js` to `scripts/` and rewrite them to the code-state contract. Delete `extensions` |
20
- | `Unrecognized key: "budget"` (at the root) | The root turn budget (`budget.maxModelCalls`) is removed: delete the key. A turn is bounded by LangGraph's `recursionLimit` (400 unless the host's invoke config sets one); bound a state with its own `budget.maxTurns` |
21
- | Code state declares no `script` | Add `script: scripts/<x>.js`, file at `workflows/<slug>/scripts/<x>.js` |
22
- | state declares `script`, which only a code state runs | Declare `type: code`, or drop the key |
23
- | `script` must be a workflow-relative path inside `scripts/` ending in .js or .mjs | `scripts/<x>.js` — no `hooks/`, no `skills/…` path, no `..` |
24
- | Code state `<s>` script not found / imports from `<x>` | Create the file under the workflow's `scripts/`; import only from `@archmax-ai/harness/*` |
25
- | Code state declares `instructions` / `model` / `budget` / `evidence` / `approvers` | Drop them: a code state makes no model call and cannot park. Say what the script does in its JSDoc and `summary`; `settings.timeoutMs` bounds it |
26
- | Grader state must declare `instructions` / at least one transition | Write the criteria in `instructions`; give it an edge onward and, to send work back, one to the graded state |
27
- | Grader state declares `evidence` / `approvers` / `budget.maxParks` | Drop them: a grader presents nothing to a person and cannot park |
28
- | `<type>` state is never offered `write_todos` / `archmax_eval` / `archmax_run` / `archmax_wait` / `archmax_reset` | Drop the entry from the state's `tools.allow`: a script calls tools directly, and an automated state cannot park or reset. The same tools in the workflow's `allow_always` are simply not offered there |
29
- | Human state must declare instructions / transitions / description; self-edge; two transitions of one type | Add them; route out of the state; one target per labelled type |
30
- | `'*'` is not a tool name a grant may use | Move the wildcard to `forbid`/`forbid_always` |
31
- | allows `task` — not grantable | Delete the entry; grade with a grader state, delegate with `archmax_workflow_<slug>` |
32
- | allows `archmax_run` on `skills/<x>/…` which the state does not enable | Add `x` to the state's `skills.allow` (or `allow_always`), or drop the entry |
33
- | `forbid_always` denies `archmax_advance` | Remove it |
34
- | not a skill slug (path/glob given) | Use the bundle directory name; narrow paths with a `tools.allow` entry |
35
- | `${{…}}` not a valid variable reference | `${{name}}` or `${{name.path}}`; snake_case names |
36
- | guards on `${{x}}` but no state requires it (warning) | Add `x` to an earlier state's `requires`, or seed it at assembly |
37
- | `allow` or `allow_always` on a path in `scratchpad/` (warning) | Drop it, or govern a non-reserved run path instead |
38
- | `tools.allow_always` is declared but grants none of the default tools (warning) | A declared list replaces the default tools: list the ones the workflow needs (`ls`, `read_file`, `write_file`, … as in the skeleton), or remove the key to grant them all |
39
- | state both allows and forbids / forbids what nothing enables / enables what allow_always already does / `skills: { allow: [] }` reads like a deny (warnings) | Drop the redundant entry; use `forbid` to subtract |
40
- | no top-level `instructions` (warning) | Add the standing block |
41
- | state has several transitions but no `instructions` (warning) | Add routing guidance so the agent classifies the request before it advances |
42
- | `transitions.<i>.description` must be a non-empty string here: '<target>' declares none (error) | The edge is undescribed and its target has no `instructions` to route on. Add the condition under which the edge is taken (say *when*, not *where*), or give the target instructions |
43
- | `transitions.<i>.description` must be a non-empty string on a human state's transition (error) | It is the decision's button label: say what choosing it means |
44
- | `transitions.<i>.description` must be a non-empty string here: '<target>' is a grader / is a code state (error) | An edge into an automated state cannot route on its target: a grader's instructions are its criteria, never shown to the work it judges, and a code state has none. Say when the work is ready for the check (`The reply is drafted`). A code state's own edges may stay undescribed |
45
- | `transitions.<i>.description` must be a string (error) | Quote it, or omit it to route on the target's instructions |
46
- | trigger declares unknown key (warning) | Keys read: `session`, `message`, `connection`, `requires`, `returns`; others are preserved |
47
- | `maxConcurrency` above 1 | Set to 1 or remove |
48
- | `WORKFLOW.md` has frontmatter | Strip it; the machine is `workflow.yaml` |
49
- | `Unsupported runtime contract 'archmax-harness@1'` (or `@2`). Supported: `archmax-harness@3` | Contracts 1 and 2 (the hook contract) are retired: rewrite any hooks as states (above), then set `runtime: { engine: archmax-harness, version: "3" }` or drop the block (omitted resolves to `3`) |
50
- | case: missing/over-long `title`/`description`; unknown key; assertion before action; `expect:` block; malformed regex; unknown trigger; `from:` missing | Fix the field named; assertions are steps; regexes are `"/p/f"` strings |
51
- | `agent cannot read workflows/**` (instructions/evidence/workspace path) | Move the text to a skill bundle or the path to `scratchpad/` |
52
-
53
- **Removed keys** you may meet (all load errors; details and migrations in
54
- `references/workflow-schema.md#removed-keys-you-may-meet-in-an-older-workflow`):
55
- `name:`→`title:`; `description:`→`instructions:`; `policy:`→`forbid_always`;
56
- root `skills.allow`→`skills.allow_always`; state `type: wait`→`archmax_wait`;
57
- `type: trigger`→`triggers:` on the entered state; `type: workflow`,
58
- `workflow:`, `params:`, `for_each:`, `result:`→an agent state allowing
59
- `archmax_workflow_<slug>` + `requires`; `parallel:`/`join:`→sequenced states;
60
- transition `on:`→nothing (the resumed state picks its edge); state
61
- `before:`/`after:` (with `{ script }`, `{ rubric }`, `subagent:`, custom kinds,
62
- `max_iterations`/`max_corrections`)→code and grader states; root
63
- `extensions:`→nothing; root `budget: { maxModelCalls }`→nothing (the
64
- `recursionLimit` bounds a turn); single-file `WORKFLOW.md` with
65
- frontmatter→`workflow.yaml` + prose.
11
+ | `Unrecognized key: "<k>"` | A typo, or a removed key: see [Removed keys](workflow-schema.md#removed-keys). `metadata` is the one free slot. |
12
+ | `Unrecognized key: "maxTurns"` at `states.<s>.budget` | Delete it. LangGraph's `recursionLimit` bounds a turn; a state's `budget` takes `timeoutMs` and `maxParks`. |
13
+ | `Unrecognized key: "budget"` at the root | Delete it: the `recursionLimit` bounds a turn. |
14
+ | `Unrecognized key: "before"` or `"after"` on a state, `"extensions"` at the root | Rewrite each check as a state: a `before` check as a code state in front of the state, an `after` check as a code state behind it, a rubric as a grader state behind it. Count rounds on the trail instead of `max_iterations`. Move `hooks/*.js` to `scripts/` and rewrite them to the code-state contract. |
15
+ | `Unrecognized key` for root `name`, `description`, `policy` | `title`, `instructions`, `tools.forbid_always`. A root `skills.allow` becomes `skills.allow_always` plus the state lists. |
16
+ | `transitions.<i>.description`: must be a non-empty string here: … | Add the condition under which the transition is taken. Say *when* (`The refund is over $50`), not *where*. The message says why this edge needs one: it is one of several, it leaves a human, grader or code state, it hands the session to one, it loops back, or its state has no `instructions`. Only an agent state's lone edge into another agent state may go without. |
17
+ | `transitions.<i>.description`: must be a string | A number or a list where the description goes: quote it, or remove it from a lone edge between agent states. |
18
+ | workflow slug or state key not kebab-case, or empty | Rename it, and update every `to`, `on_error` and `reachedState`. |
19
+ | transitions to, or `on_error` routes to, an undefined state | Fix the slug, or add the state. |
20
+ | no start state, or several states declare one trigger | Exactly one state declares each trigger id under `triggers:`. |
21
+ | trigger declares an unknown key (warning) | The runtime reads `session`, `message`, `connection`, `description`, `requires` and `returns`; it keeps other keys for the host. |
22
+ | code state declares no `script`, or `script` on another type | Add `script: scripts/<x>.js` to the code state; elsewhere, declare `type: code` or drop the key. |
23
+ | `script` must be a workflow-relative path inside `scripts/` ending in .js or .mjs | Write `scripts/<x>.js`: no `hooks/`, no `skills/…`, no `..`. |
24
+ | code state `<s>` script not found, or imports from `<x>` | Create the file in the workflow's `scripts/`, and import only from `@archmax-ai/harness/*`. |
25
+ | Code state declares `instructions` / `model` / `budget` / `evidence` / `approvers` | Drop it: a code state makes no model call and cannot park. Say what the script does in its JSDoc header and `summary`. |
26
+ | Grader state must declare `instructions` / at least one transition | Write its criteria, and give it a transition onward and one back to the state it grades. |
27
+ | Grader state declares `evidence` / `approvers` / `budget.maxParks` | Drop it: a grader presents nothing to a person and cannot park. |
28
+ | `<type>` state is never offered `write_todos` / `archmax_eval` / `archmax_run` / `archmax_wait` / `archmax_reset` | Drop the entry from the state's `tools.allow`. The same tools in `allow_always` are left out of that state without an error. |
29
+ | Human state must declare instructions or transitions; a transition to itself; two transitions of one type | Add them; point the transition at the state that does the further work; map each labelled type to one target. |
30
+ | `'*'` is not a tool name a grant may use | Move the wildcard into `forbid` or `forbid_always`. |
31
+ | allows `task` | Delete the entry: grade with a grader state, delegate with `archmax_workflow_<slug>`. |
32
+ | allows `archmax_run` on `skills/<x>/…`, which the state does not enable | Add `x` to the state's `skills.allow` (or `allow_always`), or drop the entry. |
33
+ | `tools.forbid_always` denies `archmax_advance` | Remove it: no state could move. |
34
+ | not a skill slug (a path or a glob) | Use the bundle's directory name; narrow paths with a `tools.allow` entry. |
35
+ | `${{…}}` is not a valid variable reference | Write `${{name}}` or `${{name.path}}`. |
36
+ | guards on `${{x}}`, but nothing guarantees it (warning) | Add `x` to an earlier state's or the trigger's `requires`, or seed it. |
37
+ | an allow entry on a path in `scratchpad/` (warning) | Drop it, or govern a path outside the reserved zones. |
38
+ | `tools.allow_always` grants none of the default tools (warning) | A declared list replaces them: list the ones the workflow needs, or remove the key. |
39
+ | a state both allows and forbids, forbids what nothing enables, repeats `allow_always`, or declares `allow: []` (warnings) | Drop the redundant entry. `forbid` is what subtracts. |
40
+ | a state declares the workflow's own `model` (warning) | Drop it, or name a different id. |
41
+ | no top-level `instructions` (warning) | Add the rules that hold for the whole session. |
42
+ | a state has several transitions but no `instructions` (warning) | Say how the agent decides which transition to take. |
43
+ | `maxConcurrency` above 1 | Set it to 1, or remove it. |
44
+ | `WORKFLOW.md` has frontmatter | Strip it: the machine is `workflow.yaml`. |
45
+ | `Unsupported runtime contract 'archmax-harness@1'` (or `@2`) | Rewrite any hooks as states (above), then set `version: "3"` or drop the `runtime` block. |
46
+ | case: missing or too long `title` or `description`, unknown key, assertion before an action, an `expect:` block, malformed regex, unknown trigger, missing `from:` file | Fix the field it names. Assertions are steps; regexes are `"/pattern/flags"` strings. |
47
+ | the agent cannot read `workflows/**` (an `instructions`, `evidence` or case `workspace` path) | Move the text into a skill bundle, or the path under `scratchpad/`. |
66
48
 
67
- ## Reading a failed run
49
+ ## A failed session
68
50
 
69
- `archmax test` and `archmax run` report an automated state's run in the state
70
- flow (stderr): `› code scripts/<x>.js` with each `console.log` line beneath it,
71
- `› grader grading`, and `✖ code failed <reason>` / `✖ grader failed <reason>` when
72
- the run failed. The raw events (`--verbose`, or `onEvent` in a host) are
73
- `code-start { state, script }`, `code-output { state, line }`,
74
- `code-result { state, status, durationMs, reason? }`, `grader-start { state }` and
75
- `grader-result { state, status, durationMs, reason? }`; a failure then shows as
76
- `state-error-routed` (its `on_error`) or a rejected session.
51
+ The CLI's state flow, on stderr, shows an automated state's run: `› code scripts/<x>.js`
52
+ with each `console.log` line beneath it, `› grader grading`, and `✖ code failed <reason>`
53
+ or `✖ grader failed <reason>`. With `--verbose`, or `onEvent` in a host, the events are
54
+ `code-start`, `code-output`, `code-result`, `grader-start` and `grader-result`. A failure
55
+ then shows as `state-error-routed` (its `on_error`) or as a rejected session.
77
56
 
78
- | Reason says | Fix |
57
+ | The reason says | Fix |
79
58
  | --- | --- |
80
- | `code state '<s>' finished without calling archmax_advance or archmax_raise` | Every path through a non-terminal state's script must advance or raise; returning a value does nothing |
81
- | `grader state '<s>' finished without calling …` | The grader answered in text: say in its `instructions` exactly when to take each transition and when to raise |
82
- | `grader state '<s>' exhausted its turn budget (maxTurns: N)` / `exceeded its time budget` | Raise `budget.maxTurns`/`timeoutMs` (reading the history and deciding is two calls), or narrow what it must read |
83
- | `archmax_advance rejected: cannot advance from '<s>' to '<t>'` / `cannot leave '<s>' yet: '<v>' is not set` | The script's `to` is not one of its state's transitions, or its `requires` are unmet — fix the target, or set the variable first |
84
- | `archmax_advance rejected: this state has decided` | A script or grader decided twice; only the first advance or raise counts |
85
- | a tool refused, or `tools.<x>` is `undefined`, inside a code state | Grant it on the **code state itself** (`tools.allow`, `skills.allow`, `mounts.allow`); another state's grant does not reach it |
86
- | `GraphRecursionError` / the session `failed` with `recursion-limit` | The turn hit LangGraph's `recursionLimit` (400 unless the host sets one): states cycle within one turn — automated states advancing to each other, or an agent looping between states. Add an edge out, or count rounds from the trail and give up; where one state loops on its own, bound it with `budget.maxTurns` + `on_error` |
59
+ | `code state '<s>' finished without calling archmax_advance or archmax_raise` | Every path through a non-terminal state's script must advance or raise; a return value does nothing. |
60
+ | `grader state '<s>' finished without calling archmax_advance or archmax_raise` | The grader answered in text. Say in its `instructions` exactly when to take each transition, and when to raise. |
61
+ | `exceeded its time budget (timeoutMs: N)` | Raise the state's `budget.timeoutMs`, or narrow what it must read. |
62
+ | `cannot advance from '<s>' to '<t>'`, or `cannot leave '<s>' yet: '<v>' …` | The target is not one of the state's transitions, or its `requires` are unmet. Fix the target, or set the variable first. |
63
+ | `archmax_advance rejected: this state has decided` | A script or grader decided twice. Only the first advance or raise counts. |
64
+ | a tool refused, or `tools.<x>` is `undefined`, in a code state | Grant it on the code state itself (`tools.allow`, `skills.allow`, `mounts.allow`). |
65
+ | the session `failed` with `recursion-limit` (`GraphRecursionError`) | The turn passed LangGraph's `recursionLimit` (400 unless the host sets one): states cycle within one turn, automated states advancing to each other or an agent looping. Add a way out, or count rounds on the trail and give up. |