Skip to content

chore: burn down the repository's measured slow, dead, and quietly broken parts - #241

Merged
gcko merged 10 commits into
mainfrom
chore/repo-diagnostic-cleanup
Aug 29, 2026
Merged

chore: burn down the repository's measured slow, dead, and quietly broken parts#241
gcko merged 10 commits into
mainfrom
chore/repo-diagnostic-cleanup

Conversation

@gcko

@gcko gcko commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Summary

A diagnostic pass over the repository for slow code, slow CI, and dead or inefficient code, then the fixes that survived adversarial verification.

Method. Eight finders ran one diagnostic dimension each and produced 37 findings. Every finding then faced three independent verifiers prompted to refute by default, each on a different lens: does it reproduce in the code, does the cost actually matter, and is the proposed fix safe against this repository's invariants. Majority-refute killed the finding. 15 of 37 were refuted and thrown away. The survivors were then reproduced by hand before anything was changed, which is where two more died and one was corrected.

Nothing here touches cargento_runtime/web/, so no frontend byte pins move and this does not consume the one-PR-per-web/ budget.

What was measured

before after
unittest discover, dashboard suite 59.5s 38.1s
bench_collect, total collect 146.2ms 131.8ms
bench_collect, Claude collector 123.9ms 110.0ms

The suite figure is local-only: a CI runner's home holds no agent stores, so CI will not see it. The collect figures are on the poll path, which runs on a 2.5s floor while a session is writing.

Three things were broken and nothing said so

  • python3 scripts/validate_plugins.py failed on clean main. The canonical pre-PR check walked every Markdown file under docs/, and 56 of the 78 there are gitignored: vendored Spacedock mods, the entity-state orphan-branch worktree, and local deep-dive notes. It died on a vendored template's unexpanded {state-owner} placeholders. CI never saw it because that directory is never checked out, so the red belonged to no change and pointed at no fix. Confirmed pre-existing by stashing and running main directly.
  • scripts/bench_collect.py crashed on startup with AttributeError: 'Namespace' object has no attribute 'host'. Its hand-built Namespace was never extended when cli.build_runtime grew four arguments. test_bench_collect passes because it exercises the helpers, not main(). The design docs name this script as how collection cost is measured, so the one tool for answering "is this slower now?" could not start.
  • scripts/tests/test_bench_event_latency.py was never run by CI. Seven modules on disk; the test and runtime-floor jobs each named six. AGENTS.md carries it in the canonical pre-PR list, so the gate was weaker than the document it is measured against. It costs 0.05s.

The rest

  • The suite read the developer's real HOME, so any test collecting without a store patch swept their actual ~/.claude (24,981 files here). Speed was the smaller half: a suite whose result depends on what your other agents were writing while it ran is not measuring what it claims to.
  • The Claude collector re-stat'd transcripts it had already stat'd, and built the pending-member roster for every prefix on disk before the activity gate discarded it.
  • The Cursor collector asked exists(wal) then getmtime(wal), both under the db's error handler, so a WAL checkpointed away mid-read dropped the whole chat row. Fixed, with a regression test verified to fail against the old collector.
  • runtime-floor was the only one of five setup-python calls without cache: pip, while installing the heaviest requirements file.
  • validate was the only job with no timeout-minutes, so a hang held a required check pending for six hours.
  • Dead: observer.read_sidecar (the only one of 254 public runtime definitions with zero references anywhere) and spacedock.stage_names. Three shipped plan docs, 2,592 lines, that open by telling an agent to execute their 114 unchecked task boxes.

Deliberately not done

  • The larger Claude collector restructuring. Skipping the per-session subagent walk for prefixes outside the window is real and measured, but it carries a behaviour trade around subagents running longer than the window. It deserves its own PR and its own measurement.
  • Removing coverage from runtime-floor. There is a fair argument the threshold belongs to the test job alone. But AGENTS.md says it only ratchets up, and removing one of the two places it is enforced is a decision about strictness, not a defect.
  • The Codex double-walk and the discover() existence globs. Both survived verification. Codex is 4.8ms of a 131ms collect and the fix adds a cache field to state.py, a known conflict surface; the discover() change touches five files for under a millisecond. Filed rather than bundled.
  • Six live worktrees, one locked. Left alone: a sibling session may be mid-flight, and AGENTS.md records a worktree cleanup destroying work once.

Refuted, for the record

Among the 15: that the platform-tests ubuntu leg duplicates the test job (it does not, it alone proves the suite passes with no dev tooling installed, and removing it would save zero wall clock since Windows at 119s is the long pole); that validate.yml re-running the suite is a real cost; and that assign_display_ids rebuilds a loop-invariant set that matters.

Test plan

  • Ran the pre-PR suite in AGENTS.md § Pre-PR Checks (ruff, ruff format, mypy, lint_embedded.py, validate_plugins.py, bump_version.py --current, dashboard tests under coverage via discovery) and it is clean. 2,006 tests plus 192 script tests, coverage 90.3% against a threshold of 73
  • Preserved Python 3.11 compatibility; no syntax newer than the floor
  • Invoked the sync-docs skill — it found the deleted plans fully dereferenced, the command lists already linking to AGENTS.md rather than duplicating, and one real defect of its own: its tone check globbed docs/plans/*.md including untracked local notes, reporting drift in somebody's scratch. Now scoped to tracked files. COMPATIBILITY.md's sync marker deliberately untouched, per the parallel-branch rule
  • Behavior changes include a regression test — the Cursor WAL race, verified to fail against the pre-fix collector (1 != 0) and pass after
  • No version field was touched; checked against the merge base, not just five-way parity
  • Commits are signed off (DCO)
  • Native validators run locally: claude plugin validate --strict and agy plugin validate both pass

gcko and others added 10 commits August 29, 2026 11:55
Three findings from a repository diagnostic, each reproduced before it was acted
on.

`scripts/tests/test_bench_event_latency.py` was never executed by CI. Seven test
modules live under `scripts/tests/`; the `test` and `runtime-floor` jobs each
named six. AGENTS.md carries it in the canonical pre-PR list, so the gate was
weaker than the document it is measured against. It costs 0.052s. Its one real
timing assertion is a lower bound on an elapsed wait, so load can only make it
more true - safe on a shared runner.

`.claude/worktrees/` was ignored only through `.git/info/exclude`, which is
per-clone and uncommitted. Its sibling `.worktrees/` was already in the tracked
file. A fresh clone therefore searches its own worktrees, and every repo-wide
grep returns each hit once per checkout - measured here while chasing an
unrelated symbol.

`read_sidecar` in observer.py had no caller anywhere: of 254 public definitions
in the runtime it was the only one with zero references outside its own
definition. `write_sidecar` stays - http_api.py calls it and returns the result
directly rather than reading back, which is how the reader was orphaned.
`state_read_cap_bytes` keeps its consumer in lifecycle.py.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Jared Scott <jared.scott@variable.team>
The canonical pre-PR validator walked every Markdown file under `docs/`, and
most of them are not source. 56 of the 78 present here are gitignored: the
vendored Spacedock mods, the linked worktree holding the entity-state orphan
branch, and a person's local deep-dive notes.

That made `python3 scripts/validate_plugins.py` fail on clean `main` for anyone
with the mods installed, on a vendored template's unexpanded `{state-owner}`
placeholders. CI never saw it, because the directory is gitignored and is never
checked out - so the red belonged to no change and pointed at no fix.

Filtered with `check-ignore` rather than `ls-files`, so a doc that is merely new
is still validated before it is staged. Fails open: any git error validates
everything, which is exactly the behaviour it replaces.

Verified by injecting a broken link into a tracked doc and confirming the
validator still fails on it.

AGENTS.md's Quality Gate sentence described the 3.11 job as a direct-launch
smoke test. It also runs the whole suite under coverage on that floor, so an
agent reading the sentence would underestimate what has to pass there.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Jared Scott <jared.scott@variable.team>
`support.py` already seeds CARGENTO_HOME into the process environment, and the
comment there explains why: unset, the suite reads the developer's real
~/.cargento and its verdict depends on what they happen to have dismissed.

The same argument applies one level up and was never made. Harness store roots
resolve from the user's home, not from CARGENTO_HOME (config.py:403 reads
USERPROFILE on Windows and HOME everywhere else), so every test that collects
without patching a store walked the developer's real ~/.claude, ~/.codex and
~/.cursor. On this machine that is 24,981 files under ~/.claude/projects alone.

Measured on the same command, `unittest discover` over the dashboard tests:
59.5s before, 38.1s after. 2,005 tests, green both ways. Per module the effect
tracks how much collecting each one does: test_quota 4.63s -> 1.69s,
test_lifecycle 8.04s -> 4.97s, test_http_api 11.34s -> 8.96s.

CI will not see that gain - a fresh runner's home holds no agent stores - so
this is a local-developer and local-agent saving. The hermeticity half applies
everywhere: a suite whose runtime and whose result both depend on what the
developer's other agents were writing while it ran is not measuring what it
claims to.

A second temp directory rather than reusing STATE_HOME, because the two answer
different questions: a test that redirects CARGENTO_HOME itself must still see
an empty harness home rather than the state it just pointed elsewhere.

This also subsumes the separate `_clean_env` fix in test_lifecycle: that helper
copies os.environ, which now carries the seeded HOME before it is read.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Jared Scott <jared.scott@variable.team>
…low edits

`validate` was the only job in the repository with no `timeout-minutes`, so it
inherited GitHub's 360-minute default. Its longest step is the same `unittest
discover` that AGENTS.md records hanging on subprocess and socket waits under
load, and it is a required check - so a hang held the PR pending for six hours
instead of failing in ten minutes. Its checkout also lacked the
`persist-credentials: false` that every other checkout in the repository sets.

`plugin-compatibility` ignores prose but not workflows, so editing any workflow
file installed four upstream CLIs over the network to prove that cargento's
package layout had not changed. A workflow file cannot change that layout. The
trade, which the filter now states: a change to the canary itself no longer runs
on its own PR. The push-to-main and Monday schedule runs cover it, and it is not
a required check, so nothing is gated on the gap.

mypy's `files` listed three of the six entry-point scripts. The other three -
the hook adapters the shipped manifests actually register - were checked only
because tests/test_events_ingress.py imports them and `tests` is on the list, a
guarantee lasting exactly as long as those imports. Now stated: 110 source files
before, 113 after, clean either way.

AGENTS.md's architecture tree named one hook, `notify_hook.py`, which no
manifest registers. The three that ship - `event_hook.py` for Claude and Codex,
`agy_hook.py` and `statusline_hook.py` for Antigravity - were absent, so an
agent orienting on the tree would not find the adapter code that receives real
harness events.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Jared Scott <jared.scott@variable.team>
…pped

`spacedock.stage_names` had no caller in the runtime, the hooks, the MCP server
or the scripts - only two test assertions. The one production site that needs
exactly its value, spacedock.py:676, open-codes the comprehension instead. The
result was a public function tested in isolation from the path it describes: a
change to either could not fail the other's tests.

Deleted rather than called from production, which was the other proposal. That
site already holds `entries` and uses it twice, for `stages` and for `resting`;
routing it through `stage_names(config, lines)` would re-read and re-parse the
frontmatter to rebuild a list it is already holding. The tests now assert
against `stage_entries`, which both of those methods already use a few lines
away.

AGENTS.md: "docs/plans/*.md | Transient plans for unshipped work. Delete a plan
once its work ships." All three event-driven phase plans shipped -
`scripts/bench_collect.py` for Phase 0, `cargento_runtime/snapshot.py` for 1a,
`cargento_runtime/stream.py` for 1b - and 2,592 lines of them stayed. They open
by instructing an agent to execute their 114 unchecked task boxes task-by-task,
which is the wrong instruction to leave lying in a repository agents read first.

The design owner, `event-driven-session-observation.md`, stays: it is linked
from docs/design-runtime-architecture.md and docs/captures/README.md, and it
already records what each phase delivered. Its one link to a deleted plan is
rewritten. `native-notifications.md` stays too - still linked from two design
docs and from notifications.py, and its decision is still open.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Jared Scott <jared.scott@variable.team>
`scripts/bench_collect.py` crashed on its first call for anyone who ran it:

    AttributeError: 'Namespace' object has no attribute 'host'

It hand-builds an `argparse.Namespace` to stand in for parsed CLI arguments and
hands it to `cli.build_runtime`. That function later grew `host`, `no_git`,
`no_dismiss` and `no_ask`; the stand-in was never extended, so the script died
on the first attribute read. Reproduced on clean `main` before changing
anything, so this is not fallout from the collector work in this branch.

CI did not catch it because `scripts/tests/test_bench_collect.py` exercises the
measurement helpers rather than `main()`, so every test passed against a script
that could not start. This matters more than a broken script usually would:
docs/plans/event-driven-session-observation.md and the comment at
observation.py:73 both point at this benchmark as the way collection cost is
measured, so the tool the repository names for answering "is this slower now?"
was the one tool that could not answer it.

Filled in with production defaults rather than benchmark-friendly ones, so the
figure still describes what a real collect pays. `no_usage=True` remains the one
deliberate difference, for the reason already written above it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Jared Scott <jared.scott@variable.team>
Three changes on the collection path, which runs on a 2.5s floor while a session
is writing. Measured with scripts/bench_collect.py, repeat 5, against a real
store: total collect 146.2ms -> 131.8ms (-9.9%), the Claude collector itself
123.9ms -> 110.0ms (-11.2%).

The glob loop already takes `os.path.getmtime` for every transcript, then kept
only the path. That made the newest-wins comparison re-stat the incumbent for a
number it had just measured and dropped, and the per-prefix loop stat the winner
a third time. `transcripts` now carries `(path, mtime)`, which removes both
stats and the two OSError guards that existed only to cover them.

`started_agent_ids` and the pending-member roster were computed one prefix above
the `if not (active or show_all): continue` gate, and neither feeds
`activity_sources`. `pending_members` is not read until the row is being built,
several hundred lines below. So the comprehension, the sort and one
`started_agent_ids` call ran for every prefix on disk to produce values
discarded for all but the handful that survive the gate. Moved below it. Pure
waste rather than a trade: nothing above the gate reads either name.

The Cursor collector asked `os.path.exists(wal)` and then `os.path.getmtime(wal)`
- two stats for one question, since `getmtime` raises when the file is absent.
Worse, both sat under the same handler as the db's own stat, so a WAL that
vanished between the two calls dropped the whole chat row instead of falling
back to the db's mtime. A WAL is the file most likely to go while being read.
Now one suppressed `getmtime`, scoped so its absence costs nothing.

Deliberately not taken here: the larger restructuring of the same loop, which
would skip the per-session subagent walk for prefixes outside the window. It is
a real cost and a bigger change, with a behaviour trade around long-running
subagents that deserves its own PR and its own measurement.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Jared Scott <jared.scott@variable.team>
Five jobs in the quality gate call setup-python; four pass `cache: pip`.
`runtime-floor` did not, and it installs the heaviest requirements of the five -
requirements-dev.txt, which carries ruff, mypy and coverage - so it downloaded
and built the whole toolchain on every run. Measured across two recent runs it
took 37s and 39s, against 14-20s for the type-check job that installs the same
file with a warm cache.

It does not shorten the gate's wall clock: the critical path is
changes -> Tests (windows-latest) at 119s -> aggregator, and runtime-floor is
nowhere near it. This is runner time and cache-hit rate, not latency.

Left alone deliberately: this job also runs the full suite under `coverage` and
calls `coverage report`, which enforces pyproject's `fail_under` a second time
on a second interpreter. There is a real argument that the threshold belongs to
the `test` job alone and that a duplicate gate can fail for reasons unrelated to
the 3.11 floor. But AGENTS.md says the threshold only ever ratchets up, and
removing one of the two places it is enforced is a decision about how strict the
gate should be rather than a defect to fix in a cleanup PR.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Jared Scott <jared.scott@variable.team>
The sync-docs tone check globbed `docs/plans/*.md`, which is also where per-issue
deep-dive notes are kept locally and excluded one file at a time in
.git/info/exclude. So the check reported drift in somebody's private scratch:
three hits in a deep-dive note, none of them in a file any reviewer will read,
and none fixable without editing a file that is not repository content.

`git ls-files` instead of `ls`. It still covers all nineteen tracked prose docs,
including the two plans that remain, and it keeps the reason the original `ls`
was there: step 4 deletes plan docs, and a bare glob matching nothing stays
literal and makes grep exit 2.

Same shape as the validator fix earlier in this branch. Both walked `docs/` as
though everything under it were source, and `docs/` has held vendored mods,
orphan-branch state and local notes for a while now.

With this, the tone check reads clean on a tree whose prose is already clean,
which is what makes it worth running.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Jared Scott <jared.scott@variable.team>
The WAL fix in the previous commit changed behaviour, so it gets a test that
fails without it. Verified both ways: reverted to the pre-fix collector this
asserts 1 != 0, because losing the race withdrew the whole chat row; with the
fix the row survives on the db's own mtime.

The race is made deterministic rather than waited for. `os.path.getmtime` raises
for the `-wal` path and answers honestly for everything else, which is exactly
the state the collector sees when a checkpoint removes the WAL between the
existence check and the stat.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Jared Scott <jared.scott@variable.team>
@github-actions

Copy link
Copy Markdown
Contributor

Coverage

Name                                                                  Stmts   Miss Branch BrPart  Cover
-------------------------------------------------------------------------------------------------------
cargento/skills/cargento/agy_hook.py                                     79     14     28      7  78.5%
cargento/skills/cargento/cargento_runtime/__init__.py                     0      0      0      0 100.0%
cargento/skills/cargento/cargento_runtime/aggregate.py                  213      1     64      0  99.6%
cargento/skills/cargento/cargento_runtime/asks.py                       110      0     28      0 100.0%
cargento/skills/cargento/cargento_runtime/claude_data.py                305     33    142     16  89.0%
cargento/skills/cargento/cargento_runtime/cli.py                        127     14     26      3  87.6%
cargento/skills/cargento/cargento_runtime/collectors/__init__.py          0      0      0      0 100.0%
cargento/skills/cargento/cargento_runtime/collectors/antigravity.py     410     41    166     25  87.2%
cargento/skills/cargento/cargento_runtime/collectors/claude.py          256     15     94     12  91.7%
cargento/skills/cargento/cargento_runtime/collectors/codex.py           101      7     38      7  89.9%
cargento/skills/cargento/cargento_runtime/collectors/copilot.py         148      6     50      2  96.0%
cargento/skills/cargento/cargento_runtime/collectors/cursor.py          276     19    104     16  90.3%
cargento/skills/cargento/cargento_runtime/collectors/droid.py            32      3      6      1  89.5%
cargento/skills/cargento/cargento_runtime/collectors/gemini.py           53      7     16      4  84.1%
cargento/skills/cargento/cargento_runtime/collectors/goose.py            89     11     28      4  87.2%
cargento/skills/cargento/cargento_runtime/collectors/opencode.py         78      6     26      2  92.3%
cargento/skills/cargento/cargento_runtime/collectors/pi.py              326     34    152     20  88.7%
cargento/skills/cargento/cargento_runtime/config.py                     189      1     20      1  99.0%
cargento/skills/cargento/cargento_runtime/diagnostics.py                 84      4     26      4  92.7%
cargento/skills/cargento/cargento_runtime/dismissals.py                 113      2     28      2  97.2%
cargento/skills/cargento/cargento_runtime/events.py                     169      0     64      0 100.0%
cargento/skills/cargento/cargento_runtime/git_status.py                  28      2      8      2  88.9%
cargento/skills/cargento/cargento_runtime/http_api.py                   525     34    176     10  93.7%
cargento/skills/cargento/cargento_runtime/io.py                         126      2     28      0  98.7%
cargento/skills/cargento/cargento_runtime/lifecycle.py                  325     15    106      6  95.1%
cargento/skills/cargento/cargento_runtime/notifications.py              174     14     60      4  91.5%
cargento/skills/cargento/cargento_runtime/observation.py                271      9     74      1  97.1%
cargento/skills/cargento/cargento_runtime/observer.py                   239     25    108     13  87.3%
cargento/skills/cargento/cargento_runtime/probe.py                       44      0     18      1  98.4%
cargento/skills/cargento/cargento_runtime/quota.py                      333      2    112      1  99.3%
cargento/skills/cargento/cargento_runtime/records.py                    256      5    114      9  96.2%
cargento/skills/cargento/cargento_runtime/sessions.py                   101      0     44      0 100.0%
cargento/skills/cargento/cargento_runtime/snapshot.py                    36      0      4      0 100.0%
cargento/skills/cargento/cargento_runtime/spacedock.py                  454     48    238     26  89.0%
cargento/skills/cargento/cargento_runtime/state.py                       65      0      2      0 100.0%
cargento/skills/cargento/cargento_runtime/stream.py                      57      0      8      0 100.0%
cargento/skills/cargento/cargento_runtime/transcripts.py                509     29    266     26  92.9%
cargento/skills/cargento/cargento_runtime/turns.py                      197     14    104     12  90.7%
cargento/skills/cargento/cargento_runtime/web/__init__.py                 0      0      0      0 100.0%
cargento/skills/cargento/cargento_runtime/web/page.py                    54      0     14      0 100.0%
cargento/skills/cargento/event_hook.py                                   86      4     28      3  93.9%
cargento/skills/cargento/mcp_server.py                                  377     22    112     14  92.2%
cargento/skills/cargento/notify_hook.py                                  49     15      6      1  67.3%
cargento/skills/cargento/server.py                                        3      0      2      1  80.0%
cargento/skills/cargento/statusline_hook.py                             131     13     46      8  87.0%
scripts/bench_collect.py                                                211     10     54      6  94.0%
scripts/bench_event_latency.py                                           67     21     14      1  67.9%
scripts/bump_version.py                                                  60     12     24      5  77.4%
scripts/capture_hook.py                                                 287     30     86     11  88.5%
scripts/derive_prompt_shapes.py                                         210     16     88     14  89.3%
scripts/lint_embedded.py                                                 92      3     28      2  95.8%
scripts/validate_plugins.py                                             675    190    390     60  69.2%
-------------------------------------------------------------------------------------------------------
TOTAL                                                                  9200    753   3468    363  90.2%

Threshold: fail_under in pyproject.toml · label coverage-exception to bypass (visible in PR timeline).

@gcko
gcko merged commit 0093a08 into main Aug 29, 2026
13 checks passed
@gcko
gcko deleted the chore/repo-diagnostic-cleanup branch August 29, 2026 08:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant