docs(agents): post review passes as formal PR reviews #185
No reviewers
Labels
No labels
blocked
bug
enhancement
high-priority
low-priority
needs-info
needs-triage
ready-for-agent
ready-for-human
referenced
research
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gabogg/hikcentral!185
Loading…
Reference in a new issue
No description provided.
Delete branch "docs/formal-pr-reviews"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Agents currently work PR reviews and merges from hand-typed
tea apicommands, which costs tokens every time. They re-read the command docs, retype the commands, and retry when escaping goes wrong. They also read every PR comment (tea pr N --comments) to find the review pass they must address. This PR makes review passes formal PR reviews with a fixed header line and adds scripts for the mechanical steps:scripts/wt review(backed by thescripts/review.pymodule)post <N> <file>posts a pass as a formalCOMMENTreview and rejects a file whose first line is not## Code review, pass <N> (<base>...<reviewed SHA>, ...)with a readable reviewed SHA.list <N>prints each pass with its reviewed SHA and the ref of its fix reply (## Pass <N> fixes (<SHA>)posted after it), then names the latest pass.show <N> [<ref>]prints only the body of the latest pass, or of the one you pick.## Code review, pass <N> (header, such as PR #176's. Passes with other wordings (#175's first pass, and #173's and #166's passes) are not listed; those PRs are merged, so nothing needs migrating.scripts/wt merge <N>rejects malformedWT_CI_*settings (whole seconds only), refuses a closed, draft or not-yet-mergeable PR, then waits for the head commit's CI:WT_CI_START_GRACE), it fails.<PR title> (#N)merge-commit title, pinned to the commit CI passed on, and deletes the branch. If Forgejo refuses, it prints the reason; the PR's state, not the request's exit code, decides whether it merged. It then runswt pruneand fast-forwards the main checkout'smaster./actions/runs?head_sha=, then/runs/{id}/jobs, then/jobs/{id}/logs. The web UI's raw-log URL returns 404 on v16.tea actions runs logsstill fails on v16, because Forgejo returns the jobs as a plain list whereteaexpects Gitea's{total_count, jobs}object.Architectural impact
Agent tooling and docs only; no application code changes.
docs/standards/git-and-workflow.md: review passes are formal reviews with the fixed header line, posted and read throughscripts/wt review. The reply that maps findings to fixes stays a plain comment. Branch cleanup points atwt merge.docs/agents/forgejo-cli.md: the Review passes and Merging sections are now short pointers to the scripts, replacing the long command recipes.docs/agents/workspaces.md: listswt merge.code-reviewskill (mattpocock/skills, hash-pinned inskills-lock.json) is unchanged.Verification
tests/test_review_script.pycovers header and reviewed-SHA parsing, fix replies tied to their pass (including comments in the same second), merging formal reviews with plain-comment passes, ordering, and helper shadowing.tests/test_wt_api.pycovers checked API reads.tests/test_wt_merge.pydrives thewt mergegate end to end against a faketea: malformed timing settings, draft refusal, failed CI log tail, no Actions run, refused merge, and a merge that succeeded despite a failed request. Pre-commit hooks passed, including the full pytest suite, ruff andcheck_docs.py.scripts/wt review, tested on live PRs:list/show 176found the plain-comment passc3198.postrejected a body without the header, posted a body with backticks, quotes and non-ASCII characters asr5, andlistandshowread it back. I deleted the test review afterwards.APPROVED("approve your own pull is not allowed") andREQUEST_CHANGES("reject your own pull is not allowed") from the PR author, so reviews are posted asCOMMENT.wt mergerefused a draft (#185), a closed PR (#175) and a non-numeric argument.821cf66(failed run 278, whose job timed out and was cancelled) printed 60 log lines plus the full-log path, then stopped.Checklist
scripts/wt review,scripts/wt merge, docs.cdae9a0). First-pass fixes at3cb802band0773d27, and maintainer-requestedwt reviewat8a84119: full pytest suite and pre-commit hooks passed; Ruff and docs checks passed.90ebb94; third pass (r8) fixed in7950c10, every finding including P3s.00a07a6.dc646c4.scripts/wt merge 185.🤖 Generated with Claude Code
WIP: docs(agents): post review passes as formal PR reviewsto chore(agents): script review passes and PR mergesCode review, pass 1 (
origin/master...cdae9a0, spec: maintainer requests of 2026-09-29, no issue)Result: no P1s, 4 P2s (2 Standards, 2 Spec) and 19 P3s (12 Standards, 7 Spec). This is the first pass, so every finding gets fixed on the branch.
Verification: ruff clean,
bash -n scripts/wtOK, the 3 tests intests/test_review_script.pypass, both scripts tracked as 100755. Checked read-only on the live server:review.py list/show 176,list 185, andci_gateon the failed commit821cf66(60 log lines plus the full-log path).One fact underlies several findings:
tea apiexits 0 on HTTP errors. A missing PR returns{"message":…,"errors":[]}with exit code 0.The spec is the maintainer's requests from the working session, quoted word for word; this PR has no issue.
Standards
P2
cmd_mergehides Forgejo's error (scripts/wt:310). The merge POST's output goes to>/dev/null, so ahead_commit_idmismatch or "try again later" shows up only as the generic "did not merge" (wt:313). Capture the body and print itsmessage, asreview.pytea_apidoes.ci_gatemistakes errors for "not reported yet" (scripts/wt:250-253). An API error body has nostatuses, so it maps tonone. A bad sha or auth failure then waits the full 30 minutes. Treat a body with anerrorskey as fatal.P3
3. Duplicated Code (judgement).
wthas five inlinepython3 -cJSON snippets, and none checks for an error body asreview.py:76does. Extract one helper, e.g.api_json <endpoint> <expr>.4. Silent failures in loops (wt:275-277, 281-284). Under
set -e, errors insidefor run in $(…)and< <(…)are ignored. AKeyError, or finding no runs, prints no logs and still reports "CI failed". Print a note when nothing was found.5. Doc/code mismatch (wt:277 vs forgejo-cli.md:73). Runs are kept only when their status is
failure|error, so the jobs of a cancelled run never print, although the docs say cancelled jobs are shown.6.
warningstate not handled (wt:257). It polls until the timeout.7. Misleading message (wt:305).
mergeable=Falsecan be transient after a push, but the message says "has merge conflicts".8. Draft check (wt:304). Only the
WIP:prefix is recognized;[WIP]is missed.9.
tea_apitracebacks (review.py:72-75). When tea is missing, not logged in, or returns non-JSON, the user gets a rawCalledProcessError/JSONDecodeErrortraceback instead of areview:message.10. Exit style (review.py:96/131).
mainreturnsNoneand callssys.exit(__doc__), so-hexits 1. The siblingcheck_docs.pyreturnsintand ends withraise SystemExit(main()).11. Unchecked comment refs (review.py:91-92). A
c<id>ref isn't checked against PR N, soshow 42 c<another PR's comment>succeeds.12. Pending reviews crash (review.py:52).
r["submitted_at"][:16]raises aTypeErrorfor a pending review whosesubmitted_atis null.13. Test coverage (tests/test_review_script.py). Only the pure functions are covered: not argv validation, bad refs, the header check on
post, ortea_apierrors. A monkeypatchedtea_apiwould testmainoffline (AGENTS.md §3: mock external endpoints).14. Version trivia (forgejo-cli.md:73). Why
tea actions runs logsfails could go stale. Move it to a footnote.Note: no hard violations of documented standards. The three docs agree on
wt merge, prune and running from the main checkout.Spec
P2
16. (a)
listcan't tell whether the latest pass has been addressed. Spec: "so you know how to pick the exact last review that needs to be addressed".entries()(review.py:46-63) drops fix replies. On #176,listshowslatest pass: c3229with nothing to indicate whether a reply answered it. The docs say to compare the "reviewed commit" with the head (forgejo-cli.md:61), but:- plain-comment passes print
-as their commit (review.py:59);- a formal review's
commit_idis the head at posting time, not necessarily the SHA that was reviewed.ci.ymlonly triggers onpull_request: branches: [master], so a PR based on another branch never gets a status, yetci_gatetreatsnoneas running (wt ~250-262). Fail fast when no Actions run exists for the SHA, or document the limit.P3
18. (a) The script still downloads every comment. Spec: "instead of getting all the comments you get the reviews".
fetch_entriesdownloads every PR comment's full body on eachlist/show(review.py:83). What the agent reads is small, but the network fetch isn't.19. (c)
warningstate spins until the timeout (the same issue as #6).20. (c) A fully cancelled run prints no log (the same root cause as #5). The gate dies with no log.
21. (c) A refused merge hides the reason (the same issue as #1).
22. (c) A transient
mergeable=falseis reported as "has merge conflicts" (the same issue as #7).23. Stale PR description.
- "Merge after PR #176 finishes its review cycle" is still unchecked.
- "The final merge call runs for the first time when this PR or #176 merges" is wrong now: #176 merged the old way.
24. Stale doc pointer (forgejo-cli.md:35). It still recommends
tea pr 42 --commentsfor reading a PR, which is the full comment dump the spec wanted agents to avoid for reviews. Point PR reviews toreview.py.Checked and OK: failure logs print (60 lines plus the full-log path). Success returns. The merge is pinned with
head_commit_id.mergelives inwt, not a separateprscript. Review completeness is documented as unchecked. Scope creep: none significant.Summary
ci_gatetreats API errors as "not reported yet" and waits 30 minutes.listcan't tell whether the latest pass was already addressed.🤖 Generated with Claude Code
First-pass findings addressed —
3cb802bAll P2 and P3 findings from review r6 are addressed on the PR branch.
wt_api.pycentralizes checked JSON reads for the worktree script. Failed run and job lookup errors stop the gate; empty results print an explicit note.[WIP]are refused, and an unsettledmergeable=falseis reported without asserting a conflict.review.pyreports tea and JSON errors without tracebacks, supports a successful help exit, checks that legacy comment refs belong to the PR, handles pending reviews, and has offline tests for those paths.review.py.listreads the reviewed SHA from each pass header and marks passes with a later fix reply.Verification: 464 tests passed, Ruff lint and format checks passed,
bash -n scripts/wtpassed, andcheck_docs.pypassed. The pre-commit hooks passed on3cb802b. Live reads confirmed PR #185's review listing, PR #176's legacy comment lookup, and Forgejo CI status parsing.Please run the second review pass on
3cb802b.Follow-up to the first-pass fix reply:
0773d27preserves old plain-comment passes when a PR later gains formal reviews, while still limiting comment fetches for PRs that begin with formal pass 1. The new migration test and full pre-commit suite pass. Please run the second review pass on0773d27.Maintainer request: fold the review commands into
wtPlease add this alongside the pass-1 fixes (review
r6). Agents should have one entry point for PR workflow commands,scripts/wt, as withmerge, rather than a second script whose name ends in.py.What to change
scripts/wt reviewwith three subcommands that behave asscripts/review.pydoes today, including every pass-1 fix:scripts/wt review list <N>scripts/wt review show <N> [<ref>]scripts/wt review post <N> <file>wt review …should call the module, e.g.python3 "$ROOT/scripts/review.py" "$@"orpython3 -m scripts.review, so the tests keep importing it (from scripts import review). The module can stay atscripts/review.py. Agents shouldn't need to call it directly.wt review …form:docs/agents/forgejo-cli.md: the Review passes section and the command table.docs/standards/git-and-workflow.md: the review-pass rule.docs/agents/workspaces.md: next towt merge.reviewinscripts/wt --help, and have usage errors mentionwt reviewrather thanreview.py.Acceptance
scripts/wt review list|show|postworks from any worktree, liketea, which infers the repo fromorigin.scripts/review.pydirectly.wt reviewpasses its arguments through, e.g.scripts/wt reviewwith no arguments prints the usage and exits non-zero.🤖 Generated with Claude Code
Implemented the maintainer request in
8a84119.scripts/wt review list|show|postnow forwards to the existing Python module; usage and help namewt review. Updated the CLI, workflow, and worktree docs, with no remaining doc directing agents to runscripts/review.py. Added an argument-forwarding smoke test from a nested directory; a livescripts/wt review list 185read passed. The full pre-commit suite passed. Please review the updated head8a84119in the second pass.Agent instruction clarification pushed at
ea48f68: docs/agents/workspaces.md now spells out all threescripts/wt reviewcommands. The PR already updates docs/agents/forgejo-cli.md and docs/standards/git-and-workflow.md to usewt review; no agent doc directs agents to runscripts/review.py. Documentation check and the full pre-commit suite passed. Please useea48f68for the second pass.chore(agents): script review passes and PR mergesto docs(agents): post review passes as formal PR reviewsCode review, pass 2 (
origin/master...ea48f68, spec: maintainer requests of 2026-09-29, no issue)Result: no P1s, 3 P2s (1 Standards, 2 Spec; Standards 1 and Spec B are the same issue) and 9 P3s (6 Standards, 3 Spec). The maintainer asked that every finding on this pass be fixed on the branch rather than deferred, because all future PRs rely on this tooling.
Verification: 14 tests pass in
tests/test_review_script.pyandtests/test_wt_api.py. Ruff check and format are clean, andbash -n scripts/wtis OK. Read-only live checks:wt review list 185andlist 176work.show 176 c3229works, andshow 185 c3229is refused.showexits 2.wt_api.py pron a missing PR exits 1.wt_api.py statusandruns_anyread correctly.Standards
Pass-1 fixes: 1–2 and 4–14 are fixed. #3 is partial: the merge response is still parsed inline (
scripts/wt:316).P2
scripts/review.py:26vsforgejo-cli.md:60,git-and-workflow.md:42).listmarks a pass as answered only when a later comment matchesFIX_REPLY, which accepts## Fixes,## First-pass findings addressedor## Review fixes. The docs only say "a fix-reply heading", so a reply titled## Pass 1 fixesgoes undetected and the pass looks unanswered.P3
2. Duplicated Code (judgement call).
review.py:103-117andwt_api.py:15-28are two checkedtea apiwrappers that decide what counts as an error differently, so they will drift apart.3. The inline merge-response parse at
wt:316checks onlymessage, noterrors.4. Mysterious Name (judgement call).
api_json(wt:15) returns extracted fields, not JSON.runskind returns only failed runs.showdispatches on a kind-string if-chain.wt mergecan fail right after a push. Thenonebranch (wt:260-264) dies before Forgejo has created the Actions run.>(review.py:78).wt_api.pyhas a shebang but is tracked as 100644, whilereview.pyis 100755.There are no hard violations of
AGENTS.mdorcode-standards.md.Spec
Maintainer
wt reviewcriteria, all 5 met:scripts/review.py.wt --helplistsreview.wt review.Pass-1 fixes: 17–24 are fixed. #16 is partial; both P2s below come from it.
P2
review.py:24). The documented header (git-and-workflow.md:42) has none.## Code review, pass 2 (origin/master...ea48f68, spec #185)returns None, andlistsilently falls back to the posting-timecommit_id.## Second-pass fixesdoesn't match.P3
showprints[ref]before reporting a bad ref.forgejo-cli.md:60explains fetch internals that agents don't need.Summary
🤖 Generated with Claude Code
Pass 2 fixes (
90ebb94)Every finding from review pass 2 is fixed in
90ebb94, P3s included.REVIEWED_SHAaccepts headers with or without backticks, including backticks around each side of the range. There is a parametrized test for each form.git-and-workflow.mdnow fixes the reply's first line as## Pass <N> fixes (<fix short SHA>), andforgejo-cli.mdlinks to that rule.FIX_REPLYaccepts that heading and the older wordings. One of those, #176's real## First review pass addressed, was missed until now;list 176now marks pass 1 as answered. Tests cover the matching and non-matching headings.wt_api.api(endpoint, *args)is the single checkedtea apicall.review.tea_apiwraps it, and the merge POST goes through it (api_fields quiet … -X POST -d), so the inline parse is gone.api_jsonis nowapi_fields.failed_runs,run_countandfailed_jobs.FIELDSmap instead of an if-chain.wt mergegives a new head commitWT_CI_START_GRACE(60s) to get its Actions run before failing.>=). There is a test for both a same-minute reply and an earlier one.wtruns them aspython3 -m scripts.<module>from its own checkout.showreads the body before printing the ref. There is a test for this.forgejo-cli.md.Verification:
review list 185andlist 176.show.wt_apifield.wt merge abc.The maintainer has asked for a third pass on
90ebb94.🤖 Generated with Claude Code
Code review, pass 3 (
origin/master...90ebb94, spec: maintainer requests of 2026-09-29, no issue)Result: no P1s, 3 P2s (1 Standards, 2 Spec) and 8 P3s (5 Standards, 3 Spec); Spec P3-4 repeats Standards P2-1. The maintainer asked for every finding to be fixed, with further passes until only P3s remain.
Standards
Pass-2 fixes: 1–6 are fixed, verified with probes that include a fake
teafor the merge-refusal path. 7 is fixed but caused P2-1.P2
wt's own checkout (scripts/wt:16, a regression in90ebb94).python3 -mputs the cwd ahead ofPYTHONPATH.scripts/is a namespace package, so ascripts/review.pyorscripts/wt_api.pyin the cwd wins.wt review --helprun from a directory holding a decoyscripts/review.pyprintedSHADOWED.wt merge Nrun from inside a PR's worktree uses that PR's unreviewedwt_api.pyas the merge gate.python3 -P -m, and add a test that runs from a directory with a decoyscripts/.P3
FIX_REPLYis too broad and ignores the pass number (review.py:29-32).## Fixes needed before merge,## Review fixes still missingand## Addressedall mark a pass as answered.## Pass 1 fixesposted after pass 2 marks pass 2 answered.wt_api.py:79). An empty body, or a list on a dict-only field, raises an uncaughtAttributeError. A missing key prints only'state'.wt:268-275). During the start grace it says "waiting (up to 1800s)", then dies at 60s.wt:323-324). A tea or network failure prints "Forgejo refused PR #N". If the server merged before tea timed out, prune is skipped.Entry.submittedandEntry.athold the same instant twice, andsubmitted_at or created_atis repeated.quietsits inFIELDSalthough it is a check, not a field.failed_jobsuses an inline set next toNOT_SUCCEEDED.There are no hard violations of
AGENTS.mdorcode-standards.md.Spec
Pass-2 fix claims: all verified, except "helpers run from its own checkout" (see P2-1 above). The 5
wt reviewcriteria still hold.P2
postaccepts headers thatlistcan't read a reviewed SHA from (review.py:174vs:27).…instead of....listthen falls back tocommit_id, which is the posting-time head: for r7 that is90ebb94, not the reviewedea48f68.postrejects a header with no parseable SHA and gives a readable error.listprints only| fix reply posted, without the reply's ref.forgejo-cli.md:35lost--comments, andtea pr 185without it printed 0 comments.list, and restore--commentsin the table.P3
3. A fix reply isn't matched to its pass number (same as Standards P3-1). It also misses
## Pass-3 fixesand## Pass 3 fix reply.4. Helpers run from the wrong checkout (same as Standards P2-1).
5. The PR description is stale.
## Review pass 1: …is not listed, and #173 and #166 show none. All three are merged, so this is harmless, but the claim should be reworded.Also noted (pre-existing): run outside any git repo,
wtignores git's error and setsROOT=/.Live checks:
liston #185, #176, #175, #173, #166, #168 and #169;showwith good refs, bad refs and a missing PR.Summary
postaccepts headers whose reviewed SHAlistcan't read.🤖 Generated with Claude Code
Pass 3 fixes (
7950c10)Every finding from review pass 3 (r8) is fixed in
7950c10, P3s included.wtruns its helpers withpython3 -P -m scripts.<module>. A new test runswt review --helpfrom a git repo that holds a decoyscripts/review.py, and the decoy no longer runs. The pre-existing quirk is fixed too: outside any git checkout,wtnow stops with "run it from inside a checkout" instead of usingROOT=/(tested).postaccepts butlistcan't read):postnow also requires a readable reviewed SHA and names the expected format instead of printing the regex. Tests reject the two-dot range, bare SHA, uppercase SHA and…headers. A livepostof a two-dot header was refused.listnow ends a pass's line withfix reply c<id>, readable withwt review show N c<id>.forgejo-cli.mdrestorestea pr 42 --commentsand notes that non-interactive runs omit comments without it.FIX_REPLYtoo broad, not tied to its pass):## Pass <N> fixes,## Pass-<N> fixesor## Pass <N> fix reply, plus the ordinal wordings used on #176 and #185.## Fixes needed before merge,## Review fixes still missing,## Addressed, and a late## Pass 1 fixesafter pass 2 no longer count. Each is tested.list 185shows r6 → c3239 and r7 → c3334, andlist 176shows c3198 → c3212.wt_apireports "unexpected response (missing 'ref')" or "unexpected response shape" instead of a traceback. Tests cover an empty body, a list, a bad element and a missing key.CI not started …; waiting (up to 60s), and the timeout message names the start grace.mergedstate decides. A merge that happened anyway still prunes.Entrykeeps one timestamp and derives the display date from it.checkis no longer inFIELDS.JOB_PASSED,RUN_NOT_SUCCEEDED).tests/test_wt_merge.pydriveswt mergeend to end against a faketeaon PATH:head_commit_idand title checked;gitinherited the pre-commit hook'sGIT_DIR. Agit initin a test then rewrote the main checkout'score.bare(now restored). An autouse fixture dropsGIT_*variables, and the tests pass withGIT_DIRset.Verification: 51 script tests pass, and pre-commit passed (full pytest suite, ruff, docs check). Live read-only checks covered
list 185andlist 176,show 185 c3334, and a rejectedpost.Please run the fourth pass on
7950c10.🤖 Generated with Claude Code
Code review, pass 4 (
origin/master...7950c10, spec: maintainer requests of 2026-09-29, no issue)Result: no P1s, 1 P2 (Standards) and 6 P3s (4 Standards, 2 Spec). Both axes found the same-second crash: Standards rates it P2, Spec P3. The axes are kept separate, so the Standards P2 stands, and under the maintainer's rule for this PR another pass follows once everything is fixed.
Standards
Pass-3 fixes: P2-1 and P3-1 through P3-5 are all fixed and verified by probes:
set -e;wt_apiexception branches;CI_POLLgreater than the grace;P2
scripts/review.py:116-118: two PR comments in the same second crashlistandshow(a regression in7950c10).repliessorts(datetime, int | None, ref)tuples for every comment, so a timestamp tie comparesNonewithint.## Pass 1 fixesandthanks, both at 11:00:00, raiseTypeError: '<' not supported between instances of 'NoneType' and 'int'.listorshowof that PR then crashes.P3
tests/test_wt_merge.py:143-153: the merged-anyway test doesn't prove that prune runs.wtexits 128 because the temp repo has noorigin, and the test never asserts the return code. Fix: give the temp repo a bareoriginand assertreturncode == 0.scripts/wt:271: a non-numericWT_CI_TIMEOUTorWT_CI_START_GRACE(e.g.3m) makes the gate wait forever, because[ -ge ]errors and counts as false. Fix: validate the three settings as integers.scripts/wt:19: a regularscriptspackage onsys.pathstill shadows the helpers.scripts/is a namespace package, so withPYTHONPATH=<dir with scripts/__init__.py>the decoy runs. Fix: addscripts/__init__.py.(number, Entry)tuples travel together, so the pass number belongs onEntry.HEADERduplicatesPASS_NUMBER._no_git_hook_envis copied into two test files and belongs intests/conftest.py.There are no violations of
AGENTS.md,code-standards.mdorgit-and-workflow.md.Spec
All three maintainer requests and the five
wt reviewcriteria are met, with no scope creep. All pass-3 fix claims were verified. Live:liston #185, #176, #175, #173, #166, #168, #169, #177 and #178 is correct, andshow 176 c3348is refused because that comment belongs to another PR. The docs and code agree on header and reply formats, the three-dot rule, the env defaults (1800/15/60) and the refusal conditions. The filled-in doc header passespost.P3
list 175does show pass 2 (c3186); only #175's first pass is missing.Summary
listandshow.🤖 Generated with Claude Code
Pass 4 fixes (
00a07a6)Every finding from review pass 4 (r9) is fixed in
00a07a6, P3s included.entries()collects only actual fix replies, sorted by timestamp alone, so a timestamp tie can no longer compareNonewithint. A new test puts a plain comment and two fix replies in the same second; the first reply is linked, with no crash.origin. The test asserts exit 0, that the merge happened despite the failed request, and that the main checkout was fast-forwarded, so prune ran.wt mergechecksWT_CI_TIMEOUT,WT_CI_POLLandWT_CI_START_GRACEas whole seconds before any request. It also rejectsWT_CI_POLL=0, which would otherwise loop forever. These are parametrized tests, and none of them calltea.forgejo-cli.mdstates the unit.scripts/__init__.pymakesscriptsa regular package. With-P, wt's own checkout comes first onsys.path, so ascriptspackage elsewhere onPYTHONPATHno longer wins. This is tested with a decoy regular package.Entry.is_review_passderives fromPASS_NUMBER, so the duplicateHEADERregex is gone.GIT_*isolation fixture moved totests/conftest.pyand covers every test.Verification:
GIT_DIRset.list 185andlist 176are unchanged and correct.Please run the fifth pass on
00a07a6.🤖 Generated with Claude Code
Code review, pass 5 (
origin/master...00a07a6, spec: maintainer requests of 2026-09-29, no issue)Result: no P1s, no P2s, 4 P3s (2 Standards, 2 Spec); Spec P3-1 overlaps Standards P3-1. Under the maintainer's rule for this PR, these P3s get fixed and then the PR merges.
Standards
Pass-4 fixes: all verified.
originand asserts that wt exits 0.3m,1.5and0.Regressions: none.
scripts/__init__.pyleavescheck_docs.py, CI, pre-commit,sync-database.py,lint.sh,build-css.shand packaging unaffected.GIT_*fixture breaks nothing; the full suite shows 508 passed.P3
scripts/wt:316-319: the settings check can be bypassed.WT_CI_TIMEOUT="1 2"word-split past the check, which brings back the endless wait.WT_CI_POLL=08passes, then crashes with "value too great for base", and010is read as octal.^(0|[1-9][0-9]{0,8})$, or normalise with10#.scripts/wt:284: the wait countsCI_POLLper loop, not real elapsed time. Slowteacalls stretch the real wait pastWT_CI_TIMEOUT. This predates the PR.There are no documented-standard violations and no new smells. Ruff,
bash -nandcheck_docspass.Spec
Pass-4 fix claims (c3355): all true.
post→list→## Pass 1 fixesreply linked → pass 2 posted, andshowdefaulted to the latest pass.listandshowon #185, #176, #175, #173, #166, #168, #169, #177 and #178 match the PR description, and a cross-PR ref is refused.wt reviewcriteria are met, the docs agree with the code, and there is no scope creep.P3
wt:316-319,284). This is the same issue as Standards P3-1.Summary
🤖 Generated with Claude Code
Pass 5 fixes (
dc646c4)Every finding from review pass 5 (r10) is fixed in
dc646c4. Pass 5 had only P3s, so under the maintainer's rule for this PR it now merges throughscripts/wt merge 185.WT_CI_*item is quoted before the check, and only plain decimals from0to999999999are accepted."1 2",08and a 20-digit value are now rejected before any request, and each case is tested.SECONDS, so slow API calls count towardWT_CI_TIMEOUTand the start grace.Verification:
core.bareis still false.🤖 Generated with Claude Code