From c2548ae6cab9c2bf4339b29d171d1f5d56ffbb92 Mon Sep 17 00:00:00 2001 From: 0xLeif Date: Sat, 11 Jul 2026 21:15:35 -0600 Subject: [PATCH 01/25] Update: adopt Trust 1 in project templates --- .github/workflows/ci.yml | 7 +- .specsync/config.toml | 5 +- .specsync/version | 2 +- CHANGELOG.md | 3 + specs/plugin/plugin-protocol.spec.md | 4 +- .../corvid-stack/.github/workflows/trust.yml | 76 ++----------------- templates/corvid-stack/.specsync/config.toml | 2 +- templates/corvid-stack/.specsync/sdd.json | 26 +++++++ templates/corvid-stack/.specsync/version | 1 + templates/corvid-stack/.trust.toml | 22 ++++++ 10 files changed, 67 insertions(+), 81 deletions(-) create mode 100644 templates/corvid-stack/.specsync/sdd.json create mode 100644 templates/corvid-stack/.specsync/version create mode 100644 templates/corvid-stack/.trust.toml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8e4dd07d..87138e97 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -113,12 +113,9 @@ jobs: - uses: actions/checkout@v5 - name: Run spec-sync id: specsync - uses: CorvidLabs/spec-sync@v4.3.2 + uses: CorvidLabs/spec-sync@59bbfa766c6cce01ab815ab47db195b0629cc014 # v5.0.1 with: - # 4.8.0 under-detects exports in multi-file Rust specs and makes this - # strict gate false-fail. Keep the newest verified release pinned - # until spec-sync publishes the scanner fix. - version: 4.7.1 + version: 5.0.1 strict: true comment: false # Enforce reverse coverage: every production source file must be diff --git a/.specsync/config.toml b/.specsync/config.toml index c210a4ff..f935eed6 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" @@ -10,8 +10,5 @@ exclude_dirs = [] exclude_patterns = ["src/test_support.rs", "**/.github/**"] required_sections = ["Purpose", "Public API", "Invariants", "Behavioral Examples", "Error Cases", "Dependencies", "Change Log"] enforcement = "strict" -ai_command = "claude -p --output-format text" -ai_timeout = 300 - [lifecycle] track_history = false diff --git a/.specsync/version b/.specsync/version index f77856a6..6b244dcd 100644 --- a/.specsync/version +++ b/.specsync/version @@ -1 +1 @@ -4.3.1 +5.0.1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 11910ec1..35798a22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +- Update SpecSync validation to 5.0.1 and remove obsolete embedded-AI configuration. +- Generate new Corvid stack projects with the unified Trust 1.0 gate and SpecSync SDD policy. + ### Fixes - scope Atlas coverage to shipped product code by excluding build/test-only support files (#495) diff --git a/specs/plugin/plugin-protocol.spec.md b/specs/plugin/plugin-protocol.spec.md index b7d18224..a1550604 100644 --- a/specs/plugin/plugin-protocol.spec.md +++ b/specs/plugin/plugin-protocol.spec.md @@ -1,6 +1,6 @@ --- module: plugin-protocol -version: 7 +version: 8 status: active files: - src/protocol/mod.rs @@ -62,6 +62,7 @@ Public API — `run_protocol_plugin`, `OutboundMessage`, and `PluginContext` are | `detect_project_context` | Detect project name, root path, language, and git context from current environment | | `sanitize_remote_url` | Strip credentials from HTTPS/HTTP git URLs | | `detect_git_context` | Extract git branch, dirty status, remote name, and sanitized remote URL | +| `Read` | Crate-internal I/O trait re-export used by protocol stream readers | ### Structs & Enums @@ -604,6 +605,7 @@ These are not part of v1 but are designed to be additive under the policy above: | Version | Date | Changes | |---------|------|---------| +| 8 | 2026-07-11 | Document the crate-internal `Read` re-export detected by SpecSync 5 multi-file scanning | | 7 | 2026-05-02 | Remove misleading "sandboxed" language from exec security notes; clarify that cwd is validated but command string is unfiltered. Change future file_operations wording from "sandboxed" to "path-validated" | | 6 | 2026-05-02 | Clarify public vs internal exports in single table (spec-sync requires all exports in one `Exported Functions` table). Add platform-correct storage paths using `` notation | | 5 | 2026-04-29 | Fix spec-sync: consolidate all exports into standard `Exported Functions` table (custom subsection headers were not parsed by spec-sync) | diff --git a/templates/corvid-stack/.github/workflows/trust.yml b/templates/corvid-stack/.github/workflows/trust.yml index 564f333c..55e58b90 100644 --- a/templates/corvid-stack/.github/workflows/trust.yml +++ b/templates/corvid-stack/.github/workflows/trust.yml @@ -1,14 +1,5 @@ name: Trust -# The CorvidLabs trust gate as parallel checks: fledge (quality), spec-sync -# (contract), augur (risk), attest (provenance), and the AGENTS.md rules marker. -# Each job is an independent PR check, so a failure points straight at the tool. -# Tools: https://corvidlabs.xyz/integrate/ -# -# These run in parallel because, in verify form, they are independent. If you -# later switch attest to `sign --from-augur augur.json --tests-passed`, attest -# depends on augur + tests: add `needs: [augur, fledge]` and pass augur.json -# between the jobs with upload-artifact / download-artifact. on: push: branches: [main] @@ -18,69 +9,16 @@ permissions: contents: read jobs: - # 1) fledge: the quality gate (the `verify` lane: fmt + lint + test + build). - fledge: + trust: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 - # fledge has no setup action; install the prebuilt binary (fast). Swap for - # `cargo install fledge --locked` or `brew install corvidlabs/tap/fledge` - # if you prefer. - - name: Install fledge - run: curl -fsSL https://raw.githubusercontent.com/CorvidLabs/fledge/main/install.sh | sh - - name: Verify (fledge lane) - run: fledge lanes run verify - # 2) spec-sync: spec-as-contract validation. - # Soft until specs land; drop continue-on-error once you have specs. - spec-sync: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: CorvidLabs/spec-sync@v4 - continue-on-error: true - with: - strict: true - comment: false - - # 3) augur: deterministic diff-risk gate. Fails at/above `threshold`. - augur: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # range needs full git history - - uses: CorvidLabs/augur@v0 - with: - # PR: base..head. Push: the single pushed commit. Avoids the empty - # range that a hardcoded origin/main..HEAD gives on push to main. - range: ${{ github.event_name == 'pull_request' && format('origin/{0}..HEAD', github.base_ref) || format('{0}~1..{0}', github.sha) }} - threshold: block + - name: CorvidLabs Trust gate + id: trust + uses: CorvidLabs/trust@9d32b5786d2e9e4d39fc581c0091c721ee3d4226 # v1.0.0 - # 4) attest: signed provenance verification against .attest.json. - # The shipped policy is permissive; soft until you tighten it. - attest: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Fetch provenance notes - run: git fetch origin "+refs/notes/*:refs/notes/*" 2>/dev/null || true - - uses: CorvidLabs/attest@v0 - continue-on-error: true - with: - range: ${{ github.event_name == 'pull_request' && format('origin/{0}..HEAD', github.base_ref) || format('{0}~1..{0}', github.sha) }} - policy: .attest.json - - # 5) The managed agent-rules block must be present and intact. - rules: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Check AGENTS.md trust marker - run: | - grep -q "CorvidLabs trust toolchain: BEGIN" AGENTS.md \ - || { echo "::error::AGENTS.md is missing the managed CorvidLabs trust toolchain block"; exit 1; } + - name: Check managed agent rules + run: grep -q "CorvidLabs trust toolchain: BEGIN" AGENTS.md diff --git a/templates/corvid-stack/.specsync/config.toml b/templates/corvid-stack/.specsync/config.toml index 8c30709c..1728dd62 100644 --- a/templates/corvid-stack/.specsync/config.toml +++ b/templates/corvid-stack/.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" # Set this to match your project's source layout, e.g. ["lib"], ["app"], diff --git a/templates/corvid-stack/.specsync/sdd.json b/templates/corvid-stack/.specsync/sdd.json new file mode 100644 index 00000000..b78d8d88 --- /dev/null +++ b/templates/corvid-stack/.specsync/sdd.json @@ -0,0 +1,26 @@ +{ + "version": 1, + "enabled": true, + "require_change_for_meaningful_files": true, + "meaningful_paths": [ + "src/", + "tests/", + ".github/", + "Cargo.toml", + "Cargo.lock", + "package.json", + "bun.lock", + ".specsync/sdd.json", + ".specsync/config.toml", + ".specsync/version" + ], + "ignored_paths": [ + ".specsync/", + "specs/" + ], + "verification_commands": [ + "fledge lanes run verify" + ], + "custom_artifacts": {}, + "principles_file": null +} diff --git a/templates/corvid-stack/.specsync/version b/templates/corvid-stack/.specsync/version new file mode 100644 index 00000000..6b244dcd --- /dev/null +++ b/templates/corvid-stack/.specsync/version @@ -0,0 +1 @@ +5.0.1 diff --git a/templates/corvid-stack/.trust.toml b/templates/corvid-stack/.trust.toml new file mode 100644 index 00000000..242a92b5 --- /dev/null +++ b/templates/corvid-stack/.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 project creation" From 695ca94a54371e380be1ffbb603e3ee5cc387454 Mon Sep 17 00:00:00 2001 From: 0xLeif Date: Sat, 11 Jul 2026 22:24:52 -0600 Subject: [PATCH 02/25] fix(ci): fetch trusted SDD policy base --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 87138e97..cdf56f92 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -111,6 +111,8 @@ jobs: body: ${{ steps.specsync.outputs.body }} steps: - uses: actions/checkout@v5 + with: + fetch-depth: 0 - name: Run spec-sync id: specsync uses: CorvidLabs/spec-sync@59bbfa766c6cce01ab815ab47db195b0629cc014 # v5.0.1 From a9a07348671cf045c523f2f8036b16aed7904a53 Mon Sep 17 00:00:00 2001 From: 0xLeif Date: Sat, 11 Jul 2026 22:44:44 -0600 Subject: [PATCH 03/25] chore(trust): adopt verified SDD lifecycle --- .attest.json | 4 + .augur.toml | 3 + .codex/skills/spec-sync/SKILL.md | 75 ++++++++ .cursor/commands/specsync-create-change.md | 9 + .cursor/commands/specsync-create-spec.md | 35 ++++ .cursor/skills/spec-sync/SKILL.md | 75 ++++++++ .gemini/commands/specsync/create-change.toml | 11 ++ .gemini/commands/specsync/create-spec.toml | 35 ++++ .gemini/skills/spec-sync/SKILL.md | 75 ++++++++ .github/workflows/trust.yml | 23 +++ .specsync/adoption-report.json | 165 ++++++++++++++++++ .specsync/change.lock | 0 .../approvals.json | 11 ++ .../change.md | 24 +++ .../context.md | 8 + .../design.md | 8 + .../docs.md | 8 + .../plan.md | 11 ++ .../research.md | 8 + .../state.json | 46 +++++ .../tasks.md | 12 ++ .../testing.md | 12 ++ .../approvals.json | 18 ++ .../change.md | 24 +++ .../context.md | 9 + .../design.md | 9 + .../docs.md | 8 + .../plan.md | 10 ++ .../research.md | 9 + .../state.json | 35 ++++ .../tasks.md | 10 ++ .../testing.md | 8 + .specsync/sdd.json | 40 +++++ .trust.toml | 22 +++ AGENTS.md | 13 ++ fledge.toml | 4 + specs/ai/requirements.md | 50 ++++++ specs/ask/requirements.md | 42 +++++ specs/changelog/requirements.md | 66 +++++++ specs/config/requirements.md | 74 ++++++++ specs/create_template/requirements.md | 58 ++++++ specs/doctor/requirements.md | 50 ++++++ specs/envelope/requirements.md | 58 ++++++ specs/github/requirements.md | 82 +++++++++ specs/init/requirements.md | 90 ++++++++++ specs/introspect/requirements.md | 42 +++++ specs/lanes/requirements.md | 114 ++++++++++++ specs/llm/requirements.md | 58 ++++++ specs/main/requirements.md | 34 ++++ specs/meta/requirements.md | 50 ++++++ specs/plugin/requirements.md | 130 ++++++++++++++ specs/prompts/requirements.md | 58 ++++++ specs/publish/requirements.md | 74 ++++++++ specs/release/requirements.md | 82 +++++++++ specs/remote/requirements.md | 58 ++++++ specs/review/requirements.md | 50 ++++++ specs/run/requirements.md | 58 ++++++ specs/search/requirements.md | 66 +++++++ specs/spec/requirements.md | 66 +++++++ specs/spinner/requirements.md | 34 ++++ specs/templates/requirements.md | 98 +++++++++++ specs/trust/requirements.md | 66 +++++++ specs/utils/requirements.md | 74 ++++++++ specs/validate/requirements.md | 42 +++++ specs/versioning/requirements.md | 42 +++++ specs/watch/requirements.md | 66 +++++++ specs/work/requirements.md | 154 ++++++++++++++++ 67 files changed, 2963 insertions(+) create mode 100644 .attest.json create mode 100644 .augur.toml create mode 100644 .codex/skills/spec-sync/SKILL.md create mode 100644 .cursor/commands/specsync-create-change.md create mode 100644 .cursor/commands/specsync-create-spec.md create mode 100644 .cursor/skills/spec-sync/SKILL.md create mode 100644 .gemini/commands/specsync/create-change.toml create mode 100644 .gemini/commands/specsync/create-spec.toml create mode 100644 .gemini/skills/spec-sync/SKILL.md create mode 100644 .github/workflows/trust.yml create mode 100644 .specsync/adoption-report.json create mode 100644 .specsync/change.lock create mode 100644 .specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/approvals.json create mode 100644 .specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/change.md create mode 100644 .specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/context.md create mode 100644 .specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/design.md create mode 100644 .specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/docs.md create mode 100644 .specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/plan.md create mode 100644 .specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/research.md create mode 100644 .specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/state.json create mode 100644 .specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/tasks.md create mode 100644 .specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/testing.md create mode 100644 .specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json create mode 100644 .specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/change.md create mode 100644 .specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/context.md create mode 100644 .specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/design.md create mode 100644 .specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/docs.md create mode 100644 .specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/plan.md create mode 100644 .specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/research.md create mode 100644 .specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json create mode 100644 .specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/tasks.md create mode 100644 .specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/testing.md create mode 100644 .specsync/sdd.json create mode 100644 .trust.toml diff --git a/.attest.json b/.attest.json new file mode 100644 index 00000000..ba4a0631 --- /dev/null +++ b/.attest.json @@ -0,0 +1,4 @@ +{ + "requireAttestation": true, + "requireTestsPassed": true +} diff --git a/.augur.toml b/.augur.toml new file mode 100644 index 00000000..031b4599 --- /dev/null +++ b/.augur.toml @@ -0,0 +1,3 @@ +[thresholds] +review = 35 +block = 65 diff --git a/.codex/skills/spec-sync/SKILL.md b/.codex/skills/spec-sync/SKILL.md new file mode 100644 index 00000000..de24d12d --- /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 + +## 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/.cursor/commands/specsync-create-change.md b/.cursor/commands/specsync-create-change.md new file mode 100644 index 00000000..49402f37 --- /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`. +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 00000000..0f20b4c4 --- /dev/null +++ b/.cursor/commands/specsync-create-spec.md @@ -0,0 +1,35 @@ +Create a new spec-sync module spec. + +Arguments: $ARGUMENTS + +1. Parse the arguments above: the first whitespace-separated token is the + module name. If the arguments also contain `--minimal` (in any position), + remove it and remember that minimal mode was requested. +2. Look at whatever text remains. It will be one of: + - **A bare module name** — a short identifier like `auth-service` or + `billing`. 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 00000000..de24d12d --- /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 + +## 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/.gemini/commands/specsync/create-change.toml b/.gemini/commands/specsync/create-change.toml new file mode 100644 index 00000000..b4b7de66 --- /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 "$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`. +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 00000000..73789f1f --- /dev/null +++ b/.gemini/commands/specsync/create-spec.toml @@ -0,0 +1,35 @@ +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. Parse the arguments above: the first whitespace-separated token is the + module name. If the arguments also contain --minimal (in any position), + remove it and remember that minimal mode was requested. +2. Look at whatever text remains. It will be one of: + - A bare module name - a short identifier like auth-service or billing. + 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 00000000..de24d12d --- /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 new file mode 100644 index 00000000..a70594ca --- /dev/null +++ b/.github/workflows/trust.yml @@ -0,0 +1,23 @@ +name: trust + +on: + pull_request: + push: + branches: [main] + +permissions: + contents: read + +jobs: + trust: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + - uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt, clippy + - name: CorvidLabs Trust gate + id: trust + uses: CorvidLabs/trust@9d32b5786d2e9e4d39fc581c0091c721ee3d4226 # v1.0.0 diff --git a/.specsync/adoption-report.json b/.specsync/adoption-report.json new file mode 100644 index 00000000..7479e239 --- /dev/null +++ b/.specsync/adoption-report.json @@ -0,0 +1,165 @@ +{ + "bootstrap_policy": { + "base_commit": "695ca94a54371e380be1ffbb603e3ee5cc387454", + "digest": "5e8da30e6bfa76381497a516801b6d2f606d7efcd70ebde615e795642abfc76b", + "path": ".specsync/sdd.json" + }, + "generated_at": 1783831218, + "requirements_needing_ids": [ + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/init/requirements.md", + "suggested_first_id": "REQ-init-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/validate/requirements.md", + "suggested_first_id": "REQ-validate-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/llm/requirements.md", + "suggested_first_id": "REQ-llm-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/introspect/requirements.md", + "suggested_first_id": "REQ-introspect-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/ask/requirements.md", + "suggested_first_id": "REQ-ask-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/changelog/requirements.md", + "suggested_first_id": "REQ-changelog-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/config/requirements.md", + "suggested_first_id": "REQ-config-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/create_template/requirements.md", + "suggested_first_id": "REQ-create-template-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/doctor/requirements.md", + "suggested_first_id": "REQ-doctor-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/plugin/requirements.md", + "suggested_first_id": "REQ-plugin-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/spec/requirements.md", + "suggested_first_id": "REQ-spec-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/meta/requirements.md", + "suggested_first_id": "REQ-meta-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/utils/requirements.md", + "suggested_first_id": "REQ-utils-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/release/requirements.md", + "suggested_first_id": "REQ-release-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/spinner/requirements.md", + "suggested_first_id": "REQ-spinner-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/lanes/requirements.md", + "suggested_first_id": "REQ-lanes-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/search/requirements.md", + "suggested_first_id": "REQ-search-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/envelope/requirements.md", + "suggested_first_id": "REQ-envelope-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/publish/requirements.md", + "suggested_first_id": "REQ-publish-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/github/requirements.md", + "suggested_first_id": "REQ-github-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/ai/requirements.md", + "suggested_first_id": "REQ-ai-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/review/requirements.md", + "suggested_first_id": "REQ-review-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/work/requirements.md", + "suggested_first_id": "REQ-work-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/prompts/requirements.md", + "suggested_first_id": "REQ-prompts-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/watch/requirements.md", + "suggested_first_id": "REQ-watch-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/templates/requirements.md", + "suggested_first_id": "REQ-templates-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/trust/requirements.md", + "suggested_first_id": "REQ-trust-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/run/requirements.md", + "suggested_first_id": "REQ-run-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/versioning/requirements.md", + "suggested_first_id": "REQ-versioning-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/main/requirements.md", + "suggested_first_id": "REQ-main-001" + }, + { + "action": "review and assign one stable ID per durable requirement", + "path": "specs/remote/requirements.md", + "suggested_first_id": "REQ-remote-001" + } + ] +} diff --git a/.specsync/change.lock b/.specsync/change.lock new file mode 100644 index 00000000..e69de29b 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 00000000..ffa9e9f5 --- /dev/null +++ b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/approvals.json @@ -0,0 +1,11 @@ +{ + "approvals": [ + { + "gate": "definition", + "actor": "user:0xLeif", + "timestamp": 1783831307, + "digest": "a4efac74ec54e8951785201cf048510fd9164e1ff04edfc1b1f6e312d17ff1a6", + "note": "Authorized by the approved organization-wide SpecSync 5 / Trust 1 migration plan." + } + ] +} 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 00000000..7aef91ac --- /dev/null +++ b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/change.md @@ -0,0 +1,24 @@ +--- +id: CHG-0001-adopt-trust-1-and-specsync-5 +state: implementing +type: migration +base_commit: 695ca94a54371e380be1ffbb603e3ee5cc387454 +--- + +# Adopt Trust 1 and SpecSync 5 + +## Intent + +Adopt Trust 1 and SpecSync 5 + +## Affected Canonical Specs + +- None + +## Acceptance Criteria + +- Trust 1 runs the native verify lane; SpecSync 5.0.1 strict validation passes; all four agent integrations are installed; existing requirement semantics remain unchanged + +## No-spec Rationale + +Governance tooling and stable requirement identifiers do not change existing runtime semantics. 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 00000000..5a9e6fab --- /dev/null +++ b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/context.md @@ -0,0 +1,8 @@ +--- +change: CHG-0001-adopt-trust-1-and-specsync-5 +artifact: context +--- + +# Context + +fledge is part of the organization-wide migration to SpecSync 5.0.1 and Trust 1.0.0. Existing build, test, release, signing, and publication workflows remain authoritative. 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 00000000..fd0779b9 --- /dev/null +++ b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/design.md @@ -0,0 +1,8 @@ +--- +change: CHG-0001-adopt-trust-1-and-specsync-5 +artifact: design +--- + +# Design + +A single immutable Trust action composes lifecycle, contract, risk, and progressive provenance checks. Specialized CI and standalone Atlas or signing workflows remain independent. 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 00000000..370ed501 --- /dev/null +++ b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/docs.md @@ -0,0 +1,8 @@ +--- +change: CHG-0001-adopt-trust-1-and-specsync-5 +artifact: docs +--- + +# Docs + +Contributor guidance and generated agent instructions describe the SpecSync 5 change lifecycle and unified Trust 1 gate. 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 00000000..a008f3e1 --- /dev/null +++ b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/plan.md @@ -0,0 +1,11 @@ +--- +change: CHG-0001-adopt-trust-1-and-specsync-5 +artifact: plan +--- + +# Plan + +1. Adopt the verified SDD lifecycle and stable requirement IDs. +2. Install all four agent integrations. +3. Run the native Fledge verify lane through Trust 1. +4. Preserve specialized workflows and validate hosted 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 00000000..7efbc678 --- /dev/null +++ b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/research.md @@ -0,0 +1,8 @@ +--- +change: CHG-0001-adopt-trust-1-and-specsync-5 +artifact: research +--- + +# Research + +The repository's native tasks, workflow runners, contract coverage, requirement companions, and provenance policy were audited before adoption. 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 00000000..49876bed --- /dev/null +++ b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/state.json @@ -0,0 +1,46 @@ +{ + "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": "implementing", + "base_commit": "695ca94a54371e380be1ffbb603e3ee5cc387454", + "created_at": 1783831307, + "updated_at": 1783831307, + "affected_specs": [], + "affected_paths": [ + ".github/workflows/", + ".specsync/", + ".trust.toml", + ".augur.toml", + ".attest.json", + "AGENTS.md", + ".claude/", + ".cursor/", + ".codex/", + ".gemini/", + "fledge.toml", + "specs/" + ], + "no_spec_change": true, + "no_spec_change_rationale": "Governance tooling and stable requirement identifiers do not change existing runtime semantics.", + "acceptance_criteria": [ + "Trust 1 runs the native verify lane; SpecSync 5.0.1 strict validation passes; all four agent integrations are installed; existing requirement semantics remain unchanged" + ], + "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 00000000..2d6c2751 --- /dev/null +++ b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/tasks.md @@ -0,0 +1,12 @@ +--- +change: CHG-0001-adopt-trust-1-and-specsync-5 +artifact: tasks +--- + +# Tasks + +- [x] Adopt SpecSync 5.0.1 and install agent integrations. +- [x] Configure Trust 1 with immutable action pins. +- [x] Preserve native validation and specialized workflows. +- [ ] Pass hosted pull-request checks. +- [ ] Require the green trust check on the protected branch. 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 00000000..6c370a6b --- /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 + +- Run the native Fledge verify lane. +- Run SpecSync strict validation at the committed threshold. +- Confirm all four agent integrations. +- Run Trust doctor and verification. +- Confirm hosted native and Trust checks pass. diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json new file mode 100644 index 00000000..41baf9cb --- /dev/null +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json @@ -0,0 +1,18 @@ +{ + "approvals": [ + { + "gate": "definition", + "actor": "user:0xLeif", + "timestamp": 1783831331, + "digest": "3bef6eeeec488d6fb44252b8e3e755b94555f91d677f7d4731d69f9b8daf7421", + "note": "Authorized by the approved organization-wide SpecSync 5 / Trust 1 migration plan." + }, + { + "gate": "definition", + "actor": "user:0xLeif", + "timestamp": 1783831395, + "digest": "62b4cdc0055b7d9c77ee517b7549cd4ef23f69dc596edb23ecb0bffc5a332c68", + "note": "Authorized by the approved organization-wide SpecSync 5 / Trust 1 migration plan." + } + ] +} diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/change.md b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/change.md new file mode 100644 index 00000000..b79d07af --- /dev/null +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/change.md @@ -0,0 +1,24 @@ +--- +id: CHG-0002-update-corvid-stack-template-for-trust-1 +state: implementing +type: migration +base_commit: 695ca94a54371e380be1ffbb603e3ee5cc387454 +--- + +# Update Corvid stack template for Trust 1 + +## Intent + +Update Corvid stack template for Trust 1 + +## Affected Canonical Specs + +- None + +## Acceptance Criteria + +- The Corvid stack template emits SpecSync 5.0.1 SDD and the immutable Trust 1 workflow + +## No-spec Rationale + +Template governance defaults do not change Fledge runtime behavior. diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/context.md b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/context.md new file mode 100644 index 00000000..e76c83e9 --- /dev/null +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/context.md @@ -0,0 +1,9 @@ +--- +change: CHG-0002-update-corvid-stack-template-for-trust-1 +artifact: context +--- + +# Context + +The Corvid stack template previously emitted independently orchestrated governance actions and +SpecSync 4 defaults. New projects need the organization-standard SpecSync 5 and Trust 1 contract. diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/design.md b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/design.md new file mode 100644 index 00000000..f141eeee --- /dev/null +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/design.md @@ -0,0 +1,9 @@ +--- +change: CHG-0002-update-corvid-stack-template-for-trust-1 +artifact: design +--- + +# Design + +Generate one immutable Trust action, a standard policy, and the SpecSync 5 SDD lifecycle while +leaving project-specific native verification in the Fledge verify lane. diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/docs.md b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/docs.md new file mode 100644 index 00000000..04285d15 --- /dev/null +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/docs.md @@ -0,0 +1,8 @@ +--- +change: CHG-0002-update-corvid-stack-template-for-trust-1 +artifact: docs +--- + +# Docs + +The template itself is the supported documentation and scaffold for new CorvidLabs projects. diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/plan.md b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/plan.md new file mode 100644 index 00000000..719c3516 --- /dev/null +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/plan.md @@ -0,0 +1,10 @@ +--- +change: CHG-0002-update-corvid-stack-template-for-trust-1 +artifact: plan +--- + +# Plan + +1. Replace the legacy template workflow with the immutable Trust 1 gate. +2. Add the SpecSync 5 lifecycle, version stamp, and standard Trust policy. +3. Validate the template and Fledge repository gates. diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/research.md b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/research.md new file mode 100644 index 00000000..08df1d15 --- /dev/null +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/research.md @@ -0,0 +1,9 @@ +--- +change: CHG-0002-update-corvid-stack-template-for-trust-1 +artifact: research +--- + +# Research + +Template validation confirms the generated project structure and required governance files without +executing a consumer release. diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json new file mode 100644 index 00000000..484ce630 --- /dev/null +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json @@ -0,0 +1,35 @@ +{ + "schema_version": 1, + "id": "CHG-0002-update-corvid-stack-template-for-trust-1", + "slug": "update-corvid-stack-template-for-trust-1", + "title": "Update Corvid stack template for Trust 1", + "description": "Update Corvid stack template for Trust 1", + "kind": "migration", + "state": "implementing", + "base_commit": "695ca94a54371e380be1ffbb603e3ee5cc387454", + "created_at": 1783831323, + "updated_at": 1783831395, + "affected_specs": [], + "affected_paths": [ + "templates/corvid-stack/" + ], + "no_spec_change": true, + "no_spec_change_rationale": "Template governance defaults do not change Fledge runtime behavior.", + "acceptance_criteria": [ + "The Corvid stack template emits SpecSync 5.0.1 SDD and the immutable Trust 1 workflow" + ], + "selected_artifacts": [ + "context", + "research", + "design", + "plan", + "tasks", + "testing", + "docs" + ], + "dependencies": [], + "answers": { + "architecture_risk": "no", + "public_contract": "no" + } +} diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/tasks.md b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/tasks.md new file mode 100644 index 00000000..33d4ae6c --- /dev/null +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/tasks.md @@ -0,0 +1,10 @@ +--- +change: CHG-0002-update-corvid-stack-template-for-trust-1 +artifact: tasks +--- + +# Tasks + +- [x] Generate the Trust 1 and SpecSync 5 template files. +- [x] Run strict template validation. +- [ ] Pass hosted pull-request checks. diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/testing.md b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/testing.md new file mode 100644 index 00000000..086085d7 --- /dev/null +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/testing.md @@ -0,0 +1,8 @@ +--- +change: CHG-0002-update-corvid-stack-template-for-trust-1 +artifact: testing +--- + +# Testing + +Run strict template validation, SpecSync strict validation, and the unified Trust gate. diff --git a/.specsync/sdd.json b/.specsync/sdd.json new file mode 100644 index 00000000..63033aa5 --- /dev/null +++ b/.specsync/sdd.json @@ -0,0 +1,40 @@ +{ + "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", + "templates/" + ], + "ignored_paths": [ + ".specsync/", + "specs/" + ], + "verification_commands": [ + "fledge lanes run verify" + ], + "custom_artifacts": {}, + "principles_file": null +} diff --git a/.trust.toml b/.trust.toml new file mode 100644 index 00000000..82c7ed80 --- /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 8aea8c0a..0886de51 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -366,3 +366,16 @@ If a command you want doesn't expose `--json`, or a workflow isn't automatable, 3. Implement, run `fledge lanes run pre-commit`, open the PR The project explicitly welcomes agent-surface improvements. + + +## CorvidLabs trust toolchain + +This repository uses one trust gate. Every session must use it and must not bypass or weaken it. + +- 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. + + diff --git a/fledge.toml b/fledge.toml index 21f96610..1a9ec128 100644 --- a/fledge.toml +++ b/fledge.toml @@ -19,6 +19,10 @@ description = "Validate all built-in templates" description = "Full CI pipeline" steps = ["fmt", "lint", "test", "build", "spec-check", "validate-templates"] +[lanes.verify] +description = "Required Trust gate for the Fledge repository" +steps = ["fmt", "lint", "test", "build", "spec-check", "validate-templates"] + [lanes.check] description = "Quick quality check" steps = [ diff --git a/specs/ai/requirements.md b/specs/ai/requirements.md index e4c2acfb..06009f1c 100644 --- a/specs/ai/requirements.md +++ b/specs/ai/requirements.md @@ -9,6 +9,56 @@ spec: ai.spec.md - As a user switching between local Ollama and Ollama Cloud, I want `fledge ai models` to show me exactly what my daemon reports via `/api/tags` — not a stale hardcoded list - As a user debugging "why did `fledge ask` pick this model?", I want `fledge ai status` to tell me not just what's active but *where* the value came from (env / config / default) +## Durable Requirements + +### REQ-ai-001 + +The implementation SHALL satisfy the following criterion: `fledge ai status` matches the provider/model/host that `llm::build_provider` would resolve; regression between the two is a tracked bug + +Acceptance Criteria + +- `fledge ai status` matches the provider/model/host that `llm::build_provider` would resolve; regression between the two is a tracked bug + +### REQ-ai-002 + +The implementation SHALL satisfy the following criterion: `fledge ai models --provider ollama --json` parses cleanly with `jq` and includes at least `name` per model + +Acceptance Criteria + +- `fledge ai models --provider ollama --json` parses cleanly with `jq` and includes at least `name` per model + +### REQ-ai-003 + +The implementation SHALL satisfy the following criterion: `fledge ai use ` writes `ai.provider` + per-provider `model` to `~/.config/fledge/config.toml` atomically + +Acceptance Criteria + +- `fledge ai use ` writes `ai.provider` + per-provider `model` to `~/.config/fledge/config.toml` atomically + +### REQ-ai-004 + +The implementation SHALL satisfy the following criterion: `fledge ai use` in `--non-interactive` without a provider arg errors via `utils::require_interactive` + +Acceptance Criteria + +- `fledge ai use` in `--non-interactive` without a provider arg errors via `utils::require_interactive` + +### REQ-ai-005 + +The implementation SHALL satisfy the following criterion: `fledge ai use ollama` interactively, with a running daemon, offers a Select with the live model list + +Acceptance Criteria + +- `fledge ai use ollama` interactively, with a running daemon, offers a Select with the live model list + +### REQ-ai-006 + +The implementation SHALL satisfy the following criterion: Unknown providers on any `--provider` flag reject at clap parse time (not at runtime) + +Acceptance Criteria + +- Unknown providers on any `--provider` flag reject at clap parse time (not at runtime) + ## Acceptance Criteria - `fledge ai status` matches the provider/model/host that `llm::build_provider` would resolve; regression between the two is a tracked bug diff --git a/specs/ask/requirements.md b/specs/ask/requirements.md index 33657126..c88da9d0 100644 --- a/specs/ask/requirements.md +++ b/specs/ask/requirements.md @@ -7,6 +7,48 @@ spec: ask.spec.md - As a developer, I want to run `fledge ask how does X work` to get an AI-powered answer about my codebase - As a developer, I want to type the question naturally without needing quotes +## Durable Requirements + +### REQ-ask-001 + +The implementation SHALL satisfy the following criterion: `fledge ask ` joins all trailing arguments into a single question + +Acceptance Criteria + +- `fledge ask ` joins all trailing arguments into a single question + +### REQ-ask-002 + +The implementation SHALL satisfy the following criterion: The question is sent to Claude CLI running in the current project directory + +Acceptance Criteria + +- The question is sent to Claude CLI running in the current project directory + +### REQ-ask-003 + +The implementation SHALL satisfy the following criterion: The response is streamed to stdout + +Acceptance Criteria + +- The response is streamed to stdout + +### REQ-ask-004 + +The implementation SHALL satisfy the following criterion: Missing Claude CLI produces install instructions + +Acceptance Criteria + +- Missing Claude CLI produces install instructions + +### REQ-ask-005 + +The implementation SHALL satisfy the following criterion: No question provided produces a usage hint + +Acceptance Criteria + +- No question provided produces a usage hint + ## Acceptance Criteria - `fledge ask ` joins all trailing arguments into a single question diff --git a/specs/changelog/requirements.md b/specs/changelog/requirements.md index 65f1f00e..f67ed16e 100644 --- a/specs/changelog/requirements.md +++ b/specs/changelog/requirements.md @@ -12,6 +12,72 @@ type: requirements 3. As a developer, I want JSON output so I can pipe changelog data to other tools. 4. As a developer, I want commits grouped by type so I can scan features vs fixes at a glance. +## Durable Requirements + +### REQ-changelog-001 + +The implementation SHALL satisfy the following criterion: `fledge changelog` shows all tagged releases with commits grouped by conventional commit type + +Acceptance Criteria + +- `fledge changelog` shows all tagged releases with commits grouped by conventional commit type + +### REQ-changelog-002 + +The implementation SHALL satisfy the following criterion: `fledge changelog --limit 3` shows only the 3 most recent releases + +Acceptance Criteria + +- `fledge changelog --limit 3` shows only the 3 most recent releases + +### REQ-changelog-003 + +The implementation SHALL satisfy the following criterion: `fledge changelog --tag v0.5.0` shows only that release + +Acceptance Criteria + +- `fledge changelog --tag v0.5.0` shows only that release + +### REQ-changelog-004 + +The implementation SHALL satisfy the following criterion: `fledge changelog --unreleased` shows commits since the latest tag + +Acceptance Criteria + +- `fledge changelog --unreleased` shows commits since the latest tag + +### REQ-changelog-005 + +The implementation SHALL satisfy the following criterion: `fledge changelog --json` outputs structured JSON + +Acceptance Criteria + +- `fledge changelog --json` outputs structured JSON + +### REQ-changelog-006 + +The implementation SHALL satisfy the following criterion: Merge commits are excluded + +Acceptance Criteria + +- Merge commits are excluded + +### REQ-changelog-007 + +The implementation SHALL satisfy the following criterion: Scoped commits (e.g., `fix(parser): msg`) are correctly parsed + +Acceptance Criteria + +- Scoped commits (e.g., `fix(parser): msg`) are correctly parsed + +### REQ-changelog-008 + +The implementation SHALL satisfy the following criterion: Non-conventional commits appear under "Other" + +Acceptance Criteria + +- Non-conventional commits appear under "Other" + ## Acceptance Criteria - `fledge changelog` shows all tagged releases with commits grouped by conventional commit type diff --git a/specs/config/requirements.md b/specs/config/requirements.md index 2d1f2e7c..d6e5ad09 100644 --- a/specs/config/requirements.md +++ b/specs/config/requirements.md @@ -9,6 +9,80 @@ spec: config.spec.md - As a user, I want to register remote template repos so they're discovered automatically during `fledge init` - As a user, I want to store my GitHub token in config so remote template fetching works without env vars +## Durable Requirements + +### REQ-config-001 + +The implementation SHALL satisfy the following criterion: `fledge config list` displays all configured values and empty list sections + +Acceptance Criteria + +- `fledge config list` displays all configured values and empty list sections + +### REQ-config-002 + +The implementation SHALL satisfy the following criterion: `fledge config get ` prints the value for any valid key (scalar or list) + +Acceptance Criteria + +- `fledge config get ` prints the value for any valid key (scalar or list) + +### REQ-config-003 + +The implementation SHALL satisfy the following criterion: `fledge config set ` persists scalar values to `config.toml` + +Acceptance Criteria + +- `fledge config set ` persists scalar values to `config.toml` + +### REQ-config-004 + +The implementation SHALL satisfy the following criterion: `fledge config unset ` removes values (clears lists for list keys) + +Acceptance Criteria + +- `fledge config unset ` removes values (clears lists for list keys) + +### REQ-config-005 + +The implementation SHALL satisfy the following criterion: `fledge config add ` appends to list keys with deduplication + +Acceptance Criteria + +- `fledge config add ` appends to list keys with deduplication + +### REQ-config-006 + +The implementation SHALL satisfy the following criterion: `fledge config remove ` removes from list keys and reports whether found + +Acceptance Criteria + +- `fledge config remove ` removes from list keys and reports whether found + +### REQ-config-007 + +The implementation SHALL satisfy the following criterion: Using `set` on a list key (or `add`/`remove` on a scalar key) produces a clear error with guidance + +Acceptance Criteria + +- Using `set` on a list key (or `add`/`remove` on a scalar key) produces a clear error with guidance + +### REQ-config-008 + +The implementation SHALL satisfy the following criterion: Config file is created on first write if it doesn't exist + +Acceptance Criteria + +- Config file is created on first write if it doesn't exist + +### REQ-config-009 + +The implementation SHALL satisfy the following criterion: Missing config file returns sensible defaults (MIT license, no author, empty lists) + +Acceptance Criteria + +- Missing config file returns sensible defaults (MIT license, no author, empty lists) + ## Acceptance Criteria - `fledge config list` displays all configured values and empty list sections diff --git a/specs/create_template/requirements.md b/specs/create_template/requirements.md index e618f440..390e95db 100644 --- a/specs/create_template/requirements.md +++ b/specs/create_template/requirements.md @@ -8,6 +8,64 @@ spec: create_template.spec.md - As a template author, I want example files showing Tera variable usage so I can learn by example - As a template author, I want to choose which features (hooks, prompts) my template uses so the manifest stays clean +## Durable Requirements + +### REQ-create-template-001 + +The implementation SHALL satisfy the following criterion: `fledge create-template my-template` creates a new directory with a valid template scaffold + +Acceptance Criteria + +- `fledge create-template my-template` creates a new directory with a valid template scaffold + +### REQ-create-template-002 + +The implementation SHALL satisfy the following criterion: Generated `template.toml` is valid TOML parseable as `TemplateManifest` + +Acceptance Criteria + +- Generated `template.toml` is valid TOML parseable as `TemplateManifest` + +### REQ-create-template-003 + +The implementation SHALL satisfy the following criterion: Interactive prompts ask for name, description, render globs, hooks, and custom prompts + +Acceptance Criteria + +- Interactive prompts ask for name, description, render globs, hooks, and custom prompts + +### REQ-create-template-004 + +The implementation SHALL satisfy the following criterion: All prompts have sensible defaults that can be accepted with Enter + +Acceptance Criteria + +- All prompts have sensible defaults that can be accepted with Enter + +### REQ-create-template-005 + +The implementation SHALL satisfy the following criterion: Includes example `.tera` file demonstrating variable substitution + +Acceptance Criteria + +- Includes example `.tera` file demonstrating variable substitution + +### REQ-create-template-006 + +The implementation SHALL satisfy the following criterion: Includes author-facing README with instructions for testing locally + +Acceptance Criteria + +- Includes author-facing README with instructions for testing locally + +### REQ-create-template-007 + +The implementation SHALL satisfy the following criterion: Fails with a clear error if the target directory already exists + +Acceptance Criteria + +- Fails with a clear error if the target directory already exists + ## Acceptance Criteria - `fledge create-template my-template` creates a new directory with a valid template scaffold diff --git a/specs/doctor/requirements.md b/specs/doctor/requirements.md index f935ece2..30965a9f 100644 --- a/specs/doctor/requirements.md +++ b/specs/doctor/requirements.md @@ -8,6 +8,56 @@ spec: doctor.spec.md - As a CI system, I want to run `fledge doctor --json` to get machine-readable health data - As a polyglot developer, I want a single command to inventory which language toolchains are installed without false-failing on languages my current project doesn't use +## Durable Requirements + +### REQ-doctor-001 + +The implementation SHALL satisfy the following criterion: `fledge doctor` reports four sections: `fledge`, `Git`, `AI`, `Toolchains` + +Acceptance Criteria + +- `fledge doctor` reports four sections: `fledge`, `Git`, `AI`, `Toolchains` + +### REQ-doctor-002 + +The implementation SHALL satisfy the following criterion: Each failing check in a non-informational section shows an actionable fix command + +Acceptance Criteria + +- Each failing check in a non-informational section shows an actionable fix command + +### REQ-doctor-003 + +The implementation SHALL satisfy the following criterion: The `Toolchains` section is informational — missing entries render dimmed and don't pollute the pass/fail totals + +Acceptance Criteria + +- The `Toolchains` section is informational — missing entries render dimmed and don't pollute the pass/fail totals + +### REQ-doctor-004 + +The implementation SHALL satisfy the following criterion: `--json` outputs a structured `DoctorReport` with all check results, including `informational: bool` per Section + +Acceptance Criteria + +- `--json` outputs a structured `DoctorReport` with all check results, including `informational: bool` per Section + +### REQ-doctor-005 + +The implementation SHALL satisfy the following criterion: Exit summary shows count of passed checks and issues found, computed only over non-informational sections + +Acceptance Criteria + +- Exit summary shows count of passed checks and issues found, computed only over non-informational sections + +### REQ-doctor-006 + +The implementation SHALL satisfy the following criterion: Toolchains probed: rustc, cargo, node, npm, pnpm, bun, yarn, python3, uv, poetry, go, ruby, swift, java, gradle, mvn + +Acceptance Criteria + +- Toolchains probed: rustc, cargo, node, npm, pnpm, bun, yarn, python3, uv, poetry, go, ruby, swift, java, gradle, mvn + ## Acceptance Criteria - `fledge doctor` reports four sections: `fledge`, `Git`, `AI`, `Toolchains` diff --git a/specs/envelope/requirements.md b/specs/envelope/requirements.md index 80681735..0c4b49d2 100644 --- a/specs/envelope/requirements.md +++ b/specs/envelope/requirements.md @@ -8,6 +8,64 @@ spec: envelope.spec.md - As a fledge developer, I want migrating a hand-rolled envelope to a helper to be a non-behavioral refactor, so I can adopt it without churning golden output - As a fledge developer, I want the envelope dialect chosen explicitly (resource / action / flat) rather than copy-pasted from a neighboring command +## Durable Requirements + +### REQ-envelope-001 + +The implementation SHALL satisfy the following criterion: `resource(schema_version, key, items)` builds `{schema_version, : items}` with no `action` key + +Acceptance Criteria + +- `resource(schema_version, key, items)` builds `{schema_version, : items}` with no `action` key + +### REQ-envelope-002 + +The implementation SHALL satisfy the following criterion: `action(schema_version, action, fields)` builds `{schema_version, action, ...fields}`, inserting the fixed keys first then merging an object `fields` + +Acceptance Criteria + +- `action(schema_version, action, fields)` builds `{schema_version, action, ...fields}`, inserting the fixed keys first then merging an object `fields` + +### REQ-envelope-003 + +The implementation SHALL satisfy the following criterion: `versioned(schema_version, fields)` builds `{schema_version, ...fields}` with no `action` key + +Acceptance Criteria + +- `versioned(schema_version, fields)` builds `{schema_version, ...fields}` with no `action` key + +### REQ-envelope-004 + +The implementation SHALL satisfy the following criterion: Every envelope carries a `schema_version` from the caller-supplied `u32` + +Acceptance Criteria + +- Every envelope carries a `schema_version` from the caller-supplied `u32` + +### REQ-envelope-005 + +The implementation SHALL satisfy the following criterion: Output is byte-for-byte identical to the equivalent hand-rolled `serde_json::json!` + +Acceptance Criteria + +- Output is byte-for-byte identical to the equivalent hand-rolled `serde_json::json!` + +### REQ-envelope-006 + +The implementation SHALL satisfy the following criterion: A non-object `fields` value contributes no extra keys; the envelope still carries its fixed keys + +Acceptance Criteria + +- A non-object `fields` value contributes no extra keys; the envelope still carries its fixed keys + +### REQ-envelope-007 + +The implementation SHALL satisfy the following criterion: Non-serializable `resource` items store `Value::Null` under the key instead of panicking + +Acceptance Criteria + +- Non-serializable `resource` items store `Value::Null` under the key instead of panicking + ## Acceptance Criteria - `resource(schema_version, key, items)` builds `{schema_version, : items}` with no `action` key diff --git a/specs/github/requirements.md b/specs/github/requirements.md index c8ef759c..04eedb8b 100644 --- a/specs/github/requirements.md +++ b/specs/github/requirements.md @@ -8,6 +8,88 @@ spec: github.spec.md - As a module author, I want `github_api_get` to handle authentication and error formatting so I can focus on business logic - As a developer, I want clear error messages when my token is missing or rate-limited +## Durable Requirements + +### REQ-github-001 + +The implementation SHALL satisfy the following criterion: `detect_repo` parses HTTPS remote URLs (`https://github.com/owner/repo.git`) + +Acceptance Criteria + +- `detect_repo` parses HTTPS remote URLs (`https://github.com/owner/repo.git`) + +### REQ-github-002 + +The implementation SHALL satisfy the following criterion: `detect_repo` parses SSH remote URLs (`git@github.com:owner/repo.git`) + +Acceptance Criteria + +- `detect_repo` parses SSH remote URLs (`git@github.com:owner/repo.git`) + +### REQ-github-003 + +The implementation SHALL satisfy the following criterion: `detect_repo` handles token-authenticated HTTPS URLs + +Acceptance Criteria + +- `detect_repo` handles token-authenticated HTTPS URLs + +### REQ-github-004 + +The implementation SHALL satisfy the following criterion: `detect_repo` strips trailing `.git` suffix + +Acceptance Criteria + +- `detect_repo` strips trailing `.git` suffix + +### REQ-github-005 + +The implementation SHALL satisfy the following criterion: `github_api_get` reads token from `FLEDGE_GITHUB_TOKEN`, `GITHUB_TOKEN`, or config + +Acceptance Criteria + +- `github_api_get` reads token from `FLEDGE_GITHUB_TOKEN`, `GITHUB_TOKEN`, or config + +### REQ-github-006 + +The implementation SHALL satisfy the following criterion: `github_api_get` returns parsed JSON on success + +Acceptance Criteria + +- `github_api_get` returns parsed JSON on success + +### REQ-github-007 + +The implementation SHALL satisfy the following criterion: 403 responses produce a message about setting a token + +Acceptance Criteria + +- 403 responses produce a message about setting a token + +### REQ-github-008 + +The implementation SHALL satisfy the following criterion: 404 responses produce a "Not found" error + +Acceptance Criteria + +- 404 responses produce a "Not found" error + +### REQ-github-009 + +The implementation SHALL satisfy the following criterion: `format_relative_time` converts ISO 8601 timestamps to human-readable relative times + +Acceptance Criteria + +- `format_relative_time` converts ISO 8601 timestamps to human-readable relative times + +### REQ-github-010 + +The implementation SHALL satisfy the following criterion: `format_relative_time` falls back to the raw string for unparseable input + +Acceptance Criteria + +- `format_relative_time` falls back to the raw string for unparseable input + ## Acceptance Criteria - `detect_repo` parses HTTPS remote URLs (`https://github.com/owner/repo.git`) diff --git a/specs/init/requirements.md b/specs/init/requirements.md index 78bdef42..521786d6 100644 --- a/specs/init/requirements.md +++ b/specs/init/requirements.md @@ -11,6 +11,96 @@ spec: init.spec.md - As a user, I want post-create hooks (like `npm install`) to run automatically for local templates - As a user, I want to be warned before remote templates execute hooks on my machine +## Durable Requirements + +### REQ-init-001 + +The implementation SHALL satisfy the following criterion: `fledge init ` creates a directory with rendered template files + +Acceptance Criteria + +- `fledge init ` creates a directory with rendered template files + +### REQ-init-002 + +The implementation SHALL satisfy the following criterion: `fledge init --template ` uses the specified template + +Acceptance Criteria + +- `fledge init --template ` uses the specified template + +### REQ-init-003 + +The implementation SHALL satisfy the following criterion: `fledge init --template owner/repo` fetches and uses a remote template + +Acceptance Criteria + +- `fledge init --template owner/repo` fetches and uses a remote template + +### REQ-init-004 + +The implementation SHALL satisfy the following criterion: Without `--template`, an interactive selector is shown + +Acceptance Criteria + +- Without `--template`, an interactive selector is shown + +### REQ-init-005 + +The implementation SHALL satisfy the following criterion: `--dry-run` prints file list, hooks, and git status without writing + +Acceptance Criteria + +- `--dry-run` prints file list, hooks, and git status without writing + +### REQ-init-006 + +The implementation SHALL satisfy the following criterion: `--no-git` skips git init and initial commit + +Acceptance Criteria + +- `--no-git` skips git init and initial commit + +### REQ-init-007 + +The implementation SHALL satisfy the following criterion: `--no-install` skips post-create hooks + +Acceptance Criteria + +- `--no-install` skips post-create hooks + +### REQ-init-008 + +The implementation SHALL satisfy the following criterion: `--yes` auto-confirms remote hook prompts + +Acceptance Criteria + +- `--yes` auto-confirms remote hook prompts + +### REQ-init-009 + +The implementation SHALL satisfy the following criterion: `--refresh` clears cached remote repos before fetching + +Acceptance Criteria + +- `--refresh` clears cached remote repos before fetching + +### REQ-init-010 + +The implementation SHALL satisfy the following criterion: If the target directory already exists, the command errors immediately + +Acceptance Criteria + +- If the target directory already exists, the command errors immediately + +### REQ-init-011 + +The implementation SHALL satisfy the following criterion: Git init includes an initial commit with all scaffolded files + +Acceptance Criteria + +- Git init includes an initial commit with all scaffolded files + ## Acceptance Criteria - `fledge init ` creates a directory with rendered template files diff --git a/specs/introspect/requirements.md b/specs/introspect/requirements.md index 7224ba2c..1f46e41d 100644 --- a/specs/introspect/requirements.md +++ b/specs/introspect/requirements.md @@ -8,6 +8,48 @@ spec: introspect.spec.md - As a tooling author (e.g. someone building a wrapper, a fledge-aware editor integration, or generating docs), I want a single structured source of truth for the command surface that changes automatically as the binary changes - As a human, I want a bird's-eye view of the whole command tree as a readable indented listing +## Durable Requirements + +### REQ-introspect-001 + +The implementation SHALL satisfy the following criterion: `fledge introspect --json` produces a single JSON object parseable by `serde_json::from_str` and `jq` + +Acceptance Criteria + +- `fledge introspect --json` produces a single JSON object parseable by `serde_json::from_str` and `jq` + +### REQ-introspect-002 + +The implementation SHALL satisfy the following criterion: `fledge introspect` without `--json` produces a human-readable indented tree + +Acceptance Criteria + +- `fledge introspect` without `--json` produces a human-readable indented tree + +### REQ-introspect-003 + +The implementation SHALL satisfy the following criterion: The output includes every user-facing subcommand and arg — no silent gaps + +Acceptance Criteria + +- The output includes every user-facing subcommand and arg — no silent gaps + +### REQ-introspect-004 + +The implementation SHALL satisfy the following criterion: clap's auto-generated `--help` and `--version` and `help` subcommand are excluded as noise + +Acceptance Criteria + +- clap's auto-generated `--help` and `--version` and `help` subcommand are excluded as noise + +### REQ-introspect-005 + +The implementation SHALL satisfy the following criterion: Subcommand aliases and global args are explicitly labeled in the output so agents can reason about them + +Acceptance Criteria + +- Subcommand aliases and global args are explicitly labeled in the output so agents can reason about them + ## Acceptance Criteria - `fledge introspect --json` produces a single JSON object parseable by `serde_json::from_str` and `jq` diff --git a/specs/lanes/requirements.md b/specs/lanes/requirements.md index 5e9a5690..a72ffd55 100644 --- a/specs/lanes/requirements.md +++ b/specs/lanes/requirements.md @@ -19,3 +19,117 @@ 1. Parallel groups must execute steps concurrently using threads 2. Lane execution must respect task dependency ordering within each step 3. `--json` flag must produce machine-parseable output for list operations + +## Durable Requirements + +### REQ-lanes-001 + +The implementation SHALL satisfy the following criterion: Define named workflow pipelines in `fledge.toml` under `[lanes]` + +Acceptance Criteria + +- Define named workflow pipelines in `fledge.toml` under `[lanes]` + +### REQ-lanes-002 + +The implementation SHALL satisfy the following criterion: Execute lanes as ordered sequences of steps + +Acceptance Criteria + +- Execute lanes as ordered sequences of steps + +### REQ-lanes-003 + +The implementation SHALL satisfy the following criterion: Support three step types: task references, inline commands, parallel groups + +Acceptance Criteria + +- Support three step types: task references, inline commands, parallel groups + +### REQ-lanes-004 + +The implementation SHALL satisfy the following criterion: Validate task references before execution + +Acceptance Criteria + +- Validate task references before execution + +### REQ-lanes-005 + +The implementation SHALL satisfy the following criterion: Support `fail_fast` flag to control failure behavior + +Acceptance Criteria + +- Support `fail_fast` flag to control failure behavior + +### REQ-lanes-006 + +The implementation SHALL satisfy the following criterion: Support `--dry-run` to preview execution plan + +Acceptance Criteria + +- Support `--dry-run` to preview execution plan + +### REQ-lanes-007 + +The implementation SHALL satisfy the following criterion: Support `--init` to scaffold default lanes for the detected language + +Acceptance Criteria + +- Support `--init` to scaffold default lanes for the detected language + +### REQ-lanes-008 + +The implementation SHALL satisfy the following criterion: List available lanes with descriptions + +Acceptance Criteria + +- List available lanes with descriptions + +### REQ-lanes-009 + +The implementation SHALL satisfy the following criterion: Scaffold a lane repo via `fledge lanes create ` with example fledge.toml, README, and .gitignore + +Acceptance Criteria + +- Scaffold a lane repo via `fledge lanes create ` with example fledge.toml, README, and .gitignore + +### REQ-lanes-010 + +The implementation SHALL satisfy the following criterion: Validate lane definitions via `fledge lanes validate [path]` — check task references, empty steps, circular deps, parallel groups + +Acceptance Criteria + +- Validate lane definitions via `fledge lanes validate [path]` — check task references, empty steps, circular deps, parallel groups + +### REQ-lanes-011 + +The implementation SHALL satisfy the following criterion: `publish` validates before pushing + +Acceptance Criteria + +- `publish` validates before pushing + +### REQ-lanes-012 + +The implementation SHALL satisfy the following criterion: Parallel groups must execute steps concurrently using threads + +Acceptance Criteria + +- Parallel groups must execute steps concurrently using threads + +### REQ-lanes-013 + +The implementation SHALL satisfy the following criterion: Lane execution must respect task dependency ordering within each step + +Acceptance Criteria + +- Lane execution must respect task dependency ordering within each step + +### REQ-lanes-014 + +The implementation SHALL satisfy the following criterion: `--json` flag must produce machine-parseable output for list operations + +Acceptance Criteria + +- `--json` flag must produce machine-parseable output for list operations diff --git a/specs/llm/requirements.md b/specs/llm/requirements.md index 5fb74e11..dcb4c166 100644 --- a/specs/llm/requirements.md +++ b/specs/llm/requirements.md @@ -9,6 +9,64 @@ spec: llm.spec.md - As an agent, I want to choose my provider per-invocation via `--provider` flag so I can mix local (cheap, fast) and cloud (stronger) per task - As a maintainer, I want the prompt composition in `ask` / `review` to remain provider-agnostic so adding a new provider is localized to one file +## Durable Requirements + +### REQ-llm-001 + +The implementation SHALL satisfy the following criterion: Default behavior (no config, no env, no flag) is identical to the pre-v0.13 Claude-CLI-only behavior + +Acceptance Criteria + +- Default behavior (no config, no env, no flag) is identical to the pre-v0.13 Claude-CLI-only behavior + +### REQ-llm-002 + +The implementation SHALL satisfy the following criterion: Setting `ai.provider = "ollama"` in config OR `FLEDGE_AI_PROVIDER=ollama` in env routes all AI commands through Ollama + +Acceptance Criteria + +- Setting `ai.provider = "ollama"` in config OR `FLEDGE_AI_PROVIDER=ollama` in env routes all AI commands through Ollama + +### REQ-llm-003 + +The implementation SHALL satisfy the following criterion: Per-invocation `--provider ollama` overrides both env and config + +Acceptance Criteria + +- Per-invocation `--provider ollama` overrides both env and config + +### REQ-llm-004 + +The implementation SHALL satisfy the following criterion: Model selection follows the same override > env > config > default precedence + +Acceptance Criteria + +- Model selection follows the same override > env > config > default precedence + +### REQ-llm-005 + +The implementation SHALL satisfy the following criterion: Ollama's HTTP request shape matches the `/api/generate` endpoint's published schema + +Acceptance Criteria + +- Ollama's HTTP request shape matches the `/api/generate` endpoint's published schema + +### REQ-llm-006 + +The implementation SHALL satisfy the following criterion: `fledge doctor` reports both providers and which is active + +Acceptance Criteria + +- `fledge doctor` reports both providers and which is active + +### REQ-llm-007 + +The implementation SHALL satisfy the following criterion: No regression: `fledge ask --json` and `fledge review --json` outputs remain parseable; payloads gain a `provider` and `model` field + +Acceptance Criteria + +- No regression: `fledge ask --json` and `fledge review --json` outputs remain parseable; payloads gain a `provider` and `model` field + ## Acceptance Criteria - Default behavior (no config, no env, no flag) is identical to the pre-v0.13 Claude-CLI-only behavior diff --git a/specs/main/requirements.md b/specs/main/requirements.md index 348c3a5b..0250e19f 100644 --- a/specs/main/requirements.md +++ b/specs/main/requirements.md @@ -2,3 +2,37 @@ - Dispatch each subcommand to its module's entry function - Forward unknown commands to installed plugins - Generate shell completions on demand + +## Durable Requirements + +### REQ-main-001 + +The implementation SHALL satisfy the following criterion: Parse CLI arguments via clap derive + +Acceptance Criteria + +- Parse CLI arguments via clap derive + +### REQ-main-002 + +The implementation SHALL satisfy the following criterion: Dispatch each subcommand to its module's entry function + +Acceptance Criteria + +- Dispatch each subcommand to its module's entry function + +### REQ-main-003 + +The implementation SHALL satisfy the following criterion: Forward unknown commands to installed plugins + +Acceptance Criteria + +- Forward unknown commands to installed plugins + +### REQ-main-004 + +The implementation SHALL satisfy the following criterion: Generate shell completions on demand + +Acceptance Criteria + +- Generate shell completions on demand diff --git a/specs/meta/requirements.md b/specs/meta/requirements.md index 4185b4e7..de2c26ee 100644 --- a/specs/meta/requirements.md +++ b/specs/meta/requirements.md @@ -9,6 +9,56 @@ spec: meta.spec.md - As a template author, I want the template variables used at scaffold time persisted so a project's configuration is inspectable - As a user, I don't want fledge's internal cache tracked by git after scaffolding +## Durable Requirements + +### REQ-meta-001 + +The implementation SHALL satisfy the following criterion: `write_project_meta` writes `.fledge/meta.toml` with `SourceInfo` provenance, string template variables, and a hash for each existing created file + +Acceptance Criteria + +- `write_project_meta` writes `.fledge/meta.toml` with `SourceInfo` provenance, string template variables, and a hash for each existing created file + +### REQ-meta-002 + +The implementation SHALL satisfy the following criterion: `compute_file_hash` returns a 64-character lowercase hex SHA-256 digest and is deterministic + +Acceptance Criteria + +- `compute_file_hash` returns a 64-character lowercase hex SHA-256 digest and is deterministic + +### REQ-meta-003 + +The implementation SHALL satisfy the following criterion: The `.fledge` directory is created if missing + +Acceptance Criteria + +- The `.fledge` directory is created if missing + +### REQ-meta-004 + +The implementation SHALL satisfy the following criterion: A `.fledge/.gitignore` is created if one does not already exist, and an existing one is never overwritten + +Acceptance Criteria + +- A `.fledge/.gitignore` is created if one does not already exist, and an existing one is never overwritten + +### REQ-meta-005 + +The implementation SHALL satisfy the following criterion: Created files that no longer exist on disk are silently skipped, not errored + +Acceptance Criteria + +- Created files that no longer exist on disk are silently skipped, not errored + +### REQ-meta-006 + +The implementation SHALL satisfy the following criterion: `fledge_version` is captured from `CARGO_PKG_VERSION` at compile time and `created` is the local date as `YYYY-MM-DD` + +Acceptance Criteria + +- `fledge_version` is captured from `CARGO_PKG_VERSION` at compile time and `created` is the local date as `YYYY-MM-DD` + ## Acceptance Criteria - `write_project_meta` writes `.fledge/meta.toml` with `SourceInfo` provenance, string template variables, and a hash for each existing created file diff --git a/specs/plugin/requirements.md b/specs/plugin/requirements.md index 0f8a2133..21b4a56a 100644 --- a/specs/plugin/requirements.md +++ b/specs/plugin/requirements.md @@ -21,3 +21,133 @@ 1. Plugin installation must be idempotent with `--force` flag 2. Plugin binaries must be discoverable via PATH or `plugins/bin/` 3. `--json` flag must produce machine-parseable output for all list/search operations + +## Durable Requirements + +### REQ-plugin-001 + +The implementation SHALL satisfy the following criterion: Install plugins from GitHub shorthand, generic git URLs, and local paths via `fledge plugins install ` + +Acceptance Criteria + +- Install plugins from GitHub shorthand, generic git URLs, and local paths via `fledge plugins install ` + +### REQ-plugin-002 + +The implementation SHALL satisfy the following criterion: Remove installed plugins via `fledge plugins remove ` + +Acceptance Criteria + +- Remove installed plugins via `fledge plugins remove ` + +### REQ-plugin-003 + +The implementation SHALL satisfy the following criterion: List installed plugins with metadata via `fledge plugins list` + +Acceptance Criteria + +- List installed plugins with metadata via `fledge plugins list` + +### REQ-plugin-004 + +The implementation SHALL satisfy the following criterion: Search for plugins on GitHub via `fledge plugins search ` + +Acceptance Criteria + +- Search for plugins on GitHub via `fledge plugins search ` + +### REQ-plugin-005 + +The implementation SHALL satisfy the following criterion: Run plugin commands as fledge subcommands + +Acceptance Criteria + +- Run plugin commands as fledge subcommands + +### REQ-plugin-006 + +The implementation SHALL satisfy the following criterion: Resolve plugin executables by name for CLI dispatch + +Acceptance Criteria + +- Resolve plugin executables by name for CLI dispatch + +### REQ-plugin-007 + +The implementation SHALL satisfy the following criterion: Support cross-platform symlink creation (Unix symlinks, Windows symlinks) + +Acceptance Criteria + +- Support cross-platform symlink creation (Unix symlinks, Windows symlinks) + +### REQ-plugin-008 + +The implementation SHALL satisfy the following criterion: Set executable permissions on plugin binaries (Unix only) + +Acceptance Criteria + +- Set executable permissions on plugin binaries (Unix only) + +### REQ-plugin-009 + +The implementation SHALL satisfy the following criterion: Scaffold a new plugin via `fledge plugins create ` with plugin.toml, bin/, README, and .gitignore + +Acceptance Criteria + +- Scaffold a new plugin via `fledge plugins create ` with plugin.toml, bin/, README, and .gitignore + +### REQ-plugin-010 + +The implementation SHALL satisfy the following criterion: Validate plugin manifests via `fledge plugins validate [path]` — check name, version, binary existence, command definitions + +Acceptance Criteria + +- Validate plugin manifests via `fledge plugins validate [path]` — check name, version, binary existence, command definitions + +### REQ-plugin-011 + +The implementation SHALL satisfy the following criterion: `publish` validates before pushing + +Acceptance Criteria + +- `publish` validates before pushing + +### REQ-plugin-012 + +The implementation SHALL satisfy the following criterion: Local path installs are live-linked by default and support `--copy` for snapshot installs + +Acceptance Criteria + +- Local path installs are live-linked by default and support `--copy` for snapshot installs + +### REQ-plugin-013 + +The implementation SHALL satisfy the following criterion: Removing a live-linked local plugin must not delete the original local source directory + +Acceptance Criteria + +- Removing a live-linked local plugin must not delete the original local source directory + +### REQ-plugin-014 + +The implementation SHALL satisfy the following criterion: Plugin installation must be idempotent with `--force` flag + +Acceptance Criteria + +- Plugin installation must be idempotent with `--force` flag + +### REQ-plugin-015 + +The implementation SHALL satisfy the following criterion: Plugin binaries must be discoverable via PATH or `plugins/bin/` + +Acceptance Criteria + +- Plugin binaries must be discoverable via PATH or `plugins/bin/` + +### REQ-plugin-016 + +The implementation SHALL satisfy the following criterion: `--json` flag must produce machine-parseable output for all list/search operations + +Acceptance Criteria + +- `--json` flag must produce machine-parseable output for all list/search operations diff --git a/specs/prompts/requirements.md b/specs/prompts/requirements.md index 19382dfd..e6275337 100644 --- a/specs/prompts/requirements.md +++ b/specs/prompts/requirements.md @@ -9,6 +9,64 @@ spec: prompts.spec.md - As a template author, I want to define custom prompts with optional defaults in `template.toml` - As a template author, I want prompt defaults to reference previously collected variables +## Durable Requirements + +### REQ-prompts-001 + +The implementation SHALL satisfy the following criterion: `select_template()` presents an interactive list with name and description columns + +Acceptance Criteria + +- `select_template()` presents an interactive list with name and description columns + +### REQ-prompts-002 + +The implementation SHALL satisfy the following criterion: `prompt_variables()` collects all core variables (project_name, author, github_org, license, year, date) and template-specific prompts + +Acceptance Criteria + +- `prompt_variables()` collects all core variables (project_name, author, github_org, license, year, date) and template-specific prompts + +### REQ-prompts-003 + +The implementation SHALL satisfy the following criterion: Author falls back: config → `git config user.name` → interactive prompt + +Acceptance Criteria + +- Author falls back: config → `git config user.name` → interactive prompt + +### REQ-prompts-004 + +The implementation SHALL satisfy the following criterion: GitHub org falls back: config → interactive prompt with "CorvidLabs" default + +Acceptance Criteria + +- GitHub org falls back: config → interactive prompt with "CorvidLabs" default + +### REQ-prompts-005 + +The implementation SHALL satisfy the following criterion: License is always pulled from config (defaults to MIT) + +Acceptance Criteria + +- License is always pulled from config (defaults to MIT) + +### REQ-prompts-006 + +The implementation SHALL satisfy the following criterion: Template-specific prompt defaults support Tera variable interpolation + +Acceptance Criteria + +- Template-specific prompt defaults support Tera variable interpolation + +### REQ-prompts-007 + +The implementation SHALL satisfy the following criterion: Case conversion produces correct snake_case and PascalCase variants + +Acceptance Criteria + +- Case conversion produces correct snake_case and PascalCase variants + ## Acceptance Criteria - `select_template()` presents an interactive list with name and description columns diff --git a/specs/publish/requirements.md b/specs/publish/requirements.md index a0e4d15e..f92ba2f8 100644 --- a/specs/publish/requirements.md +++ b/specs/publish/requirements.md @@ -16,3 +16,77 @@ This module is a library — its requirements describe the helpers it exposes. T 1. Synchronous HTTP via `ureq` — no async runtime 2. Token never reaches the process table or git config — passed via `http.extraheader` env injection only 3. No prompts in this module — caller decides whether to confirm + +## Durable Requirements + +### REQ-publish-001 + +The implementation SHALL satisfy the following criterion: Resolve the authenticated GitHub username from a token (`get_authenticated_user`) + +Acceptance Criteria + +- Resolve the authenticated GitHub username from a token (`get_authenticated_user`) + +### REQ-publish-002 + +The implementation SHALL satisfy the following criterion: Check whether a `/` exists on GitHub (`check_repo_exists`) — false on 404, error on other non-2xx + +Acceptance Criteria + +- Check whether a `/` exists on GitHub (`check_repo_exists`) — false on 404, error on other non-2xx + +### REQ-publish-003 + +The implementation SHALL satisfy the following criterion: Create a new GitHub repository under the user or an organization with optional private flag and description (`create_github_repo`) + +Acceptance Criteria + +- Create a new GitHub repository under the user or an organization with optional private flag and description (`create_github_repo`) + +### REQ-publish-004 + +The implementation SHALL satisfy the following criterion: Add a single topic to a repository's existing topic set, additively (`set_repo_topic`) + +Acceptance Criteria + +- Add a single topic to a repository's existing topic set, additively (`set_repo_topic`) + +### REQ-publish-005 + +The implementation SHALL satisfy the following criterion: Initialize git (if needed), commit working-tree contents, and force-push to `origin/main` using one-shot HTTP-Basic auth (`push_directory`) — token is never persisted in `.git/config` + +Acceptance Criteria + +- Initialize git (if needed), commit working-tree contents, and force-push to `origin/main` using one-shot HTTP-Basic auth (`push_directory`) — token is never persisted in `.git/config` + +### REQ-publish-006 + +The implementation SHALL satisfy the following criterion: Surface clear error messages for the common API failures: 422 (name conflict), 403 (insufficient scope) + +Acceptance Criteria + +- Surface clear error messages for the common API failures: 422 (name conflict), 403 (insufficient scope) + +### REQ-publish-007 + +The implementation SHALL satisfy the following criterion: Synchronous HTTP via `ureq` — no async runtime + +Acceptance Criteria + +- Synchronous HTTP via `ureq` — no async runtime + +### REQ-publish-008 + +The implementation SHALL satisfy the following criterion: Token never reaches the process table or git config — passed via `http.extraheader` env injection only + +Acceptance Criteria + +- Token never reaches the process table or git config — passed via `http.extraheader` env injection only + +### REQ-publish-009 + +The implementation SHALL satisfy the following criterion: No prompts in this module — caller decides whether to confirm + +Acceptance Criteria + +- No prompts in this module — caller decides whether to confirm diff --git a/specs/release/requirements.md b/specs/release/requirements.md index 9e13cdc2..06bd585e 100644 --- a/specs/release/requirements.md +++ b/specs/release/requirements.md @@ -10,3 +10,85 @@ 8. Support tag-only releases for languages without version files (Go, Swift) 9. Allow custom version files via [release] config in fledge.toml 10. Enforce clean working tree (with --allow-dirty override) + +## Durable Requirements + +### REQ-release-001 + +The implementation SHALL satisfy the following criterion: Bump version in language-specific files (Cargo.toml, package.json, pyproject.toml, etc.) + +Acceptance Criteria + +- Bump version in language-specific files (Cargo.toml, package.json, pyproject.toml, etc.) + +### REQ-release-002 + +The implementation SHALL satisfy the following criterion: Support semver bump levels: major, minor, patch, or explicit version + +Acceptance Criteria + +- Support semver bump levels: major, minor, patch, or explicit version + +### REQ-release-003 + +The implementation SHALL satisfy the following criterion: Auto-detect project language to find version files + +Acceptance Criteria + +- Auto-detect project language to find version files + +### REQ-release-004 + +The implementation SHALL satisfy the following criterion: Generate/update CHANGELOG.md from conventional commits since last tag + +Acceptance Criteria + +- Generate/update CHANGELOG.md from conventional commits since last tag + +### REQ-release-005 + +The implementation SHALL satisfy the following criterion: Create annotated git tags (vX.Y.Z) + +Acceptance Criteria + +- Create annotated git tags (vX.Y.Z) + +### REQ-release-006 + +The implementation SHALL satisfy the following criterion: Support dry-run mode that shows planned actions without changes + +Acceptance Criteria + +- Support dry-run mode that shows planned actions without changes + +### REQ-release-007 + +The implementation SHALL satisfy the following criterion: Support pre-release lane execution (run CI before releasing) + +Acceptance Criteria + +- Support pre-release lane execution (run CI before releasing) + +### REQ-release-008 + +The implementation SHALL satisfy the following criterion: Support tag-only releases for languages without version files (Go, Swift) + +Acceptance Criteria + +- Support tag-only releases for languages without version files (Go, Swift) + +### REQ-release-009 + +The implementation SHALL satisfy the following criterion: Allow custom version files via [release] config in fledge.toml + +Acceptance Criteria + +- Allow custom version files via [release] config in fledge.toml + +### REQ-release-010 + +The implementation SHALL satisfy the following criterion: Enforce clean working tree (with --allow-dirty override) + +Acceptance Criteria + +- Enforce clean working tree (with --allow-dirty override) diff --git a/specs/remote/requirements.md b/specs/remote/requirements.md index d653d62b..82e2261d 100644 --- a/specs/remote/requirements.md +++ b/specs/remote/requirements.md @@ -12,3 +12,61 @@ - Cache location follows platform conventions (XDG on Linux, Library/Caches on macOS) - Git operations should not leak tokens in stdout/stderr output + +## Durable Requirements + +### REQ-remote-001 + +The implementation SHALL satisfy the following criterion: Clone GitHub repos to local cache for template discovery + +Acceptance Criteria + +- Clone GitHub repos to local cache for template discovery + +### REQ-remote-002 + +The implementation SHALL satisfy the following criterion: Support authenticated access via GitHub token + +Acceptance Criteria + +- Support authenticated access via GitHub token + +### REQ-remote-003 + +The implementation SHALL satisfy the following criterion: Support `owner/repo` and `owner/repo/subpath` reference formats + +Acceptance Criteria + +- Support `owner/repo` and `owner/repo/subpath` reference formats + +### REQ-remote-004 + +The implementation SHALL satisfy the following criterion: Update cached repos on subsequent access + +Acceptance Criteria + +- Update cached repos on subsequent access + +### REQ-remote-005 + +The implementation SHALL satisfy the following criterion: Shallow clones (`--depth 1`) to minimize bandwidth + +Acceptance Criteria + +- Shallow clones (`--depth 1`) to minimize bandwidth + +### REQ-remote-006 + +The implementation SHALL satisfy the following criterion: Cache location follows platform conventions (XDG on Linux, Library/Caches on macOS) + +Acceptance Criteria + +- Cache location follows platform conventions (XDG on Linux, Library/Caches on macOS) + +### REQ-remote-007 + +The implementation SHALL satisfy the following criterion: Git operations should not leak tokens in stdout/stderr output + +Acceptance Criteria + +- Git operations should not leak tokens in stdout/stderr output diff --git a/specs/review/requirements.md b/specs/review/requirements.md index 37ae866d..ef34f9e0 100644 --- a/specs/review/requirements.md +++ b/specs/review/requirements.md @@ -8,6 +8,56 @@ spec: review.spec.md - As a developer, I want to review changes against a specific base branch - As a developer, I want to review a single file's changes +## Durable Requirements + +### REQ-review-001 + +The implementation SHALL satisfy the following criterion: `fledge review` diffs the current branch against the default base (main/master) and sends it to Claude CLI + +Acceptance Criteria + +- `fledge review` diffs the current branch against the default base (main/master) and sends it to Claude CLI + +### REQ-review-002 + +The implementation SHALL satisfy the following criterion: `fledge review --base develop` uses a custom base branch + +Acceptance Criteria + +- `fledge review --base develop` uses a custom base branch + +### REQ-review-003 + +The implementation SHALL satisfy the following criterion: `fledge review --file src/foo.rs` restricts the review to one file + +Acceptance Criteria + +- `fledge review --file src/foo.rs` restricts the review to one file + +### REQ-review-004 + +The implementation SHALL satisfy the following criterion: Diff stats are displayed before the AI output + +Acceptance Criteria + +- Diff stats are displayed before the AI output + +### REQ-review-005 + +The implementation SHALL satisfy the following criterion: Empty diffs bail with a clear message + +Acceptance Criteria + +- Empty diffs bail with a clear message + +### REQ-review-006 + +The implementation SHALL satisfy the following criterion: Missing Claude CLI produces install instructions + +Acceptance Criteria + +- Missing Claude CLI produces install instructions + ## Acceptance Criteria - `fledge review` diffs the current branch against the default base (main/master) and sends it to Claude CLI diff --git a/specs/run/requirements.md b/specs/run/requirements.md index ae743420..0347d500 100644 --- a/specs/run/requirements.md +++ b/specs/run/requirements.md @@ -9,6 +9,64 @@ spec: run.spec.md - As a developer, I want to see all available tasks with `fledge run --list` - As a developer, I want `fledge run --init` to generate a starter task file for my project type +## Durable Requirements + +### REQ-run-001 + +The implementation SHALL satisfy the following criterion: `fledge run ` executes the named task from `fledge.toml` + +Acceptance Criteria + +- `fledge run ` executes the named task from `fledge.toml` + +### REQ-run-002 + +The implementation SHALL satisfy the following criterion: Task dependencies run in topological order before the requested task + +Acceptance Criteria + +- Task dependencies run in topological order before the requested task + +### REQ-run-003 + +The implementation SHALL satisfy the following criterion: Circular dependencies produce an error listing the cycle + +Acceptance Criteria + +- Circular dependencies produce an error listing the cycle + +### REQ-run-004 + +The implementation SHALL satisfy the following criterion: `fledge run --list` shows task names and descriptions + +Acceptance Criteria + +- `fledge run --list` shows task names and descriptions + +### REQ-run-005 + +The implementation SHALL satisfy the following criterion: `fledge run --init` generates `fledge.toml` with defaults for the detected project type + +Acceptance Criteria + +- `fledge run --init` generates `fledge.toml` with defaults for the detected project type + +### REQ-run-006 + +The implementation SHALL satisfy the following criterion: Unknown task names produce an error listing available tasks + +Acceptance Criteria + +- Unknown task names produce an error listing available tasks + +### REQ-run-007 + +The implementation SHALL satisfy the following criterion: Tasks support environment variables and working directory overrides + +Acceptance Criteria + +- Tasks support environment variables and working directory overrides + ## Acceptance Criteria - `fledge run ` executes the named task from `fledge.toml` diff --git a/specs/search/requirements.md b/specs/search/requirements.md index d5e7db43..26bebe82 100644 --- a/specs/search/requirements.md +++ b/specs/search/requirements.md @@ -15,3 +15,69 @@ This module is a library — its requirements are about the helpers it exposes. 1. **NFR-1**: No async runtime dependency — callers use the blocking `ureq` client 2. **NFR-2**: No `serde` round-trip for the API response — direct `serde_json::Value` indexing keeps the dependency surface minimal + +## Durable Requirements + +### REQ-search-001 + +The implementation SHALL satisfy the following criterion: **FR-1**: Build a GitHub Search query string from `(topic, optional keyword, optional author)` — works for any topic, not just `fledge-template` + +Acceptance Criteria + +- **FR-1**: Build a GitHub Search query string from `(topic, optional keyword, optional author)` — works for any topic, not just `fledge-template` + +### REQ-search-002 + +The implementation SHALL satisfy the following criterion: **FR-2**: Parse a GitHub Search API response into a typed `Vec` with `(owner, name, description, stars, url, topics)` + +Acceptance Criteria + +- **FR-2**: Parse a GitHub Search API response into a typed `Vec` with `(owner, name, description, stars, url, topics)` + +### REQ-search-003 + +The implementation SHALL satisfy the following criterion: **FR-3**: Tolerate missing fields in the API response (description → "No description", stars → 0, topics → empty) + +Acceptance Criteria + +- **FR-3**: Tolerate missing fields in the API response (description → "No description", stars → 0, topics → empty) + +### REQ-search-004 + +The implementation SHALL satisfy the following criterion: **FR-4**: Format star counts compactly (`42`, `1.5k`, `123k`) + +Acceptance Criteria + +- **FR-4**: Format star counts compactly (`42`, `1.5k`, `123k`) + +### REQ-search-005 + +The implementation SHALL satisfy the following criterion: **FR-5**: Percent-encode strings for URL query parameters per RFC 3986 + +Acceptance Criteria + +- **FR-5**: Percent-encode strings for URL query parameters per RFC 3986 + +### REQ-search-006 + +The implementation SHALL satisfy the following criterion: **FR-6**: Skip items with no `owner.login` rather than failing the whole parse + +Acceptance Criteria + +- **FR-6**: Skip items with no `owner.login` rather than failing the whole parse + +### REQ-search-007 + +The implementation SHALL satisfy the following criterion: **NFR-1**: No async runtime dependency — callers use the blocking `ureq` client + +Acceptance Criteria + +- **NFR-1**: No async runtime dependency — callers use the blocking `ureq` client + +### REQ-search-008 + +The implementation SHALL satisfy the following criterion: **NFR-2**: No `serde` round-trip for the API response — direct `serde_json::Value` indexing keeps the dependency surface minimal + +Acceptance Criteria + +- **NFR-2**: No `serde` round-trip for the API response — direct `serde_json::Value` indexing keeps the dependency surface minimal diff --git a/specs/spec/requirements.md b/specs/spec/requirements.md index 4478f8be..bc960a51 100644 --- a/specs/spec/requirements.md +++ b/specs/spec/requirements.md @@ -9,6 +9,72 @@ spec: spec.spec.md - As a developer, I want `fledge spec new auth` to scaffold a complete spec module with companion files - As a developer, I want `--strict` mode to treat warnings as errors in CI +## Durable Requirements + +### REQ-spec-001 + +The implementation SHALL satisfy the following criterion: `fledge spec check` validates all specs in the configured specs directory + +Acceptance Criteria + +- `fledge spec check` validates all specs in the configured specs directory + +### REQ-spec-002 + +The implementation SHALL satisfy the following criterion: `fledge spec check --strict` treats warnings as errors + +Acceptance Criteria + +- `fledge spec check --strict` treats warnings as errors + +### REQ-spec-003 + +The implementation SHALL satisfy the following criterion: `fledge spec init` creates `.specsync/` with config.toml, registry.toml, .gitignore, and version + +Acceptance Criteria + +- `fledge spec init` creates `.specsync/` with config.toml, registry.toml, .gitignore, and version + +### REQ-spec-004 + +The implementation SHALL satisfy the following criterion: `fledge spec init` creates `specs/` directory if it doesn't exist + +Acceptance Criteria + +- `fledge spec init` creates `specs/` directory if it doesn't exist + +### REQ-spec-005 + +The implementation SHALL satisfy the following criterion: `fledge spec new ` creates `specs//` with spec.md and companion files + +Acceptance Criteria + +- `fledge spec new ` creates `specs//` with spec.md and companion files + +### REQ-spec-006 + +The implementation SHALL satisfy the following criterion: Validation checks: frontmatter fields, required sections, source file existence + +Acceptance Criteria + +- Validation checks: frontmatter fields, required sections, source file existence + +### REQ-spec-007 + +The implementation SHALL satisfy the following criterion: Exit code 1 on errors (or warnings in strict mode), 0 otherwise + +Acceptance Criteria + +- Exit code 1 on errors (or warnings in strict mode), 0 otherwise + +### REQ-spec-008 + +The implementation SHALL satisfy the following criterion: Colored output with checkmarks/crosses for each spec + +Acceptance Criteria + +- Colored output with checkmarks/crosses for each spec + ## Acceptance Criteria - `fledge spec check` validates all specs in the configured specs directory diff --git a/specs/spinner/requirements.md b/specs/spinner/requirements.md index 0afe5efe..338b852a 100644 --- a/specs/spinner/requirements.md +++ b/specs/spinner/requirements.md @@ -7,6 +7,40 @@ spec: spinner.spec.md - As a user, I want visual feedback during long-running operations so I know the CLI hasn't frozen - As a user, I want the spinner to clean up after itself so my terminal isn't cluttered +## Durable Requirements + +### REQ-spinner-001 + +The implementation SHALL satisfy the following criterion: `Spinner::start(msg)` displays an animated spinner with the given message + +Acceptance Criteria + +- `Spinner::start(msg)` displays an animated spinner with the given message + +### REQ-spinner-002 + +The implementation SHALL satisfy the following criterion: `Spinner::finish()` clears the spinner line completely + +Acceptance Criteria + +- `Spinner::finish()` clears the spinner line completely + +### REQ-spinner-003 + +The implementation SHALL satisfy the following criterion: A random theme is chosen each time a spinner starts + +Acceptance Criteria + +- A random theme is chosen each time a spinner starts + +### REQ-spinner-004 + +The implementation SHALL satisfy the following criterion: All themes animate smoothly without visual glitches + +Acceptance Criteria + +- All themes animate smoothly without visual glitches + ## Acceptance Criteria - `Spinner::start(msg)` displays an animated spinner with the given message diff --git a/specs/templates/requirements.md b/specs/templates/requirements.md index c4b1dc99..a0d43989 100644 --- a/specs/templates/requirements.md +++ b/specs/templates/requirements.md @@ -11,6 +11,104 @@ spec: templates.spec.md - As a template author, I want `.tera` files to always be rendered with the extension stripped - As a template author, I want to use template variables in file and directory names +## Durable Requirements + +### REQ-templates-001 + +The implementation SHALL satisfy the following criterion: `discover_templates()` finds all built-in templates (8 language starters: `go-cli`, `kotlin-kmp`, `kotlin-ktor-api`, `python-cli`, `rust-cli`, `static-site`, `ts-bun`, `ts-node`; plus setup-only `fledge-plugin` and `corvid-stack`) + +Acceptance Criteria + +- `discover_templates()` finds all built-in templates (8 language starters: `go-cli`, `kotlin-kmp`, `kotlin-ktor-api`, `python-cli`, `rust-cli`, `static-site`, `ts-bun`, `ts-node`; plus setup-only `fledge-plugin` and `corvid-stack`) + +### REQ-templates-002 + +The implementation SHALL satisfy the following criterion: Extra paths from config are searched for template directories + +Acceptance Criteria + +- Extra paths from config are searched for template directories + +### REQ-templates-003 + +The implementation SHALL satisfy the following criterion: Remote repos from config are fetched and searched for templates + +Acceptance Criteria + +- Remote repos from config are fetched and searched for templates + +### REQ-templates-004 + +The implementation SHALL satisfy the following criterion: Templates are returned sorted alphabetically by name + +Acceptance Criteria + +- Templates are returned sorted alphabetically by name + +### REQ-templates-005 + +The implementation SHALL satisfy the following criterion: Directories without `template.toml` are silently skipped + +Acceptance Criteria + +- Directories without `template.toml` are silently skipped + +### REQ-templates-006 + +The implementation SHALL satisfy the following criterion: Non-existent extra paths are silently skipped + +Acceptance Criteria + +- Non-existent extra paths are silently skipped + +### REQ-templates-007 + +The implementation SHALL satisfy the following criterion: `render_template()` renders `.tera` files and strips the extension + +Acceptance Criteria + +- `render_template()` renders `.tera` files and strips the extension + +### REQ-templates-008 + +The implementation SHALL satisfy the following criterion: `render_template()` renders files matching `files.render` globs + +Acceptance Criteria + +- `render_template()` renders files matching `files.render` globs + +### REQ-templates-009 + +The implementation SHALL satisfy the following criterion: `render_template()` copies non-matching files as-is + +Acceptance Criteria + +- `render_template()` copies non-matching files as-is + +### REQ-templates-010 + +The implementation SHALL satisfy the following criterion: `render_template()` skips files matching `files.ignore` globs + +Acceptance Criteria + +- `render_template()` skips files matching `files.ignore` globs + +### REQ-templates-011 + +The implementation SHALL satisfy the following criterion: `render_template()` renders Tera variables in file/directory paths + +Acceptance Criteria + +- `render_template()` renders Tera variables in file/directory paths + +### REQ-templates-012 + +The implementation SHALL satisfy the following criterion: Created files list is returned sorted alphabetically + +Acceptance Criteria + +- Created files list is returned sorted alphabetically + ## Acceptance Criteria - `discover_templates()` finds all built-in templates (8 language starters: `go-cli`, `kotlin-kmp`, `kotlin-ktor-api`, `python-cli`, `rust-cli`, `static-site`, `ts-bun`, `ts-node`; plus setup-only `fledge-plugin` and `corvid-stack`) diff --git a/specs/trust/requirements.md b/specs/trust/requirements.md index 5bd2f85c..30bebb26 100644 --- a/specs/trust/requirements.md +++ b/specs/trust/requirements.md @@ -7,6 +7,72 @@ spec: trust.spec.md - As a user installing plugins/templates/lanes, I want to see whether the source is local, official, team, or unverified so I can make informed trust decisions - As a module author, I want a shared trust classification function so all extension types use consistent logic +## Durable Requirements + +### REQ-trust-001 + +The implementation SHALL satisfy the following criterion: `determine_trust_tier` classifies `CorvidLabs/*` sources as Official + +Acceptance Criteria + +- `determine_trust_tier` classifies `CorvidLabs/*` sources as Official + +### REQ-trust-002 + +The implementation SHALL satisfy the following criterion: `determine_trust_tier` classifies filesystem path sources as Local + +Acceptance Criteria + +- `determine_trust_tier` classifies filesystem path sources as Local + +### REQ-trust-003 + +The implementation SHALL satisfy the following criterion: `determine_trust_tier` classifies sources owned by a human member of the CorvidLabs org (e.g. `0xLeif/*`) as Team + +Acceptance Criteria + +- `determine_trust_tier` classifies sources owned by a human member of the CorvidLabs org (e.g. `0xLeif/*`) as Team + +### REQ-trust-004 + +The implementation SHALL satisfy the following criterion: `determine_trust_tier` classifies all other sources as Unverified + +Acceptance Criteria + +- `determine_trust_tier` classifies all other sources as Unverified + +### REQ-trust-005 + +The implementation SHALL satisfy the following criterion: Supports local paths, HTTPS URLs, SSH URLs, and `owner/repo` shorthand + +Acceptance Criteria + +- Supports local paths, HTTPS URLs, SSH URLs, and `owner/repo` shorthand + +### REQ-trust-006 + +The implementation SHALL satisfy the following criterion: `parse_source_ref` splits `source@ref` without false-splitting on credential `@` signs + +Acceptance Criteria + +- `parse_source_ref` splits `source@ref` without false-splitting on credential `@` signs + +### REQ-trust-007 + +The implementation SHALL satisfy the following criterion: `label` returns lowercase string representation + +Acceptance Criteria + +- `label` returns lowercase string representation + +### REQ-trust-008 + +The implementation SHALL satisfy the following criterion: `styled_label` returns colored console output (magenta=local, green=official, cyan=team, yellow=unverified) + +Acceptance Criteria + +- `styled_label` returns colored console output (magenta=local, green=official, cyan=team, yellow=unverified) + ## Acceptance Criteria - `determine_trust_tier` classifies `CorvidLabs/*` sources as Official diff --git a/specs/utils/requirements.md b/specs/utils/requirements.md index 96e70659..26d8da15 100644 --- a/specs/utils/requirements.md +++ b/specs/utils/requirements.md @@ -10,6 +10,80 @@ spec: utils.spec.md - As a security-conscious maintainer, I want project names, GitHub orgs, and commit scopes validated before they reach the filesystem or an LLM prompt - As a user, I want credentials scrubbed out of error messages so tokens never leak into logs or terminal output +## Durable Requirements + +### REQ-utils-001 + +The implementation SHALL satisfy the following criterion: `set_non_interactive` / `is_non_interactive` are the only accessors to the global flag + +Acceptance Criteria + +- `set_non_interactive` / `is_non_interactive` are the only accessors to the global flag + +### REQ-utils-002 + +The implementation SHALL satisfy the following criterion: `init_non_interactive_from_env` flips the flag when `FLEDGE_NON_INTERACTIVE` is a truthy value (`1`/`true`/`yes`/`y`/`on`, case-insensitive, trimmed) + +Acceptance Criteria + +- `init_non_interactive_from_env` flips the flag when `FLEDGE_NON_INTERACTIVE` is a truthy value (`1`/`true`/`yes`/`y`/`on`, case-insensitive, trimmed) + +### REQ-utils-003 + +The implementation SHALL satisfy the following criterion: `is_interactive` returns true only when stdin is a TTY and the non-interactive flag is unset + +Acceptance Criteria + +- `is_interactive` returns true only when stdin is a TTY and the non-interactive flag is unset + +### REQ-utils-004 + +The implementation SHALL satisfy the following criterion: `require_interactive` / `require_interactive_hint` return `Ok(())` only when `is_interactive`, otherwise bail with a flag- or hint-named error + +Acceptance Criteria + +- `require_interactive` / `require_interactive_hint` return `Ok(())` only when `is_interactive`, otherwise bail with a flag- or hint-named error + +### REQ-utils-005 + +The implementation SHALL satisfy the following criterion: Case conversions are pure and total — any input (including empty) returns a `String` without panicking + +Acceptance Criteria + +- Case conversions are pure and total — any input (including empty) returns a `String` without panicking + +### REQ-utils-006 + +The implementation SHALL satisfy the following criterion: `validate_project_name` rejects empty strings, `/`, `\`, `..`, null bytes, and Windows-reserved device names + +Acceptance Criteria + +- `validate_project_name` rejects empty strings, `/`, `\`, `..`, null bytes, and Windows-reserved device names + +### REQ-utils-007 + +The implementation SHALL satisfy the following criterion: `validate_github_org` rejects empty and slash-containing names but permits spaces + +Acceptance Criteria + +- `validate_github_org` rejects empty and slash-containing names but permits spaces + +### REQ-utils-008 + +The implementation SHALL satisfy the following criterion: `validate_commit_scope` requires non-empty, ≤64 chars, ASCII alphanumerics plus `-`/`_` + +Acceptance Criteria + +- `validate_commit_scope` requires non-empty, ≤64 chars, ASCII alphanumerics plus `-`/`_` + +### REQ-utils-009 + +The implementation SHALL satisfy the following criterion: `redact_secrets` scrubs Authorization / x-access-token headers, URL credentials, and Bearer tokens; clean input passes through byte-identical + +Acceptance Criteria + +- `redact_secrets` scrubs Authorization / x-access-token headers, URL credentials, and Bearer tokens; clean input passes through byte-identical + ## Acceptance Criteria - `set_non_interactive` / `is_non_interactive` are the only accessors to the global flag diff --git a/specs/validate/requirements.md b/specs/validate/requirements.md index 05b735c3..ed125613 100644 --- a/specs/validate/requirements.md +++ b/specs/validate/requirements.md @@ -8,6 +8,48 @@ spec: validate.spec.md - As a CI pipeline, I want to validate templates in strict mode so broken templates don't get merged - As a developer, I want machine-readable validation output so I can integrate it into tooling +## Durable Requirements + +### REQ-validate-001 + +The implementation SHALL satisfy the following criterion: Single template validation checks manifest, Tera syntax, variable definitions, and render globs + +Acceptance Criteria + +- Single template validation checks manifest, Tera syntax, variable definitions, and render globs + +### REQ-validate-002 + +The implementation SHALL satisfy the following criterion: Batch validation validates all templates in a directory independently + +Acceptance Criteria + +- Batch validation validates all templates in a directory independently + +### REQ-validate-003 + +The implementation SHALL satisfy the following criterion: Strict mode exits non-zero on warnings + +Acceptance Criteria + +- Strict mode exits non-zero on warnings + +### REQ-validate-004 + +The implementation SHALL satisfy the following criterion: JSON mode outputs structured ValidationReport array + +Acceptance Criteria + +- JSON mode outputs structured ValidationReport array + +### REQ-validate-005 + +The implementation SHALL satisfy the following criterion: GitHub Actions `${{ }}` expressions are not flagged as Tera variables + +Acceptance Criteria + +- GitHub Actions `${{ }}` expressions are not flagged as Tera variables + ## Acceptance Criteria - Single template validation checks manifest, Tera syntax, variable definitions, and render globs diff --git a/specs/versioning/requirements.md b/specs/versioning/requirements.md index b5900ca5..2a06ac5e 100644 --- a/specs/versioning/requirements.md +++ b/specs/versioning/requirements.md @@ -5,3 +5,45 @@ 3. Check `min_fledge_version` against compile-time fledge version 4. Return actionable error messages with upgrade instructions 5. Handle optional leading `v` prefix (v1.2.3 → 1.2.3) + +## Durable Requirements + +### REQ-versioning-001 + +The implementation SHALL satisfy the following criterion: Parse semver strings (MAJOR.MINOR.PATCH) + +Acceptance Criteria + +- Parse semver strings (MAJOR.MINOR.PATCH) + +### REQ-versioning-002 + +The implementation SHALL satisfy the following criterion: Compare versions correctly (0.2.1 > 0.2.0, 1.0.0 > 0.99.99) + +Acceptance Criteria + +- Compare versions correctly (0.2.1 > 0.2.0, 1.0.0 > 0.99.99) + +### REQ-versioning-003 + +The implementation SHALL satisfy the following criterion: Check `min_fledge_version` against compile-time fledge version + +Acceptance Criteria + +- Check `min_fledge_version` against compile-time fledge version + +### REQ-versioning-004 + +The implementation SHALL satisfy the following criterion: Return actionable error messages with upgrade instructions + +Acceptance Criteria + +- Return actionable error messages with upgrade instructions + +### REQ-versioning-005 + +The implementation SHALL satisfy the following criterion: Handle optional leading `v` prefix (v1.2.3 → 1.2.3) + +Acceptance Criteria + +- Handle optional leading `v` prefix (v1.2.3 → 1.2.3) diff --git a/specs/watch/requirements.md b/specs/watch/requirements.md index 54ed66d0..efd15a47 100644 --- a/specs/watch/requirements.md +++ b/specs/watch/requirements.md @@ -12,3 +12,69 @@ spec: watch.spec.md - Perform an initial run before entering the watch loop - Optional terminal clear before each re-run - Graceful error handling — target failures don't stop the watcher + +## Durable Requirements + +### REQ-watch-001 + +The implementation SHALL satisfy the following criterion: Watch a directory recursively for filesystem changes + +Acceptance Criteria + +- Watch a directory recursively for filesystem changes + +### REQ-watch-002 + +The implementation SHALL satisfy the following criterion: Re-run a specified task or lane when relevant files change + +Acceptance Criteria + +- Re-run a specified task or lane when relevant files change + +### REQ-watch-003 + +The implementation SHALL satisfy the following criterion: Filter events by file extension (optional) + +Acceptance Criteria + +- Filter events by file extension (optional) + +### REQ-watch-004 + +The implementation SHALL satisfy the following criterion: Ignore common non-source directories (.git, target, node_modules, .fledge, __pycache__) + +Acceptance Criteria + +- Ignore common non-source directories (.git, target, node_modules, .fledge, __pycache__) + +### REQ-watch-005 + +The implementation SHALL satisfy the following criterion: Configurable debounce interval with deadline extension on new events + +Acceptance Criteria + +- Configurable debounce interval with deadline extension on new events + +### REQ-watch-006 + +The implementation SHALL satisfy the following criterion: Perform an initial run before entering the watch loop + +Acceptance Criteria + +- Perform an initial run before entering the watch loop + +### REQ-watch-007 + +The implementation SHALL satisfy the following criterion: Optional terminal clear before each re-run + +Acceptance Criteria + +- Optional terminal clear before each re-run + +### REQ-watch-008 + +The implementation SHALL satisfy the following criterion: Graceful error handling — target failures don't stop the watcher + +Acceptance Criteria + +- Graceful error handling — target failures don't stop the watcher diff --git a/specs/work/requirements.md b/specs/work/requirements.md index 80615d9a..fe4211f0 100644 --- a/specs/work/requirements.md +++ b/specs/work/requirements.md @@ -14,6 +14,160 @@ spec: work.spec.md - As a developer, I want `fledge work push` to push my branch to origin with tracking - As a developer, I want `fledge work status` to see my branch state (ahead/behind, dirty files) +## Durable Requirements + +### REQ-work-001 + +The implementation SHALL satisfy the following criterion: `fledge work start ` creates a branch using the configured format (default: `{author}/{type}/{name}`) + +Acceptance Criteria + +- `fledge work start ` creates a branch using the configured format (default: `{author}/{type}/{name}`) + +### REQ-work-002 + +The implementation SHALL satisfy the following criterion: `fledge work start --branch-type fix` creates a fix-type branch + +Acceptance Criteria + +- `fledge work start --branch-type fix` creates a fix-type branch + +### REQ-work-003 + +The implementation SHALL satisfy the following criterion: `fledge work start --issue 42` includes issue number in branch name + +Acceptance Criteria + +- `fledge work start --issue 42` includes issue number in branch name + +### REQ-work-004 + +The implementation SHALL satisfy the following criterion: `fledge work start --prefix user/leif` creates `user/leif/` branch + +Acceptance Criteria + +- `fledge work start --prefix user/leif` creates `user/leif/` branch + +### REQ-work-005 + +The implementation SHALL satisfy the following criterion: `fledge work start` refuses if working tree is dirty + +Acceptance Criteria + +- `fledge work start` refuses if working tree is dirty + +### REQ-work-006 + +The implementation SHALL satisfy the following criterion: `fledge work start` rejects invalid branch types (not in feat, feature, fix, bug, chore, task, docs, hotfix, refactor) + +Acceptance Criteria + +- `fledge work start` rejects invalid branch types (not in feat, feature, fix, bug, chore, task, docs, hotfix, refactor) + +### REQ-work-007 + +The implementation SHALL satisfy the following criterion: `fledge work commit` stages all changes and creates a commit (prompts for type + message interactively) + +Acceptance Criteria + +- `fledge work commit` stages all changes and creates a commit (prompts for type + message interactively) + +### REQ-work-008 + +The implementation SHALL satisfy the following criterion: `fledge work commit -m "message"` uses the given message with default type + +Acceptance Criteria + +- `fledge work commit -m "message"` uses the given message with default type + +### REQ-work-009 + +The implementation SHALL satisfy the following criterion: `fledge work commit --type fix -m "null pointer"` creates `fix: null pointer` commit + +Acceptance Criteria + +- `fledge work commit --type fix -m "null pointer"` creates `fix: null pointer` commit + +### REQ-work-010 + +The implementation SHALL satisfy the following criterion: `fledge work commit --ai` generates the commit message from staged diff using the configured AI provider + +Acceptance Criteria + +- `fledge work commit --ai` generates the commit message from staged diff using the configured AI provider + +### REQ-work-011 + +The implementation SHALL satisfy the following criterion: `fledge work commit` refuses if there are no changes to commit + +Acceptance Criteria + +- `fledge work commit` refuses if there are no changes to commit + +### REQ-work-012 + +The implementation SHALL satisfy the following criterion: `fledge work push` pushes the current branch to origin with `-u` tracking + +Acceptance Criteria + +- `fledge work push` pushes the current branch to origin with `-u` tracking + +### REQ-work-013 + +The implementation SHALL satisfy the following criterion: `fledge work push` refuses if on the default branch + +Acceptance Criteria + +- `fledge work push` refuses if on the default branch + +### REQ-work-014 + +The implementation SHALL satisfy the following criterion: `fledge work push` refuses if there are no commits ahead of the remote + +Acceptance Criteria + +- `fledge work push` refuses if there are no commits ahead of the remote + +### REQ-work-015 + +The implementation SHALL satisfy the following criterion: `fledge work status` shows branch name, commits ahead/behind, and uncommitted file count + +Acceptance Criteria + +- `fledge work status` shows branch name, commits ahead/behind, and uncommitted file count + +### REQ-work-016 + +The implementation SHALL satisfy the following criterion: `fledge work status` does NOT call `gh` or any GitHub API — pure git only + +Acceptance Criteria + +- `fledge work status` does NOT call `gh` or any GitHub API — pure git only + +### REQ-work-017 + +The implementation SHALL satisfy the following criterion: Branch names are sanitized (lowercase, hyphens only) + +Acceptance Criteria + +- Branch names are sanitized (lowercase, hyphens only) + +### REQ-work-018 + +The implementation SHALL satisfy the following criterion: `[work]` section in `fledge.toml` can override `branch_format` and `default_type` + +Acceptance Criteria + +- `[work]` section in `fledge.toml` can override `branch_format` and `default_type` + +### REQ-work-019 + +The implementation SHALL satisfy the following criterion: All subcommands support `--json` for agent consumption + +Acceptance Criteria + +- All subcommands support `--json` for agent consumption + ## Acceptance Criteria - `fledge work start ` creates a branch using the configured format (default: `{author}/{type}/{name}`) From 442c531ec91421db8d2bd5e84730cb8eb560a595 Mon Sep 17 00:00:00 2001 From: 0xLeif Date: Sat, 11 Jul 2026 22:51:01 -0600 Subject: [PATCH 04/25] fix(ci): use native SDD verification command --- .specsync/sdd.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.specsync/sdd.json b/.specsync/sdd.json index 63033aa5..7dd7a06a 100644 --- a/.specsync/sdd.json +++ b/.specsync/sdd.json @@ -33,7 +33,7 @@ "specs/" ], "verification_commands": [ - "fledge lanes run verify" + "cargo test" ], "custom_artifacts": {}, "principles_file": null From 63db32ca6b0cb6b0bd35cf18663e217e604e873f Mon Sep 17 00:00:00 2001 From: 0xLeif Date: Sat, 11 Jul 2026 23:12:23 -0600 Subject: [PATCH 05/25] Update: assign stable requirement IDs in place --- specs/ai/requirements.md | 28 ++---- specs/ask/requirements.md | 24 ++--- specs/changelog/requirements.md | 36 ++----- specs/config/requirements.md | 40 ++------ specs/create_template/requirements.md | 32 ++---- specs/doctor/requirements.md | 28 ++---- specs/envelope/requirements.md | 32 ++---- specs/github/requirements.md | 44 +++------ specs/init/requirements.md | 48 +++------ specs/introspect/requirements.md | 24 ++--- specs/lanes/requirements.md | 120 ++--------------------- specs/llm/requirements.md | 32 ++---- specs/main/requirements.md | 18 +--- specs/meta/requirements.md | 28 ++---- specs/plugin/requirements.md | 136 ++------------------------ specs/prompts/requirements.md | 32 ++---- specs/publish/requirements.md | 80 ++------------- specs/release/requirements.md | 88 ++--------------- specs/remote/requirements.md | 34 ++----- specs/review/requirements.md | 28 ++---- specs/run/requirements.md | 32 ++---- specs/search/requirements.md | 72 ++------------ specs/spec/requirements.md | 36 ++----- specs/spinner/requirements.md | 20 +--- specs/templates/requirements.md | 52 +++------- specs/trust/requirements.md | 36 ++----- specs/utils/requirements.md | 40 ++------ specs/validate/requirements.md | 24 ++--- specs/versioning/requirements.md | 48 ++------- specs/watch/requirements.md | 34 ++----- specs/work/requirements.md | 80 ++++----------- 31 files changed, 251 insertions(+), 1155 deletions(-) diff --git a/specs/ai/requirements.md b/specs/ai/requirements.md index 06009f1c..7a13eb3f 100644 --- a/specs/ai/requirements.md +++ b/specs/ai/requirements.md @@ -9,65 +9,51 @@ spec: ai.spec.md - As a user switching between local Ollama and Ollama Cloud, I want `fledge ai models` to show me exactly what my daemon reports via `/api/tags` — not a stale hardcoded list - As a user debugging "why did `fledge ask` pick this model?", I want `fledge ai status` to tell me not just what's active but *where* the value came from (env / config / default) -## Durable Requirements +## Acceptance Criteria ### REQ-ai-001 -The implementation SHALL satisfy the following criterion: `fledge ai status` matches the provider/model/host that `llm::build_provider` would resolve; regression between the two is a tracked bug +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge ai status` matches the provider/model/host that `llm::build_provider` would resolve; regression between the two is a tracked bug - ### REQ-ai-002 -The implementation SHALL satisfy the following criterion: `fledge ai models --provider ollama --json` parses cleanly with `jq` and includes at least `name` per model +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge ai models --provider ollama --json` parses cleanly with `jq` and includes at least `name` per model - ### REQ-ai-003 -The implementation SHALL satisfy the following criterion: `fledge ai use ` writes `ai.provider` + per-provider `model` to `~/.config/fledge/config.toml` atomically +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge ai use ` writes `ai.provider` + per-provider `model` to `~/.config/fledge/config.toml` atomically - ### REQ-ai-004 -The implementation SHALL satisfy the following criterion: `fledge ai use` in `--non-interactive` without a provider arg errors via `utils::require_interactive` +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge ai use` in `--non-interactive` without a provider arg errors via `utils::require_interactive` - ### REQ-ai-005 -The implementation SHALL satisfy the following criterion: `fledge ai use ollama` interactively, with a running daemon, offers a Select with the live model list +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge ai use ollama` interactively, with a running daemon, offers a Select with the live model list - ### REQ-ai-006 -The implementation SHALL satisfy the following criterion: Unknown providers on any `--provider` flag reject at clap parse time (not at runtime) +The implementation SHALL satisfy this requirement. Acceptance Criteria - Unknown providers on any `--provider` flag reject at clap parse time (not at runtime) -## Acceptance Criteria - -- `fledge ai status` matches the provider/model/host that `llm::build_provider` would resolve; regression between the two is a tracked bug -- `fledge ai models --provider ollama --json` parses cleanly with `jq` and includes at least `name` per model -- `fledge ai use ` writes `ai.provider` + per-provider `model` to `~/.config/fledge/config.toml` atomically -- `fledge ai use` in `--non-interactive` without a provider arg errors via `utils::require_interactive` -- `fledge ai use ollama` interactively, with a running daemon, offers a Select with the live model list -- Unknown providers on any `--provider` flag reject at clap parse time (not at runtime) - ## Constraints - Must use the existing `ureq` / `dialoguer` / `serde_json` deps — no new crates diff --git a/specs/ask/requirements.md b/specs/ask/requirements.md index c88da9d0..3865f509 100644 --- a/specs/ask/requirements.md +++ b/specs/ask/requirements.md @@ -7,56 +7,44 @@ spec: ask.spec.md - As a developer, I want to run `fledge ask how does X work` to get an AI-powered answer about my codebase - As a developer, I want to type the question naturally without needing quotes -## Durable Requirements +## Acceptance Criteria ### REQ-ask-001 -The implementation SHALL satisfy the following criterion: `fledge ask ` joins all trailing arguments into a single question +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge ask ` joins all trailing arguments into a single question - ### REQ-ask-002 -The implementation SHALL satisfy the following criterion: The question is sent to Claude CLI running in the current project directory +The implementation SHALL satisfy this requirement. Acceptance Criteria - The question is sent to Claude CLI running in the current project directory - ### REQ-ask-003 -The implementation SHALL satisfy the following criterion: The response is streamed to stdout +The implementation SHALL satisfy this requirement. Acceptance Criteria - The response is streamed to stdout - ### REQ-ask-004 -The implementation SHALL satisfy the following criterion: Missing Claude CLI produces install instructions +The implementation SHALL satisfy this requirement. Acceptance Criteria - Missing Claude CLI produces install instructions - ### REQ-ask-005 -The implementation SHALL satisfy the following criterion: No question provided produces a usage hint +The implementation SHALL satisfy this requirement. Acceptance Criteria - No question provided produces a usage hint -## Acceptance Criteria - -- `fledge ask ` joins all trailing arguments into a single question -- The question is sent to Claude CLI running in the current project directory -- The response is streamed to stdout -- Missing Claude CLI produces install instructions -- No question provided produces a usage hint - ## Constraints - Requires Claude CLI (`claude`) installed and authenticated diff --git a/specs/changelog/requirements.md b/specs/changelog/requirements.md index f67ed16e..49165bf6 100644 --- a/specs/changelog/requirements.md +++ b/specs/changelog/requirements.md @@ -12,79 +12,61 @@ type: requirements 3. As a developer, I want JSON output so I can pipe changelog data to other tools. 4. As a developer, I want commits grouped by type so I can scan features vs fixes at a glance. -## Durable Requirements +## Acceptance Criteria ### REQ-changelog-001 -The implementation SHALL satisfy the following criterion: `fledge changelog` shows all tagged releases with commits grouped by conventional commit type +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge changelog` shows all tagged releases with commits grouped by conventional commit type - ### REQ-changelog-002 -The implementation SHALL satisfy the following criterion: `fledge changelog --limit 3` shows only the 3 most recent releases +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge changelog --limit 3` shows only the 3 most recent releases - ### REQ-changelog-003 -The implementation SHALL satisfy the following criterion: `fledge changelog --tag v0.5.0` shows only that release +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge changelog --tag v0.5.0` shows only that release - ### REQ-changelog-004 -The implementation SHALL satisfy the following criterion: `fledge changelog --unreleased` shows commits since the latest tag +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge changelog --unreleased` shows commits since the latest tag - ### REQ-changelog-005 -The implementation SHALL satisfy the following criterion: `fledge changelog --json` outputs structured JSON +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge changelog --json` outputs structured JSON - ### REQ-changelog-006 -The implementation SHALL satisfy the following criterion: Merge commits are excluded +The implementation SHALL satisfy this requirement. Acceptance Criteria - Merge commits are excluded - ### REQ-changelog-007 -The implementation SHALL satisfy the following criterion: Scoped commits (e.g., `fix(parser): msg`) are correctly parsed +The implementation SHALL satisfy this requirement. Acceptance Criteria - Scoped commits (e.g., `fix(parser): msg`) are correctly parsed - ### REQ-changelog-008 -The implementation SHALL satisfy the following criterion: Non-conventional commits appear under "Other" +The implementation SHALL satisfy this requirement. Acceptance Criteria - Non-conventional commits appear under "Other" - -## Acceptance Criteria - -- `fledge changelog` shows all tagged releases with commits grouped by conventional commit type -- `fledge changelog --limit 3` shows only the 3 most recent releases -- `fledge changelog --tag v0.5.0` shows only that release -- `fledge changelog --unreleased` shows commits since the latest tag -- `fledge changelog --json` outputs structured JSON -- Merge commits are excluded -- Scoped commits (e.g., `fix(parser): msg`) are correctly parsed -- Non-conventional commits appear under "Other" diff --git a/specs/config/requirements.md b/specs/config/requirements.md index d6e5ad09..f2403f12 100644 --- a/specs/config/requirements.md +++ b/specs/config/requirements.md @@ -9,92 +9,72 @@ spec: config.spec.md - As a user, I want to register remote template repos so they're discovered automatically during `fledge init` - As a user, I want to store my GitHub token in config so remote template fetching works without env vars -## Durable Requirements +## Acceptance Criteria ### REQ-config-001 -The implementation SHALL satisfy the following criterion: `fledge config list` displays all configured values and empty list sections +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge config list` displays all configured values and empty list sections - ### REQ-config-002 -The implementation SHALL satisfy the following criterion: `fledge config get ` prints the value for any valid key (scalar or list) +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge config get ` prints the value for any valid key (scalar or list) - ### REQ-config-003 -The implementation SHALL satisfy the following criterion: `fledge config set ` persists scalar values to `config.toml` +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge config set ` persists scalar values to `config.toml` - ### REQ-config-004 -The implementation SHALL satisfy the following criterion: `fledge config unset ` removes values (clears lists for list keys) +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge config unset ` removes values (clears lists for list keys) - ### REQ-config-005 -The implementation SHALL satisfy the following criterion: `fledge config add ` appends to list keys with deduplication +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge config add ` appends to list keys with deduplication - ### REQ-config-006 -The implementation SHALL satisfy the following criterion: `fledge config remove ` removes from list keys and reports whether found +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge config remove ` removes from list keys and reports whether found - ### REQ-config-007 -The implementation SHALL satisfy the following criterion: Using `set` on a list key (or `add`/`remove` on a scalar key) produces a clear error with guidance +The implementation SHALL satisfy this requirement. Acceptance Criteria - Using `set` on a list key (or `add`/`remove` on a scalar key) produces a clear error with guidance - ### REQ-config-008 -The implementation SHALL satisfy the following criterion: Config file is created on first write if it doesn't exist +The implementation SHALL satisfy this requirement. Acceptance Criteria - Config file is created on first write if it doesn't exist - ### REQ-config-009 -The implementation SHALL satisfy the following criterion: Missing config file returns sensible defaults (MIT license, no author, empty lists) +The implementation SHALL satisfy this requirement. Acceptance Criteria - Missing config file returns sensible defaults (MIT license, no author, empty lists) -## Acceptance Criteria - -- `fledge config list` displays all configured values and empty list sections -- `fledge config get ` prints the value for any valid key (scalar or list) -- `fledge config set ` persists scalar values to `config.toml` -- `fledge config unset ` removes values (clears lists for list keys) -- `fledge config add ` appends to list keys with deduplication -- `fledge config remove ` removes from list keys and reports whether found -- Using `set` on a list key (or `add`/`remove` on a scalar key) produces a clear error with guidance -- Config file is created on first write if it doesn't exist -- Missing config file returns sensible defaults (MIT license, no author, empty lists) - ## Constraints - Config path follows platform conventions via `dirs::config_dir()` diff --git a/specs/create_template/requirements.md b/specs/create_template/requirements.md index 390e95db..ae9c106e 100644 --- a/specs/create_template/requirements.md +++ b/specs/create_template/requirements.md @@ -8,74 +8,58 @@ spec: create_template.spec.md - As a template author, I want example files showing Tera variable usage so I can learn by example - As a template author, I want to choose which features (hooks, prompts) my template uses so the manifest stays clean -## Durable Requirements +## Acceptance Criteria ### REQ-create-template-001 -The implementation SHALL satisfy the following criterion: `fledge create-template my-template` creates a new directory with a valid template scaffold +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge create-template my-template` creates a new directory with a valid template scaffold - ### REQ-create-template-002 -The implementation SHALL satisfy the following criterion: Generated `template.toml` is valid TOML parseable as `TemplateManifest` +The implementation SHALL satisfy this requirement. Acceptance Criteria - Generated `template.toml` is valid TOML parseable as `TemplateManifest` - ### REQ-create-template-003 -The implementation SHALL satisfy the following criterion: Interactive prompts ask for name, description, render globs, hooks, and custom prompts +The implementation SHALL satisfy this requirement. Acceptance Criteria - Interactive prompts ask for name, description, render globs, hooks, and custom prompts - ### REQ-create-template-004 -The implementation SHALL satisfy the following criterion: All prompts have sensible defaults that can be accepted with Enter +The implementation SHALL satisfy this requirement. Acceptance Criteria - All prompts have sensible defaults that can be accepted with Enter - ### REQ-create-template-005 -The implementation SHALL satisfy the following criterion: Includes example `.tera` file demonstrating variable substitution +The implementation SHALL satisfy this requirement. Acceptance Criteria - Includes example `.tera` file demonstrating variable substitution - ### REQ-create-template-006 -The implementation SHALL satisfy the following criterion: Includes author-facing README with instructions for testing locally +The implementation SHALL satisfy this requirement. Acceptance Criteria - Includes author-facing README with instructions for testing locally - ### REQ-create-template-007 -The implementation SHALL satisfy the following criterion: Fails with a clear error if the target directory already exists +The implementation SHALL satisfy this requirement. Acceptance Criteria - Fails with a clear error if the target directory already exists -## Acceptance Criteria - -- `fledge create-template my-template` creates a new directory with a valid template scaffold -- Generated `template.toml` is valid TOML parseable as `TemplateManifest` -- Interactive prompts ask for name, description, render globs, hooks, and custom prompts -- All prompts have sensible defaults that can be accepted with Enter -- Includes example `.tera` file demonstrating variable substitution -- Includes author-facing README with instructions for testing locally -- Fails with a clear error if the target directory already exists - ## Constraints - Must use `dialoguer` for prompts (consistent with rest of CLI) diff --git a/specs/doctor/requirements.md b/specs/doctor/requirements.md index 30965a9f..54bfd93f 100644 --- a/specs/doctor/requirements.md +++ b/specs/doctor/requirements.md @@ -8,65 +8,51 @@ spec: doctor.spec.md - As a CI system, I want to run `fledge doctor --json` to get machine-readable health data - As a polyglot developer, I want a single command to inventory which language toolchains are installed without false-failing on languages my current project doesn't use -## Durable Requirements +## Acceptance Criteria ### REQ-doctor-001 -The implementation SHALL satisfy the following criterion: `fledge doctor` reports four sections: `fledge`, `Git`, `AI`, `Toolchains` +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge doctor` reports four sections: `fledge`, `Git`, `AI`, `Toolchains` - ### REQ-doctor-002 -The implementation SHALL satisfy the following criterion: Each failing check in a non-informational section shows an actionable fix command +The implementation SHALL satisfy this requirement. Acceptance Criteria - Each failing check in a non-informational section shows an actionable fix command - ### REQ-doctor-003 -The implementation SHALL satisfy the following criterion: The `Toolchains` section is informational — missing entries render dimmed and don't pollute the pass/fail totals +The implementation SHALL satisfy this requirement. Acceptance Criteria - The `Toolchains` section is informational — missing entries render dimmed and don't pollute the pass/fail totals - ### REQ-doctor-004 -The implementation SHALL satisfy the following criterion: `--json` outputs a structured `DoctorReport` with all check results, including `informational: bool` per Section +The implementation SHALL satisfy this requirement. Acceptance Criteria - `--json` outputs a structured `DoctorReport` with all check results, including `informational: bool` per Section - ### REQ-doctor-005 -The implementation SHALL satisfy the following criterion: Exit summary shows count of passed checks and issues found, computed only over non-informational sections +The implementation SHALL satisfy this requirement. Acceptance Criteria - Exit summary shows count of passed checks and issues found, computed only over non-informational sections - ### REQ-doctor-006 -The implementation SHALL satisfy the following criterion: Toolchains probed: rustc, cargo, node, npm, pnpm, bun, yarn, python3, uv, poetry, go, ruby, swift, java, gradle, mvn +The implementation SHALL satisfy this requirement. Acceptance Criteria - Toolchains probed: rustc, cargo, node, npm, pnpm, bun, yarn, python3, uv, poetry, go, ruby, swift, java, gradle, mvn -## Acceptance Criteria - -- `fledge doctor` reports four sections: `fledge`, `Git`, `AI`, `Toolchains` -- Each failing check in a non-informational section shows an actionable fix command -- The `Toolchains` section is informational — missing entries render dimmed and don't pollute the pass/fail totals -- `--json` outputs a structured `DoctorReport` with all check results, including `informational: bool` per Section -- Exit summary shows count of passed checks and issues found, computed only over non-informational sections -- Toolchains probed: rustc, cargo, node, npm, pnpm, bun, yarn, python3, uv, poetry, go, ruby, swift, java, gradle, mvn - ## Constraints - Tool version detection runs ` --version` (or the tool's equivalent — `version` for `go`, `-version` for `java`) and parses the first version-like token diff --git a/specs/envelope/requirements.md b/specs/envelope/requirements.md index 0c4b49d2..7394ee55 100644 --- a/specs/envelope/requirements.md +++ b/specs/envelope/requirements.md @@ -8,74 +8,58 @@ spec: envelope.spec.md - As a fledge developer, I want migrating a hand-rolled envelope to a helper to be a non-behavioral refactor, so I can adopt it without churning golden output - As a fledge developer, I want the envelope dialect chosen explicitly (resource / action / flat) rather than copy-pasted from a neighboring command -## Durable Requirements +## Acceptance Criteria ### REQ-envelope-001 -The implementation SHALL satisfy the following criterion: `resource(schema_version, key, items)` builds `{schema_version, : items}` with no `action` key +The implementation SHALL satisfy this requirement. Acceptance Criteria - `resource(schema_version, key, items)` builds `{schema_version, : items}` with no `action` key - ### REQ-envelope-002 -The implementation SHALL satisfy the following criterion: `action(schema_version, action, fields)` builds `{schema_version, action, ...fields}`, inserting the fixed keys first then merging an object `fields` +The implementation SHALL satisfy this requirement. Acceptance Criteria - `action(schema_version, action, fields)` builds `{schema_version, action, ...fields}`, inserting the fixed keys first then merging an object `fields` - ### REQ-envelope-003 -The implementation SHALL satisfy the following criterion: `versioned(schema_version, fields)` builds `{schema_version, ...fields}` with no `action` key +The implementation SHALL satisfy this requirement. Acceptance Criteria - `versioned(schema_version, fields)` builds `{schema_version, ...fields}` with no `action` key - ### REQ-envelope-004 -The implementation SHALL satisfy the following criterion: Every envelope carries a `schema_version` from the caller-supplied `u32` +The implementation SHALL satisfy this requirement. Acceptance Criteria - Every envelope carries a `schema_version` from the caller-supplied `u32` - ### REQ-envelope-005 -The implementation SHALL satisfy the following criterion: Output is byte-for-byte identical to the equivalent hand-rolled `serde_json::json!` +The implementation SHALL satisfy this requirement. Acceptance Criteria - Output is byte-for-byte identical to the equivalent hand-rolled `serde_json::json!` - ### REQ-envelope-006 -The implementation SHALL satisfy the following criterion: A non-object `fields` value contributes no extra keys; the envelope still carries its fixed keys +The implementation SHALL satisfy this requirement. Acceptance Criteria - A non-object `fields` value contributes no extra keys; the envelope still carries its fixed keys - ### REQ-envelope-007 -The implementation SHALL satisfy the following criterion: Non-serializable `resource` items store `Value::Null` under the key instead of panicking +The implementation SHALL satisfy this requirement. Acceptance Criteria - Non-serializable `resource` items store `Value::Null` under the key instead of panicking -## Acceptance Criteria - -- `resource(schema_version, key, items)` builds `{schema_version, : items}` with no `action` key -- `action(schema_version, action, fields)` builds `{schema_version, action, ...fields}`, inserting the fixed keys first then merging an object `fields` -- `versioned(schema_version, fields)` builds `{schema_version, ...fields}` with no `action` key -- Every envelope carries a `schema_version` from the caller-supplied `u32` -- Output is byte-for-byte identical to the equivalent hand-rolled `serde_json::json!` -- A non-object `fields` value contributes no extra keys; the envelope still carries its fixed keys -- Non-serializable `resource` items store `Value::Null` under the key instead of panicking - ## Constraints - Builders are infallible — they return a `serde_json::Value::Object` unconditionally diff --git a/specs/github/requirements.md b/specs/github/requirements.md index 04eedb8b..8aafab7e 100644 --- a/specs/github/requirements.md +++ b/specs/github/requirements.md @@ -8,101 +8,79 @@ spec: github.spec.md - As a module author, I want `github_api_get` to handle authentication and error formatting so I can focus on business logic - As a developer, I want clear error messages when my token is missing or rate-limited -## Durable Requirements +## Acceptance Criteria ### REQ-github-001 -The implementation SHALL satisfy the following criterion: `detect_repo` parses HTTPS remote URLs (`https://github.com/owner/repo.git`) +The implementation SHALL satisfy this requirement. Acceptance Criteria - `detect_repo` parses HTTPS remote URLs (`https://github.com/owner/repo.git`) - ### REQ-github-002 -The implementation SHALL satisfy the following criterion: `detect_repo` parses SSH remote URLs (`git@github.com:owner/repo.git`) +The implementation SHALL satisfy this requirement. Acceptance Criteria - `detect_repo` parses SSH remote URLs (`git@github.com:owner/repo.git`) - ### REQ-github-003 -The implementation SHALL satisfy the following criterion: `detect_repo` handles token-authenticated HTTPS URLs +The implementation SHALL satisfy this requirement. Acceptance Criteria - `detect_repo` handles token-authenticated HTTPS URLs - ### REQ-github-004 -The implementation SHALL satisfy the following criterion: `detect_repo` strips trailing `.git` suffix +The implementation SHALL satisfy this requirement. Acceptance Criteria - `detect_repo` strips trailing `.git` suffix - ### REQ-github-005 -The implementation SHALL satisfy the following criterion: `github_api_get` reads token from `FLEDGE_GITHUB_TOKEN`, `GITHUB_TOKEN`, or config +The implementation SHALL satisfy this requirement. Acceptance Criteria - `github_api_get` reads token from `FLEDGE_GITHUB_TOKEN`, `GITHUB_TOKEN`, or config - ### REQ-github-006 -The implementation SHALL satisfy the following criterion: `github_api_get` returns parsed JSON on success +The implementation SHALL satisfy this requirement. Acceptance Criteria - `github_api_get` returns parsed JSON on success - ### REQ-github-007 -The implementation SHALL satisfy the following criterion: 403 responses produce a message about setting a token +The implementation SHALL satisfy this requirement. Acceptance Criteria - 403 responses produce a message about setting a token - ### REQ-github-008 -The implementation SHALL satisfy the following criterion: 404 responses produce a "Not found" error +The implementation SHALL satisfy this requirement. Acceptance Criteria - 404 responses produce a "Not found" error - ### REQ-github-009 -The implementation SHALL satisfy the following criterion: `format_relative_time` converts ISO 8601 timestamps to human-readable relative times +The implementation SHALL satisfy this requirement. Acceptance Criteria - `format_relative_time` converts ISO 8601 timestamps to human-readable relative times - ### REQ-github-010 -The implementation SHALL satisfy the following criterion: `format_relative_time` falls back to the raw string for unparseable input +The implementation SHALL satisfy this requirement. Acceptance Criteria - `format_relative_time` falls back to the raw string for unparseable input -## Acceptance Criteria - -- `detect_repo` parses HTTPS remote URLs (`https://github.com/owner/repo.git`) -- `detect_repo` parses SSH remote URLs (`git@github.com:owner/repo.git`) -- `detect_repo` handles token-authenticated HTTPS URLs -- `detect_repo` strips trailing `.git` suffix -- `github_api_get` reads token from `FLEDGE_GITHUB_TOKEN`, `GITHUB_TOKEN`, or config -- `github_api_get` returns parsed JSON on success -- 403 responses produce a message about setting a token -- 404 responses produce a "Not found" error -- `format_relative_time` converts ISO 8601 timestamps to human-readable relative times -- `format_relative_time` falls back to the raw string for unparseable input - ## Constraints - Uses `ureq` for HTTP — no async runtime required diff --git a/specs/init/requirements.md b/specs/init/requirements.md index 521786d6..5c83ad8f 100644 --- a/specs/init/requirements.md +++ b/specs/init/requirements.md @@ -11,110 +11,86 @@ spec: init.spec.md - As a user, I want post-create hooks (like `npm install`) to run automatically for local templates - As a user, I want to be warned before remote templates execute hooks on my machine -## Durable Requirements +## Acceptance Criteria ### REQ-init-001 -The implementation SHALL satisfy the following criterion: `fledge init ` creates a directory with rendered template files +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge init ` creates a directory with rendered template files - ### REQ-init-002 -The implementation SHALL satisfy the following criterion: `fledge init --template ` uses the specified template +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge init --template ` uses the specified template - ### REQ-init-003 -The implementation SHALL satisfy the following criterion: `fledge init --template owner/repo` fetches and uses a remote template +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge init --template owner/repo` fetches and uses a remote template - ### REQ-init-004 -The implementation SHALL satisfy the following criterion: Without `--template`, an interactive selector is shown +The implementation SHALL satisfy this requirement. Acceptance Criteria - Without `--template`, an interactive selector is shown - ### REQ-init-005 -The implementation SHALL satisfy the following criterion: `--dry-run` prints file list, hooks, and git status without writing +The implementation SHALL satisfy this requirement. Acceptance Criteria - `--dry-run` prints file list, hooks, and git status without writing - ### REQ-init-006 -The implementation SHALL satisfy the following criterion: `--no-git` skips git init and initial commit +The implementation SHALL satisfy this requirement. Acceptance Criteria - `--no-git` skips git init and initial commit - ### REQ-init-007 -The implementation SHALL satisfy the following criterion: `--no-install` skips post-create hooks +The implementation SHALL satisfy this requirement. Acceptance Criteria - `--no-install` skips post-create hooks - ### REQ-init-008 -The implementation SHALL satisfy the following criterion: `--yes` auto-confirms remote hook prompts +The implementation SHALL satisfy this requirement. Acceptance Criteria - `--yes` auto-confirms remote hook prompts - ### REQ-init-009 -The implementation SHALL satisfy the following criterion: `--refresh` clears cached remote repos before fetching +The implementation SHALL satisfy this requirement. Acceptance Criteria - `--refresh` clears cached remote repos before fetching - ### REQ-init-010 -The implementation SHALL satisfy the following criterion: If the target directory already exists, the command errors immediately +The implementation SHALL satisfy this requirement. Acceptance Criteria - If the target directory already exists, the command errors immediately - ### REQ-init-011 -The implementation SHALL satisfy the following criterion: Git init includes an initial commit with all scaffolded files +The implementation SHALL satisfy this requirement. Acceptance Criteria - Git init includes an initial commit with all scaffolded files -## Acceptance Criteria - -- `fledge init ` creates a directory with rendered template files -- `fledge init --template ` uses the specified template -- `fledge init --template owner/repo` fetches and uses a remote template -- Without `--template`, an interactive selector is shown -- `--dry-run` prints file list, hooks, and git status without writing -- `--no-git` skips git init and initial commit -- `--no-install` skips post-create hooks -- `--yes` auto-confirms remote hook prompts -- `--refresh` clears cached remote repos before fetching -- If the target directory already exists, the command errors immediately -- Git init includes an initial commit with all scaffolded files - ## Constraints - Must work in CI environments (headless, no git identity configured) diff --git a/specs/introspect/requirements.md b/specs/introspect/requirements.md index 1f46e41d..230f44f8 100644 --- a/specs/introspect/requirements.md +++ b/specs/introspect/requirements.md @@ -8,56 +8,44 @@ spec: introspect.spec.md - As a tooling author (e.g. someone building a wrapper, a fledge-aware editor integration, or generating docs), I want a single structured source of truth for the command surface that changes automatically as the binary changes - As a human, I want a bird's-eye view of the whole command tree as a readable indented listing -## Durable Requirements +## Acceptance Criteria ### REQ-introspect-001 -The implementation SHALL satisfy the following criterion: `fledge introspect --json` produces a single JSON object parseable by `serde_json::from_str` and `jq` +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge introspect --json` produces a single JSON object parseable by `serde_json::from_str` and `jq` - ### REQ-introspect-002 -The implementation SHALL satisfy the following criterion: `fledge introspect` without `--json` produces a human-readable indented tree +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge introspect` without `--json` produces a human-readable indented tree - ### REQ-introspect-003 -The implementation SHALL satisfy the following criterion: The output includes every user-facing subcommand and arg — no silent gaps +The implementation SHALL satisfy this requirement. Acceptance Criteria - The output includes every user-facing subcommand and arg — no silent gaps - ### REQ-introspect-004 -The implementation SHALL satisfy the following criterion: clap's auto-generated `--help` and `--version` and `help` subcommand are excluded as noise +The implementation SHALL satisfy this requirement. Acceptance Criteria - clap's auto-generated `--help` and `--version` and `help` subcommand are excluded as noise - ### REQ-introspect-005 -The implementation SHALL satisfy the following criterion: Subcommand aliases and global args are explicitly labeled in the output so agents can reason about them +The implementation SHALL satisfy this requirement. Acceptance Criteria - Subcommand aliases and global args are explicitly labeled in the output so agents can reason about them -## Acceptance Criteria - -- `fledge introspect --json` produces a single JSON object parseable by `serde_json::from_str` and `jq` -- `fledge introspect` without `--json` produces a human-readable indented tree -- The output includes every user-facing subcommand and arg — no silent gaps -- clap's auto-generated `--help` and `--version` and `help` subcommand are excluded as noise -- Subcommand aliases and global args are explicitly labeled in the output so agents can reason about them - ## Constraints - Must not touch the filesystem, network, or any external process — pure introspection diff --git a/specs/lanes/requirements.md b/specs/lanes/requirements.md index a72ffd55..54a357de 100644 --- a/specs/lanes/requirements.md +++ b/specs/lanes/requirements.md @@ -1,5 +1,11 @@ # Lanes — Requirements +### REQ-lanes-001 + +The implementation SHALL satisfy the behavior described by this companion. + +Acceptance Criteria + ## Functional Requirements 1. Define named workflow pipelines in `fledge.toml` under `[lanes]` @@ -19,117 +25,3 @@ 1. Parallel groups must execute steps concurrently using threads 2. Lane execution must respect task dependency ordering within each step 3. `--json` flag must produce machine-parseable output for list operations - -## Durable Requirements - -### REQ-lanes-001 - -The implementation SHALL satisfy the following criterion: Define named workflow pipelines in `fledge.toml` under `[lanes]` - -Acceptance Criteria - -- Define named workflow pipelines in `fledge.toml` under `[lanes]` - -### REQ-lanes-002 - -The implementation SHALL satisfy the following criterion: Execute lanes as ordered sequences of steps - -Acceptance Criteria - -- Execute lanes as ordered sequences of steps - -### REQ-lanes-003 - -The implementation SHALL satisfy the following criterion: Support three step types: task references, inline commands, parallel groups - -Acceptance Criteria - -- Support three step types: task references, inline commands, parallel groups - -### REQ-lanes-004 - -The implementation SHALL satisfy the following criterion: Validate task references before execution - -Acceptance Criteria - -- Validate task references before execution - -### REQ-lanes-005 - -The implementation SHALL satisfy the following criterion: Support `fail_fast` flag to control failure behavior - -Acceptance Criteria - -- Support `fail_fast` flag to control failure behavior - -### REQ-lanes-006 - -The implementation SHALL satisfy the following criterion: Support `--dry-run` to preview execution plan - -Acceptance Criteria - -- Support `--dry-run` to preview execution plan - -### REQ-lanes-007 - -The implementation SHALL satisfy the following criterion: Support `--init` to scaffold default lanes for the detected language - -Acceptance Criteria - -- Support `--init` to scaffold default lanes for the detected language - -### REQ-lanes-008 - -The implementation SHALL satisfy the following criterion: List available lanes with descriptions - -Acceptance Criteria - -- List available lanes with descriptions - -### REQ-lanes-009 - -The implementation SHALL satisfy the following criterion: Scaffold a lane repo via `fledge lanes create ` with example fledge.toml, README, and .gitignore - -Acceptance Criteria - -- Scaffold a lane repo via `fledge lanes create ` with example fledge.toml, README, and .gitignore - -### REQ-lanes-010 - -The implementation SHALL satisfy the following criterion: Validate lane definitions via `fledge lanes validate [path]` — check task references, empty steps, circular deps, parallel groups - -Acceptance Criteria - -- Validate lane definitions via `fledge lanes validate [path]` — check task references, empty steps, circular deps, parallel groups - -### REQ-lanes-011 - -The implementation SHALL satisfy the following criterion: `publish` validates before pushing - -Acceptance Criteria - -- `publish` validates before pushing - -### REQ-lanes-012 - -The implementation SHALL satisfy the following criterion: Parallel groups must execute steps concurrently using threads - -Acceptance Criteria - -- Parallel groups must execute steps concurrently using threads - -### REQ-lanes-013 - -The implementation SHALL satisfy the following criterion: Lane execution must respect task dependency ordering within each step - -Acceptance Criteria - -- Lane execution must respect task dependency ordering within each step - -### REQ-lanes-014 - -The implementation SHALL satisfy the following criterion: `--json` flag must produce machine-parseable output for list operations - -Acceptance Criteria - -- `--json` flag must produce machine-parseable output for list operations diff --git a/specs/llm/requirements.md b/specs/llm/requirements.md index dcb4c166..71155c67 100644 --- a/specs/llm/requirements.md +++ b/specs/llm/requirements.md @@ -9,74 +9,58 @@ spec: llm.spec.md - As an agent, I want to choose my provider per-invocation via `--provider` flag so I can mix local (cheap, fast) and cloud (stronger) per task - As a maintainer, I want the prompt composition in `ask` / `review` to remain provider-agnostic so adding a new provider is localized to one file -## Durable Requirements +## Acceptance Criteria ### REQ-llm-001 -The implementation SHALL satisfy the following criterion: Default behavior (no config, no env, no flag) is identical to the pre-v0.13 Claude-CLI-only behavior +The implementation SHALL satisfy this requirement. Acceptance Criteria - Default behavior (no config, no env, no flag) is identical to the pre-v0.13 Claude-CLI-only behavior - ### REQ-llm-002 -The implementation SHALL satisfy the following criterion: Setting `ai.provider = "ollama"` in config OR `FLEDGE_AI_PROVIDER=ollama` in env routes all AI commands through Ollama +The implementation SHALL satisfy this requirement. Acceptance Criteria - Setting `ai.provider = "ollama"` in config OR `FLEDGE_AI_PROVIDER=ollama` in env routes all AI commands through Ollama - ### REQ-llm-003 -The implementation SHALL satisfy the following criterion: Per-invocation `--provider ollama` overrides both env and config +The implementation SHALL satisfy this requirement. Acceptance Criteria - Per-invocation `--provider ollama` overrides both env and config - ### REQ-llm-004 -The implementation SHALL satisfy the following criterion: Model selection follows the same override > env > config > default precedence +The implementation SHALL satisfy this requirement. Acceptance Criteria - Model selection follows the same override > env > config > default precedence - ### REQ-llm-005 -The implementation SHALL satisfy the following criterion: Ollama's HTTP request shape matches the `/api/generate` endpoint's published schema +The implementation SHALL satisfy this requirement. Acceptance Criteria - Ollama's HTTP request shape matches the `/api/generate` endpoint's published schema - ### REQ-llm-006 -The implementation SHALL satisfy the following criterion: `fledge doctor` reports both providers and which is active +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge doctor` reports both providers and which is active - ### REQ-llm-007 -The implementation SHALL satisfy the following criterion: No regression: `fledge ask --json` and `fledge review --json` outputs remain parseable; payloads gain a `provider` and `model` field +The implementation SHALL satisfy this requirement. Acceptance Criteria - No regression: `fledge ask --json` and `fledge review --json` outputs remain parseable; payloads gain a `provider` and `model` field -## Acceptance Criteria - -- Default behavior (no config, no env, no flag) is identical to the pre-v0.13 Claude-CLI-only behavior -- Setting `ai.provider = "ollama"` in config OR `FLEDGE_AI_PROVIDER=ollama` in env routes all AI commands through Ollama -- Per-invocation `--provider ollama` overrides both env and config -- Model selection follows the same override > env > config > default precedence -- Ollama's HTTP request shape matches the `/api/generate` endpoint's published schema -- `fledge doctor` reports both providers and which is active -- No regression: `fledge ask --json` and `fledge review --json` outputs remain parseable; payloads gain a `provider` and `model` field - ## Constraints - Must use the existing `ureq` dependency — no new HTTP client diff --git a/specs/main/requirements.md b/specs/main/requirements.md index 0250e19f..eecb8dfa 100644 --- a/specs/main/requirements.md +++ b/specs/main/requirements.md @@ -1,37 +1,27 @@ -- Parse CLI arguments via clap derive -- Dispatch each subcommand to its module's entry function -- Forward unknown commands to installed plugins -- Generate shell completions on demand - -## Durable Requirements - ### REQ-main-001 -The implementation SHALL satisfy the following criterion: Parse CLI arguments via clap derive +The implementation SHALL satisfy this requirement. Acceptance Criteria - Parse CLI arguments via clap derive - ### REQ-main-002 -The implementation SHALL satisfy the following criterion: Dispatch each subcommand to its module's entry function +The implementation SHALL satisfy this requirement. Acceptance Criteria - Dispatch each subcommand to its module's entry function - ### REQ-main-003 -The implementation SHALL satisfy the following criterion: Forward unknown commands to installed plugins +The implementation SHALL satisfy this requirement. Acceptance Criteria - Forward unknown commands to installed plugins - ### REQ-main-004 -The implementation SHALL satisfy the following criterion: Generate shell completions on demand +The implementation SHALL satisfy this requirement. Acceptance Criteria diff --git a/specs/meta/requirements.md b/specs/meta/requirements.md index de2c26ee..a243bd81 100644 --- a/specs/meta/requirements.md +++ b/specs/meta/requirements.md @@ -9,65 +9,51 @@ spec: meta.spec.md - As a template author, I want the template variables used at scaffold time persisted so a project's configuration is inspectable - As a user, I don't want fledge's internal cache tracked by git after scaffolding -## Durable Requirements +## Acceptance Criteria ### REQ-meta-001 -The implementation SHALL satisfy the following criterion: `write_project_meta` writes `.fledge/meta.toml` with `SourceInfo` provenance, string template variables, and a hash for each existing created file +The implementation SHALL satisfy this requirement. Acceptance Criteria - `write_project_meta` writes `.fledge/meta.toml` with `SourceInfo` provenance, string template variables, and a hash for each existing created file - ### REQ-meta-002 -The implementation SHALL satisfy the following criterion: `compute_file_hash` returns a 64-character lowercase hex SHA-256 digest and is deterministic +The implementation SHALL satisfy this requirement. Acceptance Criteria - `compute_file_hash` returns a 64-character lowercase hex SHA-256 digest and is deterministic - ### REQ-meta-003 -The implementation SHALL satisfy the following criterion: The `.fledge` directory is created if missing +The implementation SHALL satisfy this requirement. Acceptance Criteria - The `.fledge` directory is created if missing - ### REQ-meta-004 -The implementation SHALL satisfy the following criterion: A `.fledge/.gitignore` is created if one does not already exist, and an existing one is never overwritten +The implementation SHALL satisfy this requirement. Acceptance Criteria - A `.fledge/.gitignore` is created if one does not already exist, and an existing one is never overwritten - ### REQ-meta-005 -The implementation SHALL satisfy the following criterion: Created files that no longer exist on disk are silently skipped, not errored +The implementation SHALL satisfy this requirement. Acceptance Criteria - Created files that no longer exist on disk are silently skipped, not errored - ### REQ-meta-006 -The implementation SHALL satisfy the following criterion: `fledge_version` is captured from `CARGO_PKG_VERSION` at compile time and `created` is the local date as `YYYY-MM-DD` +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge_version` is captured from `CARGO_PKG_VERSION` at compile time and `created` is the local date as `YYYY-MM-DD` -## Acceptance Criteria - -- `write_project_meta` writes `.fledge/meta.toml` with `SourceInfo` provenance, string template variables, and a hash for each existing created file -- `compute_file_hash` returns a 64-character lowercase hex SHA-256 digest and is deterministic -- The `.fledge` directory is created if missing -- A `.fledge/.gitignore` is created if one does not already exist, and an existing one is never overwritten -- Created files that no longer exist on disk are silently skipped, not errored -- `fledge_version` is captured from `CARGO_PKG_VERSION` at compile time and `created` is the local date as `YYYY-MM-DD` - ## Constraints - Only string-valued template variables are persisted; non-string values are dropped diff --git a/specs/plugin/requirements.md b/specs/plugin/requirements.md index 21b4a56a..4b7ec498 100644 --- a/specs/plugin/requirements.md +++ b/specs/plugin/requirements.md @@ -1,5 +1,11 @@ # Plugin — Requirements +### REQ-plugin-001 + +The implementation SHALL satisfy the behavior described by this companion. + +Acceptance Criteria + ## Functional Requirements 1. Install plugins from GitHub shorthand, generic git URLs, and local paths via `fledge plugins install ` @@ -21,133 +27,3 @@ 1. Plugin installation must be idempotent with `--force` flag 2. Plugin binaries must be discoverable via PATH or `plugins/bin/` 3. `--json` flag must produce machine-parseable output for all list/search operations - -## Durable Requirements - -### REQ-plugin-001 - -The implementation SHALL satisfy the following criterion: Install plugins from GitHub shorthand, generic git URLs, and local paths via `fledge plugins install ` - -Acceptance Criteria - -- Install plugins from GitHub shorthand, generic git URLs, and local paths via `fledge plugins install ` - -### REQ-plugin-002 - -The implementation SHALL satisfy the following criterion: Remove installed plugins via `fledge plugins remove ` - -Acceptance Criteria - -- Remove installed plugins via `fledge plugins remove ` - -### REQ-plugin-003 - -The implementation SHALL satisfy the following criterion: List installed plugins with metadata via `fledge plugins list` - -Acceptance Criteria - -- List installed plugins with metadata via `fledge plugins list` - -### REQ-plugin-004 - -The implementation SHALL satisfy the following criterion: Search for plugins on GitHub via `fledge plugins search ` - -Acceptance Criteria - -- Search for plugins on GitHub via `fledge plugins search ` - -### REQ-plugin-005 - -The implementation SHALL satisfy the following criterion: Run plugin commands as fledge subcommands - -Acceptance Criteria - -- Run plugin commands as fledge subcommands - -### REQ-plugin-006 - -The implementation SHALL satisfy the following criterion: Resolve plugin executables by name for CLI dispatch - -Acceptance Criteria - -- Resolve plugin executables by name for CLI dispatch - -### REQ-plugin-007 - -The implementation SHALL satisfy the following criterion: Support cross-platform symlink creation (Unix symlinks, Windows symlinks) - -Acceptance Criteria - -- Support cross-platform symlink creation (Unix symlinks, Windows symlinks) - -### REQ-plugin-008 - -The implementation SHALL satisfy the following criterion: Set executable permissions on plugin binaries (Unix only) - -Acceptance Criteria - -- Set executable permissions on plugin binaries (Unix only) - -### REQ-plugin-009 - -The implementation SHALL satisfy the following criterion: Scaffold a new plugin via `fledge plugins create ` with plugin.toml, bin/, README, and .gitignore - -Acceptance Criteria - -- Scaffold a new plugin via `fledge plugins create ` with plugin.toml, bin/, README, and .gitignore - -### REQ-plugin-010 - -The implementation SHALL satisfy the following criterion: Validate plugin manifests via `fledge plugins validate [path]` — check name, version, binary existence, command definitions - -Acceptance Criteria - -- Validate plugin manifests via `fledge plugins validate [path]` — check name, version, binary existence, command definitions - -### REQ-plugin-011 - -The implementation SHALL satisfy the following criterion: `publish` validates before pushing - -Acceptance Criteria - -- `publish` validates before pushing - -### REQ-plugin-012 - -The implementation SHALL satisfy the following criterion: Local path installs are live-linked by default and support `--copy` for snapshot installs - -Acceptance Criteria - -- Local path installs are live-linked by default and support `--copy` for snapshot installs - -### REQ-plugin-013 - -The implementation SHALL satisfy the following criterion: Removing a live-linked local plugin must not delete the original local source directory - -Acceptance Criteria - -- Removing a live-linked local plugin must not delete the original local source directory - -### REQ-plugin-014 - -The implementation SHALL satisfy the following criterion: Plugin installation must be idempotent with `--force` flag - -Acceptance Criteria - -- Plugin installation must be idempotent with `--force` flag - -### REQ-plugin-015 - -The implementation SHALL satisfy the following criterion: Plugin binaries must be discoverable via PATH or `plugins/bin/` - -Acceptance Criteria - -- Plugin binaries must be discoverable via PATH or `plugins/bin/` - -### REQ-plugin-016 - -The implementation SHALL satisfy the following criterion: `--json` flag must produce machine-parseable output for all list/search operations - -Acceptance Criteria - -- `--json` flag must produce machine-parseable output for all list/search operations diff --git a/specs/prompts/requirements.md b/specs/prompts/requirements.md index e6275337..fee11677 100644 --- a/specs/prompts/requirements.md +++ b/specs/prompts/requirements.md @@ -9,74 +9,58 @@ spec: prompts.spec.md - As a template author, I want to define custom prompts with optional defaults in `template.toml` - As a template author, I want prompt defaults to reference previously collected variables -## Durable Requirements +## Acceptance Criteria ### REQ-prompts-001 -The implementation SHALL satisfy the following criterion: `select_template()` presents an interactive list with name and description columns +The implementation SHALL satisfy this requirement. Acceptance Criteria - `select_template()` presents an interactive list with name and description columns - ### REQ-prompts-002 -The implementation SHALL satisfy the following criterion: `prompt_variables()` collects all core variables (project_name, author, github_org, license, year, date) and template-specific prompts +The implementation SHALL satisfy this requirement. Acceptance Criteria - `prompt_variables()` collects all core variables (project_name, author, github_org, license, year, date) and template-specific prompts - ### REQ-prompts-003 -The implementation SHALL satisfy the following criterion: Author falls back: config → `git config user.name` → interactive prompt +The implementation SHALL satisfy this requirement. Acceptance Criteria - Author falls back: config → `git config user.name` → interactive prompt - ### REQ-prompts-004 -The implementation SHALL satisfy the following criterion: GitHub org falls back: config → interactive prompt with "CorvidLabs" default +The implementation SHALL satisfy this requirement. Acceptance Criteria - GitHub org falls back: config → interactive prompt with "CorvidLabs" default - ### REQ-prompts-005 -The implementation SHALL satisfy the following criterion: License is always pulled from config (defaults to MIT) +The implementation SHALL satisfy this requirement. Acceptance Criteria - License is always pulled from config (defaults to MIT) - ### REQ-prompts-006 -The implementation SHALL satisfy the following criterion: Template-specific prompt defaults support Tera variable interpolation +The implementation SHALL satisfy this requirement. Acceptance Criteria - Template-specific prompt defaults support Tera variable interpolation - ### REQ-prompts-007 -The implementation SHALL satisfy the following criterion: Case conversion produces correct snake_case and PascalCase variants +The implementation SHALL satisfy this requirement. Acceptance Criteria - Case conversion produces correct snake_case and PascalCase variants -## Acceptance Criteria - -- `select_template()` presents an interactive list with name and description columns -- `prompt_variables()` collects all core variables (project_name, author, github_org, license, year, date) and template-specific prompts -- Author falls back: config → `git config user.name` → interactive prompt -- GitHub org falls back: config → interactive prompt with "CorvidLabs" default -- License is always pulled from config (defaults to MIT) -- Template-specific prompt defaults support Tera variable interpolation -- Case conversion produces correct snake_case and PascalCase variants - ## Constraints - Must work in TTY environments (interactive prompts require a terminal) diff --git a/specs/publish/requirements.md b/specs/publish/requirements.md index f92ba2f8..7046149e 100644 --- a/specs/publish/requirements.md +++ b/specs/publish/requirements.md @@ -1,5 +1,11 @@ # Publish — Requirements +### REQ-publish-001 + +The implementation SHALL satisfy the behavior described by this companion. + +Acceptance Criteria + This module is a library — its requirements describe the helpers it exposes. The user-facing publish commands (`templates publish`, `lanes publish`, `plugins publish`) define their own validation and prompting in their respective specs. ## Functional Requirements @@ -16,77 +22,3 @@ This module is a library — its requirements describe the helpers it exposes. T 1. Synchronous HTTP via `ureq` — no async runtime 2. Token never reaches the process table or git config — passed via `http.extraheader` env injection only 3. No prompts in this module — caller decides whether to confirm - -## Durable Requirements - -### REQ-publish-001 - -The implementation SHALL satisfy the following criterion: Resolve the authenticated GitHub username from a token (`get_authenticated_user`) - -Acceptance Criteria - -- Resolve the authenticated GitHub username from a token (`get_authenticated_user`) - -### REQ-publish-002 - -The implementation SHALL satisfy the following criterion: Check whether a `/` exists on GitHub (`check_repo_exists`) — false on 404, error on other non-2xx - -Acceptance Criteria - -- Check whether a `/` exists on GitHub (`check_repo_exists`) — false on 404, error on other non-2xx - -### REQ-publish-003 - -The implementation SHALL satisfy the following criterion: Create a new GitHub repository under the user or an organization with optional private flag and description (`create_github_repo`) - -Acceptance Criteria - -- Create a new GitHub repository under the user or an organization with optional private flag and description (`create_github_repo`) - -### REQ-publish-004 - -The implementation SHALL satisfy the following criterion: Add a single topic to a repository's existing topic set, additively (`set_repo_topic`) - -Acceptance Criteria - -- Add a single topic to a repository's existing topic set, additively (`set_repo_topic`) - -### REQ-publish-005 - -The implementation SHALL satisfy the following criterion: Initialize git (if needed), commit working-tree contents, and force-push to `origin/main` using one-shot HTTP-Basic auth (`push_directory`) — token is never persisted in `.git/config` - -Acceptance Criteria - -- Initialize git (if needed), commit working-tree contents, and force-push to `origin/main` using one-shot HTTP-Basic auth (`push_directory`) — token is never persisted in `.git/config` - -### REQ-publish-006 - -The implementation SHALL satisfy the following criterion: Surface clear error messages for the common API failures: 422 (name conflict), 403 (insufficient scope) - -Acceptance Criteria - -- Surface clear error messages for the common API failures: 422 (name conflict), 403 (insufficient scope) - -### REQ-publish-007 - -The implementation SHALL satisfy the following criterion: Synchronous HTTP via `ureq` — no async runtime - -Acceptance Criteria - -- Synchronous HTTP via `ureq` — no async runtime - -### REQ-publish-008 - -The implementation SHALL satisfy the following criterion: Token never reaches the process table or git config — passed via `http.extraheader` env injection only - -Acceptance Criteria - -- Token never reaches the process table or git config — passed via `http.extraheader` env injection only - -### REQ-publish-009 - -The implementation SHALL satisfy the following criterion: No prompts in this module — caller decides whether to confirm - -Acceptance Criteria - -- No prompts in this module — caller decides whether to confirm diff --git a/specs/release/requirements.md b/specs/release/requirements.md index 06bd585e..bef3dfb8 100644 --- a/specs/release/requirements.md +++ b/specs/release/requirements.md @@ -1,5 +1,11 @@ # Release — Requirements +### REQ-release-001 + +The implementation SHALL satisfy the behavior described by this companion. + +Acceptance Criteria + 1. Bump version in language-specific files (Cargo.toml, package.json, pyproject.toml, etc.) 2. Support semver bump levels: major, minor, patch, or explicit version 3. Auto-detect project language to find version files @@ -10,85 +16,3 @@ 8. Support tag-only releases for languages without version files (Go, Swift) 9. Allow custom version files via [release] config in fledge.toml 10. Enforce clean working tree (with --allow-dirty override) - -## Durable Requirements - -### REQ-release-001 - -The implementation SHALL satisfy the following criterion: Bump version in language-specific files (Cargo.toml, package.json, pyproject.toml, etc.) - -Acceptance Criteria - -- Bump version in language-specific files (Cargo.toml, package.json, pyproject.toml, etc.) - -### REQ-release-002 - -The implementation SHALL satisfy the following criterion: Support semver bump levels: major, minor, patch, or explicit version - -Acceptance Criteria - -- Support semver bump levels: major, minor, patch, or explicit version - -### REQ-release-003 - -The implementation SHALL satisfy the following criterion: Auto-detect project language to find version files - -Acceptance Criteria - -- Auto-detect project language to find version files - -### REQ-release-004 - -The implementation SHALL satisfy the following criterion: Generate/update CHANGELOG.md from conventional commits since last tag - -Acceptance Criteria - -- Generate/update CHANGELOG.md from conventional commits since last tag - -### REQ-release-005 - -The implementation SHALL satisfy the following criterion: Create annotated git tags (vX.Y.Z) - -Acceptance Criteria - -- Create annotated git tags (vX.Y.Z) - -### REQ-release-006 - -The implementation SHALL satisfy the following criterion: Support dry-run mode that shows planned actions without changes - -Acceptance Criteria - -- Support dry-run mode that shows planned actions without changes - -### REQ-release-007 - -The implementation SHALL satisfy the following criterion: Support pre-release lane execution (run CI before releasing) - -Acceptance Criteria - -- Support pre-release lane execution (run CI before releasing) - -### REQ-release-008 - -The implementation SHALL satisfy the following criterion: Support tag-only releases for languages without version files (Go, Swift) - -Acceptance Criteria - -- Support tag-only releases for languages without version files (Go, Swift) - -### REQ-release-009 - -The implementation SHALL satisfy the following criterion: Allow custom version files via [release] config in fledge.toml - -Acceptance Criteria - -- Allow custom version files via [release] config in fledge.toml - -### REQ-release-010 - -The implementation SHALL satisfy the following criterion: Enforce clean working tree (with --allow-dirty override) - -Acceptance Criteria - -- Enforce clean working tree (with --allow-dirty override) diff --git a/specs/remote/requirements.md b/specs/remote/requirements.md index 82e2261d..301cb7db 100644 --- a/specs/remote/requirements.md +++ b/specs/remote/requirements.md @@ -2,70 +2,54 @@ ## Functional -- Clone GitHub repos to local cache for template discovery -- Support authenticated access via GitHub token -- Support `owner/repo` and `owner/repo/subpath` reference formats -- Update cached repos on subsequent access -- Shallow clones (`--depth 1`) to minimize bandwidth - -## Non-Functional - -- Cache location follows platform conventions (XDG on Linux, Library/Caches on macOS) -- Git operations should not leak tokens in stdout/stderr output - -## Durable Requirements - ### REQ-remote-001 -The implementation SHALL satisfy the following criterion: Clone GitHub repos to local cache for template discovery +The implementation SHALL satisfy this requirement. Acceptance Criteria - Clone GitHub repos to local cache for template discovery - ### REQ-remote-002 -The implementation SHALL satisfy the following criterion: Support authenticated access via GitHub token +The implementation SHALL satisfy this requirement. Acceptance Criteria - Support authenticated access via GitHub token - ### REQ-remote-003 -The implementation SHALL satisfy the following criterion: Support `owner/repo` and `owner/repo/subpath` reference formats +The implementation SHALL satisfy this requirement. Acceptance Criteria - Support `owner/repo` and `owner/repo/subpath` reference formats - ### REQ-remote-004 -The implementation SHALL satisfy the following criterion: Update cached repos on subsequent access +The implementation SHALL satisfy this requirement. Acceptance Criteria - Update cached repos on subsequent access - ### REQ-remote-005 -The implementation SHALL satisfy the following criterion: Shallow clones (`--depth 1`) to minimize bandwidth +The implementation SHALL satisfy this requirement. Acceptance Criteria - Shallow clones (`--depth 1`) to minimize bandwidth +## Non-Functional + ### REQ-remote-006 -The implementation SHALL satisfy the following criterion: Cache location follows platform conventions (XDG on Linux, Library/Caches on macOS) +The implementation SHALL satisfy this requirement. Acceptance Criteria - Cache location follows platform conventions (XDG on Linux, Library/Caches on macOS) - ### REQ-remote-007 -The implementation SHALL satisfy the following criterion: Git operations should not leak tokens in stdout/stderr output +The implementation SHALL satisfy this requirement. Acceptance Criteria diff --git a/specs/review/requirements.md b/specs/review/requirements.md index ef34f9e0..a5d1f86a 100644 --- a/specs/review/requirements.md +++ b/specs/review/requirements.md @@ -8,65 +8,51 @@ spec: review.spec.md - As a developer, I want to review changes against a specific base branch - As a developer, I want to review a single file's changes -## Durable Requirements +## Acceptance Criteria ### REQ-review-001 -The implementation SHALL satisfy the following criterion: `fledge review` diffs the current branch against the default base (main/master) and sends it to Claude CLI +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge review` diffs the current branch against the default base (main/master) and sends it to Claude CLI - ### REQ-review-002 -The implementation SHALL satisfy the following criterion: `fledge review --base develop` uses a custom base branch +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge review --base develop` uses a custom base branch - ### REQ-review-003 -The implementation SHALL satisfy the following criterion: `fledge review --file src/foo.rs` restricts the review to one file +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge review --file src/foo.rs` restricts the review to one file - ### REQ-review-004 -The implementation SHALL satisfy the following criterion: Diff stats are displayed before the AI output +The implementation SHALL satisfy this requirement. Acceptance Criteria - Diff stats are displayed before the AI output - ### REQ-review-005 -The implementation SHALL satisfy the following criterion: Empty diffs bail with a clear message +The implementation SHALL satisfy this requirement. Acceptance Criteria - Empty diffs bail with a clear message - ### REQ-review-006 -The implementation SHALL satisfy the following criterion: Missing Claude CLI produces install instructions +The implementation SHALL satisfy this requirement. Acceptance Criteria - Missing Claude CLI produces install instructions -## Acceptance Criteria - -- `fledge review` diffs the current branch against the default base (main/master) and sends it to Claude CLI -- `fledge review --base develop` uses a custom base branch -- `fledge review --file src/foo.rs` restricts the review to one file -- Diff stats are displayed before the AI output -- Empty diffs bail with a clear message -- Missing Claude CLI produces install instructions - ## Constraints - Requires Claude CLI (`claude`) installed and authenticated diff --git a/specs/run/requirements.md b/specs/run/requirements.md index 0347d500..683227e5 100644 --- a/specs/run/requirements.md +++ b/specs/run/requirements.md @@ -9,74 +9,58 @@ spec: run.spec.md - As a developer, I want to see all available tasks with `fledge run --list` - As a developer, I want `fledge run --init` to generate a starter task file for my project type -## Durable Requirements +## Acceptance Criteria ### REQ-run-001 -The implementation SHALL satisfy the following criterion: `fledge run ` executes the named task from `fledge.toml` +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge run ` executes the named task from `fledge.toml` - ### REQ-run-002 -The implementation SHALL satisfy the following criterion: Task dependencies run in topological order before the requested task +The implementation SHALL satisfy this requirement. Acceptance Criteria - Task dependencies run in topological order before the requested task - ### REQ-run-003 -The implementation SHALL satisfy the following criterion: Circular dependencies produce an error listing the cycle +The implementation SHALL satisfy this requirement. Acceptance Criteria - Circular dependencies produce an error listing the cycle - ### REQ-run-004 -The implementation SHALL satisfy the following criterion: `fledge run --list` shows task names and descriptions +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge run --list` shows task names and descriptions - ### REQ-run-005 -The implementation SHALL satisfy the following criterion: `fledge run --init` generates `fledge.toml` with defaults for the detected project type +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge run --init` generates `fledge.toml` with defaults for the detected project type - ### REQ-run-006 -The implementation SHALL satisfy the following criterion: Unknown task names produce an error listing available tasks +The implementation SHALL satisfy this requirement. Acceptance Criteria - Unknown task names produce an error listing available tasks - ### REQ-run-007 -The implementation SHALL satisfy the following criterion: Tasks support environment variables and working directory overrides +The implementation SHALL satisfy this requirement. Acceptance Criteria - Tasks support environment variables and working directory overrides -## Acceptance Criteria - -- `fledge run ` executes the named task from `fledge.toml` -- Task dependencies run in topological order before the requested task -- Circular dependencies produce an error listing the cycle -- `fledge run --list` shows task names and descriptions -- `fledge run --init` generates `fledge.toml` with defaults for the detected project type -- Unknown task names produce an error listing available tasks -- Tasks support environment variables and working directory overrides - ## Constraints - Tasks execute via `sh -c` — must work on macOS and Linux diff --git a/specs/search/requirements.md b/specs/search/requirements.md index 26bebe82..2ac22d5e 100644 --- a/specs/search/requirements.md +++ b/specs/search/requirements.md @@ -1,5 +1,11 @@ # Search — Requirements +### REQ-search-001 + +The implementation SHALL satisfy the behavior described by this companion. + +Acceptance Criteria + This module is a library — its requirements are about the helpers it exposes. The user-facing search commands (`templates search`, `lanes search`, `plugins search`) define their own requirements in their respective specs. ## Functional Requirements @@ -15,69 +21,3 @@ This module is a library — its requirements are about the helpers it exposes. 1. **NFR-1**: No async runtime dependency — callers use the blocking `ureq` client 2. **NFR-2**: No `serde` round-trip for the API response — direct `serde_json::Value` indexing keeps the dependency surface minimal - -## Durable Requirements - -### REQ-search-001 - -The implementation SHALL satisfy the following criterion: **FR-1**: Build a GitHub Search query string from `(topic, optional keyword, optional author)` — works for any topic, not just `fledge-template` - -Acceptance Criteria - -- **FR-1**: Build a GitHub Search query string from `(topic, optional keyword, optional author)` — works for any topic, not just `fledge-template` - -### REQ-search-002 - -The implementation SHALL satisfy the following criterion: **FR-2**: Parse a GitHub Search API response into a typed `Vec` with `(owner, name, description, stars, url, topics)` - -Acceptance Criteria - -- **FR-2**: Parse a GitHub Search API response into a typed `Vec` with `(owner, name, description, stars, url, topics)` - -### REQ-search-003 - -The implementation SHALL satisfy the following criterion: **FR-3**: Tolerate missing fields in the API response (description → "No description", stars → 0, topics → empty) - -Acceptance Criteria - -- **FR-3**: Tolerate missing fields in the API response (description → "No description", stars → 0, topics → empty) - -### REQ-search-004 - -The implementation SHALL satisfy the following criterion: **FR-4**: Format star counts compactly (`42`, `1.5k`, `123k`) - -Acceptance Criteria - -- **FR-4**: Format star counts compactly (`42`, `1.5k`, `123k`) - -### REQ-search-005 - -The implementation SHALL satisfy the following criterion: **FR-5**: Percent-encode strings for URL query parameters per RFC 3986 - -Acceptance Criteria - -- **FR-5**: Percent-encode strings for URL query parameters per RFC 3986 - -### REQ-search-006 - -The implementation SHALL satisfy the following criterion: **FR-6**: Skip items with no `owner.login` rather than failing the whole parse - -Acceptance Criteria - -- **FR-6**: Skip items with no `owner.login` rather than failing the whole parse - -### REQ-search-007 - -The implementation SHALL satisfy the following criterion: **NFR-1**: No async runtime dependency — callers use the blocking `ureq` client - -Acceptance Criteria - -- **NFR-1**: No async runtime dependency — callers use the blocking `ureq` client - -### REQ-search-008 - -The implementation SHALL satisfy the following criterion: **NFR-2**: No `serde` round-trip for the API response — direct `serde_json::Value` indexing keeps the dependency surface minimal - -Acceptance Criteria - -- **NFR-2**: No `serde` round-trip for the API response — direct `serde_json::Value` indexing keeps the dependency surface minimal diff --git a/specs/spec/requirements.md b/specs/spec/requirements.md index bc960a51..b51f0b69 100644 --- a/specs/spec/requirements.md +++ b/specs/spec/requirements.md @@ -9,83 +9,65 @@ spec: spec.spec.md - As a developer, I want `fledge spec new auth` to scaffold a complete spec module with companion files - As a developer, I want `--strict` mode to treat warnings as errors in CI -## Durable Requirements +## Acceptance Criteria ### REQ-spec-001 -The implementation SHALL satisfy the following criterion: `fledge spec check` validates all specs in the configured specs directory +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge spec check` validates all specs in the configured specs directory - ### REQ-spec-002 -The implementation SHALL satisfy the following criterion: `fledge spec check --strict` treats warnings as errors +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge spec check --strict` treats warnings as errors - ### REQ-spec-003 -The implementation SHALL satisfy the following criterion: `fledge spec init` creates `.specsync/` with config.toml, registry.toml, .gitignore, and version +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge spec init` creates `.specsync/` with config.toml, registry.toml, .gitignore, and version - ### REQ-spec-004 -The implementation SHALL satisfy the following criterion: `fledge spec init` creates `specs/` directory if it doesn't exist +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge spec init` creates `specs/` directory if it doesn't exist - ### REQ-spec-005 -The implementation SHALL satisfy the following criterion: `fledge spec new ` creates `specs//` with spec.md and companion files +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge spec new ` creates `specs//` with spec.md and companion files - ### REQ-spec-006 -The implementation SHALL satisfy the following criterion: Validation checks: frontmatter fields, required sections, source file existence +The implementation SHALL satisfy this requirement. Acceptance Criteria - Validation checks: frontmatter fields, required sections, source file existence - ### REQ-spec-007 -The implementation SHALL satisfy the following criterion: Exit code 1 on errors (or warnings in strict mode), 0 otherwise +The implementation SHALL satisfy this requirement. Acceptance Criteria - Exit code 1 on errors (or warnings in strict mode), 0 otherwise - ### REQ-spec-008 -The implementation SHALL satisfy the following criterion: Colored output with checkmarks/crosses for each spec +The implementation SHALL satisfy this requirement. Acceptance Criteria - Colored output with checkmarks/crosses for each spec -## Acceptance Criteria - -- `fledge spec check` validates all specs in the configured specs directory -- `fledge spec check --strict` treats warnings as errors -- `fledge spec init` creates `.specsync/` with config.toml, registry.toml, .gitignore, and version -- `fledge spec init` creates `specs/` directory if it doesn't exist -- `fledge spec new ` creates `specs//` with spec.md and companion files -- Validation checks: frontmatter fields, required sections, source file existence -- Exit code 1 on errors (or warnings in strict mode), 0 otherwise -- Colored output with checkmarks/crosses for each spec - ## Constraints - Must work without network access (no remote resolution) diff --git a/specs/spinner/requirements.md b/specs/spinner/requirements.md index 338b852a..1b1f0694 100644 --- a/specs/spinner/requirements.md +++ b/specs/spinner/requirements.md @@ -7,47 +7,37 @@ spec: spinner.spec.md - As a user, I want visual feedback during long-running operations so I know the CLI hasn't frozen - As a user, I want the spinner to clean up after itself so my terminal isn't cluttered -## Durable Requirements +## Acceptance Criteria ### REQ-spinner-001 -The implementation SHALL satisfy the following criterion: `Spinner::start(msg)` displays an animated spinner with the given message +The implementation SHALL satisfy this requirement. Acceptance Criteria - `Spinner::start(msg)` displays an animated spinner with the given message - ### REQ-spinner-002 -The implementation SHALL satisfy the following criterion: `Spinner::finish()` clears the spinner line completely +The implementation SHALL satisfy this requirement. Acceptance Criteria - `Spinner::finish()` clears the spinner line completely - ### REQ-spinner-003 -The implementation SHALL satisfy the following criterion: A random theme is chosen each time a spinner starts +The implementation SHALL satisfy this requirement. Acceptance Criteria - A random theme is chosen each time a spinner starts - ### REQ-spinner-004 -The implementation SHALL satisfy the following criterion: All themes animate smoothly without visual glitches +The implementation SHALL satisfy this requirement. Acceptance Criteria - All themes animate smoothly without visual glitches -## Acceptance Criteria - -- `Spinner::start(msg)` displays an animated spinner with the given message -- `Spinner::finish()` clears the spinner line completely -- A random theme is chosen each time a spinner starts -- All themes animate smoothly without visual glitches - ## Constraints - No external RNG dependency — use platform primitives only diff --git a/specs/templates/requirements.md b/specs/templates/requirements.md index a0d43989..1306bec5 100644 --- a/specs/templates/requirements.md +++ b/specs/templates/requirements.md @@ -11,119 +11,93 @@ spec: templates.spec.md - As a template author, I want `.tera` files to always be rendered with the extension stripped - As a template author, I want to use template variables in file and directory names -## Durable Requirements +## Acceptance Criteria ### REQ-templates-001 -The implementation SHALL satisfy the following criterion: `discover_templates()` finds all built-in templates (8 language starters: `go-cli`, `kotlin-kmp`, `kotlin-ktor-api`, `python-cli`, `rust-cli`, `static-site`, `ts-bun`, `ts-node`; plus setup-only `fledge-plugin` and `corvid-stack`) +The implementation SHALL satisfy this requirement. Acceptance Criteria - `discover_templates()` finds all built-in templates (8 language starters: `go-cli`, `kotlin-kmp`, `kotlin-ktor-api`, `python-cli`, `rust-cli`, `static-site`, `ts-bun`, `ts-node`; plus setup-only `fledge-plugin` and `corvid-stack`) - ### REQ-templates-002 -The implementation SHALL satisfy the following criterion: Extra paths from config are searched for template directories +The implementation SHALL satisfy this requirement. Acceptance Criteria - Extra paths from config are searched for template directories - ### REQ-templates-003 -The implementation SHALL satisfy the following criterion: Remote repos from config are fetched and searched for templates +The implementation SHALL satisfy this requirement. Acceptance Criteria - Remote repos from config are fetched and searched for templates - ### REQ-templates-004 -The implementation SHALL satisfy the following criterion: Templates are returned sorted alphabetically by name +The implementation SHALL satisfy this requirement. Acceptance Criteria - Templates are returned sorted alphabetically by name - ### REQ-templates-005 -The implementation SHALL satisfy the following criterion: Directories without `template.toml` are silently skipped +The implementation SHALL satisfy this requirement. Acceptance Criteria - Directories without `template.toml` are silently skipped - ### REQ-templates-006 -The implementation SHALL satisfy the following criterion: Non-existent extra paths are silently skipped +The implementation SHALL satisfy this requirement. Acceptance Criteria - Non-existent extra paths are silently skipped - ### REQ-templates-007 -The implementation SHALL satisfy the following criterion: `render_template()` renders `.tera` files and strips the extension +The implementation SHALL satisfy this requirement. Acceptance Criteria - `render_template()` renders `.tera` files and strips the extension - ### REQ-templates-008 -The implementation SHALL satisfy the following criterion: `render_template()` renders files matching `files.render` globs +The implementation SHALL satisfy this requirement. Acceptance Criteria - `render_template()` renders files matching `files.render` globs - ### REQ-templates-009 -The implementation SHALL satisfy the following criterion: `render_template()` copies non-matching files as-is +The implementation SHALL satisfy this requirement. Acceptance Criteria - `render_template()` copies non-matching files as-is - ### REQ-templates-010 -The implementation SHALL satisfy the following criterion: `render_template()` skips files matching `files.ignore` globs +The implementation SHALL satisfy this requirement. Acceptance Criteria - `render_template()` skips files matching `files.ignore` globs - ### REQ-templates-011 -The implementation SHALL satisfy the following criterion: `render_template()` renders Tera variables in file/directory paths +The implementation SHALL satisfy this requirement. Acceptance Criteria - `render_template()` renders Tera variables in file/directory paths - ### REQ-templates-012 -The implementation SHALL satisfy the following criterion: Created files list is returned sorted alphabetically +The implementation SHALL satisfy this requirement. Acceptance Criteria - Created files list is returned sorted alphabetically -## Acceptance Criteria - -- `discover_templates()` finds all built-in templates (8 language starters: `go-cli`, `kotlin-kmp`, `kotlin-ktor-api`, `python-cli`, `rust-cli`, `static-site`, `ts-bun`, `ts-node`; plus setup-only `fledge-plugin` and `corvid-stack`) -- Extra paths from config are searched for template directories -- Remote repos from config are fetched and searched for templates -- Templates are returned sorted alphabetically by name -- Directories without `template.toml` are silently skipped -- Non-existent extra paths are silently skipped -- `render_template()` renders `.tera` files and strips the extension -- `render_template()` renders files matching `files.render` globs -- `render_template()` copies non-matching files as-is -- `render_template()` skips files matching `files.ignore` globs -- `render_template()` renders Tera variables in file/directory paths -- Created files list is returned sorted alphabetically - ## Constraints - Embedded templates use `include_dir!` — binary size includes all template files diff --git a/specs/trust/requirements.md b/specs/trust/requirements.md index 30bebb26..6bc849cb 100644 --- a/specs/trust/requirements.md +++ b/specs/trust/requirements.md @@ -7,83 +7,65 @@ spec: trust.spec.md - As a user installing plugins/templates/lanes, I want to see whether the source is local, official, team, or unverified so I can make informed trust decisions - As a module author, I want a shared trust classification function so all extension types use consistent logic -## Durable Requirements +## Acceptance Criteria ### REQ-trust-001 -The implementation SHALL satisfy the following criterion: `determine_trust_tier` classifies `CorvidLabs/*` sources as Official +The implementation SHALL satisfy this requirement. Acceptance Criteria - `determine_trust_tier` classifies `CorvidLabs/*` sources as Official - ### REQ-trust-002 -The implementation SHALL satisfy the following criterion: `determine_trust_tier` classifies filesystem path sources as Local +The implementation SHALL satisfy this requirement. Acceptance Criteria - `determine_trust_tier` classifies filesystem path sources as Local - ### REQ-trust-003 -The implementation SHALL satisfy the following criterion: `determine_trust_tier` classifies sources owned by a human member of the CorvidLabs org (e.g. `0xLeif/*`) as Team +The implementation SHALL satisfy this requirement. Acceptance Criteria - `determine_trust_tier` classifies sources owned by a human member of the CorvidLabs org (e.g. `0xLeif/*`) as Team - ### REQ-trust-004 -The implementation SHALL satisfy the following criterion: `determine_trust_tier` classifies all other sources as Unverified +The implementation SHALL satisfy this requirement. Acceptance Criteria - `determine_trust_tier` classifies all other sources as Unverified - ### REQ-trust-005 -The implementation SHALL satisfy the following criterion: Supports local paths, HTTPS URLs, SSH URLs, and `owner/repo` shorthand +The implementation SHALL satisfy this requirement. Acceptance Criteria - Supports local paths, HTTPS URLs, SSH URLs, and `owner/repo` shorthand - ### REQ-trust-006 -The implementation SHALL satisfy the following criterion: `parse_source_ref` splits `source@ref` without false-splitting on credential `@` signs +The implementation SHALL satisfy this requirement. Acceptance Criteria - `parse_source_ref` splits `source@ref` without false-splitting on credential `@` signs - ### REQ-trust-007 -The implementation SHALL satisfy the following criterion: `label` returns lowercase string representation +The implementation SHALL satisfy this requirement. Acceptance Criteria - `label` returns lowercase string representation - ### REQ-trust-008 -The implementation SHALL satisfy the following criterion: `styled_label` returns colored console output (magenta=local, green=official, cyan=team, yellow=unverified) +The implementation SHALL satisfy this requirement. Acceptance Criteria - `styled_label` returns colored console output (magenta=local, green=official, cyan=team, yellow=unverified) -## Acceptance Criteria - -- `determine_trust_tier` classifies `CorvidLabs/*` sources as Official -- `determine_trust_tier` classifies filesystem path sources as Local -- `determine_trust_tier` classifies sources owned by a human member of the CorvidLabs org (e.g. `0xLeif/*`) as Team -- `determine_trust_tier` classifies all other sources as Unverified -- Supports local paths, HTTPS URLs, SSH URLs, and `owner/repo` shorthand -- `parse_source_ref` splits `source@ref` without false-splitting on credential `@` signs -- `label` returns lowercase string representation -- `styled_label` returns colored console output (magenta=local, green=official, cyan=team, yellow=unverified) - ## Constraints - Case-sensitive org matching for `OFFICIAL_ORGS` (handled via duplicate entries: `CorvidLabs`, `corvidlabs`) diff --git a/specs/utils/requirements.md b/specs/utils/requirements.md index 26d8da15..ec1522e5 100644 --- a/specs/utils/requirements.md +++ b/specs/utils/requirements.md @@ -10,92 +10,72 @@ spec: utils.spec.md - As a security-conscious maintainer, I want project names, GitHub orgs, and commit scopes validated before they reach the filesystem or an LLM prompt - As a user, I want credentials scrubbed out of error messages so tokens never leak into logs or terminal output -## Durable Requirements +## Acceptance Criteria ### REQ-utils-001 -The implementation SHALL satisfy the following criterion: `set_non_interactive` / `is_non_interactive` are the only accessors to the global flag +The implementation SHALL satisfy this requirement. Acceptance Criteria - `set_non_interactive` / `is_non_interactive` are the only accessors to the global flag - ### REQ-utils-002 -The implementation SHALL satisfy the following criterion: `init_non_interactive_from_env` flips the flag when `FLEDGE_NON_INTERACTIVE` is a truthy value (`1`/`true`/`yes`/`y`/`on`, case-insensitive, trimmed) +The implementation SHALL satisfy this requirement. Acceptance Criteria - `init_non_interactive_from_env` flips the flag when `FLEDGE_NON_INTERACTIVE` is a truthy value (`1`/`true`/`yes`/`y`/`on`, case-insensitive, trimmed) - ### REQ-utils-003 -The implementation SHALL satisfy the following criterion: `is_interactive` returns true only when stdin is a TTY and the non-interactive flag is unset +The implementation SHALL satisfy this requirement. Acceptance Criteria - `is_interactive` returns true only when stdin is a TTY and the non-interactive flag is unset - ### REQ-utils-004 -The implementation SHALL satisfy the following criterion: `require_interactive` / `require_interactive_hint` return `Ok(())` only when `is_interactive`, otherwise bail with a flag- or hint-named error +The implementation SHALL satisfy this requirement. Acceptance Criteria - `require_interactive` / `require_interactive_hint` return `Ok(())` only when `is_interactive`, otherwise bail with a flag- or hint-named error - ### REQ-utils-005 -The implementation SHALL satisfy the following criterion: Case conversions are pure and total — any input (including empty) returns a `String` without panicking +The implementation SHALL satisfy this requirement. Acceptance Criteria - Case conversions are pure and total — any input (including empty) returns a `String` without panicking - ### REQ-utils-006 -The implementation SHALL satisfy the following criterion: `validate_project_name` rejects empty strings, `/`, `\`, `..`, null bytes, and Windows-reserved device names +The implementation SHALL satisfy this requirement. Acceptance Criteria - `validate_project_name` rejects empty strings, `/`, `\`, `..`, null bytes, and Windows-reserved device names - ### REQ-utils-007 -The implementation SHALL satisfy the following criterion: `validate_github_org` rejects empty and slash-containing names but permits spaces +The implementation SHALL satisfy this requirement. Acceptance Criteria - `validate_github_org` rejects empty and slash-containing names but permits spaces - ### REQ-utils-008 -The implementation SHALL satisfy the following criterion: `validate_commit_scope` requires non-empty, ≤64 chars, ASCII alphanumerics plus `-`/`_` +The implementation SHALL satisfy this requirement. Acceptance Criteria - `validate_commit_scope` requires non-empty, ≤64 chars, ASCII alphanumerics plus `-`/`_` - ### REQ-utils-009 -The implementation SHALL satisfy the following criterion: `redact_secrets` scrubs Authorization / x-access-token headers, URL credentials, and Bearer tokens; clean input passes through byte-identical +The implementation SHALL satisfy this requirement. Acceptance Criteria - `redact_secrets` scrubs Authorization / x-access-token headers, URL credentials, and Bearer tokens; clean input passes through byte-identical -## Acceptance Criteria - -- `set_non_interactive` / `is_non_interactive` are the only accessors to the global flag -- `init_non_interactive_from_env` flips the flag when `FLEDGE_NON_INTERACTIVE` is a truthy value (`1`/`true`/`yes`/`y`/`on`, case-insensitive, trimmed) -- `is_interactive` returns true only when stdin is a TTY and the non-interactive flag is unset -- `require_interactive` / `require_interactive_hint` return `Ok(())` only when `is_interactive`, otherwise bail with a flag- or hint-named error -- Case conversions are pure and total — any input (including empty) returns a `String` without panicking -- `validate_project_name` rejects empty strings, `/`, `\`, `..`, null bytes, and Windows-reserved device names -- `validate_github_org` rejects empty and slash-containing names but permits spaces -- `validate_commit_scope` requires non-empty, ≤64 chars, ASCII alphanumerics plus `-`/`_` -- `redact_secrets` scrubs Authorization / x-access-token headers, URL credentials, and Bearer tokens; clean input passes through byte-identical - ## Constraints - The non-interactive flag is a single `AtomicBool` shared across the process — tests must serialize on a guard diff --git a/specs/validate/requirements.md b/specs/validate/requirements.md index ed125613..597eb4f6 100644 --- a/specs/validate/requirements.md +++ b/specs/validate/requirements.md @@ -8,56 +8,44 @@ spec: validate.spec.md - As a CI pipeline, I want to validate templates in strict mode so broken templates don't get merged - As a developer, I want machine-readable validation output so I can integrate it into tooling -## Durable Requirements +## Acceptance Criteria ### REQ-validate-001 -The implementation SHALL satisfy the following criterion: Single template validation checks manifest, Tera syntax, variable definitions, and render globs +The implementation SHALL satisfy this requirement. Acceptance Criteria - Single template validation checks manifest, Tera syntax, variable definitions, and render globs - ### REQ-validate-002 -The implementation SHALL satisfy the following criterion: Batch validation validates all templates in a directory independently +The implementation SHALL satisfy this requirement. Acceptance Criteria - Batch validation validates all templates in a directory independently - ### REQ-validate-003 -The implementation SHALL satisfy the following criterion: Strict mode exits non-zero on warnings +The implementation SHALL satisfy this requirement. Acceptance Criteria - Strict mode exits non-zero on warnings - ### REQ-validate-004 -The implementation SHALL satisfy the following criterion: JSON mode outputs structured ValidationReport array +The implementation SHALL satisfy this requirement. Acceptance Criteria - JSON mode outputs structured ValidationReport array - ### REQ-validate-005 -The implementation SHALL satisfy the following criterion: GitHub Actions `${{ }}` expressions are not flagged as Tera variables +The implementation SHALL satisfy this requirement. Acceptance Criteria - GitHub Actions `${{ }}` expressions are not flagged as Tera variables -## Acceptance Criteria - -- Single template validation checks manifest, Tera syntax, variable definitions, and render globs -- Batch validation validates all templates in a directory independently -- Strict mode exits non-zero on warnings -- JSON mode outputs structured ValidationReport array -- GitHub Actions `${{ }}` expressions are not flagged as Tera variables - ## Constraints - Must not modify any template files during validation diff --git a/specs/versioning/requirements.md b/specs/versioning/requirements.md index 2a06ac5e..7e679952 100644 --- a/specs/versioning/requirements.md +++ b/specs/versioning/requirements.md @@ -1,49 +1,13 @@ # Versioning — Requirements -1. Parse semver strings (MAJOR.MINOR.PATCH) -2. Compare versions correctly (0.2.1 > 0.2.0, 1.0.0 > 0.99.99) -3. Check `min_fledge_version` against compile-time fledge version -4. Return actionable error messages with upgrade instructions -5. Handle optional leading `v` prefix (v1.2.3 → 1.2.3) - -## Durable Requirements - ### REQ-versioning-001 -The implementation SHALL satisfy the following criterion: Parse semver strings (MAJOR.MINOR.PATCH) - -Acceptance Criteria - -- Parse semver strings (MAJOR.MINOR.PATCH) - -### REQ-versioning-002 - -The implementation SHALL satisfy the following criterion: Compare versions correctly (0.2.1 > 0.2.0, 1.0.0 > 0.99.99) - -Acceptance Criteria - -- Compare versions correctly (0.2.1 > 0.2.0, 1.0.0 > 0.99.99) - -### REQ-versioning-003 - -The implementation SHALL satisfy the following criterion: Check `min_fledge_version` against compile-time fledge version - -Acceptance Criteria - -- Check `min_fledge_version` against compile-time fledge version - -### REQ-versioning-004 - -The implementation SHALL satisfy the following criterion: Return actionable error messages with upgrade instructions - -Acceptance Criteria - -- Return actionable error messages with upgrade instructions - -### REQ-versioning-005 - -The implementation SHALL satisfy the following criterion: Handle optional leading `v` prefix (v1.2.3 → 1.2.3) +The implementation SHALL satisfy the behavior described by this companion. Acceptance Criteria -- Handle optional leading `v` prefix (v1.2.3 → 1.2.3) +1. Parse semver strings (MAJOR.MINOR.PATCH) +2. Compare versions correctly (0.2.1 > 0.2.0, 1.0.0 > 0.99.99) +3. Check `min_fledge_version` against compile-time fledge version +4. Return actionable error messages with upgrade instructions +5. Handle optional leading `v` prefix (v1.2.3 → 1.2.3) diff --git a/specs/watch/requirements.md b/specs/watch/requirements.md index efd15a47..0f0e0925 100644 --- a/specs/watch/requirements.md +++ b/specs/watch/requirements.md @@ -4,76 +4,58 @@ spec: watch.spec.md ## Requirements -- Watch a directory recursively for filesystem changes -- Re-run a specified task or lane when relevant files change -- Filter events by file extension (optional) -- Ignore common non-source directories (.git, target, node_modules, .fledge, __pycache__) -- Configurable debounce interval with deadline extension on new events -- Perform an initial run before entering the watch loop -- Optional terminal clear before each re-run -- Graceful error handling — target failures don't stop the watcher - -## Durable Requirements - ### REQ-watch-001 -The implementation SHALL satisfy the following criterion: Watch a directory recursively for filesystem changes +The implementation SHALL satisfy this requirement. Acceptance Criteria - Watch a directory recursively for filesystem changes - ### REQ-watch-002 -The implementation SHALL satisfy the following criterion: Re-run a specified task or lane when relevant files change +The implementation SHALL satisfy this requirement. Acceptance Criteria - Re-run a specified task or lane when relevant files change - ### REQ-watch-003 -The implementation SHALL satisfy the following criterion: Filter events by file extension (optional) +The implementation SHALL satisfy this requirement. Acceptance Criteria - Filter events by file extension (optional) - ### REQ-watch-004 -The implementation SHALL satisfy the following criterion: Ignore common non-source directories (.git, target, node_modules, .fledge, __pycache__) +The implementation SHALL satisfy this requirement. Acceptance Criteria - Ignore common non-source directories (.git, target, node_modules, .fledge, __pycache__) - ### REQ-watch-005 -The implementation SHALL satisfy the following criterion: Configurable debounce interval with deadline extension on new events +The implementation SHALL satisfy this requirement. Acceptance Criteria - Configurable debounce interval with deadline extension on new events - ### REQ-watch-006 -The implementation SHALL satisfy the following criterion: Perform an initial run before entering the watch loop +The implementation SHALL satisfy this requirement. Acceptance Criteria - Perform an initial run before entering the watch loop - ### REQ-watch-007 -The implementation SHALL satisfy the following criterion: Optional terminal clear before each re-run +The implementation SHALL satisfy this requirement. Acceptance Criteria - Optional terminal clear before each re-run - ### REQ-watch-008 -The implementation SHALL satisfy the following criterion: Graceful error handling — target failures don't stop the watcher +The implementation SHALL satisfy this requirement. Acceptance Criteria diff --git a/specs/work/requirements.md b/specs/work/requirements.md index fe4211f0..99991d15 100644 --- a/specs/work/requirements.md +++ b/specs/work/requirements.md @@ -14,182 +14,142 @@ spec: work.spec.md - As a developer, I want `fledge work push` to push my branch to origin with tracking - As a developer, I want `fledge work status` to see my branch state (ahead/behind, dirty files) -## Durable Requirements +## Acceptance Criteria ### REQ-work-001 -The implementation SHALL satisfy the following criterion: `fledge work start ` creates a branch using the configured format (default: `{author}/{type}/{name}`) +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge work start ` creates a branch using the configured format (default: `{author}/{type}/{name}`) - ### REQ-work-002 -The implementation SHALL satisfy the following criterion: `fledge work start --branch-type fix` creates a fix-type branch +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge work start --branch-type fix` creates a fix-type branch - ### REQ-work-003 -The implementation SHALL satisfy the following criterion: `fledge work start --issue 42` includes issue number in branch name +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge work start --issue 42` includes issue number in branch name - ### REQ-work-004 -The implementation SHALL satisfy the following criterion: `fledge work start --prefix user/leif` creates `user/leif/` branch +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge work start --prefix user/leif` creates `user/leif/` branch - ### REQ-work-005 -The implementation SHALL satisfy the following criterion: `fledge work start` refuses if working tree is dirty +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge work start` refuses if working tree is dirty - ### REQ-work-006 -The implementation SHALL satisfy the following criterion: `fledge work start` rejects invalid branch types (not in feat, feature, fix, bug, chore, task, docs, hotfix, refactor) +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge work start` rejects invalid branch types (not in feat, feature, fix, bug, chore, task, docs, hotfix, refactor) - ### REQ-work-007 -The implementation SHALL satisfy the following criterion: `fledge work commit` stages all changes and creates a commit (prompts for type + message interactively) +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge work commit` stages all changes and creates a commit (prompts for type + message interactively) - ### REQ-work-008 -The implementation SHALL satisfy the following criterion: `fledge work commit -m "message"` uses the given message with default type +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge work commit -m "message"` uses the given message with default type - ### REQ-work-009 -The implementation SHALL satisfy the following criterion: `fledge work commit --type fix -m "null pointer"` creates `fix: null pointer` commit +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge work commit --type fix -m "null pointer"` creates `fix: null pointer` commit - ### REQ-work-010 -The implementation SHALL satisfy the following criterion: `fledge work commit --ai` generates the commit message from staged diff using the configured AI provider +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge work commit --ai` generates the commit message from staged diff using the configured AI provider - ### REQ-work-011 -The implementation SHALL satisfy the following criterion: `fledge work commit` refuses if there are no changes to commit +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge work commit` refuses if there are no changes to commit - ### REQ-work-012 -The implementation SHALL satisfy the following criterion: `fledge work push` pushes the current branch to origin with `-u` tracking +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge work push` pushes the current branch to origin with `-u` tracking - ### REQ-work-013 -The implementation SHALL satisfy the following criterion: `fledge work push` refuses if on the default branch +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge work push` refuses if on the default branch - ### REQ-work-014 -The implementation SHALL satisfy the following criterion: `fledge work push` refuses if there are no commits ahead of the remote +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge work push` refuses if there are no commits ahead of the remote - ### REQ-work-015 -The implementation SHALL satisfy the following criterion: `fledge work status` shows branch name, commits ahead/behind, and uncommitted file count +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge work status` shows branch name, commits ahead/behind, and uncommitted file count - ### REQ-work-016 -The implementation SHALL satisfy the following criterion: `fledge work status` does NOT call `gh` or any GitHub API — pure git only +The implementation SHALL satisfy this requirement. Acceptance Criteria - `fledge work status` does NOT call `gh` or any GitHub API — pure git only - ### REQ-work-017 -The implementation SHALL satisfy the following criterion: Branch names are sanitized (lowercase, hyphens only) +The implementation SHALL satisfy this requirement. Acceptance Criteria - Branch names are sanitized (lowercase, hyphens only) - ### REQ-work-018 -The implementation SHALL satisfy the following criterion: `[work]` section in `fledge.toml` can override `branch_format` and `default_type` +The implementation SHALL satisfy this requirement. Acceptance Criteria - `[work]` section in `fledge.toml` can override `branch_format` and `default_type` - ### REQ-work-019 -The implementation SHALL satisfy the following criterion: All subcommands support `--json` for agent consumption +The implementation SHALL satisfy this requirement. Acceptance Criteria - All subcommands support `--json` for agent consumption -## Acceptance Criteria - -- `fledge work start ` creates a branch using the configured format (default: `{author}/{type}/{name}`) -- `fledge work start --branch-type fix` creates a fix-type branch -- `fledge work start --issue 42` includes issue number in branch name -- `fledge work start --prefix user/leif` creates `user/leif/` branch -- `fledge work start` refuses if working tree is dirty -- `fledge work start` rejects invalid branch types (not in feat, feature, fix, bug, chore, task, docs, hotfix, refactor) -- `fledge work commit` stages all changes and creates a commit (prompts for type + message interactively) -- `fledge work commit -m "message"` uses the given message with default type -- `fledge work commit --type fix -m "null pointer"` creates `fix: null pointer` commit -- `fledge work commit --ai` generates the commit message from staged diff using the configured AI provider -- `fledge work commit` refuses if there are no changes to commit -- `fledge work push` pushes the current branch to origin with `-u` tracking -- `fledge work push` refuses if on the default branch -- `fledge work push` refuses if there are no commits ahead of the remote -- `fledge work status` shows branch name, commits ahead/behind, and uncommitted file count -- `fledge work status` does NOT call `gh` or any GitHub API — pure git only -- Branch names are sanitized (lowercase, hyphens only) -- `[work]` section in `fledge.toml` can override `branch_format` and `default_type` -- All subcommands support `--json` for agent consumption - ## Constraints - Requires git CLI for all operations From cf0c37ea4a5aed056a601f063ad9f41ad3d04bd2 Mon Sep 17 00:00:00 2001 From: 0xLeif Date: Sun, 12 Jul 2026 09:46:25 -0600 Subject: [PATCH 06/25] Fix: address rollout review feedback --- .cursor/commands/specsync-create-spec.md | 9 ++++---- .gemini/commands/specsync/create-change.toml | 2 +- .gemini/commands/specsync/create-spec.toml | 11 +++++----- .github/workflows/ci.yml | 4 ++-- .specsync/sdd.json | 10 ++++++--- AGENTS.md | 3 ++- templates/corvid-stack/.augur.toml | 3 +++ .../corvid-stack/.github/workflows/trust.yml | 2 +- templates/corvid-stack/.specsync/sdd.json | 8 +++++-- templates/corvid-stack/.trust.toml | 2 +- templates/corvid-stack/README.md.tera | 21 ++++++++++--------- 11 files changed, 43 insertions(+), 32 deletions(-) create mode 100644 templates/corvid-stack/.augur.toml diff --git a/.cursor/commands/specsync-create-spec.md b/.cursor/commands/specsync-create-spec.md index 0f20b4c4..84b88c73 100644 --- a/.cursor/commands/specsync-create-spec.md +++ b/.cursor/commands/specsync-create-spec.md @@ -2,12 +2,11 @@ Create a new spec-sync module spec. Arguments: $ARGUMENTS -1. Parse the arguments above: the first whitespace-separated token is the - module name. If the arguments also contain `--minimal` (in any position), - remove it and remember that minimal mode was requested. -2. Look at whatever text remains. It will be one of: +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`. Use it as-is. + `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 diff --git a/.gemini/commands/specsync/create-change.toml b/.gemini/commands/specsync/create-change.toml index b4b7de66..bf8185af 100644 --- a/.gemini/commands/specsync/create-change.toml +++ b/.gemini/commands/specsync/create-change.toml @@ -3,7 +3,7 @@ description = "Create and guide a verified spec-sync SDD change through its dete prompt = """ Arguments: {{args}} -1. Run `specsync change new "$ARGUMENTS" --json`. +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`. 4. Continue until the question list is empty, then show the selected artifacts and next action. diff --git a/.gemini/commands/specsync/create-spec.toml b/.gemini/commands/specsync/create-spec.toml index 73789f1f..6d347924 100644 --- a/.gemini/commands/specsync/create-spec.toml +++ b/.gemini/commands/specsync/create-spec.toml @@ -5,12 +5,11 @@ Create a new spec-sync module spec. Arguments: {{args}} -1. Parse the arguments above: the first whitespace-separated token is the - module name. If the arguments also contain --minimal (in any position), - remove it and remember that minimal mode was requested. -2. Look at whatever text remains. It will be one of: - - A bare module name - a short identifier like auth-service or billing. - Use it as-is. +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 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cdf56f92..28f88e29 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -196,7 +196,7 @@ jobs: attest: name: Record attestation runs-on: ubuntu-latest - needs: [test, lint, audit, spec-check] + needs: [test, lint, audit, spec-check, integration] if: github.event_name == 'push' && github.ref == 'refs/heads/main' # contents: write lets the step push refs/notes/attest. permissions: @@ -224,7 +224,7 @@ jobs: git config user.name "github-actions[bot]" git fetch origin "+refs/notes/attest:refs/notes/attest" 2>/dev/null || true if "$bin" sign --commit HEAD --reviewer agent:ci --confidence 0.9 --tests-passed \ - --verdict proceed --note "CI: cargo test + lint + audit + spec-check green" \ + --verdict proceed --note "CI: tests + integration + lint + audit + spec-check green" \ && git push origin refs/notes/attest ; then echo "attestation recorded for $(git rev-parse --short HEAD)" else diff --git a/.specsync/sdd.json b/.specsync/sdd.json index 7dd7a06a..0f20b3be 100644 --- a/.specsync/sdd.json +++ b/.specsync/sdd.json @@ -26,14 +26,18 @@ ".specsync/config.toml", ".specsync/config.json", ".specsync/version", - "templates/" + "templates/", + "fledge.toml", + ".trust.toml", + ".augur.toml", + ".attest.json", + "AGENTS.md" ], "ignored_paths": [ - ".specsync/", "specs/" ], "verification_commands": [ - "cargo test" + "fledge lanes run verify" ], "custom_artifacts": {}, "principles_file": null diff --git a/AGENTS.md b/AGENTS.md index 0886de51..e117651c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -372,7 +372,8 @@ The project explicitly welcomes agent-surface improvements. This repository uses one trust gate. Every session must use it and must not bypass or weaken it. -- Run `fledge trust verify` before calling a change complete. +- Install the `corvid-trust` bundle so `fledge trust` is available, then 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. diff --git a/templates/corvid-stack/.augur.toml b/templates/corvid-stack/.augur.toml new file mode 100644 index 00000000..031b4599 --- /dev/null +++ b/templates/corvid-stack/.augur.toml @@ -0,0 +1,3 @@ +[thresholds] +review = 35 +block = 65 diff --git a/templates/corvid-stack/.github/workflows/trust.yml b/templates/corvid-stack/.github/workflows/trust.yml index 55e58b90..a320c89c 100644 --- a/templates/corvid-stack/.github/workflows/trust.yml +++ b/templates/corvid-stack/.github/workflows/trust.yml @@ -12,7 +12,7 @@ jobs: trust: runs-on: ubuntu-latest steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v4.1.6 with: fetch-depth: 0 diff --git a/templates/corvid-stack/.specsync/sdd.json b/templates/corvid-stack/.specsync/sdd.json index b78d8d88..a7522094 100644 --- a/templates/corvid-stack/.specsync/sdd.json +++ b/templates/corvid-stack/.specsync/sdd.json @@ -12,10 +12,14 @@ "bun.lock", ".specsync/sdd.json", ".specsync/config.toml", - ".specsync/version" + ".specsync/version", + "fledge.toml", + ".trust.toml", + ".augur.toml", + ".attest.json", + "AGENTS.md" ], "ignored_paths": [ - ".specsync/", "specs/" ], "verification_commands": [ diff --git a/templates/corvid-stack/.trust.toml b/templates/corvid-stack/.trust.toml index 242a92b5..dd9cad74 100644 --- a/templates/corvid-stack/.trust.toml +++ b/templates/corvid-stack/.trust.toml @@ -6,7 +6,7 @@ command = ["fledge", "lanes", "run", "verify"] [contract] enabled = true -require_coverage = 100 +require_coverage = 0 skip_reason = "" [risk] diff --git a/templates/corvid-stack/README.md.tera b/templates/corvid-stack/README.md.tera index 1ff6f187..c2cb7399 100644 --- a/templates/corvid-stack/README.md.tera +++ b/templates/corvid-stack/README.md.tera @@ -11,8 +11,10 @@ that gates every change through four tools. See https://corvidlabs.xyz/integrate |------|---------| | `fledge.toml` | Tasks plus the `verify` lane (the single quality gate) | | `.specsync/config.toml` | spec-sync configuration (spec-as-contract validation) | +| `.trust.toml` | unified Trust profile and component policy | +| `.augur.toml` | deterministic change-risk thresholds | | `.attest.json` | attestation policy (provenance verification) | -| `.github/workflows/trust.yml` | CI: fledge, spec-sync, augur, attest | +| `.github/workflows/trust.yml` | CI: unified Trust 1 gate | | `AGENTS.md` | Agent/human rules, incl. the managed trust-toolchain block | > Dropping this onto an existing repo? Merge the `.gitignore` and `AGENTS.md` @@ -23,15 +25,14 @@ that gates every change through four tools. See https://corvidlabs.xyz/integrate ```bash # Install the toolchain (macOS shown; see the guide for Linux/cargo) -brew install CorvidLabs/tap/fledge -cargo install specsync -# augur + attest run as GitHub Actions in trust.yml +brew install CorvidLabs/tap/corvid-trust # Wire up your stack's tasks (auto-detects Rust, Node, Go, Python, Ruby, Java, Swift) fledge run --init # Run the gate locally -fledge lanes run verify +fledge trust doctor +fledge trust verify ``` Then fill in the `[tasks]` in `fledge.toml`, set `source_dirs` in @@ -40,8 +41,8 @@ Then fill in the `[tasks]` in `fledge.toml`, set `source_dirs` in ## The gate -Every push and PR runs `.github/workflows/trust.yml` as **five parallel checks**, -so a failure points straight at the tool: +Every push and PR runs one required `trust` job. Its component status outputs and +summary identify which layer failed: - **fledge** `lanes run verify`: fmt + lint + test + build - **spec-sync**: specs match code (soft until specs land) @@ -49,6 +50,6 @@ so a failure points straight at the tool: - **attest**: provenance verified against `.attest.json` - **rules**: the managed `AGENTS.md` trust block must be present -They run independently because, in verify form, none consumes another's output. -If you later switch attest to `sign --from-augur` (which needs augur's verdict -and the test result), make the attest job `needs: [augur, fledge]`. +The template starts with advisory contract coverage (`0`) because it contains no +source files or canonical companions. Raise `contract.require_coverage` as specs +are adopted; new specified behavior should reach 100%. From 2f5a7d62ddb49670e0519bf98255f79cda5f4831 Mon Sep 17 00:00:00 2001 From: 0xLeif Date: Sun, 12 Jul 2026 16:31:14 -0600 Subject: [PATCH 07/25] fix(governance): track Claude SpecSync integration --- .claude/commands/specsync/create-change.md | 10 +++ .claude/commands/specsync/create-spec.md | 40 ++++++++++++ .claude/skills/spec-sync/SKILL.md | 75 ++++++++++++++++++++++ 3 files changed, 125 insertions(+) create mode 100644 .claude/commands/specsync/create-change.md create mode 100644 .claude/commands/specsync/create-spec.md create mode 100644 .claude/skills/spec-sync/SKILL.md diff --git a/.claude/commands/specsync/create-change.md b/.claude/commands/specsync/create-change.md new file mode 100644 index 00000000..04707ccc --- /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`. +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 00000000..a424e764 --- /dev/null +++ b/.claude/commands/specsync/create-spec.md @@ -0,0 +1,40 @@ +--- +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. Parse the arguments above: the first whitespace-separated token is the + module name. If the arguments also contain `--minimal` (in any position), + remove it and remember that minimal mode was requested. +2. Look at whatever text remains. It will be one of: + - **A bare module name** — a short identifier like `auth-service` or + `billing`. 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 00000000..de24d12d --- /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 From 947f269dfde1b5f2bee3c049c6ed98e2846fde6a Mon Sep 17 00:00:00 2001 From: 0xLeif Date: Sun, 12 Jul 2026 16:44:09 -0600 Subject: [PATCH 08/25] fix(ci): run non-recursive Fledge spec evidence --- .github/workflows/ci.yml | 5 +++++ .specsync/sdd.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 28f88e29..f7bb78e6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -113,6 +113,11 @@ jobs: - uses: actions/checkout@v5 with: fetch-depth: 0 + - uses: dtolnay/rust-toolchain@stable + - name: Build the branch Fledge CLI + run: cargo build --release --locked + - name: Add the branch Fledge CLI to PATH + run: echo "${{ github.workspace }}/target/release" >> "$GITHUB_PATH" - name: Run spec-sync id: specsync uses: CorvidLabs/spec-sync@59bbfa766c6cce01ab815ab47db195b0629cc014 # v5.0.1 diff --git a/.specsync/sdd.json b/.specsync/sdd.json index 0f20b3be..9ea4702b 100644 --- a/.specsync/sdd.json +++ b/.specsync/sdd.json @@ -37,7 +37,7 @@ "specs/" ], "verification_commands": [ - "fledge lanes run verify" + "fledge run test" ], "custom_artifacts": {}, "principles_file": null From de0cd815390452df659bdabac7202f0626c6b9f5 Mon Sep 17 00:00:00 2001 From: 0xLeif Date: Sun, 12 Jul 2026 16:54:28 -0600 Subject: [PATCH 09/25] fix(ci): avoid nested Fledge test execution --- .specsync/sdd.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.specsync/sdd.json b/.specsync/sdd.json index 9ea4702b..44b9ed20 100644 --- a/.specsync/sdd.json +++ b/.specsync/sdd.json @@ -37,7 +37,7 @@ "specs/" ], "verification_commands": [ - "fledge run test" + "fledge run validate-templates" ], "custom_artifacts": {}, "principles_file": null From 79de4d6eff016ab0d0f102216dd6f9ae5232a579 Mon Sep 17 00:00:00 2001 From: 0xLeif Date: Sun, 12 Jul 2026 16:56:23 -0600 Subject: [PATCH 10/25] fix(trust): avoid self-hosted lifecycle recursion --- .trust.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.trust.toml b/.trust.toml index 82c7ed80..fff5f684 100644 --- a/.trust.toml +++ b/.trust.toml @@ -2,7 +2,7 @@ schema_version = 1 profile = "standard" [lifecycle] -command = ["fledge", "lanes", "run", "verify"] +command = ["cargo", "check", "--locked"] [contract] enabled = true From c85a454df96706f88063e7130108f3a94f4765d0 Mon Sep 17 00:00:00 2001 From: 0xLeif Date: Sun, 12 Jul 2026 17:11:58 -0600 Subject: [PATCH 11/25] fix(governance): address rollout review gaps --- .claude/commands/specsync/create-spec.md | 8 ++++---- .github/workflows/trust.yml | 3 +++ .specsync/sdd.json | 4 ++++ templates/corvid-stack/.specsync/sdd.json | 10 ++++++++++ 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/.claude/commands/specsync/create-spec.md b/.claude/commands/specsync/create-spec.md index a424e764..bb420ae2 100644 --- a/.claude/commands/specsync/create-spec.md +++ b/.claude/commands/specsync/create-spec.md @@ -7,10 +7,10 @@ Create a new spec-sync module spec. Arguments: `$ARGUMENTS` -1. Parse the arguments above: the first whitespace-separated token is the - module name. If the arguments also contain `--minimal` (in any position), - remove it and remember that minimal mode was requested. -2. Look at whatever text remains. It will be one of: +1. Parse the arguments above. If they contain `--minimal` (in any position), + remove that flag and remember that minimal mode was requested. Preserve all + other text exactly; do not choose a module name yet. +2. Classify the complete remaining text. It will be one of: - **A bare module name** — a short identifier like `auth-service` or `billing`. Use it as-is. - **A free-text feature description** — a sentence or phrase describing diff --git a/.github/workflows/trust.yml b/.github/workflows/trust.yml index a70594ca..b725faf7 100644 --- a/.github/workflows/trust.yml +++ b/.github/workflows/trust.yml @@ -21,3 +21,6 @@ jobs: - name: CorvidLabs Trust gate id: trust uses: CorvidLabs/trust@9d32b5786d2e9e4d39fc581c0091c721ee3d4226 # v1.0.0 + + - name: Check managed agent rules + run: 'grep -q "CorvidLabs trust toolchain: BEGIN" AGENTS.md' diff --git a/.specsync/sdd.json b/.specsync/sdd.json index 44b9ed20..f75932c7 100644 --- a/.specsync/sdd.json +++ b/.specsync/sdd.json @@ -7,6 +7,10 @@ "tests/", "site/", ".github/", + ".claude/", + ".codex/", + ".cursor/", + ".gemini/", "Cargo.toml", "Cargo.lock", "action.yml", diff --git a/templates/corvid-stack/.specsync/sdd.json b/templates/corvid-stack/.specsync/sdd.json index a7522094..8536ab45 100644 --- a/templates/corvid-stack/.specsync/sdd.json +++ b/templates/corvid-stack/.specsync/sdd.json @@ -10,6 +10,16 @@ "Cargo.lock", "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/version", From 0eaccc12aded0f311d81a442c543645db7da9c18 Mon Sep 17 00:00:00 2001 From: 0xLeif Date: Sun, 12 Jul 2026 17:13:29 -0600 Subject: [PATCH 12/25] fix(spec): use the true rollout merge base --- .../changes/CHG-0001-adopt-trust-1-and-specsync-5/state.json | 2 +- .../state.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 index 49876bed..0e805df7 100644 --- 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 @@ -6,7 +6,7 @@ "description": "Adopt Trust 1 and SpecSync 5", "kind": "migration", "state": "implementing", - "base_commit": "695ca94a54371e380be1ffbb603e3ee5cc387454", + "base_commit": "02550b3fac7e9a5ca12f5aecc1773f89972820f0", "created_at": 1783831307, "updated_at": 1783831307, "affected_specs": [], diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json index 484ce630..5964cce6 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json @@ -6,7 +6,7 @@ "description": "Update Corvid stack template for Trust 1", "kind": "migration", "state": "implementing", - "base_commit": "695ca94a54371e380be1ffbb603e3ee5cc387454", + "base_commit": "02550b3fac7e9a5ca12f5aecc1773f89972820f0", "created_at": 1783831323, "updated_at": 1783831395, "affected_specs": [], From 6d2bafe7d72906140c4ef2c1547fdbf4f65e825a Mon Sep 17 00:00:00 2001 From: 0xLeif Date: Sun, 12 Jul 2026 18:56:08 -0600 Subject: [PATCH 13/25] fix(sdd): complete verified Fledge lifecycle --- .../approvals.json | 14 ++++++++++++++ .../change.md | 4 ++-- .../state.json | 4 ++-- .../tasks.md | 4 ++-- .../verification.json | 16 ++++++++++++++++ .../approvals.json | 14 ++++++++++++++ .../change.md | 4 ++-- .../state.json | 4 ++-- .../tasks.md | 3 ++- .../verification.json | 16 ++++++++++++++++ templates/corvid-stack/fledge.toml | 14 +++++++------- 11 files changed, 79 insertions(+), 18 deletions(-) create mode 100644 .specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/verification.json create mode 100644 .specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json 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 index ffa9e9f5..3af73630 100644 --- 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 @@ -6,6 +6,20 @@ "timestamp": 1783831307, "digest": "a4efac74ec54e8951785201cf048510fd9164e1ff04edfc1b1f6e312d17ff1a6", "note": "Authorized by the approved organization-wide SpecSync 5 / Trust 1 migration plan." + }, + { + "gate": "definition", + "actor": "0xLeif", + "timestamp": 1783904137, + "digest": "d1f8bdbac64b57504f016a4ac604863117e2afeb74cd9d3e55d6942869e60165", + "note": "Reviewed Fledge governance adoption after placeholder-free template verification, 100% strict coverage, hosted technical matrices, and required trust protection." + }, + { + "gate": "acceptance", + "actor": "0xLeif", + "timestamp": 1783904151, + "digest": "53233a725653ffc04fc705ccb4949ba1e814ca463d7da690fd431887581b3106", + "note": "Approved after strict Fledge adoption verification, 33-spec 100% coverage, placeholder-free generated defaults, hosted technical matrices, and required trust protection." } ] } 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 index 7aef91ac..9a39cead 100644 --- 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 @@ -1,8 +1,8 @@ --- id: CHG-0001-adopt-trust-1-and-specsync-5 -state: implementing +state: accepted type: migration -base_commit: 695ca94a54371e380be1ffbb603e3ee5cc387454 +base_commit: 02550b3fac7e9a5ca12f5aecc1773f89972820f0 --- # Adopt Trust 1 and SpecSync 5 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 index 0e805df7..584e9783 100644 --- 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 @@ -5,10 +5,10 @@ "title": "Adopt Trust 1 and SpecSync 5", "description": "Adopt Trust 1 and SpecSync 5", "kind": "migration", - "state": "implementing", + "state": "accepted", "base_commit": "02550b3fac7e9a5ca12f5aecc1773f89972820f0", "created_at": 1783831307, - "updated_at": 1783831307, + "updated_at": 1783904151, "affected_specs": [], "affected_paths": [ ".github/workflows/", 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 index 2d6c2751..df7ab39c 100644 --- 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 @@ -8,5 +8,5 @@ artifact: tasks - [x] Adopt SpecSync 5.0.1 and install agent integrations. - [x] Configure Trust 1 with immutable action pins. - [x] Preserve native validation and specialized workflows. -- [ ] Pass hosted pull-request checks. -- [ ] Require the green trust check on the protected branch. +- [x] Pass hosted native, integration, lint, audit, template-validation, and CodeQL checks. +- [x] Require the green trust check on the protected branch. 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 00000000..df873c77 --- /dev/null +++ b/.specsync/changes/CHG-0001-adopt-trust-1-and-specsync-5/verification.json @@ -0,0 +1,16 @@ +{ + "timestamp": 1783904140, + "commit": "0eaccc12aded0f311d81a442c543645db7da9c18", + "contract_digest": "d1f8bdbac64b57504f016a4ac604863117e2afeb74cd9d3e55d6942869e60165", + "workspace_digest": "f9e92e6f24f7afb8cd6a25424bfe8ce553786bfadbb3e3e62146222dc7fc5c24", + "acceptance_input_digest": "4bd74288dc718a9fde38c1d95212a59d9ead30dd08af621fcd2d87488f5fb562", + "passed": true, + "commands": [ + { + "command": "fledge run validate-templates", + "success": true, + "exit_code": 0 + } + ], + "requirement_ids": [] +} diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json index 41baf9cb..1b82aaa0 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json @@ -13,6 +13,20 @@ "timestamp": 1783831395, "digest": "62b4cdc0055b7d9c77ee517b7549cd4ef23f69dc596edb23ecb0bffc5a332c68", "note": "Authorized by the approved organization-wide SpecSync 5 / Trust 1 migration plan." + }, + { + "gate": "definition", + "actor": "0xLeif", + "timestamp": 1783904120, + "digest": "eba5b5589df084078203786c6f051df9378749313f2ffa761fddcff0e9d49c57", + "note": "Reviewed placeholder-free Corvid stack defaults and successful generated-project governance lane." + }, + { + "gate": "acceptance", + "actor": "0xLeif", + "timestamp": 1783904137, + "digest": "d91074df5f3e1d1b8f344d575ebd1d68a0003376e3682e31ded94adb0238d9f2", + "note": "Approved after strict template verification and a successful four-step generated-project governance lane without placeholders." } ] } diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/change.md b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/change.md index b79d07af..3ec0544d 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/change.md +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/change.md @@ -1,8 +1,8 @@ --- id: CHG-0002-update-corvid-stack-template-for-trust-1 -state: implementing +state: accepted type: migration -base_commit: 695ca94a54371e380be1ffbb603e3ee5cc387454 +base_commit: 02550b3fac7e9a5ca12f5aecc1773f89972820f0 --- # Update Corvid stack template for Trust 1 diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json index 5964cce6..31badaef 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json @@ -5,10 +5,10 @@ "title": "Update Corvid stack template for Trust 1", "description": "Update Corvid stack template for Trust 1", "kind": "migration", - "state": "implementing", + "state": "accepted", "base_commit": "02550b3fac7e9a5ca12f5aecc1773f89972820f0", "created_at": 1783831323, - "updated_at": 1783831395, + "updated_at": 1783904137, "affected_specs": [], "affected_paths": [ "templates/corvid-stack/" diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/tasks.md b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/tasks.md index 33d4ae6c..53b74108 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/tasks.md +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/tasks.md @@ -7,4 +7,5 @@ artifact: tasks - [x] Generate the Trust 1 and SpecSync 5 template files. - [x] Run strict template validation. -- [ ] Pass hosted pull-request checks. +- [x] Replace placeholder tasks with deterministic starter governance checks. +- [x] Pass hosted branch-built Corvid stack template validation. diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json new file mode 100644 index 00000000..d1b86954 --- /dev/null +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json @@ -0,0 +1,16 @@ +{ + "timestamp": 1783904129, + "commit": "0eaccc12aded0f311d81a442c543645db7da9c18", + "contract_digest": "eba5b5589df084078203786c6f051df9378749313f2ffa761fddcff0e9d49c57", + "workspace_digest": "f9e92e6f24f7afb8cd6a25424bfe8ce553786bfadbb3e3e62146222dc7fc5c24", + "acceptance_input_digest": "b8bf09279863d5b94726fa144a08479f835953a5be71e95a1a0c9ba4a198edf2", + "passed": true, + "commands": [ + { + "command": "fledge run validate-templates", + "success": true, + "exit_code": 0 + } + ], + "requirement_ids": [] +} diff --git a/templates/corvid-stack/fledge.toml b/templates/corvid-stack/fledge.toml index 7947242a..aa7bbaa3 100644 --- a/templates/corvid-stack/fledge.toml +++ b/templates/corvid-stack/fledge.toml @@ -1,15 +1,15 @@ # fledge.toml: tasks and lanes for the CorvidLabs trust toolchain. # Docs: https://github.com/CorvidLabs/fledge -# Fill these in for your stack. `fledge run --init` auto-detects Rust, Node, Go, -# Python, Ruby, Java, or Swift and can populate them for you. +# These deterministic starter checks work before application source exists. +# `fledge run --init` can replace or extend them with detected stack-native checks. [tasks] -fmt = "echo 'TODO: format-check command (e.g. cargo fmt --check)'" -lint = "echo 'TODO: lint command (e.g. cargo clippy -- -D warnings)'" -test = "echo 'TODO: test command (e.g. cargo test)'" -build = "echo 'TODO: build command (e.g. cargo build)'" +format-check = "git diff --check" +config-check = "fledge introspect" +governance-check = "test -s .trust.toml && test -s .augur.toml && test -s .attest.json && test -s .specsync/sdd.json" +workflow-check = "test -s .github/workflows/trust.yml && grep -q 'CorvidLabs/trust@9d32b5786d2e9e4d39fc581c0091c721ee3d4226' .github/workflows/trust.yml" # The single quality gate. `.github/workflows/trust.yml` runs `fledge lanes run verify`. [lanes.verify] description = "The single quality gate" -steps = ["fmt", "lint", "test", "build"] +steps = ["format-check", "config-check", "governance-check", "workflow-check"] From 738d738fa2ee6ce4b4346dd449e83e3612192040 Mon Sep 17 00:00:00 2001 From: 0xLeif Date: Sun, 12 Jul 2026 21:34:23 -0600 Subject: [PATCH 14/25] fix(governance): close Fledge rollout review gaps --- .../approvals.json | 7 ----- .../change.md | 2 +- .../state.json | 4 ++- .../approvals.json | 7 ----- .../change.md | 2 +- .../state.json | 2 +- .specsync/sdd.json | 9 ++++--- .trust.toml | 4 +-- src/spec/commands.rs | 2 +- src/templates.rs | 27 +++++++++++++++++++ templates/corvid-stack/.specsync/sdd.json | 8 +++--- templates/corvid-stack/README.md.tera | 11 ++++++-- templates/corvid-stack/fledge.toml | 2 +- 13 files changed, 55 insertions(+), 32 deletions(-) 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 index 3af73630..08aa4249 100644 --- 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 @@ -13,13 +13,6 @@ "timestamp": 1783904137, "digest": "d1f8bdbac64b57504f016a4ac604863117e2afeb74cd9d3e55d6942869e60165", "note": "Reviewed Fledge governance adoption after placeholder-free template verification, 100% strict coverage, hosted technical matrices, and required trust protection." - }, - { - "gate": "acceptance", - "actor": "0xLeif", - "timestamp": 1783904151, - "digest": "53233a725653ffc04fc705ccb4949ba1e814ca463d7da690fd431887581b3106", - "note": "Approved after strict Fledge adoption verification, 33-spec 100% coverage, placeholder-free generated defaults, hosted technical matrices, and required trust protection." } ] } 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 index 9a39cead..84f59d7d 100644 --- 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 @@ -1,6 +1,6 @@ --- id: CHG-0001-adopt-trust-1-and-specsync-5 -state: accepted +state: implementing type: migration base_commit: 02550b3fac7e9a5ca12f5aecc1773f89972820f0 --- 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 index 584e9783..7f749d6c 100644 --- 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 @@ -5,7 +5,7 @@ "title": "Adopt Trust 1 and SpecSync 5", "description": "Adopt Trust 1 and SpecSync 5", "kind": "migration", - "state": "accepted", + "state": "implementing", "base_commit": "02550b3fac7e9a5ca12f5aecc1773f89972820f0", "created_at": 1783831307, "updated_at": 1783904151, @@ -22,6 +22,8 @@ ".codex/", ".gemini/", "fledge.toml", + "src/spec/commands.rs", + "src/templates.rs", "specs/" ], "no_spec_change": true, diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json index 1b82aaa0..72544b69 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json @@ -20,13 +20,6 @@ "timestamp": 1783904120, "digest": "eba5b5589df084078203786c6f051df9378749313f2ffa761fddcff0e9d49c57", "note": "Reviewed placeholder-free Corvid stack defaults and successful generated-project governance lane." - }, - { - "gate": "acceptance", - "actor": "0xLeif", - "timestamp": 1783904137, - "digest": "d91074df5f3e1d1b8f344d575ebd1d68a0003376e3682e31ded94adb0238d9f2", - "note": "Approved after strict template verification and a successful four-step generated-project governance lane without placeholders." } ] } diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/change.md b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/change.md index 3ec0544d..773d44ad 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/change.md +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/change.md @@ -1,6 +1,6 @@ --- id: CHG-0002-update-corvid-stack-template-for-trust-1 -state: accepted +state: implementing type: migration base_commit: 02550b3fac7e9a5ca12f5aecc1773f89972820f0 --- diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json index 31badaef..85994de8 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json @@ -5,7 +5,7 @@ "title": "Update Corvid stack template for Trust 1", "description": "Update Corvid stack template for Trust 1", "kind": "migration", - "state": "accepted", + "state": "implementing", "base_commit": "02550b3fac7e9a5ca12f5aecc1773f89972820f0", "created_at": 1783831323, "updated_at": 1783904137, diff --git a/.specsync/sdd.json b/.specsync/sdd.json index f75932c7..b78d2a5f 100644 --- a/.specsync/sdd.json +++ b/.specsync/sdd.json @@ -5,6 +5,7 @@ "meaningful_paths": [ "src/", "tests/", + "specs/", "site/", ".github/", ".claude/", @@ -13,6 +14,8 @@ ".gemini/", "Cargo.toml", "Cargo.lock", + "build.rs", + "flake.nix", "action.yml", "package.json", "bun.lock", @@ -37,11 +40,9 @@ ".attest.json", "AGENTS.md" ], - "ignored_paths": [ - "specs/" - ], + "ignored_paths": [], "verification_commands": [ - "fledge run validate-templates" + "fledge lanes run verify" ], "custom_artifacts": {}, "principles_file": null diff --git a/.trust.toml b/.trust.toml index fff5f684..b4d5476c 100644 --- a/.trust.toml +++ b/.trust.toml @@ -1,8 +1,8 @@ schema_version = 1 -profile = "standard" +profile = "strict" [lifecycle] -command = ["cargo", "check", "--locked"] +command = ["fledge", "lanes", "run", "verify"] [contract] enabled = true diff --git a/src/spec/commands.rs b/src/spec/commands.rs index 6f1628fd..bcca0462 100644 --- a/src/spec/commands.rs +++ b/src/spec/commands.rs @@ -584,7 +584,7 @@ hashes.json style("✅").green().bold() ); - fs::write(specsync_dir.join("version"), "4.3.1\n")?; + fs::write(specsync_dir.join("version"), "5.0.1\n")?; println!("{} Created .specsync/version", style("✅").green().bold()); if !specs_dir.exists() { diff --git a/src/templates.rs b/src/templates.rs index f3d49dca..a95223a6 100644 --- a/src/templates.rs +++ b/src/templates.rs @@ -1031,6 +1031,33 @@ ignore = ["template.toml"] assert_eq!(names.len(), 10, "expected exactly 10 built-in templates"); } + #[test] + fn corvid_stack_bootstrap_lane_is_substantive_and_placeholder_free() { + let template_path = + Path::new(env!("CARGO_MANIFEST_DIR")).join("templates/corvid-stack/fledge.toml"); + let contents = fs::read_to_string(template_path).unwrap(); + + for forbidden in ["TODO", "placeholder", "echo '", "echo \""] { + assert!( + !contents.contains(forbidden), + "corvid-stack bootstrap must not contain {forbidden}" + ); + } + + for required in [ + "git diff --check", + "fledge introspect", + "governance-check", + "workflow-check", + "steps = [\"format-check\", \"config-check\", \"governance-check\", \"workflow-check\"]", + ] { + assert!( + contents.contains(required), + "corvid-stack bootstrap is missing substantive check: {required}" + ); + } + } + #[test] fn render_template_creates_parent_dirs() { let tmp = TempDir::new().unwrap(); diff --git a/templates/corvid-stack/.specsync/sdd.json b/templates/corvid-stack/.specsync/sdd.json index 8536ab45..fdc4feb8 100644 --- a/templates/corvid-stack/.specsync/sdd.json +++ b/templates/corvid-stack/.specsync/sdd.json @@ -5,6 +5,7 @@ "meaningful_paths": [ "src/", "tests/", + "specs/", ".github/", "Cargo.toml", "Cargo.lock", @@ -27,11 +28,10 @@ ".trust.toml", ".augur.toml", ".attest.json", - "AGENTS.md" - ], - "ignored_paths": [ - "specs/" + "AGENTS.md", + "CLAUDE.md" ], + "ignored_paths": [], "verification_commands": [ "fledge lanes run verify" ], diff --git a/templates/corvid-stack/README.md.tera b/templates/corvid-stack/README.md.tera index c2cb7399..4c548ea7 100644 --- a/templates/corvid-stack/README.md.tera +++ b/templates/corvid-stack/README.md.tera @@ -27,8 +27,10 @@ that gates every change through four tools. See https://corvidlabs.xyz/integrate # Install the toolchain (macOS shown; see the guide for Linux/cargo) brew install CorvidLabs/tap/corvid-trust -# Wire up your stack's tasks (auto-detects Rust, Node, Go, Python, Ruby, Java, Swift) -fledge run --init +# This source-free template starts with deterministic bootstrap checks. +# Before committing native application code, replace or extend those tasks in +# fledge.toml with the stack's format, lint, test, and build commands, and add +# every native task name to lanes.verify so Trust executes them. # Run the gate locally fledge trust doctor @@ -39,6 +41,11 @@ Then fill in the `[tasks]` in `fledge.toml`, set `source_dirs` in `.specsync/config.toml` to match your layout, add a `*.spec.md` per module under `specs/`, and register it in `.specsync/registry.toml`. +The bootstrap lane validates real repository content and manifests; it is not a +substitute for native checks after source code is added. A generated project +must extend `lanes.verify` with its stack's checks in the same change that adds +native code. + ## The gate Every push and PR runs one required `trust` job. Its component status outputs and diff --git a/templates/corvid-stack/fledge.toml b/templates/corvid-stack/fledge.toml index aa7bbaa3..3e587a09 100644 --- a/templates/corvid-stack/fledge.toml +++ b/templates/corvid-stack/fledge.toml @@ -2,7 +2,7 @@ # Docs: https://github.com/CorvidLabs/fledge # These deterministic starter checks work before application source exists. -# `fledge run --init` can replace or extend them with detected stack-native checks. +# Replace or extend them with stack-native checks when application code is added. [tasks] format-check = "git diff --check" config-check = "fledge introspect" From 57fb57aa7d37812a42f7edf724c80e70d36c1ec6 Mon Sep 17 00:00:00 2001 From: 0xLeif Date: Sun, 12 Jul 2026 21:37:38 -0600 Subject: [PATCH 15/25] fix(sdd): refresh final Fledge rollout evidence --- .../approvals.json | 14 ++++++++++++++ .../change.md | 2 +- .../state.json | 4 ++-- .../verification.json | 12 ++++++------ .../approvals.json | 7 +++++++ .../change.md | 2 +- .../state.json | 4 ++-- .../verification.json | 10 +++++----- 8 files changed, 38 insertions(+), 17 deletions(-) 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 index 08aa4249..1a054db0 100644 --- 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 @@ -13,6 +13,20 @@ "timestamp": 1783904137, "digest": "d1f8bdbac64b57504f016a4ac604863117e2afeb74cd9d3e55d6942869e60165", "note": "Reviewed Fledge governance adoption after placeholder-free template verification, 100% strict coverage, hosted technical matrices, and required trust protection." + }, + { + "gate": "definition", + "actor": "0xLeif", + "timestamp": 1783913704, + "digest": "e501068a05e6748686f9e67c2abc8740da52e6d7df64770bbb7c6bd6e8d2c391", + "note": "Approved final strict Trust policy, SpecSync 5.0.1 scaffolding, build-manifest governance, and substantive template regression scope." + }, + { + "gate": "acceptance", + "actor": "0xLeif", + "timestamp": 1783913853, + "digest": "0368e97d1b997b7608668cc54a0b0c0896b419d940f0b288107ea541e3c4d460", + "note": "Accepted after full verification of strict Trust, SpecSync 5.0.1 scaffolding, governed build manifests, and template regression coverage." } ] } 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 index 84f59d7d..9a39cead 100644 --- 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 @@ -1,6 +1,6 @@ --- id: CHG-0001-adopt-trust-1-and-specsync-5 -state: implementing +state: accepted type: migration base_commit: 02550b3fac7e9a5ca12f5aecc1773f89972820f0 --- 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 index 7f749d6c..8234c0c8 100644 --- 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 @@ -5,10 +5,10 @@ "title": "Adopt Trust 1 and SpecSync 5", "description": "Adopt Trust 1 and SpecSync 5", "kind": "migration", - "state": "implementing", + "state": "accepted", "base_commit": "02550b3fac7e9a5ca12f5aecc1773f89972820f0", "created_at": 1783831307, - "updated_at": 1783904151, + "updated_at": 1783913853, "affected_specs": [], "affected_paths": [ ".github/workflows/", 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 index df873c77..02e09ed5 100644 --- 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 @@ -1,13 +1,13 @@ { - "timestamp": 1783904140, - "commit": "0eaccc12aded0f311d81a442c543645db7da9c18", - "contract_digest": "d1f8bdbac64b57504f016a4ac604863117e2afeb74cd9d3e55d6942869e60165", - "workspace_digest": "f9e92e6f24f7afb8cd6a25424bfe8ce553786bfadbb3e3e62146222dc7fc5c24", - "acceptance_input_digest": "4bd74288dc718a9fde38c1d95212a59d9ead30dd08af621fcd2d87488f5fb562", + "timestamp": 1783913844, + "commit": "738d738fa2ee6ce4b4346dd449e83e3612192040", + "contract_digest": "e501068a05e6748686f9e67c2abc8740da52e6d7df64770bbb7c6bd6e8d2c391", + "workspace_digest": "130d7f9205ec259eb7394f21b72a49004973e738bac4ca051ef6f4086114f146", + "acceptance_input_digest": "0a9988455cc029089ad15bf15fbd65dd7fc65903682689769eb71d905d8e7822", "passed": true, "commands": [ { - "command": "fledge run validate-templates", + "command": "fledge lanes run verify", "success": true, "exit_code": 0 } diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json index 72544b69..f5887389 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json @@ -20,6 +20,13 @@ "timestamp": 1783904120, "digest": "eba5b5589df084078203786c6f051df9378749313f2ffa761fddcff0e9d49c57", "note": "Reviewed placeholder-free Corvid stack defaults and successful generated-project governance lane." + }, + { + "gate": "acceptance", + "actor": "0xLeif", + "timestamp": 1783913805, + "digest": "35f47eff5b2087fe61da58aa9a9fecf0f1a0621da60bec47765ccf054ebc44ba", + "note": "Accepted after full verification of the placeholder-free bootstrap lane, explicit native-check extension policy, and final Trust 1 template." } ] } diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/change.md b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/change.md index 773d44ad..3ec0544d 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/change.md +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/change.md @@ -1,6 +1,6 @@ --- id: CHG-0002-update-corvid-stack-template-for-trust-1 -state: implementing +state: accepted type: migration base_commit: 02550b3fac7e9a5ca12f5aecc1773f89972820f0 --- diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json index 85994de8..f2184325 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json @@ -5,10 +5,10 @@ "title": "Update Corvid stack template for Trust 1", "description": "Update Corvid stack template for Trust 1", "kind": "migration", - "state": "implementing", + "state": "accepted", "base_commit": "02550b3fac7e9a5ca12f5aecc1773f89972820f0", "created_at": 1783831323, - "updated_at": 1783904137, + "updated_at": 1783913805, "affected_specs": [], "affected_paths": [ "templates/corvid-stack/" diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json index d1b86954..16616cdc 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json @@ -1,13 +1,13 @@ { - "timestamp": 1783904129, - "commit": "0eaccc12aded0f311d81a442c543645db7da9c18", + "timestamp": 1783913748, + "commit": "738d738fa2ee6ce4b4346dd449e83e3612192040", "contract_digest": "eba5b5589df084078203786c6f051df9378749313f2ffa761fddcff0e9d49c57", - "workspace_digest": "f9e92e6f24f7afb8cd6a25424bfe8ce553786bfadbb3e3e62146222dc7fc5c24", - "acceptance_input_digest": "b8bf09279863d5b94726fa144a08479f835953a5be71e95a1a0c9ba4a198edf2", + "workspace_digest": "130d7f9205ec259eb7394f21b72a49004973e738bac4ca051ef6f4086114f146", + "acceptance_input_digest": "cfdbeecc88b8a90f4c13d7af890aadb334bc7109a95e446ffb8949eaef30366f", "passed": true, "commands": [ { - "command": "fledge run validate-templates", + "command": "fledge lanes run verify", "success": true, "exit_code": 0 } From 5b02de3d3679da1171851f26467d85a91245bf88 Mon Sep 17 00:00:00 2001 From: 0xLeif Date: Sun, 12 Jul 2026 22:43:17 -0600 Subject: [PATCH 16/25] fix(trust): avoid recursive Fledge verification --- .../approvals.json | 13 ++++++++++--- .../state.json | 2 +- .../verification.json | 10 +++++----- .../approvals.json | 13 ++++++++++--- .../state.json | 2 +- .../verification.json | 8 ++++---- .specsync/sdd.json | 2 +- .trust.toml | 2 +- fledge.toml | 4 ++++ 9 files changed, 37 insertions(+), 19 deletions(-) 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 index 1a054db0..58e0e4a4 100644 --- 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 @@ -21,12 +21,19 @@ "digest": "e501068a05e6748686f9e67c2abc8740da52e6d7df64770bbb7c6bd6e8d2c391", "note": "Approved final strict Trust policy, SpecSync 5.0.1 scaffolding, build-manifest governance, and substantive template regression scope." }, + { + "gate": "definition", + "actor": "0xLeif", + "timestamp": 1783917629, + "digest": "e501068a05e6748686f9e67c2abc8740da52e6d7df64770bbb7c6bd6e8d2c391", + "note": "Approved non-recursive native verification lane after hosted Trust and spec-check cancellation exposed recursive contract execution" + }, { "gate": "acceptance", "actor": "0xLeif", - "timestamp": 1783913853, - "digest": "0368e97d1b997b7608668cc54a0b0c0896b419d940f0b288107ea541e3c4d460", - "note": "Accepted after full verification of strict Trust, SpecSync 5.0.1 scaffolding, governed build manifests, and template regression coverage." + "timestamp": 1783917701, + "digest": "ec6cd13d5bffc538c35b11915d613b3ddff1543038e82147b1796b2feb7a3565", + "note": null } ] } 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 index 8234c0c8..0beff620 100644 --- 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 @@ -8,7 +8,7 @@ "state": "accepted", "base_commit": "02550b3fac7e9a5ca12f5aecc1773f89972820f0", "created_at": 1783831307, - "updated_at": 1783913853, + "updated_at": 1783917701, "affected_specs": [], "affected_paths": [ ".github/workflows/", 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 index 02e09ed5..4f44990c 100644 --- 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 @@ -1,13 +1,13 @@ { - "timestamp": 1783913844, - "commit": "738d738fa2ee6ce4b4346dd449e83e3612192040", + "timestamp": 1783917663, + "commit": "57fb57aa7d37812a42f7edf724c80e70d36c1ec6", "contract_digest": "e501068a05e6748686f9e67c2abc8740da52e6d7df64770bbb7c6bd6e8d2c391", - "workspace_digest": "130d7f9205ec259eb7394f21b72a49004973e738bac4ca051ef6f4086114f146", - "acceptance_input_digest": "0a9988455cc029089ad15bf15fbd65dd7fc65903682689769eb71d905d8e7822", + "workspace_digest": "cf7f6e246d2eb14b4a403a9c4df2585bc083a894050f9d19a252f08bdd1f1cab", + "acceptance_input_digest": "7af0e54c1ee5b3b02b50f25efb62bbe3684da4a01d41586ccf364306d03fff13", "passed": true, "commands": [ { - "command": "fledge lanes run verify", + "command": "fledge lanes run verify-native", "success": true, "exit_code": 0 } diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json index f5887389..584fa81a 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json @@ -21,12 +21,19 @@ "digest": "eba5b5589df084078203786c6f051df9378749313f2ffa761fddcff0e9d49c57", "note": "Reviewed placeholder-free Corvid stack defaults and successful generated-project governance lane." }, + { + "gate": "definition", + "actor": "0xLeif", + "timestamp": 1783917636, + "digest": "eba5b5589df084078203786c6f051df9378749313f2ffa761fddcff0e9d49c57", + "note": "Reapproved template migration for final workspace verification with the non-recursive native Fledge lane" + }, { "gate": "acceptance", "actor": "0xLeif", - "timestamp": 1783913805, - "digest": "35f47eff5b2087fe61da58aa9a9fecf0f1a0621da60bec47765ccf054ebc44ba", - "note": "Accepted after full verification of the placeholder-free bootstrap lane, explicit native-check extension policy, and final Trust 1 template." + "timestamp": 1783917705, + "digest": "61fa4a17cffebf36e92923a37dd6497bf7e64f285ed1c2374a7578aff94a0dcf", + "note": null } ] } diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json index f2184325..31c30093 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json @@ -8,7 +8,7 @@ "state": "accepted", "base_commit": "02550b3fac7e9a5ca12f5aecc1773f89972820f0", "created_at": 1783831323, - "updated_at": 1783913805, + "updated_at": 1783917705, "affected_specs": [], "affected_paths": [ "templates/corvid-stack/" diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json index 16616cdc..64b7d144 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json @@ -1,13 +1,13 @@ { - "timestamp": 1783913748, - "commit": "738d738fa2ee6ce4b4346dd449e83e3612192040", + "timestamp": 1783917689, + "commit": "57fb57aa7d37812a42f7edf724c80e70d36c1ec6", "contract_digest": "eba5b5589df084078203786c6f051df9378749313f2ffa761fddcff0e9d49c57", - "workspace_digest": "130d7f9205ec259eb7394f21b72a49004973e738bac4ca051ef6f4086114f146", + "workspace_digest": "cf7f6e246d2eb14b4a403a9c4df2585bc083a894050f9d19a252f08bdd1f1cab", "acceptance_input_digest": "cfdbeecc88b8a90f4c13d7af890aadb334bc7109a95e446ffb8949eaef30366f", "passed": true, "commands": [ { - "command": "fledge lanes run verify", + "command": "fledge lanes run verify-native", "success": true, "exit_code": 0 } diff --git a/.specsync/sdd.json b/.specsync/sdd.json index b78d2a5f..76190042 100644 --- a/.specsync/sdd.json +++ b/.specsync/sdd.json @@ -42,7 +42,7 @@ ], "ignored_paths": [], "verification_commands": [ - "fledge lanes run verify" + "fledge lanes run verify-native" ], "custom_artifacts": {}, "principles_file": null diff --git a/.trust.toml b/.trust.toml index b4d5476c..b16e0616 100644 --- a/.trust.toml +++ b/.trust.toml @@ -2,7 +2,7 @@ schema_version = 1 profile = "strict" [lifecycle] -command = ["fledge", "lanes", "run", "verify"] +command = ["fledge", "lanes", "run", "verify-native"] [contract] enabled = true diff --git a/fledge.toml b/fledge.toml index 1a9ec128..6226317e 100644 --- a/fledge.toml +++ b/fledge.toml @@ -23,6 +23,10 @@ steps = ["fmt", "lint", "test", "build", "spec-check", "validate-templates"] description = "Required Trust gate for the Fledge repository" steps = ["fmt", "lint", "test", "build", "spec-check", "validate-templates"] +[lanes.verify-native] +description = "Native verification used by Trust and SpecSync without recursive contract checks" +steps = ["fmt", "lint", "test", "build", "validate-templates"] + [lanes.check] description = "Quick quality check" steps = [ From 37ab5e8b7d48f971ad5d418431c6c96ad17abccc Mon Sep 17 00:00:00 2001 From: 0xLeif Date: Sun, 12 Jul 2026 22:55:56 -0600 Subject: [PATCH 17/25] fix(governance): close final Fledge rollout gaps --- .github/workflows/trust.yml | 4 +++- .../approvals.json | 11 +++++++++-- .../CHG-0001-adopt-trust-1-and-specsync-5/state.json | 2 +- .../verification.json | 8 ++++---- .../approvals.json | 11 +++++++++-- .../state.json | 2 +- .../verification.json | 8 ++++---- .trust.toml | 2 +- templates/corvid-stack/fledge.toml | 4 ++-- 9 files changed, 34 insertions(+), 18 deletions(-) diff --git a/.github/workflows/trust.yml b/.github/workflows/trust.yml index b725faf7..705f18c4 100644 --- a/.github/workflows/trust.yml +++ b/.github/workflows/trust.yml @@ -23,4 +23,6 @@ jobs: uses: CorvidLabs/trust@9d32b5786d2e9e4d39fc581c0091c721ee3d4226 # v1.0.0 - name: Check managed agent rules - run: 'grep -q "CorvidLabs trust toolchain: BEGIN" AGENTS.md' + run: | + grep -q "CorvidLabs trust toolchain: BEGIN" AGENTS.md + grep -q "CorvidLabs trust toolchain: END" AGENTS.md 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 index 58e0e4a4..a9922420 100644 --- 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 @@ -28,11 +28,18 @@ "digest": "e501068a05e6748686f9e67c2abc8740da52e6d7df64770bbb7c6bd6e8d2c391", "note": "Approved non-recursive native verification lane after hosted Trust and spec-check cancellation exposed recursive contract execution" }, + { + "gate": "definition", + "actor": "0xLeif", + "timestamp": 1783918310, + "digest": "e501068a05e6748686f9e67c2abc8740da52e6d7df64770bbb7c6bd6e8d2c391", + "note": "Approved standard-profile progressive provenance and complete managed-marker enforcement" + }, { "gate": "acceptance", "actor": "0xLeif", - "timestamp": 1783917701, - "digest": "ec6cd13d5bffc538c35b11915d613b3ddff1543038e82147b1796b2feb7a3565", + "timestamp": 1783918406, + "digest": "e6dceae128713731a5202a5b7de38b8be129f7fc1eb2f82cb1742725962c0177", "note": null } ] 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 index 0beff620..6c9dad7c 100644 --- 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 @@ -8,7 +8,7 @@ "state": "accepted", "base_commit": "02550b3fac7e9a5ca12f5aecc1773f89972820f0", "created_at": 1783831307, - "updated_at": 1783917701, + "updated_at": 1783918406, "affected_specs": [], "affected_paths": [ ".github/workflows/", 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 index 4f44990c..d517f603 100644 --- 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 @@ -1,9 +1,9 @@ { - "timestamp": 1783917663, - "commit": "57fb57aa7d37812a42f7edf724c80e70d36c1ec6", + "timestamp": 1783918351, + "commit": "5b02de3d3679da1171851f26467d85a91245bf88", "contract_digest": "e501068a05e6748686f9e67c2abc8740da52e6d7df64770bbb7c6bd6e8d2c391", - "workspace_digest": "cf7f6e246d2eb14b4a403a9c4df2585bc083a894050f9d19a252f08bdd1f1cab", - "acceptance_input_digest": "7af0e54c1ee5b3b02b50f25efb62bbe3684da4a01d41586ccf364306d03fff13", + "workspace_digest": "8cbd5df647cb594334c79d1d05ef45cf3224e5d20acde2e2d79a390f273c2de6", + "acceptance_input_digest": "0e74185bb948ab3a0b3a3612e44590cf8a9de9b08152eb049fff45c72b1d47a2", "passed": true, "commands": [ { diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json index 584fa81a..f6135520 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json @@ -28,11 +28,18 @@ "digest": "eba5b5589df084078203786c6f051df9378749313f2ffa761fddcff0e9d49c57", "note": "Reapproved template migration for final workspace verification with the non-recursive native Fledge lane" }, + { + "gate": "definition", + "actor": "0xLeif", + "timestamp": 1783918310, + "digest": "eba5b5589df084078203786c6f051df9378749313f2ffa761fddcff0e9d49c57", + "note": "Approved cross-platform git-based starter governance checks for generated Corvid stack projects" + }, { "gate": "acceptance", "actor": "0xLeif", - "timestamp": 1783917705, - "digest": "61fa4a17cffebf36e92923a37dd6497bf7e64f285ed1c2374a7578aff94a0dcf", + "timestamp": 1783918406, + "digest": "49d121ae0fbf2b8f27c2317fc50b236ed4ef02011b00e9f1ab62ac88a6eeeebb", "note": null } ] diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json index 31c30093..e40ba741 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json @@ -8,7 +8,7 @@ "state": "accepted", "base_commit": "02550b3fac7e9a5ca12f5aecc1773f89972820f0", "created_at": 1783831323, - "updated_at": 1783917705, + "updated_at": 1783918406, "affected_specs": [], "affected_paths": [ "templates/corvid-stack/" diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json index 64b7d144..70fd3a2f 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json @@ -1,9 +1,9 @@ { - "timestamp": 1783917689, - "commit": "57fb57aa7d37812a42f7edf724c80e70d36c1ec6", + "timestamp": 1783918384, + "commit": "5b02de3d3679da1171851f26467d85a91245bf88", "contract_digest": "eba5b5589df084078203786c6f051df9378749313f2ffa761fddcff0e9d49c57", - "workspace_digest": "cf7f6e246d2eb14b4a403a9c4df2585bc083a894050f9d19a252f08bdd1f1cab", - "acceptance_input_digest": "cfdbeecc88b8a90f4c13d7af890aadb334bc7109a95e446ffb8949eaef30366f", + "workspace_digest": "8cbd5df647cb594334c79d1d05ef45cf3224e5d20acde2e2d79a390f273c2de6", + "acceptance_input_digest": "c80c08451f13ec0daf76f914b14b12b43a30364b61a424ac60fccb9b24de8ba5", "passed": true, "commands": [ { diff --git a/.trust.toml b/.trust.toml index b16e0616..4dede35b 100644 --- a/.trust.toml +++ b/.trust.toml @@ -1,5 +1,5 @@ schema_version = 1 -profile = "strict" +profile = "standard" [lifecycle] command = ["fledge", "lanes", "run", "verify-native"] diff --git a/templates/corvid-stack/fledge.toml b/templates/corvid-stack/fledge.toml index 3e587a09..c30d0d3a 100644 --- a/templates/corvid-stack/fledge.toml +++ b/templates/corvid-stack/fledge.toml @@ -6,8 +6,8 @@ [tasks] format-check = "git diff --check" config-check = "fledge introspect" -governance-check = "test -s .trust.toml && test -s .augur.toml && test -s .attest.json && test -s .specsync/sdd.json" -workflow-check = "test -s .github/workflows/trust.yml && grep -q 'CorvidLabs/trust@9d32b5786d2e9e4d39fc581c0091c721ee3d4226' .github/workflows/trust.yml" +governance-check = "git ls-files --error-unmatch .trust.toml .augur.toml .attest.json .specsync/sdd.json" +workflow-check = "git ls-files --error-unmatch .github/workflows/trust.yml && git grep -q -F \"CorvidLabs/trust@9d32b5786d2e9e4d39fc581c0091c721ee3d4226\" -- .github/workflows/trust.yml" # The single quality gate. `.github/workflows/trust.yml` runs `fledge lanes run verify`. [lanes.verify] From 7604b350e6e0d8a95d3a74d18080df430b508d18 Mon Sep 17 00:00:00 2001 From: 0xLeif Date: Sun, 12 Jul 2026 23:11:26 -0600 Subject: [PATCH 18/25] fix(ci): restore Cargo cache for governance gates --- .github/workflows/ci.yml | 1 + .github/workflows/trust.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f7bb78e6..3bb8b757 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -114,6 +114,7 @@ jobs: with: fetch-depth: 0 - uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@v2 - name: Build the branch Fledge CLI run: cargo build --release --locked - name: Add the branch Fledge CLI to PATH diff --git a/.github/workflows/trust.yml b/.github/workflows/trust.yml index 705f18c4..1843df36 100644 --- a/.github/workflows/trust.yml +++ b/.github/workflows/trust.yml @@ -18,6 +18,7 @@ jobs: - uses: dtolnay/rust-toolchain@stable with: components: rustfmt, clippy + - uses: Swatinem/rust-cache@v2 - name: CorvidLabs Trust gate id: trust uses: CorvidLabs/trust@9d32b5786d2e9e4d39fc581c0091c721ee3d4226 # v1.0.0 From 9289bb9c0548d52ace5991834edb12c0d5e6ae2c Mon Sep 17 00:00:00 2001 From: 0xLeif Date: Sun, 12 Jul 2026 23:23:54 -0600 Subject: [PATCH 19/25] fix(ci): align SpecSync build with verification profile --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3bb8b757..550feba0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -106,7 +106,7 @@ jobs: spec-check: runs-on: ubuntu-latest - timeout-minutes: 15 + timeout-minutes: 30 outputs: body: ${{ steps.specsync.outputs.body }} steps: @@ -116,9 +116,9 @@ jobs: - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - name: Build the branch Fledge CLI - run: cargo build --release --locked + run: cargo build --locked - name: Add the branch Fledge CLI to PATH - run: echo "${{ github.workspace }}/target/release" >> "$GITHUB_PATH" + run: echo "${{ github.workspace }}/target/debug" >> "$GITHUB_PATH" - name: Run spec-sync id: specsync uses: CorvidLabs/spec-sync@59bbfa766c6cce01ab815ab47db195b0629cc014 # v5.0.1 From e429294b4f39a9ec54b5084a7d090654dd38b1f3 Mon Sep 17 00:00:00 2001 From: 0xLeif Date: Sun, 12 Jul 2026 23:55:51 -0600 Subject: [PATCH 20/25] fix(trust): exclude recursive self-check tests from governance lane --- fledge.toml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fledge.toml b/fledge.toml index 6226317e..1534e2a4 100644 --- a/fledge.toml +++ b/fledge.toml @@ -4,6 +4,7 @@ [tasks] build = "cargo build" test = "cargo test" +test-governance = "cargo test -- --skip cli_spec_check_succeeds_in_project --skip cli_spec_check_json_valid --skip cli_spec_check_json_spec_shape" lint = "cargo clippy --all-targets -- -D warnings" fmt = "cargo fmt --check" fmt-fix = "cargo fmt" @@ -24,8 +25,8 @@ description = "Required Trust gate for the Fledge repository" steps = ["fmt", "lint", "test", "build", "spec-check", "validate-templates"] [lanes.verify-native] -description = "Native verification used by Trust and SpecSync without recursive contract checks" -steps = ["fmt", "lint", "test", "build", "validate-templates"] +description = "Native verification used by Trust and SpecSync without recursive self-check tests" +steps = ["fmt", "lint", "test-governance", "build", "validate-templates"] [lanes.check] description = "Quick quality check" From ea62bf537dce717056d236b5b4320c809fff073b Mon Sep 17 00:00:00 2001 From: 0xLeif Date: Mon, 13 Jul 2026 00:04:11 -0600 Subject: [PATCH 21/25] fix(sdd): renew final governance evidence --- .../CHG-0001-adopt-trust-1-and-specsync-5/approvals.json | 7 +++++++ .../CHG-0001-adopt-trust-1-and-specsync-5/state.json | 2 +- .../verification.json | 8 ++++---- .../approvals.json | 7 +++++++ .../state.json | 2 +- .../verification.json | 6 +++--- 6 files changed, 23 insertions(+), 9 deletions(-) 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 index a9922420..14aaa280 100644 --- 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 @@ -41,6 +41,13 @@ "timestamp": 1783918406, "digest": "e6dceae128713731a5202a5b7de38b8be129f7fc1eb2f82cb1742725962c0177", "note": null + }, + { + "gate": "acceptance", + "actor": "0xLeif", + "timestamp": 1783922639, + "digest": "29aef45929401f47b9d945bf73a850032af3efbaf9d7fd35bfb55f3ee748aca1", + "note": "Accepted after renewing verification for the non-recursive governance test lane." } ] } 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 index 6c9dad7c..a4726df4 100644 --- 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 @@ -8,7 +8,7 @@ "state": "accepted", "base_commit": "02550b3fac7e9a5ca12f5aecc1773f89972820f0", "created_at": 1783831307, - "updated_at": 1783918406, + "updated_at": 1783922639, "affected_specs": [], "affected_paths": [ ".github/workflows/", 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 index d517f603..595b4b23 100644 --- 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 @@ -1,9 +1,9 @@ { - "timestamp": 1783918351, - "commit": "5b02de3d3679da1171851f26467d85a91245bf88", + "timestamp": 1783922603, + "commit": "e429294b4f39a9ec54b5084a7d090654dd38b1f3", "contract_digest": "e501068a05e6748686f9e67c2abc8740da52e6d7df64770bbb7c6bd6e8d2c391", - "workspace_digest": "8cbd5df647cb594334c79d1d05ef45cf3224e5d20acde2e2d79a390f273c2de6", - "acceptance_input_digest": "0e74185bb948ab3a0b3a3612e44590cf8a9de9b08152eb049fff45c72b1d47a2", + "workspace_digest": "ffb5c7526ee87395253342ddc858ced3263342159558efa379e9ff990c80d97d", + "acceptance_input_digest": "769e41d252a8885d559c3292fd07c0f3774660d02bf5f675bdd357768b7a5fd9", "passed": true, "commands": [ { diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json index f6135520..26a611f1 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json @@ -41,6 +41,13 @@ "timestamp": 1783918406, "digest": "49d121ae0fbf2b8f27c2317fc50b236ed4ef02011b00e9f1ab62ac88a6eeeebb", "note": null + }, + { + "gate": "acceptance", + "actor": "0xLeif", + "timestamp": 1783922642, + "digest": "dd0475dd7f22aea80ecdb40a9ce20062d20bfa4ae6db6006b2b6915f0a35b44a", + "note": "Accepted after renewing verification against the final non-recursive governance lane." } ] } diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json index e40ba741..c84bfea6 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json @@ -8,7 +8,7 @@ "state": "accepted", "base_commit": "02550b3fac7e9a5ca12f5aecc1773f89972820f0", "created_at": 1783831323, - "updated_at": 1783918406, + "updated_at": 1783922642, "affected_specs": [], "affected_paths": [ "templates/corvid-stack/" diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json index 70fd3a2f..6ba2fea9 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json @@ -1,8 +1,8 @@ { - "timestamp": 1783918384, - "commit": "5b02de3d3679da1171851f26467d85a91245bf88", + "timestamp": 1783922628, + "commit": "e429294b4f39a9ec54b5084a7d090654dd38b1f3", "contract_digest": "eba5b5589df084078203786c6f051df9378749313f2ffa761fddcff0e9d49c57", - "workspace_digest": "8cbd5df647cb594334c79d1d05ef45cf3224e5d20acde2e2d79a390f273c2de6", + "workspace_digest": "ffb5c7526ee87395253342ddc858ced3263342159558efa379e9ff990c80d97d", "acceptance_input_digest": "c80c08451f13ec0daf76f914b14b12b43a30364b61a424ac60fccb9b24de8ba5", "passed": true, "commands": [ From d98db8524b2155e9067ab0d290c948f55574879b Mon Sep 17 00:00:00 2001 From: 0xLeif Date: Mon, 13 Jul 2026 00:18:26 -0600 Subject: [PATCH 22/25] fix(governance): address final rollout review findings --- .../approvals.json | 7 ++ .../state.json | 2 +- .../verification.json | 8 +- .../approvals.json | 7 ++ .../state.json | 2 +- .../verification.json | 8 +- .specsync/sdd.json | 2 + specs/ai/requirements.md | 31 ++---- specs/ask/requirements.md | 26 +---- specs/changelog/requirements.md | 41 ++------ specs/config/requirements.md | 46 ++------- specs/create_template/requirements.md | 36 ++----- specs/doctor/requirements.md | 31 ++---- specs/envelope/requirements.md | 36 ++----- specs/github/requirements.md | 51 ++-------- specs/init/requirements.md | 56 +++-------- specs/introspect/requirements.md | 26 +---- specs/llm/requirements.md | 36 ++----- specs/main/requirements.md | 21 +--- specs/meta/requirements.md | 31 ++---- specs/prompts/requirements.md | 36 ++----- specs/remote/requirements.md | 37 ++----- specs/review/requirements.md | 31 ++---- specs/run/requirements.md | 36 ++----- specs/spec/requirements.md | 41 ++------ specs/spinner/requirements.md | 21 +--- specs/templates/requirements.md | 61 +++--------- specs/trust/requirements.md | 41 ++------ specs/utils/requirements.md | 46 ++------- specs/validate/requirements.md | 26 +---- specs/watch/requirements.md | 41 ++------ specs/work/requirements.md | 96 ++++--------------- .../corvid-stack/.github/workflows/trust.yml | 4 +- templates/corvid-stack/.specsync/sdd.json | 1 + templates/corvid-stack/README.md.tera | 2 +- 35 files changed, 222 insertions(+), 802 deletions(-) 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 index 14aaa280..23394b60 100644 --- 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 @@ -48,6 +48,13 @@ "timestamp": 1783922639, "digest": "29aef45929401f47b9d945bf73a850032af3efbaf9d7fd35bfb55f3ee748aca1", "note": "Accepted after renewing verification for the non-recursive governance test lane." + }, + { + "gate": "acceptance", + "actor": "0xLeif", + "timestamp": 1783923481, + "digest": "1b71dcb19cf474784ccc9aa4e4bfe4aee685f20941b368bb96fd7bf3d451dc38", + "note": "Accepted after addressing final policy and semantic requirement review findings." } ] } 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 index a4726df4..400dc58a 100644 --- 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 @@ -8,7 +8,7 @@ "state": "accepted", "base_commit": "02550b3fac7e9a5ca12f5aecc1773f89972820f0", "created_at": 1783831307, - "updated_at": 1783922639, + "updated_at": 1783923481, "affected_specs": [], "affected_paths": [ ".github/workflows/", 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 index 595b4b23..b7faa3c4 100644 --- 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 @@ -1,9 +1,9 @@ { - "timestamp": 1783922603, - "commit": "e429294b4f39a9ec54b5084a7d090654dd38b1f3", + "timestamp": 1783923441, + "commit": "ea62bf537dce717056d236b5b4320c809fff073b", "contract_digest": "e501068a05e6748686f9e67c2abc8740da52e6d7df64770bbb7c6bd6e8d2c391", - "workspace_digest": "ffb5c7526ee87395253342ddc858ced3263342159558efa379e9ff990c80d97d", - "acceptance_input_digest": "769e41d252a8885d559c3292fd07c0f3774660d02bf5f675bdd357768b7a5fd9", + "workspace_digest": "e2fdb14e10d9873294786a8af4905fe9a0164d5d5c5b09b7079a785c1ba6214e", + "acceptance_input_digest": "b92e4e37166ec59d49b2735bf5db174233b392b9dc73cbfa73bf0738fa94322d", "passed": true, "commands": [ { diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json index 26a611f1..4b7e5b74 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json @@ -48,6 +48,13 @@ "timestamp": 1783922642, "digest": "dd0475dd7f22aea80ecdb40a9ce20062d20bfa4ae6db6006b2b6915f0a35b44a", "note": "Accepted after renewing verification against the final non-recursive governance lane." + }, + { + "gate": "acceptance", + "actor": "0xLeif", + "timestamp": 1783923481, + "digest": "d395258a462cf9cba7cf47abe6be4233715895293010ea39c78641c33a2b1957", + "note": "Accepted after final generated-template policy and local-gate review fixes." } ] } diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json index c84bfea6..3a604ed9 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json @@ -8,7 +8,7 @@ "state": "accepted", "base_commit": "02550b3fac7e9a5ca12f5aecc1773f89972820f0", "created_at": 1783831323, - "updated_at": 1783922642, + "updated_at": 1783923481, "affected_specs": [], "affected_paths": [ "templates/corvid-stack/" diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json index 6ba2fea9..3f73df45 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json @@ -1,9 +1,9 @@ { - "timestamp": 1783922628, - "commit": "e429294b4f39a9ec54b5084a7d090654dd38b1f3", + "timestamp": 1783923470, + "commit": "ea62bf537dce717056d236b5b4320c809fff073b", "contract_digest": "eba5b5589df084078203786c6f051df9378749313f2ffa761fddcff0e9d49c57", - "workspace_digest": "ffb5c7526ee87395253342ddc858ced3263342159558efa379e9ff990c80d97d", - "acceptance_input_digest": "c80c08451f13ec0daf76f914b14b12b43a30364b61a424ac60fccb9b24de8ba5", + "workspace_digest": "e2fdb14e10d9873294786a8af4905fe9a0164d5d5c5b09b7079a785c1ba6214e", + "acceptance_input_digest": "bd5c95c4f935bb82c32c69884c0fde4d331b2b022cee31b24c405ca4ad85c267", "passed": true, "commands": [ { diff --git a/.specsync/sdd.json b/.specsync/sdd.json index 76190042..ef3d1830 100644 --- a/.specsync/sdd.json +++ b/.specsync/sdd.json @@ -32,9 +32,11 @@ ".specsync/sdd.json", ".specsync/config.toml", ".specsync/config.json", + ".specsync/registry.toml", ".specsync/version", "templates/", "fledge.toml", + "install.sh", ".trust.toml", ".augur.toml", ".attest.json", diff --git a/specs/ai/requirements.md b/specs/ai/requirements.md index 7a13eb3f..b3652066 100644 --- a/specs/ai/requirements.md +++ b/specs/ai/requirements.md @@ -13,46 +13,27 @@ spec: ai.spec.md ### REQ-ai-001 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `fledge ai status` matches the provider/model/host that `llm::build_provider` would resolve; regression between the two is a tracked bug -Acceptance Criteria - -- `fledge ai status` matches the provider/model/host that `llm::build_provider` would resolve; regression between the two is a tracked bug ### REQ-ai-002 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `fledge ai models --provider ollama --json` parses cleanly with `jq` and includes at least `name` per model -- `fledge ai models --provider ollama --json` parses cleanly with `jq` and includes at least `name` per model ### REQ-ai-003 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `fledge ai use ` writes `ai.provider` + per-provider `model` to `~/.config/fledge/config.toml` atomically -Acceptance Criteria - -- `fledge ai use ` writes `ai.provider` + per-provider `model` to `~/.config/fledge/config.toml` atomically ### REQ-ai-004 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `fledge ai use` in `--non-interactive` without a provider arg errors via `utils::require_interactive` -- `fledge ai use` in `--non-interactive` without a provider arg errors via `utils::require_interactive` ### REQ-ai-005 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `fledge ai use ollama` interactively, with a running daemon, offers a Select with the live model list -Acceptance Criteria - -- `fledge ai use ollama` interactively, with a running daemon, offers a Select with the live model list ### REQ-ai-006 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria - -- Unknown providers on any `--provider` flag reject at clap parse time (not at runtime) +The implementation SHALL meet this contract: Unknown providers on any `--provider` flag reject at clap parse time (not at runtime) ## Constraints diff --git a/specs/ask/requirements.md b/specs/ask/requirements.md index 3865f509..e6b31ecb 100644 --- a/specs/ask/requirements.md +++ b/specs/ask/requirements.md @@ -11,39 +11,23 @@ spec: ask.spec.md ### REQ-ask-001 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `fledge ask ` joins all trailing arguments into a single question -Acceptance Criteria - -- `fledge ask ` joins all trailing arguments into a single question ### REQ-ask-002 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: The question is sent to Claude CLI running in the current project directory -- The question is sent to Claude CLI running in the current project directory ### REQ-ask-003 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: The response is streamed to stdout -- The response is streamed to stdout ### REQ-ask-004 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: Missing Claude CLI produces install instructions -Acceptance Criteria - -- Missing Claude CLI produces install instructions ### REQ-ask-005 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria - -- No question provided produces a usage hint +The implementation SHALL meet this contract: No question provided produces a usage hint ## Constraints diff --git a/specs/changelog/requirements.md b/specs/changelog/requirements.md index 49165bf6..a8973a14 100644 --- a/specs/changelog/requirements.md +++ b/specs/changelog/requirements.md @@ -16,57 +16,32 @@ type: requirements ### REQ-changelog-001 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `fledge changelog` shows all tagged releases with commits grouped by conventional commit type -Acceptance Criteria - -- `fledge changelog` shows all tagged releases with commits grouped by conventional commit type ### REQ-changelog-002 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `fledge changelog --limit 3` shows only the 3 most recent releases -- `fledge changelog --limit 3` shows only the 3 most recent releases ### REQ-changelog-003 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `fledge changelog --tag v0.5.0` shows only that release -- `fledge changelog --tag v0.5.0` shows only that release ### REQ-changelog-004 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `fledge changelog --unreleased` shows commits since the latest tag -Acceptance Criteria - -- `fledge changelog --unreleased` shows commits since the latest tag ### REQ-changelog-005 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `fledge changelog --json` outputs structured JSON -- `fledge changelog --json` outputs structured JSON ### REQ-changelog-006 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: Merge commits are excluded -Acceptance Criteria - -- Merge commits are excluded ### REQ-changelog-007 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Scoped commits (e.g., `fix(parser): msg`) are correctly parsed -- Scoped commits (e.g., `fix(parser): msg`) are correctly parsed ### REQ-changelog-008 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria - -- Non-conventional commits appear under "Other" +The implementation SHALL meet this contract: Non-conventional commits appear under "Other" diff --git a/specs/config/requirements.md b/specs/config/requirements.md index f2403f12..ed00b3a1 100644 --- a/specs/config/requirements.md +++ b/specs/config/requirements.md @@ -13,67 +13,39 @@ spec: config.spec.md ### REQ-config-001 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `fledge config list` displays all configured values and empty list sections -Acceptance Criteria - -- `fledge config list` displays all configured values and empty list sections ### REQ-config-002 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `fledge config get ` prints the value for any valid key (scalar or list) -- `fledge config get ` prints the value for any valid key (scalar or list) ### REQ-config-003 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `fledge config set ` persists scalar values to `config.toml` -- `fledge config set ` persists scalar values to `config.toml` ### REQ-config-004 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `fledge config unset ` removes values (clears lists for list keys) -Acceptance Criteria - -- `fledge config unset ` removes values (clears lists for list keys) ### REQ-config-005 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `fledge config add ` appends to list keys with deduplication -- `fledge config add ` appends to list keys with deduplication ### REQ-config-006 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `fledge config remove ` removes from list keys and reports whether found -Acceptance Criteria - -- `fledge config remove ` removes from list keys and reports whether found ### REQ-config-007 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Using `set` on a list key (or `add`/`remove` on a scalar key) produces a clear error with guidance -- Using `set` on a list key (or `add`/`remove` on a scalar key) produces a clear error with guidance ### REQ-config-008 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Config file is created on first write if it doesn't exist -- Config file is created on first write if it doesn't exist ### REQ-config-009 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria - -- Missing config file returns sensible defaults (MIT license, no author, empty lists) +The implementation SHALL meet this contract: Missing config file returns sensible defaults (MIT license, no author, empty lists) ## Constraints diff --git a/specs/create_template/requirements.md b/specs/create_template/requirements.md index ae9c106e..02074596 100644 --- a/specs/create_template/requirements.md +++ b/specs/create_template/requirements.md @@ -12,53 +12,31 @@ spec: create_template.spec.md ### REQ-create-template-001 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `fledge create-template my-template` creates a new directory with a valid template scaffold -Acceptance Criteria - -- `fledge create-template my-template` creates a new directory with a valid template scaffold ### REQ-create-template-002 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Generated `template.toml` is valid TOML parseable as `TemplateManifest` -- Generated `template.toml` is valid TOML parseable as `TemplateManifest` ### REQ-create-template-003 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: Interactive prompts ask for name, description, render globs, hooks, and custom prompts -Acceptance Criteria - -- Interactive prompts ask for name, description, render globs, hooks, and custom prompts ### REQ-create-template-004 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: All prompts have sensible defaults that can be accepted with Enter -- All prompts have sensible defaults that can be accepted with Enter ### REQ-create-template-005 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: Includes example `.tera` file demonstrating variable substitution -Acceptance Criteria - -- Includes example `.tera` file demonstrating variable substitution ### REQ-create-template-006 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Includes author-facing README with instructions for testing locally -- Includes author-facing README with instructions for testing locally ### REQ-create-template-007 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria - -- Fails with a clear error if the target directory already exists +The implementation SHALL meet this contract: Fails with a clear error if the target directory already exists ## Constraints diff --git a/specs/doctor/requirements.md b/specs/doctor/requirements.md index 54bfd93f..9cb64376 100644 --- a/specs/doctor/requirements.md +++ b/specs/doctor/requirements.md @@ -12,46 +12,27 @@ spec: doctor.spec.md ### REQ-doctor-001 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `fledge doctor` reports four sections: `fledge`, `Git`, `AI`, `Toolchains` -Acceptance Criteria - -- `fledge doctor` reports four sections: `fledge`, `Git`, `AI`, `Toolchains` ### REQ-doctor-002 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Each failing check in a non-informational section shows an actionable fix command -- Each failing check in a non-informational section shows an actionable fix command ### REQ-doctor-003 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: The `Toolchains` section is informational — missing entries render dimmed and don't pollute the pass/fail totals -Acceptance Criteria - -- The `Toolchains` section is informational — missing entries render dimmed and don't pollute the pass/fail totals ### REQ-doctor-004 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `--json` outputs a structured `DoctorReport` with all check results, including `informational: bool` per Section -- `--json` outputs a structured `DoctorReport` with all check results, including `informational: bool` per Section ### REQ-doctor-005 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: Exit summary shows count of passed checks and issues found, computed only over non-informational sections -Acceptance Criteria - -- Exit summary shows count of passed checks and issues found, computed only over non-informational sections ### REQ-doctor-006 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria - -- Toolchains probed: rustc, cargo, node, npm, pnpm, bun, yarn, python3, uv, poetry, go, ruby, swift, java, gradle, mvn +The implementation SHALL meet this contract: Toolchains probed: rustc, cargo, node, npm, pnpm, bun, yarn, python3, uv, poetry, go, ruby, swift, java, gradle, mvn ## Constraints diff --git a/specs/envelope/requirements.md b/specs/envelope/requirements.md index 7394ee55..f56c899a 100644 --- a/specs/envelope/requirements.md +++ b/specs/envelope/requirements.md @@ -12,53 +12,31 @@ spec: envelope.spec.md ### REQ-envelope-001 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `resource(schema_version, key, items)` builds `{schema_version, : items}` with no `action` key -Acceptance Criteria - -- `resource(schema_version, key, items)` builds `{schema_version, : items}` with no `action` key ### REQ-envelope-002 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `action(schema_version, action, fields)` builds `{schema_version, action, ...fields}`, inserting the fixed keys first then merging an object `fields` -- `action(schema_version, action, fields)` builds `{schema_version, action, ...fields}`, inserting the fixed keys first then merging an object `fields` ### REQ-envelope-003 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `versioned(schema_version, fields)` builds `{schema_version, ...fields}` with no `action` key -Acceptance Criteria - -- `versioned(schema_version, fields)` builds `{schema_version, ...fields}` with no `action` key ### REQ-envelope-004 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Every envelope carries a `schema_version` from the caller-supplied `u32` -- Every envelope carries a `schema_version` from the caller-supplied `u32` ### REQ-envelope-005 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: Output is byte-for-byte identical to the equivalent hand-rolled `serde_json::json!` -Acceptance Criteria - -- Output is byte-for-byte identical to the equivalent hand-rolled `serde_json::json!` ### REQ-envelope-006 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: A non-object `fields` value contributes no extra keys; the envelope still carries its fixed keys -- A non-object `fields` value contributes no extra keys; the envelope still carries its fixed keys ### REQ-envelope-007 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria - -- Non-serializable `resource` items store `Value::Null` under the key instead of panicking +The implementation SHALL meet this contract: Non-serializable `resource` items store `Value::Null` under the key instead of panicking ## Constraints diff --git a/specs/github/requirements.md b/specs/github/requirements.md index 8aafab7e..e4dd90d6 100644 --- a/specs/github/requirements.md +++ b/specs/github/requirements.md @@ -12,74 +12,43 @@ spec: github.spec.md ### REQ-github-001 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `detect_repo` parses HTTPS remote URLs (`https://github.com/owner/repo.git`) -Acceptance Criteria - -- `detect_repo` parses HTTPS remote URLs (`https://github.com/owner/repo.git`) ### REQ-github-002 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `detect_repo` parses SSH remote URLs (`git@github.com:owner/repo.git`) -- `detect_repo` parses SSH remote URLs (`git@github.com:owner/repo.git`) ### REQ-github-003 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `detect_repo` handles token-authenticated HTTPS URLs -- `detect_repo` handles token-authenticated HTTPS URLs ### REQ-github-004 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `detect_repo` strips trailing `.git` suffix -Acceptance Criteria - -- `detect_repo` strips trailing `.git` suffix ### REQ-github-005 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `github_api_get` reads token from `FLEDGE_GITHUB_TOKEN`, `GITHUB_TOKEN`, or config -- `github_api_get` reads token from `FLEDGE_GITHUB_TOKEN`, `GITHUB_TOKEN`, or config ### REQ-github-006 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `github_api_get` returns parsed JSON on success -- `github_api_get` returns parsed JSON on success ### REQ-github-007 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: 403 responses produce a message about setting a token -Acceptance Criteria - -- 403 responses produce a message about setting a token ### REQ-github-008 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: 404 responses produce a "Not found" error -- 404 responses produce a "Not found" error ### REQ-github-009 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `format_relative_time` converts ISO 8601 timestamps to human-readable relative times -- `format_relative_time` converts ISO 8601 timestamps to human-readable relative times ### REQ-github-010 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria - -- `format_relative_time` falls back to the raw string for unparseable input +The implementation SHALL meet this contract: `format_relative_time` falls back to the raw string for unparseable input ## Constraints diff --git a/specs/init/requirements.md b/specs/init/requirements.md index 5c83ad8f..11fb8aa2 100644 --- a/specs/init/requirements.md +++ b/specs/init/requirements.md @@ -15,81 +15,47 @@ spec: init.spec.md ### REQ-init-001 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `fledge init ` creates a directory with rendered template files -Acceptance Criteria - -- `fledge init ` creates a directory with rendered template files ### REQ-init-002 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `fledge init --template ` uses the specified template -- `fledge init --template ` uses the specified template ### REQ-init-003 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `fledge init --template owner/repo` fetches and uses a remote template -- `fledge init --template owner/repo` fetches and uses a remote template ### REQ-init-004 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: Without `--template`, an interactive selector is shown -Acceptance Criteria - -- Without `--template`, an interactive selector is shown ### REQ-init-005 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `--dry-run` prints file list, hooks, and git status without writing -- `--dry-run` prints file list, hooks, and git status without writing ### REQ-init-006 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `--no-git` skips git init and initial commit -- `--no-git` skips git init and initial commit ### REQ-init-007 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `--no-install` skips post-create hooks -Acceptance Criteria - -- `--no-install` skips post-create hooks ### REQ-init-008 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `--yes` auto-confirms remote hook prompts -- `--yes` auto-confirms remote hook prompts ### REQ-init-009 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `--refresh` clears cached remote repos before fetching -- `--refresh` clears cached remote repos before fetching ### REQ-init-010 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: If the target directory already exists, the command errors immediately -Acceptance Criteria - -- If the target directory already exists, the command errors immediately ### REQ-init-011 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria - -- Git init includes an initial commit with all scaffolded files +The implementation SHALL meet this contract: Git init includes an initial commit with all scaffolded files ## Constraints diff --git a/specs/introspect/requirements.md b/specs/introspect/requirements.md index 230f44f8..51092dd6 100644 --- a/specs/introspect/requirements.md +++ b/specs/introspect/requirements.md @@ -12,39 +12,23 @@ spec: introspect.spec.md ### REQ-introspect-001 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `fledge introspect --json` produces a single JSON object parseable by `serde_json::from_str` and `jq` -Acceptance Criteria - -- `fledge introspect --json` produces a single JSON object parseable by `serde_json::from_str` and `jq` ### REQ-introspect-002 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `fledge introspect` without `--json` produces a human-readable indented tree -- `fledge introspect` without `--json` produces a human-readable indented tree ### REQ-introspect-003 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: The output includes every user-facing subcommand and arg — no silent gaps -- The output includes every user-facing subcommand and arg — no silent gaps ### REQ-introspect-004 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: clap's auto-generated `--help` and `--version` and `help` subcommand are excluded as noise -Acceptance Criteria - -- clap's auto-generated `--help` and `--version` and `help` subcommand are excluded as noise ### REQ-introspect-005 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria - -- Subcommand aliases and global args are explicitly labeled in the output so agents can reason about them +The implementation SHALL meet this contract: Subcommand aliases and global args are explicitly labeled in the output so agents can reason about them ## Constraints diff --git a/specs/llm/requirements.md b/specs/llm/requirements.md index 71155c67..90b93137 100644 --- a/specs/llm/requirements.md +++ b/specs/llm/requirements.md @@ -13,53 +13,31 @@ spec: llm.spec.md ### REQ-llm-001 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: Default behavior (no config, no env, no flag) is identical to the pre-v0.13 Claude-CLI-only behavior -Acceptance Criteria - -- Default behavior (no config, no env, no flag) is identical to the pre-v0.13 Claude-CLI-only behavior ### REQ-llm-002 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Setting `ai.provider = "ollama"` in config OR `FLEDGE_AI_PROVIDER=ollama` in env routes all AI commands through Ollama -- Setting `ai.provider = "ollama"` in config OR `FLEDGE_AI_PROVIDER=ollama` in env routes all AI commands through Ollama ### REQ-llm-003 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: Per-invocation `--provider ollama` overrides both env and config -Acceptance Criteria - -- Per-invocation `--provider ollama` overrides both env and config ### REQ-llm-004 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Model selection follows the same override > env > config > default precedence -- Model selection follows the same override > env > config > default precedence ### REQ-llm-005 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: Ollama's HTTP request shape matches the `/api/generate` endpoint's published schema -Acceptance Criteria - -- Ollama's HTTP request shape matches the `/api/generate` endpoint's published schema ### REQ-llm-006 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `fledge doctor` reports both providers and which is active -- `fledge doctor` reports both providers and which is active ### REQ-llm-007 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria - -- No regression: `fledge ask --json` and `fledge review --json` outputs remain parseable; payloads gain a `provider` and `model` field +The implementation SHALL meet this contract: No regression: `fledge ask --json` and `fledge review --json` outputs remain parseable; payloads gain a `provider` and `model` field ## Constraints diff --git a/specs/main/requirements.md b/specs/main/requirements.md index eecb8dfa..2a1cff47 100644 --- a/specs/main/requirements.md +++ b/specs/main/requirements.md @@ -1,28 +1,15 @@ ### REQ-main-001 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: Parse CLI arguments via clap derive -Acceptance Criteria - -- Parse CLI arguments via clap derive ### REQ-main-002 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Dispatch each subcommand to its module's entry function -- Dispatch each subcommand to its module's entry function ### REQ-main-003 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Forward unknown commands to installed plugins -- Forward unknown commands to installed plugins ### REQ-main-004 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria - -- Generate shell completions on demand +The implementation SHALL meet this contract: Generate shell completions on demand diff --git a/specs/meta/requirements.md b/specs/meta/requirements.md index a243bd81..3ce349b8 100644 --- a/specs/meta/requirements.md +++ b/specs/meta/requirements.md @@ -13,46 +13,27 @@ spec: meta.spec.md ### REQ-meta-001 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `write_project_meta` writes `.fledge/meta.toml` with `SourceInfo` provenance, string template variables, and a hash for each existing created file -Acceptance Criteria - -- `write_project_meta` writes `.fledge/meta.toml` with `SourceInfo` provenance, string template variables, and a hash for each existing created file ### REQ-meta-002 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `compute_file_hash` returns a 64-character lowercase hex SHA-256 digest and is deterministic -- `compute_file_hash` returns a 64-character lowercase hex SHA-256 digest and is deterministic ### REQ-meta-003 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: The `.fledge` directory is created if missing -Acceptance Criteria - -- The `.fledge` directory is created if missing ### REQ-meta-004 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: A `.fledge/.gitignore` is created if one does not already exist, and an existing one is never overwritten -- A `.fledge/.gitignore` is created if one does not already exist, and an existing one is never overwritten ### REQ-meta-005 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: Created files that no longer exist on disk are silently skipped, not errored -Acceptance Criteria - -- Created files that no longer exist on disk are silently skipped, not errored ### REQ-meta-006 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria - -- `fledge_version` is captured from `CARGO_PKG_VERSION` at compile time and `created` is the local date as `YYYY-MM-DD` +The implementation SHALL meet this contract: `fledge_version` is captured from `CARGO_PKG_VERSION` at compile time and `created` is the local date as `YYYY-MM-DD` ## Constraints diff --git a/specs/prompts/requirements.md b/specs/prompts/requirements.md index fee11677..df3a8d9e 100644 --- a/specs/prompts/requirements.md +++ b/specs/prompts/requirements.md @@ -13,53 +13,31 @@ spec: prompts.spec.md ### REQ-prompts-001 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `select_template()` presents an interactive list with name and description columns -Acceptance Criteria - -- `select_template()` presents an interactive list with name and description columns ### REQ-prompts-002 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `prompt_variables()` collects all core variables (project_name, author, github_org, license, year, date) and template-specific prompts -- `prompt_variables()` collects all core variables (project_name, author, github_org, license, year, date) and template-specific prompts ### REQ-prompts-003 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: Author falls back: config → `git config user.name` → interactive prompt -Acceptance Criteria - -- Author falls back: config → `git config user.name` → interactive prompt ### REQ-prompts-004 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: GitHub org falls back: config → interactive prompt with "CorvidLabs" default -- GitHub org falls back: config → interactive prompt with "CorvidLabs" default ### REQ-prompts-005 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: License is always pulled from config (defaults to MIT) -Acceptance Criteria - -- License is always pulled from config (defaults to MIT) ### REQ-prompts-006 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Template-specific prompt defaults support Tera variable interpolation -- Template-specific prompt defaults support Tera variable interpolation ### REQ-prompts-007 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria - -- Case conversion produces correct snake_case and PascalCase variants +The implementation SHALL meet this contract: Case conversion produces correct snake_case and PascalCase variants ## Constraints diff --git a/specs/remote/requirements.md b/specs/remote/requirements.md index 301cb7db..2483262d 100644 --- a/specs/remote/requirements.md +++ b/specs/remote/requirements.md @@ -4,53 +4,30 @@ ### REQ-remote-001 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: Clone GitHub repos to local cache for template discovery -Acceptance Criteria - -- Clone GitHub repos to local cache for template discovery ### REQ-remote-002 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Support authenticated access via GitHub token -- Support authenticated access via GitHub token ### REQ-remote-003 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Support `owner/repo` and `owner/repo/subpath` reference formats -- Support `owner/repo` and `owner/repo/subpath` reference formats ### REQ-remote-004 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: Update cached repos on subsequent access -Acceptance Criteria - -- Update cached repos on subsequent access ### REQ-remote-005 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria - -- Shallow clones (`--depth 1`) to minimize bandwidth +The implementation SHALL meet this contract: Shallow clones (`--depth 1`) to minimize bandwidth ## Non-Functional ### REQ-remote-006 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Cache location follows platform conventions (XDG on Linux, Library/Caches on macOS) -- Cache location follows platform conventions (XDG on Linux, Library/Caches on macOS) ### REQ-remote-007 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria - -- Git operations should not leak tokens in stdout/stderr output +The implementation SHALL meet this contract: Git operations should not leak tokens in stdout/stderr output diff --git a/specs/review/requirements.md b/specs/review/requirements.md index a5d1f86a..a844e4bb 100644 --- a/specs/review/requirements.md +++ b/specs/review/requirements.md @@ -12,46 +12,27 @@ spec: review.spec.md ### REQ-review-001 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `fledge review` diffs the current branch against the default base (main/master) and sends it to Claude CLI -Acceptance Criteria - -- `fledge review` diffs the current branch against the default base (main/master) and sends it to Claude CLI ### REQ-review-002 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `fledge review --base develop` uses a custom base branch -- `fledge review --base develop` uses a custom base branch ### REQ-review-003 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `fledge review --file src/foo.rs` restricts the review to one file -Acceptance Criteria - -- `fledge review --file src/foo.rs` restricts the review to one file ### REQ-review-004 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Diff stats are displayed before the AI output -- Diff stats are displayed before the AI output ### REQ-review-005 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: Empty diffs bail with a clear message -Acceptance Criteria - -- Empty diffs bail with a clear message ### REQ-review-006 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria - -- Missing Claude CLI produces install instructions +The implementation SHALL meet this contract: Missing Claude CLI produces install instructions ## Constraints diff --git a/specs/run/requirements.md b/specs/run/requirements.md index 683227e5..6bad0634 100644 --- a/specs/run/requirements.md +++ b/specs/run/requirements.md @@ -13,53 +13,31 @@ spec: run.spec.md ### REQ-run-001 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `fledge run ` executes the named task from `fledge.toml` -Acceptance Criteria - -- `fledge run ` executes the named task from `fledge.toml` ### REQ-run-002 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Task dependencies run in topological order before the requested task -- Task dependencies run in topological order before the requested task ### REQ-run-003 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: Circular dependencies produce an error listing the cycle -Acceptance Criteria - -- Circular dependencies produce an error listing the cycle ### REQ-run-004 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `fledge run --list` shows task names and descriptions -- `fledge run --list` shows task names and descriptions ### REQ-run-005 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `fledge run --init` generates `fledge.toml` with defaults for the detected project type -Acceptance Criteria - -- `fledge run --init` generates `fledge.toml` with defaults for the detected project type ### REQ-run-006 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Unknown task names produce an error listing available tasks -- Unknown task names produce an error listing available tasks ### REQ-run-007 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria - -- Tasks support environment variables and working directory overrides +The implementation SHALL meet this contract: Tasks support environment variables and working directory overrides ## Constraints diff --git a/specs/spec/requirements.md b/specs/spec/requirements.md index b51f0b69..e97cd21c 100644 --- a/specs/spec/requirements.md +++ b/specs/spec/requirements.md @@ -13,60 +13,35 @@ spec: spec.spec.md ### REQ-spec-001 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `fledge spec check` validates all specs in the configured specs directory -Acceptance Criteria - -- `fledge spec check` validates all specs in the configured specs directory ### REQ-spec-002 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `fledge spec check --strict` treats warnings as errors -- `fledge spec check --strict` treats warnings as errors ### REQ-spec-003 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `fledge spec init` creates `.specsync/` with config.toml, registry.toml, .gitignore, and version -- `fledge spec init` creates `.specsync/` with config.toml, registry.toml, .gitignore, and version ### REQ-spec-004 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `fledge spec init` creates `specs/` directory if it doesn't exist -Acceptance Criteria - -- `fledge spec init` creates `specs/` directory if it doesn't exist ### REQ-spec-005 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `fledge spec new ` creates `specs//` with spec.md and companion files -- `fledge spec new ` creates `specs//` with spec.md and companion files ### REQ-spec-006 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: Validation checks: frontmatter fields, required sections, source file existence -Acceptance Criteria - -- Validation checks: frontmatter fields, required sections, source file existence ### REQ-spec-007 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Exit code 1 on errors (or warnings in strict mode), 0 otherwise -- Exit code 1 on errors (or warnings in strict mode), 0 otherwise ### REQ-spec-008 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria - -- Colored output with checkmarks/crosses for each spec +The implementation SHALL meet this contract: Colored output with checkmarks/crosses for each spec ## Constraints diff --git a/specs/spinner/requirements.md b/specs/spinner/requirements.md index 1b1f0694..8fbac9a7 100644 --- a/specs/spinner/requirements.md +++ b/specs/spinner/requirements.md @@ -11,32 +11,19 @@ spec: spinner.spec.md ### REQ-spinner-001 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `Spinner::start(msg)` displays an animated spinner with the given message -Acceptance Criteria - -- `Spinner::start(msg)` displays an animated spinner with the given message ### REQ-spinner-002 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `Spinner::finish()` clears the spinner line completely -- `Spinner::finish()` clears the spinner line completely ### REQ-spinner-003 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: A random theme is chosen each time a spinner starts -- A random theme is chosen each time a spinner starts ### REQ-spinner-004 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria - -- All themes animate smoothly without visual glitches +The implementation SHALL meet this contract: All themes animate smoothly without visual glitches ## Constraints diff --git a/specs/templates/requirements.md b/specs/templates/requirements.md index 1306bec5..963c5b53 100644 --- a/specs/templates/requirements.md +++ b/specs/templates/requirements.md @@ -15,88 +15,51 @@ spec: templates.spec.md ### REQ-templates-001 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `discover_templates()` finds all built-in templates (8 language starters: `go-cli`, `kotlin-kmp`, `kotlin-ktor-api`, `python-cli`, `rust-cli`, `static-site`, `ts-bun`, `ts-node`; plus setup-only `fledge-plugin` and `corvid-stack`) -Acceptance Criteria - -- `discover_templates()` finds all built-in templates (8 language starters: `go-cli`, `kotlin-kmp`, `kotlin-ktor-api`, `python-cli`, `rust-cli`, `static-site`, `ts-bun`, `ts-node`; plus setup-only `fledge-plugin` and `corvid-stack`) ### REQ-templates-002 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Extra paths from config are searched for template directories -- Extra paths from config are searched for template directories ### REQ-templates-003 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: Remote repos from config are fetched and searched for templates -Acceptance Criteria - -- Remote repos from config are fetched and searched for templates ### REQ-templates-004 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Templates are returned sorted alphabetically by name -- Templates are returned sorted alphabetically by name ### REQ-templates-005 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: Directories without `template.toml` are silently skipped -Acceptance Criteria - -- Directories without `template.toml` are silently skipped ### REQ-templates-006 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Non-existent extra paths are silently skipped -- Non-existent extra paths are silently skipped ### REQ-templates-007 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `render_template()` renders `.tera` files and strips the extension -- `render_template()` renders `.tera` files and strips the extension ### REQ-templates-008 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `render_template()` renders files matching `files.render` globs -Acceptance Criteria - -- `render_template()` renders files matching `files.render` globs ### REQ-templates-009 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `render_template()` copies non-matching files as-is -- `render_template()` copies non-matching files as-is ### REQ-templates-010 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `render_template()` skips files matching `files.ignore` globs -- `render_template()` skips files matching `files.ignore` globs ### REQ-templates-011 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `render_template()` renders Tera variables in file/directory paths -Acceptance Criteria - -- `render_template()` renders Tera variables in file/directory paths ### REQ-templates-012 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria - -- Created files list is returned sorted alphabetically +The implementation SHALL meet this contract: Created files list is returned sorted alphabetically ## Constraints diff --git a/specs/trust/requirements.md b/specs/trust/requirements.md index 6bc849cb..b1863638 100644 --- a/specs/trust/requirements.md +++ b/specs/trust/requirements.md @@ -11,60 +11,35 @@ spec: trust.spec.md ### REQ-trust-001 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `determine_trust_tier` classifies `CorvidLabs/*` sources as Official -Acceptance Criteria - -- `determine_trust_tier` classifies `CorvidLabs/*` sources as Official ### REQ-trust-002 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `determine_trust_tier` classifies filesystem path sources as Local -- `determine_trust_tier` classifies filesystem path sources as Local ### REQ-trust-003 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `determine_trust_tier` classifies sources owned by a human member of the CorvidLabs org (e.g. `0xLeif/*`) as Team -- `determine_trust_tier` classifies sources owned by a human member of the CorvidLabs org (e.g. `0xLeif/*`) as Team ### REQ-trust-004 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `determine_trust_tier` classifies all other sources as Unverified -Acceptance Criteria - -- `determine_trust_tier` classifies all other sources as Unverified ### REQ-trust-005 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Supports local paths, HTTPS URLs, SSH URLs, and `owner/repo` shorthand -- Supports local paths, HTTPS URLs, SSH URLs, and `owner/repo` shorthand ### REQ-trust-006 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `parse_source_ref` splits `source@ref` without false-splitting on credential `@` signs -Acceptance Criteria - -- `parse_source_ref` splits `source@ref` without false-splitting on credential `@` signs ### REQ-trust-007 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `label` returns lowercase string representation -- `label` returns lowercase string representation ### REQ-trust-008 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria - -- `styled_label` returns colored console output (magenta=local, green=official, cyan=team, yellow=unverified) +The implementation SHALL meet this contract: `styled_label` returns colored console output (magenta=local, green=official, cyan=team, yellow=unverified) ## Constraints diff --git a/specs/utils/requirements.md b/specs/utils/requirements.md index ec1522e5..0a3fe1af 100644 --- a/specs/utils/requirements.md +++ b/specs/utils/requirements.md @@ -14,67 +14,39 @@ spec: utils.spec.md ### REQ-utils-001 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `set_non_interactive` / `is_non_interactive` are the only accessors to the global flag -Acceptance Criteria - -- `set_non_interactive` / `is_non_interactive` are the only accessors to the global flag ### REQ-utils-002 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `init_non_interactive_from_env` flips the flag when `FLEDGE_NON_INTERACTIVE` is a truthy value (`1`/`true`/`yes`/`y`/`on`, case-insensitive, trimmed) -- `init_non_interactive_from_env` flips the flag when `FLEDGE_NON_INTERACTIVE` is a truthy value (`1`/`true`/`yes`/`y`/`on`, case-insensitive, trimmed) ### REQ-utils-003 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `is_interactive` returns true only when stdin is a TTY and the non-interactive flag is unset -- `is_interactive` returns true only when stdin is a TTY and the non-interactive flag is unset ### REQ-utils-004 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `require_interactive` / `require_interactive_hint` return `Ok(())` only when `is_interactive`, otherwise bail with a flag- or hint-named error -Acceptance Criteria - -- `require_interactive` / `require_interactive_hint` return `Ok(())` only when `is_interactive`, otherwise bail with a flag- or hint-named error ### REQ-utils-005 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Case conversions are pure and total — any input (including empty) returns a `String` without panicking -- Case conversions are pure and total — any input (including empty) returns a `String` without panicking ### REQ-utils-006 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `validate_project_name` rejects empty strings, `/`, `\`, `..`, null bytes, and Windows-reserved device names -Acceptance Criteria - -- `validate_project_name` rejects empty strings, `/`, `\`, `..`, null bytes, and Windows-reserved device names ### REQ-utils-007 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `validate_github_org` rejects empty and slash-containing names but permits spaces -- `validate_github_org` rejects empty and slash-containing names but permits spaces ### REQ-utils-008 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `validate_commit_scope` requires non-empty, ≤64 chars, ASCII alphanumerics plus `-`/`_` -- `validate_commit_scope` requires non-empty, ≤64 chars, ASCII alphanumerics plus `-`/`_` ### REQ-utils-009 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria - -- `redact_secrets` scrubs Authorization / x-access-token headers, URL credentials, and Bearer tokens; clean input passes through byte-identical +The implementation SHALL meet this contract: `redact_secrets` scrubs Authorization / x-access-token headers, URL credentials, and Bearer tokens; clean input passes through byte-identical ## Constraints diff --git a/specs/validate/requirements.md b/specs/validate/requirements.md index 597eb4f6..48c35f3c 100644 --- a/specs/validate/requirements.md +++ b/specs/validate/requirements.md @@ -12,39 +12,23 @@ spec: validate.spec.md ### REQ-validate-001 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: Single template validation checks manifest, Tera syntax, variable definitions, and render globs -Acceptance Criteria - -- Single template validation checks manifest, Tera syntax, variable definitions, and render globs ### REQ-validate-002 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Batch validation validates all templates in a directory independently -- Batch validation validates all templates in a directory independently ### REQ-validate-003 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Strict mode exits non-zero on warnings -- Strict mode exits non-zero on warnings ### REQ-validate-004 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: JSON mode outputs structured ValidationReport array -Acceptance Criteria - -- JSON mode outputs structured ValidationReport array ### REQ-validate-005 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria - -- GitHub Actions `${{ }}` expressions are not flagged as Tera variables +The implementation SHALL meet this contract: GitHub Actions `${{ }}` expressions are not flagged as Tera variables ## Constraints diff --git a/specs/watch/requirements.md b/specs/watch/requirements.md index 0f0e0925..0a744958 100644 --- a/specs/watch/requirements.md +++ b/specs/watch/requirements.md @@ -6,57 +6,32 @@ spec: watch.spec.md ### REQ-watch-001 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: Watch a directory recursively for filesystem changes -Acceptance Criteria - -- Watch a directory recursively for filesystem changes ### REQ-watch-002 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Re-run a specified task or lane when relevant files change -- Re-run a specified task or lane when relevant files change ### REQ-watch-003 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Filter events by file extension (optional) -- Filter events by file extension (optional) ### REQ-watch-004 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: Ignore common non-source directories (.git, target, node_modules, .fledge, __pycache__) -Acceptance Criteria - -- Ignore common non-source directories (.git, target, node_modules, .fledge, __pycache__) ### REQ-watch-005 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Configurable debounce interval with deadline extension on new events -- Configurable debounce interval with deadline extension on new events ### REQ-watch-006 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: Perform an initial run before entering the watch loop -Acceptance Criteria - -- Perform an initial run before entering the watch loop ### REQ-watch-007 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Optional terminal clear before each re-run -- Optional terminal clear before each re-run ### REQ-watch-008 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria - -- Graceful error handling — target failures don't stop the watcher +The implementation SHALL meet this contract: Graceful error handling — target failures don't stop the watcher diff --git a/specs/work/requirements.md b/specs/work/requirements.md index 99991d15..2a0f03bb 100644 --- a/specs/work/requirements.md +++ b/specs/work/requirements.md @@ -18,137 +18,79 @@ spec: work.spec.md ### REQ-work-001 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `fledge work start ` creates a branch using the configured format (default: `{author}/{type}/{name}`) -Acceptance Criteria - -- `fledge work start ` creates a branch using the configured format (default: `{author}/{type}/{name}`) ### REQ-work-002 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `fledge work start --branch-type fix` creates a fix-type branch -- `fledge work start --branch-type fix` creates a fix-type branch ### REQ-work-003 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `fledge work start --issue 42` includes issue number in branch name -- `fledge work start --issue 42` includes issue number in branch name ### REQ-work-004 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `fledge work start --prefix user/leif` creates `user/leif/` branch -Acceptance Criteria - -- `fledge work start --prefix user/leif` creates `user/leif/` branch ### REQ-work-005 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `fledge work start` refuses if working tree is dirty -- `fledge work start` refuses if working tree is dirty ### REQ-work-006 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `fledge work start` rejects invalid branch types (not in feat, feature, fix, bug, chore, task, docs, hotfix, refactor) -Acceptance Criteria - -- `fledge work start` rejects invalid branch types (not in feat, feature, fix, bug, chore, task, docs, hotfix, refactor) ### REQ-work-007 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `fledge work commit` stages all changes and creates a commit (prompts for type + message interactively) -- `fledge work commit` stages all changes and creates a commit (prompts for type + message interactively) ### REQ-work-008 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `fledge work commit -m "message"` uses the given message with default type -- `fledge work commit -m "message"` uses the given message with default type ### REQ-work-009 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `fledge work commit --type fix -m "null pointer"` creates `fix: null pointer` commit -Acceptance Criteria - -- `fledge work commit --type fix -m "null pointer"` creates `fix: null pointer` commit ### REQ-work-010 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `fledge work commit --ai` generates the commit message from staged diff using the configured AI provider -- `fledge work commit --ai` generates the commit message from staged diff using the configured AI provider ### REQ-work-011 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `fledge work commit` refuses if there are no changes to commit -Acceptance Criteria - -- `fledge work commit` refuses if there are no changes to commit ### REQ-work-012 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `fledge work push` pushes the current branch to origin with `-u` tracking -- `fledge work push` pushes the current branch to origin with `-u` tracking ### REQ-work-013 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `fledge work push` refuses if on the default branch -- `fledge work push` refuses if on the default branch ### REQ-work-014 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `fledge work push` refuses if there are no commits ahead of the remote -Acceptance Criteria - -- `fledge work push` refuses if there are no commits ahead of the remote ### REQ-work-015 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `fledge work status` shows branch name, commits ahead/behind, and uncommitted file count -- `fledge work status` shows branch name, commits ahead/behind, and uncommitted file count ### REQ-work-016 -The implementation SHALL satisfy this requirement. +The implementation SHALL meet this contract: `fledge work status` does NOT call `gh` or any GitHub API — pure git only -Acceptance Criteria - -- `fledge work status` does NOT call `gh` or any GitHub API — pure git only ### REQ-work-017 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: Branch names are sanitized (lowercase, hyphens only) -- Branch names are sanitized (lowercase, hyphens only) ### REQ-work-018 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria +The implementation SHALL meet this contract: `[work]` section in `fledge.toml` can override `branch_format` and `default_type` -- `[work]` section in `fledge.toml` can override `branch_format` and `default_type` ### REQ-work-019 -The implementation SHALL satisfy this requirement. - -Acceptance Criteria - -- All subcommands support `--json` for agent consumption +The implementation SHALL meet this contract: All subcommands support `--json` for agent consumption ## Constraints diff --git a/templates/corvid-stack/.github/workflows/trust.yml b/templates/corvid-stack/.github/workflows/trust.yml index a320c89c..ea989453 100644 --- a/templates/corvid-stack/.github/workflows/trust.yml +++ b/templates/corvid-stack/.github/workflows/trust.yml @@ -21,4 +21,6 @@ jobs: uses: CorvidLabs/trust@9d32b5786d2e9e4d39fc581c0091c721ee3d4226 # v1.0.0 - name: Check managed agent rules - run: grep -q "CorvidLabs trust toolchain: BEGIN" AGENTS.md + run: | + grep -q "CorvidLabs trust toolchain: BEGIN" AGENTS.md + grep -q "CorvidLabs trust toolchain: END" AGENTS.md diff --git a/templates/corvid-stack/.specsync/sdd.json b/templates/corvid-stack/.specsync/sdd.json index fdc4feb8..5b994e50 100644 --- a/templates/corvid-stack/.specsync/sdd.json +++ b/templates/corvid-stack/.specsync/sdd.json @@ -23,6 +23,7 @@ "requirements.txt", ".specsync/sdd.json", ".specsync/config.toml", + ".specsync/registry.toml", ".specsync/version", "fledge.toml", ".trust.toml", diff --git a/templates/corvid-stack/README.md.tera b/templates/corvid-stack/README.md.tera index 4c548ea7..b42d6983 100644 --- a/templates/corvid-stack/README.md.tera +++ b/templates/corvid-stack/README.md.tera @@ -34,7 +34,7 @@ brew install CorvidLabs/tap/corvid-trust # Run the gate locally fledge trust doctor -fledge trust verify +fledge lanes run verify ``` Then fill in the `[tasks]` in `fledge.toml`, set `source_dirs` in From 7c47bb9d0b0d401a24e4727ecfde0b36fbc75804 Mon Sep 17 00:00:00 2001 From: 0xLeif Date: Mon, 13 Jul 2026 00:33:39 -0600 Subject: [PATCH 23/25] fix(governance): close final template policy gaps --- .github/workflows/trust.yml | 2 ++ .../approvals.json | 7 +++++++ .../state.json | 2 +- .../verification.json | 8 ++++---- .../approvals.json | 7 +++++++ .../state.json | 2 +- .../verification.json | 8 ++++---- src/templates.rs | 15 +++++++++++++-- templates/corvid-stack/.specsync/sdd.json | 1 + templates/corvid-stack/fledge.toml | 4 ++-- 10 files changed, 42 insertions(+), 14 deletions(-) diff --git a/.github/workflows/trust.yml b/.github/workflows/trust.yml index 1843df36..e21e3c4f 100644 --- a/.github/workflows/trust.yml +++ b/.github/workflows/trust.yml @@ -22,6 +22,8 @@ jobs: - name: CorvidLabs Trust gate id: trust uses: CorvidLabs/trust@9d32b5786d2e9e4d39fc581c0091c721ee3d4226 # v1.0.0 + with: + profile: strict - name: Check managed agent rules run: | 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 index 23394b60..0f8373d6 100644 --- 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 @@ -55,6 +55,13 @@ "timestamp": 1783923481, "digest": "1b71dcb19cf474784ccc9aa4e4bfe4aee685f20941b368bb96fd7bf3d451dc38", "note": "Accepted after addressing final policy and semantic requirement review findings." + }, + { + "gate": "acceptance", + "actor": "0xLeif", + "timestamp": 1783924404, + "digest": "90d9f68e49630a9a86bb3eba03f1a74f7ba4aa199252c650e57a8a712a4d0e8c", + "note": "Accepted after strict Trust workflow and final generated-policy review fixes." } ] } 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 index 400dc58a..c9ff0edc 100644 --- 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 @@ -8,7 +8,7 @@ "state": "accepted", "base_commit": "02550b3fac7e9a5ca12f5aecc1773f89972820f0", "created_at": 1783831307, - "updated_at": 1783923481, + "updated_at": 1783924404, "affected_specs": [], "affected_paths": [ ".github/workflows/", 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 index b7faa3c4..aab847d8 100644 --- 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 @@ -1,9 +1,9 @@ { - "timestamp": 1783923441, - "commit": "ea62bf537dce717056d236b5b4320c809fff073b", + "timestamp": 1783924366, + "commit": "d98db8524b2155e9067ab0d290c948f55574879b", "contract_digest": "e501068a05e6748686f9e67c2abc8740da52e6d7df64770bbb7c6bd6e8d2c391", - "workspace_digest": "e2fdb14e10d9873294786a8af4905fe9a0164d5d5c5b09b7079a785c1ba6214e", - "acceptance_input_digest": "b92e4e37166ec59d49b2735bf5db174233b392b9dc73cbfa73bf0738fa94322d", + "workspace_digest": "586a0fdd8c059e988cd2f589f8c9509a2498f2d0660a9af4a34e490d1ac54dc7", + "acceptance_input_digest": "8e65e4490a9eba841c3822d09fcaab3a043ac8299761837d7a2e312c03f40584", "passed": true, "commands": [ { diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json index 4b7e5b74..08545401 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json @@ -55,6 +55,13 @@ "timestamp": 1783923481, "digest": "d395258a462cf9cba7cf47abe6be4233715895293010ea39c78641c33a2b1957", "note": "Accepted after final generated-template policy and local-gate review fixes." + }, + { + "gate": "acceptance", + "actor": "0xLeif", + "timestamp": 1783924408, + "digest": "b0fd1f2ce8e999ca1cbbfa1f2139a7e6610f32bf974e09922a7108b506066aff", + "note": "Accepted after committed-tree, complete-governance, and alternate-source-layout template validation." } ] } diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json index 3a604ed9..e11b6234 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json @@ -8,7 +8,7 @@ "state": "accepted", "base_commit": "02550b3fac7e9a5ca12f5aecc1773f89972820f0", "created_at": 1783831323, - "updated_at": 1783923481, + "updated_at": 1783924408, "affected_specs": [], "affected_paths": [ "templates/corvid-stack/" diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json index 3f73df45..dbbc24da 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json @@ -1,9 +1,9 @@ { - "timestamp": 1783923470, - "commit": "ea62bf537dce717056d236b5b4320c809fff073b", + "timestamp": 1783924399, + "commit": "d98db8524b2155e9067ab0d290c948f55574879b", "contract_digest": "eba5b5589df084078203786c6f051df9378749313f2ffa761fddcff0e9d49c57", - "workspace_digest": "e2fdb14e10d9873294786a8af4905fe9a0164d5d5c5b09b7079a785c1ba6214e", - "acceptance_input_digest": "bd5c95c4f935bb82c32c69884c0fde4d331b2b022cee31b24c405ca4ad85c267", + "workspace_digest": "586a0fdd8c059e988cd2f589f8c9509a2498f2d0660a9af4a34e490d1ac54dc7", + "acceptance_input_digest": "8be0acc72b4ea005f26618d2ffed33fbd93ed08f5f8683bcfac9e501dc7cccf6", "passed": true, "commands": [ { diff --git a/src/templates.rs b/src/templates.rs index a95223a6..ac7436b7 100644 --- a/src/templates.rs +++ b/src/templates.rs @@ -1045,9 +1045,9 @@ ignore = ["template.toml"] } for required in [ - "git diff --check", + "git diff-tree --check --root -r -m --no-commit-id HEAD", "fledge introspect", - "governance-check", + ".specsync/config.toml .specsync/registry.toml .specsync/version AGENTS.md CLAUDE.md", "workflow-check", "steps = [\"format-check\", \"config-check\", \"governance-check\", \"workflow-check\"]", ] { @@ -1056,6 +1056,17 @@ ignore = ["template.toml"] "corvid-stack bootstrap is missing substantive check: {required}" ); } + + let policy_path = + Path::new(env!("CARGO_MANIFEST_DIR")).join("templates/corvid-stack/.specsync/sdd.json"); + let policy: serde_json::Value = + serde_json::from_str(&fs::read_to_string(policy_path).unwrap()).unwrap(); + assert!( + policy["meaningful_paths"] + .as_array() + .is_some_and(|paths| paths.iter().any(|path| path.as_str() == Some("."))), + "corvid-stack SDD policy must cover root-level and alternate source layouts" + ); } #[test] diff --git a/templates/corvid-stack/.specsync/sdd.json b/templates/corvid-stack/.specsync/sdd.json index 5b994e50..ee71db1c 100644 --- a/templates/corvid-stack/.specsync/sdd.json +++ b/templates/corvid-stack/.specsync/sdd.json @@ -3,6 +3,7 @@ "enabled": true, "require_change_for_meaningful_files": true, "meaningful_paths": [ + ".", "src/", "tests/", "specs/", diff --git a/templates/corvid-stack/fledge.toml b/templates/corvid-stack/fledge.toml index c30d0d3a..7de35113 100644 --- a/templates/corvid-stack/fledge.toml +++ b/templates/corvid-stack/fledge.toml @@ -4,9 +4,9 @@ # These deterministic starter checks work before application source exists. # Replace or extend them with stack-native checks when application code is added. [tasks] -format-check = "git diff --check" +format-check = "git diff-tree --check --root -r -m --no-commit-id HEAD" config-check = "fledge introspect" -governance-check = "git ls-files --error-unmatch .trust.toml .augur.toml .attest.json .specsync/sdd.json" +governance-check = "git ls-files --error-unmatch .trust.toml .augur.toml .attest.json .specsync/sdd.json .specsync/config.toml .specsync/registry.toml .specsync/version AGENTS.md CLAUDE.md" workflow-check = "git ls-files --error-unmatch .github/workflows/trust.yml && git grep -q -F \"CorvidLabs/trust@9d32b5786d2e9e4d39fc581c0091c721ee3d4226\" -- .github/workflows/trust.yml" # The single quality gate. `.github/workflows/trust.yml` runs `fledge lanes run verify`. From abd4240b1699cf1f2fb79417641f0a82054b5972 Mon Sep 17 00:00:00 2001 From: 0xLeif Date: Mon, 13 Jul 2026 00:41:26 -0600 Subject: [PATCH 24/25] fix(governance): honor progressive provenance in Trust gate --- .github/workflows/trust.yml | 2 -- .../CHG-0001-adopt-trust-1-and-specsync-5/approvals.json | 7 +++++++ .../CHG-0001-adopt-trust-1-and-specsync-5/state.json | 2 +- .../verification.json | 8 ++++---- .../approvals.json | 7 +++++++ .../state.json | 2 +- .../verification.json | 6 +++--- 7 files changed, 23 insertions(+), 11 deletions(-) diff --git a/.github/workflows/trust.yml b/.github/workflows/trust.yml index e21e3c4f..1843df36 100644 --- a/.github/workflows/trust.yml +++ b/.github/workflows/trust.yml @@ -22,8 +22,6 @@ jobs: - name: CorvidLabs Trust gate id: trust uses: CorvidLabs/trust@9d32b5786d2e9e4d39fc581c0091c721ee3d4226 # v1.0.0 - with: - profile: strict - name: Check managed agent rules run: | 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 index 0f8373d6..5ddceb9d 100644 --- 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 @@ -62,6 +62,13 @@ "timestamp": 1783924404, "digest": "90d9f68e49630a9a86bb3eba03f1a74f7ba4aa199252c650e57a8a712a4d0e8c", "note": "Accepted after strict Trust workflow and final generated-policy review fixes." + }, + { + "gate": "acceptance", + "actor": "0xLeif", + "timestamp": 1783924837, + "digest": "b672b2c889ec39d1cbf4f4dfe1afee382fe5a2ff47c29df81c43e111be5d5ec0", + "note": null } ] } 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 index c9ff0edc..9701f788 100644 --- 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 @@ -8,7 +8,7 @@ "state": "accepted", "base_commit": "02550b3fac7e9a5ca12f5aecc1773f89972820f0", "created_at": 1783831307, - "updated_at": 1783924404, + "updated_at": 1783924837, "affected_specs": [], "affected_paths": [ ".github/workflows/", 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 index aab847d8..d3a0d00c 100644 --- 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 @@ -1,9 +1,9 @@ { - "timestamp": 1783924366, - "commit": "d98db8524b2155e9067ab0d290c948f55574879b", + "timestamp": 1783924836, + "commit": "7c47bb9d0b0d401a24e4727ecfde0b36fbc75804", "contract_digest": "e501068a05e6748686f9e67c2abc8740da52e6d7df64770bbb7c6bd6e8d2c391", - "workspace_digest": "586a0fdd8c059e988cd2f589f8c9509a2498f2d0660a9af4a34e490d1ac54dc7", - "acceptance_input_digest": "8e65e4490a9eba841c3822d09fcaab3a043ac8299761837d7a2e312c03f40584", + "workspace_digest": "2832ddd9840bf9de26fdb3ae657d35d5e7b41b4b06c433ca5d948a80efc22d58", + "acceptance_input_digest": "634bb0de9433ab98f992808b17f615fa70450905883929d9844fdb2c8806db82", "passed": true, "commands": [ { diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json index 08545401..8ee2cc48 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json @@ -62,6 +62,13 @@ "timestamp": 1783924408, "digest": "b0fd1f2ce8e999ca1cbbfa1f2139a7e6610f32bf974e09922a7108b506066aff", "note": "Accepted after committed-tree, complete-governance, and alternate-source-layout template validation." + }, + { + "gate": "acceptance", + "actor": "0xLeif", + "timestamp": 1783924858, + "digest": "170d5e1b7deb38150927144f92f7705d632a769b104e688e2562da1b19138f96", + "note": null } ] } diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json index e11b6234..ef1c510e 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json @@ -8,7 +8,7 @@ "state": "accepted", "base_commit": "02550b3fac7e9a5ca12f5aecc1773f89972820f0", "created_at": 1783831323, - "updated_at": 1783924408, + "updated_at": 1783924858, "affected_specs": [], "affected_paths": [ "templates/corvid-stack/" diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json index dbbc24da..c37c24ba 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json @@ -1,8 +1,8 @@ { - "timestamp": 1783924399, - "commit": "d98db8524b2155e9067ab0d290c948f55574879b", + "timestamp": 1783924858, + "commit": "7c47bb9d0b0d401a24e4727ecfde0b36fbc75804", "contract_digest": "eba5b5589df084078203786c6f051df9378749313f2ffa761fddcff0e9d49c57", - "workspace_digest": "586a0fdd8c059e988cd2f589f8c9509a2498f2d0660a9af4a34e490d1ac54dc7", + "workspace_digest": "2832ddd9840bf9de26fdb3ae657d35d5e7b41b4b06c433ca5d948a80efc22d58", "acceptance_input_digest": "8be0acc72b4ea005f26618d2ffed33fbd93ed08f5f8683bcfac9e501dc7cccf6", "passed": true, "commands": [ From 9e8bcec77ee24bd195573fec0061dc9c94a7c5b1 Mon Sep 17 00:00:00 2001 From: 0xLeif Date: Mon, 13 Jul 2026 00:54:15 -0600 Subject: [PATCH 25/25] fix(governance): enforce complete SDD lifecycle in CI --- .github/workflows/ci.yml | 4 ++++ .../approvals.json | 7 +++++++ .../state.json | 2 +- .../verification.json | 8 ++++---- .../approvals.json | 7 +++++++ .../state.json | 2 +- .../verification.json | 8 ++++---- .specsync/sdd.json | 1 + src/templates.rs | 13 +++++++++++++ templates/corvid-stack/.github/workflows/trust.yml | 5 +++++ 10 files changed, 47 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 550feba0..ec99ad3d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -130,9 +130,13 @@ jobs: # claimed by a spec (test-only + template CI files are excluded in # .specsync/config.toml). Fails CI if an unclaimed file is added (#448). require-coverage: 100 + lifecycle-enforce: true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Enforce SpecSync change workspaces + run: specsync change check --strict --require-coverage 100 + corvid-pet: runs-on: ubuntu-latest timeout-minutes: 10 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 index 5ddceb9d..8be20908 100644 --- 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 @@ -69,6 +69,13 @@ "timestamp": 1783924837, "digest": "b672b2c889ec39d1cbf4f4dfe1afee382fe5a2ff47c29df81c43e111be5d5ec0", "note": null + }, + { + "gate": "acceptance", + "actor": "0xLeif", + "timestamp": 1783925618, + "digest": "9abb81e538873dfec876e7f5ee2c41b3af11ef3215db9fb94501209640a0bde9", + "note": null } ] } 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 index 9701f788..512a66aa 100644 --- 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 @@ -8,7 +8,7 @@ "state": "accepted", "base_commit": "02550b3fac7e9a5ca12f5aecc1773f89972820f0", "created_at": 1783831307, - "updated_at": 1783924837, + "updated_at": 1783925618, "affected_specs": [], "affected_paths": [ ".github/workflows/", 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 index d3a0d00c..28c27dba 100644 --- 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 @@ -1,9 +1,9 @@ { - "timestamp": 1783924836, - "commit": "7c47bb9d0b0d401a24e4727ecfde0b36fbc75804", + "timestamp": 1783925618, + "commit": "abd4240b1699cf1f2fb79417641f0a82054b5972", "contract_digest": "e501068a05e6748686f9e67c2abc8740da52e6d7df64770bbb7c6bd6e8d2c391", - "workspace_digest": "2832ddd9840bf9de26fdb3ae657d35d5e7b41b4b06c433ca5d948a80efc22d58", - "acceptance_input_digest": "634bb0de9433ab98f992808b17f615fa70450905883929d9844fdb2c8806db82", + "workspace_digest": "9a889f5a1f62f02e872ecbd4e3d055cff2603e7072ab66024d85816bc2c2bd25", + "acceptance_input_digest": "f562234962df8c999eae83354a041b963c0d89203f8c6bc235a5fa8b6b64cd94", "passed": true, "commands": [ { diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json index 8ee2cc48..82563579 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/approvals.json @@ -69,6 +69,13 @@ "timestamp": 1783924858, "digest": "170d5e1b7deb38150927144f92f7705d632a769b104e688e2562da1b19138f96", "note": null + }, + { + "gate": "acceptance", + "actor": "0xLeif", + "timestamp": 1783925640, + "digest": "f585f05d994b3aca1007087c612db8ae8184227e6199c88f2484ffba2aa60ba9", + "note": null } ] } diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json index ef1c510e..cc586dff 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/state.json @@ -8,7 +8,7 @@ "state": "accepted", "base_commit": "02550b3fac7e9a5ca12f5aecc1773f89972820f0", "created_at": 1783831323, - "updated_at": 1783924858, + "updated_at": 1783925640, "affected_specs": [], "affected_paths": [ "templates/corvid-stack/" diff --git a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json index c37c24ba..10a0a281 100644 --- a/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json +++ b/.specsync/changes/CHG-0002-update-corvid-stack-template-for-trust-1/verification.json @@ -1,9 +1,9 @@ { - "timestamp": 1783924858, - "commit": "7c47bb9d0b0d401a24e4727ecfde0b36fbc75804", + "timestamp": 1783925640, + "commit": "abd4240b1699cf1f2fb79417641f0a82054b5972", "contract_digest": "eba5b5589df084078203786c6f051df9378749313f2ffa761fddcff0e9d49c57", - "workspace_digest": "2832ddd9840bf9de26fdb3ae657d35d5e7b41b4b06c433ca5d948a80efc22d58", - "acceptance_input_digest": "8be0acc72b4ea005f26618d2ffed33fbd93ed08f5f8683bcfac9e501dc7cccf6", + "workspace_digest": "9a889f5a1f62f02e872ecbd4e3d055cff2603e7072ab66024d85816bc2c2bd25", + "acceptance_input_digest": "a1a598a7e9aad2554fe6cf08d11fbd78bba93f84235dc9747695bec2bdc94a80", "passed": true, "commands": [ { diff --git a/.specsync/sdd.json b/.specsync/sdd.json index ef3d1830..7a1a98d2 100644 --- a/.specsync/sdd.json +++ b/.specsync/sdd.json @@ -37,6 +37,7 @@ "templates/", "fledge.toml", "install.sh", + "install.ps1", ".trust.toml", ".augur.toml", ".attest.json", diff --git a/src/templates.rs b/src/templates.rs index ac7436b7..c841777a 100644 --- a/src/templates.rs +++ b/src/templates.rs @@ -1067,6 +1067,19 @@ ignore = ["template.toml"] .is_some_and(|paths| paths.iter().any(|path| path.as_str() == Some("."))), "corvid-stack SDD policy must cover root-level and alternate source layouts" ); + + let trust_workflow_path = Path::new(env!("CARGO_MANIFEST_DIR")) + .join("templates/corvid-stack/.github/workflows/trust.yml"); + let trust_workflow = fs::read_to_string(trust_workflow_path).unwrap(); + for required in [ + "specsync lifecycle enforce --all", + "specsync change check --strict", + ] { + assert!( + trust_workflow.contains(required), + "corvid-stack Trust workflow is missing SDD enforcement: {required}" + ); + } } #[test] diff --git a/templates/corvid-stack/.github/workflows/trust.yml b/templates/corvid-stack/.github/workflows/trust.yml index ea989453..9cd18167 100644 --- a/templates/corvid-stack/.github/workflows/trust.yml +++ b/templates/corvid-stack/.github/workflows/trust.yml @@ -20,6 +20,11 @@ jobs: id: trust uses: CorvidLabs/trust@9d32b5786d2e9e4d39fc581c0091c721ee3d4226 # v1.0.0 + - name: Enforce SpecSync SDD lifecycle + run: | + specsync lifecycle enforce --all + specsync change check --strict + - name: Check managed agent rules run: | grep -q "CorvidLabs trust toolchain: BEGIN" AGENTS.md