HOMELAB-2682: feat(forgejo): full head/base sha in forgejo_get_pr #102
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "plane/HOMELAB-2682-get-pr-sha"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Why
forgejo_get_prreturned no head sha at all. A merge session told to verify theexact head could not do it through the tool: the census shows 7 characters, the
branch list 8, and this tool nothing. On 2026-11-05 one session reached for
curlwith its own token to readhead.sha— this PR closes thatimprovisation path, so no session needs a credentialed fetch to verify a head.
What
Head sha:/Base sha:lines near the top of the output, carrying the API'sfull 40-hex commit id. The API response already carried
head.sha/base.sha, so this is purely presentational — no new request, no new field inthe API layer.
NOT a full 40-hex commit id …/UNKNOWN …), never passed off as the exact head. Silence here is whatsends a session to curl.
parse the text);
detailsstill carries the whole PR.description+promptSnippet+docs/forgejo.mdnow say a mergesession verifies the exact head through this tool.
Sample output (fixture PR):
Tests
forgejo/tests/get-pr-sha.test.ts(5 tests): full 40-hex values, labelledand above the rest of the details, existing fields unchanged, short sha flagged,
absent sha
UNKNOWN(neverundefined).diff_url/patch_url, so the default fixture no longer models an invalid sha.Not merged here: one normal review seat follows.
Verdict of record — ld-reviewer — head
af31b2f5e3: APPROVEmodel: deepseek-flash
session: 01a1adbd-114b-757a-b84d-278b581280e3
Blockers
None.
What I verified on this head
Head sha:/Base sha:lines built frompr.head?.sha/pr.base?.sha, which the existingGET /repos/{o}/{r}/pulls/{n}payload already carries (PullRequest→PRRef.sha: string); no new request, no API-layer field. Live read of PR 102 confirms the payload answershead.sha=af31b2f5e37751579825a42a0b142c039e3b09bc(40 hex) andbase.sha=271a523f1912a0d027c38f5ad586ccda4ebaf5d5(40 hex), so the tool will print the exact head verbatim.State:,Author:,Mergeable:,URL: … | Diff:, the description block, the unparseable-ref early return, anddetails(raw PR) are byte-identical tomain. No caller parses by line position — grep across this repo,~/repos/lab-director,spec/andmemory/finds no positional reader of theforgejo_get_prtext; in-repo consumers (tests/merge-identity.test.ts) readdetails, which is untouched. The fixture gainingdiff_url/patch_urlfixes a fixture that was modellingDiff: undefined.forgejo/tests/get-pr-sha.test.ts(5 tests) asserts the fixture values are 40-hex, that the rendered text contains the full value (a slice would fail), that no 7-char truncation is emitted, that the lines sit aboveState:/Author:and each is one line, thatdetails.head.sha/details.base.shastill carry full values, that a short sha is flaggedNOT a full 40-hex commit id, and that an absent sha isUNKNOWNrather thanundefined.docs/forgejo.mdtool table now states the full 40-hexHead sha:/Base sha:and that this is how a merge session verifies the exact head with nocurland no token of its own;description+promptSnippetagree; the natural-language router string atindex.ts:1374is unchanged, so routing still works.npm ci && npm run typecheck && npm test→ typecheck clean, 27/27 files, 707/707 tests.npm run test:deployed→[deployed-shape] ok: 27/27 files loaded and passed, 707/707 tests, pinned tree typebox 1.3.34. Reproduced, matches the PR body.forgejo,forgejo-ci,pi-swarm-suite,plane,redact, …); run #307pythonsuccess. Remote branch tip is the reviewed sha.Concerns
~/.pi/agent/extensions/forgejo/index.tsstill has noshaLine(no occurrence of it), so until the extension is re-synced a session still sees no sha and the improvisation path stays open. Whoever lands this should ensure the drop is refreshed before the docs claim is relied on.Base sha:reads "do not treat this as the exact head". Accurate for the head line, slightly off for the base line. Cosmetic; not worth a fix round.shaLinevalidates case-insensitively but prints the value verbatim; harmless for the forge's lowercase ids, noted only so the asymmetry is deliberate.Nothing here blocks: the change is presentational, additive, pinned by a test, documented, and green in both shapes plus CI.
Verdict of record — ld-reviewer — head
af31b2f5e3: APPROVEmodel: deepseek-flash
session: 1fc90a52-16c2-4d47-9d28-2b8fb27f4c4f
Blockers
None.
What I verified on this head (independent seat 2 of 2, dangerous class)
shaLine(index.ts:186-197) formatspr.head?.sha/pr.base?.sha;PRRef.shais a requiredstringin the type (types.ts:139-144) andgetPR(api.ts:1314-1324) is an unchanged singleGET repos/{o}/{r}/pulls/{n}. A live read of PR 102 returnshead.sha=af31b2f5e37751579825a42a0b142c039e3b09bcandbase.sha=271a523f1912a0d027c38f5ad586ccda4ebaf5d5, both 40 hex, so the tool prints the exact head with no derivation of its own.docs/forgejo.md,forgejo/index.ts,forgejo/tests/fake.ts,forgejo/tests/get-pr-sha.test.ts. Inindex.tsthe additions are one regex constant, one pure string-formatting function, two appended lines to the display array, and the tool'sdescription/promptSnippettext. No new request, no newfetch, no header construction touched (headers()unchanged), andlanding.ts/verdict.ts/api.tsare untouched — nothing on the merge, lock or credential paths moves.State:; the title line,State:,Author:,Mergeable:,URL: … | Diff:, the description block, the unparseablerepo_refearly return anddetails(the raw PR) are byte-identical tomain. I grepped the package for a positional reader of this tool's text and found none — the only in-repo consumer readsdetails(tests/merge-identity.test.ts:183). The fixture gainingdiff_url/patch_urlis test-side: with the old fixture that line renderedDiff: undefined.shaLineto interpolatevalue.slice(0, 7)and rannpx vitest run tests/get-pr-sha.test.ts: 3 of 5 tests failed (thetoContain('Head sha: <full 40>')assertion and the^Head sha: [0-9a-f]{40}$multiline match). I then restored the file and confirmed the worktree is clean and ataf31b2f5e37751579825a42a0b142c039e3b09bc(git status --porcelainempty).tsc --noEmitexit 0;vitest run27/27 files, 707/707 tests;bash scripts/test-in-deployed-shape.sh→[deployed-shape] ok: 27/27 files loaded and passed, 707/707 testson the pinned tree typebox 1.3.34. CI on this head: run #306 all 15 jobs success, run #307 success.FORGEJO_API_KEY: not equal, never printed), matching the convention that every suite carries its own fake; traffic is a route-tablemockFetch, so the suite makes no network call and reads no credential.Concerns
~/.pi/agent/extensions/forgejo/index.tshas zero occurrences ofshaLine, so a session using the extension as deployed still sees no sha and the improvisation this PR closes stays open until that drop is re-synced. The landing step should confirm the drop is refreshed.Base sha:line reads oddly. Cosmetic.shaLinetests the value case-insensitively but prints it verbatim, so an uppercase-hex answer would be flagged as short. Theoretical for this forge; noted so the asymmetry is deliberate.forgejo/tests/formal-review-fake.ts:123still modelssha: "base000", the same invalid-sha modelling this PR cleans up infake.ts. That suite does not render this tool's text, so nothing breaks; it is fixture tidiness.Nothing here blocks: the change is additive and presentational, the sha is the API's own full value, a test pins it against truncation, docs agree, and both test shapes plus CI are green on the reviewed head.