The head is a bare token, and its commits live in the tree - #4
Merged
Merged
Conversation
A commit head is now a bare PushDrop coin with six fields — the five it had plus a branched-from outpoint — and nothing inscribed on the output. The commits moved into the published root: git's tree for the tip commit plus a `.git` object store holding every commit reachable from it, named by sha, with a `.` entry pointing at the tip. The five-field head with an inscribed commit is a different format and no longer decodes; there is no migration path and the test suite pins the refusal. `lib/gib-head.ts` decodes the bare token, tolerating the raw-byte forms the stack's reference encoder writes as well as the text ones this site writes, and reads the commit from the root instead of the output. `/me` is the one place that needed it: it decodes the wallet's own basket coins, so it now walks root → `.git` → `.` through ORDFS in a second query keyed on the roots. That keeps the page's whole point — it is a gateway read, not a gib overlay round trip, so a head no indexer has seen still shows its commit. Server-rendered pages read the commit off the overlay's head record, which carries what it read out of `.git` at admission, and did not change. Branched-from is the second parent, so the site can finally show what it never could: with a spend it is a merge, without one it is where a branch began. Both are badged in the push list and named on the head page, where the source head is resolved so it links under its own repository origin. `.git` is gib's, not the project's. Every listing a user sees passes through `withoutGitStore`, and the tree and blob routes refuse a path that starts with it. The store is read on purpose in exactly one place, with a light manifest read rather than `loadDirectory`: a store names every commit in the history, and enriching all of it with bulk metadata to read one entry would be absurd. Branches now come from the overlay's BRC-24 `branches` lookup rather than from guessing. It is the only source that says which branches exist per publisher, which ones nobody extends any more, and which branch a clone starts from — `.gib`'s defaultBranch is a label its publisher wrote, and this is what the chain shows. The REST branch heads stay as the fallback when the lookup cannot answer, and as the source of the commit authors the handle labels are verified against. Nothing indexes a head off the chain any more: the gib module has no queue, no event bridge and no feed, so a head that is minted and not submitted is on chain and invisible. `mintHead` therefore hands the transaction to `tm_gib` over BRC-22 with the transactions admission needs to read the push — the root, its `.git` store, and the branched-from head — as a BEEF V2 with the head last. A failed submission is not a failed mint, so it is reported as such rather than thrown. Branching is now a single wallet call: it points at the same root, which already carries the commit, and names the head it came from. Nothing is fetched and nothing is republished. The new format is not on api.1sat.app yet, so the tests build the shapes themselves: heads locked exactly the way `mintHead` locks them, encoded `ordfs/dir` manifests behind a stubbed fetch, a stubbed `ls_gib` answering with the double-encoded `result` the Go service serializes, and real transactions for the submission ordering. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01EM5trZ4BfZpW7pBjq2onqX
AGENTS.md carried the five-field head with an inscribed commit as the data model, which is no longer true anywhere. It now describes the bare six-field token, the `.git` object store and the rule that nobody browsing a repository sees it, the branched-from discriminator, the BRC-24 lookups and why only `branches` is wrapped here, and the submission — including that `@1sat/client`'s `OverlayClient` cannot serve it, because its submit hard-codes `/1sat/overlay/submit` while gib's engine is mounted at `/1sat/gib/overlay`. That belongs in the SDK as a path the caller picks. The "two wallet calls, one of which costs money" hazard is gone: branching no longer fetches a commit object first. In its place is the one that replaces it — a commit the overlay does not hold is normal, because a push may cite an object already on chain rather than republish it. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01EM5trZ4BfZpW7pBjq2onqX
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This branch was successfully deployed
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.
Makes the site correct against gib's new head format (1sat-stack#55,
feat/gib-head-v2).Do not merge before the stack deploys. The new format is not on api.1sat.app yet; merging this deploys a site that decodes nothing the live overlay serves.
The format
A commit head is a bare PushDrop coin — nothing inscribed on the output — with six fields: the five it had plus a branched-from outpoint. The commits moved into the published root: git's tree for the tip commit plus a
.gitobject store holding every commit reachable from it, named by sha, with a.entry pointing at the tip. The old five-field head with an inscribed commit is a different format and no longer decodes;lib/gib-head.test.tspins the refusal.Where the repositories page gets its commit
/medecodes the wallet's own basket coins, and its whole point is that it works with no gib overlay at all. So it reads the commit from the tree, not from the overlay's head record: a second react-query walksroot → .git → .through ORDFS, keyed on the roots, so the branch list renders from the token immediately and the subjects fill in. Going to/1sat/gib/head/{outpoint}would have been one fetch instead of two and would have made "my repositories" depend on an indexer having caught up — which is exactly what that page exists to avoid.Server-rendered pages did not need to change: the overlay's head record carries the tip commit it read out of
.gitat admission.Branched-from
The second parent, which the site has never been able to show. With a spend it is a merge; without one it is where a branch began. Badged in the push list, and named on the head page as merged in or branched from — where the source head is resolved so the link goes under its own repository origin rather than an assumed one.
Branches from the chain
lib/gib-lookup.tswraps the BRC-24branchesquery. Every page renderingRepoHeaderfetches it: it is the only source that says which branches exist per publisher, which ones nobody extends any more (spent, shown in the picker), and which branch a clone starts from..gib'sdefaultBranchis a label its publisher wrote;branches.defaultBranchis the genesis push's branch. Preference order is lookup →.gib→ themain/masterguess, and the REST branch heads remain the fallback when the lookup cannot answer.headsSinceandtxsare not wrapped — they are what a client cloning a repository needs, and this site browses through ORDFS..gitwas not hiddenIt is now. Every listing a user sees passes through
withoutGitStore, and the tree and blob routesnotFound()a path starting with.git. The store is read on purpose in one place, with a light manifest read rather thanloadDirectory: a store names the whole history, and enriching thousands of entries with bulk metadata to read one would be absurd.Beyond the brief: submission
The stack's
feat/gib-head-v2removes the event bridge, the queue and the JungleBus subscription —pkg/gib/README.md, "a head arrives by submission or not at all". Nothing indexes a head off the chain any more, so the Branch button would have minted coins nobody could ever see.mintHeadnow hands the transaction totm_gibover BRC-22 with what admission needs to read the push (the root, its.gitstore, the branched-from head), as a BEEF V2 with the head last. A failed submission is not a failed mint and is reported as such.@1sat/client'sOverlayClientcould not serve this: itssubmithard-codes/1sat/overlay/submit, and gib's engine is mounted at/1sat/gib/overlay. Worth adding to the SDK as a path the caller picks.BRC-169
Untouched. Verification is still per head against the identity that signed the head being viewed; the commit simply arrives from the tree or the overlay record instead of the token.
Tested against
Fixtures and local fakes, since production serves the old format:
mintHeadlocks them, with and without branched-from, plus the raw-byte outpoint and identity forms the stack's reference encoder writes, and the legacy inscribed head asserted to be refused;ordfs/dirmanifests behind a stubbedfetch, for the.gitwalk and the filters;ls_gibanswering with the double-encodedresultstringpkg/gib/lookup_sync.goserializes, including the empty-repository and 500 cases;bun run lint,bun run typecheck,bun test(55) andbun run buildare clean.One contradiction worth flagging
The gib CLI's
internal/tokenis still the five-field format with the inscribed commit, and AGENTS.md says that if the site and that package disagree, the site is wrong. Here the stack is the authority and the CLI has not caught up — so the CLI needs the same change before a browser-minted head and a CLI push are indistinguishable again.🤖 Generated with Claude Code
https://claude.ai/code/session_01EM5trZ4BfZpW7pBjq2onqX