Skip to content

tracking(cleanup): monthly scavenger sweep — 2026-09 #4726

Description

@Joob1n

We would rather Maka did not grow heavier than it needs to be, so this opens a monthly scavenger sweep. A new one starts on the first of each month. This round runs from 2026-09-04; the next is 2026-10-01.

Maka carries about 576,000 lines of product code and 486,000 lines of test code. Very little of that is wrong. A lot of it is more than it needs to be: two implementations of one rule, a fixture rebuilt in twenty files, a 7,000-line module that grew one honest commit at a time. None of it is anyone's fault and none of it will be fixed by a rewrite. It gets fixed by someone taking one area for one month and leaving it smaller than they found it.

How to claim:

  1. Choose an area below, or a smaller piece of one — good refactors are welcome at any size — and check that nobody else is already on it.
  2. Open a new issue describing the redundancy or the weight you mean to remove, with a plan detailed enough to argue with.
  3. Comment on this month's issue with a link to that issue.

Areas are drawn along package and directory lines, so two claimants never need to coordinate. One person can hold several. A claim that stops moving for a long time is released, and its area goes back on the board.

What counts as done

Every claim ends in one or more pull requests that state a measured result. "Simplified X" is not a result. These are:

  • a rule that had two implementations now has one, and the second is deleted;
  • a type, helper or fixture that existed in N places now exists once;
  • a module over 2,000 lines is split along a seam that already existed in it, with no behaviour change;
  • dead code removed, with the search that proves nothing reaches it;
  • a debt counter in apps/desktop/renderer-architecture.json goes down.

Not results: renaming things, reformatting, moving files without reducing anything, replacing a clear loop with a clever one, or deleting a test.

Part A — product code

# Area Scope Size Where to start
A1 Storage · session metadata packages/storage/src/sqlite-session-metadata-store.ts and its callers 7,288 lines in one file The largest file in the repository. The read face and the write face barely touch.
A2 Storage · runtime store and policy sqlite-runtime-store.ts, runtime-policy/, agent-run-store.ts ~11,000 lines Three files above 2,000 lines each.
A3 Storage · everything else the remaining 118 top-level files ~44,000 lines 121 files sit flat at the top level with almost no grouping.
A4 Runtime · session kernel session-manager.ts, runtime-kernel.ts 9,005 lines Two cores that grew together.
A5 Runtime · provider backend ai-sdk-backend.ts, model-*.ts ~8,000 lines 4,930 lines in one file, changed constantly.
A6 Runtime · tool runtime tool-runtime.ts, computer-use-tools.ts 6,881 lines Two files near 3,000 lines.
A7 Runtime · everything else the remaining ~250 files ~90,000 lines Compaction, context, permissions. Large enough to split further — say so when claiming.
A8 Runtime Host · server coordinators packages/runtime-host/src/server/, 130 files ~50,000 lines Several coordinators above 2,000 lines.
A9 Runtime Host · everything else peer mesh, client, protocol, operator ~50,000 lines peer-mesh/node.ts is 2,426 lines.
A10 Core packages/core/src, 157 files 51,620 lines Types and contracts. Simplification here pays out in every other area.
A11 Desktop · main process apps/desktop/src/main/, 190 files 56,280 lines Updates, Host boot, IPC.
A12 Desktop · renderer apps/desktop/src/renderer/, 393 files across 11 feature slices 85,685 lines The renderer ratchet already records per-file debt, so results here are countable without argument.
A13 CLI and TUI packages/cli/src, 91 files 42,375 lines pi-tui-runner.ts is 4,238 lines.
A14 UI component library packages/ui/src, 129 files 31,019 lines composer.tsx is 2,180 lines.
A15 Preload and bridge apps/desktop/src/preload/, 16 files 6,566 lines preload.ts alone is 3,754 lines and is the only channel between main and renderer. Narrowing it pays on both sides.
A16 Architecture documents docs/architecture/, 31 files Several are kept in two languages, and drift between a document and its implementation has been found more than once. Reconcile or retire.

Part B — test code

Tests are 486,000 lines across 1,942 files. In packages/runtime there is more test than source. This half needs its own rules, because the obvious way to make a test suite smaller is to make it prove less.

# Area Scope Size Where to start
T1 Runtime backend and kernel tests ai-sdk-backend.test.ts (16,206), session-manager.test.ts (14,887) 31,000 lines in two files Both are over three times the size of what they test.
T2 Runtime · remaining tests 229 files ~106,000 lines Test-to-source ratio 1.22, the highest in the repository.
T3 Runtime Host coordinator tests root-turn-coordinator (6,451), message-coordinator (4,041), host-kernel (3,848) and neighbours ~30,000 lines 21 fixture files here; much of the setup repeats.
T4 Runtime Host · remaining tests ~170 files ~74,000 lines
T5 Storage tests and fixtures 112 files including 28 fixtures 50,578 lines The most fixture-heavy package; table setup is rebuilt repeatedly.
T6 CLI and TUI tests pi-tui-runner.test.ts (10,499), pi-transcript.test.ts (5,187) 41,784 lines
T7 Desktop tests 290 files across main and renderer 80,576 lines
T8 End-to-end, stories and scripts e2e 37 files (7,423), stories 16 files (10,171), scripts/*.test.mjs 44 files (12,375) ~30,000 lines e2e flakiness is a standing cost; three separate flakes surfaced in one week of recent work.

packages/core and packages/ui have ratios of 0.40 and 0.31 and are thin rather than heavy, so their tests stay with A10 and A14 rather than becoming their own areas.

Acceptance for Part B

The same measured-result rule applies, with three additions, because a smaller suite is not automatically a better one.

  1. Coverage may not fall. A deleted test is only a result when a named other test already proves the same thing, and the claim says which.
  2. Every test touched must fail without the code it tests. Remove the implementation line, watch it go red, put it back. Say in the pull request that this was done. This is not ceremony: in recent work three new tests passed against the unchanged code because a fixture default happened to satisfy them, and a reviewer found it rather than the author.
  3. Prefer driving the real entry point. A test that hands a value directly to an internal function still passes when the call site that produces that value is deleted. Where that is cheap to fix, fix it.

Rules

  • One pull request per coherent change, not per area. A 4,000-line file does not need to be finished in one pass.
  • No behaviour change. If you find a bug, open an issue and keep it out of the cleanup pull request.
  • Existing gates decide the argument: renderer-architecture, the protocol epoch check, ASF headers, lint, format, typecheck.
  • If an area turns out to be two areas, say so here rather than quietly widening the claim.

Carry-over

Areas nobody claims roll into next month's issue, along with whatever the current round leaves unfinished.

简体中文

我们并不希望 Maka 在非必要情况下变得过于臃肿,所以现在发起 每月进行一次的清道夫行动。 每月一号开新的一份。本轮从 2026-09-04 开始,下一轮 2026-10-01。

Maka 现在有约 57.6 万行产品代码和 48.6 万行测试代码。其中错的很少,多余的不少:同一条规则有两处实现,同一个夹具在二十个文件里各建一遍,一个七千行的模块是靠一次次诚实的提交长出来的。这不怪谁,也不会被一次重写解决。它只会被这样解决:有人认领一个板块,做一个月,走的时候让它比来时更小。

认领方式如下:
1、选择你想认领的板块(也可能是比 issue 中划分的板块更小的范围,我们欢迎各种级别的优秀重构),并确认没有其他人在处理
2、开启一个新的 issue,描述清楚现在想解决的冗余/臃肿部分,并提出详细的处理方案
3、在当前月开启的 issue 下评论并链接到你的设计 issue

对于认领但是长久没有推进的工作,我们会取消认领,并重新放开相关部分的可认领状态

怎样算做完

每次认领最终落成一个或多个 PR,PR 里要写出可度量的结果。"简化了 X"不是结果。下面这些是:

  • 一条规则原本有两处实现,现在只剩一处,另一处被删除;
  • 一个类型、辅助函数或夹具原本存在于 N 处,现在只有一处;
  • 一个两千行以上的模块,沿着它本来就存在的接缝拆开,行为不变;
  • 删除死代码,并给出"没有任何路径能到达它"的检索证据;
  • apps/desktop/renderer-architecture.json 里的某个债务计数下降。

不算结果:改名、重排格式、只挪文件而不减少任何东西、把清楚的循环换成聪明的写法、删测试。

第一部分 · 产品代码

# 板块 范围 规模 从哪下手
A1 存储 · 会话元数据 packages/storage/src/sqlite-session-metadata-store.ts 及其调用方 单文件 7,288 行 全仓最大的文件,读面和写面几乎不相干
A2 存储 · 运行时存储与策略 sqlite-runtime-store.tsruntime-policy/agent-run-store.ts 约 11,000 行 三个 2,000 行以上的文件
A3 存储 · 其余 顶层剩余 118 个文件 约 44,000 行 121 个文件平铺在顶层,几乎没有分组
A4 Runtime · 会话内核 session-manager.tsruntime-kernel.ts 9,005 行 两个一起长大的核心
A5 Runtime · 供应商后端 ai-sdk-backend.tsmodel-*.ts 约 8,000 行 单文件 4,930 行,改动最频繁
A6 Runtime · 工具运行时 tool-runtime.tscomputer-use-tools.ts 6,881 行 两个接近 3,000 行的文件
A7 Runtime · 其余 剩余约 250 个文件 约 90,000 行 压缩、上下文、权限。大到应当再切分,认领时请说明
A8 Runtime Host · server 协调器 packages/runtime-host/src/server/,130 个文件 约 50,000 行 多个 2,000 行以上的 coordinator
A9 Runtime Host · 其余 peer mesh、client、protocol、operator 约 50,000 行 peer-mesh/node.ts 2,426 行
A10 Core packages/core/src,157 个文件 51,620 行 类型与契约层,这里的简化会外溢到其他所有板块
A11 Desktop · 主进程 apps/desktop/src/main/,190 个文件 56,280 行 更新、Host 引导、IPC
A12 Desktop · 渲染层 apps/desktop/src/renderer/,393 个文件、11 个 feature 切片 85,685 行 已有渲染层债务台账逐文件记账,成果无需争辩即可计量
A13 CLI 与 TUI packages/cli/src,91 个文件 42,375 行 pi-tui-runner.ts 4,238 行
A14 UI 组件库 packages/ui/src,129 个文件 31,019 行 composer.tsx 2,180 行
A15 预加载与桥接 apps/desktop/src/preload/,16 个文件 6,566 行 preload.ts 就 3,754 行,是主进程与渲染层之间唯一的通道,收窄它两边都受益
A16 架构文档 docs/architecture/,31 篇 其中多篇维护中英两份,文档与实现漂移已不止一次被发现。要么对齐,要么退役

第二部分 · 测试代码

测试有 1,942 个文件、48.6 万行。在 packages/runtime 里,测试比源码还多。这一半需要自己的规则,因为让测试套件变小最省事的办法,就是让它少证明一些东西。

# 板块 范围 规模 从哪下手
T1 Runtime 后端与内核测试 ai-sdk-backend.test.ts(16,206)、session-manager.test.ts(14,887) 两个文件 31,000 行 都是被测源文件的三倍以上
T2 Runtime · 其余测试 229 个文件 约 106,000 行 测源比 1.22,全仓最高
T3 Runtime Host 协调器测试 root-turn-coordinator(6,451)、message-coordinator(4,041)、host-kernel(3,848)及邻近文件 约 30,000 行 这里有 21 个夹具文件,大量准备代码重复
T4 Runtime Host · 其余测试 约 170 个文件 约 74,000 行
T5 存储测试与夹具 112 个文件,含 28 个夹具 50,578 行 夹具最重的包,建表准备被反复重建
T6 CLI 与 TUI 测试 pi-tui-runner.test.ts(10,499)、pi-transcript.test.ts(5,187) 41,784 行
T7 Desktop 测试 主进程与渲染层共 290 个文件 80,576 行
T8 端到端、stories 与脚本 e2e 37 个文件(7,423)、stories 16 个(10,171)、scripts/*.test.mjs 44 个(12,375) 约 30,000 行 e2e 抖动是长期成本,近期一周的工作里就撞上三种不同的抖动

packages/corepackages/ui 的测源比只有 0.40 和 0.31,属于偏薄而非偏重,因此它们的测试并入 A10 与 A14,不单列板块。

第二部分的验收

同样要求可度量的结果,另加三条,因为更小的套件并不自动等于更好的套件。

  1. 覆盖不得下降。 删掉一个测试只有在"另一个具名测试已经证明同一件事"时才算结果,并且要在 PR 里点名是哪一个。
  2. 动过的每个测试,去掉它所测的实现后必须失败。 把那行实现删掉,看它变红,再放回去,并在 PR 里说明做过这一步。这不是仪式:近期就出现过三个新测试在未改动的代码上照样通过,因为夹具默认值恰好满足了它们,而且是评审发现的,不是作者。
  3. 优先驱动真实入口。 一个把值直接喂给内部函数的测试,在产生这个值的调用点被删掉之后依然会通过。凡是修起来不贵的,就修。

规则

  • 一个 PR 对应一处自洽的改动,而不是一个板块一个 PR。四千行的文件不必一次改完。
  • 不改变行为。发现 bug 就单独开 issue,别混进清理 PR。
  • 争议由现有门禁裁决:renderer-architecture、协议 epoch 检查、ASF 头、lint、format、typecheck。
  • 如果发现某个板块其实是两个板块,请在这里说明,而不是悄悄扩大认领范围。

顺延

无人认领的板块顺延到下个月那一份,本轮未做完的部分同样顺延。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions