diff --git a/.specledger/templates/plan-template.md b/.specledger/templates/plan-template.md index c4b0bc3..67bfd83 100644 --- a/.specledger/templates/plan-template.md +++ b/.specledger/templates/plan-template.md @@ -20,7 +20,7 @@ **Language/Version**: [e.g., Python 3.11, Swift 5.9, Rust 1.75 or NEEDS CLARIFICATION] **Primary Dependencies**: [e.g., FastAPI, UIKit, LLVM or NEEDS CLARIFICATION] **Storage**: [if applicable, e.g., PostgreSQL, CoreData, files or N/A] -**Testing**: Go `go test` (standard) — quickstart.md scenarios become `TestQuickstart_` integration tests (Constitution II); unit tests for non-obvious internal logic +**Testing**: Go `go test` (standard) — quickstart.md scenarios become `TestQuickstart_` integration tests with output-shape assertions (Constitution II); unit tests via `httptest`/go-vcr cassettes; ≥1 real recorded fixture per integration boundary, secret-scrubbed (Constitution III) **Target Platform**: [e.g., Linux server, iOS 15+, WASM or NEEDS CLARIFICATION] **Project Type**: [single/web/mobile - determines source structure] **Performance Goals**: [domain-specific, e.g., 1000 req/s, 10k lines/sec, 60 fps or NEEDS CLARIFICATION] @@ -31,15 +31,17 @@ *GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* -Verify compliance with principles from `.specledger/memory/constitution.md`: +Verify compliance with principles from `.specledger/memory/constitution.md` (v2.1.0, nine principles): - [ ] **I. Specification-First**: Spec.md complete with prioritized user stories before planning -- [ ] **II. Quickstart-as-Contract**: quickstart.md scenarios authored as executable steps, each mapping 1:1 to a Go integration test (`TestQuickstart_`); acceptance lives at the integration layer -- [ ] **III. Agent-First CLI Design**: New/changed commands conform to [docs/design/cli.md](../../docs/design/cli.md) (progressive `--help`, errors-as-navigation, two-level output, standard flags, consume-only, single `skillcore` for integrity primitives) -- [ ] **IV. Code Quality (Go)**: `go test` is the test framework; `gofmt`/`go vet`/lint pass; execution logic independent of output format -- [ ] **V. Simplicity (YAGNI)**: No premature abstraction; dependencies/indirection justified by a concrete requirement - -**Complexity Violations** (if any, justify in Complexity Tracking table below): +- [ ] **II. Quickstart-as-Contract**: quickstart.md scenarios authored as executable steps, each mapping 1:1 to a Go integration test (`TestQuickstart_`); acceptance lives at the integration layer. **Output-shape assertions planned** — line-bound for compact human output, parse + structurally-complete for `--json`, 3-part (what/why/fix) + exit-code for errors (never content-only `strings.Contains`) +- [ ] **III. Ground-Truth Anchoring**: data-model.md cites ≥1 *real recorded* sample per integration boundary (git `ls-tree`/tree-SHA, `mise` resolve, GitHub `bump --pr` response, generated `index.json`), secret-scrubbed; unit tests via `httptest`/go-vcr cassettes, E2E via the real binary +- [ ] **IV. Agent-First CLI Design**: New/changed commands conform to [docs/design/cli.md](../../docs/design/cli.md) (progressive `--help`, errors-as-navigation, two-level output, standard flags, consume-only, single `skillcore` for integrity primitives) and are classified against a cli.md command pattern via the [pattern-gate checklist](../../docs/design/checklist-template.md) +- [ ] **V. Code Quality (Go)**: `go test` is the test framework; `gofmt`/`go vet`/lint pass; execution logic independent of output format +- [ ] **VI–VIII. Simplicity (YAGNI / Shortest Path to MVP / Simplicity Over Cleverness)**: no premature abstraction; minimum viable implementation; boring obvious Go over clever code; dependencies/indirection justified by a concrete requirement +- [ ] **IX. Skill–CLI Co-Evolution**: new/changed commands have a planned skill update (keywords matching real user phrasing + failure modes) and a trigger-eval task using `.claude/skills/skill-creator/` (`scripts/run_eval.py`) + +**Complexity Violations** (if any, justify against Principles VI–VIII in the Complexity Tracking table below): - None identified / [List violations and justifications] ## Project Structure @@ -58,49 +60,35 @@ specledger/[###-feature]/ ### Source Code (repository root) ```text -# [REMOVE IF UNUSED] Option 1: Single project (DEFAULT) -src/ -├── models/ -├── services/ -├── cli/ -└── lib/ - -tests/ -├── contract/ -├── integration/ -└── unit/ - -# [REMOVE IF UNUSED] Option 2: Web application (when "frontend" + "backend" detected) -backend/ -├── src/ -│ ├── models/ -│ ├── services/ -│ └── api/ -└── tests/ - -frontend/ -├── src/ -│ ├── components/ -│ ├── pages/ -│ └── services/ -└── tests/ - -# [REMOVE IF UNUSED] Option 3: Mobile + API (when "iOS/Android" detected) -api/ -└── [same as backend above] - -ios/ or android/ -└── [platform-specific structure: feature modules, UI flows, platform tests] +cmd/ +└── skillrig/ # main package — Cobra root + subcommand wiring + +internal/ +├── skillcore/ # THE single source of tree-SHA + manifest logic +│ # (verify, bump, doctor all dispatch here — cli.md AP-04) +├── config/ # origin resolution: env > project > global (one resolver — AP-06) +├── lock/ # skills-lock.json read/write +├── index/ # index.json walk + compare (bump) +├── client/ # client registry: client → path(s) → link-or-copy (multi-client) +└── / # this feature's package(s) + +testdata/ # real recorded fixtures per boundary, secret-scrubbed (Constitution III) +│ # e.g. git ls-tree output, mise resolve, GitHub bump-PR response +└── cassettes/ # go-vcr cassettes for the GitHub path (unit tier) + +# Tests live beside the code as Go convention dictates (pkg/foo_test.go). +# Quickstart-as-Contract integration/E2E tests: TestQuickstart_ invoking the real binary. ``` -**Structure Decision**: [Document the selected structure and reference the real +**Structure Decision**: [Document the selected packages and reference the real directories captured above] ## Complexity Tracking diff --git a/.specledger/templates/spec-template.md b/.specledger/templates/spec-template.md index 7d2c3d6..b25e837 100644 --- a/.specledger/templates/spec-template.md +++ b/.specledger/templates/spec-template.md @@ -18,6 +18,13 @@ - Tested independently - Deployed independently - Demonstrated to users independently + + OUTPUT-SHAPE GUIDANCE (Constitution II): when an acceptance scenario involves + command output, state the OBSERVABLE SHAPE, not just content — so it can become + a shape-asserting test rather than a `strings.Contains` check. Examples: + - "Then the compact listing is ≤ N+5 lines, one per skill, ending with a footer hint" + - "Then `--json` parses and each entry contains version/commit/treeSha/requires" + - "Then on failure stderr names what-failed + why + a suggested fix, and exit code is 2" --> ### User Story 1 - [Brief Title] (Priority: P1) diff --git a/.specledger/templates/tasks-template.md b/.specledger/templates/tasks-template.md index ba07f41..b174ef7 100644 --- a/.specledger/templates/tasks-template.md +++ b/.specledger/templates/tasks-template.md @@ -139,6 +139,7 @@ Examples of foundational tasks (adjust based on your project): - [ ] T007 Create base models/entities that all stories depend on - [ ] T008 Configure error handling and logging infrastructure - [ ] T009 Setup environment configuration management +- [ ] T009a [P] Record + secret-scrub ≥1 real fixture per integration boundary into `testdata/` (git `ls-tree`/tree-SHA, `mise` resolve, GitHub `bump --pr` response, generated `index.json`); add go-vcr cassettes for the GitHub path (Constitution III — Ground-Truth Anchoring) **Checkpoint**: Foundation ready - user story implementation can now begin in parallel @@ -152,19 +153,19 @@ Examples of foundational tasks (adjust based on your project): ### Tests for User Story 1 (REQUIRED — Quickstart-as-Contract, Constitution II) ⚠️ -**NOTE: Write these tests FIRST, ensure they FAIL before implementation. Each quickstart.md scenario for this story MUST map 1:1 to a Go integration test.** +**NOTE: Write these tests FIRST, ensure they FAIL before implementation. Each quickstart.md scenario for this story MUST map 1:1 to a Go integration test. For output-producing commands, tests MUST assert output SHAPE (Constitution II), not just content: line-bound for compact output, parse + structural-completeness for `--json`, 3-part + exit-code for errors.** -- [ ] T010 [P] [US1] Integration test `TestQuickstart_[scenario]` (from quickstart.md) in [pkg]/[name]_test.go +- [ ] T010 [P] [US1] Integration test `TestQuickstart_[scenario]` (from quickstart.md) with output-shape assertions in [pkg]/[name]_test.go - [ ] T011 [P] [US1] Unit test for non-obvious internal logic (only where genuinely useful) in [pkg]/[name]_test.go ### Implementation for User Story 1 -- [ ] T012 [P] [US1] Create [Entity1] model in src/models/[entity1].py -- [ ] T013 [P] [US1] Create [Entity2] model in src/models/[entity2].py -- [ ] T014 [US1] Implement [Service] in src/services/[service].py (depends on T012, T013) -- [ ] T015 [US1] Implement [endpoint/feature] in src/[location]/[file].py -- [ ] T016 [US1] Add validation and error handling -- [ ] T017 [US1] Add logging for user story 1 operations +- [ ] T012 [P] [US1] Create [Entity1] type in internal/[pkg]/[entity1].go +- [ ] T013 [P] [US1] Create [Entity2] type in internal/[pkg]/[entity2].go +- [ ] T014 [US1] Implement [logic] in internal/[pkg]/[file].go (depends on T012, T013) +- [ ] T015 [US1] Wire [command/subcommand] in cmd/skillrig/[command].go +- [ ] T016 [US1] Add validation and errors-as-navigation handling (what/why/fix + exit code) +- [ ] T017 [US1] Ensure execution logic is output-format-independent (presentation vs execution) **Checkpoint**: At this point, User Story 1 should be fully functional and testable independently @@ -176,16 +177,16 @@ Examples of foundational tasks (adjust based on your project): **Independent Test**: [How to verify this story works on its own] -### Tests for User Story 2 (REQUIRED — Quickstart-as-Contract, Constitution II) ⚠️ +### Tests for User Story 2 (REQUIRED — Quickstart-as-Contract + output-shape assertions, Constitution II) ⚠️ -- [ ] T018 [P] [US2] Integration test `TestQuickstart_[scenario]` (from quickstart.md) in [pkg]/[name]_test.go +- [ ] T018 [P] [US2] Integration test `TestQuickstart_[scenario]` (from quickstart.md) with output-shape assertions in [pkg]/[name]_test.go - [ ] T019 [P] [US2] Unit test for non-obvious internal logic (only where genuinely useful) in [pkg]/[name]_test.go ### Implementation for User Story 2 -- [ ] T020 [P] [US2] Create [Entity] model in src/models/[entity].py -- [ ] T021 [US2] Implement [Service] in src/services/[service].py -- [ ] T022 [US2] Implement [endpoint/feature] in src/[location]/[file].py +- [ ] T020 [P] [US2] Create [Entity] type in internal/[pkg]/[entity].go +- [ ] T021 [US2] Implement [logic] in internal/[pkg]/[file].go +- [ ] T022 [US2] Wire [command/subcommand] in cmd/skillrig/[command].go - [ ] T023 [US2] Integrate with User Story 1 components (if needed) **Checkpoint**: At this point, User Stories 1 AND 2 should both work independently @@ -198,16 +199,16 @@ Examples of foundational tasks (adjust based on your project): **Independent Test**: [How to verify this story works on its own] -### Tests for User Story 3 (REQUIRED — Quickstart-as-Contract, Constitution II) ⚠️ +### Tests for User Story 3 (REQUIRED — Quickstart-as-Contract + output-shape assertions, Constitution II) ⚠️ -- [ ] T024 [P] [US3] Integration test `TestQuickstart_[scenario]` (from quickstart.md) in [pkg]/[name]_test.go +- [ ] T024 [P] [US3] Integration test `TestQuickstart_[scenario]` (from quickstart.md) with output-shape assertions in [pkg]/[name]_test.go - [ ] T025 [P] [US3] Unit test for non-obvious internal logic (only where genuinely useful) in [pkg]/[name]_test.go ### Implementation for User Story 3 -- [ ] T026 [P] [US3] Create [Entity] model in src/models/[entity].py -- [ ] T027 [US3] Implement [Service] in src/services/[service].py -- [ ] T028 [US3] Implement [endpoint/feature] in src/[location]/[file].py +- [ ] T026 [P] [US3] Create [Entity] type in internal/[pkg]/[entity].go +- [ ] T027 [US3] Implement [logic] in internal/[pkg]/[file].go +- [ ] T028 [US3] Wire [command/subcommand] in cmd/skillrig/[command].go **Checkpoint**: All user stories should now be independently functional @@ -221,12 +222,13 @@ Examples of foundational tasks (adjust based on your project): **Purpose**: Improvements that affect multiple user stories -- [ ] TXXX [P] Documentation updates in docs/ +- [ ] TXXX [P] Documentation updates in docs/ — sync docs/design/ for any CLI pattern/flag/integrity change (Constitution: Architecture & CLI Design) +- [ ] TXXX Pattern-compliance: classify each new/changed command against a cli.md pattern and complete the [pattern-gate checklist](../../docs/design/checklist-template.md) (Constitution IV) +- [ ] TXXX [P] Skill–CLI Co-Evolution: update the command's skill (keywords matching real user phrasing + failure modes) and run trigger evals via `.claude/skills/skill-creator/scripts/run_eval.py`; verify no undertriggering (Constitution IX) - [ ] TXXX Code cleanup and refactoring -- [ ] TXXX Performance optimization across all stories - [ ] TXXX [P] Additional unit tests for non-obvious internal logic - [ ] TXXX Security hardening -- [ ] TXXX Confirm full quickstart.md suite passes (`go test ./...` — all `TestQuickstart_*` green) +- [ ] TXXX Confirm full quickstart.md suite passes (`go test ./...` — all `TestQuickstart_*` green, including output-shape assertions) --- @@ -250,8 +252,13 @@ Examples of foundational tasks (adjust based on your project): ### Within Each User Story - Quickstart-derived integration tests MUST be written and FAIL before implementation (Constitution II) -- Models before services -- Services before endpoints +- Types/models before logic +- Logic before command wiring - Core implementation before integration -- **Definition of Done**: a story is DONE only when its `quickstart.md` scenarios match the user stories AND the corresponding `TestQuickstart_*` integration tests pass +- **Definition of Done**: a story is DONE only when ALL hold — + 1. its `quickstart.md` scenarios match the user stories AND the corresponding `TestQuickstart_*` integration tests pass; + 2. output-producing tests carry shape assertions, not content-only checks (Constitution II); + 3. ≥1 real recorded fixture exists for each integration boundary the story touches (Constitution III); + 4. each new/changed command is pattern-classified via the pattern-gate checklist (Constitution IV); + 5. the command's skill is updated and trigger-eval-verified (Constitution IX) - Story complete before moving to next priority