diff --git a/.kilo/skills/v2-feature-placement/SKILL.md b/.kilo/skills/v2-feature-placement/SKILL.md index 5d407d5e3b22..f31c37b86242 100644 --- a/.kilo/skills/v2-feature-placement/SKILL.md +++ b/.kilo/skills/v2-feature-placement/SKILL.md @@ -93,16 +93,21 @@ Only when a seam makes no sense (a defect fix, or a Kilo-specific decision no kn ### 7. Done-proof for the progress map -Every v1 patch cell you replace gets its ID on the v2 code: +Every v1 cell you replace gets a proof in the same PR: - In a shared upstream file (rung 3 or 4): `// kilocode_change(:)`. -- In a Kilo-owned file (rung 1 or 2): `// kilo_port(:)` on the code that now provides the behavior. -- Behavior v2 already provides: `dispositions.json`, `state: "native"`, with the v2 pointer. Behavior not carried: `state: "dropped"`, with the reason. +- In a Kilo-owned file (rung 1 or 2): `// kilo_port(:)` on the code that now provides the behavior, also when that code only selects or configures upstream behavior, and on the Kilo-owned v2 test that replaces a v1 test patch cell. +- A Kilo-owned module or test ported under another name: the v1 file name when it fits, else `state: "ported"` in `dispositions.json` with the v2 path. +- Behavior upstream v2 provides with no Kilo code: `state: "native"`, with the v2 pointer. Behavior not carried (a shim, dead v1 code, or a decision the plan records): `state: "dropped"`, with the evidence. Behavior that a later unit ports stays open. + +Close a cell only after you compared the v1 hunk with the v2 code behavior by behavior; a cell with a known gap stays open, with the gap in the PR. The full rules are in the `v2-migration` skill, section "Progress map". Then regenerate and verify: ```sh -bun script/upstream/progress.ts && bun script/upstream/progress.ts --check +git add # the map counts only tracked files +bun script/upstream/progress.ts && bun script/upstream/progress.ts && bun script/upstream/progress.ts --check # identical output, then check +bun script/upstream/progress.ts --list # each open cell needs a reason in the PR bun script/check-shared-patches.ts --worktree && bun script/check-opencode-annotations.ts --worktree # before the commit; CI runs both without --worktree on the commit bun typecheck # from the affected package directory, never tsc ``` @@ -118,7 +123,7 @@ Add a section `## Placement` to the PR body: | compaction toolOutput setting | 3 | no editor field, no hook reaches the transcript | core/src/session/compaction.ts, 3 lines, shared-patches.json | ``` -Plus: shared files touched with rung, core-internal imports added, mirrored files, and the progress map delta (cells closed per feature, dispositions added with reasons). Self-test per `v2-migration` skill; the user should not need to test for you. +Plus: shared files touched with rung, core-internal imports added and mirrored files. When the PR changes the map, add the section `## Progress map` from the `v2-migration` skill (section "Evidence"): the box before and after, and one short line per cell or group on why it is done, why it is dropped, or why it stays open. Self-test per `v2-migration` skill; the user should not need to test for you. ## Decision in one table diff --git a/.kilo/skills/v2-migration/SKILL.md b/.kilo/skills/v2-migration/SKILL.md index 4110a1673f88..e3d6286e4ffd 100644 --- a/.kilo/skills/v2-migration/SKILL.md +++ b/.kilo/skills/v2-migration/SKILL.md @@ -162,13 +162,29 @@ Grow the test surface with each PR. ## Progress map -`migration-tracking/progress/README.md` is the generated map of Kilo's v1 delta: one cell per Kilo-owned file, `/kilocode/*` API operation and patch in a shared upstream file, grouped by feature. `bun script/upstream/progress.ts` regenerates it; CI fails when it is stale. Module and API cells turn done on their own when the file or path literal lands on v2. Patch cells and decisions do not, so for every unit: - -- Before you start, run `bun script/upstream/progress.ts --list `. The open cells are the inventory of the feature; each patch cell names its v1 source line. -- When you port a patch cell, put its ID on the v2 code that replaces it: `// kilocode_change(:)` when that code is a marked line in a shared upstream file, `// kilo_port(:)` when it is in a Kilo-owned file (rung 1 or 2). For a cell in `unattributed:`, the feature is the box: `kilo_port(unattributed::)`. Without an ID the cell stays open. An unknown ID, or a proof in the wrong kind of file, fails the run. The map records the rung where the cell landed. -- When a patch or module needs no port, add its cell ID to `migration-tracking/progress/dispositions.json` with `state` (`native` when v2 has the behavior built in, `facade` when the v1 compatibility layer serves it, `dropped` when the feature is not carried), a `note` with the reason, and `by`. Do not mark a cell `ported` by disposition when a marker or file can prove it. -- A loose patch that lands in `unattributed:` belongs to a feature. Tag its v1 marker on `main` as `kilocode_change()` in a small follow-up PR; the next re-pin moves it. -- Regenerate before you commit. CI posts one comment per PR with the delta (percent, changed features, closed and dropped cells), the placement line (new marked lines in shared files by rung, new `kilo_port` annotations, new core-internal imports), the two ratchets and the treemap of the head commit; the `progress.json` diff carries the same information. Mention the before and after count of the feature in the PR. +`migration-tracking/progress/README.md` is the generated map of Kilo's v1 delta: one cell per Kilo-owned file, `/kilocode/*` API operation and patch in a shared upstream file, grouped by feature. `bun script/upstream/progress.ts` regenerates it; CI fails when it is stale. Module and API cells turn done on their own only when the file name or path literal lands on v2. Renamed files, patch cells and decisions need a proof from you. Every port closes the cells it replaces in the same PR, so for every unit: + +- Before you start, run `bun script/upstream/progress.ts --list `. The open cells are the inventory of the feature; each patch cell names its v1 source line. Read a v1 hunk with `git show : | sed -n ',p'` (the pin is `pins.v1Target` in `features.json`). +- Close each cell with the first proof that applies: + 1. The v2 code is a marked line in a shared upstream file: `// kilocode_change(:)` on it. + 2. The v2 code is in a Kilo-owned file (rung 1 or 2): `// kilo_port(:)` on it. This includes a Kilo adapter that only selects or configures upstream code, and a Kilo-owned v2 test that carries the assertions of a v1 test patch cell. + 3. A module or test ported under another name: give the new file the v1 name when that name fits the package (the cell then closes by name). Otherwise add a `ported` disposition with the v2 path and symbol in `note`. + 4. Upstream v2 has the behavior and no Kilo code is involved: a `native` disposition with the v2 pointer. + 5. The v1 compatibility layer serves it: a `facade` disposition. + 6. The behavior is not carried: a `dropped` disposition with the evidence (see below). + + Dispositions go in `migration-tracking/progress/dispositions.json` with `state`, `note` and `by` (your branch name). Without a proof the cell stays open. An unknown ID, or a proof in the wrong kind of file, fails the run. The map records the rung where the cell landed. +- Verify before you close a cell. A proof or a disposition says that v2 has the behavior, not that a file exists: + - Compare the v1 hunk or file with the v2 code you name, behavior by behavior: defaults, precedence, retries, error paths and tests. + - Find the v1 callers: `git grep -n -- packages`. Code with no caller on v1 is `dropped` (write that in the note), not `ported`. + - `dropped` means the feature is not carried: a shim, dead v1 code, or a decision that the plan records (the unit table in `kilo-v2-migration-plan.md`, Decision 7 in `migration-context.md`). When the plan has a unit that ports the behavior, the cell stays open and the PR names the unit. "Not ported yet" is never `dropped`. + - When part of the behavior is missing, port the gap if it is small and in scope. Otherwise leave the cell open and give the gap in the PR. Do not close a cell with a known gap. + - A hunk is attributed by its first Kilo import or identifier, so it can carry lines of other features (for example one plugin list with three plugins). Close it for your feature only when the other lines are tracked by their own cells, and say so in the PR. + - A v1 test cell closes only when the v2 tests carry its important assertions. Add the missing ones when they are cheap. When v2 does the opposite on purpose, use `dropped` with the reason. + - A classification in a task, a plan or a peer message is a claim. Verify it the same way, and report each one you found wrong. +- Git must track a new file before the map sees it: `git add` new files before you regenerate. +- A loose patch that lands in `unattributed:` can be proved in place with `kilo_port(unattributed::)`, which closes the cell. It still belongs to a feature: tag its v1 marker on `main` as `kilocode_change()` in a small follow-up PR; the next re-pin moves it into the feature box. +- Regenerate before you commit: run `bun script/upstream/progress.ts` twice (the output must be identical), then `--check`, then `--list ` again. Every cell that stays open needs a reason in the PR. CI posts one comment per PR with the delta (percent, changed features, closed and dropped cells), the placement line (new marked lines in shared files by rung, new `kilo_port` annotations, new core-internal imports), the two ratchets and the treemap of the head commit; the `progress.json` diff carries the same information. ## Evidence @@ -176,6 +192,37 @@ In the PR and the final response, list: - The commands you ran, and the self-test scenarios with pass, fail or blocked. - Each shared upstream file you changed, with its option (1 to 5 above) and the missing seam. -- The progress map delta: cells closed per feature, and every disposition you added with its reason. +- The progress map delta, as the PR section below. - The CI state. For each red check, the cause: your change (fix it), a flake (one rerun) or a known baseline failure. - The limits, for example a flow that needs credentials. + +### PR section `## Progress map` + +Every PR that changes the map (a proof, a disposition, or a file that closes a cell by name) has this section. It tells the reviewer why each cell changed, so that the reviewer does not have to read `dispositions.json` or the CI comment. Keep it short: one line per cell or per group of cells with the same reason. The `note` in `dispositions.json` is the long form. + +``` +## Progress map + +``: 12/87 to 59/75 (12 dropped). module 9/44 to 30/35, patch 0/20 to 12/18, test 3/23 to 17/22; landed 11 plugin. + +Done, and why: +- kilo_port (11): v1 kilo.ts import, settings and SDK -> core/src/kilocode/gateway.ts provider transform and packageFor; ... +- ported (30): renamed modules and tests, for example api/url.ts -> kilo-gateway-core/src/server.ts; ... +- by file name (5): ported tests autocomplete, edit, fim, ... +- native (1): 00d34e8d5cd7, upstream Variant.resolve. + +Dropped, and why it is not needed: +- server/routes.ts, server/fim.ts, server/edit.ts: Hono routes with no caller on v1; the live routes are tracked in the server box. +- types/jsx.d.ts, types/tui.d.ts: type shims for TUI code outside the TUI package. + +Still open: +- cloud-sessions.ts and its test: cloud session import, U-E3-04. +- 5 transform.ts cells: default request settings for Gateway models, needs its own unit. + +Corrections: . +``` + +- "Done" names the v2 code that has the behavior. Name the gap you ported in the same PR, if any. +- "Dropped" says what the code did on v1 and why v2 does not need it, with the evidence (no caller, shim, recorded decision). Name a behavior change that a drop causes for users. +- "Still open" names what is missing and the unit or feature that owns it. +- Leave out a block that has no entries. Do not repeat the cell lists of the CI comment. diff --git a/migration-tracking/progress/README.md b/migration-tracking/progress/README.md index e79d6402ebb2..d52504a9d56d 100644 --- a/migration-tracking/progress/README.md +++ b/migration-tracking/progress/README.md @@ -338,7 +338,8 @@ Hunks in shared upstream files with no `kilocode_change()` tag, no Kilo - test: a module or patch in a test file, same rules. - landed: the rung of the done-proof. `kilo_port` is rung 2 (host) in `packages/kilo-cli` and rung 1 (plugin) in other Kilo-owned files; a marker has the rung of its file in `script/upstream/shared-patches.json` (3 seam, 4 patch). A cell with more than one proof counts once, at the highest rung. - Ratchets: core-internal imports count the distinct modules in `packages/core/src` outside `kilocode/` that non-test files in `packages/kilo-*` and `packages/*/src/kilocode` import, as `@opencode/core/*` or by relative path. A non-test file of a logic package (`packages/kilo-*-core`) that imports anything from `@opencode/*` fails the run. Shared patches by rung count the entries in `shared-patches.json`. -- A disposition in `dispositions.json` overrides: `ported`, `native` and `facade` count as done, `dropped` leaves the denominator and is listed above. Every disposition needs a note and an author. +- A disposition in `dispositions.json` overrides: `ported`, `native` and `facade` count as done, `dropped` leaves the denominator and is listed above. Every disposition needs a note and an author. A module ported under another name needs `ported` with the v2 path. +- A proof or a disposition says that v2 has the behavior. Close a cell only after you compare the v1 code with v2; a cell with a known gap stays open. `dropped` is for behavior that is not carried (a shim, dead v1 code, or a decision the plan records), not for behavior that a later unit ports. Rules: `.kilo/skills/v2-migration/SKILL.md`, section "Progress map". - Hunks whose only change is a brand rename, and hunks that contain only markers, are not cells. ## Terms diff --git a/script/upstream/progress.ts b/script/upstream/progress.ts index 09de7330c31b..f9644f89b507 100644 --- a/script/upstream/progress.ts +++ b/script/upstream/progress.ts @@ -828,7 +828,8 @@ function render(config: Config, data: Awaited>, dispo `- test: a module or patch in a test file, same rules.`, `- landed: the rung of the done-proof. \`kilo_port\` is rung 2 (host) in \`packages/kilo-cli\` and rung 1 (plugin) in other Kilo-owned files; a marker has the rung of its file in \`script/upstream/shared-patches.json\` (3 seam, 4 patch). A cell with more than one proof counts once, at the highest rung.`, `- Ratchets: core-internal imports count the distinct modules in \`packages/core/src\` outside \`kilocode/\` that non-test files in \`packages/kilo-*\` and \`packages/*/src/kilocode\` import, as \`@opencode/core/*\` or by relative path. A non-test file of a logic package (\`packages/kilo-*-core\`) that imports anything from \`@opencode/*\` fails the run. Shared patches by rung count the entries in \`shared-patches.json\`.`, - `- A disposition in \`dispositions.json\` overrides: \`ported\`, \`native\` and \`facade\` count as done, \`dropped\` leaves the denominator and is listed above. Every disposition needs a note and an author.`, + `- A disposition in \`dispositions.json\` overrides: \`ported\`, \`native\` and \`facade\` count as done, \`dropped\` leaves the denominator and is listed above. Every disposition needs a note and an author. A module ported under another name needs \`ported\` with the v2 path.`, + `- A proof or a disposition says that v2 has the behavior. Close a cell only after you compare the v1 code with v2; a cell with a known gap stays open. \`dropped\` is for behavior that is not carried (a shim, dead v1 code, or a decision the plan records), not for behavior that a later unit ports. Rules: \`.kilo/skills/v2-migration/SKILL.md\`, section "Progress map".`, `- Hunks whose only change is a brand rename, and hunks that contain only markers, are not cells.`, "", `## Terms`,