Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions .claude/skills/ci-gates/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -17205,3 +17205,51 @@ branch, and change what the merge is being asked to combine.
The same shape appears wherever two branches edit one shared position: a first line, a
counter, a next free number, a hand-maintained index. `docs/NOW.md` had it and was split.
`SKILL.md` had it and was not, until now.

## 594. The population of EVENTS, after the predicate and the operand

Three defect classes in two days, in strict order of subtlety.

the PREDICATE is the rule right? -- unit tests answer this
the OPERAND is it applied to the right -- eight gates read the working tree,
thing? the directory, or HEAD (§590)
the EVENTS what else comes through -- nothing answers this but enumeration
this place?

The third one produced two defects that every control missed, because a control tests the
event you thought of.

**A push can be a deletion.** `.githooks/pre-push` did not read stdin, so
`git push origin --delete <branch>` was refused with `SYNC REQUIRED: this PR/push adds no
docs/now entry` and the branch survived on the remote. git feeds a push hook
`<local ref> <local sha> <remote ref> <remote sha>`, one line per ref, and a deletion has
an **all-zero local sha**.

**A commit can be a merge.** Measured on git 2.50.1 with marker hooks:

event pre-commit commit-msg
normal commit yes yes
--amend yes yes
--allow-empty yes yes
merge --no-ff NO yes
cherry-pick NO NO

So every gate in the barrier — the conflict-marker refusal above all — was silent on **the
one commit type conflict markers come from**. `git merge` runs `pre-merge-commit`, whose
non-zero exit stops the merge; the index at that moment holds the merge RESULT, which is
exactly the operand the barrier reads once it is corrected to `--staged`. `cherry-pick` runs
neither hook and git offers none that could stop it: that gap is stated, not papered over.

**The method is enumeration, not cleverness.** Write marker hooks that only `touch` a file,
run each event through them, and read which files exist. It takes minutes and answers a
question no amount of reasoning about the gate will.

Two hazards met while measuring, both worth their own line:

* **`git config` inside a worktree writes to the SHARED config.** Setting `core.hooksPath`
for a probe disabled the real hooks in all 148 worktrees, including other sessions
committing at that moment. Use `git -c core.hooksPath=... <command>`, which lives only in
that process.
* **A failed `cd` does not stop a subshell.** `( cd "$P" ; git commit ; git merge )` with a
missing `$P` ran its commits in the current tree. Write `cd "$P" || exit 1`, print `pwd`,
and make any probe that WRITES confirm its location first.
2 changes: 1 addition & 1 deletion .trinity/notebook_commit_count
Original file line number Diff line number Diff line change
@@ -1 +1 @@
10
11
14 changes: 14 additions & 0 deletions docs/now/2026-09-05-the-population-of-events.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# NOW -- The population of events, after the predicate and the operand (2026-09-05)

## The population of events (Refs #3320)

- Three classes in two days, in order of subtlety: the PREDICATE (unit tests answer it),
the OPERAND (section 590: eight gates read the working tree, the directory, or HEAD),
and the EVENTS -- what else comes through this place, which nothing answers but
enumeration.
- The third produced two defects every control missed, because a control tests the event
you thought of. A push can be a deletion. A commit can be a merge.
- The method is enumeration: marker hooks that only `touch` a file, one run per event,
then read which files exist. Minutes, and it answers what no reasoning about the gate can.
- Two hazards met while measuring: `git config` inside a worktree writes to the SHARED
config, and a failed `cd` does not stop a subshell. Both are recorded with their fixes.
Loading