@agentskit/harness 0.13.0 → 0.14.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.
- package/CHANGELOG.md +58 -0
- package/README.md +8 -3
- package/dist/cli.js +223 -32
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +145 -6
- package/dist/index.js +193 -20
- package/dist/index.js.map +1 -1
- package/docs/ADR-0019-human-decision-attestation.md +9 -4
- package/docs/MODULE-BOUNDARIES.md +1 -1
- package/loop.config.example.yaml +29 -2
- package/package.json +8 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,63 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.14.0] - 2026-09-19
|
|
4
|
+
|
|
5
|
+
A queue that several machines can drain, a review whose strictness matches the risk, and four fixes that
|
|
6
|
+
were sitting unpublished. Motivated by a real 24/7 loop that had been silently doing nothing: the config
|
|
7
|
+
was invalid, the queue asked for the wrong assignee, and the diagnostic misnamed its own subject.
|
|
8
|
+
|
|
9
|
+
### The queue stops being "my issues"
|
|
10
|
+
|
|
11
|
+
- **`linear.queueOwnership`** (`person` | `unassigned`, default `person`, nothing changes unless you opt
|
|
12
|
+
in). Under `unassigned` the queue lists with `--assignee null` and the assignee becomes a **transient
|
|
13
|
+
claim**: written right after a dispatch succeeds, cleared when the item comes back. That is what lets
|
|
14
|
+
several machines share one priority-ordered queue without two of them picking the same issue.
|
|
15
|
+
The claim is non-fatal and gets its own `queue.claim-failed` event — what actually removes an issue from
|
|
16
|
+
the queue is the status transition, so a failed claim must not cost the transition or the comment.
|
|
17
|
+
- **`linear.anyLabels`** — "at least one of these" (OR), because `requireLabels` is AND: listing two
|
|
18
|
+
layers there demands both on the same issue and matches **nothing**. A queue that returns zero is
|
|
19
|
+
indistinguishable from "no work to do", which is the worst failure mode this loop has.
|
|
20
|
+
- `loop doctor` now says **which** queue it read. Under `unassigned` ownership it used to print
|
|
21
|
+
"for \<person\>" — the opposite of what it listed, and that is how an empty queue goes unnoticed.
|
|
22
|
+
|
|
23
|
+
### Review strictness that matches the risk
|
|
24
|
+
|
|
25
|
+
- **`reviewOverrides`** — stricter review for the slices that deserve it, keyed by label. First match
|
|
26
|
+
wins and only the named fields are replaced: an override that raises `votes` must not silently reset
|
|
27
|
+
the deadline or swap the CLI. The matched label travels to the deliver log, because a gate that costs
|
|
28
|
+
more without explaining itself reads as a bug.
|
|
29
|
+
- The labels come from the **dispatch record**, not a fresh Linear read, so editing a label mid-flight
|
|
30
|
+
cannot change the gate a running item is judged by.
|
|
31
|
+
|
|
32
|
+
### Telling the worker the truth about the base branch
|
|
33
|
+
|
|
34
|
+
- **`knownFailures`** — suites already red on the base, declared with the tracking issue (mandatory: a
|
|
35
|
+
quarantine without an owner becomes permanent). The harness does **not** run `verifyCommand` — the
|
|
36
|
+
worker does, in its own worktree — so tolerating known breakage is information in the brief, not output
|
|
37
|
+
parsing. Without it, every item touching a broken package fails verification for someone else's defect.
|
|
38
|
+
|
|
39
|
+
### Memory: recurrence instead of guesswork
|
|
40
|
+
|
|
41
|
+
- Learning ids are content-derived, so a lesson that reappeared was silently deduplicated and a pattern
|
|
42
|
+
looked exactly like a one-off. **`sightings` now counts**, and `loop retro` offers the lessons that hit
|
|
43
|
+
`memory.recurrence.minSightings` with the promote command already filled in.
|
|
44
|
+
- Promotion still requires a human (`HUMAN_APPROVAL_REQUIRED`, ADR-0019). Memory is read into every
|
|
45
|
+
worker brief: a wrong lesson promoted without a human is a wrong instruction on every future task.
|
|
46
|
+
|
|
47
|
+
### One human approval covers the goal's own effects
|
|
48
|
+
|
|
49
|
+
- **`tracking.authorization`** (`goal` | `separate`, default `goal`). Approving the verification result
|
|
50
|
+
now authorizes the declared external effect too, recording `authorization.recorded` at the same
|
|
51
|
+
instant. `separate` keeps the old two-gate behaviour.
|
|
52
|
+
|
|
53
|
+
### Fixes that had never shipped
|
|
54
|
+
|
|
55
|
+
- Phase age and worker age are different numbers: `ageMin` counts from dispatch, `phaseAgeMin` from the
|
|
56
|
+
event that started the phase. An item in review for 10 minutes used to show the dispatch age and looked
|
|
57
|
+
stuck for hours.
|
|
58
|
+
- Stale delivery state is reset on redispatch, dead stage locks recover, queue alerts are ignored during
|
|
59
|
+
scheduled stages, and expected pre-PR delivery gaps stop being reported as problems.
|
|
60
|
+
|
|
3
61
|
## [0.13.0] - 2026-09-14
|
|
4
62
|
|
|
5
63
|
A full-codebase test-coverage sweep (every module in `src/kernel/`, `src/execution/`, `src/adapters/`, and most of
|
package/README.md
CHANGED
|
@@ -36,7 +36,7 @@ ak-harness doctor --json
|
|
|
36
36
|
ak-harness plan approved --by human
|
|
37
37
|
ak-harness start
|
|
38
38
|
ak-verify run --json
|
|
39
|
-
ak-verify approve
|
|
39
|
+
ak-verify approve approved --by human --json
|
|
40
40
|
ak-harness cancel <run-id> --by human --reason "Requirements changed"
|
|
41
41
|
ak-harness benchmark --manifest benchmarks/harness-phase-0.json --json
|
|
42
42
|
```
|
|
@@ -90,7 +90,12 @@ that must match the `verification.completed` event before human approval. Human
|
|
|
90
90
|
approvals, rejections, and tracking authorizations are then recorded as
|
|
91
91
|
hash-chained `approval.recorded` or `authorization.recorded` events bound to
|
|
92
92
|
that digest, source revision, and contract hash. The stable `run.json` remains
|
|
93
|
-
the CLI projection and evidence index.
|
|
93
|
+
the CLI projection and evidence index. The run ID and hashes are audit fields,
|
|
94
|
+
not inputs a human needs to provide: `ak-verify approve approved` resolves the
|
|
95
|
+
latest pending run. By default, a declared tracking target is covered by the
|
|
96
|
+
same goal approval and records both lifecycle events. Set
|
|
97
|
+
`tracking.authorization` to `"separate"` only when a project explicitly needs
|
|
98
|
+
a second human decision.
|
|
94
99
|
|
|
95
100
|
Use `ak-harness audit [run-id]` to reconcile a run projection with its verified
|
|
96
101
|
events. `ak-harness status` performs the same reconciliation before reporting
|
|
@@ -157,7 +162,7 @@ contract is frozen:
|
|
|
157
162
|
|
|
158
163
|
`runtime.kind` chooses the executor used by an integration: `process` is a bounded shell-free local child process; `docker` adds the Docker sandbox. The choice is frozen in the resolved contract and therefore changes its hash. Docker remains fail-closed when its daemon or image is unavailable.
|
|
159
164
|
|
|
160
|
-
`autonomy: "yolo"` removes the generic final review only after every applicable check passes, tracking is disabled, and the frozen contract has no ambiguity. It never auto-approves a material decision, external tracking, or a tool rule that requires approval.
|
|
165
|
+
`autonomy: "yolo"` removes the generic final review only after every applicable check passes, tracking is disabled, and the frozen contract has no ambiguity. It never auto-approves a material decision, external tracking, or a tool rule that requires approval. A human goal approval covers declared intermediate work and goal-scoped tracking; it does not waive evidence, freshness, or ambiguity gates.
|
|
161
166
|
|
|
162
167
|
The phase executor applies the same rule to a declarative SDLC profile. A profile
|
|
163
168
|
declares dependencies, inputs/outputs, gates, bounded retries, budgets, and an
|