@biffo/cli 0.249.3 → 0.249.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -35,11 +35,22 @@ fi
35
35
  root=$(git rev-parse --show-toplevel) || exit 0
36
36
  cd "$root" || exit 0
37
37
 
38
- # The rewrite-scope guard runs FIRST, and it is the only thing here that needs
39
- # the ref list git puts on stdin (<local ref> <local sha> <remote ref>
40
- # <remote sha>). verify.sh reads no stdin, so consuming it here costs nothing
41
- # but it does mean this must run before the `exec` below, which replaces the
42
- # process entirely.
38
+ # git puts the ref list (<local ref> <local sha> <remote ref> <remote sha>, one
39
+ # line per ref) on this process's stdin, ONCE. Two things below need it --
40
+ # rewrite-scope-check and the pg-test block gate -- and a pipe can only be read
41
+ # once, so it is captured to a file here and each consumer is fed from that
42
+ # file instead of the real stdin. Falling back to no capture (each reader gets
43
+ # whatever is left of the real stdin, i.e. nothing for the second one) rather
44
+ # than failing the push if a temp file cannot be created: this hook's job is to
45
+ # run checks, not to invent a new way to block a push that has nothing to do
46
+ # with any of them.
47
+ REFS_FILE=$(mktemp) || REFS_FILE=""
48
+ if [ -n "$REFS_FILE" ]; then
49
+ cat >"$REFS_FILE"
50
+ trap 'rm -f "$REFS_FILE"' EXIT HUP INT TERM
51
+ fi
52
+
53
+ # The rewrite-scope guard runs FIRST.
43
54
  #
44
55
  # Why it exists: a force-push can quietly add a file to a branch's change set
45
56
  # and record a stale copy of somebody else's merged work as your own change.
@@ -51,7 +62,11 @@ cd "$root" || exit 0
51
62
  # the file was the one where nothing checked. There is no absent case now --
52
63
  # the bridge resolves the script from the package -- and if the bridge itself
53
64
  # cannot run, that is a reason to stop, not to wave the push through.
54
- sh scripts/biffo.sh rewrite-scope-check || exit 1
65
+ if [ -n "$REFS_FILE" ]; then
66
+ sh scripts/biffo.sh rewrite-scope-check <"$REFS_FILE" || exit 1
67
+ else
68
+ sh scripts/biffo.sh rewrite-scope-check || exit 1
69
+ fi
55
70
 
56
71
  # --- Claim guard (#1231 instance 2) -------------------------------------------
57
72
  #
@@ -94,6 +109,42 @@ if [ -n "$branch" ]; then
94
109
  # exit 1 instead, if you would rather block than guess.
95
110
  fi
96
111
 
112
+ # --- pg-test block gate (#656) -------------------------------------------
113
+ #
114
+ # verify.sh already reports `pg-test` as `APPLICABLE BUT NOT RUN` when the repo
115
+ # has Postgres-dependent tests and no DSN reached it, and tries to provision one
116
+ # itself via `scripts/biffo.sh pg-test-db` before giving up. That is honest and
117
+ # often self-healing -- but it surfaced on a push that was ENTIRELY RLS policy
118
+ # DDL, where the lane still did not run and the push still went through amber.
119
+ # A wall of green `OK` lines does not make a person weight one amber line
120
+ # correctly at 5pm, and CI treats this lane as required, so a local pass that
121
+ # quietly skipped it is not the thing it looks like.
122
+ #
123
+ # So: if this push touches `db/imports/**` or a `*_pg.py` module -- the
124
+ # convention `scripts/pg-test-db.sh` and verify.sh's own module discovery both
125
+ # use -- and verify.sh still cannot run the lane, block rather than warn.
126
+ # `BIFFO_PGTEST_DIFF_RELEVANT=1` is how that intent reaches verify.sh; it makes
127
+ # no decision itself, `scripts/pgtest-diff-check.sh` (through the same bridge
128
+ # as rewrite-scope-check) does, from the same ref list captured above.
129
+ #
130
+ # Deliberately narrow: an ordinary frontend push touches none of those paths,
131
+ # so `pgtest-diff-check` exits 1 and nothing here changes. A repo whose
132
+ # integration branch cannot be resolved, or that got no ref list at all, exits
133
+ # 2 -- "could not tell" -- and this does NOT block on that, the same posture
134
+ # `rewrite-scope-check` and `claim.sh --guard` take on their own blind spots: a
135
+ # coordination-shaped check that fails closed on not knowing teaches people to
136
+ # route around it, which is the opposite of what a gate is for.
137
+ #
138
+ # `BIFFO_SKIP_PGTEST=1`, checked here rather than only inside verify.sh, is the
139
+ # deliberate escape hatch AGENTS.md section 7 requires for loosening a gate --
140
+ # in the open, not by reaching for `--no-verify` and skipping every other check
141
+ # too.
142
+ if [ -z "${BIFFO_SKIP_PGTEST:-}" ] && [ -n "$REFS_FILE" ]; then
143
+ if sh scripts/biffo.sh pgtest-diff-check <"$REFS_FILE"; then
144
+ export BIFFO_PGTEST_DIFF_RELEVANT=1
145
+ fi
146
+ fi
147
+
97
148
  # Through the version-pinned CLI since #1109, so a repo cannot run a gate two
98
149
  # versions old -- eight of them did, and tabsii-crm checked ONE thing in eight
99
150
  # on a 700-line change and printed `verify passed` (#855). There is one copy of
@@ -35,11 +35,22 @@ fi
35
35
  root=$(git rev-parse --show-toplevel) || exit 0
36
36
  cd "$root" || exit 0
37
37
 
38
- # The rewrite-scope guard runs FIRST, and it is the only thing here that needs
39
- # the ref list git puts on stdin (<local ref> <local sha> <remote ref>
40
- # <remote sha>). verify.sh reads no stdin, so consuming it here costs nothing
41
- # but it does mean this must run before the `exec` below, which replaces the
42
- # process entirely.
38
+ # git puts the ref list (<local ref> <local sha> <remote ref> <remote sha>, one
39
+ # line per ref) on this process's stdin, ONCE. Two things below need it --
40
+ # rewrite-scope-check and the pg-test block gate -- and a pipe can only be read
41
+ # once, so it is captured to a file here and each consumer is fed from that
42
+ # file instead of the real stdin. Falling back to no capture (each reader gets
43
+ # whatever is left of the real stdin, i.e. nothing for the second one) rather
44
+ # than failing the push if a temp file cannot be created: this hook's job is to
45
+ # run checks, not to invent a new way to block a push that has nothing to do
46
+ # with any of them.
47
+ REFS_FILE=$(mktemp) || REFS_FILE=""
48
+ if [ -n "$REFS_FILE" ]; then
49
+ cat >"$REFS_FILE"
50
+ trap 'rm -f "$REFS_FILE"' EXIT HUP INT TERM
51
+ fi
52
+
53
+ # The rewrite-scope guard runs FIRST.
43
54
  #
44
55
  # Why it exists: a force-push can quietly add a file to a branch's change set
45
56
  # and record a stale copy of somebody else's merged work as your own change.
@@ -51,7 +62,11 @@ cd "$root" || exit 0
51
62
  # the file was the one where nothing checked. There is no absent case now --
52
63
  # the bridge resolves the script from the package -- and if the bridge itself
53
64
  # cannot run, that is a reason to stop, not to wave the push through.
54
- sh scripts/biffo.sh rewrite-scope-check || exit 1
65
+ if [ -n "$REFS_FILE" ]; then
66
+ sh scripts/biffo.sh rewrite-scope-check <"$REFS_FILE" || exit 1
67
+ else
68
+ sh scripts/biffo.sh rewrite-scope-check || exit 1
69
+ fi
55
70
 
56
71
  # --- Claim guard (#1231 instance 2) -------------------------------------------
57
72
  #
@@ -94,6 +109,42 @@ if [ -n "$branch" ]; then
94
109
  # exit 1 instead, if you would rather block than guess.
95
110
  fi
96
111
 
112
+ # --- pg-test block gate (#656) -------------------------------------------
113
+ #
114
+ # verify.sh already reports `pg-test` as `APPLICABLE BUT NOT RUN` when the repo
115
+ # has Postgres-dependent tests and no DSN reached it, and tries to provision one
116
+ # itself via `scripts/biffo.sh pg-test-db` before giving up. That is honest and
117
+ # often self-healing -- but it surfaced on a push that was ENTIRELY RLS policy
118
+ # DDL, where the lane still did not run and the push still went through amber.
119
+ # A wall of green `OK` lines does not make a person weight one amber line
120
+ # correctly at 5pm, and CI treats this lane as required, so a local pass that
121
+ # quietly skipped it is not the thing it looks like.
122
+ #
123
+ # So: if this push touches `db/imports/**` or a `*_pg.py` module -- the
124
+ # convention `scripts/pg-test-db.sh` and verify.sh's own module discovery both
125
+ # use -- and verify.sh still cannot run the lane, block rather than warn.
126
+ # `BIFFO_PGTEST_DIFF_RELEVANT=1` is how that intent reaches verify.sh; it makes
127
+ # no decision itself, `scripts/pgtest-diff-check.sh` (through the same bridge
128
+ # as rewrite-scope-check) does, from the same ref list captured above.
129
+ #
130
+ # Deliberately narrow: an ordinary frontend push touches none of those paths,
131
+ # so `pgtest-diff-check` exits 1 and nothing here changes. A repo whose
132
+ # integration branch cannot be resolved, or that got no ref list at all, exits
133
+ # 2 -- "could not tell" -- and this does NOT block on that, the same posture
134
+ # `rewrite-scope-check` and `claim.sh --guard` take on their own blind spots: a
135
+ # coordination-shaped check that fails closed on not knowing teaches people to
136
+ # route around it, which is the opposite of what a gate is for.
137
+ #
138
+ # `BIFFO_SKIP_PGTEST=1`, checked here rather than only inside verify.sh, is the
139
+ # deliberate escape hatch AGENTS.md section 7 requires for loosening a gate --
140
+ # in the open, not by reaching for `--no-verify` and skipping every other check
141
+ # too.
142
+ if [ -z "${BIFFO_SKIP_PGTEST:-}" ] && [ -n "$REFS_FILE" ]; then
143
+ if sh scripts/biffo.sh pgtest-diff-check <"$REFS_FILE"; then
144
+ export BIFFO_PGTEST_DIFF_RELEVANT=1
145
+ fi
146
+ fi
147
+
97
148
  # Through the version-pinned CLI since #1109, so a repo cannot run a gate two
98
149
  # versions old -- eight of them did, and tabsii-crm checked ONE thing in eight
99
150
  # on a 700-line change and printed `verify passed` (#855). There is one copy of
package/dist/index.js CHANGED
@@ -10849,6 +10849,13 @@ var pgTestDbCommand = packagedScriptCommand({
10849
10849
  description: "Provision the local Postgres test database and print its DSN"
10850
10850
  });
10851
10851
 
10852
+ // src/commands/pgtest-diff-check.ts
10853
+ var pgtestDiffCheckCommand = packagedScriptCommand({
10854
+ name: "pgtest-diff-check",
10855
+ script: "scripts/pgtest-diff-check.sh",
10856
+ description: "Report whether the push touches db/imports/** or a *_pg.py module"
10857
+ });
10858
+
10852
10859
  // src/commands/rewrite-scope-check.ts
10853
10860
  var rewriteScopeCheckCommand = packagedScriptCommand({
10854
10861
  name: "rewrite-scope-check",
@@ -10921,6 +10928,7 @@ program.addCommand(gateCoverageCommand);
10921
10928
  program.addCommand(runnerDropForensicsCommand);
10922
10929
  program.addCommand(hookAuditCommand);
10923
10930
  program.addCommand(pgTestDbCommand);
10931
+ program.addCommand(pgtestDiffCheckCommand);
10924
10932
  program.addCommand(rewriteScopeCheckCommand);
10925
10933
  program.addCommand(pluginCommand);
10926
10934
  program.addCommand(dataCommand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@biffo/cli",
3
- "version": "0.249.3",
3
+ "version": "0.249.5",
4
4
  "description": "Biffo project scaffolding CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -30,6 +30,7 @@
30
30
  "scripts/hook-audit.sh",
31
31
  "scripts/pg-test-db.sh",
32
32
  "scripts/rewrite-scope-check.sh",
33
+ "scripts/pgtest-diff-check.sh",
33
34
  "scripts/gate-coverage.sh",
34
35
  "scripts/verify.sh",
35
36
  "scripts/runner-drop-forensics.mjs",
@@ -0,0 +1,111 @@
1
+ #!/usr/bin/env sh
2
+ # Does the push about to happen touch the paths that make the real-Postgres
3
+ # lane matter — `db/imports/**` or a `*_pg.py` module?
4
+ #
5
+ # ## Why this exists (tabsii-platform#656)
6
+ #
7
+ # `scripts/verify.sh` already reports `pg-test` as `APPLICABLE BUT NOT RUN`
8
+ # when the repo has Postgres-dependent tests and no DSN reached it — an honest
9
+ # amber line, not a silent pass. It surfaced on a change that was ENTIRELY RLS
10
+ # policy DDL: the gate is least useful exactly where the diff most needs it,
11
+ # and a human reading a wall of green `OK` lines does not weight one amber line
12
+ # at 5pm.
13
+ #
14
+ # `verify.sh` cannot answer "is this push worth blocking over?" by itself —
15
+ # that question is about the commits being PUSHED, and a plain
16
+ # `sh scripts/biffo.sh verify` run by hand has no ref list at all. Only
17
+ # `.githooks/pre-push` sees that, on stdin, in the same
18
+ # `<local ref> <local sha> <remote ref> <remote sha>` form `rewrite-scope-check`
19
+ # reads. This script answers that one question so the hook can decide whether
20
+ # to escalate verify.sh's amber warning into a block.
21
+ #
22
+ # ## What it deliberately does NOT do
23
+ #
24
+ # It does not run the lane, provision a database, or decide whether to block —
25
+ # `verify.sh` already tries to self-provision (`scripts/biffo.sh pg-test-db`),
26
+ # and blocking is the hook's call, made by exporting
27
+ # `BIFFO_PGTEST_DIFF_RELEVANT` before `exec`ing verify. This is a narrow
28
+ # predicate: which files changed, on the paths that matter, nothing else.
29
+ #
30
+ # ## Exit codes
31
+ #
32
+ # 0 — the push touches a relevant path.
33
+ # 1 — it does not (the ordinary case; most pushes are not DDL).
34
+ # 2 — could not tell (no integration branch resolvable, no stdin, shallow
35
+ # history). Reported on stderr and treated as "do not block" by the
36
+ # caller, the same posture `rewrite-scope-check.sh` and `claim.sh --guard`
37
+ # take when their own inputs are unavailable — a coordination-shaped gate
38
+ # that fails closed on its OWN blind spot teaches people to route around
39
+ # it, and this estate has that lesson recorded more than once.
40
+
41
+ set -u
42
+
43
+ ZERO=0000000000000000000000000000000000000000
44
+ PATTERN='(^|/)db/imports/|_pg\.py$'
45
+
46
+ note() { printf 'pgtest-diff-check: %s\n' "$1" >&2; }
47
+
48
+ integration=""
49
+ for candidate in dev main master; do
50
+ if git rev-parse --verify --quiet "refs/remotes/origin/$candidate" >/dev/null 2>&1; then
51
+ integration="origin/$candidate"
52
+ break
53
+ fi
54
+ done
55
+
56
+ # Collected through a file rather than a variable, for the same reason
57
+ # rewrite-scope-check.sh does: the read loop below cannot assign to a variable
58
+ # in the parent shell once it is fed from a pipe. One line per ref: `hit` (this
59
+ # ref touches a relevant path), `indeterminate` (could not compute its range),
60
+ # or nothing (ref checked, not relevant).
61
+ RESULT_FILE=$(mktemp) || {
62
+ note "could not create a temp file - could not tell"
63
+ exit 2
64
+ }
65
+ trap 'rm -f "$RESULT_FILE"' EXIT HUP INT TERM
66
+
67
+ saw_ref=0
68
+ while read -r _local_ref local_sha _remote_ref remote_sha; do
69
+ [ -z "${local_sha:-}" ] && continue
70
+ saw_ref=1
71
+ # Branch deletion: nothing is being pushed.
72
+ [ "$local_sha" = "$ZERO" ] && continue
73
+
74
+ range=""
75
+ if [ "$remote_sha" != "$ZERO" ] && git cat-file -e "$remote_sha^{commit}" 2>/dev/null; then
76
+ # The ordinary case: compare against what the remote tip actually holds.
77
+ range="$remote_sha..$local_sha"
78
+ elif [ -n "$integration" ]; then
79
+ # A brand-new branch, or a remote tip we do not have locally (shallow
80
+ # clone, pruned object). Fall back to "everything this branch adds since
81
+ # it forked from the integration branch" — the same shape a reviewer would
82
+ # see in the PR diff.
83
+ base=$(git merge-base "$local_sha" "$integration" 2>/dev/null) || base=""
84
+ [ -n "$base" ] && range="$base..$local_sha"
85
+ fi
86
+
87
+ if [ -z "$range" ]; then
88
+ echo indeterminate >>"$RESULT_FILE"
89
+ continue
90
+ fi
91
+
92
+ if git diff --name-only "$range" 2>/dev/null | grep -qE "$PATTERN"; then
93
+ echo hit >>"$RESULT_FILE"
94
+ fi
95
+ done
96
+
97
+ if [ "$saw_ref" -eq 0 ]; then
98
+ note "no ref list on stdin - could not tell"
99
+ exit 2
100
+ fi
101
+
102
+ if grep -qx hit "$RESULT_FILE" 2>/dev/null; then
103
+ exit 0
104
+ fi
105
+
106
+ if grep -qx indeterminate "$RESULT_FILE" 2>/dev/null; then
107
+ note "could not resolve one or more refs' range - could not tell"
108
+ exit 2
109
+ fi
110
+
111
+ exit 1
package/scripts/verify.sh CHANGED
@@ -757,6 +757,39 @@ elif [ -z "$PG_TEST_DSN" ]; then
757
757
  "CI runs these as a required check; nothing local is checking them."
758
758
  printf ' \033[90m%s\033[0m\n' \
759
759
  "set BIFFO_TEST_PG_DSN, or run scripts/pg-test-db.sh if this repo ships one"
760
+
761
+ # --- Block on a relevant diff (tabsii-platform#656) --------------------
762
+ #
763
+ # The line above is honest -- it says NOT RUN, not passing -- but that is
764
+ # not enough on its own: it does not block, and a wall of green `OK` lines
765
+ # trains a reader not to weight one amber line correctly. It surfaced on a
766
+ # push that was ENTIRELY RLS policy DDL, exactly the diff this lane exists
767
+ # to check.
768
+ #
769
+ # `BIFFO_PGTEST_DIFF_RELEVANT` is set by `.githooks/pre-push`, never by a
770
+ # developer -- it is the hook's answer to "does this push touch
771
+ # db/imports/** or a *_pg.py module?", computed from the actual ref list
772
+ # via `scripts/pgtest-diff-check.sh`. A plain `sh scripts/biffo.sh verify`
773
+ # run by hand therefore stays advisory, exactly as before: this variable is
774
+ # only ever present when the hook itself decided the diff warranted it.
775
+ #
776
+ # `BIFFO_SKIP_PGTEST` is checked again here, not only in the hook, so this
777
+ # is provable by driving verify.sh directly (see verify-pg-lane.test.ts)
778
+ # and so a developer who sets it before invoking verify.sh by hand gets the
779
+ # same escape hatch the hook advertises.
780
+ if [ -n "${BIFFO_PGTEST_DIFF_RELEVANT:-}" ] && [ -z "${BIFFO_SKIP_PGTEST:-}" ]; then
781
+ FAILED="$FAILED pg-test-required"
782
+ printf '\n'
783
+ printf ' \033[31mBLOCKED\033[0m: this push touches db/imports/** or a *_pg.py module, and\n'
784
+ printf ' the pg-test lane above did not run. CI treats it as a required check, so a\n'
785
+ printf ' push here would report green without having checked the thing most likely\n'
786
+ printf ' to need it.\n\n'
787
+ printf ' Get a DSN and re-run:\n'
788
+ printf ' eval "$(sh scripts/pg-test-db.sh --export)" # if this repo ships one\n'
789
+ printf ' export BIFFO_TEST_PG_DSN=postgresql+asyncpg://user:pass@host:port/db\n\n'
790
+ printf ' Deliberate escape hatch, printed rather than silent (AGENTS.md section 7):\n'
791
+ printf ' BIFFO_SKIP_PGTEST=1 git push ...\n\n'
792
+ fi
760
793
  fi
761
794
  elif ! command -v uv >/dev/null 2>&1; then
762
795
  skip pg-test "uv not installed"