research(hook-base-ref-detection): R-phase — pre-push base-ref via git stdin (ADAPT pre-commit precedent) - #287
Merged
Merged
Conversation
chore: resync staging→main (promote 38 PRs + 3 merge-commits)
…t stdin (ADAPT pre-commit precedent) Surfaces a load-bearing asymmetry: CI knows the real PR base via github.base_ref (audit-self.yml:291-313), but pre-push.ts:50-52 + pre-push.fallback.sh:11 guess 'origin/staging'. Consumers with main/master trunk fall through git rev-parse --verify → exit 0; the entire §1.7 + §7 enforcement substrate is silently dead by default for any consumer repo without a 'staging' branch (install.sh:483 ships only the fallback to consumers, not pre-push.ts). Root cause: own-stack-blind-spot — git provides base-ref to pre-push hooks via stdin (<local_ref> <local_sha> <remote_ref> <remote_sha>), the canonical authoritative signal pre-commit framework consumes. Our hook reads stdin nowhere. Verdict: ADAPT pre-commit's stdin-parsing primitive on dev/consumer side; preserve PREPUSH_UPSTREAM_REF as CI override for full-PR-range scope (matches audit-self.yml PREPUSH_ONLY seam, PR #121). Maintainer verdict 2026-05-29: incremental-push-on-dev / full-PR-range-on-CI — per-commit trailer invariant means incremental scope checks every commit if dev stops silent-skipping. I-phase work items (NOT fixed here — T5): F1 (pre-push.ts:297 §6-guard hardcoded origin/main...HEAD + 3-dot/2-dot inconsistency vs git.ts), F2 (TS silent-skip → loud-fail alignment with fallback warning), F3 (verify .husky/pre-push native stdin forwarding), F4 (SSOT entry "pre-push base-ref via git stdin"). Scope-drift acknowledgment: R-phase prompt scope was worktree-setup.sh:73 (WorktreeCreate hook origin/HEAD staleness, 4 hits observed). Worker pivoted to pre-push hook on discovering a larger asymmetry. Pivot accepted as valid discovery — original ask remains open as separate queued umbrella (worktree-create-dual-channel per memory). Prior-art: pre-commit/pre-commit (DeepWiki 2026-05-29) — stdin remote_sha as base; rev-list --remotes for Z40 new-branch; PRE_COMMIT_FROM_REF / TO_REF env. T16 match analysis: stdin-parsing primitive transfers; full-PR vs incremental scope semantics differ — maintainer decision documented as the inherited I-phase fork. Prior-art: lefthook (WebSearch 2026-05-29) — uses git diff HEAD @{push}; the @{push} push-target signal pattern confirms mature tools read git's push-destination rather than hardcoding base. ADAPT precedent for our dev/consumer-side resolver. Prior-art: prior-art-evaluations.md SSOT consult 2026-05-29 — no existing entry for base-ref detection; F4 proposes new SSOT row in I-phase.
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.
Summary
R-phase research-patch on pre-push hook base-ref detection. Worker started on
worktree-setup.sh:73(CC WorktreeCreate hook origin/HEAD staleness, 4 observed hits) but pivoted on discovering a larger asymmetry in the pre-push enforcement substrate. Pivot accepted as valid discovery; original ask remains open as separate queued umbrella (worktree-create-dual-channelper memoryproject_worktree_create_dual_channel_decision).Main finding:
install.sh:483shipspre-push.fallback.sh(notpre-push.ts) to consumers; fallback defaults toorigin/staging. Consumers with main/master trunk →git rev-parse --verifyfails →exit 0. The §1.7 + §7 enforcement substrate the project sells is silently dead by default for any consumer without astagingbranch.Verdict (ADAPT, falsifiable): Read git pre-push stdin as base-ref on dev/consumer side (pre-commit framework precedent — DeepWiki 2026-05-29). Keep
PREPUSH_UPSTREAM_REFas CI override per existingPREPUSH_ONLYseam (audit-self.yml:291-313already correct).Maintainer verdict 2026-05-29 on the scope fork (incremental-vs-full-PR): incremental-push-on-dev / full-PR-range-on-CI. Matches existing CI backstop architecture (PR #121 PREPUSH_ONLY seam runs over real PR range). Per-commit trailer invariant means incremental scope still checks every commit if dev stops silent-skipping → stdin alone is strict improvement.
Falsifier: wrong if husky/git pre-push doesn't actually forward stdin natively in this setup — F3 verification scheduled for I-phase.
Files
docs/meta-factory/research-patches/2026-05-29-hook-base-ref-detection.md(NEW)I-phase work items (NOT in this PR — T5)
pre-push.ts:297§6 guard hardcodedorigin/main...HEAD+ 3-dot vs 2-dot inconsistency reconciliation (git.ts:45,53).pre-push.fallback.sh:11warning..husky/pre-pushnative stdin forwarding (no husky npm dep present, low risk, confirm before relying).I-phase = separate session with separate kickoff per R/I separation discipline.
§1.7 Forward-check applied
Sweep across active
.claude/rules/for disciplines bearing on this research-patch:.claude/rules/build-first-reuse-default.md §3— BFR 6-layer survey done: WebSearch ×3 (origin/HEAD detection, base-ref signals, lefthook), DeepWiki (pre-commit/pre-commit), SSOT consult (no existing base-ref entry). Verdict ADAPT for pre-commit stdin primitive at patch §Recommended-design..claude/rules/phase-research-coverage.md §1— 6-item search-coverage met: SSOT consult, WebSearch ≥3, DeepWiki, T16 problem-class explicit at patch §Prior-art..claude/rules/phase-research-coverage.md §1.7— this section..claude/rules/phase-research-coverage.md §1.12— recommendation discipline: verdict carries cited evidence + file:line backed claims (pre-push.ts:50-52,pre-push.fallback.sh:11,install.sh:483,audit-self.yml:291-313,pre-push.ts:297)..claude/rules/ai-laziness-traps.md §2 T5— R-phase output is research-patch only, no code changes (file:line: patch §I-phase findings header «do NOT fix in this R-phase — T5»)..claude/rules/ai-laziness-traps.md §2 T11— own-stack-blind-spot named explicitly at patch §Root-cause; prior-art consulted before proposing fix..claude/rules/ai-laziness-traps.md §2 T16— problem-class match analyzed at patch §Prior-art with explicit «partial match» finding (stdin-primitive transfers; scope semantics differ — maintainer fork documented)..claude/rules/dual-implementation-discipline.md §3— CI vs dev/consumer asymmetry is the core finding (CI already correct ataudit-self.yml:291-313; dev/consumer dead atpre-push.fallback.sh:11). Verdict preserves CI override path..claude/rules/no-paid-llm-in-ci.md §1— proposed mechanism is git-stdin parsing in dev hook, no LLM in CI.§1.7 Backward-check applied
Sweep for artefacts that this patch must NOT silently supersede:
docs/meta-factory/prior-art-evaluations.md— no existing base-ref entry; this patch proposes F4 new entry in I-phase, does NOT alter existing rows. SSOT consult evidence: grep verified no «pre-push» or «base-ref» entry across the register at author-time..claude/rules/phase-research-coverage.md— patch operates within its discipline (cites §1 + §1.7 + §1.12), does NOT modify the rule itself.project_warn_only_flip_and_ci_backstop) — CIPREPUSH_ONLYseam at real PR range PRESERVED. Verdict explicitly keepsPREPUSH_UPSTREAM_REFenv override peraudit-self.yml:311(setsPREPUSH_UPSTREAM_REF=origin/<github.base_ref>via GitHub Actions env). Not superseded.WorktreeCreatevs pre-push), different bug class. NOT touched, NOT superseded. Originalworktree-setup.sh:73issue queued as separate umbrella per memoryproject_worktree_create_dual_channel_decision.audit-self.yml:291-313PREPUSH_ONLY seam — explicit cite as «correct» in patch §Problem; preserved..husky/pre-pushorchestration — patch does NOT propose changes to husky setup; F3 verifies stdin forwarding before I-phase relies on it.🟢 Простыми словами
Хук pre-push проверяет трейлеры §1.7 в коммитах перед
git push. Чтобы знать какие коммиты проверять, ему нужна «база» — точка от которой считать новые. Сегодня хук угадывает базу как «origin/staging», но у внешних пользователей такой ветки обычно нет → git ругается → хук тихоexit 0→ проверки не запускаются. Дисциплина, ради которой проект существует, по умолчанию мёртвая у всех внешних потребителей.Открытие: git САМ передаёт хуку базу через stdin (стандартный pre-push протокол:
<local_ref> <local_sha> <remote_ref> <remote_sha>). Не угадывать — читать. Так делает фреймворкpre-commit/pre-commit(зрелый upstream, верифицирован через DeepWiki). На dev/consumer-стороне читаем stdin, на CI-стороне оставляем переменнуюPREPUSH_UPSTREAM_REFкоторая уже работает правильно через GitHub Actionsgithub.base_ref. Это R-phase патч — фикс будет в отдельном I-phase.Scope-drift acknowledgment: исходный запрос был про другой хук (
worktree-setup.sh:73— дляclaude -w), Worker нашёл этот более важный баг при research. Принято как valid discovery; оригинальный фикс остаётся в queued umbrellaworktree-create-dual-channel.