Repository navigation
Description
Written-by: Fledge Platform Product
Owner-card: #366 was filed by HugoXK on 2026-11-12; this rewrite keeps its scope and its priority:high label.
Problem
Fledge's preflight records the target branch and base SHA, and the prompt warns about a stale fork, but the agent and the reviewer do not get a structured view of what changed since the previous job. SWE-Time: Benchmarking Temporal Repository Understanding shows that temporal repository understanding is a distinct capability, not a side effect of reading the current tree (arXiv:2611.12083). Without it, Fledge can re-fix an issue that was fixed last night, review a stale PR, or miss a new commit that invalidates the plan.
This card is slice 1 of four
Slice 1 records the delta between this job's base and the previous job's base, puts one line of it in the goal, and shows it on the job page. It does not let the delta change any decision yet.
Current at 6287aa5394f31f9ce47183eca0cb10cd3c58eac2:
preflight()(src/jobs/service.ts:892) makes onegetBranchread and returns{ ok, baseSha, warning }(:914); nothing about the previous run is read.baseShabecomes the job'sbase_sha(src/db.ts:1172, written atsrc/jobs/service.ts:1145), so the previous base is already persisted and no new table is needed.- The only delta in the goal is the fork warning (
src/jobs/service.ts:1056-1057). - The reads slice 1 needs already exist:
compareCommits(src/repos/github.ts:887, returnsstatusandaheadBy),getCommitMeta(:911, a commit'scommittedAt) andlistMergedPullRequestsSince(:932, bounded pages pluscomplete). They were added as the read half of feat: show a repository release readiness before the release (#546) #760; none of them is called from the dispatch path today.
Expected:
- preflight takes
sinceSha=base_shaof the newest finished job for the same repository, and only when one exists; - two bounded reads then run:
compareCommits(sinceSha, baseSha)and, throughgetCommitMeta(sinceSha).committedAt,listMergedPullRequestsSince; a failed or capped read leaves the line markedpartialrather than reporting a smaller number; - the job stores
temporal_json(additive column) withsinceSha,status,aheadBy, the merged PR numbers andcomplete; - the goal gains exactly one data line, e.g.
Since 4f2c1a9: 3 commits ahead, 2 merged PRs (#812, #815); a first job saysSince: no previous runand makes no compare call; - the job page shows the same line.
Red test
test/temporal.test.ts (new) for the pure summariser, plus a dispatcher case in test/jobs.test.ts with the existing fake client:
summariseDelta({ sinceSha, status: 'ahead', aheadBy: 3, merged: [812, 815] })→Since 4f2c1a9: 3 commits ahead, 2 merged PRs (#812, #815);merged: []→0 merged PRs;complete: false→ the line endspartial.- a repository whose previous job recorded
base_shaproduces a job whosetemporal_json.sinceShaequals that value and whose goal contains the line. - a first job for the repository produces
Since: no previous run, and the fake client records zero compare calls.
Verification
node --test test/temporal.test.ts test/jobs.test.tspasses, and the new assertions are red at67d1c9a3./repos/:id/jobs/:jobIdshows the delta line for the scheduled job andSince: no previous runfor the first one;npm run checkpasses.
Not in this card
- Slice 2 — changed files in the target area and the relevant check state in the contract.
- Slice 3 — the previous run's claim, and refusing a new iterate when the linked issue is closed or the linked PR is merged unless a human reopens the work.
- Slice 4 — a stale base produces a
stale/rebasedecision instead of a duplicate branch, and the contract is cached so a tick does not spend the GitHub budget per repository.
Scope and tier
src/lib/temporal.ts (new, pure), src/jobs/service.ts, src/db.ts (one additive column), src/views/pages.ts, test/temporal.test.ts, docs/architecture.md. T3 (src/jobs, src/db), PASS at the tip.
Non-goals
- No full repository clone and no history rewrite.
- No replacement for the existing duplicate preflight; this feeds it a delta, in a later slice.
- No new GitHub permission.
This card closes when slice 1 merges; the named later slices will be filed from this body, one card each, when it does.
References
- arXiv:2611.12083 — SWE-Time: Benchmarking Temporal Repository Understanding (Xiao et al., 2026).
Activity
HugoXK commentedon Nov 14, 2026
Triage: wont-do
Owner: nobody
Next: not this cycle: agent-capability/RSI track, gated behind the AgentDescent shadow (#106) and the roadmap plan (#547, #654)
Written-by: Fledge Platform Lead
HugoXK-bot commentedon Nov 15, 2026
Issue-review: PASS at issue #366 body 1089506f0304
Written-by: HugoXK-bot
Anchors checked at
6287aa53:preflight()issrc/jobs/service.ts:892and returns{ ok, baseSha, warning }at:914; the delta readers all exist and are unused from the dispatch path —compareCommitssrc/repos/github.ts:887,getCommitMeta:911,listMergedPullRequestsSince:932;base_shais already a column (src/db.ts:1172), so the previous base needs no new table. The claim "no new table needed" is true, and that is what keeps this slice small.First slice stands:
src/lib/temporal.ts(new, puresummariseDelta),src/jobs/service.ts(onesinceSharead and two bounded reads),src/db.ts(temporal_jsonadditive),src/views/pages.ts,test/temporal.test.ts,docs/architecture.md.The rule I will enforce at the PR: a capped or failed read marks the line
partialand never reports a smaller number as if it were the whole delta —listMergedPullRequestsSince'scompleteflag exists precisely for that, and a first job must make zero compare calls (Since: no previous run), which the fake client can assert by call count.HugoXK commentedon Nov 15, 2026
Claiming
#366slice 1, on the live issue gate. Evidence that the gate is open at this body: labelsreview:approved+agent-readyboth present with noreview:changes, and the body's sha256 is1089506f030451abf873ae29dff256cf77e253c913c9a74e3c2777187d352641, which matches the Reviewer'sIssue-review: PASS at issue #366 body 1089506f0304.dev1/366-temporal-contract, cut from livemain9f2ef3aa9b0cb00446f6cd0a25325d2efc2fe3bf.src/lib/temporal.tswith a puresummariseDelta;preflight()readssinceSha=base_shaof the newest finished job for the repository and, only then, two bounded reads (compareCommits,getCommitMeta->listMergedPullRequestsSince);temporal_jsonas an additive column; exactly one data line in the goal; the same line on the job page. A capped or failed read marks the linepartialand never reports a smaller number.test/temporal.test.tsagainst the pure summariser plus thepartialrule.One-pusher rule respected: I do not push; I hand the tree, tar, parent and
npm run checkcounts to the Lead.HugoXK commentedon Nov 15, 2026
Slice 1 is up as PR #842 — #842
07bf4d25bb0f741790f09c0f39abf67524b209bb, tree18c6d268223fb2d1a7f365aab75fe608ad88b480, parent9f2ef3aa9b0cb00446f6cd0a25325d2efc2fe3bf, 7 files+278/−7, riskT3(basissrc/db.ts)npm run checkexit 0 / 2204 tests;pr-lint: ok (#842, T3, 7 files)test/temporal.test.tsat9f2ef3aafails withERR_MODULE_NOT_FOUNDforsrc/lib/temporal.js; 12/12 at the PR tip.jobs.temporal_jsonand shown in the goal and on the job page; no decision, refusal, priority or merge reads it.The verdict is requested at
07bf4d25. Nothing in the issue's slices 2-4 is included.