@archmax-ai/harness 0.5.0 → 0.6.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 (63) hide show
  1. package/README.md +6 -2
  2. package/dist/assembly/compose.js +3 -2
  3. package/dist/assembly/compose.js.map +1 -1
  4. package/dist/authoring-skill/archmax-harness/references/backend-integration.md +28 -8
  5. package/dist/authoring-skill/archmax-harness/references/hook-and-test-scripts.md +3 -1
  6. package/dist/authoring-skill/archmax-harness/references/workflow-schema.md +32 -12
  7. package/dist/core/binary-read.d.ts +20 -4
  8. package/dist/core/binary-read.js +36 -5
  9. package/dist/core/binary-read.js.map +1 -1
  10. package/dist/core/events.d.ts +6 -0
  11. package/dist/core/events.js.map +1 -1
  12. package/dist/core/mount-prompt.d.ts +2 -1
  13. package/dist/core/mount-prompt.js +4 -2
  14. package/dist/core/mount-prompt.js.map +1 -1
  15. package/dist/core/session-id.d.ts +12 -2
  16. package/dist/core/session-id.js +30 -2
  17. package/dist/core/session-id.js.map +1 -1
  18. package/dist/core/tool-context.d.ts +13 -2
  19. package/dist/core/tool-context.js +2 -1
  20. package/dist/core/tool-context.js.map +1 -1
  21. package/dist/core/workspace-router.js +5 -3
  22. package/dist/core/workspace-router.js.map +1 -1
  23. package/dist/index.d.ts +1 -1
  24. package/dist/index.js +1 -1
  25. package/dist/index.js.map +1 -1
  26. package/dist/kernel/kernel.js +8 -4
  27. package/dist/kernel/kernel.js.map +1 -1
  28. package/dist/machine/lint-spec.js +8 -4
  29. package/dist/machine/lint-spec.js.map +1 -1
  30. package/dist/machine/machine.d.ts +26 -7
  31. package/dist/machine/machine.js +41 -10
  32. package/dist/machine/machine.js.map +1 -1
  33. package/dist/machine/mount-grants.d.ts +3 -2
  34. package/dist/machine/mount-grants.js.map +1 -1
  35. package/dist/public/spec.d.ts +5 -3
  36. package/dist/public/spec.js +5 -3
  37. package/dist/public/spec.js.map +1 -1
  38. package/dist/sessions/resume.d.ts +5 -1
  39. package/dist/sessions/resume.js.map +1 -1
  40. package/dist/sessions/scope.d.ts +18 -11
  41. package/dist/sessions/scope.js +21 -23
  42. package/dist/sessions/scope.js.map +1 -1
  43. package/dist/workflow/agent-tools.d.ts +2 -1
  44. package/dist/workflow/agent-tools.js +8 -7
  45. package/dist/workflow/agent-tools.js.map +1 -1
  46. package/dist/workflow/governance.d.ts +6 -0
  47. package/dist/workflow/governance.js +69 -1
  48. package/dist/workflow/governance.js.map +1 -1
  49. package/dist/workflow/middleware.js +9 -0
  50. package/dist/workflow/middleware.js.map +1 -1
  51. package/dist/workflow/state.d.ts +7 -0
  52. package/dist/workflow/state.js +14 -1
  53. package/dist/workflow/state.js.map +1 -1
  54. package/dist/workflow/sub-workflow.d.ts +17 -0
  55. package/dist/workflow/sub-workflow.js +29 -6
  56. package/dist/workflow/sub-workflow.js.map +1 -1
  57. package/dist/workflow/tool-service.d.ts +1 -1
  58. package/dist/workflow/tool-service.js +4 -1
  59. package/dist/workflow/tool-service.js.map +1 -1
  60. package/package.json +1 -1
  61. package/skills/archmax-harness/references/backend-integration.md +28 -8
  62. package/skills/archmax-harness/references/hook-and-test-scripts.md +3 -1
  63. package/skills/archmax-harness/references/workflow-schema.md +32 -12
@@ -196,7 +196,10 @@ mounts?:
196
196
  # workflow reaches no governed mount; validate says so
197
197
  # ONCE, naming them — write `allow_always: []` to mean it.
198
198
  # An entry is a NAME, or `{ mount: <name>, access: read |
199
- # read_write }` to say what this level gives. The host's
199
+ # read_write }` to say what this level gives. A bare NAME
200
+ # asks for NO write: a governed mount is written only
201
+ # where some grant of THIS workflow says `read_write`
202
+ # (a child's or caller's grant never counts). The host's
200
203
  # readOnly is a CEILING: `read_write` on a read-only mount
201
204
  # opens nothing (validate warns); `read` NARROWS a
202
205
  # writable one, and no narrower level widens it back.
@@ -368,7 +371,9 @@ states:
368
371
  # warns about one that reads like it) — `forbid` is.
369
372
  # An entry may name its access:
370
373
  # allow: [{ mount: shared, access: read }]
371
- # reads a writable mount without writing it here. The
374
+ # reads a writable mount without writing it here, and
375
+ # allow: [{ mount: shared, access: read_write }]
376
+ # asks to write it — which a bare name never does. The
372
377
  # host's posture is the ceiling — `read_write` cannot
373
378
  # open a read-only mount — and a `read` at either level
374
379
  # holds, so a state never widens what the workflow
@@ -921,13 +926,13 @@ error.
921
926
 
922
927
  ### Read or read/write
923
928
 
924
- A grant entry is either a bare mount name — taking the posture the host wired — or
925
- a mapping naming the access this level gives:
929
+ A grant entry is either a bare mount name, which asks for no write, or a mapping
930
+ naming the access this level gives:
926
931
 
927
932
  ```yaml
928
933
  mounts:
929
934
  allow_always:
930
- - reference # the host's posture
935
+ - reference # read; written only if a grant below asks
931
936
  - { mount: shared, access: read_write } # writable where the host allows it
932
937
 
933
938
  states:
@@ -936,6 +941,17 @@ states:
936
941
  allow: [{ mount: shared, access: read }] # reads it, cannot write it here
937
942
  ```
938
943
 
944
+ **A workflow writes a governed mount only where its own grants ask to.** It is
945
+ writable in a state when the host serves it writable, some grant of *this*
946
+ workflow says `access: read_write` (in `allow_always` or any state's `allow`), and
947
+ no grant applicable in the state says `access: read`. So a bare grant in one state
948
+ and a `read_write` grant in another both write. One mount table serves a session
949
+ and every child it dispatches, and the host serves a route writable when any
950
+ workflow in that tree asks; a mount still belongs to the workflow that grants it,
951
+ so a caller's `read_write` never lets its child write through a bare grant, nor the
952
+ other way round. An ungoverned mount takes the host's posture: it has no grant to
953
+ ask with.
954
+
939
955
  The host's `readOnly` is a **ceiling**, not a default to argue with:
940
956
 
941
957
  - `access: read_write` on a mount the workspace serves read-only opens nothing,
@@ -949,7 +965,8 @@ The host's `readOnly` is a **ceiling**, not a default to argue with:
949
965
 
950
966
  Two refusals, because they are two different edits: a write into a mount the
951
967
  **host** serves read-only is `zone.read-only` (fix the wiring), and a write into
952
- one a **grant** narrowed is `mount.read-only` (fix the spec).
968
+ one a **grant** narrowed, or one no grant of the workflow asks to write, is
969
+ `mount.read-only` (fix the spec; the refusal says which).
953
970
 
954
971
  ### What the agent sees
955
972
 
@@ -985,7 +1002,8 @@ so `AGENTS.md.bak` is not captured.
985
1002
  everywhere already — use `forbid` to take one away);
986
1003
  - an `access: read_write` on a mount the host serves **read-only**;
987
1004
  - a name in both `allow_always` and a state's `allow` (unless the state entry
988
- narrows the access, which does real work);
1005
+ narrows the access to `read`, or asks `read_write` of a mount the root grants
1006
+ bare: both do real work);
989
1007
  - a state's `allow: []` beside a non-empty `allow_always`;
990
1008
  - a `forbid` naming a governed mount nothing would have enabled there;
991
1009
  - a `forbid_always` name some `allow` list also grants;
@@ -1416,8 +1434,8 @@ enrich:
1416
1434
  in `<!-- top-level-only -->` … `<!-- /top-level-only -->` lines.
1417
1435
  - **Same agent, isolated context, own session.** Same model, backend, host
1418
1436
  tools; its **own** grading rubrics, from its own spec; a fresh transcript; the child's *own* per-state
1419
- `tools.allow`. It is a separate session (`<parent>~<state>:<workflow>:<n>`)
1420
- with its own checkpoints and its own `scratchpad/`: a path it reads or writes
1437
+ `tools.allow`. It is a separate session (`<parent>~<n>`, `n` the dispatch's
1438
+ number in the caller, counted across its turns) with its own checkpoints and its own `scratchpad/`: a path it reads or writes
1421
1439
  resolves inside its own session, so it can neither see nor overwrite a file of
1422
1440
  its caller's, and concurrent sub-runs cannot collide on a path.
1423
1441
  - **Nothing crosses implicitly.** Down: only the arguments the call passed —
@@ -1753,9 +1771,11 @@ single-segment one is, and a sibling under the same first segment (`catalogs/uk`
1753
1771
  is not.
1754
1772
 
1755
1773
  A mount the host mounted **writable** is not a read-only zone — its paths are
1756
- governed like ordinary run paths — but a state may still be given it read-only,
1757
- with `mounts: { allow: [{ mount: <name>, access: read }] }`. A write refused by
1758
- that grant is `mount.read-only`; one refused by the wiring is `zone.read-only`.
1774
+ governed like ordinary run paths — but a governed one is written only where a grant
1775
+ of the workflow says `access: read_write`, and a state may still be given it
1776
+ read-only, with `mounts: { allow: [{ mount: <name>, access: read }] }`. A write
1777
+ refused by a grant is `mount.read-only`; one refused by the wiring is
1778
+ `zone.read-only`.
1759
1779
  See [Mount governance](#mount-governance).
1760
1780
 
1761
1781
  The run root is writable, and it has exactly one named working area: