Skip to content

Shapes Specification

Version
0.1.0
Status
Working Draft
Date
March 2026

Abstract

AI agents today reconstruct project context from scattered artifacts — code, documents, conversations — losing intent and constraints along the way. The Shapes Specification replaces that reconstruction with a single structured graph: every node captures what is to be built, why it matters, and what must hold true. The graph is one versioned source of project intent, history, and boundaries that AI agents and humans share. The specification is domain-agnostic and applies to software, research, writing, and any other structured endeavor.


1. The Intent Layer

Shapes is an open specification that defines a semantic layer for collaboration between agents and humans. This layer — the intent layer — captures what is to be built and why, while lower layers address how it is done.

The specification captures the following explicitly:

  • Intent — the purpose and motivation behind a unit of work.
  • Constraints — strict invariants and enforcement rules.
  • Bindings — connections to external artifacts, verification, and history.
    • Realization — deliverables that fulfill a Shape.
    • Evidence — proof that requirements are satisfied.
    • Provenance — decision history and origin records.
  • Amendments — immutable change records applied to canonical nodes.
  • Boundaries — scope derived from the graph structure.

Shapes sits between agents and the work that must be done. It provides a structured representation of the entire history and current state of a project, enabling agents to operate with full context without reconstructing it from raw artifacts alone.

The specification does not require datetime values at the base level. Profiles MAY declare date fields as required within status metadata or other sections.

HumanAgentsShapesShapesConstraintsAmendmentsProfilesWork

2. Motivation

Existing tools — version control, task tracking, review workflows, editorial pipelines — record what changed but not why it matters. Provenance-only systems capture session history and decision traces, yet they do not transform that history into a queryable, semantically structured context layer. The gap between raw historical records and structured intent remains.

As projects grow in complexity, agents require a shared semantic surface to plan, build, and review work without reconstructing context from code and artifacts alone. Human review does not scale to the volume of concurrent changes that parallelized agent workflows produce. Local AI reviewers operate at the granular level without visibility into the broader intent and constraints of the project as a whole.

Shapes addresses this gap. The specification captures intent, constraints, bindings, and amendment history as first-class structured records, forming a queryable graph that any agent — regardless of architecture — can read, evaluate, and act on.


3. The DAG

The specification is format-agnostic and storage-agnostic. Examples in this specification use YAML for readability; implementations MAY use any serialization format.

The Shapes Specification is architected as a Directed Acyclic Graph (DAG). The specification maintains two composition DAGs: the Shape composition graph and the Constraint composition graph. These structures express systems of systems — where nodes compose hierarchically and cross-reference laterally without cycles.

The specification defines four node types:

  • Shape — the primary node, describing the intent and work to be done.
  • Constraint — a strict enforcement rule that MAY be applied to Shapes, Amendments, or other Constraints.
  • Amendment — an immutable change record applied to Shapes, Constraints, or Profiles to evolve the graph over time.
  • Profile — a governance configuration defining the semantic meanings, lifecycles, and validation rules for nodes in the graph. A Profile MAY encode a domain-specific lifecycle such as an SDLC or ADLC (Agentic Development Life Cycle).

These node types compose to form a DAG that can describe a single system or an arbitrarily deep hierarchy of systems. Shapes serve as the primary structural nodes. Constraints enforce invariants across them and may compose hierarchically through their own parent/child relationships. Amendments preserve the lineage of changes while keeping targeted nodes lean — Shapes, Constraints, and Profiles describe the current state of the work. The graph may extend indefinitely, enabling expression of a system with increasing granularity at every layer.

Implementations MUST reject any mutation that would introduce a cycle in the Shape composition graph or the Constraint composition graph. Mutual dependencies between nodes are modeled through shared parents or lateral cross-references via Bindings, not through cycles.

IDs are unique per node type. A Shape and a Constraint MAY share the same ID value; they occupy separate namespaces.

Both Shapes and Constraints support inline and standalone node references. When a child entry is an object, it is an inline node definition owned by its parent. When it is a scalar, it is a reference by ID to a standalone node that may live in a different project or organization. This pattern applies uniformly to Shape children and Constraint children.

The following example illustrates how these node types compose across different domains.

Shape
Constraint
Amendment
Profile
Canonical
Promoted
Proposed
Shape:
  id: 1
  name: Platform
  description: Top-level system encompassing authentication and team management.
  profile: 1
  version: 1.0.0
  status:
    canonical:
      metadata:
        date: "2025-12-01"
  intent:
    kind: system
    summary: >
      Provide a unified platform for user identity, access control,
      and team collaboration.
    source: human
    requirements:
      - Unified identity management across all services
      - Role-based access control for team operations
    acceptance_criteria:
      - All services authenticate through a single identity provider
      - Admin, member, and viewer roles enforced across endpoints
  children:
    - shape: 2
      role: service
    - shape: 3
      role: feature
A software project governed by an SaaS Profile, with parent/child Shapes, a shared Constraint, and an Amendment

A Shape is a record that captures what is being built, why, and what rules govern it. Shapes compose through inline children and cross-references by ID, forming a directed acyclic graph (DAG). The composition graph enables descriptions that range from a single unit of work to a full system architecture.

Shape:
  id: ShapeId
  name: string
  description: string
  profile: ProfileId?
  version: string?
  predecessors: [ShapeId]?
  status:
    proposed | promoted | canonical:
      reason: string?
      uris: [string]?
      metadata: <string>: any
    rejected | superseded | abandoned | reverted:
      reason: string?
      uris: [string]?
      successors: [ShapeId]?
      metadata: <string>: any
  intent: Intent
  constraints: [ConstraintId]?
  realization: [Realization]?
  evidence: [Evidence]?
  provenance: [Provenance]?
  amendment_log: [AmendmentId]?
  parents:
    - id: ShapeId
      role: string?
      reason: string?
  children:
    - shape: Shape | ShapeId
      role: string?
      reason: string?
  metadata:
    <string>: any

id

An opaque identifier for this Shape. The specification prescribes no format or generation strategy — implementations may use UUIDs, integers, or any other scheme.

Shape schema

4. Intent

Intent captures the purpose of a Shape — what is to be built and why. Every Intent MUST include a kind (a domain label such as feature, experiment, or chapter), a human-readable summary, and a source recording the origin from which it was created (e.g. human, ai, system). The source value is free-form; Profiles MAY constrain the allowed set of sources for records under their governance.

Beyond the required fields, Intent is an open map. Each domain extends it with its own vocabulary: a software team might add goals and non_goals, a research lab hypotheses and success_criteria, an editorial team themes and target_audience.

When a Shape is decomposed into sub-Shapes, each sub-Shape's Intent MUST remain coherent with its parent. Since the graph may contain thousands of Shapes, agents are the primary mechanism for verifying coherency across the graph. Agents and humans can both evaluate whether a sub-Shape's Intent breaks cohesion with its ancestors.

Every Shape, Amendment, and Constraint carries an Intent. Intent captures the why: what the record aims to achieve, what it deliberately excludes from scope, and how success is measured. Intent makes each record reviewable independently of the deliverables that embody it.

Intent:
  kind: string
  summary: string
  source: any
  uris: [string]?
  <string>: any

kind

A free-form string that classifies the intent. Common values include feature, bugfix, governance, experiment. Profiles may constrain the allowed set of kinds.

Intent schema

5. Constraints

A Constraint is a standalone record expressing an invariant, requirement, or policy that MUST be satisfied by any Shape referencing it. Constraints are distinct from decisions recorded in provenance — they represent strict enforcement rules that MUST be upheld regardless of context.

Constraints are referenced by ID from any number of Shapes and are discovered during graph traversal. When an agent traverses the DAG, Constraints referenced by a Shape are in scope for that Shape and all its descendants. This is reference-based discovery — child Shapes do not automatically carry their parent's Constraint IDs in their own records, but agents collecting Constraints from all ancestors will discover them. Constraints do not participate in the Shape composition graph, but they MAY form their own composition hierarchy through parents and children fields, enabling decomposition of complex policies into sub-constraints.

Constraint kinds classify the nature of the rule: invariant, requirement, boundary, guideline, limit, policy. Both kind and enforcement are open strings; Profiles and projects MAY define additional values.

Constraints are standalone records with their own lifecycle, referenced by ID from any number of Shapes and Amendments. Constraints do not participate in the Shape composition graph but form their own directed acyclic graph through parents and children fields, enabling decomposition of complex policies into sub-constraints.

Constraint:
  id: ConstraintId
  name: string
  description: string
  kind: string
  rule: string
  enforcement: string
  profile: ProfileId?
  version: string?
  status:
    proposed | promoted | canonical:
      reason: string?
      uris: [string]?
      metadata: <string>: any
    rejected | superseded | abandoned | reverted:
      reason: string?
      uris: [string]?
      successors: [ConstraintId]?
      metadata: <string>: any
  intent: Intent
  realization: [Realization]?
  evidence: [Evidence]?
  provenance: [Provenance]?
  amendment_log: [AmendmentId]?
  parents:
    - id: ConstraintId
      role: string?
      reason: string?
  children:
    - constraint: Constraint | ConstraintId
      role: string?
      reason: string?
  metadata:
    <string>: any

id

An opaque identifier for this Constraint. Like Shape IDs, the specification prescribes no format.

Constraint schema
yaml
Constraint:
  id: 4
  name: Admin Guard
  description: Only admin-role users may perform destructive actions.
  kind: policy
  rule: only users with the admin role may perform destructive actions
  enforcement: machine
  version: 1.0.0
  status:
    canonical:
      metadata:
        date: "2025-11-20"
  intent:
    kind: governance
    summary: >
      Restrict destructive operations (delete, revoke, disable) to
      admin-role users to prevent accidental or unauthorized data loss.
    source: human
  realization:
    - bindings:
        - scheme: uri
          value: https://github.com/acme/platform/blob/main/src/middleware/admin_guard.rs#L12-L45
      role: primary
A standalone Constraint describing an organization-wide policy

6. Amendments

Amendments are immutable change records applied to canonical Shapes, Constraints, or Profiles to evolve the graph over time. An Amendment MUST target at least one Shape, Constraint, or Profile. Amendments are separated from the target node to preserve the lineage of changes while keeping the targeted record lean. Shapes, Constraints, and Profiles describe the current state; the amendment log is append-only and preserves the full history in the order amendments were applied.

Because amendments are kept indefinitely for audit, the log grows with entries whose insight value decays over time. Each Amendment carries an optional display-only archived object containing a required reason string explaining why the amendment was archived. When present, the amendment is hidden from default listing output — it is dropped from shapes list amendment and from the rendered amendment_log in shapes get <parent> unless the caller passes --archived, which resurfaces archived entries annotated with their archival reason so readers can distinguish them. Archiving is not deletion: the record stays on disk, reciprocity (INV-019) still applies, and validation and CI checks always see the full, unfiltered set. Setting or clearing archived is the sole permitted mutation of a canonical amendment under CI-003.

Every Shape, Constraint, and Profile moves through a seven-state lifecycle: three progressive states and four terminal states. Amendments use a five-state subset — proposed, promoted, canonical, rejected, and abandoned — excluding superseded and reverted. The base specification defines the following default transitions:

  • Progressive: proposed → promoted → canonical
  • Terminal: any state → rejected | superseded | abandoned | reverted

Profiles MAY define custom statuses beyond the base set and declare transitions involving them, enabling domain-specific workflows.

Progressive
ProposedOffered for consideration.
PromotedAccepted and actively being worked on.
CanonicalAuthoritative — the accepted source of truth.

Terminal
RejectedDeclined.
Superseded(not Amendments)Replaced by one or more successors.
AbandonedNo longer pursued.
Reverted(not Amendments)Previously accepted, now withdrawn.

While a Shape or Constraint remains Proposed, changes are direct edits. Once it reaches Promoted or Canonical, all further changes MUST be recorded as Amendments. How a canonical Amendment is applied to its targets is defined by the governing Profile (§9). The specification recognizes four amendment models:

MergeFields from the Amendment are integrated directly into the base record, replacing or extending existing values.
OverlayThe base record is not modified. Effective state is computed at read time by layering Amendments in sequence on top of it.
EditionEach canonical Amendment produces a new immutable snapshot.
Append-onlyThe base record is never mutated; the amendment log is the sole source of truth.

When a Shape or Constraint is superseded, its terminal status carries a successors field and the replacement record carries a predecessors field. A record MUST only list predecessors that are in a terminal state. Implementations MUST maintain reciprocal links: if Shape B lists Shape A in its predecessors, Shape A's terminal status MUST include Shape B in its successors.

Once a Shape or Constraint reaches Promoted or Canonical, all further changes must be recorded as Amendments — immutable records that follow a five-state lifecycle (proposed, promoted, canonical, rejected, abandoned). Amendments carry the same semantic fields as Shapes (intent, constraints, realizations, evidence) because a profile may require any of these before granting Canonical status.

Amendment:
  id: AmendmentId
  name: string
  description: string
  targets:
    shape_ids: [ShapeId]?
    constraint_ids: [ConstraintId]?
    profile_ids: [ProfileId]?
  status:
    proposed | promoted | canonical:
      reason: string?
      uris: [string]?
      metadata: <string>: any
    rejected | abandoned:
      reason: string?
      uris: [string]?
      successors: [AmendmentId]?
      metadata: <string>: any
  version_impact: string?
  intent: Intent
  constraints: [ConstraintId]?
  realization: [Realization]?
  evidence: [Evidence]?
  provenance: [Provenance]?
  initiated_by:
    type: string
    identity: string?
    provenance: string?
  archived?:
    reason: string
  metadata:
    <string>: any

id

An opaque identifier for this Amendment. Like Shape IDs, the specification prescribes no format.

Amendment schema
yaml
Shape:
  id: 3
  name: Invitations
  profile: 1
  version: 1.1.0
  status:
    canonical:
      metadata:
        date: "2026-01-15"
  intent:
    kind: feature
    summary: Allow administrators to invite users by email.
    source: human
    goals:
      - Reduce setup friction for new teams
      - Keep invitation issuance restricted to trusted actors
      # applied from amendment 5
      - Support Apple sign-in for invitation acceptance
  constraints:
    - 5  # invariant: only admins may create invitations
    # applied from amendment 5
    - 6  # requirement: invitation acceptance must support Apple sign-in
  realization:
    - bindings:
        - scheme: uri
          value: https://github.com/acme/invitations/blob/a1b2c3d/src/service.rs#L40-L118
        # applied from amendment 5
        - scheme: uri
          value: https://github.com/acme/invitations/blob/a1b2c3d/src/apple_oauth.rs#L1-L95
      role: primary
  amendment_log:
    - 5
Merge model: base Shape after amendment integration
yaml
Amendment:
  id: 5
  name: Apple Sign-In
  description: Add Apple sign-in for invitation acceptance.
  targets:
    shape_ids: [3]
  status:
    canonical:
      metadata:
        date: "2026-02-14"
  version_impact: minor
  intent:
    kind: enhancement
    summary: >
      Add Apple sign-in as an accepted authentication method
      for invitation acceptance, alongside existing Google support.
    source: human
    rationale: 34% of target users prefer Apple sign-in.
    goals:
      - Support Apple sign-in for invitation acceptance
  initiated_by:
    type: human
    identity: user.admin.jane
Amendment record for the Shape above

Amendments MAY target Shapes and Constraints in any combination. When an Amendment's targets span multiple Profiles, each Profile's gates are evaluated independently. If the resulting changes conflict, resolution is delegated to the implementing agent system. The following example targets the Admin Guard policy from §5, widening the rule from "only admins" to "admins and org owners."

yaml
Amendment:
  id: 8
  name: Org Owner Access
  description: Extend destructive-action access to org owners.
  targets:
    constraint_ids: [4]
  status:
    canonical:
      metadata:
        date: "2026-02-01"
  version_impact: minor
  intent:
    kind: policy_change
    summary: >
      Allow org owners to perform destructive actions alongside admins.
    source: human
    rationale: 40% of admin escalations were org owners unable to remove stale projects.
  initiated_by:
    type: human
    identity: user.admin.ops
Amendment targeting a standalone Constraint

7. Bindings

Bindings connect spec records to external artifacts, test results, and provenance sources. A Binding is a typed reference — a scheme that identifies the kind of reference (a URI, a file path, a query, a custom selector) and a value that resolves to the target. Bindings appear throughout the spec wherever a record needs to point to an external resource.

Bindings connect Shapes to concrete deliverables, validation, and origin records. All external references use this generic model. The scheme identifies the reference type; profiles may constrain which schemes are accepted.

Binding:
  scheme: string
  value: string
  metadata:
    <string>: any

scheme

Identifies the reference type. Common schemes: uri, doi, shape, trace, or any domain-specific scheme.

Binding schema

7.1 Realizations

A Realization connects a Shape to the deliverables that fulfill it — source files, endpoints, design documents, published chapters, or any other artifact. Each Realization MUST carry one or more Bindings and a role that classifies its relationship to the Shape (e.g. primary, supporting, test).

Realizations MAY span across projects and repositories. For example, an authentication feature might reference server-side implementation files, frontend components, and API documentation across separate codebases.

Because Realizations enumerate the concrete artifacts backing a Shape, the scope of any subsequent Amendment is bounded and unambiguous. Agents operating on the Shape have explicit visibility into which artifacts fall within its scope.

A Realization connects a Shape to the deliverables that embody it. A binding may also reference other Shapes, enabling cross-project composition.

Realization:
  bindings: [Binding]
  role: string

bindings

List of Binding records pointing to the concrete artifacts that realize this Shape — source files, services, documents, or other Shapes.

Realization schema

7.2 Evidence

Evidence records demonstrate that a Shape's constraints are satisfied and its goals are met. Each Evidence entry MUST have a type (such as test, review, or metric), a trusted indicator specifying whether the result is verified, and Bindings that point to the underlying results.

Realizations and Evidence are distinct record types. The artifact that implements a requirement and the artifact that verifies it serve different roles and require independent review. Evidence MUST demonstrate that the Realization actually satisfies the Intent — not merely that the code executes without error.

Evidence is distinct from realization. Realization identifies the deliverables that embody a Shape; Evidence establishes whether those deliverables satisfy its requirements. Evidence records may include verification reports, benchmarks, reviews, or attestations.

Evidence:
  id: string
  type: string
  bindings: [Binding]
  trusted: boolean?
  metadata:
    <string>: any

id

A unique identifier for this Evidence record, allowing it to be referenced from other records.

Evidence schema

7.3 Provenance

Provenance tracks the origin and decision history of any node in the graph — Shape, Constraint, Amendment, or Profile. The specification is agnostic to the provenance systems used. Sessions, transcripts, discussions, and any other decision artifacts MAY be incorporated as Provenance entries.

Provenance entries provide agents with the full decision history behind a node — the discussions, reasoning, and trade-offs that informed it. Bindings MAY reference any external source: a Slack thread, a Linear task, a Claude Code session, or a dedicated provenance platform such as Agent Trace or Entire.

Provenance links a record to its origin process. Provenance records operational history; Shapes record semantic state. This separation keeps the specification focused on intent and structure while delegating contributor attribution and revision-scoped details to external systems.

Provenance:
  type: string
  bindings: [Binding]
  metadata:
    <string>: any

type

Classifies the provenance record. Identifies the kind of origin process (e.g. a code review, an automated pipeline, a manual operation).

Provenance schema

8. Boundaries

Since every Shape, Constraint, and Amendment carries Realizations and Evidence within the broader DAG structure, clear boundaries can be derived from the graph itself. This allows agent planning and review to stay properly scoped to the nodes being worked on.

Any changes that affect artifacts outside the scope of the target node's Realization and Evidence records constitute a boundary violation. Implementations SHOULD surface such violations and MAY enforce them through Constraint rules.


9. Profiles

Profiles are governance configurations that control how Shapes, Constraints, and Amendments behave within a domain. A single Profile MAY govern both Shapes and Constraints through separate field declaration sections. A Shape or standalone Constraint's profile field references the Profile that governs it. Amendments inherit the Profile of their targets.

Each Profile defines lifecycle gates — preconditions that MUST be satisfied before a record can transition from one state to the next. For example, a Profile MAY require that all Constraints have passing Evidence before a Shape can move from Promoted to Canonical. Profiles MAY also define custom statuses beyond the base set, enabling domain-specific workflows. A Profile specifies which amendment model (§6) applies to its records and MAY extend the base schema with domain-specific custom fields via FieldDef declarations. The fields block is split into shape and constraint sections — either or both MAY be defined. Each section covers intent, status, constraints, realization, evidence, provenance, and metadata.

Since the specification is cross-domain and agnostic over the actual work, a Profile MAY encode any domain-specific lifecycle — an SDLC, an ADLC (Agentic Development Life Cycle), an editorial workflow, or a research methodology.

A Profile is a first-class lifecycle governance node that follows the same lifecycle as Shapes and Amendments. It defines what each gate requires, what canonical means, how amendments are applied, and which custom fields and kinds are recognized. A single Profile MAY govern both Shapes and Constraints through separate field declaration sections. Every custom field and kind carries a description so that agents and users can understand what each value means without external documentation.

Profile:
  id: ProfileId
  name: string
  description: string
  version: string?
  status:
    proposed | promoted | canonical:
      reason: string?
      uris: [string]?
      metadata: <string>: any
    rejected | superseded | abandoned | reverted:
      reason: string?
      uris: [string]?
      successors: [ProfileId]?
      metadata: <string>: any
  intent: Intent
  provenance: [Provenance]?
  lifecycle:
    statuses:
      - name: string
        description: string
        type: progressive | terminal
    gates:
      - from: status
        to: status
        preconditions: [string]?
        postconditions: [string]?
  fields:
    shape:
      intent:
        fields: [FieldDef]?
        kinds: [FieldDef]?
        sources: [FieldDef]?
      status:
        fields: [FieldDef]?
      constraints:
        fields: [FieldDef]?
        kinds: [FieldDef]?
      realization:
        fields: [FieldDef]?
        kinds: [FieldDef]?
      evidence:
        fields: [FieldDef]?
        kinds: [FieldDef]?
      provenance:
        fields: [FieldDef]?
        kinds: [FieldDef]?
      metadata:
        fields: [FieldDef]?
    constraint:
      intent:
        fields: [FieldDef]?
        kinds: [FieldDef]?
        sources: [FieldDef]?
      status:
        fields: [FieldDef]?
      realization:
        fields: [FieldDef]?
        kinds: [FieldDef]?
      evidence:
        fields: [FieldDef]?
        kinds: [FieldDef]?
      provenance:
        fields: [FieldDef]?
        kinds: [FieldDef]?
      metadata:
        fields: [FieldDef]?
  versioning:
    scheme: string
    bump_rules: string?
  amendment_rules:
    application: string
  amendment_log: [AmendmentId]?
  metadata:
    <string>: any

id

An opaque identifier for this Profile.

Profile schema

FieldDef allows a Profile to declare additional fields that nodes under its governance MAY or MUST carry. Each definition specifies a name, an optional type annotation, and a human-readable description. A FieldDef whose required flag is true must be present on governed records; when the flag is omitted it defaults to false, making the field optional. This makes the specification extensible without modifying the core schema.

Defines a custom field within a Profile's field declarations. Each FieldDef describes a field recognized within intent, status, constraints, realization, evidence, provenance, or metadata sections, and indicates whether the field is required via a boolean flag.

FieldDef:
  name: string
  description: string
  type: string?
  required: boolean?

name

The name of the custom field being defined.

FieldDef schema