Skip to content

Charter parsing relies on an implicit exact-Markdown schema that is not formally declared or validated #1522

Description

@dfberry

Summary

Squad appears to have a real charter schema in practice, but that schema is currently implicit in source code rather than explicitly declared as a contract. Agent charter behavior depends on exact H2 section names and exact bold label text inside the Markdown body, while project docs present charter.md as authoritative agent identity and as input to every spawn prompt.

This looks less like a crash bug and more like a design inconsistency / brittleness issue: charter-driven behavior is real and important, but the contract is under-specified for users and contributors.

Problem

Today, charter.md is treated as an authoritative, behavior-affecting document, but its machine-readable structure is effectively defined by parser implementation details.

That means seemingly harmless edits to charter formatting or wording can silently change behavior if they stop matching the parser’s expected section names or labels. The project currently exposes charters as human-authored Markdown, but the runtime treats them as if they follow a strict schema.

Evidence

Local project docs and templates

  • .squad/templates/charter.md defines the default charter shape, including a ## Model section.
  • .squad/templates/model-selection-reference.md says Layer 2 charter preference comes from the charter’s ## Model section, specifically Preferred.
  • .squad/templates/workflow-wiring-guide.md says charter.md is inlined into every spawn prompt.
  • .github/skills/coordinator-source-of-truth/SKILL.md describes .squad/agents/{name}/charter.md as authoritative agent identity.

Upstream implementation

  • packages/squad-sdk/src/agents/charter-compiler.ts defines ParsedCharter with fields such as identity, ownership, boundaries, modelPreference, modelRationale, modelFallback, reasoningEffort, contextTier, and collaboration.
  • parseCharterMarkdown matches exact section headings:
    • ## Identity
    • ## What I Own
    • ## Boundaries
    • ## Model
    • ## Collaboration
  • Within ## Model, it looks for exact bold labels:
    • **Preferred:**
    • **Rationale:**
    • **Fallback:**
    • **Reasoning Effort:**
    • **Context Tier:**
  • compileCharterFull resolves model selection from config override first, then parsed.modelPreference.
  • packages/squad-sdk/src/state/io/charter-io.ts says it produces the canonical charter.md format and serializes back to that same structure.
  • test/charter-compiler.test.ts uses a full charter fixture with that exact structure and asserts extraction of modelPreference, modelRationale, modelFallback, and reasoningEffort from the ## Model section.

Prior related work

Those PRs reinforce that the charter format is semantically important, but they do not appear to formalize the charter contract itself.

Why this is brittle

  • The contract is behaviorally significant but not clearly declared as a schema.
  • Parsing depends on exact Markdown strings rather than a more explicit metadata layer.
  • Contributors may reasonably treat charters as mostly human-readable prose and not realize that changing a heading or label can affect runtime behavior.
  • This creates a mismatch with the rest of the project’s direction, especially where other artifact types have moved toward more explicit schema / metadata contracts.

Expected behavior

If charter.md is authoritative agent identity and a first-class runtime input, its structured fields should be explicitly defined and stable as a contract.

At minimum, users and contributors should be able to tell which parts of a charter are machine-parsed and which parts are freeform narrative.

Actual behavior

The effective charter contract is embedded in parser implementation details and tests. Structured behavior depends on exact Markdown section names and exact bold label text, even though the document is presented primarily as a Markdown artifact rather than a formally schema-validated one.

Proposed direction

One of these two directions would make the contract clearer and less brittle:

  1. Formalize the current charter schema as an explicit documented contract.

    • Document the required sections and fields.
    • Add explicit validation and user-facing errors/warnings when required structured fields are missing or malformed.
    • Treat the current exact Markdown structure as intentional and supported.
  2. Introduce structured metadata for machine-readable charter fields, with legacy fallback.

    • For example, use frontmatter or another explicit metadata block for fields like model preference, fallback, reasoning effort, and context tier.
    • Continue supporting current Markdown parsing for backward compatibility.
    • Gradually reduce reliance on exact prose/heading parsing for behaviorally important fields.

The second option feels more resilient long-term, but even the first would be a meaningful improvement because it would turn an implicit parser contract into an explicit one.

Acceptance Criteria

  • The project explicitly documents the charter contract that the runtime relies on.
  • Users can clearly distinguish machine-parsed charter fields from freeform narrative content.
  • Charter parsing is either:
    • formally validated against a declared schema, or
    • backed by explicit metadata with documented legacy fallback.
  • Behaviorally significant charter fields such as model preference, fallback, reasoning effort, and context tier are no longer under-specified by implementation details alone.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions