devloop-coder.json 4.01 KB
{
  "_doc": "Mock fixture for Coder Agent (todo-be unit). sequence[0]=implement (first try, intentionally buggy in retry demo), sequence[1]=retry (reflective fix).",
  "sequence": [
    {
      "_variant": "implement",
      "chunks": [
        "## step 0 · 读上下文\n",
        "已读 spec.json acceptance_criteria · 3 条\n",
        "\n## step 1-5 · write code/ + contract.json\n",
        "POST /todos · GET /todos\n",
        "\n## step 6 · append coder.log\n",
        "implement 首次实现完成\n"
      ],
      "result": "mock-ok devloop-coder[implement] todo-be: code/ + contract.json + coder.log",
      "files": [
        {
          "path": "units/todo-be/code/server.js",
          "content": "// mock todo-be · attempt 1 (intentionally missing 400 branch for retry demo)\nconst express = require('express');\nconst app = express();\napp.use(express.json());\nconst todos = [];\nlet nextId = 1;\napp.post('/todos', (req, res) => {\n  // BUG: 没校验 text → empty body 会进 todos\n  const t = { id: nextId++, text: req.body.text, done: false, created_at: new Date().toISOString() };\n  todos.push(t);\n  res.status(201).json(t);\n});\napp.get('/todos', (_req, res) => res.json(todos));\nmodule.exports = app;\n"
        },
        {
          "path": "units/todo-be/contract.json",
          "content": "{\n  \"unit_id\": \"todo-be\",\n  \"version\": \"sha256:0000000000000002\",\n  \"exports\": {\n    \"http\": [\n      { \"method\": \"POST\", \"path\": \"/todos\", \"responses\": { \"201\": \"Todo\", \"400\": \"BadRequest\" } },\n      { \"method\": \"GET\", \"path\": \"/todos\", \"responses\": { \"200\": \"Todo[]\" } }\n    ]\n  }\n}\n"
        },
        {
          "path": "units/todo-be/coder.log",
          "content": "---\nattempt: 1\nts: 2026-05-13T10:02:00.000Z\nthis_fix: implement POST/GET /todos with in-memory array\nrationale: minimal happy-path scaffold per spec acceptance_criteria #1 and #2\nchanged_files: [\"code/server.js\", \"contract.json\"]\n---\n\n"
        }
      ]
    },
    {
      "_variant": "retry",
      "chunks": [
        "## step 0 · 读 failures + hint + 自己 coder.log\n",
        "上次失败:POST /todos with empty body 返 201 而期望 400\n",
        "\n## step 1 · 反思\n",
        "上次错: 没校验 req.body.text\n",
        "这次改: 在 handler 入口 if (!req.body?.text) return res.status(400)\n",
        "因为: 400 是参数错语义,201 表示创建成功\n",
        "\n## step 2-5 · 精准 patch + append coder.log\n",
        "改了一行,重写 coder.log retry 模板\n"
      ],
      "result": "mock-ok devloop-coder[retry] todo-be: added body validation; 400 branch covered",
      "files": [
        {
          "path": "units/todo-be/code/server.js",
          "content": "// mock todo-be · attempt 2 (with body validation per retry reflection)\nconst express = require('express');\nconst app = express();\napp.use(express.json());\nconst todos = [];\nlet nextId = 1;\napp.post('/todos', (req, res) => {\n  if (!req.body?.text) return res.status(400).json({ error: 'missing field: text' });\n  const t = { id: nextId++, text: req.body.text, done: false, created_at: new Date().toISOString() };\n  todos.push(t);\n  res.status(201).json(t);\n});\napp.get('/todos', (_req, res) => res.json(todos));\nmodule.exports = app;\n"
        },
        {
          "path": "units/todo-be/coder.log",
          "content": "---\nattempt: 1\nts: 2026-05-13T10:02:00.000Z\nthis_fix: implement POST/GET /todos with in-memory array\nrationale: minimal happy-path scaffold per spec acceptance_criteria #1 and #2\nchanged_files: [\"code/server.js\", \"contract.json\"]\n---\n\n---\nattempt: 2\nts: 2026-05-13T10:03:00.000Z\nlast_failure: POST /todos with empty body returned 201, expected 400\nlast_cause: req.body.text 未校验,空 body 也通过进了 todos\nthis_fix: 在 POST handler 入口加 if (!req.body?.text) return 400\nrationale: 400 是参数错语义;201 表示创建成功。区分 4xx 和 2xx 才符合 contract.\nchanged_files: [\"code/server.js\"]\n---\n\n"
        }
      ]
    }
  ]
}