# 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*