Skip to content

History rewrite: consumer repos record subconscious SHAs as build provenance, and those records are now unresolvable #74

Description

@iceteaSA

Re-fork done on my side, and the rewrite is behaviourally clean — this is about a class of stale record it leaves in other repos, several of which you own.

Confirmed: recorded subconscious SHAs in consumer repos are now orphaned

cortexkit/cerebellum records its subconscious build provenance in a tracked file at origin/main:

subconscious-source.txt   ->  three SHAs, all now unresolvable against master

Filed there as cerebellum#12. The pattern is not specific to that repo — any consumer that pins or records a subconscious SHA for build provenance has the same stale record, and the sibling-checkout recipes documented across the fleet encourage exactly that. Worth a sweep of the repos you own rather than waiting for each to notice.

The bundle makes these recoverable, so this is a migration chore rather than data loss. But the records currently look valid — which is the part that bites.

The failure mode is orphaned-not-gone, and every cheap check passes

git cat-file -e <old-sha>                        succeeds
gh api repos/cortexkit/subconscious/commits/<old-sha>   200
git merge-base --is-ancestor <old-sha> origin/master    FAILS

A module pinned to a pre-rewrite SHA resolves it, fetches it, builds successfully, and is compiling history master no longer contains — silently, until GC removes the dangling objects and the same pin hard-fails with no intervening change. git fetch reports nothing wrong.

The check that actually answers it:

git merge-base --is-ancestor <sha> origin/master || echo ORPHANED

Caveat worth carrying with that line: in a shallow clone an unresolvable SHA means "my clone never had this object", not "gone from the remote". One seat nearly reported two SHAs as GONE when their clone was 129 commits deep against 2497. test -f .git/shallow before concluding anything is missing. My own sweep was on a full clone, which is why I trust its output.

Re-derivation is mechanical, if anyone needs old→new

Subject + author-date to find the candidate, then git patch-id --stable to confirm the diff is byte-identical:

078e877 -> 6b07ed4    #61 DAEMON_ORIGIN Phase 1
e71d189 -> 6ddbfab    #59 provenance merge
30c90ee -> 86953f3    daemon build point

One trap in that method: git diff-tree -p emits nothing for a merge commit, so a naive patch-id comparison returns two empty strings that compare equal — an all-clear from a check that examined nothing, which is precisely #72's shape. Merges need -m --first-parent.

One place the rewrite touched a shipped surface

ck-subc declares its own build commit through the provenance plane, and that declaration is a subconscious SHA. My running daemon:

DAEMON BUILD
  COMMIT: 30c90eed779e...        <- orphaned as of the rewrite
  RUNNING IMAGE: match (linux_proc_sha256)

Module declarations name their own repos and are unaffected; the daemon is the one component the rewrite can invalidate this way. The declaration is still honest — it names the commit that produced the running bytes — but nothing in the render distinguishes "commit you can check out" from "commit that survives only in a dangling object and the bundle". A verifier taking the obvious path gets a failure that looks like a provenance defect and is actually a rewritten upstream.

It clears on the next daemon rebuild, so no code change is needed. It may deserve a line in the provenance doc: a declared SHA is resolvable until someone rewrites history, and the declaration cannot know. Happy to write that if you want it — it is the same shape as everything else the plane has surfaced, a value whose validity depends on a condition it does not disclose.

My status

Fork master force-updated to the rewritten tip, all 12 stale branches deleted, local branches and remote-tracking refs pruned, tooling rebuilt on the new history (the skew detector caught my stale ck immediately). No open PRs of mine were in flight, and all nine merged contributions verified present in the rewritten history by content.

One thing I could not do: gh lacks delete_repo and refreshing that scope needs an interactive browser flow, so I force-reset the fork's refs rather than deleting the repo. Nothing pre-rewrite is reachable from any ref on it — but unreachable is not deleted, and the objects persist in the fork network until GC. If you want the fork genuinely gone I will re-clone once it is deleted.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions