diff --git a/.augur.toml b/.augur.toml new file mode 100644 index 0000000..031b459 --- /dev/null +++ b/.augur.toml @@ -0,0 +1,3 @@ +[thresholds] +review = 35 +block = 65 diff --git a/.claude/commands/specsync/create-change.md b/.claude/commands/specsync/create-change.md new file mode 100644 index 0000000..48571cd --- /dev/null +++ b/.claude/commands/specsync/create-change.md @@ -0,0 +1,10 @@ +--- +description: Create and guide a verified spec-sync SDD change through its deterministic interview +argument-hint: +--- + +1. Run `specsync change new "$ARGUMENTS" --json`. +2. Read the returned `questions` array and interview the user one question at a time. +3. Record each answer with `specsync change answer "" --json`, quoting the answer so multi-word text is passed as one argument. +4. Continue until the question list is empty, then show the selected artifacts and next action. +5. Do not approve, implement, verify, accept, or archive until the corresponding human gate or work stage is reached. diff --git a/.claude/commands/specsync/create-spec.md b/.claude/commands/specsync/create-spec.md new file mode 100644 index 0000000..efef30a --- /dev/null +++ b/.claude/commands/specsync/create-spec.md @@ -0,0 +1,39 @@ +--- +description: Scaffold a new spec-sync module spec from a module name or a natural-language feature description (full scaffold by default, or minimal with --minimal) +argument-hint: [--minimal] +--- + +Create a new spec-sync module spec. + +Arguments: `$ARGUMENTS` + +1. Remove `--minimal` wherever it appears and remember that minimal mode was + requested. Preserve the complete remaining text; do not tokenize it yet. +2. Classify the complete remaining text: + - **A bare module name** — a short identifier like `auth-service` or + `billing`, matching `^[A-Za-z0-9][A-Za-z0-9._-]*$`. Use it as-is. + - **A free-text feature description** — a sentence or phrase describing + what to build, e.g. `"I want a feature that lets users export their + data as CSV"`. In this case, invent a short, kebab-case module name that + captures the idea (e.g. `csv-export`). If the right name is ambiguous, + ask the user to confirm or rename it before continuing. Keep the full + description at hand — you'll use it in step 5. +3. If minimal mode was requested, run: + ``` + specsync new + ``` + This creates a minimal spec only (no companion files). +4. Otherwise (default), run: + ``` + specsync scaffold + ``` + This creates the spec, companion files (`tasks.md`, `requirements.md`, + `context.md`, `testing.md`, and `design.md` if `companions.design` is + enabled), a registry entry, and auto-detects related source files. +5. Open the newly created `specs//.spec.md` and fill + in the `Purpose`, `Requirements`, and `Public API` sections. If a free-text + description was given in step 2, use it directly to draft these sections — + ask clarifying questions if it's underspecified, but do not leave the + sections as unfilled placeholder text. Do the same for `requirements.md` + (acceptance criteria) and `tasks.md` (initial task breakdown), if present. +6. Run `specsync check` to confirm the new spec passes validation. diff --git a/.claude/skills/spec-sync/SKILL.md b/.claude/skills/spec-sync/SKILL.md new file mode 100644 index 0000000..4832c7b --- /dev/null +++ b/.claude/skills/spec-sync/SKILL.md @@ -0,0 +1,75 @@ +--- +name: spec-sync +description: Keep markdown module specs in specs// synchronized with source code using spec-sync. Use this whenever creating, editing, or reviewing code in a module that has (or should have) a spec, or whenever the user mentions specs, spec-sync, companion files (tasks.md/requirements.md/context.md/testing.md/design.md), or asks to add/update a module's documentation. +--- + +# Spec-Sync Workflow + +This project uses [spec-sync](https://github.com/CorvidLabs/spec-sync) for bidirectional spec-to-code validation. Specs live in `specs//.spec.md`. + +## Companion files + +## Verified SDD change lifecycle (5.0) + +For every meaningful source, test, public documentation, schema, or configuration change: + +1. Run `specsync change new "" --json` and conduct the returned interview with the user. +2. Use `specsync change answer "" --json` until no questions remain. +3. Complete the adaptively selected artifacts and semantic deltas. Requirements use stable + `REQ--` IDs, a normative SHALL statement, and acceptance criteria. +4. Ask the user for the definition approval, then run `specsync change approve `. +5. Run `specsync change start ` before editing implementation code. +6. Keep tasks and artifacts current, then run `specsync change verify `. +7. Present verification evidence and ask for closing approval. Only after explicit approval, + run `specsync change accept `; archive separately with `specsync change archive `. + +Never invent or self-grant either human approval. If an approved definition changes, its digest +becomes stale and must be approved again. `specsync check` validates canonical specs plus approved +active deltas, requirement-to-test evidence, change coverage, and CI gates. + +Each canonical spec may have policy-selected companion files. Read and update the ones present; do not create empty companions only for ceremony: + +- **`tasks.md`** — Work items for this module. Check off tasks (`- [x]`) as you complete them. Add new tasks if you discover work needed. +- **`requirements.md`** — Acceptance criteria and user stories. These are permanent invariants, not tasks — do not check them off. Update if requirements change. +- **`context.md`** — Architectural decisions, key files, and current status. Update when you make design decisions or change what's in progress. +- **`testing.md`** — Test strategy: automated test locations, manual QA checklists, and edge cases/boundary conditions. +- **`design.md`** *(opt-in)* — Layout, component hierarchy, design tokens, and asset references. Present when `companions.design` is enabled in config. + +## Before modifying any module + +1. Read the relevant spec in `specs//.spec.md` +2. Read whichever companion files are present (`requirements.md`, `tasks.md`, `context.md`, `testing.md`, `design.md`, or project-defined files) +3. After changes, run `specsync check` to verify specs still pass + +## After completing work + +1. Mark completed items in `tasks.md` — check off finished tasks, add new ones discovered +2. Update `context.md` — record decisions made, update current status +3. If requirements changed, update `requirements.md` acceptance criteria +4. If test coverage changed, update `testing.md` with new test files or edge cases +5. If UI/layout changed, update `design.md` with revised layout, components, or tokens + +## Before creating a PR + +Run `specsync check --strict` — all specs must pass with zero warnings. + +## When adding new modules + +Run `specsync scaffold ` to create a spec, companion files, a registry +entry, and auto-detected source files — or `specsync new ` for a +minimal spec-only draft. Complete the spec before writing code. The +`/specsync:create-spec` command (or tool-equivalent) runs this for you, and +accepts either a bare module name or a natural-language feature description +(e.g. `/specsync:create-spec "I want a feature that lets users export their +data as CSV"`) — pass a description and it will pick a module name and use +the description to draft the spec's Purpose and Requirements. + +## Key commands + +- `specsync check` — validate all specs against source code +- `specsync check --json` — machine-readable validation output +- `specsync coverage` — show which modules lack specs +- `specsync score` — quality score for each spec (0-100) +- `specsync scaffold ` — full scaffold: spec + companions + registry entry + source detection +- `specsync new ` — quick-create a minimal spec (add `--full` for companions) +- `specsync resolve --remote` — verify cross-project dependencies diff --git a/.codex/skills/spec-sync/SKILL.md b/.codex/skills/spec-sync/SKILL.md new file mode 100644 index 0000000..e597cd0 --- /dev/null +++ b/.codex/skills/spec-sync/SKILL.md @@ -0,0 +1,75 @@ +--- +name: spec-sync +description: Keep markdown module specs in specs// synchronized with source code using spec-sync. Use this whenever creating, editing, or reviewing code in a module that has (or should have) a spec, or whenever the user mentions specs, spec-sync, companion files (tasks.md/requirements.md/context.md/testing.md/design.md), or asks to add/update a module's documentation. +--- + +# Spec-Sync Workflow + +This project uses [spec-sync](https://github.com/CorvidLabs/spec-sync) for bidirectional spec-to-code validation. Specs live in `specs//.spec.md`. + +## Companion files + +Each canonical spec may have policy-selected companion files. Read and update the ones present; do not create empty companions only for ceremony: + +- **`tasks.md`** — Work items for this module. Check off tasks (`- [x]`) as you complete them. Add new tasks if you discover work needed. +- **`requirements.md`** — Acceptance criteria and user stories. These are permanent invariants, not tasks — do not check them off. Update if requirements change. +- **`context.md`** — Architectural decisions, key files, and current status. Update when you make design decisions or change what's in progress. +- **`testing.md`** — Test strategy: automated test locations, manual QA checklists, and edge cases/boundary conditions. +- **`design.md`** *(opt-in)* — Layout, component hierarchy, design tokens, and asset references. Present when `companions.design` is enabled in config. + +## Verified SDD change lifecycle (5.0) + +For every meaningful source, test, public documentation, schema, or configuration change: + +1. Run `specsync change new "" --json` and conduct the returned interview with the user. +2. Use `specsync change answer "" --json` until no questions remain. +3. Complete the adaptively selected artifacts and semantic deltas. Requirements use stable + `REQ--` IDs, a normative SHALL statement, and acceptance criteria. +4. Ask the user for the definition approval, then run `specsync change approve `. +5. Run `specsync change start ` before editing implementation code. +6. Keep tasks and artifacts current, then run `specsync change verify `. +7. Present verification evidence and ask for closing approval. Only after explicit approval, + run `specsync change accept `; archive separately with `specsync change archive `. + +Never invent or self-grant either human approval. If an approved definition changes, its digest +becomes stale and must be approved again. `specsync check` validates canonical specs plus approved +active deltas, requirement-to-test evidence, change coverage, and CI gates. + +## Before modifying any module + +1. Read the relevant spec in `specs//.spec.md` +2. Read whichever companion files are present (`requirements.md`, `tasks.md`, `context.md`, `testing.md`, `design.md`, or project-defined files) +3. After changes, run `specsync check` to verify specs still pass + +## After completing work + +1. Mark completed items in `tasks.md` — check off finished tasks, add new ones discovered +2. Update `context.md` — record decisions made, update current status +3. If requirements changed, update `requirements.md` acceptance criteria +4. If test coverage changed, update `testing.md` with new test files or edge cases +5. If UI/layout changed, update `design.md` with revised layout, components, or tokens + +## Before creating a PR + +Run `specsync check --strict` — all specs must pass with zero warnings. + +## When adding new modules + +Run `specsync scaffold ` to create a spec, companion files, a registry +entry, and auto-detected source files — or `specsync new ` for a +minimal spec-only draft. Complete the spec before writing code. The +`/specsync:create-spec` command (or tool-equivalent) runs this for you, and +accepts either a bare module name or a natural-language feature description +(e.g. `/specsync:create-spec "I want a feature that lets users export their +data as CSV"`) — pass a description and it will pick a module name and use +the description to draft the spec's Purpose and Requirements. + +## Key commands + +- `specsync check` — validate all specs against source code +- `specsync check --json` — machine-readable validation output +- `specsync coverage` — show which modules lack specs +- `specsync score` — quality score for each spec (0-100) +- `specsync scaffold ` — full scaffold: spec + companions + registry entry + source detection +- `specsync new ` — quick-create a minimal spec (add `--full` for companions) +- `specsync resolve --remote` — verify cross-project dependencies diff --git a/.cursor/commands/specsync-create-change.md b/.cursor/commands/specsync-create-change.md new file mode 100644 index 0000000..4a27292 --- /dev/null +++ b/.cursor/commands/specsync-create-change.md @@ -0,0 +1,9 @@ +Create a verified spec-sync SDD change. + +Arguments: $ARGUMENTS + +1. Run `specsync change new "$ARGUMENTS" --json`. +2. Read the returned `questions` array and interview the user one question at a time. +3. Record each answer with `specsync change answer "" --json`, quoting the answer so multi-word text is passed as one argument. +4. Continue until the question list is empty, then show the selected artifacts and next action. +5. Do not approve, implement, verify, accept, or archive until the corresponding human gate or work stage is reached. diff --git a/.cursor/commands/specsync-create-spec.md b/.cursor/commands/specsync-create-spec.md new file mode 100644 index 0000000..84b88c7 --- /dev/null +++ b/.cursor/commands/specsync-create-spec.md @@ -0,0 +1,34 @@ +Create a new spec-sync module spec. + +Arguments: $ARGUMENTS + +1. Remove `--minimal` wherever it appears and remember that minimal mode was + requested. Preserve the complete remaining text; do not tokenize it yet. +2. Classify the complete remaining text: + - **A bare module name** — a short identifier like `auth-service` or + `billing`, matching `^[A-Za-z0-9][A-Za-z0-9._-]*$`. Use it as-is. + - **A free-text feature description** — a sentence or phrase describing + what to build, e.g. `"I want a feature that lets users export their + data as CSV"`. In this case, invent a short, kebab-case module name that + captures the idea (e.g. `csv-export`). If the right name is ambiguous, + ask the user to confirm or rename it before continuing. Keep the full + description at hand — you'll use it in step 5. +3. If minimal mode was requested, run: + ``` + specsync new + ``` + This creates a minimal spec only (no companion files). +4. Otherwise (default), run: + ``` + specsync scaffold + ``` + This creates the spec, companion files (`tasks.md`, `requirements.md`, + `context.md`, `testing.md`, and `design.md` if `companions.design` is + enabled), a registry entry, and auto-detects related source files. +5. Open the newly created `specs//.spec.md` and fill + in the `Purpose`, `Requirements`, and `Public API` sections. If a free-text + description was given in step 2, use it directly to draft these sections — + ask clarifying questions if it's underspecified, but do not leave the + sections as unfilled placeholder text. Do the same for `requirements.md` + (acceptance criteria) and `tasks.md` (initial task breakdown), if present. +6. Run `specsync check` to confirm the new spec passes validation. diff --git a/.cursor/skills/spec-sync/SKILL.md b/.cursor/skills/spec-sync/SKILL.md new file mode 100644 index 0000000..e597cd0 --- /dev/null +++ b/.cursor/skills/spec-sync/SKILL.md @@ -0,0 +1,75 @@ +--- +name: spec-sync +description: Keep markdown module specs in specs// synchronized with source code using spec-sync. Use this whenever creating, editing, or reviewing code in a module that has (or should have) a spec, or whenever the user mentions specs, spec-sync, companion files (tasks.md/requirements.md/context.md/testing.md/design.md), or asks to add/update a module's documentation. +--- + +# Spec-Sync Workflow + +This project uses [spec-sync](https://github.com/CorvidLabs/spec-sync) for bidirectional spec-to-code validation. Specs live in `specs//.spec.md`. + +## Companion files + +Each canonical spec may have policy-selected companion files. Read and update the ones present; do not create empty companions only for ceremony: + +- **`tasks.md`** — Work items for this module. Check off tasks (`- [x]`) as you complete them. Add new tasks if you discover work needed. +- **`requirements.md`** — Acceptance criteria and user stories. These are permanent invariants, not tasks — do not check them off. Update if requirements change. +- **`context.md`** — Architectural decisions, key files, and current status. Update when you make design decisions or change what's in progress. +- **`testing.md`** — Test strategy: automated test locations, manual QA checklists, and edge cases/boundary conditions. +- **`design.md`** *(opt-in)* — Layout, component hierarchy, design tokens, and asset references. Present when `companions.design` is enabled in config. + +## Verified SDD change lifecycle (5.0) + +For every meaningful source, test, public documentation, schema, or configuration change: + +1. Run `specsync change new "" --json` and conduct the returned interview with the user. +2. Use `specsync change answer "" --json` until no questions remain. +3. Complete the adaptively selected artifacts and semantic deltas. Requirements use stable + `REQ--` IDs, a normative SHALL statement, and acceptance criteria. +4. Ask the user for the definition approval, then run `specsync change approve `. +5. Run `specsync change start ` before editing implementation code. +6. Keep tasks and artifacts current, then run `specsync change verify `. +7. Present verification evidence and ask for closing approval. Only after explicit approval, + run `specsync change accept `; archive separately with `specsync change archive `. + +Never invent or self-grant either human approval. If an approved definition changes, its digest +becomes stale and must be approved again. `specsync check` validates canonical specs plus approved +active deltas, requirement-to-test evidence, change coverage, and CI gates. + +## Before modifying any module + +1. Read the relevant spec in `specs//.spec.md` +2. Read whichever companion files are present (`requirements.md`, `tasks.md`, `context.md`, `testing.md`, `design.md`, or project-defined files) +3. After changes, run `specsync check` to verify specs still pass + +## After completing work + +1. Mark completed items in `tasks.md` — check off finished tasks, add new ones discovered +2. Update `context.md` — record decisions made, update current status +3. If requirements changed, update `requirements.md` acceptance criteria +4. If test coverage changed, update `testing.md` with new test files or edge cases +5. If UI/layout changed, update `design.md` with revised layout, components, or tokens + +## Before creating a PR + +Run `specsync check --strict` — all specs must pass with zero warnings. + +## When adding new modules + +Run `specsync scaffold ` to create a spec, companion files, a registry +entry, and auto-detected source files — or `specsync new ` for a +minimal spec-only draft. Complete the spec before writing code. The +`/specsync:create-spec` command (or tool-equivalent) runs this for you, and +accepts either a bare module name or a natural-language feature description +(e.g. `/specsync:create-spec "I want a feature that lets users export their +data as CSV"`) — pass a description and it will pick a module name and use +the description to draft the spec's Purpose and Requirements. + +## Key commands + +- `specsync check` — validate all specs against source code +- `specsync check --json` — machine-readable validation output +- `specsync coverage` — show which modules lack specs +- `specsync score` — quality score for each spec (0-100) +- `specsync scaffold ` — full scaffold: spec + companions + registry entry + source detection +- `specsync new ` — quick-create a minimal spec (add `--full` for companions) +- `specsync resolve --remote` — verify cross-project dependencies diff --git a/.gemini/commands/specsync/create-change.toml b/.gemini/commands/specsync/create-change.toml new file mode 100644 index 0000000..a82d113 --- /dev/null +++ b/.gemini/commands/specsync/create-change.toml @@ -0,0 +1,11 @@ +description = "Create and guide a verified spec-sync SDD change through its deterministic interview" + +prompt = """ +Arguments: {{args}} + +1. Run `specsync change new "{{args}}" --json`. +2. Read the returned `questions` array and interview the user one question at a time. +3. Record each answer with `specsync change answer "" --json`, quoting the answer so multi-word text is passed as one argument. +4. Continue until the question list is empty, then show the selected artifacts and next action. +5. Do not approve, implement, verify, accept, or archive until the corresponding human gate or work stage is reached. +""" diff --git a/.gemini/commands/specsync/create-spec.toml b/.gemini/commands/specsync/create-spec.toml new file mode 100644 index 0000000..6d34792 --- /dev/null +++ b/.gemini/commands/specsync/create-spec.toml @@ -0,0 +1,34 @@ +description = "Scaffold a new spec-sync module spec from a module name or a natural-language feature description (full scaffold by default, or minimal with --minimal)" + +prompt = """ +Create a new spec-sync module spec. + +Arguments: {{args}} + +1. Remove --minimal wherever it appears and remember that minimal mode was + requested. Preserve the complete remaining text; do not tokenize it yet. +2. Classify the complete remaining text: + - A bare module name - a short identifier like auth-service or billing, + matching ^[A-Za-z0-9][A-Za-z0-9._-]*$. Use it as-is. + - A free-text feature description - a sentence or phrase describing what + to build, e.g. "I want a feature that lets users export their data as + CSV". In this case, invent a short, kebab-case module name that captures + the idea (e.g. csv-export). If the right name is ambiguous, ask the user + to confirm or rename it before continuing. Keep the full description at + hand - you'll use it in step 5. +3. If minimal mode was requested, run: + specsync new + This creates a minimal spec only (no companion files). +4. Otherwise (default), run: + specsync scaffold + This creates the spec, companion files (tasks.md, requirements.md, + context.md, testing.md, and design.md if companions.design is enabled), + a registry entry, and auto-detects related source files. +5. Open the newly created specs//.spec.md and fill + in the Purpose, Requirements, and Public API sections. If a free-text + description was given in step 2, use it directly to draft these sections - + ask clarifying questions if it's underspecified, but do not leave the + sections as unfilled placeholder text. Do the same for requirements.md + (acceptance criteria) and tasks.md (initial task breakdown), if present. +6. Run specsync check to confirm the new spec passes validation. +""" diff --git a/.gemini/skills/spec-sync/SKILL.md b/.gemini/skills/spec-sync/SKILL.md new file mode 100644 index 0000000..4832c7b --- /dev/null +++ b/.gemini/skills/spec-sync/SKILL.md @@ -0,0 +1,75 @@ +--- +name: spec-sync +description: Keep markdown module specs in specs// synchronized with source code using spec-sync. Use this whenever creating, editing, or reviewing code in a module that has (or should have) a spec, or whenever the user mentions specs, spec-sync, companion files (tasks.md/requirements.md/context.md/testing.md/design.md), or asks to add/update a module's documentation. +--- + +# Spec-Sync Workflow + +This project uses [spec-sync](https://github.com/CorvidLabs/spec-sync) for bidirectional spec-to-code validation. Specs live in `specs//.spec.md`. + +## Companion files + +## Verified SDD change lifecycle (5.0) + +For every meaningful source, test, public documentation, schema, or configuration change: + +1. Run `specsync change new "" --json` and conduct the returned interview with the user. +2. Use `specsync change answer "" --json` until no questions remain. +3. Complete the adaptively selected artifacts and semantic deltas. Requirements use stable + `REQ--` IDs, a normative SHALL statement, and acceptance criteria. +4. Ask the user for the definition approval, then run `specsync change approve `. +5. Run `specsync change start ` before editing implementation code. +6. Keep tasks and artifacts current, then run `specsync change verify `. +7. Present verification evidence and ask for closing approval. Only after explicit approval, + run `specsync change accept `; archive separately with `specsync change archive `. + +Never invent or self-grant either human approval. If an approved definition changes, its digest +becomes stale and must be approved again. `specsync check` validates canonical specs plus approved +active deltas, requirement-to-test evidence, change coverage, and CI gates. + +Each canonical spec may have policy-selected companion files. Read and update the ones present; do not create empty companions only for ceremony: + +- **`tasks.md`** — Work items for this module. Check off tasks (`- [x]`) as you complete them. Add new tasks if you discover work needed. +- **`requirements.md`** — Acceptance criteria and user stories. These are permanent invariants, not tasks — do not check them off. Update if requirements change. +- **`context.md`** — Architectural decisions, key files, and current status. Update when you make design decisions or change what's in progress. +- **`testing.md`** — Test strategy: automated test locations, manual QA checklists, and edge cases/boundary conditions. +- **`design.md`** *(opt-in)* — Layout, component hierarchy, design tokens, and asset references. Present when `companions.design` is enabled in config. + +## Before modifying any module + +1. Read the relevant spec in `specs//.spec.md` +2. Read whichever companion files are present (`requirements.md`, `tasks.md`, `context.md`, `testing.md`, `design.md`, or project-defined files) +3. After changes, run `specsync check` to verify specs still pass + +## After completing work + +1. Mark completed items in `tasks.md` — check off finished tasks, add new ones discovered +2. Update `context.md` — record decisions made, update current status +3. If requirements changed, update `requirements.md` acceptance criteria +4. If test coverage changed, update `testing.md` with new test files or edge cases +5. If UI/layout changed, update `design.md` with revised layout, components, or tokens + +## Before creating a PR + +Run `specsync check --strict` — all specs must pass with zero warnings. + +## When adding new modules + +Run `specsync scaffold ` to create a spec, companion files, a registry +entry, and auto-detected source files — or `specsync new ` for a +minimal spec-only draft. Complete the spec before writing code. The +`/specsync:create-spec` command (or tool-equivalent) runs this for you, and +accepts either a bare module name or a natural-language feature description +(e.g. `/specsync:create-spec "I want a feature that lets users export their +data as CSV"`) — pass a description and it will pick a module name and use +the description to draft the spec's Purpose and Requirements. + +## Key commands + +- `specsync check` — validate all specs against source code +- `specsync check --json` — machine-readable validation output +- `specsync coverage` — show which modules lack specs +- `specsync score` — quality score for each spec (0-100) +- `specsync scaffold ` — full scaffold: spec + companions + registry entry + source detection +- `specsync new ` — quick-create a minimal spec (add `--full` for companions) +- `specsync resolve --remote` — verify cross-project dependencies diff --git a/.github/workflows/trust.yml b/.github/workflows/trust.yml index 3250c25..d096218 100644 --- a/.github/workflows/trust.yml +++ b/.github/workflows/trust.yml @@ -1,24 +1,15 @@ name: trust on: - # Skip the gate for documentation-only changes (it has nothing code to verify). - # Anything that touches code, web/, specs/, SPEC.md, or conformance still runs. + # Public documentation is governed by SpecSync, so those changes run Trust. pull_request: paths-ignore: - - "README.md" - - "ROADMAP.md" - - "CONTRIBUTING.md" - - "docs/**" - "LICENSE" - "**/*.png" - ".github/ISSUE_TEMPLATE/**" push: branches: [main] paths-ignore: - - "README.md" - - "ROADMAP.md" - - "CONTRIBUTING.md" - - "docs/**" - "LICENSE" - "**/*.png" - ".github/ISSUE_TEMPLATE/**" @@ -32,15 +23,6 @@ jobs: with: fetch-depth: 0 # augur/attest need full history - - name: Install fledge (prebuilt release binary) - run: | - mkdir -p "$HOME/.local/bin" - curl -fsSL -o "$HOME/.local/bin/fledge" \ - https://github.com/CorvidLabs/fledge/releases/latest/download/fledge-macos-aarch64 - chmod +x "$HOME/.local/bin/fledge" - echo "$HOME/.local/bin" >> "$GITHUB_PATH" - "$HOME/.local/bin/fledge" --version - - name: Install swift-format run: brew install swift-format @@ -49,31 +31,43 @@ jobs: with: bun-version: latest - # Lifecycle: the single gate runs format/build/test for all three parser - # implementations (Swift, TypeScript, Rust) plus spec-sync. - - name: Verify lane - run: fledge lanes run verify - - # Contracts: specs must stay in sync with source. - - name: Spec sync - uses: CorvidLabs/spec-sync@v4.5.0 - with: - strict: "true" + # The lifecycle preserves this repository's pre-migration strict + # SpecSync check; Trust's composed contract step still owns the gate. + - name: Install pinned lifecycle tools + shell: bash + run: | + set -euo pipefail + archive="$RUNNER_TEMP/specsync-macos-aarch64.tar.gz" + checksum="$archive.sha256" + base="https://github.com/CorvidLabs/spec-sync/releases/download/v5.0.1" + curl -fsSL "$base/specsync-macos-aarch64.tar.gz" -o "$archive" + curl -fsSL "$base/specsync-macos-aarch64.tar.gz.sha256" -o "$checksum" + expected="$(awk '{print $1}' "$checksum")" + actual="$(shasum -a 256 "$archive" | awk '{print $1}')" + test "$actual" = "$expected" + mkdir -p "$RUNNER_TEMP/specsync-bin" + tar -xzf "$archive" -C "$RUNNER_TEMP/specsync-bin" + mv "$RUNNER_TEMP/specsync-bin/specsync-macos-aarch64" "$RUNNER_TEMP/specsync-bin/specsync" + chmod +x "$RUNNER_TEMP/specsync-bin/specsync" + fledge="$RUNNER_TEMP/specsync-bin/fledge" + curl -fsSL \ + "https://github.com/CorvidLabs/fledge/releases/download/v1.7.0/fledge-macos-aarch64" \ + -o "$fledge" + expected_fledge="21d0916d52ef14e6d33e3967417773369e047a0311e66bbb1eecc8f69332a040" + actual_fledge="$(shasum -a 256 "$fledge" | awk '{print $1}')" + test "$actual_fledge" = "$expected_fledge" + chmod +x "$fledge" + echo "$RUNNER_TEMP/specsync-bin" >> "$GITHUB_PATH" - # Risk: enforced, deterministic, low false-positive. - - name: Augur risk gate - uses: CorvidLabs/augur@v0.4.0 - with: - range: origin/main..HEAD - threshold: block + # Preserve the former warning-as-error contract without placing SpecSync + # inside its own configured verification command. + - name: Strict SpecSync contract + run: specsync check --strict --force --require-coverage 100 - # Trust: soft until a signing key and richer policy land. - - name: Attest verify - uses: CorvidLabs/attest@v0.4.0 - with: - range: origin/main..HEAD - policy: .attest.json - continue-on-error: true + # Unified lifecycle, contract, risk, and progressive provenance gate. + - name: CorvidLabs Trust gate + id: trust + uses: CorvidLabs/trust@9d32b5786d2e9e4d39fc581c0091c721ee3d4226 # v1.0.0 # Durability: fail if the standing rules block was removed. - name: Trust block present diff --git a/.specsync/adoption-report.json b/.specsync/adoption-report.json new file mode 100644 index 0000000..15e9c08 --- /dev/null +++ b/.specsync/adoption-report.json @@ -0,0 +1,25 @@ +{ + "bootstrap_policy": { + "base_commit": "2a145766b9ecb83d96ee15aa453a65cc2125571f", + "digest": "17da9387d2f3e8e96682c32e539ea1f1797adbdbd784e02c47b0c608ada2b8a1", + "path": ".specsync/sdd.json" + }, + "generated_at": 1783826710, + "requirements_needing_ids": [ + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/ThreeMD/requirements.md", + "suggested_first_id": "REQ-threemd-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/ThreeMDCLI/requirements.md", + "suggested_first_id": "REQ-threemdcli-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/ThreeMDElement/requirements.md", + "suggested_first_id": "REQ-threemdelement-001" + } + ] +} diff --git a/.specsync/change.lock b/.specsync/change.lock new file mode 100644 index 0000000..e69de29 diff --git a/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/approvals.json b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/approvals.json new file mode 100644 index 0000000..e66df8a --- /dev/null +++ b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/approvals.json @@ -0,0 +1,89 @@ +{ + "approvals": [ + { + "gate": "definition", + "actor": "user:0xLeif", + "timestamp": 1783826959, + "digest": "79cfe2c4cd9797c14198de4d7f463d8f8b82125287963141c78c6d3b24157aec", + "note": "Authorized by the user-approved CorvidLabs Trust 1 / SpecSync 5 rollout plan." + }, + { + "gate": "definition", + "actor": "user:0xLeif", + "timestamp": 1783971616, + "digest": "706e408d448f153b152bddf0b13b85dd7c861f0d58642d32a9a06f30301c9e23", + "note": "Definition re-approved after reviewing the migration policy, all agent templates, generated documentation, and repository-specific requirement corrections; native and hosted closing evidence remain pending." + }, + { + "gate": "definition", + "actor": "user:0xLeif", + "timestamp": 1783971650, + "digest": "77c9495b355f19a856d03e1a76f247c512f00beb33e011d66e068d839239351f", + "note": "Definition re-approved after the complete local verification lane and strict 100% contract passed; hosted pull-request checks and closing acceptance remain pending." + }, + { + "gate": "definition", + "actor": "user:0xLeif", + "timestamp": 1783973991, + "digest": "174ccd0189f9b600f8f14088871b133f15bcab0570c991e16373ce5fca69f72b", + "note": "Definition refreshed after final review: public documentation names Trust as the complete gate and README, CONTRIBUTING, and docs are governed meaningful paths." + }, + { + "gate": "definition", + "actor": "user:0xLeif", + "timestamp": 1783974811, + "digest": "3e3993f3a310d989da0f46bf1d7643e8d7c3cfe201df57371fcb31e1c4b52116", + "note": "Definition refreshed after the complete corrected PR head passed Trust, browser UI, and all CodeQL checks." + }, + { + "gate": "acceptance", + "actor": "user:0xLeif", + "timestamp": 1783974846, + "digest": "2514197b66c28890a33152e1f34edae858598990a6c2fcd0171df22d1715711c", + "note": "Accepted after native Swift, TypeScript, Rust, generated-bundle, and editor verification plus successful hosted Trust, browser UI, and CodeQL checks on the corrected PR head." + }, + { + "gate": "acceptance", + "actor": "user:0xLeif", + "timestamp": 1784013064, + "digest": "fb0b6266d5085ac27eda5e6341cb6e6c69dedba28d6bbcf227334ccf87408200", + "note": "Fresh closing approval after final governance corrections and full seven-step native verification; hosted checks are not claimed yet." + } + ], + "reopenings": [ + { + "schema_version": 1, + "change_id": "CHG-0001-adopt-trust-1-and-specsync-5", + "actor": "user:0xLeif", + "reason": "Authorized final governance review corrections changed delivery inputs after acceptance; refresh unchanged migration evidence with the full native lane.", + "timestamp": 1784012981, + "from_state": "accepted", + "to_state": "verifying", + "superseded_approval": { + "gate": "acceptance", + "actor": "user:0xLeif", + "timestamp": 1783974846, + "digest": "2514197b66c28890a33152e1f34edae858598990a6c2fcd0171df22d1715711c", + "note": "Accepted after native Swift, TypeScript, Rust, generated-bundle, and editor verification plus successful hosted Trust, browser UI, and CodeQL checks on the corrected PR head." + }, + "prior_verification": { + "timestamp": 1783974833, + "commit": "6148c1f853c5f50269a84d005a4d474ce384b9f2", + "contract_digest": "3e3993f3a310d989da0f46bf1d7643e8d7c3cfe201df57371fcb31e1c4b52116", + "workspace_digest": "0b62c7bf6e4900e50e9406a10f9d176018528ed72e5fc53aaba17d7f9594fdb6", + "acceptance_input_digest": "cfc943b5b376e22b72c0c900d66b9f2b57c945e8e70a215a880fbf4cf0dbca34", + "passed": true, + "commands": [ + { + "command": "fledge lanes run verify", + "success": true, + "exit_code": 0 + } + ], + "requirement_ids": [] + }, + "stale_acceptance_input_digest": "cfc943b5b376e22b72c0c900d66b9f2b57c945e8e70a215a880fbf4cf0dbca34", + "current_acceptance_input_digest": "a6793c577723410186164e0e0d9a4e91892380830069ed60dfb3278c211e8740" + } + ] +} diff --git a/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/change.md b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/change.md new file mode 100644 index 0000000..f4cfb2d --- /dev/null +++ b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/change.md @@ -0,0 +1,26 @@ +--- +id: CHG-0001-adopt-trust-1-and-specsync-5 +state: accepted +type: migration +base_commit: 2a145766b9ecb83d96ee15aa453a65cc2125571f +--- + +# Adopt Trust 1 and SpecSync 5 + +## Intent + +Adopt Trust 1 and SpecSync 5 + +## Affected Canonical Specs + +- None + +## Acceptance Criteria + +- Trust 1.0.0 runs the existing verify lane +- SpecSync 5.0.1 strict validation passes +- Claude Cursor Codex and Gemini integrations report installed + +## No-spec Rationale + +Tooling policy migration; no product API or canonical module contract changes. diff --git a/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/context.md b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/context.md new file mode 100644 index 0000000..100bff1 --- /dev/null +++ b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/context.md @@ -0,0 +1,14 @@ +--- +change: CHG-0001-adopt-trust-1-and-specsync-5 +artifact: context +--- + +# Context + +The repository already has a real Fledge verify lane and separate SpecSync, +Augur, and Attest checks. This migration keeps the existing runner and language +setup while making Trust 1.0.0 the single orchestration surface. + +SpecSync 5.0.1 enables its verified SDD policy, records this migration as a +no-product-contract change, and installs native workflows for Claude, Cursor, +Codex, and Gemini. diff --git a/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/design.md b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/design.md new file mode 100644 index 0000000..9c4bb1f --- /dev/null +++ b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/design.md @@ -0,0 +1,14 @@ +--- +change: CHG-0001-adopt-trust-1-and-specsync-5 +artifact: design +--- + +# Design + +The workflow retains checkout, full git history, runner selection, and +project-specific dependency setup. One Trust action then runs the existing +Fledge verify lane, SpecSync contract validation, Augur's block threshold, and +soft provenance verification. + +The committed policy is authoritative. Workflow inputs do not weaken it. +AGENTS.md remains protected by the existing marker check. diff --git a/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/docs.md b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/docs.md new file mode 100644 index 0000000..cdb3306 --- /dev/null +++ b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/docs.md @@ -0,0 +1,11 @@ +--- +change: CHG-0001-adopt-trust-1-and-specsync-5 +artifact: docs +--- + +# Docs + +AGENTS.md carries the Trust 1 managed rules. The generated Claude, Cursor, +Codex, and Gemini skills document the SpecSync 5 change lifecycle in each +tool's native discovery location. No product documentation or public API +contract changes as part of this migration. diff --git a/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/plan.md b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/plan.md new file mode 100644 index 0000000..2ad6abc --- /dev/null +++ b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/plan.md @@ -0,0 +1,12 @@ +--- +change: CHG-0001-adopt-trust-1-and-specsync-5 +artifact: plan +--- + +# Plan + +1. Adopt the SpecSync 5 policy and use the existing verify lane as evidence. +2. Install all four repository-native coding-agent integrations. +3. Adopt the standard Trust policy with Atlas disabled and progressive provenance. +4. Replace duplicated gate steps with the immutable Trust 1.0.0 action. +5. Run agent-status, doctor, strict contract, and repository verification checks. diff --git a/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/research.md b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/research.md new file mode 100644 index 0000000..6adbd2a --- /dev/null +++ b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/research.md @@ -0,0 +1,14 @@ +--- +change: CHG-0001-adopt-trust-1-and-specsync-5 +artifact: research +--- + +# Research + +The previous workflow duplicated lifecycle, contract, risk, and provenance +ordering in each repository. Trust 1.0.0 provides the same ordered gates from a +committed `.trust.toml` policy and pins SpecSync 5.0.1 internally. + +The consumer workflow pins Trust's immutable 1.0.0 commit. Existing dependency +setup remains before the Trust step, and provenance remains progressive until +the repository has a durable remote notes ledger. diff --git a/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/state.json b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/state.json new file mode 100644 index 0000000..9512fa6 --- /dev/null +++ b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/state.json @@ -0,0 +1,53 @@ +{ + "schema_version": 1, + "id": "CHG-0001-adopt-trust-1-and-specsync-5", + "slug": "adopt-trust-1-and-specsync-5", + "title": "Adopt Trust 1 and SpecSync 5", + "description": "Adopt Trust 1 and SpecSync 5", + "kind": "migration", + "state": "accepted", + "canonical_applied": true, + "base_commit": "2a145766b9ecb83d96ee15aa453a65cc2125571f", + "created_at": 1783826867, + "updated_at": 1784013064, + "affected_specs": [], + "affected_paths": [ + ".github/workflows/trust.yml", + ".specsync/", + ".claude/", + ".codex/", + ".cursor/", + ".gemini/", + ".trust.toml", + ".augur.toml", + "AGENTS.md", + "CLAUDE.md", + "README.md", + "CONTRIBUTING.md", + "docs/", + "docs.3md", + "web/docs.3md", + "fledge.toml" + ], + "no_spec_change": true, + "no_spec_change_rationale": "Tooling policy migration; no product API or canonical module contract changes.", + "acceptance_criteria": [ + "Trust 1.0.0 runs the existing verify lane", + "SpecSync 5.0.1 strict validation passes", + "Claude Cursor Codex and Gemini integrations report installed" + ], + "selected_artifacts": [ + "context", + "research", + "design", + "plan", + "tasks", + "testing", + "docs" + ], + "dependencies": [], + "answers": { + "architecture_risk": "yes", + "public_contract": "no" + } +} diff --git a/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/tasks.md b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/tasks.md new file mode 100644 index 0000000..9ae70aa --- /dev/null +++ b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/tasks.md @@ -0,0 +1,13 @@ +--- +change: CHG-0001-adopt-trust-1-and-specsync-5 +artifact: tasks +--- + +# Tasks + +- [x] Adopt SpecSync 5 SDD policy. +- [x] Install Claude, Cursor, Codex, and Gemini integrations. +- [x] Commit the standard Trust policy and Augur configuration. +- [x] Consolidate the CI workflow on Trust 1.0.0. +- [x] Pass local strict validation and the repository verify lane. +- [x] Pass hosted pull-request checks. diff --git a/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/testing.md b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/testing.md new file mode 100644 index 0000000..9d7c4a3 --- /dev/null +++ b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/testing.md @@ -0,0 +1,12 @@ +--- +change: CHG-0001-adopt-trust-1-and-specsync-5 +artifact: testing +--- + +# Testing + +- `specsync agents status` reports all four integrations installed. +- `fledge trust doctor` reports a healthy repository. +- `specsync check --strict --force` passes with the active change. +- `fledge trust verify` runs the existing verification lane and component gates. +- The pull-request `trust` job passes on the repository's established runner. diff --git a/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/verification-attempts.json b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/verification-attempts.json new file mode 100644 index 0000000..ca89cfb --- /dev/null +++ b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/verification-attempts.json @@ -0,0 +1,20 @@ +{ + "schema_version": 1, + "attempts": [ + { + "timestamp": 1784013006, + "commit": "01263f573ae8d89b58f04c2be84b041164c8d789", + "contract_digest": "3e3993f3a310d989da0f46bf1d7643e8d7c3cfe201df57371fcb31e1c4b52116", + "workspace_digest": "96b757577179b0b7c087eebd3f8e96ac148ea0abce4320e96d43696c31a9255f", + "passed": true, + "commands": [ + { + "command": "fledge lanes run verify", + "success": true, + "exit_code": 0 + } + ], + "requirement_ids": [] + } + ] +} diff --git a/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/verification.json b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/verification.json new file mode 100644 index 0000000..abe01aa --- /dev/null +++ b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/verification.json @@ -0,0 +1,16 @@ +{ + "timestamp": 1784013006, + "commit": "01263f573ae8d89b58f04c2be84b041164c8d789", + "contract_digest": "3e3993f3a310d989da0f46bf1d7643e8d7c3cfe201df57371fcb31e1c4b52116", + "workspace_digest": "96b757577179b0b7c087eebd3f8e96ac148ea0abce4320e96d43696c31a9255f", + "acceptance_input_digest": "a6793c577723410186164e0e0d9a4e91892380830069ed60dfb3278c211e8740", + "passed": true, + "commands": [ + { + "command": "fledge lanes run verify", + "success": true, + "exit_code": 0 + } + ], + "requirement_ids": [] +} diff --git a/.specsync/changes/CHG-0002-assign-stable-requirement-ids/approvals.json b/.specsync/changes/CHG-0002-assign-stable-requirement-ids/approvals.json new file mode 100644 index 0000000..a71e942 --- /dev/null +++ b/.specsync/changes/CHG-0002-assign-stable-requirement-ids/approvals.json @@ -0,0 +1,18 @@ +{ + "approvals": [ + { + "gate": "definition", + "actor": "user:0xLeif", + "timestamp": 1783827254, + "digest": "dcb9541b9bbaef2158d04f0776225b9150255a95bc679f8dbaa7a26311efc798", + "note": "Authorized by the user-approved CorvidLabs Trust 1 / SpecSync 5 rollout plan." + }, + { + "gate": "acceptance", + "actor": "user:0xLeif", + "timestamp": 1783971636, + "digest": "abc820de8a00833febd046960277b09ea308674755c6aaf828889982b7e3d39c", + "note": "Accepted after line-by-line review replaced every tautological generated statement with the exact existing repository behavior and the complete Swift, JavaScript, Rust, bundle, editor, and strict 100% SpecSync lane passed." + } + ] +} diff --git a/.specsync/changes/CHG-0002-assign-stable-requirement-ids/change.md b/.specsync/changes/CHG-0002-assign-stable-requirement-ids/change.md new file mode 100644 index 0000000..f609240 --- /dev/null +++ b/.specsync/changes/CHG-0002-assign-stable-requirement-ids/change.md @@ -0,0 +1,24 @@ +--- +id: CHG-0002-assign-stable-requirement-ids +state: accepted +type: documentation +base_commit: 2a145766b9ecb83d96ee15aa453a65cc2125571f +--- + +# Assign stable requirement IDs + +## Intent + +Assign stable requirement IDs + +## Affected Canonical Specs + +- None + +## Acceptance Criteria + +- Every durable requirement has a unique REQ ID; existing requirement semantics remain unchanged; SpecSync strict validation passes + +## No-spec Rationale + +Add stable identifiers to existing requirement statements without changing their semantics. diff --git a/.specsync/changes/CHG-0002-assign-stable-requirement-ids/context.md b/.specsync/changes/CHG-0002-assign-stable-requirement-ids/context.md new file mode 100644 index 0000000..bd89fb1 --- /dev/null +++ b/.specsync/changes/CHG-0002-assign-stable-requirement-ids/context.md @@ -0,0 +1,10 @@ +--- +change: CHG-0002-assign-stable-requirement-ids +artifact: context +--- + +# Context + +SpecSync 5 uses durable requirement identifiers to connect canonical requirements, implementation, +and verification evidence. Existing requirement companions predate that convention, so this change +adds stable `REQ-*` identifiers while preserving their original acceptance language and meaning. diff --git a/.specsync/changes/CHG-0002-assign-stable-requirement-ids/docs.md b/.specsync/changes/CHG-0002-assign-stable-requirement-ids/docs.md new file mode 100644 index 0000000..55c3810 --- /dev/null +++ b/.specsync/changes/CHG-0002-assign-stable-requirement-ids/docs.md @@ -0,0 +1,10 @@ +--- +change: CHG-0002-assign-stable-requirement-ids +artifact: docs +--- + +# Docs + +The canonical requirement companions now include a Durable Requirements section. Each existing +acceptance criterion is represented by a unique, module-scoped `REQ-*` identifier. No public API, +behavior, or verification command changes as part of this documentation migration. diff --git a/.specsync/changes/CHG-0002-assign-stable-requirement-ids/state.json b/.specsync/changes/CHG-0002-assign-stable-requirement-ids/state.json new file mode 100644 index 0000000..2e76461 --- /dev/null +++ b/.specsync/changes/CHG-0002-assign-stable-requirement-ids/state.json @@ -0,0 +1,30 @@ +{ + "schema_version": 1, + "id": "CHG-0002-assign-stable-requirement-ids", + "slug": "assign-stable-requirement-ids", + "title": "Assign stable requirement IDs", + "description": "Assign stable requirement IDs", + "kind": "documentation", + "state": "accepted", + "base_commit": "2a145766b9ecb83d96ee15aa453a65cc2125571f", + "created_at": 1783827126, + "updated_at": 1783971636, + "affected_specs": [], + "affected_paths": [ + "specs/" + ], + "no_spec_change": true, + "no_spec_change_rationale": "Add stable identifiers to existing requirement statements without changing their semantics.", + "acceptance_criteria": [ + "Every durable requirement has a unique REQ ID; existing requirement semantics remain unchanged; SpecSync strict validation passes" + ], + "selected_artifacts": [ + "context", + "docs" + ], + "dependencies": [], + "answers": { + "architecture_risk": "no", + "public_contract": "no" + } +} diff --git a/.specsync/changes/CHG-0002-assign-stable-requirement-ids/verification.json b/.specsync/changes/CHG-0002-assign-stable-requirement-ids/verification.json new file mode 100644 index 0000000..24c37b6 --- /dev/null +++ b/.specsync/changes/CHG-0002-assign-stable-requirement-ids/verification.json @@ -0,0 +1,16 @@ +{ + "timestamp": 1783971631, + "commit": "1d12ef5f068c231995d9ad1fc9cc31a515ac8f5e", + "contract_digest": "dcb9541b9bbaef2158d04f0776225b9150255a95bc679f8dbaa7a26311efc798", + "workspace_digest": "86c82a232f75d242a0ed41a77139d8aabe5348ff88b71d972684d3bfcc64cc85", + "acceptance_input_digest": "b12b187ff602d25fdf8935659d4919ead49d9317a04c86867358ed2fbed06371", + "passed": true, + "commands": [ + { + "command": "fledge lanes run verify", + "success": true, + "exit_code": 0 + } + ], + "requirement_ids": [] +} diff --git a/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/approvals.json b/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/approvals.json new file mode 100644 index 0000000..a2846b9 --- /dev/null +++ b/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/approvals.json @@ -0,0 +1,26 @@ +{ + "approvals": [ + { + "gate": "definition", + "actor": "user:0xLeif", + "timestamp": 1783976028, + "digest": "2ce2d380b030b04d904a99189d4c5d2be5a18789bdddd7155f374f83daa0961d", + "note": "Definition reviewed after final-head comments; scope is limited to Trust path filters, SDD governance paths, and installed agent guidance." + }, + { + "gate": "definition", + "actor": "user:0xLeif", + "timestamp": 1784012911, + "digest": "5bd9d4eddcff67d4e2ed60328ba2cf59b66e0a8a29627e72b6b08fd006d3f754", + "note": "Reapproved after replacing circular verification tasks with truthful completed configuration and preserving hosted checks as post-push evidence." + }, + { + "gate": "acceptance", + "actor": "user:0xLeif", + "timestamp": 1784012970, + "digest": "a02b2a8ea28461e6a5dbfe880389246f14291a0d72fb403709a616bab38bc6cb", + "note": "Closing approval after strict native verification passed all seven Swift, TypeScript, Rust, generated-bundle, and editor steps; hosted checks are not claimed yet." + } + ], + "reopenings": [] +} diff --git a/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/change.md b/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/change.md new file mode 100644 index 0000000..e0336a1 --- /dev/null +++ b/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/change.md @@ -0,0 +1,24 @@ +--- +id: CHG-0003-address-final-trust-and-sdd-governance-review-corrections +state: accepted +type: migration +base_commit: 2458e7d2e607a8cd98448652821d515ed1f51bf9 +--- + +# Address final Trust and SDD governance review corrections + +## Intent + +Address final Trust and SDD governance review corrections + +## Affected Canonical Specs + +- None + +## Acceptance Criteria + +- Trust runs for every governed public-documentation change; SDD policy and canonical spec edits require a covering change; all installed agent skills preserve multi-word interview answers; strict SpecSync and the complete Trust gate pass at 100%. + +## No-spec Rationale + +Governance policy and generated-agent guidance corrections only; no product or canonical module behavior changes. diff --git a/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/context.md b/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/context.md new file mode 100644 index 0000000..5380abe --- /dev/null +++ b/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/context.md @@ -0,0 +1,10 @@ +--- +change: CHG-0003-address-final-trust-and-sdd-governance-review-corrections +artifact: context +--- + +# Context + +Final-head review found that public documentation could skip Trust, broad ignore +rules could exempt canonical contracts and SDD policy from change coverage, and +installed agent skills could split multi-word interview answers. diff --git a/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/docs.md b/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/docs.md new file mode 100644 index 0000000..29dfab6 --- /dev/null +++ b/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/docs.md @@ -0,0 +1,10 @@ +--- +change: CHG-0003-address-final-trust-and-sdd-governance-review-corrections +artifact: docs +--- + +# Docs + +No public product documentation changes. The workflow comment now explains why +governed documentation must run Trust; installed agent guidance consistently +shows a quoted interview answer. diff --git a/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/plan.md b/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/plan.md new file mode 100644 index 0000000..19eee60 --- /dev/null +++ b/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/plan.md @@ -0,0 +1,11 @@ +--- +change: CHG-0003-address-final-trust-and-sdd-governance-review-corrections +artifact: plan +--- + +# Plan + +1. Align Trust path filters with the meaningful documentation policy. +2. Govern every source used by the public documentation bundle and remove conflicting ignores. +3. Quote interview answers in all installed agent skills. +4. Run strict SpecSync, native verification, Trust, and hosted checks. diff --git a/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/requirements.md b/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/requirements.md new file mode 100644 index 0000000..345266c --- /dev/null +++ b/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/requirements.md @@ -0,0 +1,11 @@ +--- +change: CHG-0003-address-final-trust-and-sdd-governance-review-corrections +artifact: requirements +--- + +# Requirements + +- Trust SHALL run when governed public documentation changes. +- Canonical specs and SDD policy files SHALL require a covering change. +- Every installed agent skill SHALL preserve an interview answer as one CLI argument. +- Existing product behavior and canonical module requirements SHALL remain unchanged. diff --git a/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/state.json b/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/state.json new file mode 100644 index 0000000..3a95e35 --- /dev/null +++ b/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/state.json @@ -0,0 +1,40 @@ +{ + "schema_version": 1, + "id": "CHG-0003-address-final-trust-and-sdd-governance-review-corrections", + "slug": "address-final-trust-and-sdd-governance-review-corrections", + "title": "Address final Trust and SDD governance review corrections", + "description": "Address final Trust and SDD governance review corrections", + "kind": "migration", + "state": "accepted", + "canonical_applied": true, + "base_commit": "2458e7d2e607a8cd98448652821d515ed1f51bf9", + "created_at": 1783975947, + "updated_at": 1784012970, + "affected_specs": [], + "affected_paths": [ + ".github/workflows/trust.yml", + ".specsync/sdd.json", + ".claude/skills/spec-sync/SKILL.md", + ".codex/skills/spec-sync/SKILL.md", + ".cursor/skills/spec-sync/SKILL.md", + ".gemini/skills/spec-sync/SKILL.md" + ], + "no_spec_change": true, + "no_spec_change_rationale": "Governance policy and generated-agent guidance corrections only; no product or canonical module behavior changes.", + "acceptance_criteria": [ + "Trust runs for every governed public-documentation change; SDD policy and canonical spec edits require a covering change; all installed agent skills preserve multi-word interview answers; strict SpecSync and the complete Trust gate pass at 100%." + ], + "selected_artifacts": [ + "context", + "requirements", + "plan", + "tasks", + "testing", + "docs" + ], + "dependencies": [], + "answers": { + "architecture_risk": "no", + "public_contract": "no" + } +} diff --git a/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/tasks.md b/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/tasks.md new file mode 100644 index 0000000..4f87774 --- /dev/null +++ b/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/tasks.md @@ -0,0 +1,12 @@ +--- +change: CHG-0003-address-final-trust-and-sdd-governance-review-corrections +artifact: tasks +--- + +# Tasks + +- [x] Align Trust documentation path filters. +- [x] Correct meaningful and ignored SDD paths. +- [x] Quote interview answers in all four installed agent skills. +- [x] Configure strict SpecSync and the complete local Trust gate as closing evidence. +- [x] Preserve hosted Trust, UI, and CodeQL as required post-push checks without claiming their result early. diff --git a/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/testing.md b/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/testing.md new file mode 100644 index 0000000..a71bc3f --- /dev/null +++ b/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/testing.md @@ -0,0 +1,12 @@ +--- +change: CHG-0003-address-final-trust-and-sdd-governance-review-corrections +artifact: testing +--- + +# Testing + +- Confirm `specsync check --strict --force --require-coverage 100` passes. +- Confirm all four skill copies quote the answer placeholder. +- Confirm Trust no longer ignores governed public-documentation paths. +- Run the repository native verification lane and `fledge trust verify`. +- Require the final hosted Trust, UI, and CodeQL checks to pass. diff --git a/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/verification-attempts.json b/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/verification-attempts.json new file mode 100644 index 0000000..ce267e7 --- /dev/null +++ b/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/verification-attempts.json @@ -0,0 +1,50 @@ +{ + "schema_version": 1, + "attempts": [ + { + "timestamp": 1784012924, + "commit": "765abbf6be3919262f3fb885ed36439afafc5c5b", + "contract_digest": "5bd9d4eddcff67d4e2ed60328ba2cf59b66e0a8a29627e72b6b08fd006d3f754", + "workspace_digest": "96b757577179b0b7c087eebd3f8e96ac148ea0abce4320e96d43696c31a9255f", + "passed": false, + "commands": [ + { + "command": "fledge lanes run verify", + "success": false, + "exit_code": 1 + } + ], + "requirement_ids": [] + }, + { + "timestamp": 1784012934, + "commit": "765abbf6be3919262f3fb885ed36439afafc5c5b", + "contract_digest": "5bd9d4eddcff67d4e2ed60328ba2cf59b66e0a8a29627e72b6b08fd006d3f754", + "workspace_digest": "96b757577179b0b7c087eebd3f8e96ac148ea0abce4320e96d43696c31a9255f", + "passed": false, + "commands": [ + { + "command": "fledge lanes run verify", + "success": false, + "exit_code": 1 + } + ], + "requirement_ids": [] + }, + { + "timestamp": 1784012957, + "commit": "765abbf6be3919262f3fb885ed36439afafc5c5b", + "contract_digest": "5bd9d4eddcff67d4e2ed60328ba2cf59b66e0a8a29627e72b6b08fd006d3f754", + "workspace_digest": "96b757577179b0b7c087eebd3f8e96ac148ea0abce4320e96d43696c31a9255f", + "passed": true, + "commands": [ + { + "command": "fledge lanes run verify", + "success": true, + "exit_code": 0 + } + ], + "requirement_ids": [] + } + ] +} diff --git a/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/verification.json b/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/verification.json new file mode 100644 index 0000000..0827812 --- /dev/null +++ b/.specsync/changes/CHG-0003-address-final-trust-and-sdd-governance-review-corrections/verification.json @@ -0,0 +1,16 @@ +{ + "timestamp": 1784012957, + "commit": "765abbf6be3919262f3fb885ed36439afafc5c5b", + "contract_digest": "5bd9d4eddcff67d4e2ed60328ba2cf59b66e0a8a29627e72b6b08fd006d3f754", + "workspace_digest": "96b757577179b0b7c087eebd3f8e96ac148ea0abce4320e96d43696c31a9255f", + "acceptance_input_digest": "c00a57191dd6a175286195a6217702c871180367d7d53ad5091b975b5619ee2e", + "passed": true, + "commands": [ + { + "command": "fledge lanes run verify", + "success": true, + "exit_code": 0 + } + ], + "requirement_ids": [] +} diff --git a/.specsync/config.toml b/.specsync/config.toml index 2e2c511..cdf5c32 100644 --- a/.specsync/config.toml +++ b/.specsync/config.toml @@ -1,4 +1,4 @@ -# spec-sync v4 configuration +# spec-sync v5 configuration # Docs: https://github.com/CorvidLabs/spec-sync specs_dir = "specs" diff --git a/.specsync/sdd.json b/.specsync/sdd.json new file mode 100644 index 0000000..796067c --- /dev/null +++ b/.specsync/sdd.json @@ -0,0 +1,66 @@ +{ + "version": 1, + "enabled": true, + "require_change_for_meaningful_files": true, + "meaningful_paths": [ + "src/", + "tests/", + "site/", + ".github/", + "Cargo.toml", + "Cargo.lock", + "action.yml", + "package.json", + "bun.lock", + "package-lock.json", + "pnpm-lock.yaml", + "yarn.lock", + "Package.swift", + "Package.resolved", + "go.mod", + "go.sum", + "pyproject.toml", + "uv.lock", + "requirements.txt", + ".specsync/sdd.json", + ".specsync/config.toml", + ".specsync/config.json", + ".specsync/version", + "Sources/", + "Tests/", + "Examples/", + "conformance/", + "editor/", + "element/", + "js/", + "rust/", + "uitests/", + "web/", + "scripts/", + "README.md", + "ROADMAP.md", + "CHANGELOG.md", + "SECURITY.md", + "CONTRIBUTING.md", + "docs/", + "docs.3md", + "specs/", + "SPEC.md", + "fledge.toml", + ".trust.toml", + ".augur.toml", + ".attest.json", + "AGENTS.md", + "CLAUDE.md", + ".claude/", + ".codex/", + ".cursor/", + ".gemini/" + ], + "ignored_paths": [], + "verification_commands": [ + "fledge lanes run verify" + ], + "custom_artifacts": {}, + "principles_file": null +} diff --git a/.specsync/version b/.specsync/version index f77856a..6b244dc 100644 --- a/.specsync/version +++ b/.specsync/version @@ -1 +1 @@ -4.3.1 +5.0.1 diff --git a/.trust.toml b/.trust.toml new file mode 100644 index 0000000..82c7ed8 --- /dev/null +++ b/.trust.toml @@ -0,0 +1,22 @@ +schema_version = 1 +profile = "standard" + +[lifecycle] +command = ["fledge", "lanes", "run", "verify"] + +[contract] +enabled = true +require_coverage = 100 +skip_reason = "" + +[risk] +threshold = "block" + +[provenance] +mode = "soft" +policy = ".attest.json" +skip_reason = "" + +[atlas] +enabled = false +skip_reason = "Atlas publication was not enabled during adoption" diff --git a/AGENTS.md b/AGENTS.md index 024bcdb..8ba6621 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -20,14 +20,14 @@ descriptive generic names, 4-space indentation, 120-column lines. The formatter config in `.swift-format` enforces the mechanical parts. -## CorvidLabs trust toolchain (standing rules) +## CorvidLabs trust toolchain -This repo is governed by four CLIs. Every session MUST use them; never bypass or weaken them. +This repository uses one trust gate. Every session must use it and must not bypass or weaken it. -- fledge: run `fledge lanes run verify` before calling any change done. It must pass. -- spec-sync: when you change a module with a *.spec.md, update the spec, then `fledge spec check`. (skipped: , if content-only) -- augur: `augur check --staged` before a commit; `augur check --range origin/main..HEAD` before merge. A block verdict is a hard stop, never auto-overridden. -- attest: after a green lane, `attest sign --commit HEAD --reviewer agent: --from-augur augur.json --tests-passed`. +- Run `fledge trust verify` before calling a change complete. +- Keep module specs synchronized with implementation changes. +- Treat an Augur block verdict as a hard stop that must be surfaced and de-risked. +- Record and verify provenance with Attest after the repository's verification lane passes. +- Keep generated trust configuration and this managed block in place. -CI enforces the same gate (.github/workflows/trust.yml) and fails if this block is missing. Brand rule: no em-dash characters in anything you write. diff --git a/CLAUDE.md b/CLAUDE.md index c59745e..268b063 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,3 +1,3 @@ # CLAUDE.md -This repo is governed by the CorvidLabs trust toolchain. Read AGENTS.md and follow the standing rules block before making changes (run `fledge lanes run verify`; never bypass augur/attest/spec gates). +This repo is governed by the CorvidLabs trust toolchain. Read AGENTS.md and follow the standing rules block before making changes. Run `fledge trust verify` before calling work complete; never bypass or weaken its lifecycle, contract, risk, or provenance gates. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5100d21..e996cbf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -19,14 +19,16 @@ conformance vector.** ## The gate -One command runs everything (Swift format check, build, tests, and the Rust -crate): +Run the complete repository gate before calling any change done: ```bash -fledge lanes run verify +fledge trust verify ``` -Run it before calling any change done. Per language: +Trust validates the SpecSync contract, risk policy, and provenance posture, and +composes the native `fledge lanes run verify` lane. The native lane runs the +Swift format check, build, tests, TypeScript parity, Rust crate, generated +bundle drift, and editor checks. Per language: ```bash swift test # Swift diff --git a/README.md b/README.md index 40c61d1..d5b5684 100644 --- a/README.md +++ b/README.md @@ -189,17 +189,19 @@ agreed) and for people (plain, readable, diffable text). ## Development -This repo uses the CorvidLabs trust toolchain. The single gate is: +This repo uses the CorvidLabs trust toolchain. Run the complete repository gate +before calling a change done: ```bash -fledge lanes run verify +fledge trust verify ``` -which runs the Swift format check, build, and tests plus the Rust crate. See +Trust validates the SpecSync contract, risk policy, and provenance posture, and +composes the native `fledge lanes run verify` lane. That native lane runs the +Swift format check, build, and tests plus the Rust crate, TypeScript parser +parity, generated web-component bundle drift, and VS Code grammar tests. See [AGENTS.md](AGENTS.md) for the standing rules every contributor and agent follows. -The same gate also checks TypeScript parser parity, generated web-component -bundle drift, VS Code grammar tests, and spec-sync. Browser UI tests are exposed -separately with `fledge lanes run ui`. +Browser UI tests are exposed separately with `fledge lanes run ui`. Each implementation has its own tests (the Swift suite has 122 tests, the TypeScript suite 76), and all three implementations run the shared 43-vector diff --git a/docs.3md b/docs.3md index d97d72b..4c11a35 100644 --- a/docs.3md +++ b/docs.3md @@ -21,6 +21,7 @@ regenerate with `node scripts/build-docs-3md.mjs`. # 3md [![CI](https://github.com/CorvidLabs/3md/actions/workflows/trust.yml/badge.svg)](https://github.com/CorvidLabs/3md/actions/workflows/trust.yml) +[![spec coverage](https://img.shields.io/endpoint?url=https%3A%2F%2Fcorvidlabs.github.io%2F3md%2Fbadges%2Fcoverage.json)](https://corvidlabs.github.io/3md/) [![Release](https://img.shields.io/github/v/release/CorvidLabs/3md?sort=semver)](https://github.com/CorvidLabs/3md/releases) [![License: MIT](https://img.shields.io/github/license/CorvidLabs/3md)](LICENSE) [![Live demo](https://img.shields.io/badge/demo-live-0E6F66)](https://corvidlabs.github.io/3md/) @@ -208,17 +209,19 @@ agreed) and for people (plain, readable, diffable text). ## Development -This repo uses the CorvidLabs trust toolchain. The single gate is: +This repo uses the CorvidLabs trust toolchain. Run the complete repository gate +before calling a change done: ```bash -fledge lanes run verify +fledge trust verify ``` -which runs the Swift format check, build, and tests plus the Rust crate. See +Trust validates the SpecSync contract, risk policy, and provenance posture, and +composes the native `fledge lanes run verify` lane. That native lane runs the +Swift format check, build, and tests plus the Rust crate, TypeScript parser +parity, generated web-component bundle drift, and VS Code grammar tests. See [AGENTS.md](AGENTS.md) for the standing rules every contributor and agent follows. -The same gate also checks TypeScript parser parity, generated web-component -bundle drift, VS Code grammar tests, and spec-sync. Browser UI tests are exposed -separately with `fledge lanes run ui`. +Browser UI tests are exposed separately with `fledge lanes run ui`. Each implementation has its own tests (the Swift suite has 122 tests, the TypeScript suite 76), and all three implementations run the shared 43-vector @@ -228,7 +231,7 @@ cross-implementation contract that keeps the parsers behaving identically. ## Status The format and spec are at version 1.0 (stable, frozen grammar). The latest -release is v1.0.0. Older `3md: 0.1` documents remain valid: the parser is +release is v1.8.1 (see the release badge above). Older `3md: 0.1` documents remain valid: the parser is version-lenient and never rejects a document by its version string. ## License @@ -693,14 +696,16 @@ conformance vector.** ## The gate -One command runs everything (Swift format check, build, tests, and the Rust -crate): +Run the complete repository gate before calling any change done: ```bash -fledge lanes run verify +fledge trust verify ``` -Run it before calling any change done. Per language: +Trust validates the SpecSync contract, risk policy, and provenance posture, and +composes the native `fledge lanes run verify` lane. The native lane runs the +Swift format check, build, tests, TypeScript parity, Rust crate, generated +bundle drift, and editor checks. Per language: ```bash swift test # Swift @@ -802,16 +807,16 @@ descriptive generic names, 4-space indentation, 120-column lines. The formatter config in `.swift-format` enforces the mechanical parts. -## CorvidLabs trust toolchain (standing rules) +## CorvidLabs trust toolchain -This repo is governed by four CLIs. Every session MUST use them; never bypass or weaken them. +This repository uses one trust gate. Every session must use it and must not bypass or weaken it. -- fledge: run `fledge lanes run verify` before calling any change done. It must pass. -- spec-sync: when you change a module with a *.spec.md, update the spec, then `fledge spec check`. (skipped: , if content-only) -- augur: `augur check --staged` before a commit; `augur check --range origin/main..HEAD` before merge. A block verdict is a hard stop, never auto-overridden. -- attest: after a green lane, `attest sign --commit HEAD --reviewer agent: --from-augur augur.json --tests-passed`. +- Run `fledge trust verify` before calling a change complete. +- Keep module specs synchronized with implementation changes. +- Treat an Augur block verdict as a hard stop that must be surfaced and de-risked. +- Record and verify provenance with Attest after the repository's verification lane passes. +- Keep generated trust configuration and this managed block in place. -CI enforces the same gate (.github/workflows/trust.yml) and fails if this block is missing. Brand rule: no em-dash characters in anything you write. @plane z=7 label="PROOF" file="docs/PROOF.md" diff --git a/fledge.toml b/fledge.toml index 6bf0759..2af0f11 100644 --- a/fledge.toml +++ b/fledge.toml @@ -1,8 +1,8 @@ # fledge.toml - project task definitions and lanes # Detected project type: swift # -# The single CI gate is the `verify` lane (see AGENTS.md). Run it with: -# fledge lanes run verify +# Trust is the complete repository gate (see AGENTS.md). The `verify` lane is +# its native implementation-verification component. [tasks] # swift format unifies formatting and linting. `fmt` fixes in place; `lint` @@ -33,17 +33,13 @@ cmd = "bun install --frozen-lockfile && bun test" dir = "js" description = "TypeScript port: install and run the test suite (the shared conformance vectors)." -[tasks.spec] -cmd = "fledge spec check" -description = "spec-sync: every module spec matches its tracked source files." - [lanes.verify] -description = "The single CI gate: all three parser implementations, generated element bundle drift, editor grammar, and spec-sync." -steps = ["lint", "build", "test", "js", "rust", "element-bundle", "editor", "spec"] +description = "Native verification for all three parser implementations, generated element bundle drift, and editor grammar. Trust runs SpecSync after this lane." +steps = ["lint", "build", "test", "js", "rust", "element-bundle", "editor"] [lanes.ci] -description = "Alias for the verify gate." -steps = ["lint", "build", "test", "js", "rust", "element-bundle", "editor", "spec"] +description = "Alias for the native verify lane." +steps = ["lint", "build", "test", "js", "rust", "element-bundle", "editor"] [lanes.ui] description = "Browser UI suite for the published web surfaces." diff --git a/specs/ThreeMD/requirements.md b/specs/ThreeMD/requirements.md index 29b4e2f..b1274a7 100644 --- a/specs/ThreeMD/requirements.md +++ b/specs/ThreeMD/requirements.md @@ -24,37 +24,73 @@ numbered so tests and reviews can reference it directly. ### Functional Requirements -- **FR-1 (Frontmatter required).** `Parser.parse` requires a frontmatter block: +### REQ-threemd-001 + +`Parser.parse` SHALL require a complete frontmatter block and report missing or unclosed fences with typed parse errors. + +Acceptance Criteria + +- `Parser.parse` requires a frontmatter block: a line containing exactly `---`, zero or more content lines, and a closing line containing exactly `---`. Leading blank lines before the opening fence are skipped. A source with no opening `---` throws `ParseError.missingFrontmatter`. A frontmatter block that is never closed throws `ParseError.invalidFrontmatter`. -- **FR-2 (Version marker required).** Frontmatter MUST declare a `3md` key whose +### REQ-threemd-002 + +Frontmatter SHALL declare a non-empty `3md` value that is stored as `Document.version`. + +Acceptance Criteria + +- Frontmatter MUST declare a `3md` key whose value is non-empty. Its presence is the format's magic marker. The value is stored as `Document.version`. A missing or empty `3md` value throws `ParseError.missingVersion`. -- **FR-3 (Frontmatter fields).** Inside the fences, content lines are +### REQ-threemd-003 + +The parser SHALL read frontmatter as case-insensitive `key: value` pairs while rejecting malformed content lines. + +Acceptance Criteria + +- Inside the fences, content lines are `key: value` pairs split on the first `:`. Blank lines and lines beginning with `#` are ignored. A non-blank, non-comment line with no `:` throws `ParseError.invalidFrontmatter`. Keys are matched case-insensitively. Values are trimmed, and a matching pair of surrounding single or double quotes is stripped. -- **FR-4 (Axis handling and default).** The optional `axis` key sets +### REQ-threemd-004 + +The parser SHALL normalize the optional `axis` value and default it to `Axis.layer` when absent. + +Acceptance Criteria + +- The optional `axis` key sets `Document.axis`. The `Axis` value trims and lowercases its raw string, so `axis` is normalized. When no `axis` key is present, the axis defaults to `Axis.layer`. Any axis string is permitted; `time`, `depth`, `layer`, `frame`, and `space` are provided as named constants. -- **FR-5 (Reserved frontmatter keys and metadata).** The keys `3md`, `axis`, and +### REQ-threemd-005 + +The parser SHALL map reserved frontmatter keys to document fields and preserve every other key in `Document.metadata`. + +Acceptance Criteria + +- The keys `3md`, `axis`, and `title` are reserved. `title` populates the optional `Document.title`. Every other frontmatter key is preserved verbatim in `Document.metadata` as a `[String: String]` pair. -- **FR-6 (Plane directives).** A plane begins with a line whose first +### REQ-threemd-006 + +The parser SHALL recognize `@plane` directives and parse their quoted or unquoted `key=value` attributes. + +Acceptance Criteria + +- A plane begins with a line whose first whitespace-delimited token is `@plane`, followed by space-separated `key=value` attributes. A token with no `=`, or with an empty key, throws `ParseError.invalidPlaneDirective`. Attribute keys are lowercased. Attribute @@ -62,41 +98,83 @@ numbered so tests and reviews can reference it directly. spans intact so a value may contain spaces, and surrounding quotes are stripped. -- **FR-7 (Required z attribute).** Each `@plane` directive MUST carry a `z` +### REQ-threemd-007 + +Every explicit plane SHALL provide a numeric `z` attribute, including support for negative and decimal positions. + +Acceptance Criteria + +- Each `@plane` directive MUST carry a `z` attribute. A directive with no `z` throws `ParseError.missingPlanePosition(line:)`. A `z` value that does not parse as a `Double` throws `ParseError.invalidPlaneDirective(line:detail:)`. Numbers may be integer or decimal and may be negative. -- **FR-8 (Optional x, y, label, and extra attributes).** The `x` and `y` +### REQ-threemd-008 + +Plane directives SHALL parse optional numeric `x` and `y`, optional `label`, and preserve non-reserved attributes. + +Acceptance Criteria + +- The `x` and `y` attributes are optional in-plane offsets; when present each MUST parse as a `Double` or `ParseError.invalidPlaneDirective` is thrown. `label` is an optional human-readable string. The reserved plane attributes are `z`, `x`, `y`, and `label`; every other attribute is preserved in `Plane.attributes` as a `[String: String]` pair. -- **FR-9 (Plane body and preamble handling).** Every line after a directive, up +### REQ-threemd-009 + +The parser SHALL assign trimmed Markdown bodies to their planes and preserve pre-plane Markdown as the document preamble. + +Acceptance Criteria + +- Every line after a directive, up to the next `@plane` directive or end of file, is that plane's Markdown body. Leading and trailing blank lines of a body are trimmed; an all-whitespace body collapses to an empty string. Markdown that appears after the frontmatter but before the first `@plane` directive is the document preamble, stored in the optional `Document.preamble` with the same blank-line trimming. -- **FR-10 (Single-plane shorthand).** A document with frontmatter but no +### REQ-threemd-010 + +A frontmatter document with non-empty content and no directive SHALL parse as one implicit plane at `z = 0`. + +Acceptance Criteria + +- A document with frontmatter but no `@plane` directives whose remaining content is non-empty parses as exactly one implicit plane at `z = 0`, with that content as the plane body and a `nil` preamble. This makes a plain Markdown file with a 3md frontmatter header a valid one-plane document. -- **FR-11 (Duplicate z rejection).** No two planes in a document may share the +### REQ-threemd-011 + +The parser SHALL reject duplicate plane `z` values with `ParseError.duplicatePlane(z:)`. + +Acceptance Criteria + +- No two planes in a document may share the same `z` value. A repeated `z` throws `ParseError.duplicatePlane(z:)`. -- **FR-12 (Source order preserved).** `Document.planes` holds planes in source +### REQ-threemd-012 + +`Document` SHALL preserve source plane order while providing ascending-Z lookup and sorting helpers. + +Acceptance Criteria + +- `Document.planes` holds planes in source order. `Document.planesByZ` returns them sorted by ascending `z`, and `Document.plane(atZ:)` returns the first plane whose `z` equals the argument, or `nil`. -- **FR-13 (Serialization).** `Serializer.render` produces 3md text. It always +### REQ-threemd-013 + +`Serializer.render` SHALL emit deterministic frontmatter, plane directives, attributes, and non-empty bodies. + +Acceptance Criteria + +- `Serializer.render` produces 3md text. It always emits a frontmatter block with `3md` and `axis` lines, then `title` when set, then metadata keys sorted alphabetically. For each plane it emits an `@plane` directive (`z`, then `label`, `x`, `y` when set, then extra attributes sorted @@ -104,31 +182,73 @@ numbered so tests and reviews can reference it directly. integers; `label` and extra attribute values are always quoted, and embedded double quotes are escaped. -- **FR-14 (Round-trip).** Serializing a `Document` and parsing the result yields +### REQ-threemd-014 + +Serialization output SHALL parse back to an equal document when content does not depend on quote escaping. + +Acceptance Criteria + +- Serializing a `Document` and parsing the result yields an equal document, for content that does not rely on quote escaping. -- **FR-15 (Line-ending normalization).** Parsing normalizes `\r\n` to `\n` +### REQ-threemd-015 + +Parsing SHALL normalize Windows CRLF line endings to LF before processing. + +Acceptance Criteria + +- Parsing normalizes `\r\n` to `\n` before processing, so Windows and Unix line endings parse identically. ### Non-Functional Requirements -- **NFR-1 (Swift 6, cross-platform).** The module builds under Swift 6 strict +### REQ-threemd-016 + +The module SHALL build under Swift 6 strict concurrency for supported Apple platforms, Linux, and Windows. + +Acceptance Criteria + +- The module builds under Swift 6 strict concurrency and targets all supported Apple platforms, Linux, and Windows. It relies only on portable Foundation string handling. -- **NFR-2 (Sendable value types).** `Axis`, `Plane`, `Document`, `ParseError`, +### REQ-threemd-017 + +Public model and service types SHALL provide the documented `Sendable`, value, coding, hashing, and error conformances. + +Acceptance Criteria + +- `Axis`, `Plane`, `Document`, `ParseError`, `Parser`, and `Serializer` are `Sendable`. `Axis`, `Plane`, and `Document` are immutable value types that are also `Hashable` and `Codable`; `ParseError` is `Equatable`. -- **NFR-3 (No force-unwrap).** Library code uses no force unwraps, `try!`, or +### REQ-threemd-018 + +Library code SHALL handle optionals and conversions without force unwraps, `try!`, or `as!`. + +Acceptance Criteria + +- Library code uses no force unwraps, `try!`, or `as!`. Optionals and failable conversions are handled with `guard` and typed throws. -- **NFR-4 (Zero third-party dependencies).** The module depends only on +### REQ-threemd-019 + +The ThreeMD module SHALL depend only on Foundation and no third-party packages. + +Acceptance Criteria + +- The module depends only on Foundation. No third-party packages are used. -- **NFR-5 (Deterministic parsing and serialization).** Parsing is pure: the same +### REQ-threemd-020 + +Parsing SHALL be pure and serialization SHALL order metadata and extra attributes deterministically. + +Acceptance Criteria + +- Parsing is pure: the same input always yields the same `Document`. Serialization is deterministic, ordering metadata and extra attributes alphabetically so output is stable. diff --git a/specs/ThreeMDCLI/requirements.md b/specs/ThreeMDCLI/requirements.md index f25eddb..c0f09bb 100644 --- a/specs/ThreeMDCLI/requirements.md +++ b/specs/ThreeMDCLI/requirements.md @@ -17,19 +17,79 @@ These requirements describe the ThreeMDCLI Swift executable target: the command- ### Functional Requirements -- **FR-1 (Subcommands).** The executable accepts one of the following subcommands as its first argument: `validate`, `info`, `html`, `links`, or `check-links`. Any other argument or a missing subcommand prints usage information and exits with code 1. -- **FR-2 (validate subcommand).** Parses the specified file. Prints "ok" and exits 0 on success. On parsing failure, prints the error details to stderr and exits 1. -- **FR-3 (info subcommand).** Prints metadata (version, axis, title, plane count) and each plane's properties (z, label, coordinates, extra attributes). -- **FR-4 (html subcommand).** Renders the document to HTML and prints the output to stdout. -- **FR-5 (links subcommand).** Extracts and prints all cross-plane links and the link graph representation. -- **FR-6 (check-links subcommand).** Validates all cross-plane links. If there are dangling links, it prints details to stderr and exits with code 1. If all links resolve, it prints "ok" and exits 0. -- **FR-7 (JSON output option).** The `validate`, `info`, `links`, and `check-links` subcommands support a `--json` flag. When provided, the command prints the output formatted as JSON to stdout instead of raw text. +### REQ-threemdcli-001 + +The executable SHALL accept the documented subcommands and return usage with exit code 1 for missing or unknown commands. + +Acceptance Criteria + +- The executable accepts one of the following subcommands as its first argument: `validate`, `info`, `html`, `links`, or `check-links`. Any other argument or a missing subcommand prints usage information and exits with code 1. +### REQ-threemdcli-002 + +`validate` SHALL parse the requested file, print `ok` on success, and report parse failures to stderr with exit code 1. + +Acceptance Criteria + +- Parses the specified file. Prints "ok" and exits 0 on success. On parsing failure, prints the error details to stderr and exits 1. +### REQ-threemdcli-003 + +`info` SHALL print document metadata and every plane's position, label, coordinates, and extra attributes. + +Acceptance Criteria + +- Prints metadata (version, axis, title, plane count) and each plane's properties (z, label, coordinates, extra attributes). +### REQ-threemdcli-004 + +`html` SHALL render the document to HTML on stdout. + +Acceptance Criteria + +- Renders the document to HTML and prints the output to stdout. +### REQ-threemdcli-005 + +`links` SHALL print every cross-plane link and the link graph representation. + +Acceptance Criteria + +- Extracts and prints all cross-plane links and the link graph representation. +### REQ-threemdcli-006 + +`check-links` SHALL fail with dangling-link details or print `ok` and exit successfully when all links resolve. + +Acceptance Criteria + +- Validates all cross-plane links. If there are dangling links, it prints details to stderr and exits with code 1. If all links resolve, it prints "ok" and exits 0. +### REQ-threemdcli-007 + +Supported inspection subcommands SHALL emit JSON on stdout when `--json` is supplied. + +Acceptance Criteria + +- The `validate`, `info`, `links`, and `check-links` subcommands support a `--json` flag. When provided, the command prints the output formatted as JSON to stdout instead of raw text. ### Non-Functional Requirements -- **NFR-1 (Zero third-party dependencies).** The CLI target depends only on the local `ThreeMD` library target and Foundation. No external package manager or CLI parsing library is used. -- **NFR-2 (Fast execution).** CommandLine parsing and execution are fast, with minimal startup overhead. -- **NFR-3 (Swift 6 Executable).** The executable builds cleanly under Swift 6 strict concurrency settings. +### REQ-threemdcli-008 + +The CLI target SHALL depend only on the local `ThreeMD` target and Foundation. + +Acceptance Criteria + +- The CLI target depends only on the local `ThreeMD` library target and Foundation. No external package manager or CLI parsing library is used. +### REQ-threemdcli-009 + +The executable SHALL parse commands and start with minimal overhead. + +Acceptance Criteria + +- CommandLine parsing and execution are fast, with minimal startup overhead. +### REQ-threemdcli-010 + +The executable SHALL build cleanly under Swift 6 strict concurrency. + +Acceptance Criteria + +- The executable builds cleanly under Swift 6 strict concurrency settings. ## Constraints diff --git a/specs/ThreeMDElement/requirements.md b/specs/ThreeMDElement/requirements.md index c81de52..441873a 100644 --- a/specs/ThreeMDElement/requirements.md +++ b/specs/ThreeMDElement/requirements.md @@ -30,86 +30,182 @@ requirement is numbered so tests and reviews can reference it directly. ### Functional Requirements -- **FR-1 (Parsing is delegated).** The element does not parse 3md text. It calls +### REQ-threemdelement-001 + +The element SHALL delegate 3md parsing to `@corvidlabs/threemd` and render the returned document model. + +Acceptance Criteria + +- The element does not parse 3md text. It calls `parse` from `@corvidlabs/threemd` to turn source into a `Document` and reads `document.planes` and each plane's `z`, `x`, `y`, `label`, and `body`. The format grammar lives in `SPEC.md` and the shared parser; this element only renders the result. -- **FR-2 (Source resolution).** On connect, if the `src` attribute is set the +### REQ-threemdelement-002 + +The element SHALL render either fetched `src` content or inline content and allow `setSource(text)` replacement. + +Acceptance Criteria + +- On connect, if the `src` attribute is set the element fetches that URL and renders the response text; otherwise it renders its inline text content. `setSource(text)` replaces the rendered document with new source at any time, building the DOM first if needed. -- **FR-3 (`src` fetch and staleness).** Fetching `src` is asynchronous and +### REQ-threemdelement-003 + +Asynchronous source loading SHALL discard stale responses and render descriptive failures through the error part. + +Acceptance Criteria + +- Fetching `src` is asynchronous and guarded by a load token: each load increments the token, and a response whose token no longer matches the latest is discarded. A non-ok HTTP status or a rejected request renders the error part with a message naming the source. -- **FR-4 (Empty and invalid source).** Blank source (after trim) renders the +### REQ-threemdelement-004 + +Blank or invalid source SHALL render the documented error message without building planes. + +Acceptance Criteria + +- Blank source (after trim) renders the error part with "No 3md source provided." When `parse` throws, the element renders the error part with "Invalid 3md: " and builds no planes. -- **FR-5 (Observed attributes).** `observedAttributes` is `["src", "mode"]`. +### REQ-threemdelement-005 + +The element SHALL observe `src` and `mode` and reapply them after its DOM is available. + +Acceptance Criteria + +- `observedAttributes` is `["src", "mode"]`. Changing `src` triggers a fetch and render; changing `mode` re-applies the mode and re-renders. Attribute changes before the element has built its DOM are ignored until connect. -- **FR-6 (Mode selection).** The active `Mode` is one of `stack`, `play`, +### REQ-threemdelement-006 + +The element SHALL select a supported rendering mode from `mode`, axis aliases, or the document axis, defaulting to `stack`. + +Acceptance Criteria + +- The active `Mode` is one of `stack`, `play`, `layers`, `scene`, `parallax`, `present`, `elevator`. The `mode` attribute may be a `Mode` value or an axis name; an axis name (for example `time`, `frame`, `frames`, `layer`, `layers`, `depth`, `space`, `scene`, `slide`, `slides`, `deck`, `floor`, `floors`) maps to its mode. With no usable `mode` attribute, the mode is derived from `document.axis`, defaulting to `stack`. -- **FR-7 (Focus-relative layout).** Each plane is positioned by its distance +### REQ-threemdelement-007 + +Plane layout SHALL derive true Z position from distance to focus so the focused plane remains frontmost. + +Acceptance Criteria + +- Each plane is positioned by its distance from the focus, `d = idx - focus`, so the focused plane is frontmost at the largest true Z. The layout MUST NOT pin a fixed plane to the front, because Safari paints by true Z and ignores `z-index` inside `preserve-3d`. -- **FR-8 (Synchronous render).** `render()` applies all current state to the DOM +### REQ-threemdelement-008 + +`render()` SHALL synchronously apply all interaction state as the stage's single source of truth. + +Acceptance Criteria + +- `render()` applies all current state to the DOM synchronously and is the single source of truth for the stage. It is called on every interaction (scrub, drag, step, key, pointer up) and does not depend on `requestAnimationFrame`. -- **FR-9 (Optional animation loop).** The `requestAnimationFrame` loop adds only +### REQ-threemdelement-009 + +Animation frames SHALL provide only optional idle drift and SHALL NOT be required for correct interaction rendering. + +Acceptance Criteria + +- The `requestAnimationFrame` loop adds only gentle idle drift and is progressive enhancement. Every value it produces is also produced by a direct interaction plus a synchronous `render()`, so the element stays fully correct and usable when rAF is throttled or never fires (iOS Low Power Mode). The loop is started on connect and cancelled on disconnect. -- **FR-10 (Pointer interaction).** The stage handles `pointerdown`, +### REQ-threemdelement-010 + +The stage SHALL use one pointer-event path for mouse, touch, and pen drag interactions. + +Acceptance Criteria + +- The stage handles `pointerdown`, `pointermove`, `pointerup`, and `pointercancel` through one unified path for mouse, touch, and pen. A vertical drag moves the focus along Z; a horizontal drag orbits the scene. Pointer capture is attempted and failures are tolerated. -- **FR-11 (Touch behavior and no overflow).** The stage sets +### REQ-threemdelement-011 + +The element SHALL reserve touch gestures for the model and avoid horizontal overflow from 320px through 1440px. + +Acceptance Criteria + +- The stage sets `touch-action: none` so a finger drives the model rather than scrolling the page. The element is `max-width: 100%` and `box-sizing: border-box` and MUST NOT overflow horizontally at any width from 320px to 1440px. -- **FR-12 (Scrubber, buttons, and keys).** A range input scrubs the Z axis; its +### REQ-threemdelement-012 + +The scrubber, step buttons, and arrow keys SHALL synchronously navigate the focused plane within range. + +Acceptance Criteria + +- A range input scrubs the Z axis; its max is the last plane index. Prev and next buttons step the focus by one. Arrow keys step too: Right or Up advances, Left or Down retreats. Each of these snaps the focus to the target and renders synchronously. -- **FR-13 (Read accessors).** `document` returns the parsed `Document` or `null` +### REQ-threemdelement-013 + +The public element API SHALL expose its document, current index, active mode, and clamped `goTo(index)` navigation. + +Acceptance Criteria + +- `document` returns the parsed `Document` or `null` before load. `currentIndex` returns the rounded focus index. `mode` returns the active `Mode`. `goTo(index)` focuses a plane by index, clamped to range. -- **FR-14 (planechange event).** When the rounded focus index changes, the +### REQ-threemdelement-014 + +A focus-index change SHALL emit one bubbling, composed `planechange` event containing the selected plane details. + +Acceptance Criteria + +- When the rounded focus index changes, the element dispatches a single `planechange` `CustomEvent` whose detail is `{ index, z, label, plane }`. The event bubbles and is composed so it crosses the shadow boundary. It is not re-emitted while the focused index is unchanged. -- **FR-15 (Plane rendering and Markdown subset).** Each plane renders a tag line +### REQ-threemdelement-015 + +Each plane SHALL render its tag and an HTML-escaped body using the documented limited Markdown subset. + +Acceptance Criteria + +- Each plane renders a tag line (its `z` and `label`, or `z ` when unlabeled) plus a body rendered with a deliberately small Markdown subset: headings, ordered and unordered list items, task items, blockquotes, inline code, bold, italic, and a fenced-block grid. All text is HTML-escaped before formatting. -- **FR-16 (Shadow DOM, theming, and parts).** The element attaches an open +### REQ-threemdelement-016 + +The element SHALL use an open shadow root and expose theming through the documented custom properties and parts. + +Acceptance Criteria + +- The element attaches an open shadow root and isolates its styles there. It is themeable through CSS custom properties and exposes internals through `::part`: `wrap`, `axis`, `stage`, `arrow`, `scene`, `hint`, `controls`, `prev`, `scrubber`, `next`, `readout`, @@ -117,22 +213,52 @@ requirement is numbered so tests and reviews can reference it directly. ### Non-Functional Requirements -- **NFR-1 (Framework agnostic).** As a standard custom element, `` +### REQ-threemdelement-017 + +`` SHALL work unchanged in plain HTML, React, Vue, Svelte, and Angular. + +Acceptance Criteria + +- As a standard custom element, `` works unchanged in plain HTML and in React, Vue, Svelte, and Angular. There is one tested renderer, not a per-app reimplementation. -- **NFR-2 (Cross-browser tested).** The element is covered in CI by the Playwright +### REQ-threemdelement-018 + +CI SHALL exercise the component's invariants and console cleanliness in Chromium and WebKit with Playwright. + +Acceptance Criteria + +- The element is covered in CI by the Playwright suite under `uitests/`, run in both Chromium and WebKit, guarding the three invariants and a clean console. -- **NFR-3 (Self-contained bundle).** The published bundle includes the parser, so +### REQ-threemdelement-019 + +The published element bundle SHALL include the parser so no separate parser script is required. + +Acceptance Criteria + +- The published bundle includes the parser, so loading the one module is enough; no separate parser script is required. -- **NFR-4 (Style isolation).** All component styles live inside the shadow root +### REQ-threemdelement-020 + +Component styles SHALL remain isolated inside the shadow root except for documented theming surfaces. + +Acceptance Criteria + +- All component styles live inside the shadow root so the host page cannot leak in and the component cannot leak out, except through the documented custom properties and parts. -- **NFR-5 (Resilience).** The element degrades gracefully: it tolerates absent +### REQ-threemdelement-021 + +The element SHALL degrade gracefully when optional browser capabilities or external source loading are unavailable. + +Acceptance Criteria + +- The element degrades gracefully: it tolerates absent pointer capture, a missing `requestAnimationFrame`, fetch failures, and invalid source, surfacing problems through the error part rather than throwing. diff --git a/web/docs.3md b/web/docs.3md index d97d72b..4c11a35 100644 --- a/web/docs.3md +++ b/web/docs.3md @@ -21,6 +21,7 @@ regenerate with `node scripts/build-docs-3md.mjs`. # 3md [![CI](https://github.com/CorvidLabs/3md/actions/workflows/trust.yml/badge.svg)](https://github.com/CorvidLabs/3md/actions/workflows/trust.yml) +[![spec coverage](https://img.shields.io/endpoint?url=https%3A%2F%2Fcorvidlabs.github.io%2F3md%2Fbadges%2Fcoverage.json)](https://corvidlabs.github.io/3md/) [![Release](https://img.shields.io/github/v/release/CorvidLabs/3md?sort=semver)](https://github.com/CorvidLabs/3md/releases) [![License: MIT](https://img.shields.io/github/license/CorvidLabs/3md)](LICENSE) [![Live demo](https://img.shields.io/badge/demo-live-0E6F66)](https://corvidlabs.github.io/3md/) @@ -208,17 +209,19 @@ agreed) and for people (plain, readable, diffable text). ## Development -This repo uses the CorvidLabs trust toolchain. The single gate is: +This repo uses the CorvidLabs trust toolchain. Run the complete repository gate +before calling a change done: ```bash -fledge lanes run verify +fledge trust verify ``` -which runs the Swift format check, build, and tests plus the Rust crate. See +Trust validates the SpecSync contract, risk policy, and provenance posture, and +composes the native `fledge lanes run verify` lane. That native lane runs the +Swift format check, build, and tests plus the Rust crate, TypeScript parser +parity, generated web-component bundle drift, and VS Code grammar tests. See [AGENTS.md](AGENTS.md) for the standing rules every contributor and agent follows. -The same gate also checks TypeScript parser parity, generated web-component -bundle drift, VS Code grammar tests, and spec-sync. Browser UI tests are exposed -separately with `fledge lanes run ui`. +Browser UI tests are exposed separately with `fledge lanes run ui`. Each implementation has its own tests (the Swift suite has 122 tests, the TypeScript suite 76), and all three implementations run the shared 43-vector @@ -228,7 +231,7 @@ cross-implementation contract that keeps the parsers behaving identically. ## Status The format and spec are at version 1.0 (stable, frozen grammar). The latest -release is v1.0.0. Older `3md: 0.1` documents remain valid: the parser is +release is v1.8.1 (see the release badge above). Older `3md: 0.1` documents remain valid: the parser is version-lenient and never rejects a document by its version string. ## License @@ -693,14 +696,16 @@ conformance vector.** ## The gate -One command runs everything (Swift format check, build, tests, and the Rust -crate): +Run the complete repository gate before calling any change done: ```bash -fledge lanes run verify +fledge trust verify ``` -Run it before calling any change done. Per language: +Trust validates the SpecSync contract, risk policy, and provenance posture, and +composes the native `fledge lanes run verify` lane. The native lane runs the +Swift format check, build, tests, TypeScript parity, Rust crate, generated +bundle drift, and editor checks. Per language: ```bash swift test # Swift @@ -802,16 +807,16 @@ descriptive generic names, 4-space indentation, 120-column lines. The formatter config in `.swift-format` enforces the mechanical parts. -## CorvidLabs trust toolchain (standing rules) +## CorvidLabs trust toolchain -This repo is governed by four CLIs. Every session MUST use them; never bypass or weaken them. +This repository uses one trust gate. Every session must use it and must not bypass or weaken it. -- fledge: run `fledge lanes run verify` before calling any change done. It must pass. -- spec-sync: when you change a module with a *.spec.md, update the spec, then `fledge spec check`. (skipped: , if content-only) -- augur: `augur check --staged` before a commit; `augur check --range origin/main..HEAD` before merge. A block verdict is a hard stop, never auto-overridden. -- attest: after a green lane, `attest sign --commit HEAD --reviewer agent: --from-augur augur.json --tests-passed`. +- Run `fledge trust verify` before calling a change complete. +- Keep module specs synchronized with implementation changes. +- Treat an Augur block verdict as a hard stop that must be surfaced and de-risked. +- Record and verify provenance with Attest after the repository's verification lane passes. +- Keep generated trust configuration and this managed block in place. -CI enforces the same gate (.github/workflows/trust.yml) and fails if this block is missing. Brand rule: no em-dash characters in anything you write. @plane z=7 label="PROOF" file="docs/PROOF.md"