Skip to content

feat(wrap): warn when a write verb lands a file on the default branch - #658

Merged
tieubao merged 10 commits into
masterfrom
feat/wrap-no-default-commit
Sep 16, 2026
Merged

tieubao merged 10 commits into
masterfrom
feat/wrap-no-default-commit

Conversation

@tieubao

@tieubao tieubao commented Sep 16, 2026

Copy link
Copy Markdown
Member

Closes ID-879.

Problem

Three kit verbs write a file inside a checkout and leave the commit to the caller: wrap log, wrap stage, board set. commands/wrap.md step 2 says so in prose, and the model makes that call in whatever checkout the session runs in, usually the main checkout on the default branch. Nobody pushes the default branch, so those commits never reach a PR. One Air carried 29 such commits plus 61 merge commits by 2026-09-14 before an operator drained them by hand.

What changed

lib/gate/default-branch-warn.sh adds one sourced helper, kit_warn_default_branch <path> [label]. It prints one stderr line and always returns 0:

board set: wrote BACKLOG.md on the default branch (main); do not commit it here, leave it for the next feature PR or move it to a branch

Call sites: wrap log, wrap stage, board set, board dedupe, board dedupe-all.

Warn, never refuse. The file is what the session asked for and the next feature PR carries it fine. Refusing would lose the write; auto-creating a housekeeping branch would take a git write nobody asked for, in a checkout other sessions share, while wrap is already juggling merges and worktrees.

Silent outside a git repo, on a detached HEAD, when no default branch resolves, and on any branch that is not the default one. origin/HEAD decides, then origin/main, then origin/master; a repo with no remote at all falls back to a local main or master. Every git read drops GIT_DIR and GIT_WORK_TREE so an inherited value cannot point the probe at another repo.

Prose: commands/wrap.md step 2 now states the rule for every file the pass writes, including a seam skill's flush; step 6 and the wrap.after paragraph point back at it.

Verification

  • bash tests/test-wrap.sh -> all 508 passed (498 before)
  • bash tests/test-board-set-note.sh -> ALL PASS
  • bash tests/run-all.sh -> all 148 suites passed, 1 skipped for missing tooling
  • Negative control via lib/gate/negctl.sh in a fresh clone, mutation neuters the guard's branch comparison: both suites RED under the mutation, green after restore, Verdict: PASS twice.

Spec: docs/specs/SPEC-289-no-default-branch-commit.md. Proof: docs/verification/no-default-branch-commit.md. Notes: docs/implementation-notes/no-default-branch-commit.md.

Not in this PR

The knowledge-flush skill the wrap.after seam names lives in the operator's dotfiles, and lib/gate/boundary-lint.sh forbids naming it here; step 2 carries the rule for every seam skill instead. The two companion guards the row names, an ops-toolkit pre-commit hook and a dotfiles pull.ff=only, belong to those repos.

wrap log, wrap stage and board set write a file and leave the commit to the
caller. The caller usually sits in the repo's main checkout, on the default
branch, where a commit cannot reach a PR. One machine accumulated 29 such
commits plus 61 merge commits before an operator drained them by hand.

Add kit_warn_default_branch in lib/gate/default-branch-warn.sh. Each verb
calls it after the write lands; it prints one stderr line and always returns
0, so the write is never refused. commands/wrap.md step 2 now states the rule
for every file the pass writes, including a seam skill's flush.
Review found two holes. `board dedupe-all` is a hand-runnable CLI verb, not
only wrap's internal re-merge call, so a sweep on the default branch wrote the
file the guard exists to flag and said nothing. And `git -C` does not clear an
inherited GIT_DIR, so a verb invoked from inside a git hook would resolve HEAD
against the hook's repo; every git read now drops GIT_DIR and GIT_WORK_TREE.
…t-commit

# Conflicts:
#	_meta/BACKLOG.md
#	docs/FEATURES.md
@tieubao
tieubao merged commit 21c347a into master Sep 16, 2026
1 check passed
@tieubao
tieubao deleted the feat/wrap-no-default-commit branch September 23, 2026 07:11
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.

1 participant