Skip to content

Proposal: Plan Records - tracking planning documents alongside code attribution #29

@andybrandt

Description

@andybrandt

Proposal: Plan Records for Agent Trace

Every major coding platform with agentic capabilities (Cursor, Claude Code) now has a planning phase where users co-create a design document with AI before code generation begins. Agent Trace captures the code attribution well, but these planning artifacts are currently lost. This proposal adds an optional Plan Record schema for tracking plans committed to the repo, standardized related types for linking code traces to plans, and a path field on related items as a durable alternative to external URLs.

The proposal is additive and backward-compatible, with one minor schema extension (path on related items).

Problem Statement

AI-augmented coding workflows fall on a spectrum:

  • Ad-hoc changes: A developer asks an agent to fix a bug or add a small feature as a result of exchange (prompt - response) in a single conversation or a series of such exchanges building code incrementally. The code is the only meaningful artifact, conversation can be of value and is what current Agent Trace proposal traces.
  • Planned changes: A developer co-creates a design document with an agent, iterates on it, and then it is used by AI to guide code generation. This produces two artifacts: the plan and the code.

The second pattern is not a niche workflow - it is how every major coding agent works today. Cursor has "planning mode." Claude Code has plan mode. It is the recommended way of introducing larger changes to a project. The typical flow is:

  1. Plan - Co-create a design/specification document with an AI agent (usually markdown), iterating until the user accepts the plan (says "build it").
  2. Build - Use that plan to guide AI agents during code generation.
  3. Finishing touches - User then in conversation causes some changes to code as generated or edits the code directly.
  4. Commit - The code enters version control as a new commit.

Agent Trace (v0.1.0) excellently captures step 4 - attributing which code lines came from which AI conversations. It also handles ad-hoc changes well. However, for planned changes, the planning artifacts from step 1 are currently lost. These documents represent significant intellectual investment and are valuable for:

  • Future developers (human or AI) who need to understand why code was structured a certain way
  • Re-generation or refactoring - an agent with the original plan can make better decisions than one working from code alone
  • Audit and review - understanding the intent behind AI-generated code
  • Knowledge continuity for the future

The related array in conversations can link to external resources, but there is no structured way to represent planning documents, their AI attribution, or their relationship to the code they guided.

The URL durability problem

Agent Trace currently relies on URLs to link trace records to conversations (e.g., https://api.cursor.com/v1/conversations/12345). These URLs point to vendor-hosted resources. If the vendor changes their API, the developer switches tools, or a subscription lapses, those URLs become dead links - and the trace records lose most of their contextual value.

For conversation logs, URL references are a reasonable trade-off: full chat histories are large and noisy, and committing them to repos would create significant clutter.

For planning documents, however, the trade-off is different. Plans are relatively concise, purposeful, human-readable artifacts that also frequently contain the rationale or an explanation of the change - exactly the kind of thing that belongs in a repository. This proposal therefore requires that plan documents be committed to the repository, referenced by relative file path rather than external URL. Conversation URLs in plan records remain optional enrichment - useful when they work, but the plan itself survives independently in the repo.

Proposed Changes

1. Standardized related type for plans

Add plan to the recommended vocabulary for the related[].type field:

Type Description
plan A planning/design document that guided code generation

The related[].type field is already an open string, so other document types (architecture decision records, specifications, etc.) can use the same pattern without requiring spec changes.

These types would be used in existing Trace Records to link code back to the plans that produced it. This also requires a minor extension to the related item schema: adding an optional path field as an alternative to url for repo-local resources. Either url or path must be present:

{
  "files": [
    {
      "path": "src/parser.ts",
      "conversations": [
        {
          "url": "https://api.example.com/v1/conversations/build-session",
          "contributor": { "type": "ai", "model_id": "anthropic/claude-sonnet-4-5-20250929" },
          "ranges": [{ "start_line": 1, "end_line": 120 }],
          "related": [
            {
              "type": "plan",
              "path": "docs/plans/parser-redesign.plan.md"
            }
          ]
        }
      ]
    }
  ]
}

The proposed related item schema becomes:

{
  "type": "object",
  "required": ["type"],
  "oneOf": [
    { "required": ["url"] },
    { "required": ["path"] }
  ],
  "properties": {
    "type": { "type": "string" },
    "url": { "type": "string", "format": "uri" },
    "path": {
      "type": "string",
      "description": "Relative path from repository root to a committed file"
    }
  }
}

This path field is useful beyond plans - any repo-committed resource (ADRs, specs, test fixtures) benefits from a durable, repo-local reference instead of an external URL.

2. Plan Record schema (new document type)

Plans are co-created artifacts that deserve their own attribution. A Plan Record captures:

  • The plan content or its location
  • Which AI conversations produced the plan
  • Which trace records (code) the plan guided
  • Attribution on the plan itself
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://agent-trace.dev/schemas/v1/plan-record.json",
  "title": "Agent Trace Plan Record",
  "type": "object",
  "required": ["version", "id", "timestamp", "path"],
  "properties": {
    "version": {
      "type": "string",
      "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$",
      "description": "Agent Trace specification version"
    },
    "id": {
      "type": "string",
      "format": "uuid",
      "description": "Unique identifier for this plan record"
    },
    "timestamp": {
      "type": "string",
      "format": "date-time",
      "description": "RFC 3339 timestamp when plan was recorded"
    },
    "path": {
      "type": "string",
      "description": "Relative path to the plan document from repository root"
    },
    "title": {
      "type": "string",
      "description": "Human-readable title of the plan"
    },
    "status": {
      "type": "string",
      "enum": ["draft", "active", "implemented", "superseded", "abandoned"],
      "description": "Current lifecycle status of the plan"
    },
    "contributor": {
      "$ref": "trace-record.json#/$defs/contributor",
      "description": "Overall attribution for the plan document"
    },
    "conversations": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "description": "URL of the conversation that contributed to this plan"
          },
          "contributor": {
            "$ref": "trace-record.json#/$defs/contributor"
          },
          "role": {
            "type": "string",
            "enum": ["authored", "reviewed", "refined"],
            "description": "How this conversation contributed to the plan"
          }
        }
      },
      "description": "Conversations that produced or refined this plan"
    },
    "guides": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "trace_id": {
            "type": "string",
            "format": "uuid",
            "description": "ID of a Trace Record for code guided by this plan"
          },
          "files": {
            "type": "array",
            "items": { "type": "string" },
            "description": "Subset of files from the trace that this plan guided (optional, omit if all)"
          }
        }
      },
      "description": "Trace records of code that was generated using this plan"
    },
    "supersedes": {
      "type": "string",
      "format": "uuid",
      "description": "ID of a previous plan record this one replaces"
    },
    "metadata": {
      "type": "object",
      "description": "Additional vendor-specific or implementation-specific data"
    }
  }
}

3. Example Plan Record

{
  "version": "0.1.0",
  "id": "7a3f1e00-b2c4-4d5e-8f6a-9b0c1d2e3f4a",
  "timestamp": "2026-03-05T10:00:00Z",
  "path": "docs/plans/parser-redesign.plan.md",
  "title": "Parser module redesign for streaming input",
  "status": "implemented",
  "contributor": { "type": "mixed" },
  "conversations": [
    {
      "url": "https://api.cursor.com/v1/conversations/plan-session-1",
      "contributor": {
        "type": "ai",
        "model_id": "anthropic/claude-opus-4-5-20251101"
      },
      "role": "authored"
    },
    {
      "url": "https://api.cursor.com/v1/conversations/plan-review-1",
      "contributor": {
        "type": "ai",
        "model_id": "anthropic/claude-sonnet-4-5-20250929"
      },
      "role": "reviewed"
    }
  ],
  "guides": [
    {
      "trace_id": "550e8400-e29b-41d4-a716-446655440000",
      "files": ["src/utils/parser.ts", "src/utils/helpers.ts"]
    }
  ]
}

4. Recommended file conventions

Plan documents MUST be committed to the repository. This is a deliberate design choice: unlike conversation logs (which are large, noisy, and best left as external URL references), plans are concise artifacts whose value depends on being durably available alongside the code they produced.

Recommended conventions:

  • Plan documents: docs/plans/*.plan.md (or any path - the path field in the Plan Record is authoritative)
  • Plan records: stored alongside trace records using the same implementation-defined mechanism
  • Plan documents are committed in the same commit (or shortly after) the code they guided
  • Plan records link to committed plan files via relative path from repository root
  • Conversation URLs in the conversations array are optional - they provide additional context when available but the plan document itself is the durable artifact

5. MIME Type addition

Type MIME Type
Plan Record application/vnd.agent-trace.plan+json

Relationship to existing spec

This proposal is additive and backward-compatible with one minor exception:

  • New related type value (plan) is already supported by the open-ended type: string field - no change needed
  • Plan Records are a new, optional document type alongside Trace Records
  • Plan Records reuse the existing contributor definition via $ref

The one schema change is adding an optional path field to related items as an alternative to url, with a oneOf constraint requiring at least one. Existing records with url remain valid. This change addresses a general durability concern that applies beyond plans: any repo-committed resource benefits from a local path reference that survives external service changes.

The spec text changes would be: a standardized type vocabulary table in Section 6.8 (Linked Resources), the path field addition to related items, and a new section for Plan Records.

Design decisions

  1. File reference, not inline content: Plan Records reference committed files via path rather than embedding content. This avoids duplication and ensures the plan document is the single source of truth. Since plans MUST be committed to the repo, durability is guaranteed without inline content.

  2. Plans are optional: Not all code changes involve plans. Ad-hoc fixes, quick bug patches, and conversational coding sessions produce Trace Records without any Plan Record - and that's fine. Plan Records exist for the workflow where planning is a distinct, deliberate step.

  3. Conversation URLs are optional enrichment: The conversations array in Plan Records provides useful provenance when vendor APIs are accessible, but the plan document committed to the repo is the durable artifact. A Plan Record remains fully useful even if every conversation URL in it becomes a dead link.

Open questions

  1. Granular attribution within plans: Should we support range-level attribution within plan documents (similar to code ranges), or is document-level attribution sufficient? Plans tend to be iteratively refined in conversation, making fine-grained attribution complex and potentially low-value.

  2. Scope of the URL durability concern: This proposal addresses URL durability for plans by requiring repo commitment. However, the same concern applies to the existing Agent Trace spec's conversation.url fields. Should a future revision of the core spec recommend that implementations support conversation log export alongside trace records? In some contexts (e.g. tightly regulated industries) ensuring permanence of these conversation logs might be required.

  3. Plan evolution: In current practice, plans are not revisited after implementation - if a developer re-enters planning mode, a new plan is created. However, the "finishing touches" phase (step 3) often produces changes that diverge from the original plan. Once plans are stored in the repo, a natural question arises: should the plan be retroactively updated to reflect what was actually built? If so, should the Plan Record track this (e.g., a revised status or a link to the commit that updated the plan)? Or is it more valuable to preserve the original plan as-is and let the VCS diff tell the story?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions