diff --git a/README.md b/README.md
index 8f871ad..104a4d5 100644
--- a/README.md
+++ b/README.md
@@ -260,3 +260,24 @@ This command automatically regenerates each fixture’s `expected.*` file using
Think of it like Jest’s snapshot updates:
> _You write a fixture once, and snapshot mode keeps it healthy whenever the spec evolves._
+
+# Exceptions
+## Documentation-Only Patch Rule
+-----------------------------
+Documentation-only or comment-only patches are explicitly permitted when the architect clearly requests documentation improvements (e.g., TSDoc, README updates, inline comments). Such patches remain subject to all other rules: minimal, atomic, no forbidden paths, and no runtime behavior changes.
+
+
+## Configuration & Non-Source File Safety Rule
+-------------------------------------------
+When a task requires modifying configuration, environment, workflow, or other normally-forbidden files, the architect MUST:
+
+ 1. Explicitly list *every* configuration or non-source file that is permitted
+ to be modified for this task (e.g., .github/workflows/ci.yml,
+ config/staging.json, migrations/001-add-users.sql).
+
+ 2. Reaffirm that all other configuration, environment, or non-source files
+ remain forbidden. No sibling files or directories are implicitly allowed.
+
+This explicit-file-whitelist requirement ensures the planner, coder, and reviewer
+operate with a deterministic and safe scope, preventing accidental or speculative
+changes outside the architect’s intent.
\ No newline at end of file
diff --git a/fixtures/debugging-and-repair/task-1201-fix-broken-build/architect/expected.json b/fixtures/debugging-and-repair/task-1201-fix-broken-build/architect/expected.json
new file mode 100644
index 0000000..8443ddc
--- /dev/null
+++ b/fixtures/debugging-and-repair/task-1201-fix-broken-build/architect/expected.json
@@ -0,0 +1,11 @@
+{
+ "feasibility": "feasible",
+ "highLevelSummary": "Fix type mismatch in `src/main.ts` by assigning a number to `retries` instead of a string.",
+ "complexity": "low",
+ "pagesOrScreens": [],
+ "apis": [],
+ "dataModels": [],
+ "recommendedFileStructure": [
+ "src/main.ts"
+ ]
+}
\ No newline at end of file
diff --git a/fixtures/debugging-and-repair/task-1201-fix-broken-build/architect/prompt.md b/fixtures/debugging-and-repair/task-1201-fix-broken-build/architect/prompt.md
new file mode 100644
index 0000000..61975ee
--- /dev/null
+++ b/fixtures/debugging-and-repair/task-1201-fix-broken-build/architect/prompt.md
@@ -0,0 +1,20 @@
+You are a senior software architect.
+
+## Context
+The build is failing with a TypeScript error:
+`src/main.ts:10:5 - error TS2322: Type 'string' is not assignable to type 'number'.`
+
+## Files
+`src/main.ts`:
+```ts
+interface Config {
+ retries: number;
+}
+
+const config: Config = {
+ retries: "3" // Error here
+};
+```
+
+## Task
+Diagnose and describe the fix for this build error.
diff --git a/fixtures/debugging-and-repair/task-1201-fix-broken-build/architect/verify.ts b/fixtures/debugging-and-repair/task-1201-fix-broken-build/architect/verify.ts
new file mode 100644
index 0000000..c9b3f64
--- /dev/null
+++ b/fixtures/debugging-and-repair/task-1201-fix-broken-build/architect/verify.ts
@@ -0,0 +1,15 @@
+import {
+ verifyArchitect,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyArchitect(ctx, (spec) => {
+ const summary = spec.highLevelSummary.toLowerCase();
+ if (!summary.includes("type mismatch") && !summary.includes("number")) {
+ return { ok: false, reason: "Must mention type error fix" };
+ }
+ return { ok: true };
+ });
+}
diff --git a/fixtures/debugging-and-repair/task-1201-fix-broken-build/coder/expected.patch b/fixtures/debugging-and-repair/task-1201-fix-broken-build/coder/expected.patch
new file mode 100644
index 0000000..d061f4b
--- /dev/null
+++ b/fixtures/debugging-and-repair/task-1201-fix-broken-build/coder/expected.patch
@@ -0,0 +1,10 @@
+diff --git a/src/main.ts b/src/main.ts
+index 1234567..8901234 100644
+--- a/src/main.ts
++++ b/src/main.ts
+@@ -4,5 +4,5 @@
+
+ const config: Config = {
+- retries: "3" // Error here
++ retries: 3
+ };
diff --git a/fixtures/debugging-and-repair/task-1201-fix-broken-build/coder/prompt.md b/fixtures/debugging-and-repair/task-1201-fix-broken-build/coder/prompt.md
new file mode 100644
index 0000000..484dd90
--- /dev/null
+++ b/fixtures/debugging-and-repair/task-1201-fix-broken-build/coder/prompt.md
@@ -0,0 +1,19 @@
+You are a senior developer.
+
+## Task
+Fix the TS error in `src/main.ts`.
+
+## Files
+`src/main.ts`:
+```ts
+interface Config {
+ retries: number;
+}
+
+const config: Config = {
+ retries: "3" // Error here
+};
+```
+
+## Constraints
+- Return a unified diff.
diff --git a/fixtures/debugging-and-repair/task-1201-fix-broken-build/coder/verify.ts b/fixtures/debugging-and-repair/task-1201-fix-broken-build/coder/verify.ts
new file mode 100644
index 0000000..c4d15c2
--- /dev/null
+++ b/fixtures/debugging-and-repair/task-1201-fix-broken-build/coder/verify.ts
@@ -0,0 +1,18 @@
+import {
+ verifyCoder,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyCoder(ctx, (patch) => {
+ // Check that we are adding the number
+ if (!patch.includes("retries: 3")) return { ok: false, reason: "Must set number value" };
+
+ // Check that we are NOT adding the string (simple string check would match deleted line)
+ // So we look for the line starting with +
+ if (patch.includes('+ retries: "3"')) return { ok: false, reason: "Must not use string value" };
+
+ return { ok: true };
+ });
+}
diff --git a/fixtures/debugging-and-repair/task-1201-fix-broken-build/planner/expected.json b/fixtures/debugging-and-repair/task-1201-fix-broken-build/planner/expected.json
new file mode 100644
index 0000000..a96cbeb
--- /dev/null
+++ b/fixtures/debugging-and-repair/task-1201-fix-broken-build/planner/expected.json
@@ -0,0 +1,14 @@
+{
+ "tasks": [
+ {
+ "id": "fix-type-error",
+ "type": "fix",
+ "description": "Change retries value from string '3' to number 3 in src/main.ts",
+ "complexity": "low",
+ "file": "src/main.ts",
+ "dependsOn": []
+ }
+ ],
+ "ambiguities": [],
+ "invalidTaskCount": 0
+}
\ No newline at end of file
diff --git a/fixtures/debugging-and-repair/task-1201-fix-broken-build/planner/prompt.md b/fixtures/debugging-and-repair/task-1201-fix-broken-build/planner/prompt.md
new file mode 100644
index 0000000..c698db0
--- /dev/null
+++ b/fixtures/debugging-and-repair/task-1201-fix-broken-build/planner/prompt.md
@@ -0,0 +1,19 @@
+You are a tech lead dealing with a broken build.
+
+## Context
+Architect's Summary: "Fix type mismatch in `src/main.ts` by assigning a number to `retries` instead of a string."
+
+## Files
+`src/main.ts`:
+```ts
+interface Config {
+ retries: number;
+}
+
+const config: Config = {
+ retries: "3" // Error here
+};
+```
+
+## Task
+Plan the fix.
diff --git a/fixtures/debugging-and-repair/task-1201-fix-broken-build/planner/verify.ts b/fixtures/debugging-and-repair/task-1201-fix-broken-build/planner/verify.ts
new file mode 100644
index 0000000..d43b31c
--- /dev/null
+++ b/fixtures/debugging-and-repair/task-1201-fix-broken-build/planner/verify.ts
@@ -0,0 +1,13 @@
+import {
+ verifyPlanner,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyPlanner(ctx, (out) => {
+ if (out.tasks.length !== 1) return { ok: false, reason: "Should have 1 task" };
+ if (out.tasks[0].file !== "src/main.ts") return { ok: false, reason: "Target file mismatch" };
+ return { ok: true };
+ });
+}
diff --git a/fixtures/debugging-and-repair/task-1201-fix-broken-build/reviewer/expected.json b/fixtures/debugging-and-repair/task-1201-fix-broken-build/reviewer/expected.json
new file mode 100644
index 0000000..5881434
--- /dev/null
+++ b/fixtures/debugging-and-repair/task-1201-fix-broken-build/reviewer/expected.json
@@ -0,0 +1,11 @@
+{
+ "decision": "approve",
+ "comments": [
+ {
+ "message": "Correct fix. Type mismatch resolved.",
+ "path": "src/main.ts",
+ "line": 5,
+ "blocking": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/fixtures/debugging-and-repair/task-1201-fix-broken-build/reviewer/prompt.md b/fixtures/debugging-and-repair/task-1201-fix-broken-build/reviewer/prompt.md
new file mode 100644
index 0000000..9a7557f
--- /dev/null
+++ b/fixtures/debugging-and-repair/task-1201-fix-broken-build/reviewer/prompt.md
@@ -0,0 +1,21 @@
+You are a senior code reviewer.
+
+## Task
+Review the build fix.
+
+## Patch
+```diff
+diff --git a/src/main.ts b/src/main.ts
+index 1234567..8901234 100644
+--- a/src/main.ts
++++ b/src/main.ts
+@@ -4,5 +4,5 @@
+
+ const config: Config = {
+- retries: "3" // Error here
++ retries: 3
+ };
+```
+
+## Considerations
+- Does it fix the type error?
diff --git a/fixtures/debugging-and-repair/task-1201-fix-broken-build/reviewer/verify.ts b/fixtures/debugging-and-repair/task-1201-fix-broken-build/reviewer/verify.ts
new file mode 100644
index 0000000..b88ccd9
--- /dev/null
+++ b/fixtures/debugging-and-repair/task-1201-fix-broken-build/reviewer/verify.ts
@@ -0,0 +1,12 @@
+import {
+ verifyReviewer,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyReviewer(ctx, (output) => {
+ if (output.decision !== "approve") return { ok: false, reason: "Should approve" };
+ return { ok: true };
+ });
+}
diff --git a/fixtures/debugging-and-repair/task-1202-flakey-test-fix/architect/expected.json b/fixtures/debugging-and-repair/task-1202-flakey-test-fix/architect/expected.json
new file mode 100644
index 0000000..c4edc98
--- /dev/null
+++ b/fixtures/debugging-and-repair/task-1202-flakey-test-fix/architect/expected.json
@@ -0,0 +1,11 @@
+{
+ "feasibility": "feasible",
+ "highLevelSummary": "Fix race condition in `test/flaky.test.js` by awaiting the async `fetchData` call.",
+ "complexity": "low",
+ "pagesOrScreens": [],
+ "apis": [],
+ "dataModels": [],
+ "recommendedFileStructure": [
+ "test/flaky.test.js"
+ ]
+}
\ No newline at end of file
diff --git a/fixtures/debugging-and-repair/task-1202-flakey-test-fix/architect/prompt.md b/fixtures/debugging-and-repair/task-1202-flakey-test-fix/architect/prompt.md
new file mode 100644
index 0000000..8f3c82e
--- /dev/null
+++ b/fixtures/debugging-and-repair/task-1202-flakey-test-fix/architect/prompt.md
@@ -0,0 +1,17 @@
+You are a senior software architect.
+
+## Context
+The test `test/flaky.test.js` is flakey. It fails about 50% of the time.
+It seems to be a race condition where the test checks for the result before the async operation completes.
+
+## Files
+`test/flaky.test.js`:
+```js
+test('fetches data', () => {
+ const data = fetchData();
+ expect(data).toBe('success');
+});
+```
+
+## Task
+Describe how to fix the test to be deterministic.
diff --git a/fixtures/debugging-and-repair/task-1202-flakey-test-fix/architect/verify.ts b/fixtures/debugging-and-repair/task-1202-flakey-test-fix/architect/verify.ts
new file mode 100644
index 0000000..8cf017b
--- /dev/null
+++ b/fixtures/debugging-and-repair/task-1202-flakey-test-fix/architect/verify.ts
@@ -0,0 +1,15 @@
+import {
+ verifyArchitect,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyArchitect(ctx, (spec) => {
+ const summary = spec.highLevelSummary.toLowerCase();
+ if (!summary.includes("await") && !summary.includes("async")) {
+ return { ok: false, reason: "Must mention async/await fix" };
+ }
+ return { ok: true };
+ });
+}
diff --git a/fixtures/debugging-and-repair/task-1202-flakey-test-fix/coder/expected.patch b/fixtures/debugging-and-repair/task-1202-flakey-test-fix/coder/expected.patch
new file mode 100644
index 0000000..7c5852b
--- /dev/null
+++ b/fixtures/debugging-and-repair/task-1202-flakey-test-fix/coder/expected.patch
@@ -0,0 +1,11 @@
+diff --git a/test/flaky.test.js b/test/flaky.test.js
+index 1234567..8901234 100644
+--- a/test/flaky.test.js
++++ b/test/flaky.test.js
+@@ -1,4 +1,4 @@
+-test('fetches data', () => {
+- const data = fetchData();
++test('fetches data', async () => {
++ const data = await fetchData();
+ expect(data).toBe('success');
+ });
diff --git a/fixtures/debugging-and-repair/task-1202-flakey-test-fix/coder/prompt.md b/fixtures/debugging-and-repair/task-1202-flakey-test-fix/coder/prompt.md
new file mode 100644
index 0000000..2530e43
--- /dev/null
+++ b/fixtures/debugging-and-repair/task-1202-flakey-test-fix/coder/prompt.md
@@ -0,0 +1,16 @@
+You are a senior developer.
+
+## Task
+Fix the flaky test in `test/flaky.test.js`.
+
+## Files
+`test/flaky.test.js`:
+```js
+test('fetches data', () => {
+ const data = fetchData();
+ expect(data).toBe('success');
+});
+```
+
+## Constraints
+- Return a unified diff.
diff --git a/fixtures/debugging-and-repair/task-1202-flakey-test-fix/coder/verify.ts b/fixtures/debugging-and-repair/task-1202-flakey-test-fix/coder/verify.ts
new file mode 100644
index 0000000..7dbc8ac
--- /dev/null
+++ b/fixtures/debugging-and-repair/task-1202-flakey-test-fix/coder/verify.ts
@@ -0,0 +1,13 @@
+import {
+ verifyCoder,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyCoder(ctx, (patch) => {
+ if (!patch.includes("async")) return { ok: false, reason: "Must make test async" };
+ if (!patch.includes("await")) return { ok: false, reason: "Must await promise" };
+ return { ok: true };
+ });
+}
diff --git a/fixtures/debugging-and-repair/task-1202-flakey-test-fix/planner/expected.json b/fixtures/debugging-and-repair/task-1202-flakey-test-fix/planner/expected.json
new file mode 100644
index 0000000..14bf701
--- /dev/null
+++ b/fixtures/debugging-and-repair/task-1202-flakey-test-fix/planner/expected.json
@@ -0,0 +1,14 @@
+{
+ "tasks": [
+ {
+ "id": "fix-race-condition",
+ "type": "fix",
+ "description": "Update test/flaky.test.js to use async/await for fetchData",
+ "complexity": "low",
+ "file": "test/flaky.test.js",
+ "dependsOn": []
+ }
+ ],
+ "ambiguities": [],
+ "invalidTaskCount": 0
+}
\ No newline at end of file
diff --git a/fixtures/debugging-and-repair/task-1202-flakey-test-fix/planner/prompt.md b/fixtures/debugging-and-repair/task-1202-flakey-test-fix/planner/prompt.md
new file mode 100644
index 0000000..3f831b6
--- /dev/null
+++ b/fixtures/debugging-and-repair/task-1202-flakey-test-fix/planner/prompt.md
@@ -0,0 +1,16 @@
+You are a tech lead dealing with a flaky test.
+
+## Context
+Architect's Summary: "Fix race condition in `test/flaky.test.js` by awaiting the async `fetchData` call."
+
+## Files
+`test/flaky.test.js`:
+```js
+test('fetches data', () => {
+ const data = fetchData();
+ expect(data).toBe('success');
+});
+```
+
+## Task
+Plan the fix.
diff --git a/fixtures/debugging-and-repair/task-1202-flakey-test-fix/planner/verify.ts b/fixtures/debugging-and-repair/task-1202-flakey-test-fix/planner/verify.ts
new file mode 100644
index 0000000..8d5e0ce
--- /dev/null
+++ b/fixtures/debugging-and-repair/task-1202-flakey-test-fix/planner/verify.ts
@@ -0,0 +1,13 @@
+import {
+ verifyPlanner,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyPlanner(ctx, (out) => {
+ if (out.tasks.length !== 1) return { ok: false, reason: "Should have 1 task" };
+ if (out.tasks[0].file !== "test/flaky.test.js") return { ok: false, reason: "Target file mismatch" };
+ return { ok: true };
+ });
+}
diff --git a/fixtures/debugging-and-repair/task-1202-flakey-test-fix/reviewer/expected.json b/fixtures/debugging-and-repair/task-1202-flakey-test-fix/reviewer/expected.json
new file mode 100644
index 0000000..2bda5fa
--- /dev/null
+++ b/fixtures/debugging-and-repair/task-1202-flakey-test-fix/reviewer/expected.json
@@ -0,0 +1,11 @@
+{
+ "decision": "approve",
+ "comments": [
+ {
+ "message": "Correct fix. Awaiting the promise ensures the test waits for completion.",
+ "path": "test/flaky.test.js",
+ "line": 1,
+ "blocking": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/fixtures/debugging-and-repair/task-1202-flakey-test-fix/reviewer/prompt.md b/fixtures/debugging-and-repair/task-1202-flakey-test-fix/reviewer/prompt.md
new file mode 100644
index 0000000..6461524
--- /dev/null
+++ b/fixtures/debugging-and-repair/task-1202-flakey-test-fix/reviewer/prompt.md
@@ -0,0 +1,22 @@
+You are a senior code reviewer.
+
+## Task
+Review the flaky test fix.
+
+## Patch
+```diff
+diff --git a/test/flaky.test.js b/test/flaky.test.js
+index 1234567..8901234 100644
+--- a/test/flaky.test.js
++++ b/test/flaky.test.js
+@@ -1,4 +1,4 @@
+-test('fetches data', () => {
+- const data = fetchData();
++test('fetches data', async () => {
++ const data = await fetchData();
+ expect(data).toBe('success');
+ });
+```
+
+## Considerations
+- Does it fix the race condition?
diff --git a/fixtures/debugging-and-repair/task-1202-flakey-test-fix/reviewer/verify.ts b/fixtures/debugging-and-repair/task-1202-flakey-test-fix/reviewer/verify.ts
new file mode 100644
index 0000000..b88ccd9
--- /dev/null
+++ b/fixtures/debugging-and-repair/task-1202-flakey-test-fix/reviewer/verify.ts
@@ -0,0 +1,12 @@
+import {
+ verifyReviewer,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyReviewer(ctx, (output) => {
+ if (output.decision !== "approve") return { ok: false, reason: "Should approve" };
+ return { ok: true };
+ });
+}
diff --git a/fixtures/dependency-management/task-1001-security-audit-fix/architect/expected.json b/fixtures/dependency-management/task-1001-security-audit-fix/architect/expected.json
new file mode 100644
index 0000000..2f0e2ee
--- /dev/null
+++ b/fixtures/dependency-management/task-1001-security-audit-fix/architect/expected.json
@@ -0,0 +1,12 @@
+{
+ "feasibility": "feasible",
+ "highLevelSummary": "Update `lodash` from 4.17.15 to 4.17.21 to resolve a prototype pollution vulnerability. No other dependencies should be changed.",
+ "complexity": "low",
+ "pagesOrScreens": [],
+ "apis": [],
+ "dataModels": [],
+ "recommendedFileStructure": [
+ "package.json",
+ "package-lock.json"
+ ]
+}
\ No newline at end of file
diff --git a/fixtures/dependency-management/task-1001-security-audit-fix/architect/prompt.md b/fixtures/dependency-management/task-1001-security-audit-fix/architect/prompt.md
new file mode 100644
index 0000000..6404398
--- /dev/null
+++ b/fixtures/dependency-management/task-1001-security-audit-fix/architect/prompt.md
@@ -0,0 +1,26 @@
+You are a senior software architect.
+
+## Context
+A security audit has identified a critical vulnerability in the `lodash` dependency (version 4.17.15) used in our project. The vulnerability allows prototype pollution.
+The security team recommends upgrading `lodash` to version `4.17.21`.
+
+## Files
+`package.json`:
+```json
+{
+ "name": "my-service",
+ "dependencies": {
+ "lodash": "4.17.15",
+ "express": "4.17.1"
+ }
+}
+```
+
+## Task
+Describe the architectural changes needed to fix this vulnerability.
+
+## Constraints
+- Upgrade `lodash` to exactly `4.17.21`.
+- Do **not** upgrade `express` or any other dependencies.
+- Do **not** change any application code unless the API has changed (it hasn't).
+- Explicitly state the non-goal of general dependency updates.
diff --git a/fixtures/dependency-management/task-1001-security-audit-fix/architect/verify.ts b/fixtures/dependency-management/task-1001-security-audit-fix/architect/verify.ts
new file mode 100644
index 0000000..62c73f4
--- /dev/null
+++ b/fixtures/dependency-management/task-1001-security-audit-fix/architect/verify.ts
@@ -0,0 +1,33 @@
+import {
+ verifyArchitect,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyArchitect(ctx, (spec) => {
+ const summary = spec.highLevelSummary.toLowerCase();
+
+ if (!summary.includes("lodash")) {
+ return {
+ ok: false,
+ reason: "highLevelSummary must mention lodash",
+ };
+ }
+
+ if (!summary.includes("4.17.21")) {
+ return {
+ ok: false,
+ reason: "highLevelSummary must mention the target version 4.17.21",
+ };
+ }
+
+ // Check for non-goal or constraint awareness
+ if (!summary.includes("no other") && !summary.includes("only")) {
+ // Ideally we want to ensure they don't upgrade everything, but a strict check might be flaky.
+ // Let's rely on the mention of the specific version for now.
+ }
+
+ return { ok: true };
+ });
+}
diff --git a/fixtures/dependency-management/task-1001-security-audit-fix/coder/expected.patch b/fixtures/dependency-management/task-1001-security-audit-fix/coder/expected.patch
new file mode 100644
index 0000000..db5dfb3
--- /dev/null
+++ b/fixtures/dependency-management/task-1001-security-audit-fix/coder/expected.patch
@@ -0,0 +1,12 @@
+diff --git a/package.json b/package.json
+index 1234567..8901234 100644
+--- a/package.json
++++ b/package.json
+@@ -2,6 +2,6 @@
+ "name": "my-service",
+ "dependencies": {
+- "lodash": "4.17.15",
++ "lodash": "4.17.21",
+ "express": "4.17.1"
+ }
+ }
diff --git a/fixtures/dependency-management/task-1001-security-audit-fix/coder/prompt.md b/fixtures/dependency-management/task-1001-security-audit-fix/coder/prompt.md
new file mode 100644
index 0000000..93ce192
--- /dev/null
+++ b/fixtures/dependency-management/task-1001-security-audit-fix/coder/prompt.md
@@ -0,0 +1,21 @@
+You are a senior developer.
+
+## Task
+Update the `lodash` dependency in `package.json` to version `4.17.21`.
+
+## Files
+`package.json`:
+```json
+{
+ "name": "my-service",
+ "dependencies": {
+ "lodash": "4.17.15",
+ "express": "4.17.1"
+ }
+}
+```
+
+## Constraints
+- Only update `lodash`.
+- Do not change `express`.
+- Return a unified diff.
diff --git a/fixtures/dependency-management/task-1001-security-audit-fix/coder/verify.ts b/fixtures/dependency-management/task-1001-security-audit-fix/coder/verify.ts
new file mode 100644
index 0000000..b9a679c
--- /dev/null
+++ b/fixtures/dependency-management/task-1001-security-audit-fix/coder/verify.ts
@@ -0,0 +1,33 @@
+import {
+ verifyCoder,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyCoder(ctx, (patch) => {
+ if (!patch.includes("package.json")) {
+ return {
+ ok: false,
+ reason: "Patch must target package.json",
+ };
+ }
+
+ if (!patch.includes(`+ "lodash": "4.17.21"`)) {
+ return {
+ ok: false,
+ reason: "Patch must add the correct lodash version",
+ };
+ }
+
+ if (patch.includes("express")) {
+ // We want to ensure express isn't *changed*.
+ // A unified diff context might show express, so simple includes check is risky.
+ // But verifyCoder checks the *content* of the patch.
+ // If the patch *modifies* express, it would show as -/+ lines.
+ // If it shows as context, it's fine.
+ }
+
+ return { ok: true };
+ });
+}
diff --git a/fixtures/dependency-management/task-1001-security-audit-fix/planner/expected.json b/fixtures/dependency-management/task-1001-security-audit-fix/planner/expected.json
new file mode 100644
index 0000000..7bb031d
--- /dev/null
+++ b/fixtures/dependency-management/task-1001-security-audit-fix/planner/expected.json
@@ -0,0 +1,24 @@
+{
+ "tasks": [
+ {
+ "id": "update-lodash",
+ "type": "fix",
+ "description": "Update lodash to version 4.17.21 in package.json and update lockfile",
+ "complexity": "low",
+ "file": "package.json",
+ "dependsOn": []
+ },
+ {
+ "id": "verify-update",
+ "type": "unknown",
+ "description": "Verify that the build passes and lodash is at the correct version",
+ "complexity": "low",
+ "file": "package.json",
+ "dependsOn": [
+ "update-lodash"
+ ]
+ }
+ ],
+ "ambiguities": [],
+ "invalidTaskCount": 0
+}
\ No newline at end of file
diff --git a/fixtures/dependency-management/task-1001-security-audit-fix/planner/prompt.md b/fixtures/dependency-management/task-1001-security-audit-fix/planner/prompt.md
new file mode 100644
index 0000000..51ae95d
--- /dev/null
+++ b/fixtures/dependency-management/task-1001-security-audit-fix/planner/prompt.md
@@ -0,0 +1,20 @@
+You are a tech lead planning the fix for the `lodash` vulnerability.
+
+## Context
+Architect's Summary: "Update `lodash` from 4.17.15 to 4.17.21 to resolve a prototype pollution vulnerability. No other dependencies should be changed."
+
+## Files
+`package.json`:
+```json
+{
+ "name": "my-service",
+ "dependencies": {
+ "lodash": "4.17.15",
+ "express": "4.17.1"
+ }
+}
+```
+
+## Task
+Produce a development plan to implement this fix.
+The plan should be concise and focused only on this update.
diff --git a/fixtures/dependency-management/task-1001-security-audit-fix/planner/verify.ts b/fixtures/dependency-management/task-1001-security-audit-fix/planner/verify.ts
new file mode 100644
index 0000000..31382fc
--- /dev/null
+++ b/fixtures/dependency-management/task-1001-security-audit-fix/planner/verify.ts
@@ -0,0 +1,27 @@
+import {
+ verifyPlanner,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyPlanner(ctx, (out) => {
+ const updateTask = out.tasks.find((t) =>
+ t.description.toLowerCase().includes("lodash")
+ );
+
+ if (!updateTask) {
+ return {
+ ok: false,
+ reason: "Must include a task to update lodash",
+ };
+ }
+
+ // Check constraints
+ if (out.tasks.length > 3) {
+ return { ok: false, reason: "Plan is too bloated for a single dep update" };
+ }
+
+ return { ok: true };
+ });
+}
diff --git a/fixtures/dependency-management/task-1001-security-audit-fix/reviewer/expected.json b/fixtures/dependency-management/task-1001-security-audit-fix/reviewer/expected.json
new file mode 100644
index 0000000..5221b3d
--- /dev/null
+++ b/fixtures/dependency-management/task-1001-security-audit-fix/reviewer/expected.json
@@ -0,0 +1,11 @@
+{
+ "decision": "approve",
+ "comments": [
+ {
+ "message": "Looks good. Correctly updates lodash to 4.17.21.",
+ "path": "package.json",
+ "line": 4,
+ "blocking": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/fixtures/dependency-management/task-1001-security-audit-fix/reviewer/prompt.md b/fixtures/dependency-management/task-1001-security-audit-fix/reviewer/prompt.md
new file mode 100644
index 0000000..91e362c
--- /dev/null
+++ b/fixtures/dependency-management/task-1001-security-audit-fix/reviewer/prompt.md
@@ -0,0 +1,24 @@
+You are a senior code reviewer.
+
+## Task
+Review the provided patch for the `lodash` vulnerability fix (upgrade to 4.17.21).
+
+## Patch
+```diff
+diff --git a/package.json b/package.json
+index 1234567..8901234 100644
+--- a/package.json
++++ b/package.json
+@@ -2,6 +2,6 @@
+ "name": "my-service",
+ "dependencies": {
+- "lodash": "4.17.15",
++ "lodash": "4.17.21",
+ "express": "4.17.1"
+ }
+ }
+```
+
+## Considerations
+- Is the version correct?
+- Are there any unrelated changes?
diff --git a/fixtures/dependency-management/task-1001-security-audit-fix/reviewer/verify.ts b/fixtures/dependency-management/task-1001-security-audit-fix/reviewer/verify.ts
new file mode 100644
index 0000000..9ed600e
--- /dev/null
+++ b/fixtures/dependency-management/task-1001-security-audit-fix/reviewer/verify.ts
@@ -0,0 +1,28 @@
+import {
+ verifyReviewer,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyReviewer(ctx, (output) => {
+ if (output.decision !== "approve") {
+ return {
+ ok: false,
+ reason: "The patch is correct and should be approved",
+ };
+ }
+
+ // Check key phrases in comments instead of summary
+ const hasLodashComment = output.comments.some(c =>
+ c.message.toLowerCase().includes("lodash") ||
+ c.message.toLowerCase().includes("version")
+ );
+
+ if (!hasLodashComment && output.comments.length > 0) {
+ // loose check
+ }
+
+ return { ok: true };
+ });
+}
diff --git a/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/architect/expected.json b/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/architect/expected.json
new file mode 100644
index 0000000..ad4f1e8
--- /dev/null
+++ b/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/architect/expected.json
@@ -0,0 +1,13 @@
+{
+ "feasibility": "feasible",
+ "highLevelSummary": "Upgrade React and ReactDOM to React 18. Replace legacy `ReactDOM.render` with `ReactDOM.createRoot` in `src/index.js`.",
+ "complexity": "medium",
+ "pagesOrScreens": [],
+ "apis": [],
+ "dataModels": [],
+ "recommendedFileStructure": [
+ "package.json",
+ "package-lock.json",
+ "src/index.js"
+ ]
+}
\ No newline at end of file
diff --git a/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/architect/prompt.md b/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/architect/prompt.md
new file mode 100644
index 0000000..cff64dc
--- /dev/null
+++ b/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/architect/prompt.md
@@ -0,0 +1,29 @@
+You are a senior software architect.
+
+## Context
+We need to upgrade our frontend application from React 17 to React 18.
+This is a major upgrade with breaking changes, specifically the new Root API for rendering.
+
+## Files
+`package.json`:
+```json
+{
+ "dependencies": {
+ "react": "^17.0.2",
+ "react-dom": "^17.0.2"
+ }
+}
+```
+
+`src/index.js`:
+```js
+import React from 'react';
+import ReactDOM from 'react-dom';
+import App from './App';
+
+ReactDOM.render(, document.getElementById('root'));
+```
+
+## Task
+Describe the necessary changes to upgrade to React 18 and switch to the new Root API.
+Do NOT change any application features, only the migration.
diff --git a/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/architect/verify.ts b/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/architect/verify.ts
new file mode 100644
index 0000000..b652011
--- /dev/null
+++ b/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/architect/verify.ts
@@ -0,0 +1,20 @@
+import {
+ verifyArchitect,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyArchitect(ctx, (spec) => {
+ const summary = spec.highLevelSummary.toLowerCase();
+
+ if (!summary.includes("react 18")) {
+ return { ok: false, reason: "Must mention React 18" };
+ }
+ if (!summary.includes("createroot")) {
+ return { ok: false, reason: "Must mention createRoot" };
+ }
+
+ return { ok: true };
+ });
+}
diff --git a/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/coder/expected.patch b/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/coder/expected.patch
new file mode 100644
index 0000000..540e52a
--- /dev/null
+++ b/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/coder/expected.patch
@@ -0,0 +1,25 @@
+diff --git a/package.json b/package.json
+index 1234567..8901234 100644
+--- a/package.json
++++ b/package.json
+@@ -2,6 +2,6 @@
+ "dependencies": {
+- "react": "^17.0.2",
+- "react-dom": "^17.0.2"
++ "react": "^18.0.0",
++ "react-dom": "^18.0.0"
+ }
+ }
+diff --git a/src/index.js b/src/index.js
+index 1234567..8901234 100644
+--- a/src/index.js
++++ b/src/index.js
+@@ -1,5 +1,6 @@
+ import React from 'react';
+-import ReactDOM from 'react-dom';
++import { createRoot } from 'react-dom/client';
+ import App from './App';
+
+-ReactDOM.render(, document.getElementById('root'));
++const root = createRoot(document.getElementById('root'));
++root.render();
diff --git a/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/coder/prompt.md b/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/coder/prompt.md
new file mode 100644
index 0000000..c67bbaf
--- /dev/null
+++ b/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/coder/prompt.md
@@ -0,0 +1,29 @@
+You are a senior developer.
+
+## Task
+Implement the React 18 upgrade and migration.
+1. Update `package.json` dependencies for `react` and `react-dom` to `^18.0.0`.
+2. Update `src/index.js` to use `ReactDOM.createRoot` instead of `ReactDOM.render`.
+
+## Files
+`package.json`:
+```json
+{
+ "dependencies": {
+ "react": "^17.0.2",
+ "react-dom": "^17.0.2"
+ }
+}
+```
+
+`src/index.js`:
+```js
+import React from 'react';
+import ReactDOM from 'react-dom';
+import App from './App';
+
+ReactDOM.render(, document.getElementById('root'));
+```
+
+## Constraints
+- Return a unified diff.
diff --git a/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/coder/verify.ts b/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/coder/verify.ts
new file mode 100644
index 0000000..21d6120
--- /dev/null
+++ b/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/coder/verify.ts
@@ -0,0 +1,17 @@
+import {
+ verifyCoder,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyCoder(ctx, (patch) => {
+ if (!patch.includes("react-dom/client")) {
+ return { ok: false, reason: "Must import from react-dom/client" };
+ }
+ if (!patch.includes("createRoot")) {
+ return { ok: false, reason: "Must use createRoot" };
+ }
+ return { ok: true };
+ });
+}
diff --git a/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/planner/expected.json b/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/planner/expected.json
new file mode 100644
index 0000000..fe5ced3
--- /dev/null
+++ b/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/planner/expected.json
@@ -0,0 +1,24 @@
+{
+ "tasks": [
+ {
+ "id": "upgrade-deps",
+ "type": "fix",
+ "description": "Upgrade react and react-dom to version 18 in package.json",
+ "complexity": "low",
+ "file": "package.json",
+ "dependsOn": []
+ },
+ {
+ "id": "migrate-render",
+ "type": "refactor",
+ "description": "Replace ReactDOM.render with ReactDOM.createRoot in src/index.js",
+ "complexity": "low",
+ "file": "src/index.js",
+ "dependsOn": [
+ "upgrade-deps"
+ ]
+ }
+ ],
+ "ambiguities": [],
+ "invalidTaskCount": 0
+}
\ No newline at end of file
diff --git a/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/planner/prompt.md b/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/planner/prompt.md
new file mode 100644
index 0000000..20ffbc0
--- /dev/null
+++ b/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/planner/prompt.md
@@ -0,0 +1,27 @@
+You are a tech lead planning a major React upgrade.
+
+## Context
+Architect's Summary: "Upgrade React and ReactDOM to version 18. Replace legacy `ReactDOM.render` with `ReactDOM.createRoot` in `src/index.js`."
+
+## Files
+`package.json`:
+```json
+{
+ "dependencies": {
+ "react": "^17.0.2",
+ "react-dom": "^17.0.2"
+ }
+}
+```
+
+`src/index.js`:
+```js
+import React from 'react';
+import ReactDOM from 'react-dom';
+import App from './App';
+
+ReactDOM.render(, document.getElementById('root'));
+```
+
+## Task
+Create a plan to implement these changes.
diff --git a/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/planner/verify.ts b/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/planner/verify.ts
new file mode 100644
index 0000000..8697b52
--- /dev/null
+++ b/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/planner/verify.ts
@@ -0,0 +1,17 @@
+import {
+ verifyPlanner,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyPlanner(ctx, (out) => {
+ const hasUpgrade = out.tasks.some(t => t.file === "package.json" && t.description.includes("18"));
+ const hasRefactor = out.tasks.some(t => t.file === "src/index.js" && t.description.includes("createRoot"));
+
+ if (!hasUpgrade) return { ok: false, reason: "Missing dependency upgrade task" };
+ if (!hasRefactor) return { ok: false, reason: "Missing code migration task" };
+
+ return { ok: true };
+ });
+}
diff --git a/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/reviewer/expected.json b/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/reviewer/expected.json
new file mode 100644
index 0000000..00083f6
--- /dev/null
+++ b/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/reviewer/expected.json
@@ -0,0 +1,11 @@
+{
+ "decision": "approve",
+ "comments": [
+ {
+ "message": "Correctly updated to React 18 and used createRoot API.",
+ "path": "src/index.js",
+ "line": 4,
+ "blocking": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/reviewer/prompt.md b/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/reviewer/prompt.md
new file mode 100644
index 0000000..cd807d8
--- /dev/null
+++ b/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/reviewer/prompt.md
@@ -0,0 +1,37 @@
+You are a senior code reviewer.
+
+## Task
+Review the React 18 upgrade patch.
+
+## Patch
+```diff
+diff --git a/package.json b/package.json
+index 1234567..8901234 100644
+--- a/package.json
++++ b/package.json
+@@ -2,6 +2,6 @@
+ "dependencies": {
+- "react": "^17.0.2",
+- "react-dom": "^17.0.2"
++ "react": "^18.0.0",
++ "react-dom": "^18.0.0"
+ }
+ }
+diff --git a/src/index.js b/src/index.js
+index 1234567..8901234 100644
+--- a/src/index.js
++++ b/src/index.js
+@@ -1,5 +1,6 @@
+ import React from 'react';
+-import ReactDOM from 'react-dom';
++import { createRoot } from 'react-dom/client';
+ import App from './App';
+
+-ReactDOM.render(, document.getElementById('root'));
++const root = createRoot(document.getElementById('root'));
++root.render();
+```
+
+## Considerations
+- Did they use the new root API?
+- Are the versions correct?
diff --git a/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/reviewer/verify.ts b/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/reviewer/verify.ts
new file mode 100644
index 0000000..b88ccd9
--- /dev/null
+++ b/fixtures/dependency-management/task-1002-major-upgrade-breaking-changes/reviewer/verify.ts
@@ -0,0 +1,12 @@
+import {
+ verifyReviewer,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyReviewer(ctx, (output) => {
+ if (output.decision !== "approve") return { ok: false, reason: "Should approve" };
+ return { ok: true };
+ });
+}
diff --git a/fixtures/documentation/task-1401-add-tsdoc-interfaces/architect/expected.json b/fixtures/documentation/task-1401-add-tsdoc-interfaces/architect/expected.json
new file mode 100644
index 0000000..949423c
--- /dev/null
+++ b/fixtures/documentation/task-1401-add-tsdoc-interfaces/architect/expected.json
@@ -0,0 +1,9 @@
+{
+ "highLevelSummary": "Add TSDoc comments to User interface in src/types/user.ts for better developer experience.",
+ "pagesOrScreens": [],
+ "apis": [],
+ "dataModels": [],
+ "recommendedFileStructure": [
+ "src/types/user.ts"
+ ]
+}
\ No newline at end of file
diff --git a/fixtures/documentation/task-1401-add-tsdoc-interfaces/architect/prompt.md b/fixtures/documentation/task-1401-add-tsdoc-interfaces/architect/prompt.md
new file mode 100644
index 0000000..1d4670f
--- /dev/null
+++ b/fixtures/documentation/task-1401-add-tsdoc-interfaces/architect/prompt.md
@@ -0,0 +1,15 @@
+# Add TSDoc to Interfaces
+
+The `src/types/user.ts` file contains exported interfaces that lack documentation.
+
+## Request
+
+Add TSDoc comments to the `User` interface and its properties.
+- `id`: Unique identifier
+- `name`: Full name of the user
+- `email`: Optional email address
+
+## Non-goals
+
+Do not change any types or runtime behavior.
+Documentation changes only.
diff --git a/fixtures/documentation/task-1401-add-tsdoc-interfaces/architect/repo/src/types/user.ts b/fixtures/documentation/task-1401-add-tsdoc-interfaces/architect/repo/src/types/user.ts
new file mode 100644
index 0000000..d2ba713
--- /dev/null
+++ b/fixtures/documentation/task-1401-add-tsdoc-interfaces/architect/repo/src/types/user.ts
@@ -0,0 +1,5 @@
+export interface User {
+ id: string;
+ name: string;
+ email?: string;
+}
diff --git a/fixtures/documentation/task-1401-add-tsdoc-interfaces/architect/verify.ts b/fixtures/documentation/task-1401-add-tsdoc-interfaces/architect/verify.ts
new file mode 100644
index 0000000..5107305
--- /dev/null
+++ b/fixtures/documentation/task-1401-add-tsdoc-interfaces/architect/verify.ts
@@ -0,0 +1,18 @@
+import {
+ verifyArchitect,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyArchitect(ctx, (spec) => {
+ const summary = spec.highLevelSummary.toLowerCase();
+ if (!summary.includes("tsdoc") && !summary.includes("comment") && !summary.includes("documentation")) {
+ return {
+ ok: false,
+ reason: "Summary must mention TSDoc or documentation",
+ };
+ }
+ return { ok: true };
+ });
+}
diff --git a/fixtures/documentation/task-1401-add-tsdoc-interfaces/coder/expected.patch b/fixtures/documentation/task-1401-add-tsdoc-interfaces/coder/expected.patch
new file mode 100644
index 0000000..b8c6fad
--- /dev/null
+++ b/fixtures/documentation/task-1401-add-tsdoc-interfaces/coder/expected.patch
@@ -0,0 +1,15 @@
+diff --git a/src/types/user.ts b/src/types/user.ts
+--- a/src/types/user.ts
++++ b/src/types/user.ts
+@@ -1,5 +1,10 @@
++/**
++ * User interface representing a system user.
++ */
+ export interface User {
++ /** Unique identifier */
+ id: string;
++ /** Full name of the user */
+ name: string;
++ /** Optional email address */
+ email?: string;
+ }
diff --git a/fixtures/documentation/task-1401-add-tsdoc-interfaces/coder/prompt.md b/fixtures/documentation/task-1401-add-tsdoc-interfaces/coder/prompt.md
new file mode 100644
index 0000000..25efaad
--- /dev/null
+++ b/fixtures/documentation/task-1401-add-tsdoc-interfaces/coder/prompt.md
@@ -0,0 +1,7 @@
+# Add TSDoc Implementation
+
+Add TSDoc comments to `User` interface in `src/types/user.ts`.
+Do not change logic.
+
+## Files
+`src/types/user.ts`
diff --git a/fixtures/documentation/task-1401-add-tsdoc-interfaces/coder/repo/src/types/user.ts b/fixtures/documentation/task-1401-add-tsdoc-interfaces/coder/repo/src/types/user.ts
new file mode 100644
index 0000000..d2ba713
--- /dev/null
+++ b/fixtures/documentation/task-1401-add-tsdoc-interfaces/coder/repo/src/types/user.ts
@@ -0,0 +1,5 @@
+export interface User {
+ id: string;
+ name: string;
+ email?: string;
+}
diff --git a/fixtures/documentation/task-1401-add-tsdoc-interfaces/coder/verify.ts b/fixtures/documentation/task-1401-add-tsdoc-interfaces/coder/verify.ts
new file mode 100644
index 0000000..7c4439a
--- /dev/null
+++ b/fixtures/documentation/task-1401-add-tsdoc-interfaces/coder/verify.ts
@@ -0,0 +1,17 @@
+import {
+ verifyCoder,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyCoder(ctx, (patch) => {
+ if (!patch.includes("src/types/user.ts")) {
+ return { ok: false, reason: "Patch must modify src/types/user.ts" };
+ }
+ if (!patch.includes("/**") || !patch.includes("User interface")) {
+ return { ok: false, reason: "Patch must include TSDoc comments" };
+ }
+ return { ok: true };
+ });
+}
diff --git a/fixtures/documentation/task-1401-add-tsdoc-interfaces/planner/expected.json b/fixtures/documentation/task-1401-add-tsdoc-interfaces/planner/expected.json
new file mode 100644
index 0000000..c246cd2
--- /dev/null
+++ b/fixtures/documentation/task-1401-add-tsdoc-interfaces/planner/expected.json
@@ -0,0 +1,15 @@
+{
+ "tasks": [
+ {
+ "id": "add-tsdoc-user",
+ "title": "Add TSDoc to User interface",
+ "description": "Add TSDoc comments to the User interface and its properties (id, name, email) in src/types/user.ts.",
+ "type": "refactor",
+ "complexity": "low",
+ "file": "src/types/user.ts",
+ "dependsOn": []
+ }
+ ],
+ "ambiguities": [],
+ "invalidTaskCount": 0
+}
\ No newline at end of file
diff --git a/fixtures/documentation/task-1401-add-tsdoc-interfaces/planner/prompt.md b/fixtures/documentation/task-1401-add-tsdoc-interfaces/planner/prompt.md
new file mode 100644
index 0000000..a7c254b
--- /dev/null
+++ b/fixtures/documentation/task-1401-add-tsdoc-interfaces/planner/prompt.md
@@ -0,0 +1,12 @@
+# Add TSDoc Plan
+
+The architect has requested adding TSDoc comments to `src/types/user.ts`.
+
+## Request
+
+Plan to add TSDoc to the `User` interface.
+No logic changes.
+
+## Context
+
+File: `src/types/user.ts` (Interface User)
diff --git a/fixtures/documentation/task-1401-add-tsdoc-interfaces/planner/repo/src/types/user.ts b/fixtures/documentation/task-1401-add-tsdoc-interfaces/planner/repo/src/types/user.ts
new file mode 100644
index 0000000..d2ba713
--- /dev/null
+++ b/fixtures/documentation/task-1401-add-tsdoc-interfaces/planner/repo/src/types/user.ts
@@ -0,0 +1,5 @@
+export interface User {
+ id: string;
+ name: string;
+ email?: string;
+}
diff --git a/fixtures/documentation/task-1401-add-tsdoc-interfaces/planner/verify.ts b/fixtures/documentation/task-1401-add-tsdoc-interfaces/planner/verify.ts
new file mode 100644
index 0000000..c9c0ec5
--- /dev/null
+++ b/fixtures/documentation/task-1401-add-tsdoc-interfaces/planner/verify.ts
@@ -0,0 +1,21 @@
+import {
+ verifyPlanner,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyPlanner(ctx, (plan) => {
+ if (plan.tasks.length !== 1) {
+ return { ok: false, reason: "Plan should have exactly 1 task" };
+ }
+ const task = plan.tasks[0];
+ if (task.type !== "refactor" && task.type !== "fix") {
+ return { ok: false, reason: "Task type should be refactor or fix" };
+ }
+ if (task.file !== "src/types/user.ts") {
+ return { ok: false, reason: "Task must target src/types/user.ts" };
+ }
+ return { ok: true };
+ });
+}
diff --git a/fixtures/documentation/task-1401-add-tsdoc-interfaces/reviewer/expected.json b/fixtures/documentation/task-1401-add-tsdoc-interfaces/reviewer/expected.json
new file mode 100644
index 0000000..d12ba42
--- /dev/null
+++ b/fixtures/documentation/task-1401-add-tsdoc-interfaces/reviewer/expected.json
@@ -0,0 +1,4 @@
+{
+ "decision": "approve",
+ "comments": []
+}
\ No newline at end of file
diff --git a/fixtures/documentation/task-1401-add-tsdoc-interfaces/reviewer/prompt.md b/fixtures/documentation/task-1401-add-tsdoc-interfaces/reviewer/prompt.md
new file mode 100644
index 0000000..e80249f
--- /dev/null
+++ b/fixtures/documentation/task-1401-add-tsdoc-interfaces/reviewer/prompt.md
@@ -0,0 +1,7 @@
+# Review TSDoc Addition
+
+The Coder has added TSDoc comments to `src/types/user.ts`.
+
+## Criteria
+- Comments should be valid TSDoc.
+- No logic changes.
diff --git a/fixtures/documentation/task-1401-add-tsdoc-interfaces/reviewer/repo/src/types/user.ts b/fixtures/documentation/task-1401-add-tsdoc-interfaces/reviewer/repo/src/types/user.ts
new file mode 100644
index 0000000..d2ba713
--- /dev/null
+++ b/fixtures/documentation/task-1401-add-tsdoc-interfaces/reviewer/repo/src/types/user.ts
@@ -0,0 +1,5 @@
+export interface User {
+ id: string;
+ name: string;
+ email?: string;
+}
diff --git a/fixtures/documentation/task-1401-add-tsdoc-interfaces/reviewer/verify.ts b/fixtures/documentation/task-1401-add-tsdoc-interfaces/reviewer/verify.ts
new file mode 100644
index 0000000..1e33c85
--- /dev/null
+++ b/fixtures/documentation/task-1401-add-tsdoc-interfaces/reviewer/verify.ts
@@ -0,0 +1,14 @@
+import {
+ verifyReviewer,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyReviewer(ctx, (review) => {
+ if (review.decision !== "approve") {
+ return { ok: false, reason: "Should approve documentation changes" };
+ }
+ return { ok: true };
+ });
+}
diff --git a/fixtures/modernization/task-1101-convert-cjs-to-esm/architect/expected.json b/fixtures/modernization/task-1101-convert-cjs-to-esm/architect/expected.json
new file mode 100644
index 0000000..1581f17
--- /dev/null
+++ b/fixtures/modernization/task-1101-convert-cjs-to-esm/architect/expected.json
@@ -0,0 +1,11 @@
+{
+ "feasibility": "feasible",
+ "highLevelSummary": "Convert `src/utils.js` from CommonJS to ESM by replacing `module.exports` with named exports.",
+ "complexity": "low",
+ "pagesOrScreens": [],
+ "apis": [],
+ "dataModels": [],
+ "recommendedFileStructure": [
+ "src/utils.js"
+ ]
+}
\ No newline at end of file
diff --git a/fixtures/modernization/task-1101-convert-cjs-to-esm/architect/prompt.md b/fixtures/modernization/task-1101-convert-cjs-to-esm/architect/prompt.md
new file mode 100644
index 0000000..540d150
--- /dev/null
+++ b/fixtures/modernization/task-1101-convert-cjs-to-esm/architect/prompt.md
@@ -0,0 +1,22 @@
+You are a senior software architect.
+
+## Context
+We are modernizing our codebase.
+Convert the legacy CommonJS module `src/utils.js` to ES Modules (ESM).
+We have already updated `package.json` to `"type": "module"`.
+
+## Files
+`src/utils.js`:
+```js
+const add = (a, b) => a + b;
+const subtract = (a, b) => a - b;
+
+module.exports = {
+ add,
+ subtract
+};
+```
+
+## Task
+Describe the changes needed to convert this file to ESM.
+Maintain the same functionality.
diff --git a/fixtures/modernization/task-1101-convert-cjs-to-esm/architect/verify.ts b/fixtures/modernization/task-1101-convert-cjs-to-esm/architect/verify.ts
new file mode 100644
index 0000000..761fd0c
--- /dev/null
+++ b/fixtures/modernization/task-1101-convert-cjs-to-esm/architect/verify.ts
@@ -0,0 +1,15 @@
+import {
+ verifyArchitect,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyArchitect(ctx, (spec) => {
+ const summary = spec.highLevelSummary.toLowerCase();
+ if (!summary.includes("esm") && !summary.includes("es modules")) {
+ return { ok: false, reason: "Must mention ESM conversion" };
+ }
+ return { ok: true };
+ });
+}
diff --git a/fixtures/modernization/task-1101-convert-cjs-to-esm/coder/expected.patch b/fixtures/modernization/task-1101-convert-cjs-to-esm/coder/expected.patch
new file mode 100644
index 0000000..9173db5
--- /dev/null
+++ b/fixtures/modernization/task-1101-convert-cjs-to-esm/coder/expected.patch
@@ -0,0 +1,14 @@
+diff --git a/src/utils.js b/src/utils.js
+index 1234567..8901234 100644
+--- a/src/utils.js
++++ b/src/utils.js
+@@ -1,6 +1,2 @@
+-const add = (a, b) => a + b;
+-const subtract = (a, b) => a - b;
+-
+-module.exports = {
+- add,
+- subtract
+-};
++export const add = (a, b) => a + b;
++export const subtract = (a, b) => a - b;
diff --git a/fixtures/modernization/task-1101-convert-cjs-to-esm/coder/prompt.md b/fixtures/modernization/task-1101-convert-cjs-to-esm/coder/prompt.md
new file mode 100644
index 0000000..d22b64b
--- /dev/null
+++ b/fixtures/modernization/task-1101-convert-cjs-to-esm/coder/prompt.md
@@ -0,0 +1,19 @@
+You are a senior developer.
+
+## Task
+Convert `src/utils.js` to ESM. Use `export` keywords.
+
+## Files
+`src/utils.js`:
+```js
+const add = (a, b) => a + b;
+const subtract = (a, b) => a - b;
+
+module.exports = {
+ add,
+ subtract
+};
+```
+
+## Constraints
+- Return a unified diff.
diff --git a/fixtures/modernization/task-1101-convert-cjs-to-esm/coder/verify.ts b/fixtures/modernization/task-1101-convert-cjs-to-esm/coder/verify.ts
new file mode 100644
index 0000000..95d7a66
--- /dev/null
+++ b/fixtures/modernization/task-1101-convert-cjs-to-esm/coder/verify.ts
@@ -0,0 +1,22 @@
+import {
+ verifyCoder,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyCoder(ctx, (patch) => {
+ if (!patch.includes("export const")) return { ok: false, reason: "Must use export const" };
+
+ // Check if module.exports is added back (fail)
+ // We want to ensure it is removed, so it should be in deleted lines, but not added lines.
+ // Simple string check matches deleted lines.
+
+ const lines = patch.split('\n');
+ const addsModuleExports = lines.some(l => l.startsWith('+') && l.includes('module.exports'));
+
+ if (addsModuleExports) return { ok: false, reason: "Must remove module.exports (not add it)" };
+
+ return { ok: true };
+ });
+}
diff --git a/fixtures/modernization/task-1101-convert-cjs-to-esm/planner/expected.json b/fixtures/modernization/task-1101-convert-cjs-to-esm/planner/expected.json
new file mode 100644
index 0000000..03f378f
--- /dev/null
+++ b/fixtures/modernization/task-1101-convert-cjs-to-esm/planner/expected.json
@@ -0,0 +1,14 @@
+{
+ "tasks": [
+ {
+ "id": "convert-utils",
+ "type": "refactor",
+ "description": "Convert src/utils.js to use ESM syntax (export instead of module.exports)",
+ "complexity": "low",
+ "file": "src/utils.js",
+ "dependsOn": []
+ }
+ ],
+ "ambiguities": [],
+ "invalidTaskCount": 0
+}
\ No newline at end of file
diff --git a/fixtures/modernization/task-1101-convert-cjs-to-esm/planner/prompt.md b/fixtures/modernization/task-1101-convert-cjs-to-esm/planner/prompt.md
new file mode 100644
index 0000000..3984434
--- /dev/null
+++ b/fixtures/modernization/task-1101-convert-cjs-to-esm/planner/prompt.md
@@ -0,0 +1,19 @@
+You are a tech lead planning a migration to ESM.
+
+## Context
+Architect's Summary: "Convert `src/utils.js` from CommonJS to ESM by replacing `module.exports` with named exports."
+
+## Files
+`src/utils.js`:
+```js
+const add = (a, b) => a + b;
+const subtract = (a, b) => a - b;
+
+module.exports = {
+ add,
+ subtract
+};
+```
+
+## Task
+Plan the conversion.
diff --git a/fixtures/modernization/task-1101-convert-cjs-to-esm/planner/verify.ts b/fixtures/modernization/task-1101-convert-cjs-to-esm/planner/verify.ts
new file mode 100644
index 0000000..133c530
--- /dev/null
+++ b/fixtures/modernization/task-1101-convert-cjs-to-esm/planner/verify.ts
@@ -0,0 +1,13 @@
+import {
+ verifyPlanner,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyPlanner(ctx, (out) => {
+ if (out.tasks.length !== 1) return { ok: false, reason: "Should have 1 task" };
+ if (out.tasks[0].file !== "src/utils.js") return { ok: false, reason: "Target file mismatch" };
+ return { ok: true };
+ });
+}
diff --git a/fixtures/modernization/task-1101-convert-cjs-to-esm/reviewer/expected.json b/fixtures/modernization/task-1101-convert-cjs-to-esm/reviewer/expected.json
new file mode 100644
index 0000000..004943f
--- /dev/null
+++ b/fixtures/modernization/task-1101-convert-cjs-to-esm/reviewer/expected.json
@@ -0,0 +1,11 @@
+{
+ "decision": "approve",
+ "comments": [
+ {
+ "message": "Valid ESM conversion.",
+ "path": "src/utils.js",
+ "line": 1,
+ "blocking": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/fixtures/modernization/task-1101-convert-cjs-to-esm/reviewer/prompt.md b/fixtures/modernization/task-1101-convert-cjs-to-esm/reviewer/prompt.md
new file mode 100644
index 0000000..2a1f60b
--- /dev/null
+++ b/fixtures/modernization/task-1101-convert-cjs-to-esm/reviewer/prompt.md
@@ -0,0 +1,25 @@
+You are a senior code reviewer.
+
+## Task
+Review the ESM conversion.
+
+## Patch
+```diff
+diff --git a/src/utils.js b/src/utils.js
+index 1234567..8901234 100644
+--- a/src/utils.js
++++ b/src/utils.js
+@@ -1,6 +1,2 @@
+-const add = (a, b) => a + b;
+-const subtract = (a, b) => a - b;
+-
+-module.exports = {
+- add,
+- subtract
+-};
++export const add = (a, b) => a + b;
++export const subtract = (a, b) => a - b;
+```
+
+## Considerations
+- Is it valid ESM?
diff --git a/fixtures/modernization/task-1101-convert-cjs-to-esm/reviewer/verify.ts b/fixtures/modernization/task-1101-convert-cjs-to-esm/reviewer/verify.ts
new file mode 100644
index 0000000..b88ccd9
--- /dev/null
+++ b/fixtures/modernization/task-1101-convert-cjs-to-esm/reviewer/verify.ts
@@ -0,0 +1,12 @@
+import {
+ verifyReviewer,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyReviewer(ctx, (output) => {
+ if (output.decision !== "approve") return { ok: false, reason: "Should approve" };
+ return { ok: true };
+ });
+}
diff --git a/fixtures/modernization/task-1102-async-await-migration/architect/expected.json b/fixtures/modernization/task-1102-async-await-migration/architect/expected.json
new file mode 100644
index 0000000..d78367b
--- /dev/null
+++ b/fixtures/modernization/task-1102-async-await-migration/architect/expected.json
@@ -0,0 +1,11 @@
+{
+ "feasibility": "feasible",
+ "highLevelSummary": "Refactor `getData` in `src/api.js` to use `async/await` syntax instead of `.then()` chains, ensuring `try/catch` is used for error handling.",
+ "complexity": "low",
+ "pagesOrScreens": [],
+ "apis": [],
+ "dataModels": [],
+ "recommendedFileStructure": [
+ "src/api.js"
+ ]
+}
\ No newline at end of file
diff --git a/fixtures/modernization/task-1102-async-await-migration/architect/prompt.md b/fixtures/modernization/task-1102-async-await-migration/architect/prompt.md
new file mode 100644
index 0000000..053e7f7
--- /dev/null
+++ b/fixtures/modernization/task-1102-async-await-migration/architect/prompt.md
@@ -0,0 +1,26 @@
+You are a senior software architect.
+
+## Context
+We are migrating our async code from Promise chains to `async/await` for better readability.
+Target specific functions in `src/api.js`.
+
+## Files
+`src/api.js`:
+```js
+function getData(url) {
+ return fetch(url)
+ .then(response => response.json())
+ .then(data => {
+ console.log(data);
+ return data;
+ })
+ .catch(error => {
+ console.error(error);
+ throw error;
+ });
+}
+```
+
+## Task
+Describe the refactoring of `getData` to use `async/await`.
+Preserve error handling semantics.
diff --git a/fixtures/modernization/task-1102-async-await-migration/architect/verify.ts b/fixtures/modernization/task-1102-async-await-migration/architect/verify.ts
new file mode 100644
index 0000000..58cb47f
--- /dev/null
+++ b/fixtures/modernization/task-1102-async-await-migration/architect/verify.ts
@@ -0,0 +1,15 @@
+import {
+ verifyArchitect,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyArchitect(ctx, (spec) => {
+ const summary = spec.highLevelSummary.toLowerCase();
+ if (!summary.includes("async") && !summary.includes("await")) {
+ return { ok: false, reason: "Must mention async/await" };
+ }
+ return { ok: true };
+ });
+}
diff --git a/fixtures/modernization/task-1102-async-await-migration/coder/expected.patch b/fixtures/modernization/task-1102-async-await-migration/coder/expected.patch
new file mode 100644
index 0000000..83bf8ab
--- /dev/null
+++ b/fixtures/modernization/task-1102-async-await-migration/coder/expected.patch
@@ -0,0 +1,27 @@
+diff --git a/src/api.js b/src/api.js
+index 1234567..8901234 100644
+--- a/src/api.js
++++ b/src/api.js
+@@ -1,10 +1,11 @@
+-function getData(url) {
+- return fetch(url)
+- .then(response => response.json())
+- .then(data => {
+- console.log(data);
+- return data;
+- })
+- .catch(error => {
+- console.error(error);
+- throw error;
+- });
++async function getData(url) {
++ try {
++ const response = await fetch(url);
++ const data = await response.json();
++ console.log(data);
++ return data;
++ } catch (error) {
++ console.error(error);
++ throw error;
++ }
+ }
diff --git a/fixtures/modernization/task-1102-async-await-migration/coder/prompt.md b/fixtures/modernization/task-1102-async-await-migration/coder/prompt.md
new file mode 100644
index 0000000..2075a7f
--- /dev/null
+++ b/fixtures/modernization/task-1102-async-await-migration/coder/prompt.md
@@ -0,0 +1,24 @@
+You are a senior developer.
+
+## Task
+Refactor `getData` in `src/api.js` to use `async/await`.
+
+## Files
+`src/api.js`:
+```js
+function getData(url) {
+ return fetch(url)
+ .then(response => response.json())
+ .then(data => {
+ console.log(data);
+ return data;
+ })
+ .catch(error => {
+ console.error(error);
+ throw error;
+ });
+}
+```
+
+## Constraints
+- Return a unified diff.
diff --git a/fixtures/modernization/task-1102-async-await-migration/coder/verify.ts b/fixtures/modernization/task-1102-async-await-migration/coder/verify.ts
new file mode 100644
index 0000000..ff81c23
--- /dev/null
+++ b/fixtures/modernization/task-1102-async-await-migration/coder/verify.ts
@@ -0,0 +1,13 @@
+import {
+ verifyCoder,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyCoder(ctx, (patch) => {
+ if (!patch.includes("async function")) return { ok: false, reason: "Must use async function" };
+ if (!patch.includes("await fetch")) return { ok: false, reason: "Must use await fetch" };
+ return { ok: true };
+ });
+}
diff --git a/fixtures/modernization/task-1102-async-await-migration/planner/expected.json b/fixtures/modernization/task-1102-async-await-migration/planner/expected.json
new file mode 100644
index 0000000..f703048
--- /dev/null
+++ b/fixtures/modernization/task-1102-async-await-migration/planner/expected.json
@@ -0,0 +1,14 @@
+{
+ "tasks": [
+ {
+ "id": "refactor-getdata",
+ "type": "refactor",
+ "description": "Refactor getData function in src/api.js to use async/await and try/catch",
+ "complexity": "low",
+ "file": "src/api.js",
+ "dependsOn": []
+ }
+ ],
+ "ambiguities": [],
+ "invalidTaskCount": 0
+}
\ No newline at end of file
diff --git a/fixtures/modernization/task-1102-async-await-migration/planner/prompt.md b/fixtures/modernization/task-1102-async-await-migration/planner/prompt.md
new file mode 100644
index 0000000..941c994
--- /dev/null
+++ b/fixtures/modernization/task-1102-async-await-migration/planner/prompt.md
@@ -0,0 +1,24 @@
+You are a tech lead planning a refactor.
+
+## Context
+Architect's Summary: "Refactor `getData` in `src/api.js` to use `async/await` syntax instead of `.then()` chains."
+
+## Files
+`src/api.js`:
+```js
+function getData(url) {
+ return fetch(url)
+ .then(response => response.json())
+ .then(data => {
+ console.log(data);
+ return data;
+ })
+ .catch(error => {
+ console.error(error);
+ throw error;
+ });
+}
+```
+
+## Task
+Plan the refactoring.
diff --git a/fixtures/modernization/task-1102-async-await-migration/planner/verify.ts b/fixtures/modernization/task-1102-async-await-migration/planner/verify.ts
new file mode 100644
index 0000000..6e12ae0
--- /dev/null
+++ b/fixtures/modernization/task-1102-async-await-migration/planner/verify.ts
@@ -0,0 +1,13 @@
+import {
+ verifyPlanner,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyPlanner(ctx, (out) => {
+ if (out.tasks.length !== 1) return { ok: false, reason: "Should have 1 task" };
+ if (out.tasks[0].file !== "src/api.js") return { ok: false, reason: "Target file mismatch" };
+ return { ok: true };
+ });
+}
diff --git a/fixtures/modernization/task-1102-async-await-migration/reviewer/expected.json b/fixtures/modernization/task-1102-async-await-migration/reviewer/expected.json
new file mode 100644
index 0000000..a6a0228
--- /dev/null
+++ b/fixtures/modernization/task-1102-async-await-migration/reviewer/expected.json
@@ -0,0 +1,11 @@
+{
+ "decision": "approve",
+ "comments": [
+ {
+ "message": "Good refactor. Error handling is preserved with try/catch.",
+ "path": "src/api.js",
+ "line": 1,
+ "blocking": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/fixtures/modernization/task-1102-async-await-migration/reviewer/prompt.md b/fixtures/modernization/task-1102-async-await-migration/reviewer/prompt.md
new file mode 100644
index 0000000..043ad7d
--- /dev/null
+++ b/fixtures/modernization/task-1102-async-await-migration/reviewer/prompt.md
@@ -0,0 +1,38 @@
+You are a senior code reviewer.
+
+## Task
+Review the async/await refactor.
+
+## Patch
+```diff
+diff --git a/src/api.js b/src/api.js
+index 1234567..8901234 100644
+--- a/src/api.js
++++ b/src/api.js
+@@ -1,10 +1,11 @@
+-function getData(url) {
+- return fetch(url)
+- .then(response => response.json())
+- .then(data => {
+- console.log(data);
+- return data;
+- })
+- .catch(error => {
+- console.error(error);
+- throw error;
+- });
++async function getData(url) {
++ try {
++ const response = await fetch(url);
++ const data = await response.json();
++ console.log(data);
++ return data;
++ } catch (error) {
++ console.error(error);
++ throw error;
++ }
+ }
+```
+
+## Considerations
+- Is error handling preserved?
diff --git a/fixtures/modernization/task-1102-async-await-migration/reviewer/verify.ts b/fixtures/modernization/task-1102-async-await-migration/reviewer/verify.ts
new file mode 100644
index 0000000..b88ccd9
--- /dev/null
+++ b/fixtures/modernization/task-1102-async-await-migration/reviewer/verify.ts
@@ -0,0 +1,12 @@
+import {
+ verifyReviewer,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyReviewer(ctx, (output) => {
+ if (output.decision !== "approve") return { ok: false, reason: "Should approve" };
+ return { ok: true };
+ });
+}
diff --git a/fixtures/performance/task-1301-algorithmic-optimization/architect/expected.json b/fixtures/performance/task-1301-algorithmic-optimization/architect/expected.json
new file mode 100644
index 0000000..59caed7
--- /dev/null
+++ b/fixtures/performance/task-1301-algorithmic-optimization/architect/expected.json
@@ -0,0 +1,9 @@
+{
+ "highLevelSummary": "Refactor findDuplicates in src/utils/arrayUtils.ts from O(N^2) to O(N) using a Set, without changing the signature.",
+ "pagesOrScreens": [],
+ "apis": [],
+ "dataModels": [],
+ "recommendedFileStructure": [
+ "src/utils/arrayUtils.ts"
+ ]
+}
\ No newline at end of file
diff --git a/fixtures/performance/task-1301-algorithmic-optimization/architect/prompt.md b/fixtures/performance/task-1301-algorithmic-optimization/architect/prompt.md
new file mode 100644
index 0000000..ba0bc9b
--- /dev/null
+++ b/fixtures/performance/task-1301-algorithmic-optimization/architect/prompt.md
@@ -0,0 +1,13 @@
+# Algorithmic Optimization
+
+The `findDuplicates` function in `src/utils/arrayUtils.ts` is currently implemented with O(N^2) complexity using nested loops, which is causing performance issues.
+
+## Request
+
+Refactor `findDuplicates` to use a Set or hash map to improve performance to O(N).
+Do not change the function signature.
+The return value must still be an array of unique duplicates.
+
+## Non-goals
+
+Do not modify any other files or functions.
diff --git a/fixtures/performance/task-1301-algorithmic-optimization/architect/repo/src/utils/arrayUtils.ts b/fixtures/performance/task-1301-algorithmic-optimization/architect/repo/src/utils/arrayUtils.ts
new file mode 100644
index 0000000..d4ac4a7
--- /dev/null
+++ b/fixtures/performance/task-1301-algorithmic-optimization/architect/repo/src/utils/arrayUtils.ts
@@ -0,0 +1,11 @@
+export function findDuplicates(items: number[]): number[] {
+ const duplicates: number[] = [];
+ for (let i = 0; i < items.length; i++) {
+ for (let j = i + 1; j < items.length; j++) {
+ if (items[i] === items[j] && !duplicates.includes(items[i])) {
+ duplicates.push(items[i]);
+ }
+ }
+ }
+ return duplicates;
+}
diff --git a/fixtures/performance/task-1301-algorithmic-optimization/architect/verify.ts b/fixtures/performance/task-1301-algorithmic-optimization/architect/verify.ts
new file mode 100644
index 0000000..290963b
--- /dev/null
+++ b/fixtures/performance/task-1301-algorithmic-optimization/architect/verify.ts
@@ -0,0 +1,19 @@
+import {
+ verifyArchitect,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyArchitect(ctx, (spec) => {
+ const summary = spec.highLevelSummary.toLowerCase();
+
+ if (!summary.includes("set") && !summary.includes("map") && !summary.includes("o(n)")) {
+ return {
+ ok: false,
+ reason: "highLevelSummary must mention Set, Map, or O(N) complexity improvement",
+ };
+ }
+ return { ok: true };
+ });
+}
diff --git a/fixtures/performance/task-1301-algorithmic-optimization/coder/expected.patch b/fixtures/performance/task-1301-algorithmic-optimization/coder/expected.patch
new file mode 100644
index 0000000..02ec0cb
--- /dev/null
+++ b/fixtures/performance/task-1301-algorithmic-optimization/coder/expected.patch
@@ -0,0 +1,23 @@
+diff --git a/src/utils/arrayUtils.ts b/src/utils/arrayUtils.ts
+--- a/src/utils/arrayUtils.ts
++++ b/src/utils/arrayUtils.ts
+@@ -1,10 +1,11 @@
+ export function findDuplicates(items: number[]): number[] {
+- const duplicates: number[] = [];
+- for (let i = 0; i < items.length; i++) {
+- for (let j = i + 1; j < items.length; j++) {
+- if (items[i] === items[j] && !duplicates.includes(items[i])) {
+- duplicates.push(items[i]);
+- }
++ const seen = new Set();
++ const duplicates = new Set();
++ for (const item of items) {
++ if (seen.has(item)) {
++ duplicates.add(item);
++ } else {
++ seen.add(item);
+ }
+ }
+- return duplicates;
++ return Array.from(duplicates);
+ }
diff --git a/fixtures/performance/task-1301-algorithmic-optimization/coder/prompt.md b/fixtures/performance/task-1301-algorithmic-optimization/coder/prompt.md
new file mode 100644
index 0000000..ac69943
--- /dev/null
+++ b/fixtures/performance/task-1301-algorithmic-optimization/coder/prompt.md
@@ -0,0 +1,11 @@
+# Algorithmic Optimization Implementation
+
+Implement the plan to refactor `findDuplicates` in `src/utils/arrayUtils.ts`.
+
+## Plan
+1. Refactor `findDuplicates` to use a Set for O(N) duplicate detection.
+2. Ensure function signature `(items: number[]): number[]` remains unchanged.
+3. Ensure return value is still an array of unique duplicates.
+
+## Files
+- `src/utils/arrayUtils.ts` (O(N^2) implementation)
diff --git a/fixtures/performance/task-1301-algorithmic-optimization/coder/repo/src/utils/arrayUtils.ts b/fixtures/performance/task-1301-algorithmic-optimization/coder/repo/src/utils/arrayUtils.ts
new file mode 100644
index 0000000..d4ac4a7
--- /dev/null
+++ b/fixtures/performance/task-1301-algorithmic-optimization/coder/repo/src/utils/arrayUtils.ts
@@ -0,0 +1,11 @@
+export function findDuplicates(items: number[]): number[] {
+ const duplicates: number[] = [];
+ for (let i = 0; i < items.length; i++) {
+ for (let j = i + 1; j < items.length; j++) {
+ if (items[i] === items[j] && !duplicates.includes(items[i])) {
+ duplicates.push(items[i]);
+ }
+ }
+ }
+ return duplicates;
+}
diff --git a/fixtures/performance/task-1301-algorithmic-optimization/coder/verify.ts b/fixtures/performance/task-1301-algorithmic-optimization/coder/verify.ts
new file mode 100644
index 0000000..12638aa
--- /dev/null
+++ b/fixtures/performance/task-1301-algorithmic-optimization/coder/verify.ts
@@ -0,0 +1,25 @@
+import {
+ verifyCoder,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyCoder(ctx, (patch) => {
+ // Basic check: file modified
+ if (!patch.includes("src/utils/arrayUtils.ts")) {
+ return {
+ ok: false,
+ reason: "Patch must modify src/utils/arrayUtils.ts",
+ };
+ }
+ // Content check
+ if (!patch.includes("new Set")) {
+ return {
+ ok: false,
+ reason: "Patch must introduce Set usage",
+ };
+ }
+ return { ok: true };
+ });
+}
diff --git a/fixtures/performance/task-1301-algorithmic-optimization/planner/expected.json b/fixtures/performance/task-1301-algorithmic-optimization/planner/expected.json
new file mode 100644
index 0000000..924826f
--- /dev/null
+++ b/fixtures/performance/task-1301-algorithmic-optimization/planner/expected.json
@@ -0,0 +1,15 @@
+{
+ "tasks": [
+ {
+ "id": "refactor-find-duplicates",
+ "title": "Refactor findDuplicates to use Set for O(N) complexity",
+ "description": "Rewrite the findDuplicates logic in src/utils/arrayUtils.ts to use a Set to track seen items, reducing complexity from O(N^2) to O(N). Ensure function signature is preserved.",
+ "type": "refactor",
+ "complexity": "low",
+ "file": "src/utils/arrayUtils.ts",
+ "dependsOn": []
+ }
+ ],
+ "ambiguities": [],
+ "invalidTaskCount": 0
+}
\ No newline at end of file
diff --git a/fixtures/performance/task-1301-algorithmic-optimization/planner/prompt.md b/fixtures/performance/task-1301-algorithmic-optimization/planner/prompt.md
new file mode 100644
index 0000000..eee6de2
--- /dev/null
+++ b/fixtures/performance/task-1301-algorithmic-optimization/planner/prompt.md
@@ -0,0 +1,13 @@
+# Algorithmic Optimization Plan
+
+The architect has identified a performance bottleneck in `src/utils/arrayUtils.ts` (O(N^2) complexity in `findDuplicates`).
+
+## Request
+
+Create a plan to refactor `findDuplicates` to use a Set-based approach (O(N)).
+Ensure the function signature remains unchanged.
+Verify that the implementation passes tests (or in this case, simply compiles and runs).
+
+## Context
+
+The file `src/utils/arrayUtils.ts` exists and contains the slow implementation.
diff --git a/fixtures/performance/task-1301-algorithmic-optimization/planner/repo/src/utils/arrayUtils.ts b/fixtures/performance/task-1301-algorithmic-optimization/planner/repo/src/utils/arrayUtils.ts
new file mode 100644
index 0000000..d4ac4a7
--- /dev/null
+++ b/fixtures/performance/task-1301-algorithmic-optimization/planner/repo/src/utils/arrayUtils.ts
@@ -0,0 +1,11 @@
+export function findDuplicates(items: number[]): number[] {
+ const duplicates: number[] = [];
+ for (let i = 0; i < items.length; i++) {
+ for (let j = i + 1; j < items.length; j++) {
+ if (items[i] === items[j] && !duplicates.includes(items[i])) {
+ duplicates.push(items[i]);
+ }
+ }
+ }
+ return duplicates;
+}
diff --git a/fixtures/performance/task-1301-algorithmic-optimization/planner/verify.ts b/fixtures/performance/task-1301-algorithmic-optimization/planner/verify.ts
new file mode 100644
index 0000000..a5f2b7c
--- /dev/null
+++ b/fixtures/performance/task-1301-algorithmic-optimization/planner/verify.ts
@@ -0,0 +1,30 @@
+import {
+ verifyPlanner,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyPlanner(ctx, (plan) => {
+ if (plan.tasks.length !== 1) {
+ return {
+ ok: false,
+ reason: "Plan should have exactly 1 task",
+ };
+ }
+ const task = plan.tasks[0];
+ if (task.type !== "refactor") {
+ return {
+ ok: false,
+ reason: "Task type must be 'refactor'",
+ };
+ }
+ if (task.file !== "src/utils/arrayUtils.ts") {
+ return {
+ ok: false,
+ reason: "Task must target src/utils/arrayUtils.ts",
+ };
+ }
+ return { ok: true };
+ });
+}
diff --git a/fixtures/performance/task-1301-algorithmic-optimization/reviewer/expected.json b/fixtures/performance/task-1301-algorithmic-optimization/reviewer/expected.json
new file mode 100644
index 0000000..d12ba42
--- /dev/null
+++ b/fixtures/performance/task-1301-algorithmic-optimization/reviewer/expected.json
@@ -0,0 +1,4 @@
+{
+ "decision": "approve",
+ "comments": []
+}
\ No newline at end of file
diff --git a/fixtures/performance/task-1301-algorithmic-optimization/reviewer/prompt.md b/fixtures/performance/task-1301-algorithmic-optimization/reviewer/prompt.md
new file mode 100644
index 0000000..911de85
--- /dev/null
+++ b/fixtures/performance/task-1301-algorithmic-optimization/reviewer/prompt.md
@@ -0,0 +1,9 @@
+# Review Algorithm Optimization
+
+The Coder has refactored `findDuplicates` to use a Set. Please review the changes.
+
+## Criteria
+- Time complexity should be O(N).
+- Function signature must be unchanged.
+- Logic must be correct (return value unique duplicates).
+- Code style should be clean.
diff --git a/fixtures/performance/task-1301-algorithmic-optimization/reviewer/repo/src/utils/arrayUtils.ts b/fixtures/performance/task-1301-algorithmic-optimization/reviewer/repo/src/utils/arrayUtils.ts
new file mode 100644
index 0000000..d4ac4a7
--- /dev/null
+++ b/fixtures/performance/task-1301-algorithmic-optimization/reviewer/repo/src/utils/arrayUtils.ts
@@ -0,0 +1,11 @@
+export function findDuplicates(items: number[]): number[] {
+ const duplicates: number[] = [];
+ for (let i = 0; i < items.length; i++) {
+ for (let j = i + 1; j < items.length; j++) {
+ if (items[i] === items[j] && !duplicates.includes(items[i])) {
+ duplicates.push(items[i]);
+ }
+ }
+ }
+ return duplicates;
+}
diff --git a/fixtures/performance/task-1301-algorithmic-optimization/reviewer/verify.ts b/fixtures/performance/task-1301-algorithmic-optimization/reviewer/verify.ts
new file mode 100644
index 0000000..1266ca8
--- /dev/null
+++ b/fixtures/performance/task-1301-algorithmic-optimization/reviewer/verify.ts
@@ -0,0 +1,17 @@
+import {
+ verifyReviewer,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyReviewer(ctx, (review) => {
+ if (review.decision !== "approve") {
+ return {
+ ok: false,
+ reason: "Reviewer should approve the correct refactor",
+ };
+ }
+ return { ok: true };
+ });
+}
diff --git a/fixtures/performance/task-1302-bundle-size-reduction/architect/expected.json b/fixtures/performance/task-1302-bundle-size-reduction/architect/expected.json
new file mode 100644
index 0000000..d58ab39
--- /dev/null
+++ b/fixtures/performance/task-1302-bundle-size-reduction/architect/expected.json
@@ -0,0 +1,9 @@
+{
+ "highLevelSummary": "Refactor src/index.ts to replace full lodash import with granular import of uniq to reduce bundle size.",
+ "pagesOrScreens": [],
+ "apis": [],
+ "dataModels": [],
+ "recommendedFileStructure": [
+ "src/index.ts"
+ ]
+}
\ No newline at end of file
diff --git a/fixtures/performance/task-1302-bundle-size-reduction/architect/prompt.md b/fixtures/performance/task-1302-bundle-size-reduction/architect/prompt.md
new file mode 100644
index 0000000..2d7d5e6
--- /dev/null
+++ b/fixtures/performance/task-1302-bundle-size-reduction/architect/prompt.md
@@ -0,0 +1,12 @@
+# Bundle Size Reduction
+
+The `src/index.ts` file imports the entire `lodash` library using `import * as _`, which increases bundle size significantly.
+
+## Request
+
+Refactor the import to use a granular import for `uniq` (e.g., `import uniq from 'lodash/uniq'`) to enable tree-shaking or simply reduce what is included.
+Verify that the function behavior remains the same.
+
+## Non-goals
+
+Do not change the exported function signature.
diff --git a/fixtures/performance/task-1302-bundle-size-reduction/architect/repo/src/index.ts b/fixtures/performance/task-1302-bundle-size-reduction/architect/repo/src/index.ts
new file mode 100644
index 0000000..47f27fb
--- /dev/null
+++ b/fixtures/performance/task-1302-bundle-size-reduction/architect/repo/src/index.ts
@@ -0,0 +1,5 @@
+import * as _ from 'lodash';
+
+export function processList(items: number[]): number[] {
+ return _.uniq(items);
+}
diff --git a/fixtures/performance/task-1302-bundle-size-reduction/architect/verify.ts b/fixtures/performance/task-1302-bundle-size-reduction/architect/verify.ts
new file mode 100644
index 0000000..84c53ff
--- /dev/null
+++ b/fixtures/performance/task-1302-bundle-size-reduction/architect/verify.ts
@@ -0,0 +1,18 @@
+import {
+ verifyArchitect,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyArchitect(ctx, (spec) => {
+ const summary = spec.highLevelSummary.toLowerCase();
+ if (!summary.includes("import") && !summary.includes("bundle") && !summary.includes("tree-shake")) {
+ return {
+ ok: false,
+ reason: "Summary must mention import refactoring or bundle size",
+ };
+ }
+ return { ok: true };
+ });
+}
diff --git a/fixtures/performance/task-1302-bundle-size-reduction/coder/expected.patch b/fixtures/performance/task-1302-bundle-size-reduction/coder/expected.patch
new file mode 100644
index 0000000..f17f7bf
--- /dev/null
+++ b/fixtures/performance/task-1302-bundle-size-reduction/coder/expected.patch
@@ -0,0 +1,11 @@
+diff --git a/src/index.ts b/src/index.ts
+--- a/src/index.ts
++++ b/src/index.ts
+@@ -1,5 +1,5 @@
+-import * as _ from 'lodash';
++import uniq from 'lodash/uniq';
+
+ export function processList(items: number[]): number[] {
+- return _.uniq(items);
++ return uniq(items);
+ }
diff --git a/fixtures/performance/task-1302-bundle-size-reduction/coder/prompt.md b/fixtures/performance/task-1302-bundle-size-reduction/coder/prompt.md
new file mode 100644
index 0000000..37fcbc0
--- /dev/null
+++ b/fixtures/performance/task-1302-bundle-size-reduction/coder/prompt.md
@@ -0,0 +1,12 @@
+# Bundle Size Reduction Implementation
+
+Refactor `src/index.ts` to reduce bundle size by using granular imports.
+
+## Plan
+
+1. Replace `import * as _ from 'lodash'` with `import uniq from 'lodash/uniq'`.
+2. Update usage of `_.uniq` to `uniq`.
+3. Do not change function signature.
+
+## Files
+`src/index.ts`
diff --git a/fixtures/performance/task-1302-bundle-size-reduction/coder/repo/src/index.ts b/fixtures/performance/task-1302-bundle-size-reduction/coder/repo/src/index.ts
new file mode 100644
index 0000000..47f27fb
--- /dev/null
+++ b/fixtures/performance/task-1302-bundle-size-reduction/coder/repo/src/index.ts
@@ -0,0 +1,5 @@
+import * as _ from 'lodash';
+
+export function processList(items: number[]): number[] {
+ return _.uniq(items);
+}
diff --git a/fixtures/performance/task-1302-bundle-size-reduction/coder/verify.ts b/fixtures/performance/task-1302-bundle-size-reduction/coder/verify.ts
new file mode 100644
index 0000000..d79b15f
--- /dev/null
+++ b/fixtures/performance/task-1302-bundle-size-reduction/coder/verify.ts
@@ -0,0 +1,17 @@
+import {
+ verifyCoder,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyCoder(ctx, (patch) => {
+ if (!patch.includes("src/index.ts")) {
+ return { ok: false, reason: "Patch must modify src/index.ts" };
+ }
+ if (!patch.includes("import uniq from") && !patch.includes("import { uniq } from")) {
+ return { ok: false, reason: "Patch must import uniq explicitly" };
+ }
+ return { ok: true };
+ });
+}
diff --git a/fixtures/performance/task-1302-bundle-size-reduction/planner/expected.json b/fixtures/performance/task-1302-bundle-size-reduction/planner/expected.json
new file mode 100644
index 0000000..583e4dd
--- /dev/null
+++ b/fixtures/performance/task-1302-bundle-size-reduction/planner/expected.json
@@ -0,0 +1,15 @@
+{
+ "tasks": [
+ {
+ "id": "refactor-import",
+ "title": "Refactor lodash import in src/index.ts",
+ "description": "Change the import in `src/index.ts` from `import * as _ from 'lodash'` to a granular import like `import uniq from 'lodash/uniq'` to reduce bundle size. Update usage of `_.uniq` to `uniq`.",
+ "type": "refactor",
+ "complexity": "low",
+ "file": "src/index.ts",
+ "dependsOn": []
+ }
+ ],
+ "ambiguities": [],
+ "invalidTaskCount": 0
+}
\ No newline at end of file
diff --git a/fixtures/performance/task-1302-bundle-size-reduction/planner/prompt.md b/fixtures/performance/task-1302-bundle-size-reduction/planner/prompt.md
new file mode 100644
index 0000000..1007240
--- /dev/null
+++ b/fixtures/performance/task-1302-bundle-size-reduction/planner/prompt.md
@@ -0,0 +1,12 @@
+# Bundle Size Reduction Plan
+
+The architect identified that `src/index.ts` uses `import * as _ from 'lodash'`, which is inefficient.
+
+## Request
+
+Create a plan to refactor `src/index.ts` to use `import uniq from 'lodash/uniq'` (or similar granular import).
+Ensure the function `processList` continues to work (it uses `_.uniq`).
+
+## Context
+
+File: `src/index.ts`
diff --git a/fixtures/performance/task-1302-bundle-size-reduction/planner/repo/src/index.ts b/fixtures/performance/task-1302-bundle-size-reduction/planner/repo/src/index.ts
new file mode 100644
index 0000000..47f27fb
--- /dev/null
+++ b/fixtures/performance/task-1302-bundle-size-reduction/planner/repo/src/index.ts
@@ -0,0 +1,5 @@
+import * as _ from 'lodash';
+
+export function processList(items: number[]): number[] {
+ return _.uniq(items);
+}
diff --git a/fixtures/performance/task-1302-bundle-size-reduction/planner/verify.ts b/fixtures/performance/task-1302-bundle-size-reduction/planner/verify.ts
new file mode 100644
index 0000000..10fba0f
--- /dev/null
+++ b/fixtures/performance/task-1302-bundle-size-reduction/planner/verify.ts
@@ -0,0 +1,30 @@
+import {
+ verifyPlanner,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyPlanner(ctx, (plan) => {
+ if (plan.tasks.length !== 1) {
+ return {
+ ok: false,
+ reason: "Plan should have exactly 1 task",
+ };
+ }
+ const task = plan.tasks[0];
+ if (task.type !== "refactor") {
+ return {
+ ok: false,
+ reason: "Task type must be refactor",
+ };
+ }
+ if (task.file !== "src/index.ts") {
+ return {
+ ok: false,
+ reason: "Task must target src/index.ts",
+ };
+ }
+ return { ok: true };
+ });
+}
diff --git a/fixtures/performance/task-1302-bundle-size-reduction/reviewer/expected.json b/fixtures/performance/task-1302-bundle-size-reduction/reviewer/expected.json
new file mode 100644
index 0000000..d12ba42
--- /dev/null
+++ b/fixtures/performance/task-1302-bundle-size-reduction/reviewer/expected.json
@@ -0,0 +1,4 @@
+{
+ "decision": "approve",
+ "comments": []
+}
\ No newline at end of file
diff --git a/fixtures/performance/task-1302-bundle-size-reduction/reviewer/prompt.md b/fixtures/performance/task-1302-bundle-size-reduction/reviewer/prompt.md
new file mode 100644
index 0000000..7ff78d7
--- /dev/null
+++ b/fixtures/performance/task-1302-bundle-size-reduction/reviewer/prompt.md
@@ -0,0 +1,9 @@
+# Review Bundle Size Reduction
+
+The Coder has refactored `src/index.ts` to use granular imports.
+
+## Criteria
+- Should import `uniq` specifically (e.g. `import uniq from 'lodash/uniq'`).
+- Should not use `import * as _`.
+- Behavior should be preserved.
+- Code style should be clean.
diff --git a/fixtures/performance/task-1302-bundle-size-reduction/reviewer/repo/src/index.ts b/fixtures/performance/task-1302-bundle-size-reduction/reviewer/repo/src/index.ts
new file mode 100644
index 0000000..47f27fb
--- /dev/null
+++ b/fixtures/performance/task-1302-bundle-size-reduction/reviewer/repo/src/index.ts
@@ -0,0 +1,5 @@
+import * as _ from 'lodash';
+
+export function processList(items: number[]): number[] {
+ return _.uniq(items);
+}
diff --git a/fixtures/performance/task-1302-bundle-size-reduction/reviewer/verify.ts b/fixtures/performance/task-1302-bundle-size-reduction/reviewer/verify.ts
new file mode 100644
index 0000000..ef47490
--- /dev/null
+++ b/fixtures/performance/task-1302-bundle-size-reduction/reviewer/verify.ts
@@ -0,0 +1,14 @@
+import {
+ verifyReviewer,
+ type VerifyCtx,
+ type VerifyResult,
+} from "@kit/fixture-helpers";
+
+export function verify(ctx: VerifyCtx): VerifyResult {
+ return verifyReviewer(ctx, (review) => {
+ if (review.decision !== "approve") {
+ return { ok: false, reason: "Should approve valid refactor" };
+ }
+ return { ok: true };
+ });
+}
diff --git a/instructions.md b/instructions.md
index e0d05ac..7799b49 100644
--- a/instructions.md
+++ b/instructions.md
@@ -4,7 +4,7 @@
This guide explains exactly how to create fixtures under `/fixtures/` for all topics, tasks, and agents described in the master JSON. The goal is a fully populated, schema-valid, deterministic fixture suite.
-Follow this process consistently for every task.
+Follow this process consistently for every task in the api-design-and-versioning, database-migrations, config-and-feature-flags, ci-cd-and-automation, and error-handling-and-observability topics.
---
@@ -44,6 +44,28 @@ fixtures/
* Adding a readable slug (`.../task-001-is-even/`) is recommended.
* `repo/` is included only when a scenario requires source files.
* fixtures/zero-change/task-001-is-even/* is already completed and serves as a template for new tasks.
+* Never try to update src/schemas/*.
+
+
+## Documentation-Only Patch Rule
+-----------------------------
+Documentation-only or comment-only patches are explicitly permitted when the architect clearly requests documentation improvements (e.g., TSDoc, README updates, inline comments). Such patches remain subject to all other rules: minimal, atomic, no forbidden paths, and no runtime behavior changes.
+
+
+## Configuration & Non-Source File Safety Rule
+-------------------------------------------
+When a task requires modifying configuration, environment, workflow, or other normally-forbidden files, the architect MUST:
+
+ 1. Explicitly list *every* configuration or non-source file that is permitted
+ to be modified for this task (e.g., .github/workflows/ci.yml,
+ config/staging.json, migrations/001-add-users.sql).
+
+ 2. Reaffirm that all other configuration, environment, or non-source files
+ remain forbidden. No sibling files or directories are implicitly allowed.
+
+This explicit-file-whitelist requirement ensures the planner, coder, and reviewer
+operate with a deterministic and safe scope, preventing accidental or speculative
+changes outside the architect’s intent.
---
diff --git a/topics.json b/topics.json
index a86cf6d..ba16705 100644
--- a/topics.json
+++ b/topics.json
@@ -937,6 +937,475 @@
}
}
]
+ },
+ {
+ "id": "dependency-management",
+ "name": "Dependency Management & Security",
+ "range": "1000-1099",
+ "tasks": [
+ {
+ "id": "task-1001-security-audit-fix",
+ "title": "Fix security vulnerability in dependency",
+ "agents": {
+ "architect": {
+ "description": "Identifies a vulnerable dependency from a security report and specifies the exact target safe version, plus any constraints or non-goals (for example, 'do not change unrelated packages'). Clearly indicates that updating package.json and lockfiles is allowed for this dependency."
+ },
+ "planner": {
+ "description": "Plans a focused upgrade of the vulnerable package and any directly affected dependents, including tasks to run tests or checks that confirm the vulnerability is resolved. Does not introduce unrelated dependency changes."
+ },
+ "coder": {
+ "description": "Updates package.json and the appropriate lockfile entries for the vulnerable dependency, and adjusts usage if the API changed slightly. Keeps the patch minimal and does not modify unrelated dependencies."
+ },
+ "reviewer": {
+ "description": "Verifies that the dependency is upgraded to the specified safe version, that tests or checks pass, and that no unnecessary dependency churn or regressions were introduced."
+ },
+ "swarm": {
+ "description": "End-to-end security patch application and verification, limited to the vulnerable dependency and its immediate impact surface."
+ }
+ }
+ },
+ {
+ "id": "task-1002-major-upgrade-breaking-changes",
+ "title": "Major dependency upgrade with breaking changes",
+ "agents": {
+ "architect": {
+ "description": "Analyzes the release notes and breaking changes for a major library update (for example, a React or database driver upgrade), outlines required code migrations, and explicitly defines scope and non-goals (for example, 'migrate auth flows only; do not refactor unrelated features')."
+ },
+ "planner": {
+ "description": "Creates a structured migration plan that includes dependency updates in package.json/lockfiles and a set of refactoring tasks that touch only the affected modules. Tasks should capture any required API changes and necessary test updates."
+ },
+ "coder": {
+ "description": "Performs the major version upgrade, updates package.json/lockfiles, and refactors only the code affected by the breaking changes to align with the new API surface. Avoids speculative cleanups unrelated to the migration."
+ },
+ "reviewer": {
+ "description": "Checks that deprecated or removed APIs are no longer used, that the code is compatible with the new major version, and that the change set respects the migration scope without introducing unrelated modifications."
+ },
+ "swarm": {
+ "description": "End-to-end major version migration that handles API breakage in a controlled, scoped way and results in passing tests."
+ }
+ }
+ }
+ ]
+ },
+ {
+ "id": "modernization",
+ "name": "Codebase Modernization & Refactoring",
+ "range": "1100-1199",
+ "tasks": [
+ {
+ "id": "task-1101-convert-cjs-to-esm",
+ "title": "Convert CommonJS to ESM",
+ "agents": {
+ "architect": {
+ "description": "Specifies converting a legacy CommonJS module (or small set of modules) to ES Modules (import/export), including any constraints such as which files are in scope and whether package.json \"type\" may be updated. Emphasizes that behavior must remain the same."
+ },
+ "planner": {
+ "description": "Plans file-by-file conversion from require/module.exports to import/export, including any necessary updates to the package.json type field or build config. Ensures the plan is limited to the specified modules."
+ },
+ "coder": {
+ "description": "Rewrites require/module.exports to import/export syntax, fixes relative import paths, and updates any package.json type settings as needed. Does not change runtime behavior beyond what is required for the module system migration."
+ },
+ "reviewer": {
+ "description": "Ensures valid ESM syntax, correct imports/exports, and that the modules behave the same as before. Flags any unintended behavior changes or unnecessary edits."
+ },
+ "swarm": {
+ "description": "End-to-end module system migration for a small, clearly scoped portion of the codebase while preserving behavior."
+ }
+ }
+ },
+ {
+ "id": "task-1102-async-await-migration",
+ "title": "Migrate callbacks/promises to async/await",
+ "agents": {
+ "architect": {
+ "description": "Identifies specific callback-based or complex promise-based code paths that should be simplified using async/await, and states that behavior and error handling must remain semantically equivalent. May highlight tricky flows such as retries or parallelism."
+ },
+ "planner": {
+ "description": "Targets specific functions or modules for async/await refactoring, ensuring the plan is limited to those areas. Includes tasks to preserve error-handling semantics, logging, and ordering."
+ },
+ "coder": {
+ "description": "Refactors the selected code to clean async/await syntax, preserving the original control flow and error handling logic. Does not introduce new features or broaden the scope beyond the identified functions."
+ },
+ "reviewer": {
+ "description": "Verifies that the async behavior, error handling, and side effects strictly match the original behavior, and that tests cover the refactored flows. Flags any behavioral drift or unnecessary changes."
+ },
+ "swarm": {
+ "description": "Code modernization run focused on async/await adoption that improves readability without changing behavior."
+ }
+ }
+ }
+ ]
+ },
+ {
+ "id": "debugging-and-repair",
+ "name": "Debugging & Repository Repair",
+ "range": "1200-1299",
+ "tasks": [
+ {
+ "id": "task-1201-fix-broken-build",
+ "title": "Fix broken build / compilation error",
+ "agents": {
+ "architect": {
+ "description": "Analyzes compilation or build errors (for example, TypeScript type mismatches, missing files, or misconfigured scripts), diagnoses the root cause, and specifies the minimal area of the codebase that should be changed to repair the build."
+ },
+ "planner": {
+ "description": "Creates one or a small number of targeted tasks to resolve the specific build error while avoiding broad, speculative changes. May include a task to adjust configuration or types and a task to run the build to confirm the fix."
+ },
+ "coder": {
+ "description": "Fixes the code or configuration so the build passes, using the smallest reasonable change (for example, adding a missing import or correcting a type). Does not suppress errors with broad ignore flags or unrelated configuration changes."
+ },
+ "reviewer": {
+ "description": "Confirms that the build now passes, that the fix addresses the real root cause, and that the patch does not simply hide the error (for example, by disabling type checking). Flags any unnecessary or risky edits."
+ },
+ "swarm": {
+ "description": "End-to-end repair of a repository in a broken state, resulting in a clean, passing build with minimal, well-justified changes."
+ }
+ }
+ },
+ {
+ "id": "task-1202-flakey-test-fix",
+ "title": "Fix flakey or failing test",
+ "agents": {
+ "architect": {
+ "description": "Identifies a specific test that fails intermittently or under certain conditions, points to likely causes such as race conditions, timing issues, or improper mocking, and describes the expected stable behavior."
+ },
+ "planner": {
+ "description": "Plans a focused investigation and remediation of the flaky test, including tasks to adjust test setup, mocking, or underlying code behavior. Explicitly avoids fixes that simply disable or weaken the test."
+ },
+ "coder": {
+ "description": "Refactors the test and/or implementation code so the test becomes deterministic and reliable (for example, by removing brittle timing assumptions or improper shared state). Does not fix flakiness by adding arbitrary sleeps or skipping the test."
+ },
+ "reviewer": {
+ "description": "Validates that the test is now stable across runs, that the underlying behavior is correct, and that no shortcuts were taken (such as test skipping, excessive timeouts, or over-broad mocking)."
+ },
+ "swarm": {
+ "description": "Scenario focused on making an unreliable test stable through proper debugging of asynchronous or stateful behavior, rather than weakening test coverage."
+ }
+ }
+ }
+ ]
+ },
+ {
+ "id": "performance",
+ "name": "Performance Optimization",
+ "range": "1300-1399",
+ "tasks": [
+ {
+ "id": "task-1301-algorithmic-optimization",
+ "title": "Optimize algorithmic complexity",
+ "agents": {
+ "architect": {
+ "description": "Identifies a specific performance bottleneck (e.g., an O(N^2) lookup) and prescribes a more efficient data structure or algorithm (e.g., using a Set/Map for O(1) access), while warning against premature optimization of non-hot paths."
+ },
+ "planner": {
+ "description": "Plans the refactor to switch algorithms, ensuring that edge cases and correctness tests are retained or updated. Includes validation steps to confirm the performance gain."
+ },
+ "coder": {
+ "description": "Reimplements the logic with the improved algorithm, ensuring the new implementation passes all existing tests and preserves external behavior. Produces a minimal, focused patch."
+ },
+ "reviewer": {
+ "description": "Verifies the time complexity improvement and ensures the code remains readable and correct. Flags any regression in readability or correctness that is not justified by the speedup."
+ },
+ "swarm": {
+ "description": "End-to-end performance refactor improving efficiency while maintaining correctness."
+ }
+ }
+ },
+ {
+ "id": "task-1302-bundle-size-reduction",
+ "title": "Reduction of bundle size via tree-shaking",
+ "agents": {
+ "architect": {
+ "description": "Identifies large imports that can be tree-shaken (e.g. importing an entire library instead of a single submodule) and mandates more granular imports."
+ },
+ "planner": {
+ "description": "Targets specific files and import statements for refinement, ensuring no functionality is lost."
+ },
+ "coder": {
+ "description": "Refactors imports to be more granular and specific, removing unused code paths where possible while preserving behavior."
+ },
+ "reviewer": {
+ "description": "Checks that the application still builds and runs correctly and that refined imports reduce bundle size without regressions."
+ },
+ "swarm": {
+ "description": "Optimization run focusing on efficient packaging and import management."
+ }
+ }
+ }
+ ]
+ },
+ {
+ "id": "documentation",
+ "name": "Documentation & Standardization",
+ "range": "1400-1499",
+ "tasks": [
+ {
+ "id": "task-1401-add-tsdoc-interfaces",
+ "title": "Add TSDoc to exported interfaces",
+ "agents": {
+ "architect": {
+ "description": "Requests the addition of missing TSDoc comments to public interfaces and types to improve developer experience. Makes clear that no logic should be changed and that documentation-only patches are allowed."
+ },
+ "planner": {
+ "description": "Identifies undocumented exported types and creates a plan to document them. Ensures all tasks are documentation-only and do not modify runtime behavior."
+ },
+ "coder": {
+ "description": "Writes clear, concise TSDoc comments for the specified types, explaining properties and usage without altering logic. Produces a documentation-only unified diff, containing only comment additions or updates."
+ },
+ "reviewer": {
+ "description": "Checks that comments are accurate, helpful, and follow standard TSDoc formatting. Ensures the patch is documentation-only (no behavior changes) and flags any unnecessary edits or reformatting."
+ },
+ "swarm": {
+ "description": "Documentation-focused run where the patch consists solely of TSDoc updates, now officially supported by the system."
+ }
+ }
+ }
+ ]
+ },
+ {
+ "id": "api-design-and-versioning",
+ "name": "API Design, Backwards Compatibility, and Versioning",
+ "range": "1500-1599",
+ "tasks": [
+ {
+ "id": "task-1501-non-breaking-additive-change",
+ "title": "Non-breaking additive API change",
+ "agents": {
+ "architect": {
+ "description": "Requests adding an optional field or query parameter to an existing endpoint and states explicitly that the change must be backwards-compatible. No existing client behavior may break."
+ },
+ "planner": {
+ "description": "Creates tasks to update handler logic, request/response types, and tests. Does not produce tasks that remove or rename existing fields or alter established semantics."
+ },
+ "coder": {
+ "description": "Implements the optional field in a minimal patch, updates types, and adds or updates tests. Avoids touching surrounding code or unrelated endpoints."
+ },
+ "reviewer": {
+ "description": "Ensures backwards compatibility is preserved, the new field is optional, and no unrelated refactors or breaking changes appear in the patch."
+ },
+ "swarm": {
+ "description": "End-to-end additive API evolution with zero behavior changes for existing clients."
+ }
+ }
+ },
+ {
+ "id": "task-1502-api-deprecation-and-v2",
+ "title": "Deprecate field and add v2 endpoint",
+ "agents": {
+ "architect": {
+ "description": "Describes a deprecated field in v1 and requests a new v2 endpoint. Specifies v1 must remain fully functional during transition."
+ },
+ "planner": {
+ "description": "Produces tasks to add v2 route, annotate deprecated field in v1, and update tests for both versions. No removal tasks for v1 behavior."
+ },
+ "coder": {
+ "description": "Implements v2 endpoint and deprecation markers while keeping v1 logic intact. Patch must be minimal and aligned with architect scope."
+ },
+ "reviewer": {
+ "description": "Checks that v1 remains untouched behaviorally, v2 is correct, and deprecation markers are present but non-breaking."
+ },
+ "swarm": {
+ "description": "Scenario for careful versioned API evolution handling both old and new contracts."
+ }
+ }
+ }
+ ]
+ },
+ {
+ "id": "database-migrations",
+ "name": "Database Migrations & Data Integrity",
+ "range": "1600-1699",
+ "tasks": [
+ {
+ "id": "task-1601-add-column-with-backfill",
+ "title": "Add non-nullable column safely",
+ "agents": {
+ "architect": {
+ "description": "Requests addition of a non-nullable column using safe multi-step migration: add nullable column -> backfill data -> enforce NOT NULL."
+ },
+ "planner": {
+ "description": "Emits tasks for migration creation, application code adjustments, and backfill checks. No destructive steps."
+ },
+ "coder": {
+ "description": "Implements additive-first migration sequence and code updates. Does not alter unrelated models or tables."
+ },
+ "reviewer": {
+ "description": "Verifies correct ordering (add, backfill, enforce), tests new schema behavior, and ensures zero data loss."
+ },
+ "swarm": {
+ "description": "End-to-end safe DB evolution with data integrity guarantees."
+ }
+ }
+ },
+ {
+ "id": "task-1602-table-split-with-compat",
+ "title": "Table split with compatibility window",
+ "agents": {
+ "architect": {
+ "description": "Describes splitting a large table into two normalized tables while maintaining compatibility for existing queries during the migration window."
+ },
+ "planner": {
+ "description": "Produces tasks for new schema creation, incremental data copy, temporary dual-read/dual-write logic, and eventual cleanup."
+ },
+ "coder": {
+ "description": "Implements migrations and code changes such that no callers break mid-migration; cleanup only after compatibility is confirmed."
+ },
+ "reviewer": {
+ "description": "Checks for compatibility guarantees, safe rollout sequencing, and presence of fallback paths if needed."
+ },
+ "swarm": {
+ "description": "Scenario for multi-step backward-compatible database refactors."
+ }
+ }
+ }
+ ]
+ },
+ {
+ "id": "config-and-feature-flags",
+ "name": "Configuration, Environments, and Feature Flags",
+ "range": "1700-1799",
+ "tasks": [
+ {
+ "id": "task-1701-feature-flagged-rollout",
+ "title": "Add feature behind config flag",
+ "agents": {
+ "architect": {
+ "description": "Requests addition of a new feature behind an existing flag system. Behavior when flag=off must remain identical to current production."
+ },
+ "planner": {
+ "description": "Emits tasks for integrating the feature with the config system, writing tests for both flag states, and updating documentation."
+ },
+ "coder": {
+ "description": "Implements the feature behind a flag; no behavior change when disabled; avoids hardcoded .env changes."
+ },
+ "reviewer": {
+ "description": "Ensures zero regression with the flag off, clean flag integration, and minimal code surface changes."
+ },
+ "swarm": {
+ "description": "End-to-end gated feature rollout ensuring safe, reversible changes."
+ }
+ }
+ },
+ {
+ "id": "task-1702-environment-specific-bugfix",
+ "title": "Fix staging-only config bug",
+ "agents": {
+ "architect": {
+ "description": "Describes a bug affecting staging only. Production config cannot be touched."
+ },
+ "planner": {
+ "description": "Emits tasks to inspect environment configs, correct the staging value, and validate behavior. No changes to production or shared config."
+ },
+ "coder": {
+ "description": "Modifies staging config only; avoids touching production secrets or values."
+ },
+ "reviewer": {
+ "description": "Checks that only the intended environment is changed, no secrets are leaked, and no global hacks are added."
+ },
+ "swarm": {
+ "description": "Scenario to teach precise environment-scoped fixes with zero collateral edits."
+ }
+ }
+ }
+ ]
+ },
+ {
+ "id": "ci-cd-and-automation",
+ "name": "CI/CD Pipelines and Automation",
+ "range": "1800-1899",
+ "tasks": [
+ {
+ "id": "task-1801-add-ci-checks",
+ "title": "Wire lint and test to CI workflow",
+ "agents": {
+ "architect": {
+ "description": "Requests that existing lint and test scripts be executed in CI. No source code changes are allowed."
+ },
+ "planner": {
+ "description": "Creates tasks targeting only config/workflow files. No weakening of tests or logic."
+ },
+ "coder": {
+ "description": "Adds or updates CI workflow to run lint and test scripts. Does not touch application code."
+ },
+ "reviewer": {
+ "description": "Ensures workflow is correct, minimal, and free of hacks like \"|| true\" that mask failures."
+ },
+ "swarm": {
+ "description": "Teaches Swarm CI integration without altering app correctness."
+ }
+ }
+ },
+ {
+ "id": "task-1802-fix-broken-ci-job",
+ "title": "Repair misconfigured pipeline",
+ "agents": {
+ "architect": {
+ "description": "Describes a failing CI job due to configuration error (bad script, missing environment variable, wrong path). Application code is correct."
+ },
+ "planner": {
+ "description": "Produces tasks limited to pipeline config; includes validation to re-run CI checks."
+ },
+ "coder": {
+ "description": "Fixes only workflow/YAML configuration; does not touch any source, tests, or package scripts."
+ },
+ "reviewer": {
+ "description": "Ensures the fix resolves the root cause and does not weaken CI checks."
+ },
+ "swarm": {
+ "description": "Scenario where agents debug pipeline configuration rather than app code."
+ }
+ }
+ }
+ ]
+ },
+ {
+ "id": "error-handling-and-observability",
+ "name": "Error Handling, Logging, and Observability",
+ "range": "1900-1999",
+ "tasks": [
+ {
+ "id": "task-1901-standardize-error-handling",
+ "title": "Consistent error handling pattern",
+ "agents": {
+ "architect": {
+ "description": "Requests standardizing error-handling across selected handlers without changing external API behavior."
+ },
+ "planner": {
+ "description": "Emits tasks for refactoring designated files only, introducing shared error helpers, and updating tests accordingly."
+ },
+ "coder": {
+ "description": "Refactors only targeted paths; maintains old semantics; avoids unrelated cleanup."
+ },
+ "reviewer": {
+ "description": "Ensures behavior is preserved, logs are consistent, and no new failure modes are introduced."
+ },
+ "swarm": {
+ "description": "Scenario ensuring behavior-preserving refactors remain minimal and controlled."
+ }
+ }
+ },
+ {
+ "id": "task-1902-add-structured-logging",
+ "title": "Add structured logs and correlation ID",
+ "agents": {
+ "architect": {
+ "description": "Requests adding structured logging and correlation IDs to critical paths. No PII allowed; no functional change."
+ },
+ "planner": {
+ "description": "Creates tasks to inject logging and propagate the ID through a narrow call chain; includes tests asserting logs when enabled."
+ },
+ "coder": {
+ "description": "Implements logs and ID propagation only in designated areas; avoids touching unrelated modules."
+ },
+ "reviewer": {
+ "description": "Ensures logs omit sensitive data, logging levels are appropriate, and the patch surface is minimal."
+ },
+ "swarm": {
+ "description": "Scenario teaching observability without creating noise, regressions, or unnecessary refactors."
+ }
+ }
+ }
+ ]
}
]
}