Skip to content

Meta-specs as a first-class codev primitive #683

@waleedkadous

Description

@waleedkadous

Source: Inbound feature request from the Shannon project's architect, based on a 10-spec ASPIR cascade run over 2026-04-18/19. Shared via cross-workspace messaging on 2026-04-19.

Problem

When an architect parallelizes a large structural change across many specs — the happy path for ASPIR — codev has no mechanism for shared, authoritative design context. Each spec is self-contained. Parallel builders re-derive vocabulary, re-argue disambiguations, and drift from each other. The architect becomes the human tie-breaker on every contradiction, which defeats the point of autonomous parallel work.

In Shannon this bit us repeatedly before we invented the meta-spec pattern: projects-vs-buckets, todos-vs-tasks, and memory-file taxonomy got re-litigated inside individual specs. Parallel builders produced solutions that were locally correct but mutually inconsistent.

What Shannon ended up doing (evidence)

Over 2026-04-17/18, the Shannon architect wrote two long design documents — not specs, not plans — and committed them to codev/architecture/:

  • codev/architecture/state-and-memory.md — lifecycle: sessions, state.json shape, daily rotation, reflection, tasks-vs-sessions.
  • codev/architecture/entities-and-layout.md — taxonomy: buckets, people, organizations, CLI family conventions, cross-cutting vs bucket-scoped.

Both docs are structured around named invariants and taxonomies (§P1–P7, §2.1–2.5, etc.) and end with an explicit "doc wins over diverging spec" rule plus a list of specs expected to cascade from them.

From those two documents, 10+ specs (737, 738, 739, 740, 741, 742, 744, 746, 755, 759, 760, 761) were drafted and run in parallel by ASPIR builders, each referencing the meta-spec by section as its authoritative source. Every cascaded spec has a Meta-spec: codev/architecture/<doc>.md §P2, §7 header or equivalent. Review overhead collapsed: reviewers (Codex, Gemini, Claude) cited §P6 when flagging drift instead of re-deriving the rule. Specs 741 (shanperson) and 740 (shanorg) are structurally near-identical because they share meta-spec §6 ("entity CLI family conventions"); the architect didn't coordinate them turn-by-turn.

A companion spec — Spec 734, "architecture-conformance contract tests" — turned a subset of the meta-spec's prose into enforced invariants via <!-- contract: apps/agent/tests/contract/... --> HTML comments embedded next to the relevant claims. Today the two meta-specs carry 6 contract annotations pointing at 8 contract test files in apps/agent/tests/contract/. Grepping <!-- contract: gives a live inventory of which architectural claims are enforced vs aspirational.

Concrete drift-catches that the meta-spec enabled (from Shannon's lessons-learned):

  • Spec 742 (MEMORY.md demotion): the spec initially scoped only the read path. Reviewers caught that 8 SKILL.md files still wrote to the old location — they used the meta-spec §P6 "indices are thin" rule to force the spec to expand. Without the meta-spec, every reviewer would have had to re-derive "why this matters."
  • Spec 741 (shanperson): the meta-spec's §3 canonical tree and §4 slug regex disagreed internally (underscore vs hyphen). A Phase 1 review caught it by citing both sections of the same doc — the disambiguation job the meta-spec is designed to do.
  • Spec 744 (bucket archival): the spec says "filesystem-moved, not metadata-flipped" and cites §7 by name. Reviewers rejected a metadata-flag alternative by reference to the meta-spec, not a re-argument.

The concept to recognize

A meta-spec is a first-class authoring artifact that sits above individual specs. Properties:

  1. Architect-authored, longer-lived than any single spec.
  2. Named, addressable structure — sections have stable identifiers (§P1, §2.2) so specs can point at exact claims.
  3. Cascade source — individual specs declare which meta-spec sections they derive from; builders read those sections as context.
  4. Tie-breaker — when a cascaded spec contradicts the meta-spec, the meta-spec wins; the spec is updated or escalated to the architect.
  5. Contract surface — invariants can be tagged with machine-readable annotations (<!-- contract: path::test -->) linking prose to enforcement.

Rough directions for framework support (not prescriptions)

We'd like codev to make this a supported pattern rather than a convention each project reinvents. The codev architect should design the exact shape; possibilities:

  • A standard location (codev/architecture/) recognized by codev tooling.
  • A spec-header convention (Meta-spec: <doc>#<section>) that tooling can validate — e.g., codev doctor flags orphan specs and missing sections.
  • Optional ASPIR/SPIR protocol hooks: the builder loads cascaded meta-spec sections into context automatically; the reviewer bots are told "the meta-spec wins."
  • A <!-- contract: … --> annotation convention with a grep-friendly inventory command.
  • Templates for authoring a meta-spec (structure: principles, disambiguations, canonical layout, cascades-into list, amendment policy).

Non-goals

  • Not a replacement for specs. Meta-specs describe shared rules; specs describe changes.
  • Not a rigid schema for the doc body — architects should be free to structure them as the domain demands.
  • Not automation for the architect authoring the doc itself — it's a human artifact.

Open questions

  • Should meta-specs have lifecycle states (draft / approved / superseded)?
  • Is the cascade relationship one-way (spec → meta-spec) or should meta-specs enumerate children?
  • Should contract annotations be codev's concern or stay project-local?
  • What's the right relationship to lessons-learned — do meta-specs absorb recurring principles automatically?

Shannon's 10-spec cascade is the proof case; raw artifacts are available on request.

Metadata

Metadata

Assignees

No one assigned

    Labels

    projectNew project or feature

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions