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
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# fsck extracts — load-bearing matches with context
# Source: `git fsck --full --no-progress 2>&1 | grep <obj> -C 5` (reflog-inclusive)
# Captured 2026-04-29 (Day 3 corruption triage)

## Reflog-inclusive fsck — context for 8d5e67fd
error: inflate: data stream error (incorrect data check)
error: corrupt loose object '8d5e67fd313573855848705e4af114f3ff0eecbc'
error: unable to unpack contents of .git/objects/8d/5e67fd313573855848705e4af114f3ff0eecbc
error: 8d5e67fd313573855848705e4af114f3ff0eecbc: object corrupt or missing: .git/objects/8d/5e67fd313573855848705e4af114f3ff0eecbc
error: inflate: data stream error (incorrect data check)
error: cannot unpack 9bf2daee3ce53c88633824f9532a0158aaa92ed9 from .git/objects/pack/pack-16732bccb3ace9ec45c913c57a1fd050fd730c3f.pack at offset 4973478
dangling blob 1f003ef9077ba9779af779c18efa3ff5a6f39470
dangling commit 2a00a9f5168ddfd359f62f2e274cb768159f9014
dangling blob e20172cea3dd96f93dc3004d5ebc7eb137693701
--
dangling commit 795b1d3a5b7c5379cd6a1ad8419f0a5e9535c476
dangling commit b55b5628445f31bb2f1df636859915daef5be582
dangling tree f65bb21a7409dcdadb9ee6e8f02f1c0d07c93a96
dangling commit 6e5c40364b078f5a947bf79d9cc9540c3ae940e7
dangling tree ba5cc0356d2b571ba19477f5be8c16e15993faf6
missing blob 8d5e67fd313573855848705e4af114f3ff0eecbc
dangling commit 385f12ddc72e05da9be752c5a5acc53ba472bb90
dangling commit c95f5c65cbae62fd249fedb38c9e45d59260d061
dangling tree 78606cccb9ba0693d61a3cad81d71b05727ddf2f
dangling commit a1605b88ddb8dd3543610235c585b1372f1eaba4
dangling commit f5609f368a7e17ba22224eec4bbc715ba3c6f4dc

## Reflog-inclusive fsck — context for 9bf2daee
error: inflate: data stream error (incorrect data check)
error: corrupt loose object '8d5e67fd313573855848705e4af114f3ff0eecbc'
error: unable to unpack contents of .git/objects/8d/5e67fd313573855848705e4af114f3ff0eecbc
error: 8d5e67fd313573855848705e4af114f3ff0eecbc: object corrupt or missing: .git/objects/8d/5e67fd313573855848705e4af114f3ff0eecbc
error: inflate: data stream error (incorrect data check)
error: cannot unpack 9bf2daee3ce53c88633824f9532a0158aaa92ed9 from .git/objects/pack/pack-16732bccb3ace9ec45c913c57a1fd050fd730c3f.pack at offset 4973478
dangling blob 1f003ef9077ba9779af779c18efa3ff5a6f39470
dangling commit 2a00a9f5168ddfd359f62f2e274cb768159f9014
dangling blob e20172cea3dd96f93dc3004d5ebc7eb137693701
dangling tree fa019e9576ad659d4a75caf4599d831ee4df415b
dangling tree 490275af8f57e4fac5e77d026c4b47f97e81bf27

## --no-reflogs fsck — context for 8d5e67fd
error: inflate: data stream error (incorrect data check)
error: corrupt loose object '8d5e67fd313573855848705e4af114f3ff0eecbc'
error: unable to unpack contents of .git/objects/8d/5e67fd313573855848705e4af114f3ff0eecbc
error: 8d5e67fd313573855848705e4af114f3ff0eecbc: object corrupt or missing: .git/objects/8d/5e67fd313573855848705e4af114f3ff0eecbc
error: inflate: data stream error (incorrect data check)
error: cannot unpack 9bf2daee3ce53c88633824f9532a0158aaa92ed9 from .git/objects/pack/pack-16732bccb3ace9ec45c913c57a1fd050fd730c3f.pack at offset 4973478
dangling blob 1f003ef9077ba9779af779c18efa3ff5a6f39470
dangling commit 2a00a9f5168ddfd359f62f2e274cb768159f9014
dangling commit 9f01f442e7362a9efcd6fc7b1c87fed41eb4146f
--
dangling tree f65bb21a7409dcdadb9ee6e8f02f1c0d07c93a96
dangling commit 6e5c40364b078f5a947bf79d9cc9540c3ae940e7
dangling commit 8d5ca82de7eaa851a12c952ef9ae162ee675581a
dangling tree ba5cc0356d2b571ba19477f5be8c16e15993faf6
dangling commit 9d5db210aee2b017e99c8d2c78f77242fb24ec0b
missing blob 8d5e67fd313573855848705e4af114f3ff0eecbc
dangling commit be5ed39f8f223aac1149a287fa8f24e3a94c52ae
dangling commit e15e99645306000c5f9d6ee549b8bdff88069a71
dangling commit fc5ec3b3552af63e82f8f9992a3d1fdcd7931c6e
dangling commit 145ff57c8a073d0fc8ff11dece9ac7e492c85adc
dangling commit 255ff59fc67565e9be345b810aa2b784360c7887

## --no-reflogs fsck — context for 9bf2daee
error: inflate: data stream error (incorrect data check)
error: corrupt loose object '8d5e67fd313573855848705e4af114f3ff0eecbc'
error: unable to unpack contents of .git/objects/8d/5e67fd313573855848705e4af114f3ff0eecbc
error: 8d5e67fd313573855848705e4af114f3ff0eecbc: object corrupt or missing: .git/objects/8d/5e67fd313573855848705e4af114f3ff0eecbc
error: inflate: data stream error (incorrect data check)
error: cannot unpack 9bf2daee3ce53c88633824f9532a0158aaa92ed9 from .git/objects/pack/pack-16732bccb3ace9ec45c913c57a1fd050fd730c3f.pack at offset 4973478
dangling blob 1f003ef9077ba9779af779c18efa3ff5a6f39470
dangling commit 2a00a9f5168ddfd359f62f2e274cb768159f9014
dangling commit 9f01f442e7362a9efcd6fc7b1c87fed41eb4146f
dangling blob e20172cea3dd96f93dc3004d5ebc7eb137693701
dangling commit e5019d81cf9d549bfeee9c6751f7c8d5911af94f

## Connectivity-only fsck — context for 8d5e67fd
(no match)

## Connectivity-only fsck — context for 9bf2daee
(no match)

## Mode-comparison summary
fsck-full (reflog-inclusive) line count: 627
fsck-full-no-reflogs line count: 1116
fsck-connectivity line count: 620

(Mode-dependent reachability: --no-reflogs reports MORE objects as
dangling because reflog-tip commits no longer count as reachable.)
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# git gc + rerere config snapshot — 2026-04-29 corruption triage
# (read-only inspection; no mutation)

git version = git version 2.54.0

gc.auto = (unset; default ~6700)
gc.autoPackLimit = (unset; default 50)
gc.pruneExpire = (unset; default 2.weeks.ago)
gc.reflogExpire = (unset; default 90.days.ago)
gc.reflogExpireUnreachable = (unset; default 30.days.ago)
gc.worktreePruneExpire = (unset; default 3.months.ago)
gc.rerereResolved = (unset; default 60.days)
gc.rerereUnresolved = (unset; default 15.days)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# git ls-remote --heads origin chore/heartbeat-batch-2026-04-26-hour-05Z
# Captured 2026-04-29 (Day 3 corruption triage)
#
# Result: empty (no output below this header).
#
# Empty output proves origin no longer has the branch
# `refs/heads/chore/heartbeat-batch-2026-04-26-hour-05Z`.
# The same-named local remote-tracking ref under
# `refs/remotes/origin/chore/heartbeat-batch-2026-04-26-hour-05Z`
# is therefore stale (preserved evidence, not origin recovery).
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
d9feb3f08603e37118491e26527c03e6e5760d5b refs/heads/chore/heartbeat-batch-2026-04-26-hour-05Z
d9feb3f08603e37118491e26527c03e6e5760d5b refs/remotes/origin/chore/heartbeat-batch-2026-04-26-hour-05Z
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# rev-list extracts — load-bearing matches only
# Source: `git rev-list --objects --all | grep <obj>`
# Captured 2026-04-29 (Day 3 corruption triage)

## Matches for 8d5e67fd313573855848705e4af114f3ff0eecbc
8d5e67fd313573855848705e4af114f3ff0eecbc docs/hygiene-history/loop-tick-history.md

## Matches for 9bf2daee3ce53c88633824f9532a0158aaa92ed9
9bf2daee3ce53c88633824f9532a0158aaa92ed9 docs/category-theory/ctfp-milewski.pdf
220 changes: 220 additions & 0 deletions docs/lost-substrate/artifacts/2026-04-29-corruption/triage-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
# Corruption triage — 2026-04-29 — empirical artifact

This file captures the exact commands run, the raw outputs (in
sibling files), and the conclusion drawn. It exists so a future
reader can verify the prose conclusions in the ledger against the
artifacts, rather than trusting the summary.

## Sibling artifact files (load-bearing extracts only)

Per Aaron 2026-04-29 (the repo is the soulfile — keep it
clean): only the **load-bearing extracts** are committed,
not the raw multi-MB diagnostic dumps. The grep recipes that
produce these extracts are below; future readers can re-run
locally to regenerate the raw outputs if needed.

| File | Source command (extract-recipe in re-run section) |
|---|---|
| `fsck-extracts.txt` | grep -C 5 of corrupt SHAs against `git fsck` outputs in three modes (reflog-inclusive / `--no-reflogs` / `--connectivity-only`) plus per-mode line-counts to evidence mode-dependence |
| `rev-list-extracts.txt` | grep of corrupt SHAs against `git rev-list --objects --all` |
| `git-gc-config.txt` | git version + per-key `git config --get gc.*` + `gc.rerereResolved` / `gc.rerereUnresolved` snapshot |
| `hour-05Z-show-ref.txt` | `git show-ref \| grep hour-05Z` |
| `hour-05Z-ls-remote.txt` | `git ls-remote --heads origin hour-05Z` (empty = origin no longer has the branch) |
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Query exact ref when proving remote branch absence

The stale-ref conclusion is keyed to hour-05Z-ls-remote.txt, but this source-command row uses git ls-remote --heads origin hour-05Z, which is a pattern query, not an exact ref lookup. git ls-remote patterns are glob-matched against ref tails, so this can match multiple branches that end with hour-05Z; a non-empty result would not prove the specific chore/heartbeat-batch-2026-04-26-hour-05Z branch still exists. For corruption triage, that ambiguity can misclassify a remote-tracking ref as current vs stale.

Useful? React with 👍 / 👎.


All files are point-in-time evidence; do not edit.
Comment thread
AceHack marked this conversation as resolved.

### Re-run recipe (regenerates raw outputs locally)

If a future reader wants the raw multi-MB dumps (this file
intentionally does not commit them — see Aaron's
soulfile-cleanliness rule), run from repo root:

```bash
mkdir -p /tmp/corruption-triage-raw
git fsck --full --no-progress > /tmp/corruption-triage-raw/fsck-full.txt 2>&1
git fsck --full --no-reflogs --no-progress > /tmp/corruption-triage-raw/fsck-full-no-reflogs.txt 2>&1
git fsck --connectivity-only --no-progress > /tmp/corruption-triage-raw/fsck-connectivity.txt 2>&1
git rev-list --objects --all > /tmp/corruption-triage-raw/rev-list-all-objects.txt 2>&1
ls -la /tmp/corruption-triage-raw/
```

The raw outputs are reproducible from any clone with the same
local refs at the same point in time. Committing the extracts
preserves the load-bearing evidence; committing the raw dumps
would dirty the soulfile.

## Two corrupt objects under triage

| SHA | Type | Size | Source path |
|---|---|---|---|
| `9bf2daee3ce53c88633824f9532a0158aaa92ed9` | blob (recovered from origin) | 16,455,417 bytes | unknown — large blob |
| `8d5e67fd313573855848705e4af114f3ff0eecbc` | blob (corrupt loose, locally) | unrecoverable from origin | `docs/hygiene-history/loop-tick-history.md` (intermediate version) |

## Three-bucket reachability — `8d5e67fd`

Per Amara 2026-04-29: `git fsck` reachability is mode-dependent
(reflog-inclusive vs `--no-reflogs`). A correct classification
distinguishes three buckets:

| Bucket | Definition | Verdict for `8d5e67fd` |
|---|---|---|
| A | Live branch / tag / ref reachable | **YES** — `refs/heads/chore/heartbeat-batch-2026-04-26-hour-05Z` reaches it (local-only; the same-named remote-tracking ref is stale — origin no longer has the branch) |
| B | Reflog / stash / local-recovery reachable | Indeterminate from this scan; reflog scan was reflog-inclusive fsck (showed dangling adjacency); `refs/stash` is empty |
| C | Dangling / unreachable only | **NO** — bucket A applies, so C does not |

### Verifying bucket A

```text
$ git rev-list --objects --all | grep 8d5e67fd
8d5e67fd313573855848705e4af114f3ff0eecbc docs/hygiene-history/loop-tick-history.md

$ git for-each-ref ... | per-ref rev-list grep
ref=refs/heads/chore/heartbeat-batch-2026-04-26-hour-05Z → reaches it
ref=refs/remotes/origin/chore/heartbeat-batch-2026-04-26-hour-05Z → reaches it (stale)
```

### Verifying the remote-tracking ref is stale

```text
$ git ls-remote origin refs/heads/chore/heartbeat-batch-2026-04-26-hour-05Z
(empty — origin no longer has this branch)

$ git clone --no-checkout --quiet \
--branch chore/heartbeat-batch-2026-04-26-hour-05Z \
https://github.com/Lucent-Financial-Group/Zeta.git \
/tmp/repo-fresh-corruption-recheck-2026-04-29
fatal: Remote branch chore/heartbeat-batch-2026-04-26-hour-05Z not found in upstream origin
```

### Content-equivalence verification — `8d5e67fd`

Per Amara's correction: verify squash-preservation by **content**,
not by ancestry vibe.

```text
$ BR=refs/heads/chore/heartbeat-batch-2026-04-26-hour-05Z
$ OBJ=8d5e67fd313573855848705e4af114f3ff0eecbc

$ git ls-tree -r "$BR" | grep "$OBJ"
(no path-match — corrupt blob is NOT at the branch tip)

$ git show "$BR":docs/hygiene-history/loop-tick-history.md | head -1
# Loop-tick history ← branch tip's tick-history.md is readable

$ git diff --name-status origin/main..."$BR" \
-- docs/hygiene-history/loop-tick-history.md
M docs/hygiene-history/loop-tick-history.md ← diff succeeds

$ git log --oneline -1 "$BR"
d9feb3f chore(loop-tick-history): hour-05Z bundle close 2026-04-26T05:59:36Z ...
```

**Branch tip is clean.** The corrupt blob `8d5e67fd` is from
the branch's **intermediate history** (an earlier commit on the
same branch path), NOT the current tip. The branch is also NOT
an ancestor of `main` (its tip is post-squash-merge and
abandoned), and `main` carries the equivalent content under a
different blob (`de670f72d6fd34208d04863818288d764150a151`).

```text
main's tick-history blob: de670f72d6fd34208d04863818288d764150a151
branch-tip's blob: (different, clean — readable via git show)
corrupt blob: 8d5e67fd313573855848705e4af114f3ff0eecbc
← appears only in intermediate history
```

## Final classification — `8d5e67fd`

```text
CORRUPT_BLOB_REFERENCED_BY_LIVE_LOCAL_BRANCH_AND_STALE_REMOTE_TRACKING_REF
```

(sub-bucket of bucket A under the three-bucket schema; refined
sub-condition: branch TIP is clean, corrupt blob is in
intermediate history of the branch only.)

Substrate-loss assessment:

- **Current-state use** (checkout / hard-reset-to-tip / diff vs
main): zero impact. Branch tip and main are both readable.
- **Bisect-through-pre-merge-history**: impacted. Bisecting
`loop-tick-history.md` through this branch's intermediate
revisions would surface the corrupt blob; that pre-merge
bisect-step granularity is the only thing actually lost,
and it's a niche use case for a stale post-merge local
branch.

## Hard-reset readiness — qualified statement

```text
This corruption does not appear to affect current main, but it
DOES affect at least one live local branch (specifically, the
intermediate history of refs/heads/chore/heartbeat-batch-2026-
04-26-hour-05Z). Hard reset / branch cleanup remains blocked
until the branch's content is classified as preserved,
obsolete, or explicitly abandoned.
```

Branch-tip checkout / hard-reset-to-tip is fine. Reading
intermediate-history blobs would surface the corruption.

## Stale remote-tracking ref — evidence, not origin recovery

```text
$ git show-ref | grep 'chore/heartbeat-batch-2026-04-26-hour-05Z'
d9feb3f08603e37118491e26527c03e6e5760d5b refs/heads/chore/heartbeat-batch-2026-04-26-hour-05Z
d9feb3f08603e37118491e26527c03e6e5760d5b refs/remotes/origin/chore/heartbeat-batch-2026-04-26-hour-05Z
↑ same SHA → ref is stale, not authoritative

$ git ls-remote --heads origin chore/heartbeat-batch-2026-04-26-hour-05Z
(empty — origin no longer has this branch)
```

The remote-tracking ref is **stale** — origin deleted the
branch (presumably after squash-merge), but the local repo
still carries the same-named ref under
`refs/remotes/origin/...`. This stale ref is evidence about
the prior state of origin; it is NOT proof origin currently
has the object. Do not prune it during triage — `git fetch
--prune origin` and `git remote prune` would remove it, and
that's a destructive cleanup decision under the same rule as
GC.

```text
Stale remote-tracking ref is evidence, not origin recovery.
Do not prune it while investigating lost substrate.
```

## Cleanup posture

```text
Cleanup is a destructive decision, not a repair step.
```

`git gc` / `git prune` / `git repack -Ad` / `git fsck --lost-found`
remain forbidden during triage. Auto-gc thresholds are at default
(per `gc-config-snapshot.txt`); below-threshold loose-object count
Comment thread
AceHack marked this conversation as resolved.
Comment thread
AceHack marked this conversation as resolved.
means auto-gc is not imminent, but the discipline is "no implicit
cleanup decision" not "we have time."

A future cleanup may remove this unreachable/corrupt evidence, so
cleanup must wait until related dangling/reflog/stash surfaces
are classified and either preserved or explicitly abandoned.

## Composes with

- `docs/lost-substrate/inventory-ledger-2026-04-29.md` — the
inventory ledger that surfaced these findings.
- `memory/feedback_corruption_triage_discipline_object_health_incident_aaron_amara_2026_04_29.md`
— the durable discipline rule.

## Distilled keepers (Amara 2026-04-29)

```text
A corrupt object is not a backlog item — it is a substrate health incident.
Do not prune the evidence while investigating lost evidence.
Recoverable-from-origin requires fresh-clone cat-file type + size verification.
Cleanup is a destructive decision, not a repair step.
Corruption lane means exclusive lane.
If corruption is the incident, everything else is noise.
```
Loading
Loading