records: land opencv, nothing outstanding - #52
Merged
Merged
Conversation
* flow: stage maintainer-requested fixes off open upstream PRs Once an upstream PR is open, its head branch (moat-port) is upstream-visible: any push lands in front of the maintainer before review, revalidation, or a person's approval. The colmap #4635 maintainer round nearly shipped an unreviewed fix this way. This closes the hole: - fixes stage on moat-fix-<pr#> (moatlib fix-branch); head_sha tracks the staging tip so revalidate/pr-gate derivation is unchanged; new published_sha records what the open PR shows - a person approves the delta on a fork review PR (upstream.py --fix-review); a body section headed '## Upstream reply' is approved with it - upstream.py --merge-fix --apply re-checks the live approval and all gates, fast-forwards moat-port to exactly the approved tip, posts the approved reply, deletes the staging branch, and records it -- the second pre-authorized upstream write, same contract as --publish --apply - enforcement: a fork-clone pre-push hook (moatlib protect-fork, installed by orient), a check.py 'published' gate, and a HEAD-MOVED report in the --dry-run reconciler (a maintainer push is reviewed and recommended on, never auto-absorbed) Docs: AGENTS.md, moat-checkup skill, porter/reviewer/validator roles, CONTRIBUTING.md, VISUAL.md. Schema regenerated; README table regenerated. Verified with a synthetic project and local bare fork: hook refusal/bypass, gate detection, fix-branch backfill, fix-ready refusals, report paths. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * flow: make the fix-flow enforcement hold where the records live Review of the staged fix flow found the enforcement layer passing in the configuration MOAT actually runs in, and the merge path leaving residue a person then has to untangle. Fixes, in the order they bite: - the fork pre-push hook read projects/<name>/status.json as a PATH, but an in-flight project's folder lives on port/<name> and is absent from every checkout standing anywhere else. json.load then raised, the state read as empty, and the hook exited 0 -- so it allowed exactly the push it exists to refuse. Verified on the gfx1151 host: projects/colmap/status.json is absent while projects/colmap/src is present, and colmap #4635 is the round this flow is meant to run first. The hook now asks `moatlib.py pr-state <name>` (project_record, so it resolves from whichever ref holds the record) and REFUSES when the state cannot be read: a guard that cannot tell must not be the reason an unreviewed commit reaches a maintainer. It reads the ref updates first, so only a push to the PR branch pays for the lookup, and --refresh re-fetches so another host's `set-pr-open` cannot be missed. - protect-fork now returns a level and sends "a NON-moat pre-push hook is installed; not touching it" to stderr, which orient no longer discards. An unprotected clone that looks exactly like a protected one is the failure mode being guarded against. - the 'published' gate compared the clone's LOCAL port branch to published_sha. --merge-fix pushes a sha to the fork and moves no local ref, so the host that performed the approved merge failed this gate on every subsequent push (install_hooks' pre-push runs check.py --fast, which includes it), and any host that had not fetched since a merge failed it too. It now asks the only question a clone can answer -- is it AHEAD of the published tip, which is the actual precursor to an unapproved push. Behind is a stale fetch and passes silently; diverged is reported as a rewrite. do_merge_fix also fast-forwards the clone's own branch afterwards. - fix-branch was unreachable for most projects it applies to: 30 of the 53 open-PR records are trunk-resident with no port/<name>, so save_record raised "check out main", which rule 1 forbids and orient refuses -- and belongs_on_branch only flips once head_sha moves, which cannot happen until the round is recorded. It now re-homes the folder onto port/<name> first (ensure_port_branch): the fix round IS the event that means "in flight again", so it is what breaks the circle. - record_writable_here is the same question asked in advance, and both --fix-review and --merge-fix now pre-flight it. Discovering an unwritable record AFTER the upstream PR has moved is the worst state this flow can produce; --merge-fix reports HELD instead. - do_merge_fix records the merge BEFORE deleting the staging branch. A failed delete leaves a spare branch; a failed record after a delete left a moved PR, a published_sha naming the old tip, and a fix block pointing at a branch that no longer existed -- which --dry-run then reports as a maintainer push. set-fix-merged is exposed for that recovery (it records, it authorises nothing). - open_fix_review_pr no longer lets set_fix_review_pr raise past a created PR: the URL was lost, the round still read as needing a review PR, and the next run would open a second one. - the delta jargon scan treated any parsed compare as complete. `compare` caps at 250 commits and 300 files and omits `patch` on large ones, so a truncated answer read as clean on the last check before in-house vocabulary reaches a stranger's repository. It now scans from the fork clone when one holds both commits, and raises on a truncated API answer. - fix_branch backfilled published_sha from head_sha unverified, though that value becomes the merge-time ancestry baseline AND the baseline --dry-run calls a maintainer push. It now confirms against the live PR head and refuses when they disagree, which is the HEAD-MOVED case. - the '## Upstream reply' section ran to the end of the body, so a trailing '## Notes' written for our own eyes would have been posted verbatim upstream. It now ends at the next ## heading, skipping fenced blocks. - poll() compared shas with != while everything else uses same_commit; an abbreviated published_sha would have reported a maintainer push every sweep. set_fix_review_pr and set_fix_merged also switched from load_status to project_record, so a port branch's copy of somebody else's folder cannot be edited and written back over the real record. Verified: the hook refuses/allows correctly across 6 cases against a local bare fork, including the branch-resident record that defeated v1 and the unreadable-state refusal (v1 allowed both); 27 logic checks over the reply extraction, compare truncation, local delta scan, residency helpers; 7 over the published gate's ahead/behind/diverged/stale-object paths; 8 over the branch sync. Full check.py green apart from the pre-existing gh-shim PATH artifact on this host. --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
The gfx1151 host is back in service, so the selector offered kaldi's windows gate to it: `next-task windows-gfx1151` returned kaldi/port-ready/validator. That is a build that cannot succeed. kaldi's ROCm path is gated on the host OS, not on the GPU -- src/configure's configure_rocm() exits 1 unless uname is Linux and uname -m is x86_64, before any arch is consulted -- and windows-gfx1101 and windows-gfx1201 already say so in their blocked_reason. The gfx1151 record that said it too was removed with the other 132 records of an intention to validate on a machine we no longer had. Removing it was right; an absent record means "no host has worked this platform" and the selector defaults it correctly. But the arch that has recorded nothing is exactly the arch most likely to discover it cannot run the project at all, and set_blocked indexed straight into obj["platforms"][platform] and raised KeyError. The one way to record the finding was the one case it could not handle. So blocking creates the row, the way a stage transition already does. Clearing does not: writing a row that says "not blocked" would put back an intention to validate somewhere, which is fleet state, so --clear on an arch with no record says there is nothing to clear rather than inventing one to unset. kaldi's windows-gfx1151 block is recorded with the configure line that proves it, verified against the fork rather than copied from the sibling archs. The README regeneration that follows also picks up colmap and HEonGPU moving from validated to revalidate, which their advanced heads already implied. Test Plan: ``` python3 utils/moatlib.py set-blocked kaldi windows-gfx1151 "..." # was KeyError python3 utils/moatlib.py set-blocked kaldi linux-gfx942 --clear # nothing to clear python3 utils/moatlib.py validate kaldi python3 utils/moatlib.py next-task windows-gfx1151 # no longer kaldi python3 utils/check.py ``` Authored with Claude (Opus 5) as the AI assistant.
The branch had independently applied both trunk commits -- the fix-flow work and the set-blocked fix -- under different shas, so utils/ conflicted as the same content twice rather than as a disagreement: check.py, upstream.py and reviewer.md are byte-identical to main@b29761d and moatlib.py to main@beacaaa. The trunk is strictly newer in every case, adding the reviewing work lock on top, so the trunk's copy wins and the branch loses nothing. projects/kaldi/status.json conflicted for the same reason and resolves the same way: the branch carries its own copy of the windows-gfx1151 block, and the trunk's copy additionally carries the published_sha backfill. The branch's own projects/opencv/ records are untouched.
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.
Lands the completed control-plane records for opencv.
review-passed, no waivers, no open deferrals.Records-only, under
projects/opencv/.Part of the misplaced-branch sweep.
🤖 Generated with Claude Code