{
  "version": 1,
  "language": "en",
  "title": "Edits need regression tests",
  "description": "Compare a unique edit followed by locale-isolation and cache-reuse tests with an ambiguous target that causes no write. These are teaching examples of a made-up locale-cache repair.",
  "caption": "Figure 2. A unique edit target permits a write, then tests check locale isolation and cache reuse. Ambiguous targets cause no write in this example; other tools may partly apply edits before failing. Playback is illustrative, not measured runtime.",
  "alt": "Flow diagram: a unique edit target leads to a write and regression tests; an ambiguous target returns a no-write error.",
  "stateLabels": {
    "target": "Edit target",
    "writes": "Completed writes",
    "file": "Cache key in the file",
    "tests": "Regression tests",
    "evidence": "Recorded results",
    "next": "Next decision"
  },
  "targets": {
    "propose": {
      "id": "patch-propose",
      "kind": "node",
      "label": "Propose edit"
    },
    "match": {
      "id": "patch-match",
      "kind": "node",
      "label": "Match source"
    },
    "write": {
      "id": "patch-write",
      "kind": "node",
      "label": "Apply edit"
    },
    "verify": {
      "id": "patch-verify",
      "kind": "node",
      "label": "Verify behavior"
    },
    "reject": {
      "id": "patch-reject",
      "kind": "node",
      "label": "Reject match"
    },
    "request": {
      "id": "patch-request",
      "kind": "edge",
      "label": "Submit edit target"
    },
    "unique": {
      "id": "patch-unique",
      "kind": "edge",
      "label": "Apply unique match"
    },
    "test": {
      "id": "patch-test",
      "kind": "edge",
      "label": "Run regression tests"
    },
    "ambiguous": {
      "id": "patch-ambiguous",
      "kind": "edge",
      "label": "Reject ambiguous target"
    },
    "reread": {
      "id": "patch-reread",
      "kind": "edge",
      "label": "Return no-write feedback"
    }
  },
  "sources": [
    {
      "title": "Original author teaching trace",
      "file": "diagram.svg",
      "sha256": "56b9fe5a2418bebcc80c06b311504908a52e3446c397027e0cfdd303e33ad779"
    },
    {
      "title": "Pi v0.80.6 edit contract",
      "url": "https://github.com/earendil-works/pi/blob/v0.80.6/packages/coding-agent/src/core/tools/edit.ts"
    },
    {
      "title": "Article evidence and version ledger",
      "file": "SOURCE.md"
    }
  ],
  "limitations": [
    "The code and regression outcomes are constructed teaching examples, not a measured repair campaign.",
    "The ambiguous branch guarantees zero writes only in this example. Other tools or multi-file batches can apply changes before reporting failure.",
    "A completed write still needs behavior tests. The focused regression checks only the stated locale isolation and reuse cases.",
    "Playback timing is illustrative, not measured runtime."
  ],
  "scenarios": [
    {
      "id": "unique-verified",
      "title": "Unique target: write and test",
      "description": "A complete, unique replacement updates both lookup and insertion to a document-and-locale key. The focused tests then check locale isolation and same-locale reuse.",
      "initial": {
        "target": "not proposed",
        "writes": "0",
        "file": "document ID only",
        "tests": "not run",
        "evidence": "none",
        "next": "inspect current source"
      },
      "unselected": [
        "reject",
        "ambiguous",
        "reread"
      ],
      "steps": [
        {
          "title": "Propose one coherent replacement",
          "description": "The new key is proposed for both lookup and insertion. The current file has not changed.",
          "duration": 3000,
          "active": [
            "propose"
          ],
          "paths": [],
          "state": {
            "target": "unique function block",
            "writes": "0",
            "file": "document ID only",
            "tests": "not run",
            "evidence": "none",
            "next": "match against current source"
          }
        },
        {
          "title": "Find one current match",
          "description": "This example checks for one matching target before writing.",
          "duration": 3000,
          "active": [
            "match"
          ],
          "paths": [
            "request"
          ],
          "state": {
            "target": "one current match",
            "writes": "0",
            "file": "document ID only",
            "tests": "not run",
            "evidence": "none",
            "next": "apply the accepted replacement"
          }
        },
        {
          "title": "Complete the file change",
          "description": "The write count and cache key change only after the accepted edit arrives and completes.",
          "duration": 3000,
          "active": [
            "write"
          ],
          "paths": [
            "unique"
          ],
          "state": {
            "target": "one current match",
            "writes": "1",
            "file": "document ID + locale",
            "tests": "not run",
            "evidence": "write result recorded",
            "next": "run the focused regression"
          }
        },
        {
          "title": "Verify isolation and reuse",
          "description": "The regression result arrives after the file change. The tests check separate locales and repeated same-locale requests.",
          "duration": 3000,
          "active": [
            "verify"
          ],
          "paths": [
            "test"
          ],
          "state": {
            "target": "one current match",
            "writes": "1",
            "file": "document ID + locale",
            "tests": "focused checks passed",
            "evidence": "locale isolation and same-locale reuse",
            "next": "review final diff and report test scope"
          }
        }
      ]
    },
    {
      "id": "ambiguous-no-write",
      "title": "Ambiguous target: reject without writing",
      "description": "The selected fragment occurs twice. This example rejects it before writing, returns the reason, and ends while the agent reads context for a narrower edit.",
      "initial": {
        "target": "not proposed",
        "writes": "0",
        "file": "document ID only",
        "tests": "not run",
        "evidence": "none",
        "next": "inspect current source"
      },
      "unselected": [
        "write",
        "verify",
        "unique",
        "test"
      ],
      "steps": [
        {
          "title": "Propose an underspecified fragment",
          "description": "The proposal selects a small cache expression that appears twice. No change has been made.",
          "duration": 3000,
          "active": [
            "propose"
          ],
          "paths": [],
          "state": {
            "target": "fragment appears twice",
            "writes": "0",
            "file": "document ID only",
            "tests": "not run",
            "evidence": "none",
            "next": "count matches in current source"
          }
        },
        {
          "title": "Observe two candidate matches",
          "description": "The target is ambiguous in this example. The tool does not choose either match automatically.",
          "duration": 3000,
          "active": [
            "match"
          ],
          "paths": [
            "request"
          ],
          "state": {
            "target": "two current matches",
            "writes": "0",
            "file": "document ID only",
            "tests": "not run",
            "evidence": "ambiguous target",
            "next": "reject before writing"
          }
        },
        {
          "title": "Return a no-write result",
          "description": "The rejection leaves the original file intact. The write count and test status remain unchanged.",
          "duration": 3000,
          "active": [
            "reject"
          ],
          "paths": [
            "ambiguous"
          ],
          "state": {
            "target": "two current matches",
            "writes": "0",
            "file": "document ID only",
            "tests": "not run",
            "evidence": "two matches; file unchanged",
            "next": "read distinguishing function context"
          }
        },
        {
          "title": "Prepare to read distinguishing context",
          "description": "The error returns to the proposal stage. This trace stops before a replacement is resubmitted.",
          "duration": 3000,
          "active": [
            "propose"
          ],
          "paths": [
            "reread"
          ],
          "state": {
            "target": "needs distinguishing context",
            "writes": "0",
            "file": "document ID only",
            "tests": "not run",
            "evidence": "two matches; file unchanged",
            "next": "read source and propose a unique target"
          }
        }
      ]
    }
  ]
}
