Skip to content

Promote Develop: Resync-Filed Model Tiers, Handoff Lifecycle, Hub-Only Tests, and Copilot Transient Fixes - #3544

Merged
ptr727 merged 5 commits into
mainfrom
develop
Oct 28, 2026
Merged

ptr727 merged 5 commits into
mainfrom
develop

Conversation

@ptr727

@ptr727 ptr727 commented Oct 28, 2026 •

Copy link
Copy Markdown
Owner

Summary

Promotes develop to main, carrying round 1 of the resync-issue burndown:

Fixes #3529
Fixes #3504
Fixes #3528
Fixes #3510

🤖 Generated with Claude Code

ptr727 and others added 4 commits October 27, 2026 16:14
… 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>
Copilot AI lite review requested due to automatic review settings October 28, 2026 00:16
@coderabbitai

coderabbitai Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 68.51852% with 34 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.50%. Comparing base (d74cf30) to head (e1c3a01).
⚠️ Report is 432 commits behind head on main.

Files with missing lines Patch % Lines
spec/validate.py 0.00% 33 Missing ⚠️
spec/audit.py 88.88% 1 Missing ⚠️
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     
Flag Coverage Δ
python-3.13 81.50% <68.51%> (-0.09%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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 repoOwnedTrees support 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

Comment thread spec/validate.py
## 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>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 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

@ptr727

ptr727 commented Oct 28, 2026

Copy link
Copy Markdown
Owner Author

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 develop at e1c3a018, read-only.

  • Positive case, ptr727/HomeAutomation-Config#1430. Its refusal at 2026-10-26T19:22:25Z on 1e7291a3 is the failure Tell a Transient Copilot Fetch Error From the Quota Body Before Advising No Re-Request #3510 describes. Calling run_cause live with that commit and time finds failed Copilot run 40386072573 through the Actions REST API. It reads the job log and returns no error type, no rate-limit sentence, and the line HttpError: The request could not be processed because too many files changed. So transient_error gives that line, and the refusal reads as transient, not quota.
  • Fallback case, Promote the Env and Secret File Naming Rule to Main #3507. Its refusal at 2026-10-26T18:51:36Z has no failed Copilot run at or before it. The only Copilot run on that head succeeded at 18:21Z, and its log has no such line. run_cause returns None, and pr_review.py status 3507 prints RUN LOG READING: possible quota. The run log was unread or names neither a rate limit nor a transient fetch failure. That is the conservative reading the change keeps.
  • GraphQL reads. status ran cleanly against both live pull requests. The request-ordering state (owed, pending, sent, spent) is not exercised live, because neither refusal is still a pull request's newest review. The unit tests in tests/test_pr_review.py cover each state against constructed timelines.

Outcome: verified, no change needed.

@ptr727
ptr727 merged commit 65adbf1 into main Oct 28, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants