# Response: "sgit-ai 0.25.0 in the newsroom, first morning" (conductor@php.newsroom, 26 Oct 2026), cli.sgit.ai

> The CLI team's answer to the newsroom's first morning on 0.25.0: the first status after a fresh clone read every file back from a slow disk (18 minutes); every write sgit makes now seeds the scan cache, and a pull of a whole pass went from 566 s to 31.7 s.

*Source: <https://cli.sgit.ai/research/newsroom-first-morning-response.html> · generated from the same content as the page, so the two cannot drift. Published from <https://github.com/SGit-AI/SGit-AI__CLI/blob/09172b0f3e50fc15712e7418ce8c46b56416d832/team/humans/dinis_cruz/claude-code-web/10/26/response__newsroom-first-morning-on-0-25-0.md>.*

---
# Response: "sgit-ai 0.25.0 in the newsroom, first morning" (conductor@php.newsroom, 26 Oct 2026)

**Brief:** `2026-10-26__brief__for-the-sgit-cli-team-0-25-0-in-the-newsroom.md`.
**In one line:** items 1, 3 and 5 are fixed on the branch (the first command after a fresh clone no longer reads
the files it just wrote; `sgit version` names a shadowing install); item 2, the pull of a whole pass, is measured
below with where the time goes and what is fixed now versus next; item 4 needs nothing.

## 1. The first `status` after a clone (items 1 and 3)

**What it was doing.** Exactly what the brief suspected: reading every file's content where a stat would do. The
scan cache (0.25.0) records a file only when a scan has hashed it, and a fresh clone has no scan behind it, so the
first status read all 4.2 GB back from the session's scratch disk. The researcher's 11 s and the curator's 18 min
on the same vault are the same read on two disks: 19.6 s user + 41.5 s sys is the hashing and the syscalls; the
17 minutes between is the disk. The correspondent's 226 s on the read-only clone is the same read (a read-only
pull's dirty-tree check scans the working copy).

**What changed.** sgit wrote those files itself, so it knows their hashes. Every working-copy write — clone
extraction, pull, read-only pull, branch switch, history edits, scope widening — now records each file in the scan
cache under the hash of the bytes written (the real hash of the plaintext, never the tree entry's claim, which is
only what the committer said). The next status, commit or pull stats the file and moves on. Two details:

- the racy rule still holds: a scan that starts within two seconds of the write reads the file, and keeps the
  record when the hash it computes is the recorded one, so a status immediately after a clone is not the one
  that throws the seed away;
- a full clone now extracts through the flat map and writes the head's flat cache, so that first status opens
  no tree either (the tree walk through the schema was the other half of the researcher's 11 s).

**Measured** on the synthetic vault (228,000 files, 305,230 objects, in-memory host, a fast local disk):

| | before | after |
| --- | --- | --- |
| clone | 275 s | 216 s |
| first `status` after the clone | 20.1 s (every file read and hashed) | 8.2 s |
| second `status` | 7.4 s | 6.5 s |

Here the disk is fast, so "before" is the hashing; on the curator's session it was the 18 minutes. The clone
itself also writes the scan cache in the same pass (a hash per file as it is written, no second read).

**Lazily or in the background?** Not needed once the seed exists, and a lazy build would be wrong: a status
must know whether a file changed, and only a hash (or a record of what sgit wrote) can say so. The one case left
is a clone made by 0.24.x or 0.25.0 and then upgraded: its first status still reads everything once. Agents on
fresh containers never hit that.

## 2. The pull of a whole pass (item 2)

**Measured** on the synthetic vault (228,000 files), a 300-file pass pushed from one clone and pulled in another,
under cProfile: **566 s before, 31.7 s after.** Where the 566 s went, and what changed:

| Cost | Before | Cause | Now |
| --- | --- | --- | --- |
| the fetch's tree walk | 347 s (154,454 tree loads through `Type_Safe.from_json`) | every tree of the new head was opened to find what was missing, twice | the walk does not open a folder of the head this clone last accepted (that record is written only once every object of the head was local), and the trees it does open are read as JSON: 8 trees opened for a two-leaf change on a 24-tree test vault |
| writing the working copy | 171 s (229,310 files written for 301 changed) | the merge checked out the whole merged tree | only the files whose blob changed are written |
| flattening the new head | ~45 s | a full walk, the cache being for the old head | the new head's map is built by copying the unchanged folders from the cached old head |

What is left in the 31.7 s is the vault's size, in seconds: the dirty-tree scan (15 s, one `lstat` per file over
228k files), the missing-blob check (6 s, `exists` over 235k ids) and pruning empty folders after deletes (5 s).
On the curator's clone, the 8 minutes also held the disk writes of 6,807 files, which stay.

## 3. `sgit version` and a shadowing install (item 5)

`sgit version` now prints a note when the `sgit` first on the PATH is another program, with that one's version
when it answers:

```
sgit-ai 0.25.1
note: the `sgit` first on your PATH is /usr/local/bin/sgit (sgit-ai 0.24.0), not this one
      (/home/agent/.venv/bin/sgit). Commands typed as `sgit` run that one; upgrade it too, or put this one first on the PATH.
```

It compares the resolved paths and, failing that, the entry scripts' bytes, so a venv's `sgit` and the same
script reached through another path are not reported as two installs. Only `sgit version` checks (every command
would cost a PATH search and a subprocess per invocation); the wake step that runs `sgit version` first gets it.

## 4. Commit and push (item 4)

Nothing to do: 25 s and 67 s for phase 1 of a pass on 79,000 files, 4 s and 16 s for phase 2, are the branch
working as intended, and the 35-minute pass is the capture. If a pass ever shows a commit back above a minute on
a small change, send the run record: that would be the incremental build missing a case.

## 5. Files

`sgit_ai/core/Vault__Sync__Base.py` (`_checkout_flat_map` seeds; `_scan_cache_seed`; a confirmed seed survives a
racy scan), `sgit_ai/workflow/clone/Step__Clone__Extract_Working_Copy.py` (flat-map extraction, flat cache
written, a refused tree still refuses the clone), `sgit_ai/storage/Vault__Sub_Tree.py` (the flat cache is written
through to a vault that has none), `sgit_ai/cli/CLI__Main.py` (`cmd_version`, `path_shadow_note`). Tests:
`tests/unit/sync/test_Vault__Sync__Scan_Cache__Seeded_On_Write.py`, `tests/unit/cli/test_CLI__Version__Path_Note.py`.

---

*[Site index for agents](../llms.txt) · [HTML version](https://cli.sgit.ai/research/newsroom-first-morning-response.html)*
