@archmax-ai/harness 0.1.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 (77) hide show
  1. package/README.md +45 -4
  2. package/dist/assembly/compose.js +3 -5
  3. package/dist/assembly/compose.js.map +1 -1
  4. package/dist/assembly/delegation-registry.js +4 -2
  5. package/dist/assembly/delegation-registry.js.map +1 -1
  6. package/dist/authoring-skill/archmax-harness/README.md +24 -16
  7. package/dist/authoring-skill/archmax-harness/SKILL.md +7 -1
  8. package/dist/authoring-skill/archmax-harness/references/backend-integration.md +58 -2
  9. package/dist/authoring-skill/archmax-harness/references/workflow-schema.md +66 -20
  10. package/dist/authoring-skill/archmax-harness/references/workflow-yaml.md +14 -4
  11. package/dist/cli/turn.d.ts +9 -4
  12. package/dist/cli/turn.js +35 -8
  13. package/dist/cli/turn.js.map +1 -1
  14. package/dist/cli.js +4 -5
  15. package/dist/cli.js.map +1 -1
  16. package/dist/index.d.ts +12 -0
  17. package/dist/index.js +15 -0
  18. package/dist/index.js.map +1 -1
  19. package/dist/machine/machine.d.ts +9 -0
  20. package/dist/machine/machine.js +13 -0
  21. package/dist/machine/machine.js.map +1 -1
  22. package/dist/machine/signature.d.ts +104 -0
  23. package/dist/machine/signature.js +210 -0
  24. package/dist/machine/signature.js.map +1 -0
  25. package/dist/machine/spec-schema.d.ts +158 -8
  26. package/dist/machine/spec-schema.js +78 -6
  27. package/dist/machine/spec-schema.js.map +1 -1
  28. package/dist/machine/triggers.d.ts +6 -2
  29. package/dist/machine/triggers.js +7 -2
  30. package/dist/machine/triggers.js.map +1 -1
  31. package/dist/machine/types.d.ts +7 -1
  32. package/dist/machine/types.js.map +1 -1
  33. package/dist/machine/variables.d.ts +2 -0
  34. package/dist/machine/variables.js +4 -0
  35. package/dist/machine/variables.js.map +1 -1
  36. package/dist/public/spec.d.ts +17 -2
  37. package/dist/public/spec.js +15 -1
  38. package/dist/public/spec.js.map +1 -1
  39. package/dist/sessions/resume.d.ts +4 -0
  40. package/dist/sessions/resume.js +8 -1
  41. package/dist/sessions/resume.js.map +1 -1
  42. package/dist/workflow/control-tools.d.ts +7 -2
  43. package/dist/workflow/control-tools.js +27 -2
  44. package/dist/workflow/control-tools.js.map +1 -1
  45. package/dist/workflow/governance.js +28 -19
  46. package/dist/workflow/governance.js.map +1 -1
  47. package/dist/workflow/middleware.js +5 -10
  48. package/dist/workflow/middleware.js.map +1 -1
  49. package/dist/workflow/prompt-cache.d.ts +0 -2
  50. package/dist/workflow/prompt-cache.js +0 -7
  51. package/dist/workflow/prompt-cache.js.map +1 -1
  52. package/dist/workflow/render-prompt.js +28 -7
  53. package/dist/workflow/render-prompt.js.map +1 -1
  54. package/dist/workflow/signature-checks.d.ts +22 -0
  55. package/dist/workflow/signature-checks.js +52 -0
  56. package/dist/workflow/signature-checks.js.map +1 -0
  57. package/dist/workflow/sub-workflow.d.ts +23 -16
  58. package/dist/workflow/sub-workflow.js +78 -14
  59. package/dist/workflow/sub-workflow.js.map +1 -1
  60. package/dist/workflow/tool-service.js +1 -1
  61. package/dist/workflow/tool-service.js.map +1 -1
  62. package/dist/workflow/turn-boundary.js +4 -5
  63. package/dist/workflow/turn-boundary.js.map +1 -1
  64. package/dist/workflow/workflow-tools.d.ts +17 -9
  65. package/dist/workflow/workflow-tools.js +30 -17
  66. package/dist/workflow/workflow-tools.js.map +1 -1
  67. package/package.json +2 -1
  68. package/skills/archmax-harness/README.md +82 -0
  69. package/skills/archmax-harness/SKILL.md +247 -0
  70. package/skills/archmax-harness/references/backend-integration.md +681 -0
  71. package/skills/archmax-harness/references/cases.md +41 -0
  72. package/skills/archmax-harness/references/diagnostics.md +51 -0
  73. package/skills/archmax-harness/references/hook-and-test-scripts.md +1070 -0
  74. package/skills/archmax-harness/references/hooks-and-scripts.md +82 -0
  75. package/skills/archmax-harness/references/wiring.md +101 -0
  76. package/skills/archmax-harness/references/workflow-schema.md +1677 -0
  77. package/skills/archmax-harness/references/workflow-yaml.md +251 -0
@@ -0,0 +1,41 @@
1
+ # Cases — the `*.test.yaml` grammar
2
+
3
+ Load this when writing or fixing a case. Worked examples for every shape
4
+ (mocks, human decisions, triggered starts, fixtures):
5
+ [`hook-and-test-scripts.md`](hook-and-test-scripts.md) Part 2.
6
+
7
+ ## Keys, actions, assertions
8
+
9
+ One YAML document per `tests/<case>.test.yaml`; the case id is the
10
+ tests-relative path minus the extension (the `test` filter is a substring of
11
+ it). Host-interpreted; no sandbox runs a case. **Unknown keys are errors.**
12
+
13
+ | Key | Shape |
14
+ | --- | --- |
15
+ | `title` | required, ≤ 60 chars, one line: the behaviour under test |
16
+ | `description` | required, ≤ 200 chars: scenario driven + what is asserted; longer rationale in a YAML comment above |
17
+ | `skip` | a reason; reports skipped |
18
+ | `trigger` | `{ id }` only — the trigger every turn runs under (default `manual`); unknown id fails the case |
19
+ | `variables` | `{ name: value }` seeded and **locked** every turn — the firing's payload; never seed what the agent must establish (assert it with `variables:` instead) |
20
+ | `workspace` | `{ <run path>: content }` — strings verbatim, other YAML → JSON, `{ from: <tests-relative path> }` copies a file; only run-zone paths (`trigger.json`, `scratchpad/…`) |
21
+ | `mocks` | `[{ tool, whenInput?, result }]` — intercepts agent and script calls alike (partial-input match) |
22
+ | `steps` | one flat list; actions and assertions are peers; an assertion evaluates against the nearest action above it |
23
+
24
+ Actions: `send: "<message>"` (a new turn; against a parked run, a reply-only
25
+ message that leaves it parked), `decide: { to, comment? }`,
26
+ `deliver: { trigger, variables? }`.
27
+
28
+ Assertions (**structural** ones halt the case when they miss; later steps are
29
+ reported `not-executed`): `succeeded: true`ˢ · `parked: true | decision | input | { channel?, state? }`ˢ ·
30
+ `reachedState: <slug>`ˢ (a committed non-trigger trail step) ·
31
+ `trail: { to?, kind?, reason?, count }`ˢ (`kind`: trigger/agent/human/on_error) ·
32
+ `noTraversal: true`ˢ · `triggerArrival: <id>`ˢ ·
33
+ `reply: { includes?, excludes? }` (token or list; `"/regex/flags"` strings are regexes; matched against the whole turn's assistant text) ·
34
+ `calledTool` / `notCalledTool` / `blockedTool: { name, input? }` (partial input; `blockedTool` = governance refused it — the assertion that tests a guard) ·
35
+ `ranWorkflow: { workflow, status?, count? }` · `usedNoTools: true` (whole conversation) ·
36
+ `variables: { expect, path?, locked? }` · `grade: { closedQA, atLeast }` (LLM grades the reply plus the tool record; `atLeast` is a hard bar; needs `tests.judge`).
37
+
38
+ Put the structural assertion right after the action that should satisfy it,
39
+ before content assertions that only make sense in that state:
40
+
41
+ ```yaml
@@ -0,0 +1,51 @@
1
+ # `archmax validate` diagnostics → fix
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).
6
+
7
+ ## Diagnostics
8
+
9
+ `validate` output names file and field. The recurring ones:
10
+
11
+ | Diagnostic says | Fix |
12
+ | --- | --- |
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
+ | hook must be a `{ script }` or `{ rubric }` entry / single-key tagged object | One kind per hook; the only sidecar is `max_iterations`; `specification:` and `subagent:` do not exist |
20
+ | hook script must be inside `hooks/` / not found | `before: { script: hooks/<x>.js }`, file at `workflows/<slug>/hooks/<x>.js` |
21
+ | `before` declares `max_iterations` | Remove it; before hooks are ok/veto |
22
+ | Human state must declare instructions / transitions / description; self-edge; hook can never run; two transitions of one type | Add them; route out of the state; drop the hook; one target per labelled type |
23
+ | `'*'` is not a tool name a grant may use | Move the wildcard to `forbid`/`forbid_always` |
24
+ | allows `task` — not grantable | Delete the entry; declare a `rubric:` hook instead |
25
+ | 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 |
26
+ | `forbid_always` denies `archmax_advance` | Remove it |
27
+ | not a skill slug (path/glob given) | Use the bundle directory name; narrow paths with a `tools.allow` entry |
28
+ | `${{…}}` not a valid variable reference | `${{name}}` or `${{name.path}}`; snake_case names |
29
+ | guards on `${{x}}` but no state requires it (warning) | Add `x` to an earlier state's `requires`, or seed it at assembly |
30
+ | `allow` on a path in `scratchpad/` (warning) | Drop it, or govern a non-reserved run path instead |
31
+ | `tools.allow_always` constrains essential tool (warning) | Narrow per state with `tools.allow` |
32
+ | 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 |
33
+ | no top-level `instructions` (warning) | Add the standing block |
34
+ | state has several transitions but no `instructions` (warning) | Add routing guidance so the agent classifies the request before it advances |
35
+ | `transitions.<i>.description` must be a non-empty string (error) | Add the condition under which that edge is taken — it is the only thing the agent knows about it. Say *when*, not *where* |
36
+ | trigger declares unknown key (warning) | Keys read: `session`, `message`, `connection`, `requires`, `returns`; others are preserved |
37
+ | `maxConcurrency` above 1 | Set to 1 or remove |
38
+ | `WORKFLOW.md` has frontmatter | Strip it; the machine is `workflow.yaml` |
39
+ | 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 |
40
+ | `agent cannot read workflows/**` (instructions/evidence/workspace path) | Move the text to a skill bundle or the path to `scratchpad/` |
41
+
42
+ **Removed keys** you may meet (all load errors; details and migrations in
43
+ `references/workflow-schema.md#removed-keys-you-may-meet-in-an-older-workflow`):
44
+ `name:`→`title:`; `description:`→`instructions:`; `policy:`→`forbid_always`;
45
+ root `skills.allow`→`skills.allow_always`; state `type: wait`→`archmax_wait`;
46
+ `type: trigger`→`triggers:` on the entered state; `type: workflow`,
47
+ `workflow:`, `params:`, `for_each:`, `result:`→an agent state allowing
48
+ `archmax_workflow_<slug>` + `requires`; `parallel:`/`join:`→sequenced states;
49
+ transition `on:`→nothing (the resumed state picks its edge); `subagent:` hook
50
+ →`rubric:`; `max_corrections`→`max_iterations`; single-file `WORKFLOW.md` with
51
+ frontmatter→`workflow.yaml` + prose.