Repository navigation
Conversation
… Runs At (#3538) ## Summary `AGENTS.md` "Model Tiers" gave two answers for a dispatch that names no model. The `highest` bullet states the conditional form: the agent definition's model where one is set, otherwise the session's own. Two later bullets stated only the session fallback. - The "A tier resolves only through this table" bullet loses its trailing clause. It now says only that such a session names no model. - The "An orchestrating seat" bullet loses its restating sentence. Its rationale, "a choice nobody made", is false where an agent definition pins a model. The `highest` bullet stays the single statement of the result. `scripts/build_dist.py` regenerated the include regions in `backlog-burndown`, `local-strict-review`, and `unattended-handoff`, plus their generated copies. ## Pre-existing findings, filed - `AGENTS.md` "Model Tiers", the paragraph under the tier table, and the `spec/model-tiers.json` note: an unconditional "session's own model" claim for a tool with no row. Class `pre-existing`, filed as #3537, since the two change together and the spec file is outside this change. Closes on promotion: #3529 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…ifecycle (#3539) ## Summary `GOVERNANCE.md` "Durable Knowledge and Self-Improvement" described the old per-link handoff lifecycle in two bullets. This brings both onto the standing-issue lifecycle that `AGENTS.md` "Session Scope" and the `session-handoff` skill state. - The blocker bullet said a handoff "closes with its successor". It now says the next round replaces the handoff's body in place, which is why a wait belongs in the backlog instead. - The `blocked` bullet said the label comes off "when a session hands the link back to be worked". It now comes off once a session writes the next round, matching `session-handoff`'s resume step 6. - The `agent-conduct` include region and its generated copies are regenerated with `scripts/build_dist.py`. ## Dropped findings - `GOVERNANCE.md:20` (and line 103 of the three `agent-conduct` copies), `style`: five untouched sentences in the blocker bullet exceed 25 words. The diff-mode sentence-length check reads the whole changed line. A later sentence-length round owns them. Closes on promotion: #3504 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
## Summary `spec/audit.py` reported a carrier's own `tests/<name>.py` as `hub-only:` whenever the hub has a test module of the same name. Its remedy then suggested deleting the file. The hub's `tests/` tree is never carried, so such a hit is always a path collision. This closes the class rather than adding one `gaps` entry per instance. - `spec/files.json` gains a `repoOwnedTrees` declaration, listing `tests` with its reason. - `spec/files.schema.json` describes the new array. - `hub_only_paths` drops every hub path below a declared repo-owned tree. Both of its consumers inherit this: the audit's hub-only check and the fidelity-honesty manifest gap pass. - A new `hub_paths_below` helper holds the declared-source walk, shared by both `hub_only_paths` loops and `check_tree_verbatim`. - `AUDIT.md`'s carried-scope bullet, the `carried.hubonly.absent` assertion in `spec/project-types.json`, and `RESYNC.md` section 4 each name the exclusion. - `spec/validate.py` checks the `repoOwnedTrees` shape beside its `trees` checks. It refuses a missing source or reason, a source at or above the repository root or not in normalized form, a source with a symlinked component, and a source that is not a directory. - `tests/test_audit.py` adds a case where a carrier's `tests/test_a.py` shares a constructed hub test's name and is not reported. A control shows a hub-only path outside `tests/` is still reported. Its fixture loads the shipped declaration, so a malformed entry or a dropped `tests` fails the suite. - `tests/test_spec_validate.py` adds `RepoOwnedTreeGateCase`, running the real gate against a scratch tree for each refusal and a plain entry. It shares a new `run_gate_on_files` runner with `TreePathGateCase`. ## Verification - The full unittest suite passes under the OPERATIONS.md invocation. - With the `tests` declaration renamed, both new audit cases fail. - `ruff check`, `ruff format --check`, `mypy`, `spec/validate.py`, and `scripts/prose_lint.py --diff origin/develop` are clean. ## Pre-existing findings, not filed - `AUDIT.md:88`, `pre-existing`: `prose_lint.py --check sentence-length` flags three sentences of 36, 53, and 35 words in the carried-scope bullet. This change added one 25-word sentence there and wrote none of the three. - `RESYNC.md:92`, `pre-existing`: the same check flags a 41-word sentence in section 4. This change added a shorter sentence before it. - `AUDIT.md:88`, `RESYNC.md:92`, `spec/project-types.json:161`, `pre-existing`: each derivation names the baseline and now the repo-owned exclusion, but not the carried `trees` exclusion `hub_only_paths` has always applied. ## Dropped findings - `scripts/canonical_review.py:303`, consolidation on text this change did not touch: its tree walk could reuse `hub_paths_below`. Closes on promotion: #3528 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
## What `pr_review.py` read every Copilot error refusal as a possible quota hit, so `wait` stopped and handed the drive to the maintainer. The same body is posted for a transient fetch failure that one re-request clears. `wait` and `status` now read the reviewer's run log for a `too many files changed` line before taking the quota reading. - `run_cause` also returns the log's transient-failure line, beside the error type and rate-limit sentence it already read. A logged rate limit still wins. - One primitive, `transient_state`, says where an error refusal stands on its one re-request: `owed`, `pending`, `sent`, or `spent`. `wait`'s request, its exit, and the digest line all read it. - `wait` sends the one re-request while the state is `owed`. A request made after the refusal spends it, so a request that vanished is not sent again. Two error refusals in a row spend it too. - A pending re-request polls until the next round lands, then exits on that round. With no round by the timeout it exits `30`, `status=PENDING`. - A held head, into a branch other than the default, exits `41` as `COPILOT_ERROR_TRANSIENT`, naming `--request` as what sends the re-request. Elsewhere an owed refusal steps aside, so an unrecorded request, an outside answer, or the repo-wide quota keeps its own status. - A spent or sent-and-unanswered re-request, an unread log, or a log naming neither cause keeps `COPILOT_ERROR_POSSIBLE_QUOTA`. Its status line now says which reading was taken. - `status` prints a `RUN LOG READING` line under an `ERROR` refusal, naming the reading taken. No exit code is added. The transient state rides the existing `0`, `30`, `40`, and `41` outcomes and their status lines. The help text, `scripts/README.md`, and `pr-review-conduct` describe the transient exception. The skill's generated copies are regenerated. `drive-pr` carries no changed section, so its copies are unchanged. ## Tests `tests/test_pr_review.py` covers the reading with constructed run logs and request histories: the transient line parsed with and without an error type, a rate limit outranking it, one re-request reviewed normally on the current head and on an earlier one, a second refusal ending the poll as quota, two refusals in a row, a pending re-request at the timeout, a re-request already sent, an unrecorded re-request, a second wait on a pending re-request, a held head, an unread log, and the digest's readings. ## Local strict review findings The first push left two `introduced` findings open once its edit budget was spent. Both are fixed in dc2bbe5, and that push's pass raised none. - `scripts/README.md:225`, `introduced`, fixed: it said `wait` exits `41` as `COPILOT_ERROR_TRANSIENT` wherever it sent none, while only a held head reaches that exit. - `scripts/pr_review.py` `transient_state`, `introduced`, fixed: the digest and the exit each read the request history. The read is now kept on the payload, so they share one answer. ## Filed elsewhere - #3541: the digest's fixed `COPILOT REFUSED THIS ROUND` text says "re-requesting repeats it", which a transient refusal contradicts, and the `RUN LOG READING` line belongs inside that block. Both need `scripts/pr_review_digest.py`, outside this change's files. Closes on promotion: #3510 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars.
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3544 +/- ##
==========================================
- Coverage 81.58% 81.50% -0.09%
==========================================
Files 26 26
Lines 8972 9065 +93
==========================================
+ Hits 7320 7388 +68
- Misses 1652 1677 +25
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
🟡 Changes recommended
A critical active finding remains because repo-owned sources can overlap carried declarations, allowing contradictory paths to suppress hub-only findings without test coverage for the conflict.
1 open issue
What changed in this PR
This pull request promotes develop to main, synchronizing governance guidance, generated skills, repository-owned audit paths, and transient Copilot review handling.
Changes:
- Aligns model-tier dispatch and handoff lifecycle guidance across canonical and generated instruction files.
- Adds
repoOwnedTreessupport to manifests, schemas, validation, auditing, documentation, and tests. - Adds Copilot run-log classification and one bounded re-request for transient failures.
- Review findings remain for broad transient-error matching, capped review-history detection, and missing ownership-overlap validation.
| File | Description |
|---|---|
tests/test_spec_validate.py |
Adds validation coverage for repository-owned tree declarations. |
tests/test_pr_review.py |
Tests transient Copilot failure detection, retry state, quota handling, and status output. |
tests/test_audit.py |
Verifies repository-owned test paths are excluded from hub-only findings. |
spec/validate.py |
Validates repoOwnedTrees declarations. |
spec/project-types.json |
Documents the repository-owned tree exclusion. |
spec/files.schema.json |
Defines the repoOwnedTrees schema. |
spec/files.json |
Declares the tests tree as repository-owned. |
spec/audit.py |
Applies repository-owned exclusions to hub-only auditing. |
scripts/README.md |
Documents transient Copilot refusal handling. |
scripts/pr_review.py |
Reads run logs and manages one transient re-request. |
RESYNC.md |
Documents repository-owned paths in resync guidance. |
GOVERNANCE.md |
Aligns blocker and handoff lifecycle guidance. |
AUDIT.md |
Documents repository-owned tree audit behavior. |
AGENTS.md |
Removes contradictory model-tier dispatch claims. |
.github/skills/unattended-handoff/SKILL.md |
Regenerated model-tier guidance. |
.github/skills/pr-review-conduct/SKILL.md |
Documents transient Copilot refusal handling. |
.github/skills/local-strict-review/SKILL.md |
Regenerated model-tier guidance. |
.github/skills/backlog-burndown/SKILL.md |
Regenerated model-tier guidance. |
.github/skills/agent-conduct/SKILL.md |
Regenerated handoff lifecycle guidance. |
.claude-plugin/fleet-skills/skills/unattended-handoff/SKILL.md |
Regenerated plugin skill distribution. |
.claude-plugin/fleet-skills/skills/pr-review-conduct/SKILL.md |
Regenerated plugin review guidance. |
.claude-plugin/fleet-skills/skills/local-strict-review/SKILL.md |
Regenerated plugin skill distribution. |
.claude-plugin/fleet-skills/skills/backlog-burndown/SKILL.md |
Regenerated plugin skill distribution. |
.claude-plugin/fleet-skills/skills/agent-conduct/SKILL.md |
Regenerated plugin handoff guidance. |
.claude-plugin/fleet-skills/.source-digests/unattended-handoff |
Updates the generated skill digest. |
.claude-plugin/fleet-skills/.source-digests/pr-review-conduct |
Updates the generated skill digest. |
.claude-plugin/fleet-skills/.source-digests/local-strict-review |
Updates the generated skill digest. |
.claude-plugin/fleet-skills/.source-digests/backlog-burndown |
Updates the generated skill digest. |
.claude-plugin/fleet-skills/.source-digests/agent-conduct |
Updates the generated skill digest. |
.agents/skills/unattended-handoff/SKILL.md |
Updates the canonical model-tier guidance. |
.agents/skills/pr-review-conduct/SKILL.md |
Updates the canonical Copilot review guidance. |
.agents/skills/local-strict-review/SKILL.md |
Updates the canonical model-tier guidance. |
.agents/skills/backlog-burndown/SKILL.md |
Updates the canonical model-tier guidance. |
.agents/skills/agent-conduct/SKILL.md |
Updates the canonical handoff lifecycle guidance. |
Review effort: Lite
## Summary This is a promotion fix for review thread `PRRT_kwDOQ5caqM6w8BW3` on #3544. `spec/validate.py` now refuses a `repoOwnedTrees` source that overlaps carried content. The audit skips every hub file below a repo-owned source. An overlap would therefore hide hub-only findings while the manifest still claims the content is carried. The check refuses three shapes: - a source equal to a `trees[].source` - a source that is an ancestor or a descendant of a `trees[].source` - a source with a `baseline` path at or below it `RepoOwnedTreeGateCase` runs the real gate on a scratch tree for each refused shape, plus a control beside the carried content. The fixture paths are constructed. The shipped `spec/files.json` still passes. ## Local review The pass raised one finding, declined on evidence. - `spec/validate.py`, the new tree-source comparison, `introduced`, design. The reviewer asked for one `paths_overlap` helper shared with the tree-target loop. Declined: no such helper exists to reuse, and the repeated expression is correct rather than a defect class. Moving the tree-target site is outside this change's claim, which is the `repoOwnedTrees` check only. Closes on promotion: #3528 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🔵 Needs a closer look
The transient Copilot retry and review-gate changes depend on live GitHub Actions logs and GraphQL event ordering that mocked tests cannot fully validate, so real-run verification is needed before approval.
No open issues 🎉
1 resolved since last review
Review effort: Lite
|
Answering the round's headline, "real-run verification is needed before approval", for the transient Copilot retry (#3542). I verified it against live runs from
Outcome: verified, no change needed. |

Summary
Promotes
developtomain, carrying round 1 of the resync-issue burndown:AGENTS.md"Model Tiers" now states the no-model dispatch result once, conditionally, in thehighestbullet. The two bullets that contradicted it lost their unconditional claims. The three skills including the section are regenerated.GOVERNANCE.md"Durable Knowledge and Self-Improvement" describes the standing-issue handoff lifecycle, matchingAGENTS.md"Session Scope".agent-conductis regenerated.spec/files.jsongains arepoOwnedTreeslist declaringtests, andspec/audit.pyhub_only_pathsleaves those paths out. A carrier's owntests/file is no longer reported as hub-only.spec/validate.pyshape-checks the list, andAUDIT.md,RESYNC.mdand the project-types assertion state the exclusion.pr_review.py waitandstatusread the Copilot run log before calling an error refusal quota. Atoo many files changedline is transient and earns one re-request, asCOPILOT_ERROR_TRANSIENTon the existing exit 41.spec/validate.pyrefuses arepoOwnedTreessource that overlaps a carriedtrees[].sourceor holds abaselinepath.Fixes #3529
Fixes #3504
Fixes #3528
Fixes #3510
🤖 Generated with Claude Code