diff --git a/.agents/skills/upstream-status/SKILL.md b/.agents/skills/upstream-status/SKILL.md index fa01d7ce..6370f491 100644 --- a/.agents/skills/upstream-status/SKILL.md +++ b/.agents/skills/upstream-status/SKILL.md @@ -24,17 +24,20 @@ dependency policies, constraints, and the `watch` list of upstream threads. 2. Give the counts first, in plain language, from `counts`. Leave out groups with zero items. 3. Then list the action items with their links, one report group at a time, in this order (the report's group titles): - - "Could not check" first, each thread with its error from `fetchErrors`: nothing about it - is known; + - "Could not check" first, each thread with its error from `fetchErrors`. When the thread + itself could not be read nothing about it is known; when only its release could not be + confirmed, its other groups still hold; - "Needs our reply"; - "Released and actionable"; + - "Released, fix not confirmed": offer to confirm by hand and record `minVersion`; never + dispatch it; - "Fixed upstream, ak still carries the workaround"; - "Reopened upstream after ak recorded a fix"; - "Closed upstream as not planned"; - "No upstream activity for the stale limit"; - "Ready to retire"; - "Constraints past their retest date"; - - "Tracking issues to migrate". + - "Our tracking issues". For each item give the id, title, URL and a one-line reason: who replied and when, which release, or which ak change is pending. Give "Fixed upstream, not yet released", @@ -52,8 +55,8 @@ dependency policies, constraints, and the `watch` list of upstream threads. comment on the ledger issue, push, open a pull request or merge without the maintainer's explicit confirmation of that specific action. - Never merge a dispatch pull request. The maintainer merges. -- A "candidate" release is the first version published after the fix. Confirm the fix is in - it before dispatching. +- A release is actionable only when it contains the merged fixing pull request or commit + (`release.basis` says which). An unconfirmed release is never dispatched. - Issue closure alone does not prove a fix (ADR-0041 §7). - For events since a date, run `node scripts/upstream-watch.mjs check --since `. Each line is a ledger line: `UPSTREAM-WATCH …`. diff --git a/.claude/skills/upstream-status/SKILL.md b/.claude/skills/upstream-status/SKILL.md index fa01d7ce..6370f491 100644 --- a/.claude/skills/upstream-status/SKILL.md +++ b/.claude/skills/upstream-status/SKILL.md @@ -24,17 +24,20 @@ dependency policies, constraints, and the `watch` list of upstream threads. 2. Give the counts first, in plain language, from `counts`. Leave out groups with zero items. 3. Then list the action items with their links, one report group at a time, in this order (the report's group titles): - - "Could not check" first, each thread with its error from `fetchErrors`: nothing about it - is known; + - "Could not check" first, each thread with its error from `fetchErrors`. When the thread + itself could not be read nothing about it is known; when only its release could not be + confirmed, its other groups still hold; - "Needs our reply"; - "Released and actionable"; + - "Released, fix not confirmed": offer to confirm by hand and record `minVersion`; never + dispatch it; - "Fixed upstream, ak still carries the workaround"; - "Reopened upstream after ak recorded a fix"; - "Closed upstream as not planned"; - "No upstream activity for the stale limit"; - "Ready to retire"; - "Constraints past their retest date"; - - "Tracking issues to migrate". + - "Our tracking issues". For each item give the id, title, URL and a one-line reason: who replied and when, which release, or which ak change is pending. Give "Fixed upstream, not yet released", @@ -52,8 +55,8 @@ dependency policies, constraints, and the `watch` list of upstream threads. comment on the ledger issue, push, open a pull request or merge without the maintainer's explicit confirmation of that specific action. - Never merge a dispatch pull request. The maintainer merges. -- A "candidate" release is the first version published after the fix. Confirm the fix is in - it before dispatching. +- A release is actionable only when it contains the merged fixing pull request or commit + (`release.basis` says which). An unconfirmed release is never dispatched. - Issue closure alone does not prove a fix (ADR-0041 §7). - For events since a date, run `node scripts/upstream-watch.mjs check --since `. Each line is a ledger line: `UPSTREAM-WATCH …`. diff --git a/docs/UPSTREAM-WATCH.md b/docs/UPSTREAM-WATCH.md index f7e294c1..6b6f59a4 100644 --- a/docs/UPSTREAM-WATCH.md +++ b/docs/UPSTREAM-WATCH.md @@ -1,8 +1,8 @@ # Upstream watch -agentic-kit depends on fixes in Ruflo, Agentic QE, AgentDB, RuVector, RuvNet Brain, Codex and -agent-browser. The upstream watch tracks every upstream thread ak relies on, says when a fix -is ready for ak, and records each event once. +agentic-kit depends on fixes in Ruflo, Agentic QE, AgentDB, RuVector, RuvNet Brain, Codex, +Claude Code, OpenCode and agent-browser. The upstream watch tracks every upstream thread ak +relies on, says when a fix is ready for ak, and records each event once. ## One registry @@ -16,23 +16,27 @@ is the only upstream registry. It ships with ak because the hook audit reads it. - `watchPolicy`: our GitHub logins, the stale limit (90 days), automated-reply patterns, the ledger issue and its sentinel, and the dispatch rules. - `watch`: every upstream issue or pull request ak filed, commented on, or cites in `src/`, - `bin/`, `claude/` or `tests/`, plus ak's own tracking issues that migrate here. + `bin/`, `claude/`, `tests/`, `README.md` or a guide in `docs/` (dated audits, proposals and + research references are exempt by name in `scripts/upstream-watch/citations.mjs`), plus ak's + own tracking issues (pacphi/agentic-kit#213 and #240), each listing the upstream threads it + waits on. The [schema](schemas/agentic-dependency-constraints.schema.json) describes the shape; the loader (`src/lib/hook-audit/upstream.mjs`) also checks that each constraint's issue has a -watch entry naming it. `tests/kit/upstream-watch-registry.test.mjs` fails when source cites a -watched-repository thread the list lacks, or when a file an entry names no longer cites it. +watch entry naming it. `tests/kit/upstream-watch-registry.test.mjs` fails when source or a +user-facing doc cites a watched-repository thread the list lacks, or when a file an entry names +no longer cites it. A watch entry records: | Field | Meaning | |---|---| | `id`, `url`, `kind`, `title` | The thread (`owner/repo#n`, issue or pr). | -| `relation` | `filed`, `commented`, `referenced` (cited, not ours) or `tracking` (our issue that migrates here; lists `tracks`). | -| `dependency` | The dependency policy that governs it. AgentDB threads use `ruflo`: ak gets AgentDB through Ruflo. | -| `doneWhen` | `closed-completed` or `merged`, plus the release channel and the first fixed version when known. | +| `relation` | `filed`, `commented`, `referenced` (cited, not ours) or `tracking` (our own issue that waits on upstream threads; lists them in `tracks`). | +| `dependency` | The dependency policy that governs it. AgentDB threads use `ruflo`: ak gets AgentDB through Ruflo, so an AgentDB fix counts as released only when the newest Ruflo (npm `latest`, the newest version in the support window) installs a fixed agentdb (`doneWhen.release.bundledBy`). AgentDB publishes no tags, so a fix is confirmed by hand and recorded as `minVersion` until then. | +| `doneWhen` | `closed-completed` or `merged`, plus the release channel, the first fixed version when known, the upstream tag spelling (`tagPattern`) when it is not `v`, and the carrier chain (`bundledBy`) when ak gets the package through another. | | `mapping`, `kitImpact`, `adjustment` | Whether ak carries something for it, which files and plan or decision refs, and the change ak makes when it lands. | -| `status`, `history` | Lifecycle status and dated events. | +| `status`, `history` | Lifecycle status and dated events. A `reviewed` event (with a `note`) records that every comment up to the end of that UTC day was read and needs no reply. History carries dates, not times, so a comment posted later on the day of the review is covered too: record a review only after the day's comments are read, or on a later day. | | `constraintIds` | Constraints this thread backs. | ## Lifecycle @@ -49,20 +53,32 @@ A watch entry records: The watcher does not change statuses. The maintainer, or a dispatch pull request, updates the entry and adds a dated `history` line. -## Re-verifying constraints +## Re-checking and re-verifying -Weekly, and before a managed upgrade, re-check each constraint's issue state on GitHub and the -released versions on npm. Update `issueState` where it changed, set `lastVerifiedAt` to the -check date and every `nextRetestAt` one week later, and list what was not re-verified -(reproductions, conformance, sunset conditions) in the commit body. The tests take their -clock from `lastVerifiedAt`, so this is a data-only change. +- **Re-check (weekly, and before a managed upgrade):** re-read each constraint's issue state on + GitHub and the released versions on npm. Update `issueState` where it changed and set + `lastCheckedAt` to the check date. Nothing else moves. The tests take their clock from + `lastCheckedAt`, so this is a data-only change. +- **Re-verify (after a conformance run):** when a constraint's retest (its reproduction or + conformance proof) has been run again, move that constraint's `nextRetestAt`. When every + constraint has been re-run, also set `lastVerifiedAt` to that date. List in the commit body what + was run and what was not. + +A constraint whose `nextRetestAt` has passed shows as stale evidence in the hook audit and under +"Constraints past their retest date"; the registry stays valid. ## The check `scripts/upstream-watch.mjs` is maintainer tooling; it is not published. It reads GitHub with `gh api` and releases with `npm view` or GitHub releases, at most four calls at a time, and -writes nothing. If `gh` is missing or signed out it says so and reports only what the registry -records. It exits 0 unless the command line is wrong. +writes nothing. It runs on macOS and Linux (the routine runs on Linux). On Windows, npm is a +`.cmd` file, which Node refuses to start without a shell +([Spawning `.bat` and `.cmd` files on Windows](https://nodejs.org/api/child_process.html#spawning-bat-and-cmd-files-on-windows)), +so every npm-gated release would read "Could not check"; the script passes version ranges such as +`^3.33.0` that `cmd.exe` would misread, so it does not add one. If `gh` is missing or signed out it says so and reports only what the registry +records. It exits 0 unless the command line is wrong. `check` prints only ledger lines on stdout; +each thread or release it could not check goes to stderr as `Could not check : `, and +`check --json` lists them in `fetchErrors`. ```bash node scripts/upstream-watch.mjs report [--json] @@ -73,8 +89,9 @@ node scripts/upstream-watch.mjs check --since [--ledger ] [--js | Group | Rule | |---|---| -| Needs our reply | A comment from someone else, not a bot, after our last word (a filed issue's body counts) and after the entry's last status change. Automated acknowledgements show as "acknowledged" instead. | -| Released and actionable | Upstream fixed, a release contains the fix, the entry is `watching` or `fixed-unreleased`, and ak has an adjustment. Carries the dispatch branch and removal proof. With no recorded first fixed version, the first release after the fix is a **candidate**: confirm it contains the fix. | +| Needs our reply | A comment from someone else, not a bot, after our last word (a filed issue's body counts) and after the entry's last status change or `reviewed` history line (the maintainer read the thread and nothing needs a reply). Automated acknowledgements show as "acknowledged" instead. | +| Released and actionable | Upstream fixed, and a published release contains the merged fixing pull request (or closing commit), checked against the repository's tag for that version, or the registry records the first fixed version (`minVersion`). The entry is `watching` or `fixed-unreleased` and ak has an adjustment. Carries the dispatch branch and removal proof. | +| Released, fix not confirmed | A release came out after the fix, but ak could not prove it contains the fixing change (no merged pull request closed the thread, or no tag for that version). Confirm by hand and record `minVersion`. Never dispatched. | | Fixed upstream, ak still carries the workaround | The entry is `released` or `dispatched` and ak has an adjustment. | | Fixed upstream, not yet released | Upstream fixed, no release contains it, the entry is `watching` or `fixed-unreleased`, and ak has an adjustment. | | Reopened upstream | Open upstream while the entry says fixed, released, dispatched or adopted. | @@ -83,15 +100,15 @@ node scripts/upstream-watch.mjs check --since [--ledger ] [--js | Closed upstream as not planned | Closed with reason `not_planned`. | | Ready to retire | `adopted`, or closed upstream with nothing in ak waiting on it. | | Constraints past their retest date | A constraint's `nextRetestAt` has passed. | -| Tracking issues to migrate | Open `tracking` entries. | +| Our tracking issues | Open `tracking` entries: our own issues waiting on the upstream threads they list. | | Unmapped | No ak change recorded. | -| Could not check | Reading the thread or the release failed; the report names the error. Nothing about the thread is known. | +| Could not check | Reading the thread, the release or its confirmation failed; the report names the error. When the thread itself could not be read, nothing about it is known; when only the release could not be confirmed, the thread's other groups and ledger lines still count. | ## The ledger -The ledger is one pinned issue titled "Upstream watch" in `pacphi/agentic-kit`. The maintainer -creates, pins and locks it (`gh issue lock`, so only collaborators can comment) when creating -the daily routine. The repository is public, so the routine reads only its own comments and +The ledger is [pacphi/agentic-kit#243](https://github.com/pacphi/agentic-kit/issues/243), titled +"Upstream watch", pinned and locked (`gh issue lock`, so only collaborators can comment); +`watchPolicy.ledger.issue` records it. The repository is public, so the routine reads only its own comments and those of the logins in `watchPolicy.ours`; anyone else's comment is ignored. Each event is a line: @@ -100,7 +117,8 @@ UPSTREAM-WATCH [key=value ...] ``` Events: `reply` and `acknowledged` (with `by=` and the comment's `at=` time, so each comment is -its own line), `closed`, `merged`, `released`, `reopened`, `stale`, +its own line), `closed`, `merged`, `released` (with `version=`, and `pr=` or `commit=` naming the +fixing change when the release was confirmed from it), `reopened`, `stale`, `retire-proposed`, `retest-due` (constraint id) and `idle` (id `registry`, nothing left to watch). `check --since` limits replies, acknowledgements, closures and merges to activity after `--since`. The other events repeat while their condition holds, dated by the upstream fact, so @@ -109,6 +127,34 @@ so an exact line the routine recorded is never acted on twice. The file holds on routine's own comments: a line someone else posted would suppress a real event. Each posted comment ends with `checked-at