Repo · motir-core. One PR. Filed as the DEFERRAL card for the indexer's cost, which the engine-fairness story explicitly puts out of scope. It is related_to that story and blocked by nothing — the two are independent.
Measured, production, 2026-08-28 (job_run, read inside the Fly machine):
system.code-graph-refresh runs for moooon-B-V/motir-core: 2 058–2 116 s each, back to back 07:12→10:50.output.projectsIndexed: 2.moooon-B-V/motir-ai took 226 s and for moooon-B-V/motir-meta 60 s, both also at projectsIndexed: 2.Read in the code (origin/main):
lib/jobs/indexFleetSteps.ts:243 — for (const projectId of target.projectIds), i.e. one container per (repo × project), supervised sequentially.dispatchInput differs in exactly ONE field, projectId. repoOwner, repoName, repoRef, defaultBranch, installationId and workspaceId are identical, so the same tree is cloned and parsed twice.lib/jobs/definitions/codeGraphRefresh.ts states a refresh is a full whole-tree rebuild and has always been one.Measured on a developer box, 2026-08-20, codegraph CLI 1.1.6 — a reading with a subject and a date, NOT a property of the fleet container, and to be re-taken before it is relied on:
| operation | wall |
|---|---|
motir-core index --force (full) | 32.0 s |
motir-core sync, 10 changed files | 0.7 s |
motir-core sync, 2 481-file stale diff | 38.2 s |
1 — Why is the parse duplicated per project? The graph is a property of the repository at a ref, and the ledger already treats it that way: one job_run per repo with one output.repoRef. If the per-project fan-out exists for tenancy of the PUBLISHED index rather than of the parse, then parse once and publish per project — which halves the work by construction and makes the sequential-vs-parallel question disappear. Settle this before optimising anything, because the answer may remove the second question.
2 — Where does the rest of the time go? 32 s of measured parse against ~2 100 s of production wall clock leaves ~98% unaccounted for. Instrument before fixing: the admission backoff, the boot/provision, the tarball fetch, and the poll-to-detect lag (indexPollWaitMs backs off to a 15 s cap, so detection alone costs up to 15 s per container). Do not assume which dominates.
codegraph sync exists and is dramatically cheaper on a near-current graph. It has no caller: motir-ai's diff path GraphIndexPublisher.refresh was deleted on 2026-08-05 (MOTIR-2145) and the container runs a whole-tree build. Reaching it needs the prior .codegraph/codegraph.db carried or fetched as a base, and a "changed > X% of tree ⇒ full rebuild" threshold for the measured crossover. Worth doing for the fleet CPU it stops burning — not for latency, since per the numbers above the parse is a small share of the wall clock.
job_run and quoted.codeGraphIndexAdmissionService's cap before it is made, and the card says what that cap permits.codegraph sync is either reached, with a stated full-rebuild threshold and a re-taken measurement on the CONTAINER rather than a developer box, or explicitly deferred to its own card with the reason.lib/jobs/indexFleetSteps.ts — the sequential per-project loop and the ledger contract.lib/jobs/definitions/codeGraphRefresh.ts — the whole-tree-rebuild statement and its history.lib/services/codeGraphIndexDispatchService.ts — indexPollWaitMs, the admission backoff, MAX_POLL_ITERATIONS.lib/services/codeGraphIndexAdmissionService.ts — the cap any parallelisation must respect.system.code-graph-refresh failing ~32% on admission deferral; the same subsystem, a different symptom.