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
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@ regression.out
.pgc_source_stamp.*
__pycache__/
*.pyc

# Git bundles. A transfer artifact, not a build one: they are how a change gets from
# a container to a clone, they are named after whatever branch was in flight, and
# nothing ever reads them again. Nine of them rode into c697c8cd under `git add -A`.
*.bundle
33 changes: 33 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -1979,6 +1979,39 @@ true until the next version shipped.
than replace it, so each renamed line still matches its own old form. Anchoring on the
closing quote gives 1, which is the one that matters.

- Nine git bundles are out of the tree, `*.bundle` is ignored, and
`310-a-compiled-artifact-must-not-be.sh` now covers transfer artifacts as well as
compiled ones.

**I put them there.** 76,194 bytes across nine files went into `c697c8cd` -- a merged
commit whose subject is a check name in `sorted_pathkeys.sh`. I create bundles in my clone
to move a branch into the audit container, and I staged with `git add -A`. That is the
same mechanism the existing comment in part 310 calls out for a stray `.pyc`: *a tracked
build artifact joins whichever commit is next.*

**Nothing caught it.** Five suites and the whole selftest ran green either side, because
no suite has an opinion about files it does not read. What found it was a later rebase
printing the filenames in a list I happened to read.

Part 310's scope note said Python only, and deferred the wider question:

> Whether every derived file in the tree deserves one rule is a larger judgement and is
> deliberately not decided here.

This decides it for one more class, and only that class. **A bundle is a transfer
artifact**, which is why it belongs beside the `.pyc` rather than beside the Parquet
fixtures: it is derived from commits already in the history, it is named after whatever
branch was in flight, nothing in the tree opens one, and the next person to make one will
choose a different name -- so it can never become a fixture anything depends on.

Same two-part rule, same `no-repo` discipline as the Python arms, and a control: a source
file merely *named* like a bundle (`test/bundle_notes.sh`) must not be ignored, or the
suffix rule is broader than it claims.

The blobs stay reachable in the repository's history -- removing a file from the tree does
not unwrite it, and rewriting `main` is not something a stray artifact justifies. What this
stops is the tree carrying them, and the next `git add -A` re-adding them.

## [1.0-alpha3] - 2026-09-02

### Added
Expand Down
Binary file removed b983.bundle
Binary file not shown.
Binary file removed b983r.bundle
Binary file not shown.
Binary file removed b990.bundle
Binary file not shown.
Binary file removed b991.bundle
Binary file not shown.
Binary file removed b993r2.bundle
Binary file not shown.
Binary file removed b995.bundle
Binary file not shown.
Binary file removed b997r.bundle
Binary file not shown.
Binary file removed b998.bundle
Binary file not shown.
Binary file removed b998b.bundle
Binary file not shown.
4 changes: 4 additions & 0 deletions test/check_ledger.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,13 @@ harness_selftest 300-a-test-script-must-be-runnable premise: the documents name
harness_selftest 300-a-test-script-must-be-runnable premise: the sourced parts are inside the population, not pruned never -
harness_selftest 300-a-test-script-must-be-runnable premise: the sweep reads a population of scripts, not an empty find never -
harness_selftest 310-a-compiled-artifact-must-not-be and a compiled artifact written beside its source never -
harness_selftest 310-a-compiled-artifact-must-not-be and the tracked BUNDLE list names none of them never -
harness_selftest 310-a-compiled-artifact-must-not-be and the tracked list names none of them never -
harness_selftest 310-a-compiled-artifact-must-not-be and the tree ignores a git bundle, so the next add cannot re-add it never -
harness_selftest 310-a-compiled-artifact-must-not-be and the tree ignores the directory Python writes them to never -
harness_selftest 310-a-compiled-artifact-must-not-be control: a source file named like a bundle is not ignored never -
harness_selftest 310-a-compiled-artifact-must-not-be no compiled Python artifact is tracked never -
harness_selftest 310-a-compiled-artifact-must-not-be no git bundle is tracked never -
harness_selftest 310-a-compiled-artifact-must-not-be premise: and git ls-files sees the harness it is being asked about never -
harness_selftest 310-a-compiled-artifact-must-not-be premise: and that a tracked source file is not never -
harness_selftest 310-a-compiled-artifact-must-not-be premise: check-ignore agrees a build object is already ignored never -
Expand Down
2 changes: 1 addition & 1 deletion test/check_ledger_budget.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@ suites_not_covered 250
# Without that it is a hand-maintained count that drifts, which is the failure
# this repository has spent a day proving. It is not a ceiling; it is a
# measurement that must be true.
checks_never_observed_red 909
checks_never_observed_red 913
66 changes: 59 additions & 7 deletions test/selftest/310-a-compiled-artifact-must-not-be.sh
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,27 @@
# writes a one-line gitfile into the build dir, which
# costs no bytes and makes the question answerable. ok
#
# SCOPE. Python only. The tree tracks Iceberg .avro/.puffin and Parquet
# fixtures, which are inputs rather than output and are meant to be there;
# .gitignore already covers the C artifacts (*.o, *.so, *.bc). Whether every
# derived file in the tree deserves one rule is a larger judgement and is
# deliberately not decided here.
# SCOPE. Python artifacts, and git bundles. The tree tracks Iceberg
# .avro/.puffin and Parquet fixtures, which are inputs rather than output and are
# meant to be there; .gitignore already covers the C artifacts (*.o, *.so, *.bc).
# Whether every derived file deserves one rule is still a larger judgement and is
# still not decided here.
#
# THE SECOND CLASS WAS ADDED THE SAME WAY AS THE FIRST: expensively. Nine git
# bundles, 76,194 bytes, went into c697c8cd -- a merged commit whose subject is a
# check name in sorted_pathkeys.sh. I made them in my clone to move a branch into a
# container and then staged with `git add -A`, which is the same mechanism the
# comment above calls out for the .pyc: a tracked artifact joins whichever commit is
# next. Nothing caught it. Five suites and the whole selftest ran green either side,
# because no suite has any opinion about files it does not read.
#
# A BUNDLE IS A TRANSFER ARTIFACT, which is why it belongs with the .pyc and not
# with the Parquet fixtures. It is derived from commits that are already in the
# history, it is named after whatever branch was in flight, nothing in the tree
# opens one, and the next person to make one will give it a different name -- so it
# can never be a fixture somebody depends on. The same two-part rule therefore
# applies: not tracked, and ignored, because ignoring is what stops the deletion
# being undone by the next `git add -A`.

_pyc_root="$(cd "$PGC_TESTDIR/.." && pwd)"
_pyc_repo="$(git -C "$_pyc_root" rev-parse --is-inside-work-tree 2>/dev/null || echo no)"
Expand All @@ -71,6 +87,11 @@ _pyc_ignored() { # _pyc_ignored PATH -> ignored | not-ignored | no-repo
git -C "$_pyc_root" check-ignore -q -- "$1" && echo ignored || echo not-ignored
}

_pyc_bundles() { # -> the tracked git bundles, or `no-repo`
[ "$_pyc_repo" = true ] || { printf 'no-repo'; return; }
git -C "$_pyc_root" ls-files -- '*.bundle' | sort | tr '\n' ' '
}

# PREMISE. git has to be able to answer, and it has to be answering about THIS
# tree.
check_text "premise: the source tree is a git checkout" "$_pyc_repo" "true"
Expand Down Expand Up @@ -122,5 +143,36 @@ check_text "and the tree ignores the directory Python writes them to" \
check_text "and a compiled artifact written beside its source" \
"$(_pyc_ignored test/x.pyc)" "ignored"

unset _pyc_root _pyc_tracked _pyc_repo
unset -f _pyc_tracked_list _pyc_ignored
# ---- and a transfer artifact is the same rule, for the same reason ------------

# Counted rather than compared against an empty string: `check_text` refuses a side
# that is empty, because "nothing was compared" and "the two agreed" are the same
# observation otherwise. My first version of these three arms compared against "" and
# all three were refused on exactly that ground -- the harness catching an arm that
# asserted nothing.
_pyc_bund="$(_pyc_bundles)"
check_text "no git bundle is tracked" \
"$([ "$_pyc_bund" = no-repo ] && echo no-repo \
|| printf '%s tracked' "$(printf '%s' "$_pyc_bund" | wc -w)")" \
"0 tracked"
# Named for the thing it lists, not "them": the Python half four arms up already owns
# `and the tracked list names none of them`, and the ledger's duplicate-name detector
# caught the collision on the first merge -- `distinct checks this merge=866` against
# `checks run=867`. #982's defect, created in the session that finished removing the
# last of its 24 instances.
check_text "and the tracked BUNDLE list names none of them" \
"[${_pyc_bund}]" "[]"

# The other half, as for the .pyc: without the ignore rule the deletion lasts until
# the next `git add -A` in a clone where somebody has moved a branch about.
check_text "and the tree ignores a git bundle, so the next add cannot re-add it" \
"$(_pyc_ignored some-branch.bundle)" "ignored"

# CONTROL. The rule keys on the SUFFIX, so a source file merely named like one must
# not be swept up -- and without this, a check-ignore answering "ignored" to
# everything would make the arm above vacuous.
check_text "control: a source file named like a bundle is not ignored" \
"$(_pyc_ignored test/bundle_notes.sh)" "not-ignored"

unset _pyc_root _pyc_tracked _pyc_repo _pyc_bund
unset -f _pyc_tracked_list _pyc_ignored _pyc_bundles
Loading