---
doc_id: PQDX-STD-0001b
title: "pqdx/2.0.0 Schema Specification"
version: "2.0.0"
status: draft
last_updated: "2026-05-07"
author: "Jeremy Dodson"
superseded_by: null
schema_version: "pqdx/2.0.0"
depends_on: null
classification: normative
---

# pqdx/2.0.0 Schema Specification

## Abstract

This document is the definitive specification for the pqdx state file
format. A pqdx state file (`{project}.state.yaml`) is a structured YAML
document that captures the complete living state of a managed endeavor:
what it is, where it is going, what was decided, what is broken or at
risk, what needs doing, what happened, and what is planned next. The
format is domain-agnostic — the schema defines structural categories,
field relationships, and validation rules; domain-specific vocabulary is
configured through external vocabulary profiles referenced by the state
file itself.

This specification covers schema version `pqdx/2.0.0`. It defines the
file's top-level structure, every field within each structural category,
the lifecycle of every stateful entity type, the entity ID system, the
cross-reference syntax, the provenance model, the extension point model,
the visibility and projection system, and the validation rules that
conforming tools MUST enforce.

## Status of This Document

This is a **normative specification**. It is the authoritative reference
for all pqdx tooling, domain profiles, and consuming applications.

## Document Set

This specification is part of the pqdx/2.0.0 standard document set:

| Doc ID | Title | Role |
|--------|-------|------|
| PQDX-STD-0001a | `pqdx-schema-spec.yaml` | Annotated schema — structural contract |
| PQDX-STD-0001b | `pqdx-schema-spec.md` | Prose specification (this document) |
| PQDX-STD-0001c | `pqdx-template.yaml` | Bare template — project bootstrapping |
| PQDX-STD-0001d | `pqdx-fixture.state.yaml` | Canonical fixture — validation reference |
| PQDX-GDE-0001 | `pqdx-patching-guide.md` | Patching guide — humans, AI, automation |
| PQDX-GDE-0002 | `pqdx-directory-reference.md` | Directory reference — `.pqdx/` structure |

The annotated schema (STD-0001a) defines WHAT — every field, every
constraint, every valid value. This document defines WHY and HOW — the
rationale behind each design decision, the lifecycle transition rules,
the validation semantics, and the Consumer Question Test justification
for every field's existence.

## Scope

This specification governs:

1. The structure and content of `{project}.state.yaml` files.
2. The semantics of every field, including type, requirement level,
   value constraints, defaults, and validation rules.
3. The lifecycle of every stateful entity type (milestones, milestone
   items, decisions, concerns, actions, queued items).
4. The entity ID system, including format patterns, uniqueness rules,
   and the distinction between project-local and cross-project
   references.
5. The provenance model for entity attribution and closure tracking.
6. The visibility and projection system for trust boundary management.
7. The extension point model that governs how vocabulary profiles
   interact with the schema.

This specification does **not** govern:

1. The content or structure of vocabulary profiles. That is specified in
   PQDX-STD-0002 (Vocabulary Profile Format Specification).
2. The governance methodology (session governance, decision taxonomy).
   That is non-normative guidance.
3. Any domain-specific vocabulary, concern types, project types, or ID
   prefix aliases. Those are defined in domain profile documents (e.g.,
   PQDC-STD-0001 for the software development profile).
4. Tool-specific behavior beyond what is required for schema conformance.
5. Renderer-specific behavior (colors, layout, dimming, icons). That is
   tool documentation, not protocol specification.

## Conformance Language

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in RFC 2119.

---

# §1 — Introduction and Cross-Cutting Concepts

This section defines concepts that span multiple entity types and govern
the behavior of the state file as a whole. Entity-specific sections
(§2–§9) reference these concepts by section number.

## §1.1 Schema Version

Every state file MUST begin with a `schema_version` field.

- **Type:** String
- **Required:** MUST be present. MUST be the first key in the file.
- **Pattern:** `pqdx/{semver}` where `{semver}` follows Semantic
  Versioning 2.0.0 (`MAJOR.MINOR.PATCH`).
- **Current value:** `"pqdx/2.0.0"`
- **Consumer:** Any tool opening a state file.
- **Question:** "What specification governs this file?"
- **Validation:** Tools MUST check `schema_version` before processing.
  Major version mismatch (e.g., tool expects `pqdx/2.x.x`, file says
  `pqdx/3.0.0`) SHOULD cause a warning or refusal to process. Minor
  version excess (file declares a higher minor than the tool knows)
  SHOULD produce a warning but MUST NOT cause rejection — the file may
  use features the tool doesn't know about. Patch difference MUST be
  treated as fully compatible.
- **Extension point:** Immutable.
- **Governing decisions:** ILD-9 (namespaced version format), ILD-10
  (semver semantics), ILD-153 (top-level key inventory).

The namespace makes every state file self-identifying. A tool or human
encountering the file in any context — attached to a Slack message,
uploaded to project knowledge, sitting in a downloads folder — knows
immediately what spec governs it.

Versioning semantics for the schema itself: additive changes (new
optional fields, new extension points) are minor version bumps. Changed
semantics on existing fields are major version bumps. Documentation-only
changes are patch bumps.

## §1.2 Top-Level Key Inventory

A pqdx/2.0.0 state file has eleven top-level keys (per ILD-153):

| Key | Required | Type | §Ref |
|-----|----------|------|------|
| `schema_version` | MUST | String | §1.1 |
| `vocabulary` | MUST | Mapping | §1.3 |
| `projection` | Conditional | String | §10.4 |
| `identity` | MUST | Mapping | §2 |
| `milestones` | MUST | Sequence | §3 |
| `decisions` | MUST | Sequence | §4 |
| `concerns` | MUST | Sequence | §5 |
| `actions` | MUST | Sequence | §6 |
| `sessions` | MUST | Sequence | §7 |
| `queued` | MUST | Sequence | §8 |
| `notes` | MUST | Sequence | §9 |

All eleven keys MUST be present. Sequence keys MAY be empty (`[]`).
The `projection` key is OPTIONAL on canonical state files (MUST NOT be
present per §10.4); REQUIRED on generated projection files. Value:
`public`. Identifies a state file as a generated public projection.
Full specification at §10.4.

**Forward compatibility:** Tools SHOULD warn on unknown top-level keys
but MUST NOT reject the file. Future schema versions may introduce
additional keys. A tool built for pqdx/2.0.0 encountering a file with
an unknown key should process all known keys normally and surface a
warning that the file contains unrecognized content.

**Governing decisions:** ILD-153 (eleven-key inventory), ILD-152
(projection as top-level key).

## §1.3 Vocabulary Block

The `vocabulary` block declares which vocabulary profiles govern display
and extension for this state file.

- **Type:** Mapping with exactly five keys.
- **Required:** MUST be present. All five layer keys MUST be present —
  empty layers use `[]` (per ILD-114).
- **Governing decisions:** DR-005 (vocabulary block replaces
  context_ref), ILD-109 (five-layer model), ILD-114 (empty layers),
  ILD-87 (advisory resolution), ILD-88 (first-wins merging), ILD-145
  (`.pqdx/vocab/` directory).

### Layer Keys

| Key | Mnemonic | Purpose |
|-----|----------|---------|
| `field` | "How do we build?" | Discipline vocabulary — software, healthcare, education |
| `specialty` | "Who do we build for?" | Intersection vocabulary — fintech, edtech, health-AI |
| `org` | "Who are we?" | Organization-wide conventions |
| `team` | "Which team?" | Team-level overrides |
| `individual` | "Personal prefs?" | Individual display and workflow preferences |

### Layer Entries

Each layer holds a sequence of `{ profile, version }` entries:

```yaml
vocabulary:
  field:
    - profile: pqdc-software-dev
      version: "1.0.0"
  specialty: []
  org:
    - profile: meridian-consulting
      version: "1.0.0"
  team: []
  individual: []
```

The `profile` value is a logical identifier that tools resolve to
`{profile}.vocab.yaml` in the `.pqdx/vocab/` directory (per ILD-145).
The `version` value declares which version of the profile this file
expects.

### Precedence

Cross-layer precedence (highest wins):
`individual > team > org > specialty > field`

Within a single layer, array order determines precedence — first entry
wins (per ILD-88).

### Resolution Semantics

Resolution is **advisory** — tools MUST NOT fail if referenced profiles
are missing (per ILD-87). A state file that references a vocabulary
profile that doesn't exist on disk is structurally valid. The missing
profile means display aliases won't resolve, but the universal
vocabulary in the state file remains readable.

The full vocabulary profile format is specified in PQDX-STD-0002.

## §1.4 Provenance Model

Every entity in a state file tracks where it came from. The provenance
model is unified across all entity types — no exceptions.

### The Two-Field Model

**`session`** — MUST be present on all entity types that carry it (see
individual entity sections for requirement levels). String value
identifying which session formalized this entity, or the creation
surface if created outside a governed session.

Values SHOULD be valid session IDs (e.g., `"S014"`) in governed
projects. Non-session values are permitted for entities created outside
session governance: `"dashboard"`, `"direct"`, `"migrated:jira-1234"`.
Tools MUST NOT reject non-session values.

**`origin`** — OPTIONAL on all entity types. String value. Freeform.
Records where the information came from when different from the
formalizing session. If absent, the entity originated in the session
referenced by the `session` field.

Examples: `"Inherited from firm security policy SEC-2024-017"`,
`"Carried from legacy wiki decommission project"`,
`"Firm all-hands Q&A — Managing Partner mentioned Compass by name"`.

The `session` (and optionally `origin`) opening-provenance fields are
applicable to decisions, concerns, actions, queued items, notes, and —
per DR-010 — milestones (optional). See per-entity sections (§3.1,
§4.1, §5.1, §6.1, §7.1, §8.1, §9.1) for the MUST/OPTIONAL
disposition on each entity type.

**Governing decisions:** ILD-23 (two-field provenance model), S027
unified provenance (session replaces source on actions and notes),
DR-010 (milestone opening provenance — additive consistency).

### The Closure Field

**`closed_in`** — OPTIONAL. String (session ID). A cross-cutting field
applicable to concerns, actions, queued items, milestones, and
decisions. SHOULD be present when an entity reaches a terminal status. Records which
session transitioned the entity to its terminal state.

Tools MUST NOT error on unresolvable `closed_in` references — the
referenced session may exist in another project or may not yet be
written.

`closed_in` answers a distinct question from `session`: `session` says
"where did this entity come from?" while `closed_in` says "where did
this entity's lifecycle end?" For entities that are created and resolved
in the same session, both fields carry the same value.

**Governing decisions:** S027 (closed_in replaces resolved_in as
universal closure field), ILD-201 (extended to decisions).

## §1.5 Array Ordering Convention

All sequences in a state file are **chronologically ordered** — oldest
first, newest last. New entries are appended to the end of their
section. Existing entries are MUST NOT be reordered.

This convention applies to all top-level sequences (`milestones`,
`decisions`, `concerns`, `actions`, `sessions`, `queued`, `notes`) and
to nested sequences (`milestones[].items`, `sessions[].produced`,
`sessions[].decisions_made`, `sessions[].state_changes`).

The array index of an entry is part of its identity in version control
diffs. Reordering creates phantom changes that obscure real edits.

No entry is ever deleted from a state file. Resolved concerns stay.
Completed actions stay. Superseded decisions stay. Cancelled milestones
stay. The state file is an audit trail — deletion destroys history.

**Governing decisions:** ILD-22 (chronological ordering, flow-style
convention).

## §1.6 Extension Point Model

The schema is rigid about structure and permissive about vocabulary.
Every field in the schema has one of four extension point
classifications:

### Immutable

The field's value set and semantics are fixed by the schema. Vocabulary
profiles MUST NOT modify, extend, or alias these fields. Most fields
are immutable — `id`, `text`, `session`, `notes`, `ref`, `scope`,
`decision_date`, `duration`, `planned_duration`, and all structural
fields.

### Aliasable

The field has a closed value set defined by the schema. Vocabulary
profiles MAY provide display aliases via triple-mapping (canonical
value → display label → back to canonical). The underlying values in
the state file MUST always use universal vocabulary. Aliases affect
display only — they never appear in the state file itself.

Aliasable fields: `identity.tier`, `identity.blast_radius`,
`identity.team.role`, `identity.team.type`, `concern.type`,
`concern.severity`, `concern.status` (display only),
`decision.blast_radius`, `oq.impact`, `action.priority`,
`action.status` (display only), `queued.priority`, `session.purpose`,
`session.mode`, `session.participant.type`, `session.participant.role`,
`produced.purpose`, `produced.format`.

### Additive

The field has a base value set defined by the schema. Vocabulary
profiles MAY add values — they MUST NOT remove or rename existing ones.
New values MUST include a description in the vocabulary profile.

Additive fields: `identity.type` (10 universal base types, domain
profiles add more).

### Delegated

The field's value set is defined entirely by the vocabulary profile.
The schema defines the structural slot; the profile fills it.

Delegated fields: concern ID prefix mappings (the vocabulary profile
provides the complete mapping from prefix to concern type).

**Governing decisions:** ILD-82 (extension point classification), ILD-84
(alias mechanism), ILD-85 (additive mechanism), ILD-86 (context file
syntax).

## §1.7 Visibility

Stateful entities in pqdx state files MAY carry an optional
`visibility` field controlling whether and how they appear in
public projections. The full normative specification of the
visibility model — values, defaults, resolution order, section
defaults, and projection algorithm — is given in §10 (Trust
Boundary). See §10.3 for entity visibility, §10.4 for the
`projection` top-level key, §10.5 for skeleton field sets, and
§10.6 for the projection algorithm.

The `visibility` field accepts three values: `internal`,
`skeleton`, `public`. Default when absent is `internal` (security-
first per ILD-149). For full semantics including resolution order,
section defaults, and inheritance rules for nested entities, see
§10.3.

## §1.8 Cross-Reference Syntax

Entities reference each other by ID. Two reference scopes exist:

**Project-local references:** Bare entity IDs — `DR-001`, `ILD-47`,
`BL-1`, `S014`. These reference entities within the same state file.

**Cross-project references:** Qualified syntax —
`{project}:{entity-id}`. Example: `pqdc-cc:DR-004`. The project name
MUST match the `identity.project` value of the target state file.

Cross-project references appear in `notes`, `origin`, `depends_on`,
`blocked_by`, and `blocks` fields. Tools MUST NOT error on
unresolvable cross-project references — the target project may not be
accessible from the current context.

**Governing decisions:** ILD-20 (cross-reference syntax).

---

# §2 — Identity

The `identity` block is the project's fingerprint. It answers "what am
I looking at?" for any consumer encountering the state file for the
first time.

- **Type:** Mapping
- **Required:** MUST be present.
- **Consumer:** Everyone — this is the first thing read.
- **Question:** "What is this project?"

## §2.1 Identity Fields

### `project`

- **Type:** String
- **Required:** MUST be present. MUST be non-empty.
- **Constraints:** SHOULD be lowercase kebab-case. MUST match the
  `{project}` portion of the filename (`{project}.state.yaml`).
- **Default:** None.
- **Consumer:** Every tool and human. **Question:** "What is the
  project's identifier?"
- **Validation:** Non-empty string. Tools SHOULD warn if the value
  doesn't match the filename.
- **Extension point:** Immutable.
- **Governing decisions:** ILD-92 (state file naming convention).

### `description`

- **Type:** String (multi-line via YAML folded scalar `>`).
- **Required:** MUST be present.
- **Constraints:** SHOULD be 2–4 sentences. SHOULD include purpose,
  key constraints, and primary audience.
- **Default:** None.
- **Consumer:** First-time reader, portfolio viewer. **Question:**
  "What does this project do and why does it exist?"
- **Validation:** Non-empty string.
- **Extension point:** Immutable.

### `entity`

- **Type:** String
- **Required:** MUST be present. MUST be non-empty.
- **Constraints:** Freeform — abbreviation, full name, or identifier
  for the owning organization.
- **Default:** None.
- **Consumer:** Portfolio viewer, cross-project reports. **Question:**
  "Which organization owns this project?"
- **Validation:** Non-empty string.
- **Extension point:** Immutable.

### `type`

- **Type:** String
- **Required:** MUST be present. MUST be non-empty.
- **Constraints:** Universal base types (10): `docs`, `engagement`,
  `event`, `initiative`, `procurement`, `product`, `program`,
  `research`, `response`, `service`. Domain profiles add types via the
  additive mechanism.
- **Default:** None.
- **Consumer:** Portfolio viewer, project categorization tools.
  **Question:** "What kind of project is this?"
- **Validation:** Tools SHOULD accept unknown types with a warning
  (they may come from a vocabulary profile). Tools MUST accept all 10
  universal base types without warning.
- **Extension point:** Additive.
- **Governing decisions:** ILD-64 (three-domain test for universal
  vocabulary), ILD-82 (additive extension point).

### `tier`

- **Type:** String
- **Required:** MUST be present.
- **Constraints:** Values: `minimal | standard | full`. Governance
  intensity selector.
- **Default:** None (MUST be explicitly set).
- **Consumer:** Scaffolding tools, validators. **Question:** "How much
  governance ceremony does this project expect?"
- **Validation:** Value MUST be in the enumerated set.
- **Extension point:** Aliasable.
- **Governing decisions:** ILD-82 (tier reclassified from immutable to
  aliasable).

The tier values define governance intensity:

- `minimal` — Lightweight. State file and maybe a decisions directory.
  Appropriate for personal projects, proofs of concept, small tools.
- `standard` — Active governance with session capture, vocabulary
  profiles, runbooks, and the full session infrastructure. The working
  tier for most governed projects.
- `full` — Maximum ceremony. Everything in standard plus structured
  reference material, CI integration, and generated documentation.

Tier does not gate what a project can contain — it signals what the
project expects to have, informing scaffolding tools and validators.
See PQDX-GDE-0002 for tier-based directory structure guidance.

### `owner`

- **Type:** String
- **Required:** MUST be present. MUST be non-empty.
- **Constraints:** SHOULD be a full human name.
- **Default:** None.
- **Consumer:** Everyone needing accountability. **Question:** "Who is
  the single person accountable for this project?"
- **Validation:** Non-empty string.
- **Extension point:** Immutable.

The `owner` field is always a single person — the point of
accountability. For team composition, see `team` below. The `team`
array supplements `owner`; it never replaces it.

### `blast_radius`

- **Type:** String
- **Required:** MUST be present.
- **Constraints:** Values: `negligible | low | medium | high | critical`.
  Five-value scale congruent with `severity`, `impact`, and `priority`
  across the schema.
- **Default:** None (MUST be explicitly set).
- **Consumer:** Portfolio viewer, risk assessor. **Question:** "How much
  damage would a failure in this project cause?"
- **Validation:** Value MUST be in the enumerated set. Tools SHOULD
  warn on reduction (blast radius can go up, never down).
- **Extension point:** Aliasable.
- **Governing decisions:** ILD-148 (five-value scale congruence).

### `posture`

- **Type:** String
- **Required:** OPTIONAL.
- **Constraints:** Values: `private | public | custom`. Closed
  set.
- **Default:** `private` when absent.
- **Consumer:** Ecosystem tooling, portfolio dashboards,
  validators, contributors orienting to a project. **Question:**
  "Is this project's canonical state file private, published, or
  operating under a custom configuration that needs review?"
- **Validation:** §11.16 (posture validation).
- **Extension point:** Aliasable for display only. Vocabulary
  profiles MAY rename values for domain-specific UI; the
  underlying enum values remain canonical in state file content.
- **Governing decisions:** DR-009 (posture model and declaration
  requirement). Field added in SD-6 / GAP-10 resolution (S036).

See §10.1 for the posture model and §10.2 for the full normative
specification of this field, including defaulting behavior, custom
posture handling, and public posture additional requirements.

### `created`

- **Type:** String
- **Required:** MUST be present.
- **Constraints:** ISO 8601 date (`YYYY-MM-DD`).
- **Default:** None.
- **Consumer:** Project historian. **Question:** "When did this project
  start?"
- **Validation:** MUST parse as a valid date.
- **Extension point:** Immutable.

### `status`

- **Type:** String
- **Required:** OPTIONAL.
- **Constraints:** Values: `active | dormant | archived | complete`.
- **Default:** `active` when absent.
- **Consumer:** Portfolio viewer. **Question:** "Is this project
  currently active?"
- **Validation:** Value MUST be in the enumerated set when present.
- **Extension point:** Immutable.
- **Governing decisions:** ILD-32 (identity status field).

### `contact`

- **Type:** String
- **Required:** OPTIONAL.
- **Constraints:** Freeform — email, Slack handle, phone number, URL.
- **Default:** None.
- **Consumer:** Anyone needing to reach the project team. **Question:**
  "How do I contact the people working on this?"
- **Validation:** No constraints beyond non-empty when present.
- **Extension point:** Immutable.

### `repo`

- **Type:** String
- **Required:** OPTIONAL.
- **Constraints:** Freeform — repository URL or shorthand identifier.
- **Default:** None.
- **Consumer:** Developer, CI tool. **Question:** "Where is the code?"
- **Validation:** No constraints.
- **Extension point:** Immutable.

### `version`

- **Type:** String
- **Required:** OPTIONAL.
- **Constraints:** SHOULD follow Semantic Versioning.
- **Default:** None.
- **Consumer:** Release tracker, deployment tool. **Question:** "What
  version is currently released?"
- **Validation:** No constraints.
- **Extension point:** Immutable.

### `metrics`

- **Type:** Mapping (key-value pairs)
- **Required:** OPTIONAL.
- **Constraints:** Keys and values are freeform. Content is
  domain-specific; the schema only requires that the value be a valid
  YAML mapping.
- **Default:** None.
- **Consumer:** Dashboard, project health tracker. **Question:** "What
  are the key quantitative indicators for this project?"
- **Validation:** Must be a valid YAML mapping when present.
- **Extension point:** Immutable (structure); content is freeform.
- **Governing decisions:** ILD-99 (renamed from `codebase` to
  `metrics`).

### `notes`

- **Type:** String (multi-line RECOMMENDED)
- **Required:** OPTIONAL.
- **Constraints:** Operational context beyond the description.
- **Default:** None.
- **Consumer:** Handoff recipient, project historian. **Question:**
  "What else should I know about this project?" — rename history,
  access constraints, legacy references.
- **Validation:** No constraints.
- **Extension point:** Immutable.
- **Governing decisions:** S027 (notes formalized on identity).

### `team`

- **Type:** Sequence of participant objects
- **Required:** OPTIONAL. Supplements `owner` (which remains MUST).
- **Constraints:** Each entry has three fields matching the session
  participant model:
  - `name` — MUST. String.
  - `role` — MUST. Same 9-value closed set as session participants:
    `authority | driver | facilitator | contributor | observer |
    executor | recorder | reviewer | recipient`.
  - `type` — MUST. Same 3-value closed set as session participants:
    `human | collaborator | agent`.
- **Default:** Absent or empty. Absence means solo project or team
  composition not documented.
- **Consumer:** Portfolio viewer, handoff recipient, AI tool routing
  questions to the right person. **Question:** "Who works on this
  project and what are their roles?"
- **Validation:** When present, each entry MUST have `name`, `role`,
  and `type`. Role and type values MUST be in their respective
  enumerated sets.
- **Extension point:** Role and type are aliasable (same as session
  participants).
- **Governing decisions:** DR-002 (team/role model accepted S028).

The identity `team` is the **structural roster** — who works on the
project overall. Session `participants` are the **operational record**
— who was present in each specific session. A team member who never
participates in a governed session still belongs in the team array. A
contractor who completed one action and left does not.

Tools rendering team data SHOULD use dynamic filtering patterns (as
with action assignee filtering). The state file IS the team roster —
no separate configuration needed.

### `visibility`

- **Type:** String
- **Required:** OPTIONAL.
- **Constraints:** §1.7. Values: `internal | skeleton | public`.
- **Default:** `internal` when absent.
- **Consumer:** Projection tool. **Question:** "Should this project's
  identity be included in public projections?"
- **Validation:** Value MUST be in the enumerated set when present.
- **Extension point:** Immutable.
- **Governing decisions:** ILD-149 (visibility model).

---

# §3 — Milestones

The `milestones` sequence tracks scoped work packages — what the
project intends to deliver, organized into versioned or phased
containers with checklist items.

- **Type:** Sequence of milestone objects
- **Required:** MUST be present (MAY be empty `[]`).
- **Consumer:** Everyone tracking project progress.
- **Question:** "Where is this project going?"

## §3.1 Milestone Fields

### `id`

- **Type:** String
- **Required:** MUST be present.
- **Constraints:** MUST be unique within the `milestones` sequence.
  Freeform — versions (`v1.0`), phases (`phase-1`), sprints
  (`sprint-3`), or any identifier meaningful to the project. IDs are
  stable and MUST NOT be reused.
- **Default:** None.
- **Consumer:** Every consumer. **Question:** "Which milestone is
  this?"
- **Validation:** Non-empty string, unique within milestones.
- **Extension point:** Immutable.

### `name`

- **Type:** String
- **Required:** MUST be present.
- **Constraints:** SHOULD follow the pattern `"{id} — {Short
  Description}"` for scannability.
- **Default:** None.
- **Consumer:** Everyone. **Question:** "What is this milestone about?"
- **Validation:** Non-empty string.
- **Extension point:** Immutable.

### `status`

- **Type:** String
- **Required:** MUST be present.
- **Constraints:** Values: `planned | in-progress | on-hold | complete
  | cancelled`. Closed set.
- **Default:** `planned` for new milestones.
- **Consumer:** Progress tracker, dashboard. **Question:** "What is the
  state of this milestone?"
- **Validation:** Value MUST be in the enumerated set.
- **Extension point:** Immutable.
- **Lifecycle:** See §3.3.
- **Governing decisions:** ILD-57 (on-hold added), ILD-45 (cancelled
  added).

### `target`

- **Type:** String or null
- **Required:** OPTIONAL.
- **Constraints:** Freeform — date, relative reference, qualitative
  target. `null` or absent means no target set.
- **Default:** `null`.
- **Consumer:** Scheduler, project lead. **Question:** "When is this
  expected to be done?"
- **Validation:** No constraints on value format.
- **Extension point:** Immutable.

### `depends_on`

- **Type:** Sequence of strings (entity IDs)
- **Required:** OPTIONAL.
- **Constraints:** Planned sequencing — "this milestone should start
  after these entities are resolved."
- **Default:** Empty sequence or absent.
- **Consumer:** Scheduler, dependency graph. **Question:** "What must
  happen before this milestone can start?"
- **Validation:** Tools MUST NOT error on unresolvable references.
- **Extension point:** Immutable.

### `blocked_by`

- **Type:** Sequence of strings (entity IDs)
- **Required:** OPTIONAL.
- **Constraints:** Emergent impediments — distinct from `depends_on`.
  A dependency is planned sequencing; a blocker is an emergent
  impediment. A dependency can be met and a blocker can still exist.
- **Default:** Empty sequence or absent.
- **Consumer:** Project lead, impediment tracker. **Question:** "What
  is preventing this milestone from progressing?"
- **Validation:** Tools MUST NOT error on unresolvable references.
- **Extension point:** Immutable.
- **Governing decisions:** ILD-83 (depends_on vs blocked_by semantic
  distinction).

### `completed`

- **Type:** String
- **Required:** OPTIONAL. SHOULD be present when `status` is
  `complete`.
- **Constraints:** ISO 8601 date (`YYYY-MM-DD`).
- **Default:** None.
- **Consumer:** Project historian. **Question:** "When was this
  milestone delivered?"
- **Validation:** MUST parse as a valid date when present.
- **Extension point:** Immutable.
- **Governing decisions:** ILD-33 (completion date), S027 (`completed`
  is canonical field name, not `completed_date`).

### `closed_in`

- **Type:** String (session ID)
- **Required:** OPTIONAL. §1.4. SHOULD be present when `status` is
  `complete` or `cancelled`.
- **Default:** None.
- **Consumer:** Governance auditor. **Question:** "Which session closed
  this milestone?"
- **Validation:** Tools MUST NOT error on unresolvable references.
- **Extension point:** Immutable.

### `session`

- **Type:** String
- **Required:** OPTIONAL. §1.4 provenance.
- **Constraints:** Non-session values permitted: `"dashboard"`,
  `"direct"`, `"migrated:..."` (e.g., `"migrated:jira-EPIC-1247"`).
- **Default:** None.
- **Consumer:** Governance auditor, project historian, handoff
  recipient. **Question:** "Which session introduced this milestone
  into the project's plan?"
- **Validation:** Non-empty string when present. Tools MUST NOT error
  on unresolvable references (consistent with §11.13).
- **Extension point:** Immutable.
- **Governing decisions:** DR-010 (milestone opening provenance —
  additive consistency).

### `origin`

- **Type:** String
- **Required:** OPTIONAL. §1.4 provenance.
- **Constraints:** Freeform. Where the milestone originally came from
  when different from the introducing session. Examples: `"Carried
  from legacy wiki decommission project"`, `"Inherited from firm
  strategic roadmap, Q1 2026"`, `"Migrated from Jira EPIC-1247"`.
- **Default:** None. When absent and `session` is set, the milestone
  originated in that session.
- **Consumer:** Milestone historian, migration auditor. **Question:**
  "Where did this milestone originally come from, when different from
  a captured session?"
- **Validation:** No constraints.
- **Extension point:** Immutable.
- **Governing decisions:** DR-010.

### `notes`

- **Type:** String (multi-line RECOMMENDED)
- **Required:** OPTIONAL.
- **Default:** None.
- **Consumer:** AI tool starting a session, handoff recipient.
  **Question:** "What context do I need about this milestone's current
  state?"
- **Validation:** No constraints.
- **Extension point:** Immutable.

### `visibility`

- **Type:** String
- **Required:** OPTIONAL. §1.7.
- **Default:** `internal` when absent.
- **Extension point:** Immutable.
- **Governing decisions:** ILD-149 (visibility model).

### `items`

- **Type:** Sequence of milestone item objects
- **Required:** OPTIONAL. A milestone with no items is structurally
  valid but SHOULD have at least one item before transitioning to
  `in-progress`.
- **Default:** Empty sequence or absent.
- **Consumer:** Everyone tracking progress. **Question:** "What
  specific things must be true for this milestone to close?"
- **Validation:** See §3.2.
- **Extension point:** Immutable (structure).

## §3.2 Milestone Item Fields

Milestone items are the atomic checklist entries within a milestone.
They use flow-style YAML for scannability (per ILD-22):

```yaml
- { id: v01-1, text: "Define repo directory structure", status: open }
- { id: v01-8, text: "Verification gate", status: open, gate: true }
```

Field order in flow-style is normative: `id`, `text`, `status`, then
optional fields. Authoring tools SHOULD preserve this order. Items that
require extended context (e.g., a notes field) MAY use block-style
YAML.

### `id`

- **Type:** String
- **Required:** MUST be present.
- **Constraints:** MUST be unique within the parent milestone's `items`
  sequence. SHOULD follow the pattern `{milestone_prefix}-{N}` (e.g.,
  `v01-1`, `phase1-3`). IDs are stable and never reused — if an item
  is deferred or dropped, its ID remains occupied.
- **Default:** None.
- **Consumer:** Every consumer. **Question:** "Which item is this?"
- **Validation:** Non-empty string, unique within parent milestone.
- **Extension point:** Immutable.
- **Governing decisions:** ILD-14 (stable IDs, never reused).

### `text`

- **Type:** String
- **Required:** MUST be present. MUST be non-empty.
- **Constraints:** SHOULD describe a condition that can be verified as
  true or false. Parenthetical annotations (e.g., "Define repo
  structure (deferred to v0.2)") are permitted as a human convention
  for scannability, but tools MUST read the `status` field for state
  — tools MUST NOT parse `text` for state information.
- **Default:** None.
- **Consumer:** Anyone tracking progress. **Question:** "What must be
  true for this item to be done?"
- **Validation:** Non-empty string.
- **Extension point:** Immutable.
- **Governing decisions:** ILD-22 (text is descriptive, status is
  authoritative).

### `status`

- **Type:** String
- **Required:** MUST be present.
- **Constraints:** Values: `open | done | deferred | dropped | subsumed`.
  Closed set — vocabulary profiles MUST NOT extend (per ILD-18).
- **Default:** `open` for new items.
- **Values:**
  - `open` — Not yet done. Active work or waiting.
  - `done` — The condition described in `text` is verified as true.
  - `deferred` — Intentionally postponed. Terminal in the source
    milestone (per ILD-43, tombstone model).
  - `dropped` — Intentionally removed from scope. Terminal.
  - `subsumed` — Merged into another item or absorbed by a broader
    scope change. Terminal.
- **Consumer:** Progress tracker, milestone completion validator.
  **Question:** "What is the state of this item?"
- **Validation:** Value MUST be in the enumerated set. Reject on
  unknown.
- **Extension point:** Immutable.
- **Governing decisions:** ILD-18 (closed set), ILD-43 (tombstone model).

> **Tombstone model (ILD-43):** When a milestone item is deferred, it
> remains in the source milestone with `status: deferred` — this
> preserves scope history ("we planned this but deferred it"). A new
> entry with a new lifecycle starting at `status: open` is created in
> the target milestone. The deferred entry in the source milestone is a
> tombstone; the new entry in the target is the active item. Both
> coexist.

### `gate`

- **Type:** Boolean
- **Required:** OPTIONAL.
- **Default:** `false` when absent.
- **Constraints:** When `true`, this item is a verification gate — it
  MUST have `status: done` before the parent milestone can transition
  to `complete` (per ILD-30).
- **Consumer:** Milestone completion validator. **Question:** "Is this
  item required for milestone completion?"
- **Validation:** Boolean when present.
- **Extension point:** Immutable.
- **Governing decisions:** ILD-30 (gate items), ILD-16 (verification
  gates concept).

### `notes`

- **Type:** String
- **Required:** OPTIONAL.
- **Default:** None.
- **Consumer:** Handoff recipient, item assignee. **Question:** "What
  additional context do I need for this item?"
- **Validation:** No constraints.
- **Extension point:** Immutable.

### `visibility`

- **Type:** String
- **Required:** OPTIONAL. §1.7. Inherits from parent milestone when
  absent.
- **Default:** Parent milestone's resolved visibility.
- **Extension point:** Immutable.
- **Governing decisions:** ILD-151 (nested entity inheritance).

## §3.3 Milestone Lifecycle

The milestone lifecycle defines the valid states and transitions for
the `status` field on milestone entries.

### States

| State | Terminal? | Description |
|-------|-----------|-------------|
| `planned` | No | Future work, not yet started. Initial state. |
| `in-progress` | No | Actively being worked on. |
| `on-hold` | No | Paused due to external factors (legal hold, priority shift, resource reallocation). Not an impediment to a specific item — that is tracked as a concern with `blocks` references (per ILD-44). |
| `complete` | Yes | All scope resolved with delivery. Completion guard satisfied. |
| `cancelled` | Yes | Milestone abandoned or emptied of deliverables. |

### Transition Table

| From | To | Guard | Side Effects |
|------|----|-------|--------------|
| `planned` | `in-progress` | None | — |
| `planned` | `cancelled` | None | Session close-out SHOULD record rationale. |
| `in-progress` | `complete` | Completion guard (§3.4) | `completed` date SHOULD be set. `closed_in` SHOULD be set. |
| `in-progress` | `on-hold` | None | — |
| `in-progress` | `planned` | None | Valid for premature starts (per ILD-58). Session close-out SHOULD record rationale. |
| `in-progress` | `cancelled` | None | Session close-out SHOULD record rationale. `closed_in` SHOULD be set. |
| `on-hold` | `in-progress` | None | — |
| `on-hold` | `planned` | None | — |
| `on-hold` | `cancelled` | None | Session close-out SHOULD record rationale. `closed_in` SHOULD be set. |
| `on-hold` | `complete` | Completion guard (§3.4) | `completed` date SHOULD be set. `closed_in` SHOULD be set. |

### Invalid Transitions

- `complete` → any state. Terminal. A completed milestone that needs
  reopening indicates a scope change — create a new milestone with the
  revised scope.
- `cancelled` → any state. Terminal.

### Normative Notes

- `on-hold` is distinct from action `blocked` — `on-hold` expresses
  broader situational factors (legal hold, priority shift, resource
  reallocation) while `blocked` is a specific impediment to a specific
  task.
- `in-progress` → `planned` is valid (per ILD-58). Premature starts can
  retreat directly without an intermediate state.

**Governing decisions:** ILD-44 (no blocked status on milestones),
ILD-45 (cancelled status), ILD-57 (on-hold status), ILD-58 (in-progress
→ planned valid).

## §3.4 Milestone Completion Guard

A milestone MUST satisfy ALL of the following conditions before
transitioning to `complete`:

1. The milestone MUST have at least one item with `status: done`. A
   milestone that delivered nothing is `cancelled`, not `complete`.
2. Every item with `gate: true` MUST have `status: done`. Non-gate
   items MAY have any terminal status (`done`, `deferred`, `dropped`,
   `subsumed`).
3. No item in the milestone MAY have `status: open`. All items must
   have reached a terminal state.

A conforming validator MUST reject a `complete` milestone that violates
any of these conditions.

Domain profiles MAY document additional requirements (e.g., "pqdc
requires code review before milestone completion") and enforce them in
domain-specific tooling, but they MUST NOT weaken or modify universal
guards.

The schema is the behavioral floor. Domain profiles raise the floor;
they never lower it.

**Governing decisions:** ILD-30 (gate items), ILD-59 (at-least-one-done
guard).

## §3.5 Milestone Item Status Lifecycle

Milestone item status is simpler than milestone status. All transitions
originate from `open`:

| From | To | Notes |
|------|----|-------|
| `open` | `done` | Item verified as true. |
| `open` | `deferred` | Terminal in source milestone. Tombstone model applies (ILD-43). |
| `open` | `dropped` | Terminal. Item will not be delivered. |
| `open` | `subsumed` | Terminal. Item absorbed by broader scope change. |

**Invalid transitions:** `done` → any state. `deferred` → any state.
`dropped` → any state. `subsumed` → any state. All non-open states are
terminal within the milestone. A deferred item gets a fresh lifecycle
in the target milestone.

### Normative Note: Deferred Asymmetry

Milestone item `deferred` is terminal (the item's lifecycle in this
milestone is over — tombstone model). Concern `deferred` is
non-terminal (the concern stays in the same list and can reopen). The
underlying principle is consistent: "deferred" means "not now." The
divergence is in what happens next — milestone items relocate on
deferral; concerns do not.

**Governing decisions:** ILD-43 (tombstone model), ILD-49 (concern
deferred is non-terminal), ILD-54 (done vs complete terminology).

---

# §4 — Decisions

The `decisions` sequence tracks formal records, open questions, and
informal locks in a unified array. Three subtypes coexist because
decisions interact across types — an OQ may resolve into a DR, an ILD
may be superseded by another ILD, a DR may reference OQs in its
analysis.

- **Type:** Sequence of decision objects
- **Required:** MUST be present (MAY be empty `[]`).
- **Consumer:** Decision archaeologist, handoff recipient, project lead.
- **Question:** "What was decided?"

## §4.1 Common Fields (All Subtypes)

These fields are shared by DR, OQ, and ILD entries.

### `id`

- **Type:** String
- **Required:** MUST be present.
- **Constraints:** MUST be unique across the entire `decisions`
  sequence (not just within a subtype). Pattern depends on subtype:
  - DR: `^DR-\d+$` (zero-padded, 3-digit minimum)
  - OQ: `^OQ-\d+$` (simple integer)
  - ILD: `^ILD-\d+$` (simple integer)
- **Default:** None.
- **Consumer:** Every consumer. **Question:** "Which decision is this?"
- **Validation:** Non-empty string, unique within decisions, matches
  subtype pattern.
- **Extension point:** Immutable.
- **Governing decisions:** ILD-154 (ILD prefix, renamed from ID-).

### `title`

- **Type:** String
- **Required:** MUST be present.
- **Constraints:** Single sentence describing the decision. SHOULD be
  scannable — a reader browsing a list of 50 decisions should
  understand each one's substance from the title alone.
- **Default:** None.
- **Consumer:** Everyone scanning decisions. **Question:** "What was
  decided (or asked)?"
- **Validation:** Non-empty string.
- **Extension point:** Immutable.

### `status`

- **Type:** String
- **Required:** MUST be present.
- **Constraints:** Values depend on subtype — see §4.2, §4.3, §4.4.
- **Consumer:** Decision tracker. **Question:** "What is the current
  state of this decision?"
- **Validation:** Value MUST match the valid set for the entry's
  subtype.
- **Extension point:** Immutable (closed sets per subtype).

### `session`

- **Type:** String
- **Required:** MUST be present (per S027 — elevated from SHOULD).
- **Constraints:** §1.4 provenance.
- **Default:** None.
- **Consumer:** Governance auditor. **Question:** "Where was this
  decision formalized?"
- **Validation:** Non-empty string.
- **Extension point:** Immutable.
- **Governing decisions:** S027 (session elevated to MUST on
  decisions).

### `origin`

- **Type:** String
- **Required:** OPTIONAL. §1.4 provenance.
- **Default:** None. When absent, the entity originated in the
  referenced session.
- **Consumer:** Decision historian. **Question:** "Where did this
  information originally come from?"
- **Validation:** No constraints.
- **Extension point:** Immutable.

### `blast_radius`

- **Type:** String
- **Required:** OPTIONAL.
- **Constraints:** Values: `negligible | low | medium | high | critical`.
  Same five-value scale as `identity.blast_radius` and
  `concern.severity`.
- **Default:** None.
- **Consumer:** Risk assessor, escalation reviewer. **Question:** "How
  much impact would getting this decision wrong have?"
- **Validation:** Value MUST be in the enumerated set when present.
- **Extension point:** Aliasable.
- **Governing decisions:** ILD-35 (blast_radius on all decision types),
  ILD-148 (five-value congruence).

### `scope`

- **Type:** String
- **Required:** OPTIONAL.
- **Constraints:** Freeform. What area, subsystem, or domain this
  decision constrains.
- **Default:** None. Absence means scope is not explicitly bounded
  (project-wide or unspecified).
- **Consumer:** Handoff recipient, portfolio viewer, dashboard filter.
  **Question:** "What does this decision apply to?"
- **Validation:** No constraints beyond non-empty when present.
- **Extension point:** Immutable (freeform content).
- **Governing decisions:** S028 (scope formalized on all decision
  subtypes).

Projects SHOULD establish scope vocabulary early and use it
consistently across decisions. Dashboard tools MAY group and filter
decisions by exact string match on `scope`. Consistent vocabulary
makes this useful; inconsistent vocabulary makes it noise.

### `decision_date`

- **Type:** String
- **Required:** OPTIONAL. SHOULD be present on accepted DRs and
  resolved OQs.
- **Constraints:** ISO 8601 date (`YYYY-MM-DD`).
- **Default:** None. When absent on a DR, the consumer falls back to
  the session date of the acceptance session.
- **Consumer:** Governance auditor, compliance reviewer, timeline
  analyst. **Question:** "When did this decision become binding?"
- **Validation:** MUST parse as a valid date when present.
- **Extension point:** Immutable.
- **Governing decisions:** S028 (decision_date formalized).

The `decision_date` is distinct from the `session` date. A DR may be
proposed in S005 (the `session` value) and accepted in S008. The
`decision_date` records when it became binding — the acceptance date,
not the proposal date. For ILDs that start `pending` and later
transition to `locked`, the `decision_date` captures the lock date
when different from the `session` date.

### `notes`

- **Type:** String
- **Required:** OPTIONAL.
- **Default:** None.
- **Consumer:** Decision reviewer, handoff recipient. **Question:**
  "What additional context exists for this decision?"
- **Validation:** No constraints.
- **Extension point:** Immutable.

### `closed_in`

- **Type:** String (session ID)
- **Required:** OPTIONAL. §1.4. SHOULD be present when the decision
  reaches a terminal status.
- **Default:** None.
- **Constraints:** Terminal states by subtype: DR (`superseded`,
  `rejected`, `withdrawn`), OQ (`resolved`), ILD (`superseded`).
- **Consumer:** Decision archaeologist, handoff recipient.
  **Question:** "When did this decision's lifecycle end?"
- **Validation:** Tools MUST NOT error on unresolvable session refs.
- **Extension point:** Immutable.
- **Governing decisions:** ILD-201 (closed_in extended to decisions).

### `visibility`

- **Type:** String
- **Required:** OPTIONAL. §1.7.
- **Default:** `internal` when absent.
- **Extension point:** Immutable.
- **Governing decisions:** ILD-149 (visibility model).

## §4.2 DR — Decision Record

Decision Records are formal decisions requiring structured analysis.
They SHOULD have a companion document with context, options, trade-offs,
and consequences.

**ID pattern:** `^DR-\d+$` (zero-padded, 3-digit minimum).

### DR-Specific Fields

#### `companion`

- **Type:** String (location-schemed)
- **Required:** OPTIONAL. SHOULD be present for accepted DRs.
- **Constraints:** Location-schemed path to the analysis document.
  Schemes: `repo://`, `local://`, `url://`, `session://`,
  `project-knowledge://`, `state://`, `pending://`.
- **Default:** None.
- **Consumer:** Decision reviewer, future analyst. **Question:** "Where
  is the full analysis for this decision?"
- **Validation:** Non-empty string when present. Tools SHOULD validate
  scheme prefix.
- **Extension point:** Immutable.
- **Governing decisions:** ILD-96 (companion field).

#### `reviewed_by`

- **Type:** Sequence of strings (names)
- **Required:** OPTIONAL. SHOULD be present on accepted DRs with
  `critical` or `high` blast_radius.
- **Default:** None. When absent, the session participants list is
  the fallback.
- **Consumer:** Governance auditor, executive oversight, compliance
  reviewer. **Question:** "Who reviewed and approved this decision?"
- **Validation:** When present, sequence MUST contain at least one
  non-empty string.
- **Extension point:** Immutable.
- **Governing decisions:** S028 (reviewed_by formalized).

#### `superseded_by`

- **Type:** String (entity ID)
- **Required:** OPTIONAL. SHOULD be present when `status` is
  `superseded`.
- **Default:** None.
- **Consumer:** Decision archaeologist, handoff recipient tracing
  decision lineage. **Question:** "What replaced this decision?"
- **Validation:** Non-empty string when present. Tools MUST NOT error
  on unresolvable references.
- **Extension point:** Immutable.
- **Governing decisions:** S028 (superseded_by formalized).

The `superseded_by` field enables lineage tracing — follow the chain
from a superseded decision to its replacement until a non-superseded
decision is reached. Without this field, lineage requires parsing
freeform notes.

### DR Lifecycle

#### States

| State | Terminal? | Description |
|-------|-----------|-------------|
| `proposed` | No | Under consideration. Initial state. |
| `accepted` | No | Approved and in effect. Binding. |
| `deferred` | No | Evaluation postponed (per ILD-82). |
| `superseded` | Yes | Replaced by another decision. |
| `rejected` | Yes | Evaluated and declined. |
| `withdrawn` | Yes | Retracted by author before evaluation (per ILD-46). |

#### Transition Table

| From | To | Guard | Side Effects |
|------|----|-------|--------------|
| `proposed` | `accepted` | Review complete | `decision_date` SHOULD be set. `reviewed_by` SHOULD be set for critical/high blast_radius. |
| `proposed` | `deferred` | None | Session SHOULD record rationale. |
| `proposed` | `rejected` | Evaluation complete | Session SHOULD record rationale. |
| `proposed` | `withdrawn` | Author retracts | Session SHOULD record rationale. |
| `proposed` | `superseded` | Replaced before acceptance | `superseded_by` SHOULD be set. |
| `accepted` | `superseded` | Replaced after being in effect | `superseded_by` SHOULD be set. |
| `deferred` | `proposed` | None | Re-enters evaluation. |
| `deferred` | `superseded` | None | `superseded_by` SHOULD be set. |

#### Invalid Transitions

- `superseded` → any state. Terminal.
- `rejected` → any state. Terminal.
- `withdrawn` → any state. Terminal.
- `accepted` → `proposed`. A decision that was accepted cannot return
  to proposed — if it needs re-evaluation, supersede it and propose a
  new DR.

**Governing decisions:** ILD-46 (withdrawn status), ILD-82 (deferred
added).

## §4.3 OQ — Open Question

Open Questions track uncertainties with impact assessment. They
represent things the project doesn't know yet that affect its direction.

**ID pattern:** `^OQ-\d+$` (simple integer).

### OQ-Specific Fields

#### `impact`

- **Type:** String
- **Required:** SHOULD be present.
- **Constraints:** Values: `negligible | low | medium | high | critical`.
  Five-value scale.
- **Default:** None.
- **Consumer:** Project lead, triage. **Question:** "How much does not
  knowing the answer to this question affect the project?"
- **Validation:** Value MUST be in the enumerated set when present.
- **Extension point:** Aliasable.
- **Governing decisions:** ILD-148 (negligible added, five-value
  congruence).

#### `resolution_path`

- **Type:** String
- **Required:** OPTIONAL.
- **Default:** None.
- **Consumer:** Project lead, session planner. **Question:** "What is
  the plan for answering this question?"
- **Validation:** No constraints.
- **Extension point:** Immutable.

### OQ Lifecycle

#### States

| State | Terminal? | Description |
|-------|-----------|-------------|
| `open` | No | Unanswered. Initial state. |
| `narrowed` | No | Option space has contracted but question remains open. |
| `deferred` | No | Question postponed (per ILD-82). |
| `resolved` | Yes | Answered. |

#### Transition Table

| From | To | Guard | Side Effects |
|------|----|-------|--------------|
| `open` | `narrowed` | None | Session SHOULD record what was eliminated. |
| `open` | `deferred` | None | Session SHOULD record rationale. |
| `open` | `resolved` | None | `decision_date` SHOULD be set. Resolution SHOULD be recorded in notes. |
| `narrowed` | `deferred` | None | — |
| `narrowed` | `resolved` | None | `decision_date` SHOULD be set. |
| `deferred` | `open` | None | Re-enters active consideration. |

#### Invalid Transitions

- `resolved` → any state. Terminal. A resolved OQ that generates new
  questions is a new OQ, not a reopening.
- `narrowed` → `open`. Information gain doesn't reverse (per ILD-47).
  If new information expands the option space, either update notes
  (incorrect narrowing) or create a new OQ (fundamentally different
  question).

**Governing decisions:** ILD-47 (narrowed → open invalid), ILD-82
(deferred added).

## §4.4 ILD — Informal Locked Decision

Informal Locked Decisions are quick governance locks — recording what
was decided without the full analysis of a DR. Most project decisions
are ILDs.

**ID pattern:** `^ILD-\d+$` (simple integer).

> **Migration note:** The ILD prefix was renamed from `ID-` in S027
> (per ILD-154) to eliminate collision with the word "identifier." The
> migration procedure is documented in PQDX-GDE-0001 Appendix A.
> DR-006 documents the decision rationale and downstream impact.

### ILD-Specific Fields

#### `superseded_by`

- **Type:** String (entity ID)
- **Required:** OPTIONAL. SHOULD be present when `status` is
  `superseded`.
- **Default:** None.
- **Consumer:** Decision archaeologist. **Question:** "What replaced
  this decision?"
- **Validation:** Non-empty string when present. Same semantics as
  DR `superseded_by`.
- **Extension point:** Immutable.
- **Governing decisions:** S028 (superseded_by formalized).

### ILD Lifecycle

#### States

| State | Terminal? | Description |
|-------|-----------|-------------|
| `pending` | No | Articulated but not yet confirmed. Authority deferred the lock (per S027). |
| `locked` | No | In effect. Binding. Most ILDs are born locked. |
| `superseded` | Yes | Replaced by another decision. |

#### Transition Table

| From | To | Guard | Side Effects |
|------|----|-------|--------------|
| `pending` | `locked` | Authority confirms | `decision_date` SHOULD be set when different from session date. |
| `pending` | `superseded` | Different direction chosen | `superseded_by` SHOULD be set. |
| `locked` | `superseded` | Replaced after being in effect | `superseded_by` SHOULD be set. |

#### Invalid Transitions

- `locked` → `pending`. A confirmed decision cannot return to
  unconfirmed. If it needs revisiting, supersede it and create a new
  decision.
- `superseded` → any state. Terminal.

**Governing decisions:** ILD-34 (superseded status), S027 (pending
status added, three-state lifecycle).

---

# §5 — Concerns

The `concerns` sequence tracks typed deficiencies — things that are
broken, at risk, or missing. Type and status are orthogonal dimensions:
the `type` field classifies WHAT the deficiency is; the `status` field
tracks WHERE it is in its lifecycle (per ILD-48).

- **Type:** Sequence of concern objects
- **Required:** MUST be present (MAY be empty `[]`).
- **Consumer:** Triage dashboard, project lead, risk assessor.
- **Question:** "What is broken, at risk, or missing?"

## §5.1 Concern Fields

### `id`

- **Type:** String
- **Required:** MUST be present.
- **Constraints:** Pattern: `^[A-Z]{1,4}-\d+$`. The prefix encodes the
  concern type. Universal prefixes: `BL` (blocker), `DBT` (debt),
  `DEF` (defect), `GAP` (gap), `KI` (known-issue), `RSK` (risk),
  `SD` (stale-doc). Domain profiles may declare additional prefixes via
  vocabulary profile triple-mapping (§5.3). IDs are unique within
  `concerns` and MUST NOT be reused.
- **Default:** None.
- **Consumer:** Every consumer. **Question:** "Which concern is this?"
- **Validation:** Non-empty string, matches pattern, unique within
  concerns.
- **Extension point:** Delegated (prefix mappings from vocabulary
  profile).
- **Governing decisions:** ILD-29 (gap as universal type), ILD-82
  (delegated extension point for prefix mapping).

### `type`

- **Type:** String
- **Required:** MUST be present.
- **Constraints:** Values: `blocker | debt | defect | gap | known-issue
  | risk | stale-doc`. Exhaustive closed set of 7 universal types.
  Prefix and type MUST agree (§11.9).
- **Default:** None.
- **Consumer:** Triage dashboard, concern filter. **Question:** "What
  kind of deficiency is this?"
- **Validation:** Value MUST be in the enumerated set.
- **Extension point:** Aliasable. Display labels may differ (e.g., pqdc
  might display "bug" for `defect`), but the state file value is always
  the universal term.
- **Governing decisions:** ILD-48 (all types share one lifecycle), ILD-29
  (gap added).

The seven universal concern types:

| Type | Meaning | Example |
|------|---------|---------|
| `blocker` | Active impediment preventing progress | SSO integration blocked by misconfiguration |
| `debt` | Known compromise needing future attention | No debounce on autocomplete queries |
| `defect` | Something that doesn't work correctly | Search ranking degrades for articles with code blocks |
| `gap` | Something that should exist but doesn't | No content review workflow |
| `known-issue` | Acknowledged imperfection, accepted for now | Preview truncates mid-word on narrow viewports |
| `risk` | Something that might go wrong | Single database instance with no replica |
| `stale-doc` | Documentation that doesn't match reality | README references old project name |

### `severity`

- **Type:** String
- **Required:** MUST be present.
- **Constraints:** Values: `negligible | low | medium | high | critical`.
  Five-value scale matching `blast_radius`, `impact`, and `priority`
  across the schema.
- **Default:** None (MUST be explicitly set).
- **Consumer:** Triage dashboard, risk assessor. **Question:** "How
  bad is this?"
- **Validation:** Value MUST be in the enumerated set.
- **Extension point:** Aliasable.
- **Governing decisions:** ILD-148 (negligible added, five-value
  congruence), ILD-60 (severity is mutable).

**Severity is mutable** (per ILD-60). A concern's severity may change
as understanding evolves — a `low` risk that materializes may escalate
to `critical`. Severity changes SHOULD be recorded in the session's
`state_changes` array. The schema allows any value in the closed set at
any time — there is no severity transition table. Building a transition
table for a five-value scale is overengineering.

### `text`

- **Type:** String
- **Required:** MUST be present. MUST be non-empty.
- **Constraints:** Substantive description of the deficiency. SHOULD be
  self-contained — a reader should understand the concern without
  needing to find other entries.
- **Default:** None.
- **Consumer:** Everyone. **Question:** "What is the problem?"
- **Validation:** Non-empty string.
- **Extension point:** Immutable.

### `status`

- **Type:** String
- **Required:** MUST be present.
- **Constraints:** Values: `open | monitoring | deferred | resolved`.
  Closed set.
- **Default:** `open` for new concerns.
- **Consumer:** Triage dashboard. **Question:** "What is the current
  state of this concern?"
- **Validation:** Value MUST be in the enumerated set.
- **Extension point:** Immutable. Aliasable for display only.
- **Lifecycle:** See §5.2.
- **Governing decisions:** ILD-48 (all types share one lifecycle),
  ILD-100 (monitoring status added).

### `session`

- **Type:** String
- **Required:** MUST be present (per S027 — elevated from SHOULD).
- **Constraints:** §1.4 provenance.
- **Default:** None.
- **Consumer:** Governance auditor. **Question:** "When was this
  concern identified?"
- **Validation:** Non-empty string.
- **Extension point:** Immutable.

### `origin`

- **Type:** String
- **Required:** OPTIONAL. §1.4 provenance.
- **Default:** None.
- **Consumer:** Concern historian. **Question:** "Where did this
  concern originally come from?"
- **Validation:** No constraints.
- **Extension point:** Immutable.

### `ref`

- **Type:** String
- **Required:** OPTIONAL.
- **Constraints:** Freeform. Identifies which artifact has this
  deficiency — a file path, document name, entity ID, URL, or any
  identifier that locates the affected artifact.
- **Default:** None.
- **Consumer:** Person fixing the deficiency, triage dashboard grouping
  concerns by affected artifact. **Question:** "Where is the thing
  that's broken/at-risk/missing?"
- **Validation:** No constraints beyond non-empty when present.
- **Extension point:** Immutable.
- **Governing decisions:** S028 (ref formalized on concerns).

The `ref` field is orthogonal to `blocks`. `ref` answers "where is the
deficiency?" (which artifact is affected). `blocks` answers "what does
this deficiency impede?" (which entities can't progress). A concern can
have both, either, or neither.

### `resolution`

- **Type:** String
- **Required:** MUST be present when `status` is `resolved`. MUST NOT
  be present when `status` is `open`.
- **Constraints:** Describes how the concern was resolved.
- **Default:** None.
- **Consumer:** Concern reviewer, handoff recipient. **Question:** "How
  was this fixed/addressed?"
- **Validation:** MUST be present when resolved, MUST NOT be present
  when open.
- **Extension point:** Immutable.

### `closed_in`

- **Type:** String (session ID)
- **Required:** OPTIONAL. §1.4. SHOULD be present when `status` is
  `resolved`.
- **Default:** None.
- **Consumer:** Governance auditor. **Question:** "Which session
  resolved this concern?"
- **Validation:** Tools MUST NOT error on unresolvable references.
- **Extension point:** Immutable.

### `blocks`

- **Type:** String or sequence of strings (entity IDs)
- **Required:** OPTIONAL.
- **Constraints:** Entity IDs that this concern impedes. MAY reference
  entities without a `blocked` status field (per ILD-63) — a concern
  can block a milestone even though milestones have no `blocked`
  status.
- **Default:** None.
- **Consumer:** Dependency tracker, dashboard. **Question:** "What is
  this concern preventing?"
- **Validation:** Tools MUST NOT error on unresolvable references.
- **Extension point:** Immutable.
- **Governing decisions:** ILD-36 (blocks on all concern types), ILD-61
  (blocks is passive annotation), ILD-63 (blocks may reference entities
  without blocked status).

**`blocks` is a passive annotation** (per ILD-61). It does NOT change
on concern status transitions. When a concern is deferred, its `blocks`
references persist — the concern still impacts those entities, the
impact is just acknowledged-but-unaddressed. Dashboards compute
"currently blocked" by intersecting `blocks` references with `status:
open` — a deferred concern with `blocks` is displayed differently from
an open one, but the reference itself is preserved.

### `notes`

- **Type:** String
- **Required:** OPTIONAL.
- **Default:** None.
- **Consumer:** Concern reviewer. **Question:** "What additional
  context exists?"
- **Validation:** No constraints.
- **Extension point:** Immutable.

### `visibility`

- **Type:** String
- **Required:** OPTIONAL. §1.7.
- **Default:** `internal` when absent.
- **Extension point:** Immutable.

## §5.2 Concern Lifecycle

All seven concern types share a single lifecycle. Type and status are
orthogonal — a blocker and a stale-doc have the same valid transitions.

### States

| State | Terminal? | Description |
|-------|-----------|-------------|
| `open` | No | Active deficiency. Initial state. |
| `monitoring` | No | Watch posture — acknowledged, not actively working, tracking for changes (per ILD-100). |
| `deferred` | No | Intentionally postponed. Non-terminal — can reopen (per ILD-49). |
| `resolved` | Yes | Addressed or accepted as no longer relevant. |

### Transition Table

| From | To | Guard | Side Effects |
|------|----|-------|--------------|
| `open` | `monitoring` | None | — |
| `open` | `deferred` | None | Session SHOULD record rationale. |
| `open` | `resolved` | None | `resolution` MUST be set. `closed_in` SHOULD be set. |
| `monitoring` | `open` | Situation changed | — |
| `monitoring` | `deferred` | None | — |
| `monitoring` | `resolved` | None | `resolution` MUST be set. `closed_in` SHOULD be set. |
| `deferred` | `open` | Deferral reason expired | — |
| `deferred` | `resolved` | None | `resolution` MUST be set. `closed_in` SHOULD be set. |

### Invalid Transitions

- `resolved` → any state. Terminal. A resolved concern that recurs is a
  new concern, not a reopening.

### Normative Note: Deferred Is Non-Terminal

Concern `deferred` is non-terminal (reopenable). This is an intentional
asymmetry with milestone item `deferred` (which is terminal). Milestone
items relocate on deferral (tombstone model, ILD-43). Concerns don't
relocate — they stay in the same concerns list and can reopen when the
deferral reason expires.

**Governing decisions:** ILD-48 (orthogonal type/status), ILD-49
(deferred non-terminal), ILD-100 (monitoring status).

## §5.3 Concern Prefix Mapping

The concern ID prefix encodes the type. The universal mapping is:

| Prefix | Type |
|--------|------|
| `BL` | blocker |
| `DBT` | debt |
| `DEF` | defect |
| `GAP` | gap |
| `KI` | known-issue |
| `RSK` | risk |
| `SD` | stale-doc |

Domain profiles provide this mapping via vocabulary profile
triple-mapping — the full mapping (canonical type → prefix → display
label) is declared in the profile. Tools use this mapping for ID
validation (§11.9) and display.

---

# §6 — Actions

The `actions` sequence tracks discrete tasks requiring human effort.
Actions are binary — done or not. They emerge from session close-outs,
dashboard reviews, or direct creation.

- **Type:** Sequence of action objects
- **Required:** MUST be present (MAY be empty `[]`).
- **Consumer:** Task assignee, project lead, sprint planner.
- **Question:** "What does a human need to do?"

## §6.1 Action Fields

### `id`

- **Type:** String
- **Required:** MUST be present.
- **Constraints:** Pattern: `^A-\d+$` (bare integer, no padding). Unique
  within `actions`. Never reused.
- **Default:** None.
- **Consumer:** Every consumer. **Question:** "Which action is this?"
- **Validation:** Non-empty string, matches pattern, unique within
  actions.
- **Extension point:** Immutable.

### `text`

- **Type:** String
- **Required:** MUST be present. MUST be non-empty.
- **Constraints:** Task description. SHOULD be actionable — a reader
  should understand what needs to be done without reading other entries.
- **Default:** None.
- **Consumer:** Assignee. **Question:** "What do I need to do?"
- **Validation:** Non-empty string.
- **Extension point:** Immutable.

### `session`

- **Type:** String
- **Required:** MUST be present. §1.4 provenance.
- **Constraints:** Non-session values permitted for actions created
  outside governed sessions: `"dashboard"`, `"migrated:jira-1234"`.
- **Default:** None.
- **Consumer:** Governance auditor. **Question:** "Where did this task
  come from?"
- **Validation:** Non-empty string.
- **Extension point:** Immutable.
- **Governing decisions:** S027 (session replaces source — unified
  provenance).

### `origin`

- **Type:** String
- **Required:** OPTIONAL. §1.4 provenance.
- **Default:** None.
- **Consumer:** Task historian. **Question:** "Where did this task
  originally come from, if not this session?"
- **Validation:** No constraints.
- **Extension point:** Immutable.

### `assignee`

- **Type:** String
- **Required:** SHOULD be present (per S027 — relaxed from MUST).
- **Constraints:** Name of the responsible person. Solo or lightweight
  projects may omit.
- **Default:** None.
- **Consumer:** Task tracker, assignee filter. **Question:** "Who is
  responsible for this?"
- **Validation:** Tools SHOULD warn when absent.
- **Extension point:** Immutable.
- **Governing decisions:** S027 (relaxed from MUST to SHOULD).

### `status`

- **Type:** String
- **Required:** MUST be present.
- **Constraints:** Values: `open | blocked | deferred | done |
  cancelled`. Closed set.
- **Default:** `open` for new actions.
- **Consumer:** Task tracker, dashboard. **Question:** "What is the
  state of this action?"
- **Validation:** Value MUST be in the enumerated set.
- **Extension point:** Immutable. Aliasable for display only.
- **Lifecycle:** See §6.2.
- **Governing decisions:** ILD-38 (action lifecycle), ILD-82 (deferred
  added).

### `priority`

- **Type:** String
- **Required:** OPTIONAL.
- **Constraints:** Values: `negligible | low | medium | high | critical`.
  Five-value scale matching severity and blast_radius.
- **Default:** None.
- **Consumer:** Assignee triaging, project lead. **Question:** "How
  urgent is this?"
- **Validation:** Value MUST be in the enumerated set when present.
- **Extension point:** Aliasable.
- **Governing decisions:** S027 (priority formalized on actions),
  ILD-148 (five-value congruence).

### `due`

- **Type:** String
- **Required:** OPTIONAL.
- **Constraints:** ISO 8601 date (`YYYY-MM-DD`). **Purely
  informational** — no auto-escalation, no lifecycle effect.
- **Default:** None.
- **Consumer:** Assignee, project lead. **Question:** "When is this
  due?"
- **Validation:** MUST parse as a valid date when present.
- **Extension point:** Immutable.
- **Governing decisions:** ILD-37 (due field), ILD-55 (purely
  informational).

Dashboards MAY flag overdue actions (`open` or `blocked` past due date),
but this is display logic, not lifecycle. No auto-transition occurs.

### `depends_on`

- **Type:** Sequence of strings (entity IDs)
- **Required:** OPTIONAL.
- **Default:** Empty sequence or absent.
- **Consumer:** Task scheduler. **Question:** "What must complete
  before I can do this?"
- **Validation:** Tools MUST NOT error on unresolvable refs.
- **Extension point:** Immutable.
- **Governing decisions:** ILD-83 (depends_on as universal sequencing
  field).

### `resolution`

- **Type:** String
- **Required:** OPTIONAL. SHOULD be present when `status` is `done`.
- **Default:** None.
- **Consumer:** Action reviewer. **Question:** "How was this
  completed?"
- **Validation:** No constraints.
- **Extension point:** Immutable.

### `closed_in`

- **Type:** String (session ID)
- **Required:** OPTIONAL. §1.4. SHOULD be present when `status` is
  `done` or `cancelled`.
- **Default:** None.
- **Consumer:** Governance auditor. **Question:** "Which session closed
  this action?"
- **Validation:** Tools MUST NOT error on unresolvable references.
- **Extension point:** Immutable.

### `notes`

- **Type:** String
- **Required:** OPTIONAL.
- **Default:** None.
- **Consumer:** Assignee, handoff recipient. **Question:** "What
  context do I need?"
- **Validation:** No constraints.
- **Extension point:** Immutable.

### `visibility`

- **Type:** String
- **Required:** OPTIONAL. §1.7.
- **Default:** `internal` when absent.
- **Extension point:** Immutable.

## §6.2 Action Lifecycle

### States

| State | Terminal? | Description |
|-------|-----------|-------------|
| `open` | No | Not yet done. Initial state. |
| `blocked` | No | Cannot proceed due to a specific impediment. |
| `deferred` | No | Intentionally postponed (per ILD-82). |
| `done` | Yes | Completed. Uses `done` (not `complete`) per ILD-54 — leaf entity terminology. |
| `cancelled` | Yes | No longer needed. |

### Transition Table

| From | To | Guard | Side Effects |
|------|----|-------|--------------|
| `open` | `done` | None | `resolution` SHOULD be set. `closed_in` SHOULD be set. |
| `open` | `blocked` | Impediment identified | Session SHOULD record what blocks it. |
| `open` | `deferred` | None | Session SHOULD record rationale. |
| `open` | `cancelled` | None | Session SHOULD record rationale. `closed_in` SHOULD be set. |
| `blocked` | `open` | Impediment removed | — |
| `blocked` | `done` | Impediment removed + action completed | `resolution` SHOULD be set. `closed_in` SHOULD be set. |
| `blocked` | `cancelled` | None | `closed_in` SHOULD be set. |
| `deferred` | `open` | None | Reopens the action. |
| `deferred` | `cancelled` | None | No longer needed. `closed_in` SHOULD be set. |

### Invalid Transitions

- `done` → any state. Terminal.
- `cancelled` → any state. Terminal.
- `deferred` → `done`. Deferred actions must return to `open` before
  completing — the deferral implies work was not done, so completing
  from deferred would skip the work step.
- `deferred` → `blocked`. A deferred action is not being worked on,
  so a blocker is irrelevant while deferred. Return to `open` first.

**Governing decisions:** ILD-38 (action lifecycle), ILD-54 (done vs
complete), ILD-82 (deferred added).

---

# §7 — Sessions

The `sessions` sequence is the chronological audit trail — the
governance record of what happened and when. Sessions are **immutable
after creation** (per ILD-56). Once written, substantive fields MUST NOT
change. The `produced` array is the sole exception — artifacts
discovered or completed after the session may be appended with a note
indicating the amendment session.

- **Type:** Sequence of session objects
- **Required:** MUST be present (MAY be empty `[]`).
- **Consumer:** Handoff recipient, governance auditor, AI tool starting
  a new session.
- **Question:** "What happened and when?"

**ID pattern:** `^S\d+$` (zero-padded, 3-digit minimum). Sessions are never
renumbered or deleted.

## §7.1 Session Fields

### `id`

- **Type:** String
- **Required:** MUST be present.
- **Constraints:** Pattern: `^S\d+$`. Unique within `sessions`.
  Sequential, never reused, never renumbered.
- **Default:** None.
- **Consumer:** Every consumer. **Question:** "Which session is this?"
- **Validation:** Non-empty string, matches pattern, unique within
  sessions.
- **Extension point:** Immutable.

### `date`

- **Type:** String
- **Required:** MUST be present.
- **Constraints:** ISO 8601 date (`YYYY-MM-DD`).
- **Default:** None.
- **Consumer:** Timeline viewer, session historian. **Question:** "When
  did this session occur?"
- **Validation:** MUST parse as a valid date.
- **Extension point:** Immutable.

### `title`

- **Type:** String
- **Required:** MUST be present.
- **Constraints:** Scannable session summary. A reader browsing a list
  of 30 sessions should understand each one's focus from the title.
- **Default:** None.
- **Consumer:** Everyone scanning session history. **Question:** "What
  was this session about?"
- **Validation:** Non-empty string.
- **Extension point:** Immutable.

### `purpose`

- **Type:** String
- **Required:** MUST be present.
- **Constraints:** Values: `coordination | discussion | evaluation |
  production | transfer`. Closed set.
- **Default:** None.
- **Consumer:** Session categorizer, pattern analyst. **Question:**
  "What kind of session was this?"
- **Validation:** Value MUST be in the enumerated set.
- **Extension point:** Aliasable.

The five purpose values:

| Value | Meaning |
|-------|---------|
| `coordination` | Aligning people or plans (standups, planning, cross-team sync) |
| `discussion` | Exploring ideas, debating options (brainstorming, design review) |
| `evaluation` | Assessing something (code review, feasibility study, audit) |
| `production` | Creating deliverables (writing, coding, designing) |
| `transfer` | Handing off knowledge or responsibility (onboarding, handoff) |

### `mode`

- **Type:** String
- **Required:** SHOULD be present (per S027 — relaxed from MUST).
  Informal sessions may omit.
- **Constraints:** Values: `live-verbal | live-text | async |
  async-verbal | automated | hybrid`. Closed set of 6 values.
- **Default:** None.
- **Consumer:** Session analyst, communication pattern tracker.
  **Question:** "How did this session happen?"
- **Validation:** Value MUST be in the enumerated set when present.
- **Extension point:** Aliasable.
- **Governing decisions:** S027 (expanded from 3 to 6 values, relaxed
  from MUST to SHOULD).

The six mode values:

| Value | Meaning |
|-------|---------|
| `live-verbal` | Synchronous, speech primary (in-person, video, phone) |
| `live-text` | Synchronous, text primary (chat, AI dialogue, pair programming) |
| `async` | Asynchronous, text-based (email, PR review, document review) |
| `async-verbal` | Asynchronous, recorded speech/video (Loom, voice messages) |
| `automated` | System-initiated or machine-only (CI/CD, multi-agent, pipeline) |
| `hybrid` | Multiple channels or timing modes combined |

### `duration`

- **Type:** String
- **Required:** OPTIONAL.
- **Constraints:** Freeform. Effort duration — how much time this
  session actually consumed. For async sessions, effort duration is
  more meaningful than wall-clock span (e.g., `"~2h effort across 3
  days"`).
- **Default:** None.
- **Consumer:** Process improver, project lead, time analyst.
  **Question:** "How much time did this session consume?"
- **Validation:** Tools MAY parse common patterns (`"2h 15m"`, `"45m"`,
  `"1h 30m"`) but MUST NOT reject unusual formats. Any non-empty
  string is valid.
- **Extension point:** Immutable.
- **Governing decisions:** S028 (duration formalized on sessions).

### `planned_duration`

- **Type:** String
- **Required:** OPTIONAL.
- **Constraints:** Freeform. How much time was allocated or estimated
  for this session.
- **Default:** None.
- **Consumer:** Scheduler, process improver (for delta analysis).
  **Question:** "How much time was allocated for this session?"
- **Validation:** Same as `duration` — tools MAY parse common patterns
  but MUST NOT reject unusual formats.
- **Extension point:** Immutable.
- **Governing decisions:** S028 (planned_duration formalized).

When both `duration` and `planned_duration` are present, tools MAY
compute and display the delta for retrospective analysis. A project
where every 1-hour session runs to 3 hours has a scoping problem. A
project where 2-hour sessions finish in 45 minutes has an efficiency
win or an over-estimation habit. Neither insight is available without
both values.

### `participants`

- **Type:** Sequence of participant objects
- **Required:** MUST be present. At least one entry.
- **Constraints:** Each entry has three fields:
  - `name` — MUST. String.
  - `type` — MUST. Values: `human | collaborator | agent`. Closed set.
  - `role` — MUST. Values (9): `authority | driver | facilitator |
    contributor | observer | executor | recorder | reviewer |
    recipient`. Closed set.
- **Default:** None.
- **Consumer:** Session reviewer, governance auditor. **Question:**
  "Who was in this session and what did they do?"
- **Validation:** At least one entry. Each entry MUST have `name`,
  `type`, and `role`. Values MUST be in their respective sets.
- **Extension point:** `type` and `role` are aliasable.
- **Governing decisions:** S027 (type and role formalized as closed
  sets, facilitator added to role set).

Flow-style recommended for participant entries:
`{ name: sarah, type: human, role: authority }`

The three participant types:

| Type | Meaning |
|------|---------|
| `human` | A person |
| `collaborator` | AI in dialogue mode — contributes to decisions |
| `agent` | AI in execution mode — carries out instructions |

The nine participant roles:

| Role | Meaning |
|------|---------|
| `authority` | Decision-maker, final say |
| `driver` | Doing the primary work |
| `facilitator` | Managing session process |
| `contributor` | Actively participating, not driving |
| `observer` | Present but passive |
| `executor` | Carrying out instructions (not deciding) |
| `recorder` | Documenting (not deciding) |
| `reviewer` | Evaluating output |
| `recipient` | Receiving a handoff |

## §7.2 Produced Artifacts

The `produced` field tracks what a session created.

- **Type:** Sequence of artifact objects
- **Required:** OPTIONAL.
- **Consumer:** Session reviewer, artifact searcher. **Question:**
  "What did this session produce?"

Each artifact entry has the following fields:

### `description`

- **Type:** String
- **Required:** MUST be present.
- **Consumer:** Artifact searcher. **Question:** "What is this
  artifact?"
- **Validation:** Non-empty string.
- **Extension point:** Immutable.

### `purpose`

- **Type:** String
- **Required:** MUST be present.
- **Constraints:** Values: `analysis | communication | decision |
  design | implementation | instruction | reference | scaffold`.
  Closed set of 8 values.
- **Default:** None.
- **Consumer:** Artifact categorizer. **Question:** "Why was this
  artifact created?"
- **Validation:** Value MUST be in the enumerated set.
- **Extension point:** Aliasable.

### `format`

- **Type:** String
- **Required:** MUST be present.
- **Constraints:** Values: `audio | code | composite | data | diagram |
  image | prose | slides | spreadsheet | video`. Closed set of 10
  values.
- **Default:** None.
- **Consumer:** Artifact organizer, search tool. **Question:** "What
  kind of artifact is this?"
- **Validation:** Value MUST be in the enumerated set.
- **Extension point:** Aliasable.
- **Governing decisions:** S028 (10-value set validated and locked).

The ten format values:

| Value | Meaning |
|-------|---------|
| `audio` | Sound recordings — meetings, interviews, podcasts |
| `code` | Source code, scripts, configuration files |
| `composite` | Multi-format bundles — zip archives, packages |
| `data` | Structured data — YAML, JSON, CSV, databases, datasets |
| `diagram` | Visual representations — architecture, flow, concept maps |
| `image` | Static visuals — screenshots, photos, mockups, infographics |
| `prose` | Written text — specs, reports, READMEs, memos, articles |
| `slides` | Presentation decks — keynotes, pitch decks |
| `spreadsheet` | Tabular data with computation — budgets, trackers, models |
| `video` | Moving image recordings — demos, walkthroughs, lectures |

### `location`

- **Type:** String (location-schemed)
- **Required:** MUST be present.
- **Constraints:** Location-schemed string identifying where the
  artifact can be found.
- **Default:** None.
- **Consumer:** Anyone retrieving the artifact. **Question:** "Where
  is this artifact?"
- **Validation:** Non-empty string. Tools SHOULD validate scheme
  prefix.
- **Extension point:** Immutable.

Location schemes:

| Scheme | Purpose | Example |
|--------|---------|---------|
| `repo://` | Path relative to repository root | `repo://decisions/DR-001.md` |
| `project-knowledge://` | Claude project knowledge upload | `project-knowledge://pqdx.state.yaml` |
| `state://` | Entity within this state file | `state://decisions/DR-001` |
| `session://` | Inline in a session transcript | `session://S013` |
| `url://` | External URL | `url://https://pqdx.dev/spec` |
| `local://` | Local filesystem path | `local:///home/user/notes.md` |
| `pending://` | Planned but not yet created | `pending://decisions/DR-005.md` |

### `notes`

- **Type:** String
- **Required:** OPTIONAL.
- **Default:** None.
- **Consumer:** Artifact reviewer. **Question:** "What additional
  context exists about this artifact?"
- **Validation:** No constraints.
- **Extension point:** Immutable.
- **Governing decisions:** S027 (restored per ILD-21 original design).

### `visibility`

- **Type:** String
- **Required:** OPTIONAL. §1.7. Inherits from parent session when
  absent.
- **Default:** Parent session's resolved visibility.
- **Extension point:** Immutable.
- **Governing decisions:** ILD-151 (nested entity inheritance).

## §7.3 Session Output and Handoff Fields

### `decisions_made`

- **Type:** Sequence of strings (decision IDs)
- **Required:** OPTIONAL.
- **Constraints:** IDs of decisions formalized, resolved, accepted,
  or otherwise actioned in this session. DR-NNN, OQ-N, ILD-N.
- **Default:** Empty sequence or absent.
- **Consumer:** Session reviewer, decision tracer. **Question:** "What
  decisions were made in this session?"
- **Validation:** Tools MUST NOT error on unresolvable refs.
- **Extension point:** Immutable.

**Inline array rule:** `decisions_made` MUST be on the same line as
the key — never on the next line. The pqdc-cc parser breaks silently
on split arrays. This is a practical constraint, not a YAML spec
requirement.

### `state_changes`

- **Type:** Sequence of strings
- **Required:** OPTIONAL.
- **Constraints:** Brief, past-tense descriptions of state changes
  that occurred during this session.
- **Default:** Empty sequence or absent.
- **Consumer:** Session reviewer, change historian. **Question:** "What
  changed in this session besides decisions?"
- **Validation:** No constraints on individual string values.
- **Extension point:** Immutable.

### `next_action`

- **Type:** String
- **Required:** OPTIONAL. SHOULD be present.
- **Constraints:** The most important field for session continuity —
  what the next session reads first. A single sentence or short
  paragraph describing what should happen next.
- **Default:** None.
- **Consumer:** AI tool starting the next session, handoff recipient.
  **Question:** "What should happen next?"
- **Validation:** No constraints.
- **Extension point:** Immutable.

### `notes`

- **Type:** String
- **Required:** OPTIONAL.
- **Default:** None.
- **Consumer:** Session reviewer. **Question:** "What additional
  context exists about this session?"
- **Validation:** No constraints.
- **Extension point:** Immutable.

### `visibility`

- **Type:** String
- **Required:** OPTIONAL. §1.7.
- **Default:** `internal` when absent.
- **Extension point:** Immutable.

## §7.4 Session Immutability

Sessions are immutable records (per ILD-56). Once a session entry is
written, the following fields MUST NOT change: `id`, `date`, `title`,
`purpose`, `mode`, `participants`, `decisions_made`, `state_changes`,
`next_action`, `notes`, `duration`, `planned_duration`.

The `produced` array is the sole exception. Artifacts discovered or
completed after the session may be appended with a note on the new
entry indicating the amendment session.

**Governing decisions:** ILD-56 (session immutability).

---

# §8 — Queued Items

The `queued` sequence tracks identified work needing governed attention.
Queued items may resolve in a single session, span multiple sessions,
or complete through async work. They are the project's governed backlog.

- **Type:** Sequence of queued item objects
- **Required:** MUST be present (MAY be empty `[]`).
- **Consumer:** Backlog manager, session planner.
- **Question:** "What governed work is planned?"

**ID pattern:** `^QI-\d+$` (simple integer).

> **Migration note:** The QI prefix was renamed from `DS-Q` in S027
> (per ILD-155). The entity type is "Queued Item," not limited to design
> sessions.

## §8.1 Queued Item Fields

### `id`

- **Type:** String
- **Required:** MUST be present.
- **Constraints:** Pattern: `^QI-\d+$`. Unique within `queued`. Never
  reused.
- **Default:** None.
- **Consumer:** Every consumer. **Question:** "Which queued item is
  this?"
- **Validation:** Non-empty string, matches pattern, unique within
  queued.
- **Extension point:** Immutable.
- **Governing decisions:** ILD-155 (QI prefix, renamed from DS-Q).

### `title`

- **Type:** String
- **Required:** MUST be present.
- **Constraints:** Scannable description of the planned work.
- **Default:** None.
- **Consumer:** Project lead scanning backlog. **Question:** "What is
  this planned work about?"
- **Validation:** Non-empty string.
- **Extension point:** Immutable.

### `status`

- **Type:** String
- **Required:** MUST be present.
- **Constraints:** Values: `pending | in-progress | deferred | complete
  | cancelled`. Closed set.
- **Default:** `pending` for new queued items.
- **Consumer:** Backlog manager. **Question:** "What is the state of
  this planned work?"
- **Validation:** Value MUST be in the enumerated set.
- **Extension point:** Immutable.
- **Lifecycle:** See §8.2.

### `session`

- **Type:** String
- **Required:** MUST be present. §1.4 provenance.
- **Default:** None.
- **Consumer:** Governance auditor. **Question:** "When was this work
  identified?"
- **Validation:** Non-empty string.
- **Extension point:** Immutable.

### `origin`

- **Type:** String
- **Required:** OPTIONAL. §1.4 provenance.
- **Default:** None.
- **Consumer:** Backlog historian. **Question:** "Where did this planned
  work come from?"
- **Validation:** No constraints.
- **Extension point:** Immutable.

### `prompt`

- **Type:** String (location-schemed)
- **Required:** OPTIONAL.
- **Default:** None. Absence means no prompt has been prepared.
- **Constraints:** Location-schemed path or inline preparation material.
  Same schemes as `produced[].location` (see §7.2).
- **Consumer:** Session facilitator, AI tool loading context.
  **Question:** "Where is the session prompt for this planned work?"
- **Validation:** Non-empty string when present. Tools SHOULD validate
  scheme prefix.
- **Extension point:** Immutable.
- **Governing decisions:** ILD-97 (prompt field on queued items).

### `priority`

- **Type:** String
- **Required:** OPTIONAL.
- **Constraints:** Values: `negligible | low | medium | high | critical`.
  Five-value scale, consistent with actions.
- **Default:** None.
- **Consumer:** Project lead. **Question:** "Which queued item is most
  important?"
- **Validation:** Value MUST be in the enumerated set when present.
- **Extension point:** Aliasable.
- **Governing decisions:** S027 (priority formalized on queued items),
  ILD-148 (five-value congruence).

### `depends_on`

- **Type:** Sequence of strings (entity IDs)
- **Required:** OPTIONAL.
- **Constraints:** Advisory, not hard-blocking (per ILD-50). Tools
  SHOULD warn when a queued item transitions to `in-progress` while
  dependencies are unresolved. Tools MUST NOT block the transition.
- **Default:** Empty sequence or absent.
- **Consumer:** Project lead, scheduler. **Question:** "Can I start
  this now?"
- **Validation:** Tools MUST NOT error on unresolvable refs.
- **Extension point:** Immutable.
- **Governing decisions:** ILD-50 (advisory depends_on).

### `scope`

- **Type:** String
- **Required:** OPTIONAL.
- **Constraints:** Freeform. Estimation context — answers "how big is
  this planned work?" (e.g., `"2-3 sessions"`, `"1 sprint"`,
  `"multi-week effort"`).
- **Default:** None.
- **Consumer:** Project lead, scheduler. **Question:** "How big is
  this?"
- **Validation:** No constraints.
- **Extension point:** Immutable.
- **Governing decisions:** S027 (scope on queued items), ILD-41.

> **Note:** The `scope` field on queued items answers "how big is this
> work?" — it is an estimation field. The `scope` field on decisions
> answers "what area does this decision apply to?" — it is a
> classification field. Same field name, different semantic purpose,
> different entity types.

### `closed_in`

- **Type:** String (session ID)
- **Required:** OPTIONAL. §1.4. SHOULD be present when `status` is
  `complete` or `cancelled`.
- **Default:** None.
- **Consumer:** Governance auditor. **Question:** "Which session
  completed this planned work?"
- **Validation:** Tools MUST NOT error on unresolvable references.
- **Extension point:** Immutable.

### `notes`

- **Type:** String
- **Required:** OPTIONAL.
- **Default:** None.
- **Consumer:** Session facilitator. **Question:** "What context do I
  need before starting?"
- **Validation:** No constraints.
- **Extension point:** Immutable.

### `visibility`

- **Type:** String
- **Required:** OPTIONAL. §1.7.
- **Default:** `internal` when absent.
- **Extension point:** Immutable.

## §8.2 Queued Item Lifecycle

### States

| State | Terminal? | Description |
|-------|-----------|-------------|
| `pending` | No | Not yet started. May or may not have a prompt ready. Initial state. |
| `in-progress` | No | Work underway. May span multiple sessions. |
| `deferred` | No | Postponed (per ILD-82). |
| `complete` | Yes | Work finished. Uses `complete` (not `done`) per ILD-54 — container/work-unit terminology. |
| `cancelled` | Yes | No longer needed. |

### Transition Table

| From | To | Guard | Side Effects |
|------|----|-------|--------------|
| `pending` | `in-progress` | None | Tools SHOULD warn on unresolved `depends_on`. |
| `pending` | `deferred` | None | Session SHOULD record rationale. |
| `pending` | `cancelled` | None | Session SHOULD record rationale. `closed_in` SHOULD be set. |
| `in-progress` | `complete` | None | `closed_in` SHOULD be set. |
| `in-progress` | `pending` | None | Work can pause and return to queue (per ILD-52). |
| `in-progress` | `deferred` | None | — |
| `in-progress` | `cancelled` | None | `closed_in` SHOULD be set. |
| `deferred` | `pending` | None | Returns to queue. |
| `deferred` | `cancelled` | None | `closed_in` SHOULD be set. |

### Invalid Transitions

- `pending` → `complete`. Work must pass through `in-progress` (per
  ILD-53). You cannot complete work that was never started. If queued
  work becomes moot before starting, the correct path is `pending` →
  `cancelled`.
- `complete` → any state. Terminal.
- `cancelled` → any state. Terminal.

### Normative Note: No Blocked Status

Queued items have no `blocked` status (per ILD-51). The `depends_on`
field covers planned sequencing. External blockers are tracked as
concerns with `blocks` references pointing to the queued item. Adding
`blocked` would create ambiguity with `depends_on` (blocked because
of a dependency, or because of an external factor?). Actions need
`blocked` because they lack `depends_on`. Queued items have the
dependency mechanism, so external blockers go in concerns.

**Governing decisions:** ILD-51 (no blocked on queued), ILD-52
(in-progress → pending valid), ILD-53 (pending → complete invalid),
ILD-54 (complete vs done terminology), ILD-82 (deferred added).

---

# §9 — Notes

The `notes` sequence provides timestamped, session-attributed
commentary. Notes are freeform observations — they have no lifecycle,
no status, and no governance constraints beyond provenance. They are
append-only.

- **Type:** Sequence of note objects
- **Required:** MUST be present (MAY be empty `[]`).
- **Consumer:** Project historian, context builder.
- **Question:** "What observations have been recorded?"

## §9.1 Note Fields

### `id`

- **Type:** String
- **Required:** MUST be present.
- **Constraints:** Pattern: `^N-\d+$` (simple integer). Unique within
  `notes`. Never reused.
- **Default:** None.
- **Consumer:** Every consumer. **Question:** "Which note is this?"
- **Validation:** Non-empty string, matches pattern, unique within
  notes.
- **Extension point:** Immutable.
- **Governing decisions:** S027 (id field added to notes — enables
  referenceability, stable visibility overrides, cross-entity linking).

### `date`

- **Type:** String
- **Required:** MUST be present.
- **Constraints:** ISO 8601 date (`YYYY-MM-DD`).
- **Default:** None.
- **Consumer:** Timeline viewer. **Question:** "When was this
  observation made?"
- **Validation:** MUST parse as a valid date.
- **Extension point:** Immutable.

### `session`

- **Type:** String
- **Required:** MUST be present. §1.4 provenance.
- **Constraints:** Non-session values permitted: `"dashboard"`,
  `"direct"`.
- **Default:** None.
- **Consumer:** Context tracer. **Question:** "Where was this
  observation recorded?"
- **Validation:** Non-empty string.
- **Extension point:** Immutable.
- **Governing decisions:** S027 (session replaces source — unified
  provenance).

### `origin`

- **Type:** String
- **Required:** OPTIONAL. §1.4 provenance.
- **Default:** None.
- **Consumer:** Note historian. **Question:** "Where did this
  observation originally come from?"
- **Validation:** No constraints.
- **Extension point:** Immutable.

### `text`

- **Type:** String (multi-line RECOMMENDED)
- **Required:** MUST be present. MUST be non-empty.
- **Constraints:** Self-contained observation. A reader SHOULD be able
  to understand the note without finding the referenced session.
- **Default:** None.
- **Consumer:** Everyone. **Question:** "What was observed?"
- **Validation:** Non-empty string.
- **Extension point:** Immutable.

### `visibility`

- **Type:** String
- **Required:** OPTIONAL. §1.7.
- **Default:** `internal` when absent.
- **Extension point:** Immutable.

---

# §10 — Trust Boundary

The pqdx schema supports projects whose canonical state file remains
private and projects whose canonical state file is published openly.
This chapter specifies the shared model that handles both: the
posture a project declares, the visibility values that govern per-
entity disclosure, the projection key that identifies generated
public artifacts, and the algorithm by which canonical state files
transform into public projections.

This chapter is the normative home for trust boundary concepts
referenced throughout STD-0001. Field-level visibility was
introduced in §1.7; that section now redirects here for the full
specification. The posture model itself is established by DR-009 and
operationalized below; readers seeking design rationale should
consult DR-009.

## §10.1 Posture Model

A pqdx project's posture is a configuration of three orthogonal
axes:

| Axis | Values | Affects |
|------|--------|---------|
| Canonical visibility | `private` / `public` | Where the canonical state file lives in version control |
| Projection role | `none` / `regenerable` / `authoritative` | Whether `{project}.public-state.yaml` exists, and whether it is published as the source of truth for external audiences |
| Operator coordination | `solo` / `multi-operator` | Whether canonical storage requires a coordination layer (pqsy or equivalent) |

Two named postures are defined as default configurations of those
axes:

| Posture | Canonical visibility | Projection role | Operator coordination |
|---------|----------------------|-----------------|------------------------|
| **Private** (default) | Private (in-tree) | `none` or `regenerable` | Solo or git-mediated multi-operator |
| **Public** | Private (separate tree or out-of-band) | `authoritative` (committed, published) | Solo or pqsy-mediated multi-operator |

Other axis combinations are valid; operators MAY compose them with
appropriate gitignore configuration. Valid-but-unnamed combinations
are referred to as **custom postures**.

New named postures MUST be added via Decision Record. Operators MUST
NOT mint posture names ad hoc and have them recognized as ecosystem-
standard.

Every pqdx-governed project declares a posture. The schema slot for
declaration is specified in §10.2. Silent posture ambiguity is
itself a posture violation — for projects whose declared posture is
`custom`, prose justification SHOULD appear in onboarding
documentation.

**Governing decisions:** DR-009 (posture model); §10.2 (declaration
site); §10.3 (visibility values used in projection generation).

## §10.2 Posture Declaration — `identity.posture`

The `identity.posture` field is the schema slot for posture
declaration on every pqdx-governed project's state file.

### `identity.posture`

- **Type:** String
- **Required:** OPTIONAL.
- **Constraints:** Values: `private | public | custom`. Closed set.
- **Default:** `private` when absent.
- **Consumer:** Ecosystem tooling (pqdc-cc, pqdc-init, pqsn,
  pqsy/pqtf when shipped), portfolio dashboards, validators,
  contributors orienting to a project. **Question:** "Is this
  project's canonical state file private, published, or operating
  under a custom configuration that needs review?"
- **Validation:** See §11 (validation chapter).
- **Extension point:** Aliasable for display only. Vocabulary
  profiles MAY rename `private` (e.g., to `internal-only`) or
  `public` (e.g., to `oss-published`) for domain-specific UI; the
  underlying enum values remain canonical in state file content.
- **Governing decisions:** DR-009 (posture model and declaration
  requirement). Field added in SD-6 / GAP-10 resolution (S036).

### Defaulting behavior

A state file with no `identity.posture` field MUST be treated as
`posture: private` by all conformant tools.

Absent and explicit `posture: private` are semantically equivalent
at runtime. Tools performing operations other than explicit
migration SHOULD NOT silently add or remove the explicit form; the
distinction is preserved at the file level for audit-trail
integrity.

### Custom posture declaration

When `identity.posture: custom`, the operator has chosen an axis
combination not covered by the named postures. Tools cannot
programmatically validate that a custom posture is consistent — this
is by design. The `custom` value is a declared signal that the
project's configuration warrants review by anyone unfamiliar with
it.

For `custom` posture:

- The operator SHOULD document the chosen axis values in onboarding
  documentation.
- Tools SHOULD warn (not error) when encountering `posture: custom`
  without onboarding documentation present at conventional locations
  (`README.md`, `CONTRIBUTING.md`, `.pqdx/docs/`).
- Validators MUST NOT block operations on `custom` posture; the
  value is informational at the schema level.

If a custom posture configuration becomes common across multiple
projects, an operator SHOULD propose it as a new named posture via
Decision Record (per §10.1).

### Public posture additional requirements

When `identity.posture: public`:

- The state file MUST include the top-level `projection` key (see
  §10.4) declaring the projection mode.
- Validators SHOULD verify that a corresponding
  `{project}.public-state.yaml` projection file exists at the
  expected location, OR that `projection.mode: regenerable` is
  declared (which permits the projection to be generated on demand
  rather than stored alongside the canonical).
- Tools generating the public projection MUST follow the projection
  algorithm specified in §10.6.

### Examples

Private posture (default — most projects):

```yaml
identity:
  project: my-internal-tool
  # ... other fields ...
  # posture: private  # OPTIONAL; absent is equivalent
```

Public posture (canonical Rust implementation, OSS publication,
etc.):

```yaml
identity:
  project: pqdx-rs
  # ... other fields ...
  posture: public
```

Custom posture (axis combination not covered by named defaults):

```yaml
identity:
  project: my-hybrid-project
  # ... other fields ...
  posture: custom
# See README.md "Repository posture" section for axis configuration.
```

## §10.3 Entity Visibility — `visibility` field

Every stateful entity in a state file MAY carry an optional
`visibility` field declaring whether and how the entity appears in
public projections.

### `visibility`

- **Type:** String
- **Required:** OPTIONAL.
- **Constraints:** Values: `internal | skeleton | public`. Closed
  set.
- **Default:** `internal` when absent (security-first per ILD-149).
- **Consumer:** Projection algorithm (§10.6); tool implementations
  rendering audience-filtered views (e.g., pqdc-cc's internal/public
  toggle). **Question:** "Should this entity appear in public
  projections, and if so, with what content?"
- **Validation:** Value MUST be in the enumerated set when present.
  `skeleton` is meaningful only on entity types with a defined
  skeleton field set (§10.5); on entity types without a defined
  skeleton, validators MUST treat `skeleton` equivalently to
  `internal`.
- **Extension point:** Aliasable for display only. Vocabulary
  profiles MAY rename values for domain-specific UI; the underlying
  enum values remain canonical in state file content.
- **Governing decisions:** ILD-135 (per-entry visibility field);
  ILD-149 (security-first absent default); ILD-151 (nested
  inheritance); DR-009 (operationalized in trust boundary chapter).

### Value semantics

- **`internal`** — The entity does not appear in public projections.
  Used for content the operator does not wish to publish.
- **`skeleton`** — The entity appears in public projections in
  stripped form, retaining only the fields enumerated in the entity
  type's skeleton field set (§10.5). Used for entities whose
  existence is part of the public record but whose content is not.
- **`public`** — The entity appears in public projections in full.
  Asserts that the entire entry is safe to publish — there is no
  per-field visibility (per ILD-140; if any field of an entity is
  sensitive, the entry stays `internal`).

### Resolution order

When generating a public projection (§10.6), tools determine each
entity's effective visibility by walking this resolution order:

1. **Explicit field value.** If the entity has an explicit
   `visibility` value, use it.
2. **Parent inheritance** (nested entities only). For milestone
   items and for `produced` artifacts inside session entries,
   inherit the parent entity's resolved visibility (per ILD-151).
3. **Section default.** If the entity's `visibility` is absent and
   no parent inheritance applies, the projection algorithm applies
   the section default from the table below.
4. **Floor.** If no section default applies, the entity is treated
   as `internal`.

### Section visibility defaults

The following defaults govern projection generation when an entity's
`visibility` is absent. Operators MAY override on individual
entities; the section default applies only to entities without an
explicit value.

| Section | Default visibility | Notes |
|---------|---------------------|-------|
| `schema_version` | `public` | Required for projection self-identification; always rendered. |
| `vocabulary` | `public` (filtered) | `field` and `specialty` layers retained; `org`, `team`, `individual` layers stripped (per ILD-131 + S036 OQ-A). |
| `identity` | `public` | Project-level summary information; intended for portfolio surfaces (per ILD-136). Operators MUST NOT include financial, competitive, or personnel-sensitive values in `identity.metrics` (per ILD-139). |
| `milestones` | `public` | Version-scoped scope and progress (per ILD-136). Items inherit per ILD-151. |
| `decisions` | `internal` | Decision records and open questions default private (per ILD-136). |
| `concerns` | `internal` | Per ILD-136. |
| `actions` | `internal` | Per ILD-136. |
| `sessions` | `skeleton` | Structure preserved, content stripped (per ILD-136 + ILD-137). |
| `queued` | `internal` | Per ILD-136. |
| `notes` | `internal` | Per ILD-136. |

These defaults are normative for projection algorithm conformance
(§10.6); two conformant projection tools MUST produce identical
output from identical canonical input under identical posture
declarations.

### Nested entity inheritance

For nested entities — milestone items within milestones, and
`produced` artifacts within sessions — the resolution order applies
the parent's resolved visibility before the section default.

Concretely:

- A milestone item without an explicit `visibility` inherits the
  parent milestone's resolved visibility. If the parent milestone
  resolves to `public`, the item resolves to `public`. If the parent
  resolves to `internal`, the item resolves to `internal` regardless
  of the milestones-section default.
- A `produced` artifact entry without an explicit `visibility`
  inherits the parent session's resolved visibility. If the parent
  session resolves to `skeleton`, the produced array is stripped per
  the session skeleton field set (§10.5).
- An operator MAY override inheritance by setting `visibility`
  explicitly on the nested entity.

This rule means an operator marking a milestone `public`
automatically publishes its items. Operators retain the option to
mark individual items `internal` if some items in a public milestone
should not appear.

## §10.4 Projection Key — `projection`

The top-level `projection` key is the file-identification marker for
generated public projection files.

### `projection`

- **Type:** String
- **Required:** OPTIONAL.
- **Constraints:** Closed set of values: `public`. Future projection
  types are reserved as additional string values; current schema
  accepts only `public`.
- **Default:** Absent on canonical state files; present on generated
  projection files.
- **Consumer:** Any tool reading a state file. **Question:** "Is
  this file the canonical state file or a generated projection?"
- **Validation:** When present, value MUST be `public`. Tools SHOULD
  treat files carrying `projection: public` as read-only —
  modifications to projection files do not flow back to canonical
  and are lost on the next regeneration.
- **Extension point:** Immutable. The string `public` is the v2.0.0
  projection type; additional types require schema amendment.
- **Governing decisions:** ILD-134 (key introduction); ILD-152
  (formalization, read-only convention, forward compatibility);
  DR-009 (header convention preserved in posture model).

### Canonical state files MUST NOT carry the `projection` key

The `projection` key is valid only on generated projection files.
Tools encountering `projection: public` on a file in the canonical
location (`.pqdx/{project}.state.yaml`) MUST flag this as a
structural error.

### Relationship to posture

Whether a project generates a projection at all is determined by
`identity.posture`, not by the `projection` key:

| `identity.posture` | Generated projection file | `projection` key on generated file |
|--------------------|---------------------------|---------------------------------------|
| `private` (default) | Optional. May be regenerated on demand and gitignored, or absent. | `projection: public` when present. |
| `public` | Required. `{project}.public-state.yaml` MUST exist alongside canonical and MUST be regenerated before any push to a public-tracked branch (per ILD-142). | `projection: public`. |
| `custom` | Operator-declared in onboarding documentation. | `projection: public` if a public projection exists. |

Projection mode (regenerable vs. authoritative, in DR-009's axis
vocabulary) is implied by posture: `public` posture means
authoritative projection; `private` posture with a generated
projection means regenerable. Operators do not declare projection
mode independently.

### Projection target filename

Generated projection files MUST be named
`{project}.public-state.yaml` (per ILD-133), where `{project}`
matches the canonical's `identity.project` value. The projection
file lives in the same directory as the canonical (typically
`.pqdx/`).

Future projection types (e.g., `audit-state`, `partner-state`) are
reserved but not specified in v2.0.0. The string `public` in the
`projection` key is the only currently recognized value.

## §10.5 Skeleton Field Set

When an entity's resolved visibility (§10.3) is `skeleton`, the
projection algorithm (§10.6) emits the entity with only the fields
enumerated in the entity type's skeleton field set. All other fields
are stripped.

The skeleton field sets defined in this section are normative. Two
conformant projection tools MUST produce identical output for
skeleton entities given identical canonical input. Domain profiles
and tools MAY add fields to an entity that are not enumerated here;
such fields are stripped from skeleton output regardless of their
absence from this enumeration (skeleton field sets are *whitelist*,
not blacklist).

The design principle for every skeleton: **classification metadata
and lifecycle traceability are retained; substantive content is
stripped.** A reader of a skeleton entity can verify that the entity
exists, see how it is classified, and trace its lifecycle, but
cannot read its substantive content.

### Vocabulary (special case — layer-based, not field-based)

The `vocabulary` block is not subject to skeleton field semantics.
Public projection retains the `field` and `specialty` layers in full
and strips the `org`, `team`, and `individual` layers (per ILD-131
and S036 OQ-A). This rule is specified in §10.3's section default
table; no entity-level `visibility` declaration applies to the
vocabulary block.

### Identity

- **Skeleton fields:** `project`, `entity`, `type`, `tier`,
  `posture`, `blast_radius`, `created`, `status`
- **Stripped fields:** `description`, `owner`, `contact`, `metrics`,
  `team`, `notes`
- **Rationale:** Project fingerprint (what it is, who governs it,
  when it started, current operational state) is retained.
  Personnel (`owner`, `contact`, `team`), substantive description,
  quantitative metrics, and freeform notes are stripped.
- **Governing decisions:** ILD-150 (skeleton normative across entity
  types); ILD-139 (sensitive content guidance for `metrics`).

Identity defaults to `public` per the section default table (§10.3);
`skeleton` on identity is meaningful only when an operator
explicitly downgrades.

### Milestones

- **Skeleton fields:** `id`, `name`, `status`, `target`, `completed`, `session`
- **Stripped fields:** `notes`, `items` field content (see below)
- **Items in skeleton:** Each milestone item is reduced to `id`,
  `status`, `gate`. The `text` and `notes` fields are stripped from
  items.
- **Rationale:** Scope structure (which version contains which item
  slots) and progress (which items are done, which gate items
  remain) are retained. The substantive description of each item is
  stripped. Opening-session provenance is retained as
  lifecycle-traceability metadata, consistent with skeleton field
  sets for other entity types that carry `session` (per DR-010).
- **Governing decisions:** ILD-150 (skeleton normative); ILD-151
  (nested inheritance — items inherit milestone visibility unless
  explicitly overridden); DR-010 (session added to milestone skeleton).

### Decisions (DR, OQ, ILD)

- **Skeleton fields (all subtypes):** `id`, `title`, `status`,
  `session`, `blast_radius`, `scope`, `decision_date`
- **Stripped fields (all subtypes):** `notes`, `origin`, `closed_in`
- **DR additional skeleton fields:** `companion` (location
  reference, not content), `reviewed_by`, `superseded_by`
- **OQ additional skeleton fields:** `impact`
- **OQ additional stripped fields:** `resolution_path`
- **ILD additional skeleton fields:** `superseded_by`
- **Rationale:** Decision metadata (what was decided, what status,
  what scope, when it became binding) is retained. Substantive
  notes, resolution paths, and provenance trails are stripped. Title
  is retained because it is the decision's identity; operators with
  sensitive titles SHOULD use `internal` visibility, not `skeleton`.
- **Governing decisions:** ILD-150; ILD-165 (`blast_radius` common);
  ILD-173 (`scope` common); ILD-174 (`decision_date` common).

### Concerns

- **Skeleton fields:** `id`, `type`, `severity`, `status`, `session`,
  `closed_in`
- **Stripped fields:** `text`, `ref`, `resolution`, `blocks`,
  `notes`, `origin`
- **Rationale:** Concern classification (what kind of deficiency,
  how severe, what state) and lifecycle provenance (which session
  opened it, which session closed it) are retained. Substantive
  description, resolution narrative, and block relationships are
  stripped.
- **Governing decisions:** ILD-150; ILD-67 (universal concern
  types); ILD-148 (severity scale).

### Actions

- **Skeleton fields:** `id`, `status`, `priority`, `due`,
  `closed_in`, `session`
- **Stripped fields:** `text`, `assignee`, `origin`, `depends_on`,
  `resolution`, `notes`
- **Rationale:** Action lifecycle (what state, what priority, when
  due, when closed, what session formalized it) is retained.
  Personnel (`assignee`), substantive description, dependencies, and
  resolution narrative are stripped. The deliberate omission of
  `text` from skeleton means a reader sees that an action exists and
  where it is in its lifecycle, but not what the action requires.
- **Governing decisions:** ILD-150; ILD-162 (priority on actions);
  ILD-166 (assignee SHOULD, not MUST).

### Sessions

- **Skeleton fields:** `id`, `date`, `title`, `purpose`, `mode`,
  `participants`
- **Stripped fields:** `produced`, `decisions_made`, `state_changes`,
  `next_action`, `notes`, `duration`, `planned_duration`, `origin`
- **Rationale:** Session structural metadata (when it happened, what
  kind of session, who was present, what mode of communication) is
  retained. Substantive output (`produced`, `decisions_made`,
  `state_changes`, `next_action`) and operational telemetry
  (`duration`, `planned_duration`) are stripped. Participants are
  retained because the governance trail "who was in the room" is
  part of session identity.
- **Governing decisions:** ILD-137 (S024 — session skeleton field
  set, the precedent for all other entity skeletons).

### Queued items

- **Skeleton fields:** `id`, `title`, `status`, `session`, `priority`,
  `scope`, `closed_in`
- **Stripped fields:** `prompt`, `depends_on`, `origin`, `notes`
- **Rationale:** Queue lifecycle metadata (what is planned, what
  state, how big, when closed) is retained. Substantive prompt
  content, dependency graph, and notes are stripped.
- **Governing decisions:** ILD-150; ILD-39 (priority on queued
  items); ILD-163 (scope on queued items).

### Notes

- **Skeleton fields:** `id`, `date`, `session`
- **Stripped fields:** `text`, `origin`
- **Rationale:** Note existence and provenance (when, which session)
  are retained. The note's content is stripped. Skeleton on notes is
  meaningful for audit-trail purposes — proving that observations
  were recorded without disclosing what was observed.
- **Governing decisions:** ILD-150; ILD-164 (notes gain `id`).

### Behavior on extension fields

Domain profiles and individual projects MAY introduce additional
fields on entities (per the extension point model in
PQDX-STD-0002). Such extension fields are stripped from skeleton
output unless explicitly enumerated in this section.

A future revision of this specification MAY add extension fields to
skeleton field sets — for example, if a domain profile field becomes
commonly-needed for skeleton-projection purposes, the schema could
be amended to include it. Until such amendment, conformant
projection tools strip all non-enumerated fields.

This whitelist approach is the security-conservative default: an
operator adding a new field cannot accidentally publish its content
via skeleton projection without an explicit schema amendment.

## §10.6 Projection Algorithm

The projection algorithm transforms a canonical state file into a
public projection file. The transformation is mechanical,
deterministic, and reproducible across implementations: two
conformant projection tools given the same canonical state file, the
same loaded vocabulary profiles, and the same posture declaration
MUST produce byte-identical projection output.

The algorithm is a strict subset operation (per ILD-138). The
projection emits a subset of the canonical's content — never
modified, paraphrased, summarized, or substituted. Stripping fields
and omitting entries are the only permitted transformations.

### §10.6.1 Inputs

A projection algorithm implementation accepts:

1. **Canonical state file** (`{project}.state.yaml`), parsed into
   the schema's data model.
2. **Vocabulary profiles** referenced in the canonical's
   `vocabulary` block, loaded and resolved per PQDX-STD-0002 §6.5.
3. **Posture declaration** read from the canonical's
   `identity.posture` field (or the default `private` if absent).

### §10.6.2 Preconditions

Before generating a projection:

1. The canonical state file MUST validate against the pqdx/2.0.0
   schema. Tools MUST refuse to project an invalid canonical.
2. `identity.posture` MUST be `public`. Tools MUST refuse to
   generate a projection for `private` posture (no projection is
   needed) or for `custom` posture without explicit operator opt-in
   (custom posture's projection mode is operator-declared).
3. The canonical MUST NOT itself carry the top-level `projection`
   key (per §10.4). Tools encountering a `projection` key on a
   canonical MUST emit a structural error and refuse.

If any precondition fails, the tool emits an error describing the
failure and exits without producing output.

### §10.6.3 Output scaffold

The projection's top-level structure is constructed in this order:

1. `schema_version` — copied verbatim from canonical.
2. `projection: public` — added to identify the file as a projection
   (per §10.4 and ILD-152).
3. `vocabulary` — emitted per §10.6.5 (vocabulary projection).
4. `identity` — emitted per §10.3 visibility resolution. Identity
   defaults to `public`; skeleton applies if the operator marked
   identity `skeleton`; the entity is omitted entirely if marked
   `internal`.
5. Each remaining section (`milestones`, `decisions`, `concerns`,
   `actions`, `sessions`, `queued`, `notes`) — emitted per §10.6.4
   (section processing).

Sections that produce empty output (all entries internal, or section
was empty in canonical) MUST be emitted as empty arrays (`[]`), not
omitted. The eleven top-level keys present in canonical state files
are also present in projections; absence of a key is reserved for
forward compatibility, not for "no entries to emit."

### §10.6.4 Section processing

For each entity-bearing section in the canonical:

1. Iterate entries in canonical order. The projection MUST preserve
   the canonical's entry order; reordering is a structural
   violation.
2. For each entry, compute the entry's resolved visibility per §10.3
   resolution order (explicit value → parent inheritance → section
   default → internal floor).
3. Apply visibility to determine emission:
   - **`internal`** — Skip the entry entirely. The projection
     contains no record of the entry.
   - **`skeleton`** — Emit the entry with only the fields enumerated
     in §10.5 for the entity type. All other fields are stripped.
   - **`public`** — Emit the entry with all fields present in the
     canonical, with no field-level filtering (per ILD-140 — the
     entry is the unit of trust).
4. Nested entities (milestone items, `produced` artifacts) are
   processed within their parent's emission per §10.3 inheritance
   rules and §10.5 skeleton field sets.

### §10.6.5 Vocabulary block projection

The `vocabulary` block in the projection retains the `field` and
`specialty` layers from the canonical and strips the `org`, `team`,
and `individual` layers (per §10.3 section default rule and
ILD-131).

The retained layers are emitted in their full canonical form;
profile entries within retained layers are not subject to per-entity
visibility filtering. Stripped layers MUST be emitted as empty
arrays:

```yaml
vocabulary:
  field:
    - profile: pqdc-software-dev
      version: 1.0.0
  specialty: []
  org: []
  team: []
  individual: []
```

The five-layer key inventory is preserved structurally regardless of
which layers contain content (per ILD-114).

### §10.6.6 Serialization conventions

For byte-deterministic output, conformant projection tools MUST emit
YAML following these conventions:

1. **Encoding.** UTF-8 with no byte-order mark.
2. **Line endings.** LF (`\n`). CRLF is non-conformant.
3. **Final newline.** A single trailing newline at end of file.
4. **Indentation.** Two-space indentation for nested structures.
   Tabs are non-conformant.
5. **Key order within mappings.** Schema-canonical order. For each
   entity type, the field order is the order specified in the
   entity's schema definition (PQDX-STD-0001a). Operator-authored
   field order in canonical is NOT preserved in projection output.
6. **List style.** Block style for multi-element lists in most
   sections. Flow style is required for milestone items (per
   ILD-22) and for inline arrays (`decisions_made`, `depends_on`,
   `blocks`, `blocked_by` per PQDX-GDE-0001 Rule 5). Empty arrays
   use the flow-style empty literal `[]`.
7. **String quoting.** Double quotes only when required by YAML
   grammar (strings containing colons, leading/trailing whitespace,
   ambiguous values such as `yes`/`no`/`true`/`false`, or starting
   with reserved characters). Otherwise unquoted.
8. **Multi-line strings.** Folded scalar (`>`) for prose; literal
   scalar (`|`) for content where line breaks are semantically
   significant. The choice MUST follow the form used in the
   canonical.
9. **Boolean and null serialization.** Booleans as `true` / `false`.
   Nulls as the literal `null`, never as empty string.
10. **Date serialization.** ISO 8601 dates as unquoted bare strings
    (`YYYY-MM-DD`).
11. **Numeric serialization.** Integers as bare integers; decimals
    as bare decimals with a leading digit (`0.5`, never `.5`).
12. **Comments.** Comments in the canonical are NOT preserved in
    the projection. Comments are operator authoring aids; they do
    not survive projection.

These conventions are defined normatively to ensure projection
determinism. Tools whose YAML serialization library produces output
deviating from these conventions MUST apply a post-processing step
to normalize the output before writing.

### §10.6.7 Conformance

A projection tool is **conformant** with §10.6 when, for every
well-formed canonical state file with `identity.posture: public` and
a fully resolved vocabulary stack, it produces byte-identical output
to the reference implementation.

The reference implementation for pqdx/2.0.0 is currently pqdx-rs's
prototype projection tool (per DR-009 Risks & Mitigations: "Block
production tooling implementations until SD-6 resolution lands the
algorithm spec inside STD-0001's trust boundary section"). Reference
status will transfer to pqtf (Piqued Transform) when shipped.

A projection tool that diverges from byte-identity is non-conformant.
Divergences are a structural defect, not a styling preference —
non-conformance breaks the audit invariant that the public projection
is a deterministic function of canonical state plus posture.

### §10.6.8 Regeneration discipline

Per ILD-142, the projection file MUST be regenerated before any push
to a public-tracked branch. Tools generating projections SHOULD
provide a CI guard mode that:

1. Regenerates the projection from the current canonical.
2. Compares the regenerated output against the committed projection
   file.
3. Fails if they differ.

This discipline catches stale projections before they reach
published surfaces. The pattern is analogous to `go mod tidy` or
`gofmt -d` CI checks.

Operators MAY suppress regeneration during local edits, but the CI
guard MUST run on every public-branch push. A drift between
committed projection and current canonical is a governance defect.

## §10.7 Standard Infrastructure vs Project-Authored Content

A pqdx-governed repository contains two categories of content within
`.pqdx/`:

- **Standard infrastructure** — files distributed by `pqsn spec
  push` (or equivalent distribution mechanism) that are identical
  across all projects governed by the same standard version. The
  standard schema specs, bundled vocabulary profiles, ecosystem
  documents (Piqued Manifesto, C² Methodology), and standard-level
  decision records.
- **Project-authored content** — files written by the project's
  operators for the project's own purposes. Session artifacts,
  project-specific decision records, project-specific runbooks,
  project-specific documentation.

These categories carry different posture implications. This section
specifies the distinction and the projection rules that follow from
it. The discrimination *mechanism* for project-authored mixed-
provenance directories is deferred to OQ-11.

### §10.7.1 Standard Infrastructure

Files in `.pqdx/spec/` and `.pqdx/vocab/` are standard infrastructure
when they originate from `pqsn spec push` distribution. These
directories are managed by distribution tooling (currently `pqsn`,
future `pqtf`); their contents are identical across all projects
governed by the same standard version.

Standard infrastructure is **not subject to project posture
filtering**. The contents of `.pqdx/spec/` and `.pqdx/vocab/`:

- MUST be tracked in version control regardless of project posture.
- MUST be present in fresh clones for the project's governance to
  be operational.
- Are not subject to the projection algorithm in §10.6 — the
  projection algorithm operates on the state file, not on
  infrastructure files alongside it.

Rationale: standard infrastructure is the project's governance
configuration, not project-authored content. A public-posture
project cannot omit `.pqdx/spec/` from its public-tracked tree —
the spec is what tells consumers (and tools) which standard the
project is governed by. Withholding it would render the project
ungovernable.

**Vocabulary layer exception.** Per ILD-222, vocabulary profiles
are organized by layer in `.pqdx/vocab/{layer}/` subdirectories. The
`org`, `team`, and `individual` layer subdirectories may contain
operator-internal alias mappings; per §10.3 section default and
ILD-131, only `field` and `specialty` layer profiles project to
public-state. For public-posture projects, the `org`, `team`, and
`individual` layer subdirectories MAY be gitignored at the directory
level — this is gitignore-time filtering, distinct from
projection-time visibility filtering. The directory structure
persists via the structural persistence pattern (ILD-223 / ILD-224).

### §10.7.2 Project-Authored Mixed-Provenance Content

Three `.pqdx/` subdirectories contain content of mixed provenance:

- **`.pqdx/docs/`** — project-authored governance documentation,
  sometimes alongside synced kit content (templates and references
  redistributed from upstream) and operator drafts.
- **`.pqdx/runbooks/`** — project-authored operational procedures,
  sometimes alongside synced standard runbooks and operator drafts.
- **`.pqdx/sessions/`** — session artifacts (prompts, captures,
  deliverables) produced during AI-collaborative work, whose
  individual provenance varies (project-authored deliverables,
  synced kit prompts, operator-internal verbatim transcripts).

For public posture, these directories require a mechanism to
discriminate project-authored content (commits to public history)
from synced kit content and operator-internal drafts (gitignored).
Without such a mechanism, public-posture projects either commit
content that should remain private, or rely entirely on operator
discipline at authoring time — which is fragile.

This specification does NOT mandate a specific discrimination
mechanism in pqdx/2.0.0. The choice is deferred to OQ-11 (per
DR-009 §Alternatives Considered, Alternative D). Three candidate
mechanisms with materially different trade-offs are tracked in
OQ-11 for comparison-depth analysis:

- **Filename-prefix re-allow** — `.gitignore` re-allows files
  matching `{project}-*.md`. Two-line rule. Fragile under rename.
- **Subdirectory-based provenance** — `docs/project/`, `docs/synced/`,
  `docs/drafts/` separate provenance at directory level. Increases
  nesting; provenance is explicit.
- **Frontmatter-based discrimination** — each doc carries a
  `visibility:` field; gitignore via metadata. Most flexible;
  requires tooling support.

OQ-11 will select among these (or compose them) and produce the
normative mechanism via a follow-on Decision Record.

### §10.7.3 Interim guidance pending OQ-11

Until OQ-11 resolves, public-posture projects MUST address
provenance discrimination through one or more of the following
operational patterns:

1. **Operator discipline at PR-review time.** Reviewers verify that
   commits to `.pqdx/docs/`, `.pqdx/runbooks/`, and `.pqdx/sessions/`
   contain only project-authored content intended for the public
   surface. This is the minimum pattern; it is fragile but workable
   at small operator counts.

2. **Recursive ignore plus structural persistence** (per ILD-223 and
   ILD-224). The standard `.pqdx/` subdirectory structure persists
   in fresh clones via `.gitkeep` re-allow rules; content within
   those subdirectories is gitignored except where explicit re-allow
   rules opt content in. This is the pattern prototyped in
   pqdx-rs:S001 and adopted by DR-009 for both private and public
   postures.

3. **Filename-prefix re-allow** (per the pqdx-rs:S001 prototype,
   ungoverned by this specification at v2.0.0). Operators MAY apply
   `!/{project}-*.md` re-allow rules to `.pqdx/docs/` and
   `.pqdx/runbooks/` as a transitional pattern. Operators choosing
   this path SHOULD document the choice as a project-local deviation
   pending OQ-11 resolution.

Operators MUST NOT treat the absence of an OQ-11 resolution as
license to commit operator-internal content to public history. The
OQ-11 deferral is a deferral of mechanism choice, not of the
underlying constraint that operator-internal content stay out of
public-tracked surfaces.

When OQ-11 resolves with a chosen mechanism, public-posture projects
following interim patterns SHOULD migrate to the resolved mechanism.
The migration cost is tracked as part of OQ-11's downstream impact.

---

# §11 — Validation Rules

This section defines the validation rules that conforming tools MUST
enforce. A conforming validator produces zero errors and zero warnings
against the canonical fixture (PQDX-STD-0001d).

## §11.1 Schema Version Validation

Tools MUST check `schema_version` before processing. The value MUST
match `pqdx/{semver}`. Major mismatch SHOULD cause a warning or refusal.
Minor excess SHOULD warn but MUST NOT reject. Patch difference is fully
compatible.

## §11.2 Top-Level Key Validation

All eleven keys (§1.2) MUST be present. Tools SHOULD warn on unknown
top-level keys but MUST NOT reject the file (per ILD-153).

## §11.3 Vocabulary Block Validation

The `vocabulary` mapping MUST have exactly five keys: `field`,
`specialty`, `org`, `team`, `individual`. All five MUST be present.
Each key's value MUST be a sequence (empty `[]` is valid). Each entry
in a layer MUST have `profile` (string) and `version` (string) fields.

## §11.4 Entity ID Validation

### Uniqueness

IDs MUST be unique within their containing sequence:

- Decision IDs unique within `decisions` (across all three subtypes)
- Concern IDs unique within `concerns`
- Action IDs unique within `actions`
- Session IDs unique within `sessions`
- Queued item IDs unique within `queued`
- Note IDs unique within `notes`
- Milestone IDs unique within `milestones`
- Milestone item IDs unique within their parent milestone's `items`

### Pattern Validation

| Entity | Pattern | Example |
|--------|---------|---------|
| Decision Record | `^DR-\d+$` | `DR-001` |
| Open Question | `^OQ-\d+$` | `OQ-1` |
| Informal Locked Decision | `^ILD-\d+$` | `ILD-47` |
| Concern | `^[A-Z]{1,4}-\d+$` | `BL-1`, `DEF-3` |
| Action | `^A-\d+$` | `A-1` |
| Session | `^S\d+$` | `S014` |
| Queued Item | `^QI-\d+$` | `QI-1` |
| Note | `^N-\d+$` | `N-1` |
| Milestone | freeform | `v1.0` |
| Milestone Item | freeform (convention: `{ms}-N`) | `v01-1` |

Entity ID sequence numbers are unbounded decimal integers. Canonical
spelling: Session and DR are zero-padded to a minimum of three digits;
OQ, ILD, concerns, queued, and notes carry no leading zeros. Consumers
MUST order IDs by integer value, never lexically.

## §11.5 Status Validation

Each stateful entity type has a closed status set. Tools MUST reject
unknown status values.

| Entity | Valid Statuses |
|--------|---------------|
| Identity | `active`, `dormant`, `archived`, `complete` |
| Milestone | `planned`, `in-progress`, `on-hold`, `complete`, `cancelled` |
| Milestone Item | `open`, `done`, `deferred`, `dropped`, `subsumed` |
| DR | `proposed`, `accepted`, `deferred`, `superseded`, `rejected`, `withdrawn` |
| OQ | `open`, `narrowed`, `deferred`, `resolved` |
| ILD | `pending`, `locked`, `superseded` |
| Concern | `open`, `monitoring`, `deferred`, `resolved` |
| Action | `open`, `blocked`, `deferred`, `done`, `cancelled` |
| Queued Item | `pending`, `in-progress`, `deferred`, `complete`, `cancelled` |

## §11.6 Required Field Validation

Tools MUST verify that all MUST-level fields are present and non-empty
on every entity. The specific fields are documented per entity type in
§2–§9.

## §11.7 Milestone Completion Guard

When a milestone has `status: complete`, tools MUST verify the three
conditions in §3.4. Violation is an error.

## §11.8 Value Set Validation

For all fields with closed value sets (status, severity, impact,
priority, blast_radius, tier, type, purpose, mode, format,
participant type, participant role), tools MUST validate that the value
is in the enumerated set. Unknown values are errors for immutable
fields, warnings for aliasable fields (the value may come from a
vocabulary profile the tool doesn't have).

## §11.9 Concern Prefix-Type Agreement

The concern ID prefix and `type` field MUST agree. A concern with
`id: BL-1` MUST have `type: blocker`. The universal mapping is defined
in §5.3. Domain profiles extend this mapping — tools SHOULD load
available vocabulary profiles to validate domain-specific prefixes.

## §11.10 Visibility Validation

When present, the `visibility` field MUST have a value of `internal`,
`skeleton`, or `public`. Unknown values are errors. Full value
semantics, resolution order, section defaults, and inheritance rules
are specified normatively in §10.3.

## §11.11 Skeleton Field Sets

The normative skeleton field sets for every entity type are specified
in §10.5. When generating projections, tools MUST use those field sets
for entities with resolved visibility `skeleton`; only the enumerated
fields are preserved and all others are stripped. Two independent
implementers MUST produce identical skeleton output for the same input
entity (per §10.5 conformance requirement).

## §11.12 Projection Validation

Files with `projection: "public"` MUST NOT contain entities with
`visibility: internal`. Tools SHOULD warn if a projection file contains
internal entities — this indicates a generation error. The full
projection algorithm and conformance requirements are specified in
§10.4 (projection key) and §10.6 (projection algorithm); §11.17
specifies additional structural-consistency rules between canonical
and projection files.

## §11.13 Cross-Entity Reference Validation

Tools MUST NOT error on unresolvable entity references in `depends_on`,
`blocked_by`, `blocks`, `decisions_made`, `superseded_by`, or
cross-project references. The referenced entity may be in another
project, may not yet exist, or may have been removed from scope.

Tools MAY warn on unresolvable references as an aid to the author.

## §11.14 Date Validation

All date fields (`created`, `date`, `completed`, `due`,
`decision_date`) MUST parse as valid ISO 8601 dates (`YYYY-MM-DD`)
when present.

## §11.15 Resolution Guard

Concerns with `status: resolved` MUST have a `resolution` field.
Concerns with `status: open` MUST NOT have a `resolution` field.

## §11.16 Posture Validation

The following rules govern the `identity.posture` field:

1. When `identity.posture` is present, its value MUST be one of
   `private`, `public`, `custom`. Unrecognized values are
   validation errors.
2. When `identity.posture` is absent, validators MUST treat the
   file as posture `private` (per §10.2 defaulting behavior).
3. When `identity.posture` is `public`, the file MUST NOT carry
   the top-level `projection` key (per §10.4 — the `projection`
   key is valid only on generated projection files).
4. When `identity.posture` is `public`, validators SHOULD verify
   that a corresponding `{project}.public-state.yaml` projection
   file exists in the canonical's directory, OR that the project's
   documentation declares the projection as regenerable. Validators
   MUST NOT block on absence — projection generation may be
   deferred to a build step.
5. When `identity.posture` is `custom`, validators SHOULD warn if
   onboarding documentation is not present at conventional
   locations (`README.md`, `CONTRIBUTING.md`, `.pqdx/docs/`).
   Validators MUST NOT block on `custom` posture; the value is
   informational.
6. Tools MUST NOT silently rewrite or "upgrade" absent posture
   fields to explicit `private` (per §10.2). Migration tools that
   explicitly add the field at operator request MAY do so;
   non-migration operations MUST NOT.

## §11.17 Projection Consistency

The following rules govern the relationship between a canonical
state file and its generated public projection:

1. A file carrying the top-level `projection: public` is a
   generated projection file. Tools MUST NOT treat it as canonical,
   MUST NOT apply patches to it via `apply_patch` or equivalent
   canonical-mutation operations, and SHOULD treat it as
   read-only.
2. A canonical state file (one without the `projection` key) at
   `.pqdx/{project}.state.yaml` whose `identity.posture` is
   `public` MUST have its projection regenerated before any push
   to a public-tracked branch (per §10.6.8 and ILD-142).
3. The `vocabulary` block in a projection MUST contain only `field`
   and `specialty` layer entries (per §10.6.5). Validators
   encountering `org`, `team`, or `individual` layer entries in a
   file carrying `projection: public` MUST flag a structural
   error.
4. Entities marked `visibility: skeleton` in a projection MUST
   contain only the fields enumerated in §10.5 for the entity
   type. Additional fields beyond the skeleton field set are
   structural errors.
5. Entities marked `visibility: internal` MUST NOT appear in a
   projection. Any record of an internal entity in a file carrying
   `projection: public` is a structural error.
6. The projection's section ordering and entry ordering within
   each section MUST match the canonical's order (per §10.6.4 —
   projection is order-preserving). Reordering is a structural
   defect.
7. The projection MUST be a strict subset of the canonical (per
   ILD-138). Any field value in a projection that does not match
   the corresponding field in the canonical (after applying
   skeleton stripping) is a structural error indicating the
   projection has been modified outside the projection algorithm.

## §11.18 Validator Diagnostic Completeness

**(MUST)**

Within a single validation invocation, a pqdx validator MUST emit all diagnostics surfaced by its validation rule set rather than terminating after the first diagnostic.

### Scope of "single invocation"

For batch validators (whole-file validation entry points such as a CLI validator invoked on a state file), a single invocation covers the full input. For incremental validators that validate per-operation (such as MCP-server patch-entry validators), a single invocation covers all operations submitted in one call; diagnostics from across operations MUST be aggregated into a single diagnostic set, and individual diagnostics SHOULD be tagged with their originating operation when more than one operation is present in the batch.

### Exception — irrecoverable source-syntax failures

A validator MAY emit a single diagnostic and terminate early when the underlying source representation cannot be parsed under the YAML 1.2 grammar (for example: unterminated block scalar, structurally invalid token stream, malformed UTF-8 at the byte level). The exception applies only to YAML-grammar-level corruption of the source representation. It does NOT apply to:

- typed-conversion failures,
- structural-rule violations (including ID uniqueness violations),
- referential-rule violations (including missing-target failures on update operations),
- lifecycle-rule violations (including terminal-state gate failures),
- visibility-rule violations,
- projection-rule violations,
- or any other rule violation across one or more sections of the parsed input.

### Partial-validity continuation

When typed-conversion fails for one entity or one top-level section, validator passes (structural, referential, lifecycle, visibility consistency, projection determinism) MUST continue to operate on the typed-conversion-successful subset. When one entry within a multi-operation batch fails validation, the validator MUST continue validating subsequent entries. Diagnostics produced by downstream passes against a partial-result subset MAY include a help-text marker indicating the upstream cause when the downstream diagnostic is a direct consequence of the missing typed entity.

### Rollup thresholds

Reserved for a future additive update. At pqdx/2.0.0 this rule does not permit rollup-style diagnostic suppression; an implementation MUST emit all diagnostics surfaced by its validation rule set, subject only to the partial-validity continuation clause and the irrecoverable-source-syntax exception above.

### Conformance verification

`pqdx-conformance` provides multi-error fixtures under `parser/multi-error-*/`, `validator/structural/multi-error-*/`, `validator/referential/multi-error-*/`, and `validator/lifecycle/multi-error-*/`. Each multi-error fixture asserts an expected diagnostic set of size N ≥ 3 using set-equality semantics (order tolerated, contents exact) per pqdx-conformance fixture conventions. An implementation claiming `parser` or `validator` capability MUST emit a diagnostic set whose contents exactly match the fixture's expected set for each multi-error fixture's input. The conformance fixture set MUST include at least 2 fixtures per validator pass category and at least 1 cross-cutting fixture combining parser, structural, and referential diagnostics in a single input.

### Normative Note: Tool-Behavior Rules in §11

§11.18 is a validator-behavior rule (governing how diagnostics are emitted) rather than a state-file-property rule (governing what a valid state file looks like). It is placed in §11 following the §10.6 precedent — the projection algorithm, a tool-behavior rule, sits alongside state-file-property rules in §10 without sub-section split. Should additional validator-behavior rules accumulate (3+ beyond §11.18), §11 and §10 may be reorganized into structural/behavioral sub-sections via a future spec-organization DR.

---

## Appendix A — Minimal Valid File

The smallest conforming `{project}.state.yaml`:

```yaml
schema_version: "pqdx/2.0.0"

vocabulary:
  field: []
  specialty: []
  org: []
  team: []
  individual: []

identity:
  project: my-project
  description: "A brief description of the project."
  entity: "MyOrg"
  type: initiative
  tier: minimal
  owner: "Your Name"
  blast_radius: low
  created: "2026-01-15"

milestones: []
decisions: []
concerns: []
actions: []
sessions: []
queued: []
notes: []
```

## Appendix B — Location Scheme Reference

| Scheme | Purpose | Example |
|--------|---------|---------|
| `repo://` | Path relative to repository root | `repo://decisions/DR-001.md` |
| `project-knowledge://` | Claude project knowledge upload | `project-knowledge://pqdx.state.yaml` |
| `state://` | Entity within this state file | `state://decisions/DR-001` |
| `session://` | Inline in a session transcript | `session://S013` |
| `url://` | External URL | `url://https://pqdx.dev/spec` |
| `local://` | Local filesystem path | `local:///home/user/notes.md` |
| `pending://` | Planned but not yet created | `pending://decisions/DR-005.md` |

## Appendix C — Entity ID Quick Reference

| Pattern | Entity Type | Array | Padding |
|---------|-------------|-------|---------|
| `DR-NNN` | Decision Record | `decisions` | zero-padded, 3-digit minimum |
| `OQ-N` | Open Question | `decisions` | Simple integer |
| `ILD-N` | Informal Locked Decision | `decisions` | Simple integer |
| `{PREFIX}-N` | Concern | `concerns` | Simple integer, 1–4 char prefix |
| `A-N` | Action | `actions` | bare integer (no padding) |
| `SNNN` | Session | `sessions` | zero-padded, 3-digit minimum |
| `QI-N` | Queued Item | `queued` | Simple integer |
| `N-N` | Note | `notes` | Simple integer |
| *(freeform)* | Milestone | `milestones` | N/A |
| *(freeform)* | Milestone Item | `milestones[].items` | N/A (convention: `{milestone}-N`) |

## Appendix D — Lifecycle Summary

### Terminal States by Entity Type

| Entity Type | Terminal States |
|-------------|---------------|
| Milestone | `complete`, `cancelled` |
| Milestone Item | `done`, `deferred`, `dropped`, `subsumed` |
| DR | `superseded`, `rejected`, `withdrawn` |
| OQ | `resolved` |
| ILD | `superseded` |
| Concern | `resolved` |
| Action | `done`, `cancelled` |
| Queued Item | `complete`, `cancelled` |

### done vs. complete (ILD-54)

- **`done`** — Leaf entities (milestone items, actions). "I finished
  this task."
- **`complete`** — Containers / work units (milestones, queued items).
  "Everything within this scope is resolved."

### Deferred Asymmetry

- **Milestone item `deferred`** — Terminal in source milestone.
  Tombstone model (ILD-43). Fresh entry in target milestone.
- **Concern `deferred`** — Non-terminal. Reopenable. Stays in place.
- **Action `deferred`** — Non-terminal. Reopenable.
- **DR `deferred`** — Non-terminal. Returns to proposed.
- **OQ `deferred`** — Non-terminal. Returns to open.
- **Queued `deferred`** — Non-terminal. Returns to pending.

The underlying principle is consistent: "deferred" means "not now." The
divergence is in what happens next — milestone items relocate; all other
entities stay in place.

## Appendix E — Five-Value Scale Congruence

Four fields share the same five-value scale (per ILD-148):

| Field | Entity | Question |
|-------|--------|----------|
| `blast_radius` | Identity, Decisions | "How much damage?" |
| `severity` | Concerns | "How bad is this?" |
| `impact` | Open Questions | "How much does not knowing cost?" |
| `priority` | Actions, Queued Items | "How urgent is this?" |

The values: `negligible | low | medium | high | critical`.

The congruence is intentional — tools can use a single rendering scale,
color map, and sort order for all four fields. Domain profiles alias
display labels independently per field, but the underlying scale is
always the same five values.

---

*pqdx/2.0.0 Schema Specification — PQDX-STD-0001b*
*© 2026 Our Collaborative Space, LLC — CC-BY-ND 4.0*
