Conversation
leggetter
force-pushed
the
docs/agent-review-skill
branch
2 times, most recently
from
September 21, 2026 17:43
0127a6a to
9b7e068
Compare
Adds .agents/skills/hookdeck-cli-review/SKILL.md, alongside hookdeck-cli-release, plus a pointer in AGENTS.md § Agent skills. The skill is the review delta over AGENTS.md: what to look at in a diff, and the traps a green pull request hides. - Acceptance runs on every PR to main/next with no path filter, but is not a required check, so a red or skipped run still merges -- and then blocks the next release tag, since release.yml gates its builds on acceptance. The one case it genuinely does not run is a head branch updated by merging another PR into it; workflow_dispatch is the only remedy. - A new acceptance build tag must be registered in five hand-maintained lists -- run_parallel.sh, acceptance.yml, and three in test/acceptance/README.md -- with //go:build manual as a deliberate exception. - REFERENCE.md is generated and no CI job checks it; CLITelemetry JSON tags are a wire contract; acceptance logs are world-readable on a public repo. - What not to raise: CHANGELOG entries, and the machine-written package.json version. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
leggetter
force-pushed
the
docs/agent-review-skill
branch
from
September 21, 2026 18:10
9b7e068 to
2340843
Compare
Two review findings on the hookdeck-cli-review skill. The tag-registration section said all five hand-maintained lists agree "on 21 distinct tags". Four of them carry 20: telemetry is the twenty-first and is registered separately in the same files -- run_telemetry() in run_parallel.sh, the acceptance-telemetry job in acceptance.yml, and its own -tags=telemetry command in the README. Only the README's "Run all automated tests" string carries all 21 in one list. A reviewer following the section's own instruction would have opened run_parallel.sh, counted 20, and reported drift that is not there -- the same failure the manual-tag exception was added to prevent. The required-check list is the only claim in the file sourced from GitHub branch-protection settings rather than from the tree, so it can rot without a commit. It now carries the gh api query to re-read it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Three review findings on the hookdeck-cli-review skill. The CLITelemetry section said a renamed JSON tag "compiles, passes unit tests, passes acceptance, and silently empties the dashboards". It does not. pkg/hookdeck/telemetry_test.go asserts the tags by literal key name against a marshalled map -- TestTelemetryJSONSerialization covers six of the eight, TestTelemetryJSONWithGeneratedResource covers generated_resource -- and neither carries a build tag or a testing.Short() guard, so both run under the required unit-test check. command_flags is pinned by the acceptance telemetry job. Seven of the eight renames turn a required check red. The wire-contract point survives, but the trap is the next move, not the rename: the obvious way to get the build green is to update the expected key in the test, which restores the signal while the dashboards built on the old name stay empty. A diff that edits telemetry.go and its expected key names together is the thing to flag. That also fixes the section premise. Two surfaces here are unguarded -- REFERENCE.md and the website generator -- not three. The credentials section attributed the test-only-account rule to "the test credentials" generally. The comment in acceptance.yml is scoped to HOOKDECK_CLI_TESTING_CLI_KEY, and its reason -- a key that reaches every org its owner belongs to -- is a property of that account-wide key, not of the per-slice project-scoped secrets. Scoped, with the world-readable log kept as the part that applies to all of them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The `CLITelemetry` section claimed `command_flags` was "pinned by the acceptance telemetry job". The assertion exists, but it never runs: TestTelemetryLoginCommandFlagsProxy skips unless HOOKDECK_CLI_TESTING_CLI_KEY is set, and the acceptance-telemetry job does not set it. Renaming that tag really does go green and empty the dashboard. Rather than correct the per-tag breakdown a third time, state the rule and hand over the grep that re-derives it for whichever tag is in the diff, mirroring how the branch-protection section already works. Adds a section on the failure mode that hid this: an acceptance job can be green because its tests skipped themselves for a missing credential, which `gh pr checks` cannot show. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this adds
AGENTS.mdcovers how to build, test and lint this repository, thoroughly. Nothing in the repo covers what to look for in a diff — there's noCONTRIBUTING.md, no PR template, noCODEOWNERS, and neither existing skill is about review. So an agent asked to review a change here infers the standard from scratch each time.This adds
.agents/skills/hookdeck-cli-review/SKILL.md, alongsidehookdeck-cli-release, plus one line inAGENTS.md§ Agent skills. 300 lines; frontmatter isnameanddescriptiononly; nothing in it references a skill, role or repository a reader of hookdeck-cli cannot see.Second review round: four findings, all addressed
A review of
9b7e068found no false statements but four things to change. The commit was amended, so diff9b7e068..2340843(the force-push is in the timeline) to see only this round.1. The tag rule was not a two-place rule — it's five. The file said a new acceptance tag has to be registered in
run_parallel.shandacceptance.yml.test/acceptance/README.mdcarries the same list in three more hand-maintained spots: the "Run all automated tests" command, the three per-slice commands, and theSlice N featuresbullets. All five are listed now. The section calls out the "Run all" one as the worst to miss, because the documented way to run everything then quietly stops running everything and still exits 0. I re-checked the sync claim by parsing//go:buildout of everytest/acceptance/*_test.go: 22 tags, 21 oncemanualis excluded, and the "Run all" string is exactly that set.2. "The part no other file in the repository covers" was overstated, and is gone.
test/acceptance/README.md§ Parallelisation already documents the slice-to-tag mapping, the per-slice accounts and the separate telemetry job. The section now points at the README for the mechanism and claims only what is actually uncovered: that the five lists drift independently. The "Which slice a tag lands in" section was trimmed to the judgement it's there for — the 12-tags-against-a-12-minute-timeout imbalance — instead of restating the accounts.Included in that fix: the README misattributes the matrix to
.github/workflows/test-acceptance.yml. That file only declares triggers and callsacceptance.yml, which is where the slices live. The skill says so, since it sends readers to the README.3. The one case where acceptance genuinely does not run was missing.
test-acceptance.ymldocuments it in a comment above its triggers:pull_requestdoesn't fire when a PR's head branch is updated by merging another PR into it, so a stacked release branch can reachmainhaving never run acceptance.workflow_dispatchis the remedy, with the catch that GitHub reads the workflow definition from the dispatched ref — so a branch cut before that block landed has to be rebased first. The file now says all of this. It was the "skipped" case the section tells you to flag, with no action attached.I added one sentence the review didn't ask for: dispatch it on its own.
test/acceptance/README.md§ Rate limits warns that a push also triggers thepull_requestrun, and two concurrent runs exhaust the API rate limit and fail at the timeout with zero assertion failures. Advising a dispatch without that produces exactly that confusing failure.4. Broken cross-reference fixed. The
go test ./...exclusion was cited asAGENTS.md§ Acceptance tests. No such heading exists — it's atAGENTS.md:291, under § Runninggo testafter code changes. Corrected. I then re-checked all seven citations in the file by grepping the headings:AGENTS.md§ Acceptance tests and feature tags, § Command help text, § Cobra Example and output for website docs, andtest/acceptance/README.md§ Running Tests, § Parallelisation, § Rate limits all resolve.Third review round: two findings, both addressed
A review of
2340843confirmed every claim in the file against the tree and returned two. Both are indcf4a7c, a follow-up commit rather than an amend, so2340843..dcf4a7cis exactly this round. (The task asked for an amend; the force-push was blocked by a tooling guard, and a separate commit keeps the reviewed commit readable anyway.)1. "All five agree today, on 21 distinct tags" was wrong, and wrong in the direction that manufactures a false finding.
telemetryis registered separately from the slice lists, so four of the five carry 20:SLICE0/1/2_TAGSinrun_parallel.sh(telemetry is inrun_telemetry()),matrix.includeinacceptance.yml(telemetry is its ownacceptance-telemetryjob), the three per-slice README commands (there is a fourth,-tags=telemetry), and theSlice N featuresbullets (the fourth job is described separately at README:63). Only the "Run all automated tests" string carries all 21 in one list. A reviewer doing what the section told them to do would openrun_parallel.sh, count 20, and report drift that is not there — the same failure themanualexception was added to prevent, one subsection earlier. The file now says so explicitly, and points a telemetry-tagged addition at the three separate sites instead.The review scoped this to three of the five; it is four. The
Slice N featuresbullets carry 12 + 2 + 6 = 20 as well.2. The required-check list had no source in the tree. It is correct today and it is the one claim in the file that lives in GitHub's branch-protection settings rather than in a file, so it rots without a commit — in the section most likely to be trusted. It now carries the query to re-read it:
Run just now:
["unit-test","build-linux","build-mac","build-windows"]— unchanged.Fourth review round: three findings, all addressed
A review of
dcf4a7creturned three, one substantive. All are inb2b2ed6, sodcf4a7c..b2b2ed6is exactly this round.1. The
CLITelemetryclaim was false — the one kind of error this file can least afford. The section said a renamed JSON tag "compiles, passes unit tests, passes acceptance, and silently empties the dashboards". It does not.pkg/hookdeck/telemetry_test.gomarshals the struct into amap[string]interface{}and asserts the tags by literal key name; neither test carries a build tag or atesting.Short()guard, and.github/workflows/test.ymlrunsgo test -short ./pkg/..., so both run under the requiredunit-testcheck. Seven of the eight renames turn a required check red:source,environment,command_path,invocation_id,device_name,mcp_clientTestTelemetryJSONSerializationunit-test(required)generated_resourceTestTelemetryJSONWithGeneratedResourceunit-test(required)command_flagstest/acceptance/telemetry_test.goacceptance-telemetryThe review attributed seven tags to
TestTelemetryJSONSerialization; it is six. Thegenerated_resourcecheck in that test asserts absence (the field isomitemptyand false there), so a rename still passes it — the positive assertion lives inTestTelemetryJSONWithGeneratedResource. Same conclusion, different test; the file names both.The wire-contract point survives, and the trap is sharper than the original: the obvious way to get the build green again is to update the expected key in the test, which restores the signal while the dashboards built on the old name stay empty. The file now says to flag a diff that edits
telemetry.goand its expected key names together.2. "Three surfaces ... have no test or CI job guarding them" was two. Follows from the above.
REFERENCE.mdand the website generator are genuinely unguarded (grep -rn generate-reference .github/→ no hits); telemetry is guarded, and the guard is what makes it dangerous. The premise says so now.3. The credential rule was attributed too broadly. The file said
acceptance.ymlis why "the test credentials" must belong to a test-only account. The comment there is scoped toHOOKDECK_CLI_TESTING_CLI_KEY, and its reason — "reaches every org its owner belongs to" — is a property of that account-wide key, not of the per-sliceHOOKDECK_CLI_TESTING_API_KEY*secrets, which are project-scoped. Scoped to the account-wide key, with the world-readable log kept as the part that applies to all of them.Also in this round: the line count above was stale (236 → 268), and the telemetry and credentials bullets below repeated the two corrected claims.
Fifth review round: three findings, all addressed
A review of
b2b2ed6returned three, one substantive. All are indfc13fe, sob2b2ed6..dfc13feis exactly this round.1.
command_flagsis not pinned in CI — round four's correction was itself wrong. Round four replaced a false claim ("a rename silently empties the dashboards") with a narrower false one: thatcommand_flagsis "pinned only by the acceptance telemetry job". The assertion exists; it never runs.TestTelemetryLoginCommandFlagsProxyskips unlessHOOKDECK_CLI_TESTING_CLI_KEYis set (test/acceptance/telemetry_test.go:84-87), and theacceptance-telemetryjob'senv:block suppliesACCEPTANCE_SLICE,HOOKDECK_CLI_TESTING_API_KEYandHOOKDECK_CLI_TELEMETRY_DISABLED— not that key (acceptance.yml:54-60). The matrix slices do set it (acceptance.yml:37) but do not build-tags=telemetry. Confirmed in this PR's own green run onb2b2ed6, job106696045003:So for that one tag, the scenario round four deleted as false is the truth: renaming it goes green and empties the dashboard.
I did not take the suggested sentence. The review offered a replacement that keeps the per-tag breakdown ("seven of the eight are caught that way; the eighth ..."). Three of the last four rounds' findings came out of that one enumeration, and it has now been wrong twice — the shape of the error is a coverage claim verified one level short of what it asserts, and a more precise enumeration gives it more places to be wrong. So the section now states the rule and hands over the command that re-derives it for whichever tag is in the diff, modelled on how the branch-protection section already handles a fact that rots:
No hit means nothing guards it; hits only under
test/acceptance/mean go and check whether that test runs.command_flagsstays in as the worked example, flagged as a thing to re-derive rather than to trust. Re-run just now:command_flags→test/acceptance/telemetry_test.goonly; the other seven tags →pkg/hookdeck/telemetry_test.go, all as positiverequire.Equalassertions on literal keys (telemetry_test.go:121-125,148-150,278).2. A green acceptance job is not a run. The headline section stopped at job colour, and finding 1 is a third failure mode it could not see: a green job whose tests skipped themselves for a missing credential. New subsection A green acceptance job is not a run, with the three gates between an assertion existing and a red check — the file's build tag being in a slice list or the telemetry job's
-tags, the test's owntesting.Short()/ missing-envt.Skipguards, and the job'senv:block — plus the log grep. Onb2b2ed6,acceptance-telemetrywas green at 62 pass / 8 skip; slice 0 was 207 pass / 0 skip.3. The "a third is guarded" premise inherited the defect. It now reads "guarded only in part", which is what the section below it says.
Not a finding, but someone should fix it:
acceptance-telemetrynot settingHOOKDECK_CLI_TESTING_CLI_KEYis a repo gap, not a PR gap —TestTelemetryLoginProxyandTestTelemetryLoginCommandFlagsProxyhave never run in CI. One line in that job'senv:, mirroringacceptance.yml:37. Out of scope for a docs PR, so it is filed separately as #422.What the file covers
main/nextwith no path filter, but is not a required check — branch protection requires exactlyunit-test,build-linux,build-mac,build-windows— so a red or skipped run merges silently, and then fails at the next release tag, becauserelease.ymlgates its builds on the same acceptance workflow. Readgh pr checks; nothing else will.telemetryregistered separately in the same files and only the README "Run all" string carrying all 21 — plus//go:build manualas a deliberate exception that a literal reading would report as drift.REFERENCE.mdis generated,--checkexits 1 when stale, and no CI job runs it. Hand-edits insideGENERATEblocks are destroyed on the next regeneration.HOOKDECK_CLI_TESTING_CLI_KEYis why the test account must not be a person's. The concrete edge: the CLI writes single-quoted TOML, so a redaction regex written againstapi_key = "..."— as thepkg/config/testdatafixtures are — leaks the key verbatim.CLITelemetryJSON tags are a wire contract. Whether a rename goes red depends on the tag — most are pinned by literal key inpkg/hookdeck/telemetry_test.gounder the requiredunit-testcheck, butcommand_flagsis asserted only by an acceptance test that CI never runs. The file gives the grep that settles it for a given tag rather than a breakdown to trust, and names the trap either way: fixing a red check by editing the expected key restores the signal and leaves the analytics built on the old name empty.Annotations["cli.arguments"]for positional args.KNOWN_ISSUES.mdmoves with behaviour fixes.CHANGELOG.mdentries, the machine-writtenpackage.jsonversion, and unenforced style.Deviations I'm keeping, unless told otherwise
build-*declareneeds: [acceptance],publish-npmneeds those builds) rather than as a directneeds: [acceptance]onpublish-npm, because that's whatrelease.ymlactually says.Verification
Re-run in this worktree on
dfc13fe:go build ./...— clean, exit 0go vet ./...— clean, exit 0go test ./...— 17 packagesok, no failuresgo run ./tools/generate-reference --check—REFERENCE.md is up to date, exit 0golangci-lint runreports 116 pre-existing issues (50 errcheck, 29 staticcheck, 29 unused, 7 govet, 1 ineffassign), all in Go files this branch does not touch —git diff origin/main --statis one Markdown file plus one line inAGENTS.md.gofmt -lnot re-run, same reason.No tests added, and none apply — the change is documentation. The file's claims are what is under test, and round five's were re-derived from the tree rather than from the review write-up: the skip guard at
test/acceptance/telemetry_test.go:84-87, theenv:block atacceptance.yml:54-60,grep -rn command_flags --include='*.go'(two hits: that test andtelemetry.go:38), each of the eight JSON tags grepped separately against*_test.go, andpkg/hookdeck/telemetry_test.goconfirmed to carry no build tag and notesting.Short()againstgo test -short ./pkg/...intest.yml:32.CI on
b2b2ed6— the previous round's run, now finished green. 12 checks pass, read per the file's own new advice rather than at job-colour level:acceptance / acceptance (0, ...)pass, 7m56s, 207 pass / 0 skip — the slice the file calls out as carrying 12 tags against a 12m timeout. 8m34s ondcf4a7c, 7m35s on2340843; roughly four minutes of margin, on a branch that changes no Go code.acceptance / acceptance (1, request event)pass, 4m51sacceptance / acceptance (2, ...)pass, 3m35sacceptance / acceptance-telemetrypass, 3m2s — 62 pass / 8 skip, two of them the login tests that wantHOOKDECK_CLI_TESTING_CLI_KEY. This is the green-is-not-a-run case, on this pull request.unit-test,build-linux,build-mac,build-windows,govulncheck,test-npm-build,test-homebrew-build— all pass[code]smithandcheck-dependabotreportskipping; neither is an acceptance job and neither is required.CI on
dfc13fehas not been read yet — it changes one Markdown file and no Go code, but per the section above, read it before merge rather than assuming.Still worth challenging
Drafted from reading the repo, not from having maintained it. The judgement calls are the part to push on — particularly whether the slice-balance advice matches how you actually allocate tags, and whether the what-not-to-raise list is missing anything that wastes reviewer time today.
The five-list tag registration is arguably a finding about the repo rather than about review: if those lists were generated from one source, the section would shrink to a sentence. I didn't do that here — it's a change to the test tooling, not to a review skill.
Draft until someone who knows the CLI has read it.