diff --git a/.changeset/diff-worlds.md b/.changeset/diff-worlds.md deleted file mode 100644 index 0e04428..0000000 --- a/.changeset/diff-worlds.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"github-agent-workflow": patch ---- - -`diffWorlds(before, after)` in `scripts/scenario.mjs` turns the change a run left behind into the effects the scenario checker takes, so a real run can be judged by the same scope, invariant and oracle checks as a golden scenario. A change that no effect can express (a title or body edit, an edited or removed comment, a reopened item) is reported as an `unmodelled` effect, which `checkScenario` rejects unless the contract lists a new `unmodelled` write scope. Tests round-trip every golden scenario and 600 generated worlds. diff --git a/.changeset/gh-simulator-api-faults.md b/.changeset/gh-simulator-api-faults.md deleted file mode 100644 index 6d0baf4..0000000 --- a/.changeset/gh-simulator-api-faults.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"github-agent-workflow": patch ---- - -The `gh` simulator for tests is finished. `gh api` answers the REST calls the package makes (a user, an item's comments, editing a comment in place, a PR's files, repository contents and tree, the PR list and one PR, and `update-branch`), a world's `faults` make a matching call fail or let another run get in first, and `tests/lib.test.sh` now runs against the simulator instead of its own stub, so there is one mock of `gh`. The checker's effect model gains `comment_edit`, so a lease edited in place is read back by `diffWorlds`. diff --git a/.changeset/gh-simulator-read-paths.md b/.changeset/gh-simulator-read-paths.md deleted file mode 100644 index 0be2cfe..0000000 --- a/.changeset/gh-simulator-read-paths.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"github-agent-workflow": patch ---- - -A `gh` simulator for tests (`tests/sim/bin/gh`) answers `gh` calls from a world file in the scenarios' format and logs every call. This part covers the read paths: `issue list|view`, `pr list|view|checks`, `label list`, `repo view`, `auth status` and `run view`, with `--json` fields checked against the ones `gh` really has. A command, flag or field it does not cover exits with `unsupported: `, and a test fails when a skill calls a `gh` command that is not in the manifest. The write paths, `api` and fault injection follow. diff --git a/.changeset/gh-simulator-write-paths.md b/.changeset/gh-simulator-write-paths.md deleted file mode 100644 index 3c7a401..0000000 --- a/.changeset/gh-simulator-write-paths.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"github-agent-workflow": patch ---- - -The `gh` simulator for tests now writes. `issue edit|close|create|comment|reopen`, `pr edit|create|comment|merge` and `label create` change the world file the way `gh` would and refuse what `gh` refuses (an unknown label, a merge pinned to the wrong head, a duplicate PR), leaving the file untouched when a call fails. A run's changes are read back by `diffWorlds`. For that, a `create_issue` or `create_pr` effect can carry the new item's title, body, creation time, author and branch as `data`, and a `close` effect its `reason`. diff --git a/.changeset/grill-contract.md b/.changeset/grill-contract.md deleted file mode 100644 index a9297c9..0000000 --- a/.changeset/grill-contract.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"github-agent-workflow": patch ---- - -`grill-via-github-comments` has a `## Contract` (`kind: utility`, pure, `used_by: [unattended-triage]`) and three scenarios: two independent decisions asked as one round, a dependent decision left for a later round, and an open question the code answers, stated as a finding. The contract says what the text already said, that the skill returns the round and posts nothing, and its description now says it drafts the questions for the caller to post. The scenario checker accepts a list as a document value and has an oracle that checks a round against the subject's decision tree: the whole frontier is asked, nothing whose prerequisite is open, nothing that can be looked up, and every question has a recommended answer. See ADR 0013. diff --git a/.changeset/group-dispatch-scenarios.md b/.changeset/group-dispatch-scenarios.md deleted file mode 100644 index 560d8c4..0000000 --- a/.changeset/group-dispatch-scenarios.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"github-agent-workflow": patch ---- - -The five group skills have scenarios (three each). A group scenario lists `expect.dispatches`, the group's `results` and its one run-log `entry`, and for `triage-github-issues` the `reconcile` call that comes first. The checker picks the batch from the real item skill's eligibility oracle, oldest first, so a dispatch of an ineligible item, one past the batch, or in the wrong order fails. It reads what a dispatch must carry from the real item contract, `write_log=false` and the run's inputs that the item lists in `params`, so a dispatch that drops `trusted_authors`, or forwards something the item does not list, fails. `explore-github-repo` is checked as its own kind of group: findings ranked best first, one call to `file-github-issues` with `limit` and the shared inputs, only filed issues counting toward the cap, and the count line and deferred list in the log. The coverage gate wants three scenarios for a group skill, one that dispatches and one that does not. See ADR 0012. diff --git a/.changeset/merge-safety-contract.md b/.changeset/merge-safety-contract.md deleted file mode 100644 index 0bf9d39..0000000 --- a/.changeset/merge-safety-contract.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"github-agent-workflow": patch ---- - -`merge-safety` has a `## Contract` (`kind: utility`, pure, `used_by: [review-github-pr]`) and five scenarios: a breaking change and a migration with no rollback plan (BLOCK), a clean small PR (PASS), and a moved head and a pending check (HOLD). The scenario checker has a mode for a skill that returns a document: the report must have the contract's lines and a verdict it allows, a pure skill must leave no effects, and the world settles what it can (a draft, a pending check or a head that is not the pinned one must give HOLD). The coverage gate counts a utility skill's verdicts. One behaviour is now written down: when `head` is given and is not the PR's current head, `merge-safety` assesses nothing and reports HOLD. See ADR 0013. diff --git a/.changeset/model-evals.md b/.changeset/model-evals.md deleted file mode 100644 index d4752c7..0000000 --- a/.changeset/model-evals.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"github-agent-workflow": minor ---- - -`npm run eval -- / --model ` runs a model through a skill against the `gh` simulator and judges what it did with the scenario checker. It reports a pass, a deviation from the scenario's golden, or a violation of the skill's contract, with the diff of effects and the skills the model called. It is opt-in (it needs `ANTHROPIC_API_KEY` and costs money), capped by `--max-runs`, `--max-tokens` and `--max-turns`, never part of CI, and keeps transcripts in the git-ignored `.eval/`. diff --git a/.changeset/one-lease-comment-per-step.md b/.changeset/one-lease-comment-per-step.md deleted file mode 100644 index 5939af9..0000000 --- a/.changeset/one-lease-comment-per-step.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"github-agent-workflow": patch ---- - -`claim` and `renew` now edit this account's own lease comment for the step in place instead of posting a new one each time, so an item taken through three claims of a step has one lease comment, not three. Each step keeps its own comment, a comment from another account is never edited, and if the edit fails the helper posts a new one. Because a comment's position in the thread no longer says which lease is newest, `lease_live` and `leaseState` now take the lease written last (`updated_at`, else `created_at`, else thread order); the expiry is still the `expires=` in the marker. New helper `ownLeaseComment` and CLI command `own-lease` in `helpers.mjs`, shared fixtures for the ordering, and shell tests for one comment per step, other accounts, the failed-edit fallback and the ordering (#69). diff --git a/.changeset/oracles-for-item-skills.md b/.changeset/oracles-for-item-skills.md deleted file mode 100644 index 04eadce..0000000 --- a/.changeset/oracles-for-item-skills.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"github-agent-workflow": patch ---- - -Scenario checks now have an eligibility oracle for every item skill: `triage-github-issue`, `implement-github-issue` and `review-github-pr` join `shepherd-github-pr`. Each mirrors its skill's `requires`, models the lease as `lease: live | stale | none` on the item, and honours `lease_held`. A test compares each skill's number of `requires` entries with the oracle's, so a changed precondition prompts a look at the oracle. A skipped item no longer has to be free of lease labels, because the label may belong to the run that holds it. Test tooling only, with no change to any skill. See `docs/adr/0012-scenarios.md`. diff --git a/.changeset/pr-author-association.md b/.changeset/pr-author-association.md deleted file mode 100644 index f247299..0000000 --- a/.changeset/pr-author-association.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"github-agent-workflow": patch ---- - -`prs_for_issue` and `issue_for_pr` work on a real `gh`. They asked `gh pr list` and `gh pr view` for `authorAssociation`, which `gh` rejects as a PR field (`Unknown JSON field`), so neither could find the PR that belongs to an issue. Both now read the REST pull request, which has the author's association, and apply the same trust rule as before. `issue_for_pr` reads GitHub's own issue links with `gh` 2.72 or newer, and without that it still reads the description. It now prints the issue numbers in numeric order. diff --git a/.changeset/rerun-expectation.md b/.changeset/rerun-expectation.md deleted file mode 100644 index 108baf6..0000000 --- a/.changeset/rerun-expectation.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"github-agent-workflow": patch ---- - -A scenario can say what a second run finds, so that `idempotent` in a contract is checked. `expect.rerun` is `ineligible` (a terminal outcome), `eligible` (a failed run, which leaves the item for a retry) or `{skip: }`, and the checker asks the skill's own eligibility oracle about the same item in the world the run leaves behind. A push puts the PR's checks back to pending, so a pushed fix is not eligible again until CI reports. A scenario with `interrupted: true` returns no result and must be eligible again, with a stale lease, and its `rerun_effects` may not repeat what the interrupted pass already did. All 30 scenarios that complete a run now carry a `rerun`, two scenarios cover an interrupted triage and an interrupted implementation, and the coverage report lists any scenario that has none, which `npm test` fails on. A test with a deliberately broken oracle shows a terminal state that is still eligible being rejected. diff --git a/.changeset/retrospective-contract.md b/.changeset/retrospective-contract.md deleted file mode 100644 index 78183c0..0000000 --- a/.changeset/retrospective-contract.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"github-agent-workflow": patch ---- - -`retrospective` has a `## Contract` (`kind: utility`, pure, `used_by: []`) and five scenarios over a world of run-log issues: an entry older than `days` is not used, `step` and `only_runner` filter, ranked suggestions never exceed `max_suggestions`, and a log with only idle entries gives an empty report. The scenario world can now describe run-log entries (`run`, `step`, `runner`, `at`, `outcome`, `problems`) and a scenario carries a `now` date. The skill now says what the report contains when no entry is left: `Entries considered: 0`, a summary that says nothing was found, and no suggestions. The validator accepts `used_by: []` for a skill that is not user-invoked only when the skill's text says it is run by hand, which `retrospective` now does. See ADR 0013. diff --git a/.changeset/runner-docs-sweeper-dispatch.md b/.changeset/runner-docs-sweeper-dispatch.md deleted file mode 100644 index f022583..0000000 --- a/.changeset/runner-docs-sweeper-dispatch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"github-agent-workflow": patch ---- - -`docs/RUNNERS.md` now covers the sweeper and the newer inputs. It says when to schedule `reconcile-github-issues` (and that Triaging also runs it), what a runner that dispatches items itself must pass (the item's URL, `write_log=false` and the group's inputs), and where `write_log`, `lease_held` and `limit` are defined. The README's schedule table lists the sweeper. diff --git a/.changeset/setup-contract.md b/.changeset/setup-contract.md deleted file mode 100644 index 7449096..0000000 --- a/.changeset/setup-contract.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"github-agent-workflow": patch ---- - -`setup-github-agent-workflow` has a `## Contract` (`kind: utility`, user-invoked, `used_by: []`) and five scenarios: an empty repository gets every label, an existing `agent:` label is reset and an existing triage label is kept, a second run changes nothing, the settings go into `CLAUDE.md` when it exists, and only the `## GitHub workflow` section is updated. Every skill now has a contract, and `CONTRACT_PENDING` is empty. The skill lists its nine settings in an Inputs table, which the protocol's Defaults rows now name it as a user of, and the protocol says that `repository` writes include repository settings such as the label set. The scenario world can hold the repository's labels and files, with `label_create`, `label_update` and `write_file` effects that `diffWorlds` also produces. The label set a scenario expects is read from `references/labels.md`. See ADR 0013. diff --git a/.changeset/split-an-issue-that-is-too-large.md b/.changeset/split-an-issue-that-is-too-large.md deleted file mode 100644 index bfa23da..0000000 --- a/.changeset/split-an-issue-that-is-too-large.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"github-agent-workflow": minor ---- - -`implement-github-issue` splits an issue that is too large for one PR into linked sub-issues (`#N split into #A, #B`), bounded by the new `max_depth` input (default `1`). `file-github-issues` takes a `parent`, `reconcile-github-issues` closes the parent when its sub-issues close, and the scenario checker rejects `lease_held=true` from a skill that does not hold the lease. See ADR 0015. diff --git a/.changeset/test-prerequisites.md b/.changeset/test-prerequisites.md deleted file mode 100644 index ffc4781..0000000 --- a/.changeset/test-prerequisites.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"github-agent-workflow": patch ---- - -`tests/lib.test.sh` now checks for `jq`, `git` and `node` first and exits with one line naming the missing tool, instead of printing dozens of `jq: command not found` errors and ending with a long list of failures. The hooks check in `npm test` now says how to install the hooks (`npm ci`) and how to skip the check (`HUSKY=0`). `AGENTS.md` lists what the checks need. diff --git a/.changeset/unattended-triage-contract.md b/.changeset/unattended-triage-contract.md deleted file mode 100644 index 4e2c3ae..0000000 --- a/.changeset/unattended-triage-contract.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"github-agent-workflow": patch ---- - -`unattended-triage` has a `## Contract` (`kind: utility`, pure, `used_by: [triage-github-issue]`) and four scenarios: a complete bug (ready-for-agent), a feature with no use case and an issue with an open question (needs-info), and a wontfix recommendation (ready-for-human, never a close). The skill's description said it writes the outcome comment, while its body and its caller say the caller posts it. The description now says it drafts the comment and the caller posts it, as the body always did. The skill's text now says that an open question or a missing use case is needs-info and that wontfix is ready-for-human, which `triage-github-issue` already applied after the fact. The scenario checker gains an oracle for the state, the comment structure and these rules. See ADR 0013. diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 4415ee1..507a33b 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "github-agent-workflow", - "version": "1.10.0", + "version": "1.11.0", "description": "Agent skills that run a GitHub repository's issue-to-merge pipeline unattended: explore, triage, implement, shepherd through CI, review and merge. Each step is a group skill that selects work and an item skill that does it.", "author": { "name": "Glenn Faison" diff --git a/CHANGELOG.md b/CHANGELOG.md index 028d706..00469ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,31 @@ # github-agent-workflow +## 1.11.0 + +### Minor Changes + +- 3d8c535: `npm run eval -- / --model ` runs a model through a skill against the `gh` simulator and judges what it did with the scenario checker. It reports a pass, a deviation from the scenario's golden, or a violation of the skill's contract, with the diff of effects and the skills the model called. It is opt-in (it needs `ANTHROPIC_API_KEY` and costs money), capped by `--max-runs`, `--max-tokens` and `--max-turns`, never part of CI, and keeps transcripts in the git-ignored `.eval/`. +- d171e89: `implement-github-issue` splits an issue that is too large for one PR into linked sub-issues (`#N split into #A, #B`), bounded by the new `max_depth` input (default `1`). `file-github-issues` takes a `parent`, `reconcile-github-issues` closes the parent when its sub-issues close, and the scenario checker rejects `lease_held=true` from a skill that does not hold the lease. See ADR 0015. + +### Patch Changes + +- f92015c: `diffWorlds(before, after)` in `scripts/scenario.mjs` turns the change a run left behind into the effects the scenario checker takes, so a real run can be judged by the same scope, invariant and oracle checks as a golden scenario. A change that no effect can express (a title or body edit, an edited or removed comment, a reopened item) is reported as an `unmodelled` effect, which `checkScenario` rejects unless the contract lists a new `unmodelled` write scope. Tests round-trip every golden scenario and 600 generated worlds. +- 6da1eff: The `gh` simulator for tests is finished. `gh api` answers the REST calls the package makes (a user, an item's comments, editing a comment in place, a PR's files, repository contents and tree, the PR list and one PR, and `update-branch`), a world's `faults` make a matching call fail or let another run get in first, and `tests/lib.test.sh` now runs against the simulator instead of its own stub, so there is one mock of `gh`. The checker's effect model gains `comment_edit`, so a lease edited in place is read back by `diffWorlds`. +- 302d78c: A `gh` simulator for tests (`tests/sim/bin/gh`) answers `gh` calls from a world file in the scenarios' format and logs every call. This part covers the read paths: `issue list|view`, `pr list|view|checks`, `label list`, `repo view`, `auth status` and `run view`, with `--json` fields checked against the ones `gh` really has. A command, flag or field it does not cover exits with `unsupported: `, and a test fails when a skill calls a `gh` command that is not in the manifest. The write paths, `api` and fault injection follow. +- 862e759: The `gh` simulator for tests now writes. `issue edit|close|create|comment|reopen`, `pr edit|create|comment|merge` and `label create` change the world file the way `gh` would and refuse what `gh` refuses (an unknown label, a merge pinned to the wrong head, a duplicate PR), leaving the file untouched when a call fails. A run's changes are read back by `diffWorlds`. For that, a `create_issue` or `create_pr` effect can carry the new item's title, body, creation time, author and branch as `data`, and a `close` effect its `reason`. +- b0f6069: `grill-via-github-comments` has a `## Contract` (`kind: utility`, pure, `used_by: [unattended-triage]`) and three scenarios: two independent decisions asked as one round, a dependent decision left for a later round, and an open question the code answers, stated as a finding. The contract says what the text already said, that the skill returns the round and posts nothing, and its description now says it drafts the questions for the caller to post. The scenario checker accepts a list as a document value and has an oracle that checks a round against the subject's decision tree: the whole frontier is asked, nothing whose prerequisite is open, nothing that can be looked up, and every question has a recommended answer. See ADR 0013. +- 3342d51: The five group skills have scenarios (three each). A group scenario lists `expect.dispatches`, the group's `results` and its one run-log `entry`, and for `triage-github-issues` the `reconcile` call that comes first. The checker picks the batch from the real item skill's eligibility oracle, oldest first, so a dispatch of an ineligible item, one past the batch, or in the wrong order fails. It reads what a dispatch must carry from the real item contract, `write_log=false` and the run's inputs that the item lists in `params`, so a dispatch that drops `trusted_authors`, or forwards something the item does not list, fails. `explore-github-repo` is checked as its own kind of group: findings ranked best first, one call to `file-github-issues` with `limit` and the shared inputs, only filed issues counting toward the cap, and the count line and deferred list in the log. The coverage gate wants three scenarios for a group skill, one that dispatches and one that does not. See ADR 0012. +- f25834a: `merge-safety` has a `## Contract` (`kind: utility`, pure, `used_by: [review-github-pr]`) and five scenarios: a breaking change and a migration with no rollback plan (BLOCK), a clean small PR (PASS), and a moved head and a pending check (HOLD). The scenario checker has a mode for a skill that returns a document: the report must have the contract's lines and a verdict it allows, a pure skill must leave no effects, and the world settles what it can (a draft, a pending check or a head that is not the pinned one must give HOLD). The coverage gate counts a utility skill's verdicts. One behaviour is now written down: when `head` is given and is not the PR's current head, `merge-safety` assesses nothing and reports HOLD. See ADR 0013. +- 6ae692f: `claim` and `renew` now edit this account's own lease comment for the step in place instead of posting a new one each time, so an item taken through three claims of a step has one lease comment, not three. Each step keeps its own comment, a comment from another account is never edited, and if the edit fails the helper posts a new one. Because a comment's position in the thread no longer says which lease is newest, `lease_live` and `leaseState` now take the lease written last (`updated_at`, else `created_at`, else thread order); the expiry is still the `expires=` in the marker. New helper `ownLeaseComment` and CLI command `own-lease` in `helpers.mjs`, shared fixtures for the ordering, and shell tests for one comment per step, other accounts, the failed-edit fallback and the ordering (#69). +- e5fad13: Scenario checks now have an eligibility oracle for every item skill: `triage-github-issue`, `implement-github-issue` and `review-github-pr` join `shepherd-github-pr`. Each mirrors its skill's `requires`, models the lease as `lease: live | stale | none` on the item, and honours `lease_held`. A test compares each skill's number of `requires` entries with the oracle's, so a changed precondition prompts a look at the oracle. A skipped item no longer has to be free of lease labels, because the label may belong to the run that holds it. Test tooling only, with no change to any skill. See `docs/adr/0012-scenarios.md`. +- b563fd8: `prs_for_issue` and `issue_for_pr` work on a real `gh`. They asked `gh pr list` and `gh pr view` for `authorAssociation`, which `gh` rejects as a PR field (`Unknown JSON field`), so neither could find the PR that belongs to an issue. Both now read the REST pull request, which has the author's association, and apply the same trust rule as before. `issue_for_pr` reads GitHub's own issue links with `gh` 2.72 or newer, and without that it still reads the description. It now prints the issue numbers in numeric order. +- 8eb937a: A scenario can say what a second run finds, so that `idempotent` in a contract is checked. `expect.rerun` is `ineligible` (a terminal outcome), `eligible` (a failed run, which leaves the item for a retry) or `{skip: }`, and the checker asks the skill's own eligibility oracle about the same item in the world the run leaves behind. A push puts the PR's checks back to pending, so a pushed fix is not eligible again until CI reports. A scenario with `interrupted: true` returns no result and must be eligible again, with a stale lease, and its `rerun_effects` may not repeat what the interrupted pass already did. All 30 scenarios that complete a run now carry a `rerun`, two scenarios cover an interrupted triage and an interrupted implementation, and the coverage report lists any scenario that has none, which `npm test` fails on. A test with a deliberately broken oracle shows a terminal state that is still eligible being rejected. +- dcfca22: `retrospective` has a `## Contract` (`kind: utility`, pure, `used_by: []`) and five scenarios over a world of run-log issues: an entry older than `days` is not used, `step` and `only_runner` filter, ranked suggestions never exceed `max_suggestions`, and a log with only idle entries gives an empty report. The scenario world can now describe run-log entries (`run`, `step`, `runner`, `at`, `outcome`, `problems`) and a scenario carries a `now` date. The skill now says what the report contains when no entry is left: `Entries considered: 0`, a summary that says nothing was found, and no suggestions. The validator accepts `used_by: []` for a skill that is not user-invoked only when the skill's text says it is run by hand, which `retrospective` now does. See ADR 0013. +- cd2e13c: `docs/RUNNERS.md` now covers the sweeper and the newer inputs. It says when to schedule `reconcile-github-issues` (and that Triaging also runs it), what a runner that dispatches items itself must pass (the item's URL, `write_log=false` and the group's inputs), and where `write_log`, `lease_held` and `limit` are defined. The README's schedule table lists the sweeper. +- 14b9c41: `setup-github-agent-workflow` has a `## Contract` (`kind: utility`, user-invoked, `used_by: []`) and five scenarios: an empty repository gets every label, an existing `agent:` label is reset and an existing triage label is kept, a second run changes nothing, the settings go into `CLAUDE.md` when it exists, and only the `## GitHub workflow` section is updated. Every skill now has a contract, and `CONTRACT_PENDING` is empty. The skill lists its nine settings in an Inputs table, which the protocol's Defaults rows now name it as a user of, and the protocol says that `repository` writes include repository settings such as the label set. The scenario world can hold the repository's labels and files, with `label_create`, `label_update` and `write_file` effects that `diffWorlds` also produces. The label set a scenario expects is read from `references/labels.md`. See ADR 0013. +- 87feef1: `tests/lib.test.sh` now checks for `jq`, `git` and `node` first and exits with one line naming the missing tool, instead of printing dozens of `jq: command not found` errors and ending with a long list of failures. The hooks check in `npm test` now says how to install the hooks (`npm ci`) and how to skip the check (`HUSKY=0`). `AGENTS.md` lists what the checks need. +- 85dd01f: `unattended-triage` has a `## Contract` (`kind: utility`, pure, `used_by: [triage-github-issue]`) and four scenarios: a complete bug (ready-for-agent), a feature with no use case and an issue with an open question (needs-info), and a wontfix recommendation (ready-for-human, never a close). The skill's description said it writes the outcome comment, while its body and its caller say the caller posts it. The description now says it drafts the comment and the caller posts it, as the body always did. The skill's text now says that an open question or a missing use case is needs-info and that wontfix is ready-for-human, which `triage-github-issue` already applied after the fact. The scenario checker gains an oracle for the state, the comment structure and these rules. See ADR 0013. + ## 1.10.0 ### Minor Changes diff --git a/package.json b/package.json index f86f5ab..8a64af4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "github-agent-workflow", - "version": "1.10.0", + "version": "1.11.0", "private": true, "description": "Agent skills that run a GitHub repository's issue-to-merge pipeline unattended", "license": "MIT",