Day 57: Coding Agents That Only Emit Intents

Day 57: Coding Agents That Only Emit Intents

LLMs that emit unified diffs against moving files will corrupt JSX “successfully.” Safer coding agents emit intents (AST operations, codemod names, parameter maps). A deterministic apply layer turns intents into patches.

⚡ TL;DR: Model outputs Intent JSON; apply layer runs jscodeshift/libcst/ts-morph. Reject freeform file bytes. Validate AST after apply.

Intent schema

# intents/schema.py
from pydantic import BaseModel, Field
from typing import Literal, Any

class Intent(BaseModel):
    kind: Literal["rename_symbol", "add_import", "wrap_call", "codemod"]
    path: str
    params: dict[str, Any] = Field(default_factory=dict)
    rationale: str
{
  "kind": "rename_symbol",
  "path": "src/billing/invoice.ts",
  "params": {"from": "calcTotal", "to": "calculateInvoiceTotal"},
  "rationale": "Match domain language in ADR-17"
}

Deterministic apply

// apply/rename.ts
import { Project } from "ts-morph";

export function applyRename(path: string, from: string, to: string) {
  const project = new Project();
  const sf = project.addSourceFileAtPath(path);
  sf.getDescendantsOfKind(/* Identifier */).forEach((id) => {
    if (id.getText() === from) id.replaceWithText(to); // ✅ AST-aware
  });
  sf.saveSync();
}
# apply/dispatch.py
HANDLERS = {
  "rename_symbol": apply_rename,
  "add_import": apply_add_import,
  "codemod": apply_named_codemod,
}

def apply_intent(intent: Intent):
    fn = HANDLERS.get(intent.kind)
    if not fn:
        raise ValueError(f"unknown_intent:{intent.kind}")
    return fn(intent.path, **intent.params)

open(path,'w').write(model_bytes) — never let the model own the file body.

Closing checklist

  • [ ] Typed intents only
  • [ ] AST/codemod apply layer
  • [ ] Parse/typecheck after apply
  • [ ] Allowlist codemod names
  • [ ] Keep a rollback snapshot per intent

Series navigation

Day 56: Supervisor Patterns on Bedrock Agents · Day 58: Spec-First: OpenAPI Remains Source of Truth

Last updated September 11, 2026


Discover more from CheatCoders

Subscribe to get the latest posts sent to your email.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply