fix(ci): the NOW sync gate writes nothing to the clone it runs in (Refs #5482) - #5488
Merged
Merged
Conversation
#5482) scripts/ci/now-sync-gate-diff.sh ended every pass with setup_skill_merge_driver (#4728). It appended `.claude/skills/ci-gates/SKILL.md merge=union` to .gitattributes and set merge.union.name/driver in the shared .git/config. `tri gates preview` and `tri hooks pre-push` run the script in contributors' clones. There the configured driver replaced git's built-in `union`, which .trinity/experience/*.jsonl relies on. Its command used unset shell variables instead of git's %O %A %B, so every union merge of those logs failed with `bash: $REMOTE: ambiguous redirect`. The writer is removed. scripts/ci/test_now_gate_writes_nothing.py runs each caller in its own scratch repository, on a range the gate passes. The callers are the script's three arms and, with --tri, `tri gates preview` and `tri hooks pre-push`. For each, .git/config, .gitattributes, .git/info/attributes and git status must be byte-identical before and after, and a union merge must still work. A planted copy of the old writer must be caught, and must break the merge. Against the unfixed script all five callers fail on both counts. Wired into untrusted-input-gate.yml, and into cli-tri.yml with the binary that job builds. .gitattributes: its header pointed to .git/config "for implementations"; it uses built-in drivers only. Census: `shell` moved, run: steps 280 -> 282 and "the runner does" 259 -> 261. These are the two new steps. Re-blessed with `tri census pin --bless`. Clean an affected clone with git config --unset merge.union.driver git config --unset merge.union.name git checkout -- .gitattributes (if the appended line is still there) Refs #5482 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 1, 2026
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
Contributor
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.
Refs #5482
What was wrong
scripts/ci/now-sync-gate-diff.shended every passing run withsetup_skill_merge_driver(added by #4728 for #3236). That function:.claude/skills/ci-gates/SKILL.md merge=unionto.gitattributes, which leftM .gitattributes;merge.union.nameandmerge.union.driver(bash -c 'cat $BASE $LOCAL $RIGHT > $REMOTE') in the repository's shared.git/config.Three callers run the script in a contributor's own clone: a direct run,
tri gates preview(rowcheck-now-freshness), andtri hooks pre-push(run by.githooks/pre-push, which CONTRIBUTING step 1 installs).When a merge driver is configured under a name, it replaces git's built-in driver of that name. So this driver replaced the built-in
unionthat.gitattributesuses for.trinity/experience/*.jsonl. git fills in%O %A %Bin a driver command, but this command used$BASE $LOCAL $RIGHT $REMOTE, which are unset shell variables. Two branches appending to one*.jsonlfile then failed to merge (bash: $REMOTE: ambiguous redirect, exit 1). With the built-in driver the same merge is clean. In CI the writes were lost when the runner was discarded.Change
scripts/ci/now-sync-gate-diff.sh: removed the writer. A comment now states that the gate is read-only, says why, and gives the cleanup commands.scripts/ci/test_now_gate_writes_nothing.py(new control): runs each caller in its own scratch repository, with an empty global config, on a range the gate passes. The writer only ran after a pass, so a refused range would prove nothing. For each caller,.git/config,.gitattributes,.git/info/attributesandgit statusmust be byte-identical before and after the run, and a two-branch union merge of a*.jsonllog must still succeed afterwards..git/info/attributes, a stray untracked file, and a gate that stops passing. A no-op passes.untrusted-input-gate.ymlruns the script's three arms, which need no Rust.cli-tri.ymlruns all five callers with--tri ./target/debug/tri, right after the build.tools/census/shell.txt: re-blessed.run:steps went from 280 to 282 and "the runner does" from 259 to 261. These are the two new steps..gitattributes: the header comment pointed to.git/config"for implementations". It now says the file uses built-in drivers only. This is a comment change only.docs/now/2026-10-01-the-now-gate-writes-nothing-to-the-clone.md: the NOW entry for this change.SKILL.md conflicts are handled by the spool (ci-gates SKILL.md sections 592-593). Whether SKILL.md should get a committed
merge=unionline using the built-in driver is a separate decision, and this PR does not add one.Cleaning an affected clone
No commit on master contains the appended line. On 2026-10-01, none of the 52 open PRs touched
.gitattributes.Verified locally
python3 scripts/ci/test_now_gate_writes_nothing.py --tri ./target/debug/tri: 20 checks ok, exit 0. Without--tri: 14 checks ok, exit 0, and the output says the twotricallers were not run.tri gates preview --base origin/masterand the gate script: the sha256 of the shared.git/configand of.gitattributesis the same before and after, and nomerge.*keys exist.tri census pin --gate: PASS.test_required_gates_name_their_subject.py: ok.check_now_entry_shape.py: ok.🤖 Generated with Claude Code