Skip to content

Make carry.py's check-sections Refuse What apply-sections Would and Name an Open Fence - #3835

Merged
ptr727 merged 2 commits into
developfrom
burndown/3690-check-sections
Nov 2, 2026
Merged

ptr727 merged 2 commits into
developfrom
burndown/3690-check-sections

Conversation

@ptr727

@ptr727 ptr727 commented Nov 2, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes the three follow-ups #3690 records against scripts/carry.py's section modes.

  1. plan_unit now renders the insertion and the splice in memory, so check-sections meets every refusal apply-sections raises. SectionPlan carries the rendered inserted and rewritten lines, and apply_plans only writes and asserts them. The scripts/README.md sentence on refusals now says so.
  2. An inserted section whose heading lands inside a code fence the target leaves open is refused naming that fence and its line, rather than as an absent section. Any other block that swallows the heading gets a refusal naming the insertion line. Tests assert both messages.
  3. RESYNC.md step 1 and scripts/README.md now say the rename check covers text in the same file, since the scan is per file.

Verification

  • python -m unittest test_carry from tests/, with tests/requirements.txt: 78 tests pass.
  • Each new test fails against the code before its fix.
  • ruff check, ruff format --check, and prose_lint.py --diff origin/develop over the changed files: clean. The pre-commit hooks passed.

Local strict review

Two rounds. Round 1 raised two findings, and round 2 raised none.

  • Fixed in 62e5d18: when the inserted hub region held a fence of its own, that fence closed the target's open one in the spliced text. So the refusal fell back to the generic message. unparsed_insertion now reads the open fence from the text ahead of the insertion, and a test covers it.
  • Declined: consolidate the open-fence filter with scripts/build_dist.py:364. Both sites already call the shared primitive, spec/fidelity_text.py's code_blocks and its closed field. What is left at each site is a one-line filter with a different range meaning. There it keeps blocks that start strictly inside a heading's body, and here it keeps a block reaching the end of a prefix.

Closes on promotion: #3690

🤖 Generated with Claude Code

ptr727 and others added 2 commits November 2, 2026 13:25
… what apply-sections would

plan_unit now runs the in-memory insertion and splice, so check-sections
meets every refusal apply-sections raises. An insertion whose heading lands
inside a code fence the target leaves open is refused naming that fence,
not as an absent section. The docs say the rename check is per file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A fence in the inserted hub region can close the target's open fence, so
reading the spliced text hid it and the refusal fell back to the generic
message.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings November 2, 2026 21:30
@ptr727

ptr727 commented Nov 2, 2026

Copy link
Copy Markdown
Owner Author

A recorded local strict-review pass covers head 62e5d182e30652163785179d8bd7d07be41ccc95, the content this pull request carries at that commit against develop, and it recorded 0 findings.

@coderabbitai

coderabbitai Bot commented Nov 2, 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

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

The only remaining active finding is a nit at tests/test_carry.py line 664, where the test name runs several clauses together and does not directly state that the open fence is named even though the inserted hub region's own fence closes it, so the item is unresolved.

1 open issue
What changed in this PR

This PR makes scripts/carry.py's check-sections mode refuse everything that apply-sections would refuse. Before this change, check-sections could report a file as ready while apply-sections later rejected it. The PR also gives a clearer error when an inserted section lands inside a code fence the target leaves open. It closes the three follow-ups in issue #3690.

Changes:

  • Planning now renders each insertion and replacement in memory, so every refusal is raised before any file is written. apply_plans only writes and checks the rendered text.
  • An inserted section that would land inside an open code fence now fails with a message naming that fence and its line. Other blocks that swallow the heading get a message naming the insertion line.
  • The docs in RESYNC.md and scripts/README.md now say the rename check covers only the same file, since the scan is per file.
File Description
tests/​test_carry.py Adds tests for the planning-time refusal, the open-fence message, and the generic insertion message.
scripts/​README.md Updates the refusal sentence to say planning renders insertions and that the rename check is per file.
scripts/​carry.py Renders insertions and splices during planning, and adds the open-fence refusal helper.
RESYNC.md Says the rename refusal covers text in the same file only.

Review effort: Lite

Comment thread tests/test_carry.py Resolved
@codecov

codecov Bot commented Nov 2, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.97%. Comparing base (b38e084) to head (62e5d18).
⚠️ Report is 81 commits behind head on develop.

Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #3835      +/-   ##
===========================================
+ Coverage    81.60%   82.97%   +1.36%     
===========================================
  Files           26       29       +3     
  Lines         9070     9747     +677     
===========================================
+ Hits          7402     8088     +686     
+ Misses        1668     1659       -9     
Flag Coverage Δ
python-3.13 82.97% <100.00%> (+1.36%) ⬆️

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.

@ptr727
ptr727 merged commit 638d627 into develop Nov 2, 2026
14 checks passed
@ptr727
ptr727 deleted the burndown/3690-check-sections branch November 2, 2026 21:44
@ptr727

ptr727 commented Nov 2, 2026

Copy link
Copy Markdown
Owner Author

Backlog burndown orchestrator, for the record. The worker reported that round 2 of local-strict-review on this PR was run by a read-only reviewer that could not write its own report file. The worker then wrote that report itself, containing the digest line and no findings, before recording. The reviewer did return no findings, so the count is right. But develop's local-strict-review rule since #3807 is that the reviewer writes the report and the driver never writes it for the reviewer. This pass therefore lacks the binding that rule exists for. Later workers in this run are now briefed to dispatch a reviewer that can write.

ptr727 added a commit that referenced this pull request Nov 3, 2026
…f Filing Issues (#3846)

## Summary

Until now, filing an issue was always an acceptable way to dispose of a
finding. backlog-burndown's file claim and its prose bound ("the next
issue, filed") made filing the required route for a doc describing a
group's own change. This PR closes those routes. A fix that can land in
the pull request already open now lands there. Filing is kept for work
that really needs its own lane.

- **pr-review-conduct, outcome 4** (drive-pr carries it as an include):
  - An `introduced` finding is never filed.
- An edge case on new code is fixed where its deployment can produce the
input. Otherwise it is declined under Trust Boundaries.
- A `pre-existing` correctness defect in a file the diff touches is
fixed in this PR, within the same two-round budget. This uses the same
file grain as the class sweep, and Merge Gate item 3 excepts these
defects from the canonical tracker.
- Only a `pre-existing` correctness defect **in code that runs**,
elsewhere, is filed.
- An edge case on new code follows Trust Boundaries' whole
fix-or-decline test.
- The open-ended "Any other deferral is filed" catch-all is gone. The
only filings left are a design finding's untouched-file sites (one
issue, per "Triaging findings") and a fix belonging to another
repository.
- **GOVERNANCE.md, Verification Discipline** (agent-conduct carries it
as an include): the doc, manifest entry, or rule sentence describing
changed behavior is a sibling the change put in disagreement. It is
fixed in the change, not filed.
- **backlog-burndown**:
  - Claims predict the docs that describe each fix.
- A grown claim into an unclaimed file is granted at once. A grown claim
into a held file is sequenced: the requester's PR waits for the holder's
merge, and parks behind a holder that is stopped. A mutual wait is
adjudicated as a conflict. A file on an unclaimed branch stops for the
maintainer.
  - The prose bound admits units the change put in disagreement.
- Growth into carried canonical content or a design change under a
worker below `frontier` re-tiers the group, so that work never falls to
a lower tier.
- Hub workers read develop's copy of any skill develop has changed. This
closes the stale-installed-skill gap behind the self-written reports on
#3835, #3836, and #3838.
- **local-strict-review**: the reviewer brief stops asking for wording,
style, or consolidation remarks on text the diff did not write. Those
were dropped anyway, so this only cuts output and disposal tokens.

Maintainer decisions, 2026-11-02:
- Lever 1: agreed.
- Lever 2: file only code that runs.
- In-file pre-existing defects: fix them in the PR.
- Lever 3: rejected.

## Open `introduced` findings (loop stopped by the maintainer)

There were twelve recorded local passes at the `frontier` tier, raising
10, 9, 8, 6, 3, 3, 5, 4, 4, 2, 6, and 3 findings. Nearly every finding
was against text an earlier round had written. Of pass 11's six
findings, 1 to 5 were fixed in d70a96e. Finding 6, which asked to
revive the automatic re-tier, is declined: that hand-off drew new
findings in every round, so it was replaced on purpose with the existing
stop for the maintainer. By the maintainer's call, the last pass's
findings get no further edit round. On 2026-11-02 the maintainer
accepted both as known gaps (outcome 3):

1. `introduced`, backlog-burndown "Choosing the Worker's Model Tier":
the tier-stop paragraph's "claim comment is extended first" does not
repeat re-verify's limit to a file no branch holds. Read alone, it could
extend a claim over a file another group holds.
2. `introduced`, pr-review-conduct outcome 4, last bullet: where the
other repository's fix goes to the maintainer, no upstream issue exists
for the local blocker record to name.

## Pre-existing findings, not filed

- `pre-existing`, local-strict-review "The Carried-Content Sweep" with
pr-review-conduct outcome 4: a sweep pass's findings are on units the
sweep branch has not edited yet, so they route to the per-unit tracker
rather than to a fix.
- `pre-existing`, pr-review-conduct outcome 1 and "Triaging findings":
the untouched-file sites of a design finding are routed two ways. One
route files them as one issue, and the other drops them as a
consolidation on untouched text.

## Replay of the 25 issues the run filed

| Category | Issues | Under these rules |
| --- | --- | --- |
| Adjacent doc outside the claim | #3804, #3805, #3808, #3810, #3817,
#3820, #3837 | Fixed in the originating PR through the predicted or
granted claim. #3810 is a consolidation and #3817 is dead code, so each
is fixed if in a touched file and otherwise dropped or listed |
| Old defect next to the diff | #3813, #3821, #3824, #3825, #3833,
#3834, #3841, #3844 | Fixed where it sits in a touched file or unit.
Still filed only if it is code that runs elsewhere, which is about
#3821, #3824, and #3841. #3833 keeps its canonical tracker |
| Edge case past the done-definition | #3806, #3827, #3830, #3840, #3842
| `introduced`, so fixed in the PR or declined. #3830 is a contradiction
the fix wrote and is never filed |
| Decision | #3812, #3814, #3815, #3826 | Unchanged, still `decision`
issues |

Expected result for the same run: about 7 issues filed instead of 25.

Closes on promotion: #3845

## Verification

- `scripts/build_dist.py --check`: generated distributions are current.
- `prose_lint.py --diff origin/develop`: clean.
- `spec/validate.py`: OK.
- `repo_gate.py --check eol`: 0 issues.
- Docker markdownlint and cspell: 0 issues.
- local-strict-review: twelve passes recorded at the `frontier` tier.
The receipt covers the pushed head.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
ptr727 added a commit that referenced this pull request Nov 3, 2026
…rge on a Running Hosted Review, and Gate Skill Description Length (#3843)

Promotes the changes merged into `develop` since promotion #3797 to
`main`, the end of an away-mode backlog burndown.

- [#3803](#3803) exempts
the Roslyn embedded-language marker (`// lang=json`, `language=`) from
the prose gate's comment rules as a tool directive.
- [#3807](#3807) has
`local_review.py record` take `--report`, the file the reviewer wrote,
bind the pass to its sha256, and derive the finding count from it.
`status` gains `reportPath`.
- [#3809](#3809) holds
`pr_review.py merge` while a hosted review is still running on the head,
and routes a declined Qodo finding to a dismiss request.
- [#3811](#3811) dates an
anchored `intentRef` by the section its anchor names, and lets a
`driftNote` acknowledge a verified intent advisory.
- [#3816](#3816) moves the
null GraphQL node check into the shared `gh_graphql` transport as
`NullNodeError`.
- [#3818](#3818) explains
the workspace-edit default in `GOVERNANCE.md` and names the aggregator's
expression form.
- [#3822](#3822) moves the
abandon discard to the `backlog-burndown` orchestrator, aligns the
abandoned-branch delete, and holds a grown agent-safety set.
- [#3823](#3823) scopes
the Husky prose gate to staged paths and adds `--skip-generated` so a
named file inside a generated tree is skipped.
- [#3828](#3828) reads
Copilot's `Open findings:` label, drops the duplicate `null_node`, and
matches `scripts/README.md` to the Merge Gate.
- [#3829](#3829) bumps the
two stale hub caller snippet pins and documents the fallback's
mixed-pair refusal.
- [#3831](#3831) keeps an
inherited `GIT_DIR` from rerooting the prose gate's subdirectory git
reads.
- [#3832](#3832) gives
`backlog-burndown` a disposition for a worker's standalone clone and
keeps the agent-safety hold past a park.
- [#3835](#3835) makes
`carry.py check-sections` refuse what `apply-sections` would, and name
an open fence.
- [#3836](#3836) pins the
reusable-workflow stubs by placeholder and ticks the PlexCleaner gates
item.
- [#3838](#3838) has the
`runtime-secrets` audit dimension detect a bare `secrets/` directory
from the tracked files that name it.
- [#3839](#3839) gates
skill descriptions at the 1024-character limit and trims every one over
it.
- [#3846](#3846) fixes an
adjacent doc, an in-file pre-existing defect, and an edge case on new
code in the open pull request instead of filing an issue for each, and
keeps filing for code that runs elsewhere.
- [#3847](#3847) refuses
skill frontmatter that parses to a list or a scalar, so the description
length gate cannot be bypassed.

Fixes #3770
Fixes #3699
Fixes #3705
Fixes #3789
Fixes #1819
Fixes #727
Fixes #3710
Fixes #3706
Fixes #3623
Fixes #3687
Fixes #3617
Fixes #3757
Fixes #3790
Fixes #3786
Fixes #3785
Fixes #3772
Fixes #1657
Fixes #3443
Fixes #3824
Fixes #3817
Fixes #3805
Fixes #1666
Fixes #3700
Fixes #3821
Fixes #3771
Fixes #3794
Fixes #3825
Fixes #3690
Fixes #1472
Fixes #3813
Fixes #3719
Fixes #1592
Fixes #3845

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants