From 373da6ddc1f58bfc1a057b31f5abcd5c97bac427 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Darko=20Mijic=CC=81?= Date: Thu, 2 Apr 2026 06:37:27 +0200 Subject: [PATCH 1/3] =?UTF-8?q?chore(specs):=20retire=2045=20completed=20d?= =?UTF-8?q?esign=20specs=20=E2=80=94=20value=20transferred=20to=20executab?= =?UTF-8?q?le=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Consolidate completed planning/design specs into their executable test counterparts. For each retired spec, the primary test file inherits the canonical @architect-pattern name, @architect-phase, and @architect-depends-on tags. Design-level metadata (effort, priority, release, business-value, deliverables table) is dropped — these are historical planning artifacts with no ongoing value for completed patterns. Migration mechanics (per spec): - Primary test file promoted to canonical pattern name - Sibling test files linked via @architect-implements - Feature description narrative transferred where missing - Spec file deleted from architect/specs/ - Stubs deleted from architect/stubs/ Results: - 45 specs retired (69 → 24 remaining: roadmap + active only) - 51 test files modified (received canonical names + metadata) - ~24 stub files deleted across ~10 directories - 8,808 tests passing, zero failures - Pattern graph integrity preserved (canonical names, deps, phases intact) - 45 sequential Opus 4.6 agent deployments, ~35-60s each Remaining in architect/specs/: 24 roadmap/active specs awaiting implementation. Remaining in architect/stubs/: 1 directory (mcp-server-integration, active pattern). architect/decisions/: 6 ADRs untouched (permanent records). This validates the ephemeral design spec principle: design specs guide implementation, then their value transfers to executable specs. The executable spec IS the living documentation — it runs in CI and can never go stale. --- .../architecture-diagram-advanced.feature | 171 ----- .../specs/architecture-diagram-core.feature | 318 ---------- .../architecture-doc-refactoring.feature | 442 ------------- .../specs/claude-module-generation.feature | 444 ------------- architect/specs/cli-recipe-codec.feature | 265 -------- .../specs/cli-reference-generation.feature | 158 ----- .../codec-driven-reference-generation.feature | 159 ----- .../config-based-workflow-definition.feature | 171 ----- .../cross-cutting-document-inclusion.feature | 358 ----------- .../data-api-architecture-queries.feature | 190 ------ .../specs/data-api-cli-ergonomics.feature | 145 ----- .../specs/data-api-context-assembly.feature | 281 -------- .../specs/data-api-output-shaping.feature | 299 --------- .../data-api-platform-integration.feature | 216 ------- .../specs/data-api-session-support.feature | 139 ---- .../specs/data-api-stub-integration.feature | 206 ------ .../declaration-level-shape-tagging.feature | 391 ------------ .../specs/docs-consolidation-strategy.feature | 186 ------ .../specs/docs-live-consolidation.feature | 95 --- .../specs/enhanced-index-generation.feature | 235 ------- architect/specs/error-guide-codec.feature | 224 ------- architect/specs/generated-doc-quality.feature | 124 ---- .../gherkin-patterns-restructure.feature | 129 ---- architect/specs/gherkin-rules-support.feature | 128 ---- .../specs/mvp-workflow-implementation.feature | 85 --- ...strator-pipeline-factory-migration.feature | 313 --------- architect/specs/pattern-graph-api-cli.feature | 293 --------- ...ern-graph-api-relationship-queries.feature | 191 ------ .../pattern-graph-layered-extraction.feature | 324 ---------- .../specs/pattern-relationship-model.feature | 356 ----------- architect/specs/phase-state-machine.feature | 101 --- .../specs/procedural-guide-codec.feature | 307 --------- architect/specs/process-guard-linter.feature | 332 ---------- architect/specs/publishing-relocation.feature | 155 ----- .../specs/readme-rationalization.feature | 159 ----- .../specs/reference-doc-showcase.feature | 390 ------------ .../specs/scoped-architectural-view.feature | 144 ----- .../session-guides-module-source.feature | 353 ----------- architect/specs/shape-extraction.feature | 600 ------------------ .../specs/step-lint-extended-rules.feature | 149 ----- .../specs/step-lint-vitest-cucumber.feature | 260 -------- ...typescript-taxonomy-implementation.feature | 164 ----- ...universal-doc-generator-robustness.feature | 247 ------- ...validator-read-model-consolidation.feature | 203 ------ .../handoff-generator.ts | 171 ----- .../scope-validator.ts | 284 --------- .../cli-recipe-codec/cli-recipe-generator.ts | 310 --------- .../stubs/cli-recipe-codec/recipe-data.ts | 270 -------- .../stubs/cli-recipe-codec/recipe-schema.ts | 219 ------- .../default-workflow-config.ts | 65 -- .../arch-queries.ts | 318 ---------- .../coverage-analyzer.ts | 151 ----- .../context-assembler.ts | 383 ----------- .../context-formatter.ts | 159 ----- .../data-api-output-shaping/fuzzy-match.ts | 98 --- .../output-pipeline.ts | 190 ------ .../data-api-output-shaping/summarize.ts | 80 --- .../stub-resolver.ts | 150 ----- .../index-codec-options.ts | 175 ----- .../enhanced-index-generation/index-codec.ts | 210 ------ .../index-preamble-config.ts | 403 ------------ .../convention-annotation-example.ts | 153 ----- .../enhanced-validation-options.ts | 155 ----- .../error-guide-codec/error-guide-config.ts | 222 ------- .../annotation-guide-preamble.ts | 126 ---- .../procedural-guide-codec/load-preamble.ts | 133 ---- .../procedural-codec-options.ts | 135 ---- .../procedural-codec.ts | 209 ------ .../session-guide-preamble.ts | 146 ----- src/cli/cli-schema.ts | 1 - .../built-in/cli-recipe-generator.ts | 1 - .../architecture-queries/arch-queries.feature | 23 +- .../context-assembler.feature | 26 +- .../context-formatter.feature | 1 + .../api/output-shaping/fuzzy-match.feature | 1 + .../output-shaping/output-pipeline.feature | 6 +- .../output-shaping/pattern-helpers.feature | 1 + .../api/output-shaping/summarize.feature | 1 + tests/features/api/pattern-graph-api.feature | 3 +- .../session-support/handoff-generator.feature | 1 + .../session-support/scope-validator.feature | 14 +- .../stub-integration/stub-resolver.feature | 6 +- .../stub-integration/taxonomy-tags.feature | 1 + .../architecture-diagrams/arch-index.feature | 2 +- .../arch-tag-extraction.feature | 2 +- .../component-diagram.feature | 21 +- .../generator-registration.feature | 2 +- .../layered-diagram.feature | 15 +- .../behavior/cli/cli-reference.feature | 20 +- .../behavior/codecs/composite-codec.feature | 12 +- .../codecs/generated-doc-quality.feature | 24 +- .../codecs/reference-codec-core.feature | 18 +- .../reference-codec-diagram-types.feature | 16 +- .../codecs/reference-generators.feature | 16 +- .../implements-tag.feature | 17 +- tests/features/cli/data-api-help.feature | 26 +- .../cli/pattern-graph-cli-core.feature | 17 +- tests/features/cli/validate-patterns.feature | 21 +- tests/features/config/config-loader.feature | 24 +- .../architecture-doc-refactoring.feature | 21 +- .../doc-generation/index-codec.feature | 22 +- .../doc-generation/poc-integration.feature | 12 +- .../robustness-integration.feature | 10 +- .../validation-rules-codec.feature | 17 +- .../declaration-level-shape-tagging.feature | 27 +- .../extractor/dual-source-extraction.feature | 9 +- .../shape-extraction-rendering.feature | 2 +- .../extractor/shape-extraction-types.feature | 4 +- .../generators/business-rules-codec.feature | 1 + .../features/generators/orchestrator.feature | 20 +- .../features/lint/step-lint-extended.feature | 25 +- tests/features/lint/step-lint.feature | 24 +- tests/features/poc/rule-keyword-poc.feature | 1 + tests/features/scanner/gherkin-parser.feature | 12 +- .../features/types/deliverable-status.feature | 1 + .../features/types/normalized-status.feature | 1 + .../types/tag-registry-builder.feature | 10 +- .../features/validation/fsm-validator.feature | 4 +- .../features/validation/process-guard.feature | 5 +- .../status-transition-detection.feature | 17 +- .../workflow-config-schemas.feature | 1 + .../poc-decision-document.feature | 5 +- .../doc-generation/poc-integration.steps.ts | 2 +- 123 files changed, 497 insertions(+), 15610 deletions(-) delete mode 100644 architect/specs/architecture-diagram-advanced.feature delete mode 100644 architect/specs/architecture-diagram-core.feature delete mode 100644 architect/specs/architecture-doc-refactoring.feature delete mode 100644 architect/specs/claude-module-generation.feature delete mode 100644 architect/specs/cli-recipe-codec.feature delete mode 100644 architect/specs/cli-reference-generation.feature delete mode 100644 architect/specs/codec-driven-reference-generation.feature delete mode 100644 architect/specs/config-based-workflow-definition.feature delete mode 100644 architect/specs/cross-cutting-document-inclusion.feature delete mode 100644 architect/specs/data-api-architecture-queries.feature delete mode 100644 architect/specs/data-api-cli-ergonomics.feature delete mode 100644 architect/specs/data-api-context-assembly.feature delete mode 100644 architect/specs/data-api-output-shaping.feature delete mode 100644 architect/specs/data-api-platform-integration.feature delete mode 100644 architect/specs/data-api-session-support.feature delete mode 100644 architect/specs/data-api-stub-integration.feature delete mode 100644 architect/specs/declaration-level-shape-tagging.feature delete mode 100644 architect/specs/docs-consolidation-strategy.feature delete mode 100644 architect/specs/docs-live-consolidation.feature delete mode 100644 architect/specs/enhanced-index-generation.feature delete mode 100644 architect/specs/error-guide-codec.feature delete mode 100644 architect/specs/generated-doc-quality.feature delete mode 100644 architect/specs/gherkin-patterns-restructure.feature delete mode 100644 architect/specs/gherkin-rules-support.feature delete mode 100644 architect/specs/mvp-workflow-implementation.feature delete mode 100644 architect/specs/orchestrator-pipeline-factory-migration.feature delete mode 100644 architect/specs/pattern-graph-api-cli.feature delete mode 100644 architect/specs/pattern-graph-api-relationship-queries.feature delete mode 100644 architect/specs/pattern-graph-layered-extraction.feature delete mode 100644 architect/specs/pattern-relationship-model.feature delete mode 100644 architect/specs/phase-state-machine.feature delete mode 100644 architect/specs/procedural-guide-codec.feature delete mode 100644 architect/specs/process-guard-linter.feature delete mode 100644 architect/specs/publishing-relocation.feature delete mode 100644 architect/specs/readme-rationalization.feature delete mode 100644 architect/specs/reference-doc-showcase.feature delete mode 100644 architect/specs/scoped-architectural-view.feature delete mode 100644 architect/specs/session-guides-module-source.feature delete mode 100644 architect/specs/shape-extraction.feature delete mode 100644 architect/specs/step-lint-extended-rules.feature delete mode 100644 architect/specs/step-lint-vitest-cucumber.feature delete mode 100644 architect/specs/typescript-taxonomy-implementation.feature delete mode 100644 architect/specs/universal-doc-generator-robustness.feature delete mode 100644 architect/specs/validator-read-model-consolidation.feature delete mode 100644 architect/stubs/DataAPIDesignSessionSupport/handoff-generator.ts delete mode 100644 architect/stubs/DataAPIDesignSessionSupport/scope-validator.ts delete mode 100644 architect/stubs/cli-recipe-codec/cli-recipe-generator.ts delete mode 100644 architect/stubs/cli-recipe-codec/recipe-data.ts delete mode 100644 architect/stubs/cli-recipe-codec/recipe-schema.ts delete mode 100644 architect/stubs/config-based-workflow-definition/default-workflow-config.ts delete mode 100644 architect/stubs/data-api-architecture-queries/arch-queries.ts delete mode 100644 architect/stubs/data-api-architecture-queries/coverage-analyzer.ts delete mode 100644 architect/stubs/data-api-context-assembly/context-assembler.ts delete mode 100644 architect/stubs/data-api-context-assembly/context-formatter.ts delete mode 100644 architect/stubs/data-api-output-shaping/fuzzy-match.ts delete mode 100644 architect/stubs/data-api-output-shaping/output-pipeline.ts delete mode 100644 architect/stubs/data-api-output-shaping/summarize.ts delete mode 100644 architect/stubs/data-api-stub-integration/stub-resolver.ts delete mode 100644 architect/stubs/enhanced-index-generation/index-codec-options.ts delete mode 100644 architect/stubs/enhanced-index-generation/index-codec.ts delete mode 100644 architect/stubs/enhanced-index-generation/index-preamble-config.ts delete mode 100644 architect/stubs/error-guide-codec/convention-annotation-example.ts delete mode 100644 architect/stubs/error-guide-codec/enhanced-validation-options.ts delete mode 100644 architect/stubs/error-guide-codec/error-guide-config.ts delete mode 100644 architect/stubs/procedural-guide-codec/annotation-guide-preamble.ts delete mode 100644 architect/stubs/procedural-guide-codec/load-preamble.ts delete mode 100644 architect/stubs/procedural-guide-codec/procedural-codec-options.ts delete mode 100644 architect/stubs/procedural-guide-codec/procedural-codec.ts delete mode 100644 architect/stubs/procedural-guide-codec/session-guide-preamble.ts rename architect/specs/doc-generation-proof-of-concept.feature => tests/fixtures/doc-generation/poc-decision-document.feature (99%) diff --git a/architect/specs/architecture-diagram-advanced.feature b/architect/specs/architecture-diagram-advanced.feature deleted file mode 100644 index 9cdd5560..00000000 --- a/architect/specs/architecture-diagram-advanced.feature +++ /dev/null @@ -1,171 +0,0 @@ -@architect -@architect-pattern:ArchitectureDiagramAdvanced -@architect-status:completed -@architect-unlock-reason:Retroactive-completion -@architect-phase:23 -@architect-effort:1w -@architect-product-area:Generation -@architect-executable-specs:tests/features/behavior/architecture-diagrams -Feature: Architecture Diagram Generation - Advanced - - **Problem:** Core diagram generation (see ArchitectureDiagramCore) produces - component-level diagrams from `arch-*` tags. However, large codebases need - additional visualization modes: layered views grouping patterns by architectural - layer, CLI-integrated generation via the generator registry, and sequence - diagrams showing runtime interaction flows between components. - - **Solution:** Extend the architecture diagram system with advanced capabilities: - - Layered diagrams that group patterns by `@architect-arch-layer` (domain, application, infrastructure) - - Generator registry integration for CLI-driven generation via `pnpm docs:architecture` - - Sequence diagram support for modeling runtime interactions between components - - **Why It Matters:** - | Benefit | How | - | Layer visibility | Layered diagrams reveal architectural boundaries | - | CLI integration | Generator registry enables `pnpm docs:architecture` | - | Runtime modeling | Sequence diagrams show interaction flows | - | Composable views | Multiple diagram types from the same annotations | - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | Tests | Test Type | - | ArchitectureCodec (layered) | complete | renderable/codecs/architecture.ts | Yes | unit | - | Architecture generator | complete | generators/built-in/codec-generators.ts | Yes | unit | - | Example app annotations | n/a | examples/sample-project/src/ | No | - | - | Sequence diagram support | superseded | renderable/codecs/architecture.ts | Yes | unit | - - # ============================================================================ - # RULE 5: Layered Diagram Generation - # ============================================================================ - - Rule: Layered diagrams group patterns by architectural layer - - **Invariant:** Layered diagrams must render patterns grouped by architectural - layer (domain, application, infrastructure) with top-to-bottom flow. - - **Rationale:** Layered architecture visualization shows dependency direction - - domain at top, infrastructure at bottom - following conventional layer ordering. - - **Verified by:** Generate subgraphs per layer, Layer order is domain-application-infrastructure, - Include context label in node names - - @acceptance-criteria @happy-path - Scenario: Generate subgraphs per layer - Given patterns with arch-layer: - | Pattern | arch-layer | arch-context | - | Decider | domain | orders | - | Handler | application | orders | - | Infra | infrastructure | - | - When the layered diagram codec runs - Then output contains subgraph "Domain Layer" - And output contains subgraph "Application Layer" - And output contains subgraph "Infrastructure Layer" - - @acceptance-criteria @happy-path - Scenario: Layer order is domain-application-infrastructure - Given patterns with all three layers - When the layered diagram codec runs - Then Domain Layer appears before Application Layer in output - And Application Layer appears before Infrastructure Layer in output - - @acceptance-criteria @happy-path - Scenario: Include context label in node names - Given patterns: - | Pattern | arch-layer | arch-context | - | OrderHandler | application | orders | - | InventoryHandler | application | inventory | - When the layered diagram codec runs - Then OrderHandler node label includes "(orders)" - And InventoryHandler node label includes "(inventory)" - - @acceptance-criteria @validation - Scenario: Patterns without layer go to Other subgraph - Given patterns: - | Pattern | arch-layer | arch-role | - | Layered | application | handler | - | Unlayered | - | saga | - When the layered diagram codec runs - Then output contains subgraph "Other" - And Unlayered is inside Other subgraph - - # ============================================================================ - # RULE 6: Generator Registry Integration - # ============================================================================ - - Rule: Architecture generator is registered with generator registry - - **Invariant:** An "architecture" generator must be registered with the generator - registry to enable `pnpm docs:architecture` via the existing `generate-docs.js` CLI. - - **Rationale:** The Architect uses a generator registry pattern. New - generators register with the orchestrator rather than creating separate CLI commands. - - **Verified by:** Generator is registered, Generator produces component diagram, - Generator produces layered diagram, npm script works - - @acceptance-criteria @happy-path - Scenario: Architecture generator is registered - Given the generator registry - When listing available generators - Then "architecture" should be in the list - - @acceptance-criteria @happy-path - Scenario: Generator produces component diagram by default - When running generate-docs with --generators architecture - Then output contains valid mermaid graph TB - And output contains bounded context subgraphs - - @acceptance-criteria @happy-path - Scenario: Generator option for layered diagram - When running generate-docs with --generators architecture --diagram-type layered - Then output contains layer subgraphs - And output follows domain-application-infrastructure order - - @acceptance-criteria @happy-path - Scenario: Generator option for context filtering - When running generate-docs with --generators architecture --contexts orders - Then output only contains patterns from orders context - And output does not contain inventory context subgraph - - @acceptance-criteria @happy-path - Scenario: npm script pnpm docs:architecture works - When running `pnpm docs:architecture` - Then command exits successfully - And architecture diagram is written to output directory - - # ============================================================================ - # RULE 7: Sequence Diagram Generation (Future) - # ============================================================================ - - Rule: Sequence diagrams render interaction flows - - **Invariant:** Sequence diagrams must render interaction flows (command flow, - saga flow) showing step-by-step message passing between components. - - **Rationale:** Component diagrams show structure but not behavior. Sequence - diagrams show runtime flow - essential for understanding command/saga execution. - - **Verified by:** Generate command flow sequence, Generate saga flow sequence - - @acceptance-criteria @happy-path @future - Scenario: Generate command flow sequence diagram - Given a command handler pattern with uses relationships - When the sequence diagram codec runs with command flow template - Then output contains mermaid sequenceDiagram - And participants are derived from uses relationships - And 7-step CommandOrchestrator flow is rendered - - @acceptance-criteria @happy-path @future - Scenario: Generate saga flow sequence diagram - Given a saga pattern with uses relationships to multiple BCs - When the sequence diagram codec runs with saga flow template - Then output contains mermaid sequenceDiagram - And participants include each bounded context - And compensation steps are shown - - @acceptance-criteria @happy-path @future - Scenario: Participant ordering follows architectural layers - Given patterns spanning multiple layers - When the sequence diagram codec runs - Then participants are ordered by layer - And infrastructure layer appears first diff --git a/architect/specs/architecture-diagram-core.feature b/architect/specs/architecture-diagram-core.feature deleted file mode 100644 index af9392dc..00000000 --- a/architect/specs/architecture-diagram-core.feature +++ /dev/null @@ -1,318 +0,0 @@ -@architect -@architect-pattern:ArchitectureDiagramCore -@architect-status:completed -@architect-unlock-reason:Retroactive-completion -@architect-phase:23 -@architect-effort:1w -@architect-product-area:Generation -@architect-executable-specs:tests/features/behavior/architecture-diagrams -Feature: Architecture Diagram Generation - Core - - **Problem:** Architecture documentation requires manually maintaining mermaid diagrams - that duplicate information already encoded in source code. When code changes, - diagrams become stale. Manual sync is error-prone and time-consuming. - - **Solution:** Generate architecture diagrams automatically from source code annotations - using dedicated `arch-*` tags for precise control. Three tags classify components: - - `@architect-arch-role` - Component type (preset-configurable: service, handler, repository, etc.) - - `@architect-arch-context` - Bounded context for subgraph grouping - - `@architect-arch-layer` - Architectural layer (domain, application, infrastructure) - - **Why It Matters:** - | Benefit | How | - | Always-current diagrams | Generated from source annotations | - | Bounded context isolation | arch-context groups into subgraphs | - | Multiple diagram types | Component diagrams + layered diagrams | - | UML-inspired semantics | Relationship arrows match uses/depends-on/implements/extends | - | CLI integration | `pnpm docs:architecture` via generator registry | - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | Tests | Test Type | - | arch-role tag definition | complete | taxonomy/registry-builder.ts | Yes | unit | - | arch-context tag definition | complete | taxonomy/registry-builder.ts | Yes | unit | - | arch-layer tag definition | complete | taxonomy/registry-builder.ts | Yes | unit | - | DocDirective schema fields | complete | validation-schemas/doc-directive.ts | Yes | unit | - | ExtractedPattern schema fields | complete | validation-schemas/extracted-pattern.ts | Yes | unit | - | AST parser tag extraction | complete | scanner/ast-parser.ts | Yes | unit | - | PatternGraph archIndex | complete | generators/pipeline/transform-dataset.ts | Yes | unit | - | ArchitectureCodec (component) | complete | renderable/codecs/architecture.ts | Yes | unit | - - # ============================================================================ - # RULE 1: Architecture Tags in Registry - # ============================================================================ - - Rule: Architecture tags exist in the tag registry - - **Invariant:** Three architecture-specific tags (`arch-role`, `arch-context`, - `arch-layer`) must exist in the tag registry with correct format and enum values. - - **Rationale:** Architecture diagram generation requires metadata to classify - source files into diagram components. Standard tag infrastructure enables - consistent extraction via the existing AST parser. - - **Note:** The `arch-role` enum values are configurable via presets: - - `libar-generic` preset: generic roles (`service`, `repository`, `handler`, `infrastructure`) - - `ddd-es-cqrs` preset: DDD-specific roles (`command-handler`, `projection`, `saga`, etc.) - - **Verified by:** Tag registry contains arch-role, Tag registry contains arch-context, - Tag registry contains arch-layer, arch-role has enum values, arch-layer has enum values - - @acceptance-criteria @happy-path - Scenario: Tag registry contains arch-role - Given the tag registry is loaded - When querying for tag "arch-role" - Then the tag should exist - And the tag format should be "enum" - And the tag should have values including "service", "repository", "infrastructure" - - @acceptance-criteria @happy-path - Scenario: Tag registry contains arch-context - Given the tag registry is loaded - When querying for tag "arch-context" - Then the tag should exist - And the tag format should be "value" - - @acceptance-criteria @happy-path - Scenario: Tag registry contains arch-layer - Given the tag registry is loaded - When querying for tag "arch-layer" - Then the tag should exist - And the tag format should be "enum" - And the tag should have values "domain", "application", "infrastructure" - - # ============================================================================ - # RULE 2: AST Parser Extraction - # ============================================================================ - - Rule: AST parser extracts architecture tags from TypeScript - - **Invariant:** The AST parser must extract `arch-role`, `arch-context`, and - `arch-layer` tags from TypeScript JSDoc comments into DocDirective objects. - - **Rationale:** Source code annotations are the single source of truth for - architectural metadata. Parser must extract them alongside existing pattern metadata. - - **Verified by:** Extract arch-role from TypeScript, Extract arch-context from TypeScript, - Extract arch-layer from TypeScript, Extract all three together - - @acceptance-criteria @happy-path - Scenario: Extract arch-role from TypeScript annotation - Given TypeScript source with annotation: - """typescript - /** - * @architect - * @architect-pattern MyProjection - * @architect-status completed - * @architect-arch-role projection - */ - """ - When the AST parser extracts metadata - Then the directive should have archRole "projection" - - @acceptance-criteria @happy-path - Scenario: Extract arch-context from TypeScript annotation - Given TypeScript source with annotation: - """typescript - /** - * @architect - * @architect-pattern OrderHandler - * @architect-status completed - * @architect-arch-context orders - */ - """ - When the AST parser extracts metadata - Then the directive should have archContext "orders" - - @acceptance-criteria @happy-path - Scenario: Extract arch-layer from TypeScript annotation - Given TypeScript source with annotation: - """typescript - /** - * @architect - * @architect-pattern MyInfra - * @architect-status completed - * @architect-arch-layer infrastructure - */ - """ - When the AST parser extracts metadata - Then the directive should have archLayer "infrastructure" - - @acceptance-criteria @happy-path - Scenario: Extract multiple arch tags together - Given TypeScript source with annotation: - """typescript - /** - * @architect - * @architect-pattern OrderCommandHandlers - * @architect-status completed - * @architect-arch-role command-handler - * @architect-arch-context orders - * @architect-arch-layer application - */ - """ - When the AST parser extracts metadata - Then the directive should have archRole "command-handler" - And the directive should have archContext "orders" - And the directive should have archLayer "application" - - @acceptance-criteria @validation - Scenario: Missing arch tags yield undefined - Given TypeScript source with annotation: - """typescript - /** - * @architect - * @architect-pattern NoArchTags - * @architect-status completed - */ - """ - When the AST parser extracts metadata - Then the directive should have archRole undefined - And the directive should have archContext undefined - And the directive should have archLayer undefined - - # ============================================================================ - # RULE 3: PatternGraph ArchIndex - # ============================================================================ - - Rule: PatternGraph builds archIndex during transformation - - **Invariant:** The `transformToPatternGraph` function must build an `archIndex` - that groups patterns by role, context, and layer for efficient diagram generation. - - **Rationale:** Single-pass extraction during dataset transformation avoids - expensive re-traversal. Index structure enables O(1) lookup by each dimension. - - **Verified by:** archIndex groups by role, archIndex groups by context, - archIndex groups by layer, archIndex.all contains all arch-annotated patterns - - @acceptance-criteria @happy-path - Scenario: archIndex groups patterns by arch-role - Given patterns with arch-role annotations: - | Pattern | arch-role | - | Handler1 | command-handler | - | Handler2 | command-handler | - | Projection1 | projection | - When transformToPatternGraph runs - Then archIndex.byRole["command-handler"] contains 2 patterns - And archIndex.byRole["projection"] contains 1 pattern - - @acceptance-criteria @happy-path - Scenario: archIndex groups patterns by arch-context - Given patterns with arch-context annotations: - | Pattern | arch-context | - | OrderHandler | orders | - | OrderProjection | orders | - | InventoryHandler | inventory | - When transformToPatternGraph runs - Then archIndex.byContext["orders"] contains 2 patterns - And archIndex.byContext["inventory"] contains 1 pattern - - @acceptance-criteria @happy-path - Scenario: archIndex groups patterns by arch-layer - Given patterns with arch-layer annotations: - | Pattern | arch-layer | - | Decider1 | domain | - | Handler1 | application | - | Infra1 | infrastructure | - When transformToPatternGraph runs - Then archIndex.byLayer["domain"] contains 1 pattern - And archIndex.byLayer["application"] contains 1 pattern - And archIndex.byLayer["infrastructure"] contains 1 pattern - - @acceptance-criteria @happy-path - Scenario: archIndex.all contains all patterns with any arch tag - Given patterns: - | Pattern | arch-role | arch-context | arch-layer | - | WithAll | projection | orders | application | - | WithRole | saga | - | - | - | WithContext | - | inventory | - | - | NoArchTags | - | - | - | - When transformToPatternGraph runs - Then archIndex.all contains 3 patterns - And archIndex.all does not contain "NoArchTags" - - # ============================================================================ - # RULE 4: Component Diagram Generation - # ============================================================================ - - Rule: Component diagrams group patterns by bounded context - - **Invariant:** Component diagrams must render patterns as nodes grouped into - bounded context subgraphs, with relationship arrows using UML-inspired styles. - - **Rationale:** Component diagrams visualize system architecture showing how - bounded contexts isolate components. Subgraphs enforce visual separation. - - **Verified by:** Generate subgraphs per bounded context, Group context-less patterns - in Shared Infrastructure, Render uses as solid arrow, Render depends-on as dashed arrow - - @acceptance-criteria @happy-path - Scenario: Generate subgraphs per bounded context - Given patterns with arch-context: - | Pattern | arch-context | arch-role | - | OrderHandler | orders | command-handler | - | OrderProjection | orders | projection | - | InventoryHandler | inventory | command-handler | - When the component diagram codec runs - Then output contains subgraph "Orders BC" - And output contains subgraph "Inventory BC" - And OrderHandler is inside Orders BC subgraph - And InventoryHandler is inside Inventory BC subgraph - - @acceptance-criteria @happy-path - Scenario: Patterns without arch-context go to Shared Infrastructure - Given patterns: - | Pattern | arch-context | arch-role | - | OrderHandler | orders | command-handler | - | GlobalSaga | - | saga | - | CrossContextProjection | - | projection | - When the component diagram codec runs - Then output contains subgraph "Shared Infrastructure" - And GlobalSaga is inside Shared Infrastructure subgraph - And CrossContextProjection is inside Shared Infrastructure subgraph - - @acceptance-criteria @happy-path - Scenario: Render uses relationship as solid arrow - Given patterns with uses relationship: - | Pattern | arch-role | uses | - | SagaA | saga | HandlerB | - | HandlerB | command-handler | - | - When the component diagram codec runs - Then output contains "SagaA --> HandlerB" - - @acceptance-criteria @happy-path - Scenario: Render depends-on relationship as dashed arrow - Given patterns with depends-on relationship: - | Pattern | arch-role | depends-on | - | FeatureA | projection | FeatureB | - | FeatureB | projection | - | - When the component diagram codec runs - Then output contains "FeatureA -.-> FeatureB" - - @acceptance-criteria @happy-path - Scenario: Render implements relationship as dotted arrow - Given patterns with implements relationship: - | Pattern | arch-role | implements | - | ConcreteImpl | command-handler | AbstractSpec | - | AbstractSpec | - | - | - When the component diagram codec runs - Then output contains "ConcreteImpl ..-> AbstractSpec" - - @acceptance-criteria @happy-path - Scenario: Render extends relationship as open arrow - Given patterns with extends relationship: - | Pattern | arch-role | extends | - | SpecializedHandler | command-handler | BaseHandler | - | BaseHandler | command-handler | - | - When the component diagram codec runs - Then output contains "SpecializedHandler -->> BaseHandler" - - @acceptance-criteria @validation - Scenario: Arrows only render between annotated components - Given patterns: - | Pattern | arch-role | uses | - | AnnotatedA | saga | UnannotatedB | - And UnannotatedB has no arch tags - When the component diagram codec runs - Then output does not contain arrow to UnannotatedB diff --git a/architect/specs/architecture-doc-refactoring.feature b/architect/specs/architecture-doc-refactoring.feature deleted file mode 100644 index 5055e92b..00000000 --- a/architect/specs/architecture-doc-refactoring.feature +++ /dev/null @@ -1,442 +0,0 @@ -@architect -@architect-pattern:ArchitectureDocRefactoring -@architect-status:completed -@architect-unlock-reason:Implement-test-coverage-and-fix-spec-metadata -@architect-phase:36 -@architect-effort:2d -@architect-product-area:Generation -@architect-depends-on:DocsConsolidationStrategy -@architect-business-value:decomposes-1287-line-manual-architecture-doc-into-curated-overview-with-generated-references -@architect-priority:high -Feature: Architecture Document Refactoring - - **Problem:** - ARCHITECTURE.md is 1,287 lines of manually-maintained documentation covering 14 - sections. The codec system already generates much of this content (codec references - via convention tags, PatternGraph types via shape extraction, pipeline diagrams - via architecture annotations). Maintaining parallel manual and generated versions - creates drift and duplication. - - **Solution:** - Decompose ARCHITECTURE.md into a curated architecture overview (~320 lines of - editorial narrative optimized for Claude as primary consumer) that links to generated - reference documents for detailed content. Phase 2 established the convention-tag - pattern by extracting the 368-line Available Codecs section. Phase 4 applies - product area absorption, generated shapes, architecture diagram references, and - usefulness-driven editorial trimming to the remaining consolidatable content. - - **Why It Matters:** - | Benefit | How | - | Reduced drift | Generated sections always match current code annotations | - | Focused overview | Editorial narrative explains "why" without duplicating "what" | - | Dual output | Each generated section gets docs/ detailed + _claude-md/ compact versions | - | Convention-driven | Adding a new codec only requires adding a convention tag to its JSDoc | - - **Section Disposition (line ranges from original 1,287-line pre-refactoring document):** - | Section | Lines | Action | Target | - | Executive Summary | 28-69 | Keep | Editorial narrative | - | Configuration Architecture | 70-139 | Phase 4: absorb | Configuration product area | - | Four-Stage Pipeline | 140-343 | Keep, trim | Editorial narrative (core concepts) | - | Unified Transformation | 345-478 | Phase 4: generate | Shapes reference doc (PatternGraph types) | - | Codec Architecture | 481-527 | Keep | Editorial narrative (concepts only) | - | Available Codecs | 529-534 | Phase 2: done | Pointer to ARCHITECTURE-CODECS.md | - | Progressive Disclosure | 535-584 | Keep | Editorial narrative | - | Source Systems | 585-692 | Phase 4: absorb | Annotation product area (examples merge to Pipeline) | - | Key Design Patterns | 693-772 | Phase 4: trim | Result pointer to CoreTypes, summaries for others (DD-5) | - | Data Flow Diagrams | 774-957 | Phase 4: generate | Architecture diagrams reference | - | Workflow Integration | 959-1068 | Phase 4: absorb | Process product area | - | Programmatic Usage | 1070-1125 | Phase 4: drop | Claude reads source directly (DD-9) | - | Extending the System | 1127-1194 | Phase 4: drop | Claude infers from codec patterns (DD-9) | - | Quick Reference | 1196-1287 | Phase 2: done | Pointer to ARCHITECTURE-CODECS.md + CLI | - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | Tests | Test Type | - | Convention-tag codec-registry on 14 codec files | complete | src/renderable/codecs/*.ts | Yes | integration | - | Machine-extractable JSDoc format for codecs | complete | src/renderable/codecs/*.ts | Yes | integration | - | Codec-registry reference config | complete | architect.config.ts | Yes | integration | - | Convention-extractor heading match bugfix | complete | src/renderable/codecs/convention-extractor.ts | Yes | unit | - | Available Codecs section replaced with pointer | complete | docs/ARCHITECTURE.md | No | n/a | - | Configuration Architecture to product area | complete | docs/ARCHITECTURE.md | Yes | integration | - | PatternGraph Schema to shapes reference | complete | docs/ARCHITECTURE.md | Yes | integration | - | Source Systems to Annotation product area | complete | docs/ARCHITECTURE.md | Yes | integration | - | Data Flow Diagrams to architecture diagrams | complete | docs/ARCHITECTURE.md | Yes | integration | - | Workflow Integration to Process product area | complete | docs/ARCHITECTURE.md | Yes | integration | - | Key Design Patterns to CoreTypes product area | complete | docs/ARCHITECTURE.md | Yes | integration | - | Usefulness-driven editorial trim (DD-9) | complete | docs/ARCHITECTURE.md | No | n/a | - - Rule: Convention-tagged JSDoc produces machine-extractable codec documentation - - **Invariant:** Every codec source file annotated with `@architect-convention - codec-registry` must have structured JSDoc following the machine-extractable - format. The convention extractor splits multi-codec files by `## Heading` into - separate convention rules, each rendered as its own section in the generated - reference document. - - **Rationale:** DD-1: Convention tag approach over dedicated codec. Rather than - creating a new "codec inventory" codec that enumerates codecs from source, the - existing convention-tag mechanism is reused. Each codec file's JSDoc is treated - as convention rules tagged with `codec-registry`. This avoids new codec - infrastructure and leverages the proven convention extractor path. The reference - codec already handles 4-layer composition, so convention tags slot into the - existing Layer 1 (conventions) position. - - **Verified by:** Multi-codec file produces separate sections, - Options table renders in both detail levels, - Codec without structured JSDoc produces fallback content - - @acceptance-criteria @happy-path - Scenario: Multi-codec file produces separate convention sections - Given a codec file with three codecs under separate headings - """ - ## SessionContextCodec - **Purpose:** Current session context for AI agents. - **Output Files:** SESSION-CONTEXT.md - - ## RemainingWorkCodec - **Purpose:** Incomplete work across phases. - **Output Files:** REMAINING-WORK.md - - ## CurrentWorkCodec - **Purpose:** Active development work in progress. - **Output Files:** CURRENT-WORK.md - """ - And the file is annotated with @architect-convention codec-registry - When the convention extractor processes the file - Then three separate convention rules are produced - And each rule has its own Purpose and Output Files - - @acceptance-criteria @happy-path - Scenario: Options table renders correctly in both detail levels - Given a codec JSDoc with an options table - """ - | Option | Type | Default | Description | - | generateDetailFiles | boolean | true | Create phase detail files | - | detailLevel | string | standard | Output verbosity level | - """ - When the reference codec generates at detailed level - Then the options table appears with all columns - When the reference codec generates at summary level - Then the options table appears in the compact output - - @acceptance-criteria @edge-case - Scenario: Codec file without structured JSDoc produces fallback - Given a codec file with @architect-convention codec-registry - But the JSDoc lacks structured headings - When the convention extractor processes the file - Then the entire JSDoc description is treated as a single convention rule - - Rule: Machine-extractable JSDoc format follows structured heading convention - - **Invariant:** DD-2: Multi-codec JSDoc splitting uses one `## Heading` per codec - per file. Each heading block contains structured fields in a fixed order: - `**Purpose:**` one-liner, `**Output Files:**` file paths, options table with - Type/Default/Description columns, `**When to Use:**` bullet list, and - `**Factory Pattern:**` code example. Fields are optional -- codecs without options - omit the table, codecs without factory patterns omit the code block. - - **Rationale:** The convention extractor uses `## ` heading regex to split - descriptions into rules. Without this structure, a file like `session.ts` - (3 codecs) would produce a single undifferentiated blob. The heading text becomes - the convention rule title in the generated reference. The fixed field order ensures - consistent rendering across all 20+ codec entries. - - **Verified by:** Heading text becomes convention rule title, - Field order is consistent across all codec files - - @acceptance-criteria @happy-path - Scenario: Heading text becomes the convention rule title - Given a codec JSDoc heading "## ValidationRulesCodec" - When the convention extractor splits the description - Then the convention rule title is "ValidationRulesCodec" - And the content below the heading becomes the rule body - - @acceptance-criteria @validation - Scenario: All codec files follow the structured format - Given the 14 codec files tagged with codec-registry - Then each file has at least one heading starting with "## " - And each heading block contains a "Purpose:" field - And each heading block contains an "Output Files:" field - - Rule: Heading match in convention extractor handles whitespace correctly - - **Invariant:** The convention extractor's heading parser uses `matchEnd` (the - character position after the full regex match) rather than `indexOf('\n', - heading.index)` to calculate where content starts after a heading. This prevents - the `\s*` prefix in the heading regex from consuming leading newlines, which - would cause `heading.index` to point to those newlines instead of the heading text. - - **Rationale:** Discovered during Phase 2 implementation. The heading regex - `/^\s*##\s+(.+)$/gm` matches headings with optional leading whitespace. When a - heading has leading newlines, `heading.index` points to the first newline (part - of the `\s*` match), not the `##` character. Using `indexOf('\n', heading.index)` - then finds the newline BEFORE the heading, producing content that includes the - heading text itself. The fix uses the regex match's end position directly. - - **Verified by:** Heading with leading whitespace splits correctly, - Heading at start of description splits correctly - - @acceptance-criteria @happy-path - Scenario: Convention extraction splits headings with leading whitespace - Given a JSDoc description with a heading preceded by blank lines - When the convention extractor splits the description - Then the heading text is extracted without leading whitespace - And the content starts after the heading line - - @acceptance-criteria @edge-case - Scenario: Heading at start of description splits correctly - Given a JSDoc description starting directly with a heading - When the convention extractor splits the description - Then the heading is extracted as the first rule - And no empty content precedes it - - Rule: Section disposition follows content-type routing - - **Invariant:** DD-3: Each ARCHITECTURE.md section is routed based on content type. - Three routing strategies apply: (1) product area absorption -- sections describing - a specific pipeline stage move to the corresponding product area document where - they get live diagrams and relationship graphs; (2) generated shapes -- sections - documenting TypeScript interfaces move to generated shape reference docs; - (3) generated diagrams -- ASCII/text data flow diagrams are replaced by live - Mermaid diagrams generated from architecture annotations. - - **Rationale:** The routing heuristic is: if a generated equivalent already exists, - replace with pointer; if content is convention-taggable in source files, tag and - generate; if editorial content that cannot be expressed as annotations, retain. - This ensures each section lands in the location with the best maintenance model - for its content type. - - **Verified by:** Product area absorption captures equivalent content, - Shape reference covers PatternGraph documentation, - No content is lost in routing - - @acceptance-criteria @happy-path - Scenario: Product area absorption captures section content - Given the Configuration Architecture section in ARCHITECTURE.md - And the Configuration product area doc with annotated source content - When the section is compared with the product area output - Then the product area doc covers the same config resolution flow - And the ARCHITECTURE.md section can be replaced with a pointer - - @acceptance-criteria @happy-path - Scenario: Shape reference covers PatternGraph documentation - Given the Unified Transformation section with PatternGraph schema - And TypeScript types tagged with @architect-shape in the source - When a shapes reference doc config targets PatternGraph types - Then the generated shapes section contains the same type definitions - And the manual schema documentation can be replaced - - @acceptance-criteria @validation - Scenario: No content is lost in section routing - Given all sections being routed to generated equivalents - When each manual section is compared with its target generated doc - Then every technical fact in the manual section appears in the generated output - And editorial context is preserved in the retained overview sections - - Rule: Product area absorption validates content coverage before pointer replacement - - **Invariant:** DD-4: Product area absorption replaces ARCHITECTURE.md sections with - pointers only when the target product area document already covers the equivalent - content. Three sections route to product areas: Configuration Architecture (L70-139) - to CONFIGURATION.md, Source Systems (L585-692) to ANNOTATION.md, and Workflow - Integration (L959-1068) to PROCESS.md. Annotation format examples from Source - Systems merge into the Four-Stage Pipeline retained section rather than being lost. - Workflow API code examples are dropped -- Claude reads source files directly. - - **Rationale:** Product area documents are generated from annotated source code and - already contain live diagrams, relationship graphs, and API types. Absorbing manual - Architecture sections into these generated docs eliminates drift while preserving - the content in a maintained location. The key test is: does the product area doc - cover the same technical facts? If yes, the manual section becomes a 4-line pointer. - - **Verified by:** Configuration section covered by product area, - Source Systems covered with annotation examples preserved, - Workflow Integration covered without API tutorials, - Annotation format examples appear in Four-Stage Pipeline - - @acceptance-criteria @happy-path - Scenario: Configuration Architecture section absorbed by Configuration product area - Given the Configuration Architecture section in ARCHITECTURE.md (L70-139) - And the generated CONFIGURATION.md product area document - When the product area content is compared with the manual section - Then CONFIGURATION.md covers config resolution flow, presets, and key types - And the manual section is replaced with a 4-line pointer - - @acceptance-criteria @happy-path - Scenario: Source Systems section absorbed by Annotation product area - Given the Source Systems section in ARCHITECTURE.md (L585-692) - And the generated ANNOTATION.md product area document - When the product area content is compared with the manual section - Then ANNOTATION.md covers scanner types, tag dispatch, and extraction pipeline - And annotation format examples (L598-631) merge into Four-Stage Pipeline section - And the manual section is replaced with a 4-line pointer - - @acceptance-criteria @happy-path - Scenario: Workflow Integration section absorbed by Process product area - Given the Workflow Integration section in ARCHITECTURE.md (L959-1068) - And the generated PROCESS.md product area document - When the product area content is compared with the manual section - Then PROCESS.md covers FSM lifecycle, session types, and workflow handoffs - And API code examples are dropped because Claude reads source directly - And the manual section is replaced with a 4-line pointer - - @acceptance-criteria @validation - Scenario: Annotation format examples preserved in Four-Stage Pipeline section - Given the annotation format examples from Source Systems (L598-631) - When the Source Systems section is absorbed - Then the annotation format examples appear in the Four-Stage Pipeline section - And the examples explain how to read and write architect tags - - Rule: PatternGraph shapes generate a dedicated ARCHITECTURE-TYPES reference document - - **Invariant:** DD-6: A new ReferenceDocConfig produces ARCHITECTURE-TYPES.md using - shapeSelectors with group pattern-graph to extract PatternGraph schema types, - RuntimePatternGraph, RawDataset, PipelineOptions, and PipelineResult. Source files - tagged with @architect-shape pattern-graph - contribute shapes to the reference doc. The Unified Transformation section (L345-478) - is replaced with a condensed narrative (~15 lines) and pointer to ARCHITECTURE-TYPES.md. - - **Rationale:** The PatternGraph is the central data structure -- the sole read model - per ADR-006. It deserves dedicated reference doc treatment alongside ARCHITECTURE-CODECS.md. - Shape extraction from TypeScript declarations provides exact type signatures that stay - in sync with code, unlike the manual schema table in ARCHITECTURE.md. - - **Verified by:** PatternGraph shapes extracted into reference doc, - Pipeline types included alongside schema types, - Unified Transformation section replaced with pointer - - @acceptance-criteria @happy-path - Scenario: PatternGraph shapes extracted via shape selectors - Given source files tagged with @architect-shape pattern-graph - And a ReferenceDocConfig with shapeSelectors targeting pattern-graph group - When the reference codec generates ARCHITECTURE-TYPES.md - Then PatternGraphSchema, RuntimePatternGraph, and RawDataset types appear - And each shape includes its TypeScript declaration and JSDoc description - - @acceptance-criteria @happy-path - Scenario: Pipeline types included in ARCHITECTURE-TYPES reference doc - Given PipelineOptions and PipelineResult tagged with @architect-shape pattern-graph - And @architect-shape pattern-graph on their source files - When the reference codec generates ARCHITECTURE-TYPES.md - Then PipelineOptions and PipelineResult shapes appear in the API Types section - And both detailed and compact outputs are produced - - @acceptance-criteria @happy-path - Scenario: Unified Transformation section replaced with pointer and narrative - Given the Unified Transformation section in ARCHITECTURE.md (L345-478) - And ARCHITECTURE-TYPES.md generated with PatternGraph shapes - When the section is consolidated - Then the section is replaced with a condensed narrative and pointer - And the narrative explains PatternGraph role as the sole read model - And no type definitions remain in ARCHITECTURE.md - - Rule: Pipeline architecture convention content replaces ASCII data flow diagrams - - **Invariant:** DD-7: The Data Flow Diagrams section (L774-957) contains 4 ASCII - diagrams totaling ~183 lines. These are replaced using a hybrid approach: convention - tag pipeline-architecture (already registered, currently unused) on orchestrator.ts - and build-pipeline.ts produces prose descriptions of pipeline steps and consumer - architecture. A new pattern-graph-views hardcoded diagram source generates a - Mermaid fan-out diagram showing dataset view relationships. DD-8: Both convention - content and diagram source are configured on the ARCHITECTURE-TYPES.md ReferenceDocConfig, - keeping all architecture reference content in one generated document. - - **Rationale:** ASCII diagrams cannot be generated from code annotations. The hybrid - approach maximizes generated coverage: convention-tagged JSDoc captures the narrative - (pipeline steps, ADR-006 consumer pattern) while the hardcoded diagram source produces - visual Mermaid output. Using the already-registered pipeline-architecture convention - tag avoids new taxonomy entries. - - **Verified by:** Convention tag produces pipeline flow content, - Diagram source generates Mermaid fan-out, - Data Flow Diagrams section replaced with pointer - - @acceptance-criteria @happy-path - Scenario: Convention tag pipeline-architecture produces pipeline flow content - Given orchestrator.ts annotated with @architect-convention pipeline-architecture - And build-pipeline.ts annotated with @architect-convention pipeline-architecture - When the reference codec generates ARCHITECTURE-TYPES.md - Then convention content describing pipeline steps appears in the document - And consumer architecture patterns from build-pipeline.ts appear - - @acceptance-criteria @happy-path - Scenario: pattern-graph-views diagram source generates Mermaid fan-out diagram - Given pattern-graph-views added to DIAGRAM_SOURCE_VALUES in reference.ts - And buildPatternGraphViewsDiagram builder function implemented - And ARCHITECTURE-TYPES.md config includes pattern-graph-views in diagramScopes - When the reference codec generates the document - Then a Mermaid diagram showing PatternGraph view fan-out is rendered - And the diagram appears in both detailed and compact outputs - - @acceptance-criteria @happy-path - Scenario: Data Flow Diagrams section replaced with pointer to generated reference - Given ARCHITECTURE-TYPES.md generated with convention content and diagrams - When the Data Flow Diagrams section (L774-957) is consolidated - Then the 4 ASCII diagrams are removed from ARCHITECTURE.md - And a 5-line pointer to ARCHITECTURE-TYPES.md replaces the section - - Rule: Usefulness-driven editorial trimming targets Claude as primary consumer - - **Invariant:** DD-9: ARCHITECTURE.md serves Claude (primary audience) and human - developers (secondary). Content retained must answer architectural "why" and "how - things connect" questions. Content available via source file reads or generated - reference documents is removed. Post-decomposition target: ~320 lines (~75% reduction - from 1,287 lines). Sections dropped entirely: Programmatic Usage (L1070-1125) and - Extending the System (L1127-1194) -- Claude reads source files directly and infers - extension patterns from existing codec implementations. DD-5: Key Design Patterns - section (L693-772) trimmed from ~80 to ~15 lines: Result Monad becomes a pointer to - CORE-TYPES.md, Schema-First Validation becomes a 3-line summary with source pointer, - Tag Registry becomes a 4-line summary with source pointer. - - **Rationale:** Claude has direct access to source files and generated reference docs. - Duplicating this content in ARCHITECTURE.md wastes context window tokens. The - remaining editorial sections (Executive Summary, Four-Stage Pipeline, Codec Architecture, - Progressive Disclosure) provide the mental model and architectural "why" that cannot - be inferred from code alone. - - **Verified by:** Tutorial sections removed for Claude efficiency, - Four-Stage Pipeline trimmed to conceptual model, - Key Design Patterns trimmed to pointers and summaries, - Post-decomposition file is under target size, - Every pointer resolves to covering generated doc - - @acceptance-criteria @validation - Scenario: Tutorial sections removed because Claude reads source directly - Given the Programmatic Usage section (L1070-1125) - And the Extending the System section (L1127-1194) - When Phase 4 editorial trimming is applied - Then both sections are removed entirely from ARCHITECTURE.md - And no replacement pointers are needed because content is in source files - - @acceptance-criteria @validation - Scenario: Key Design Patterns trimmed to pointers and summaries - Given the Key Design Patterns section (L693-772) with three subsections - When editorial trimming is applied - Then Result Monad subsection is replaced with a pointer to CORE-TYPES.md - And Schema-First Validation is trimmed to a 3-line summary with source pointer - And Tag Registry is trimmed to a 4-line summary with source pointer - And the section shrinks from ~80 to ~15 lines - - @acceptance-criteria @validation - Scenario: Four-Stage Pipeline trimmed to conceptual model with annotation examples - Given the Four-Stage Pipeline section (L140-343) - When editorial trimming is applied - Then the section is trimmed to approximately 120 lines - And the conceptual pipeline model is retained - And annotation format examples merged from Source Systems are included - And detailed function walkthrough code is removed - - @acceptance-criteria @validation - Scenario: Post-decomposition ARCHITECTURE.md is under 400 lines - Given all Phase 4 pointer replacements are complete - And editorial trimming is applied to retained sections - When the final line count is measured - Then ARCHITECTURE.md is approximately 320 lines - And the document contains Executive Summary, Pipeline, Codec Architecture, and Progressive Disclosure - - @acceptance-criteria @validation - Scenario: Every pointer links to a generated doc that covers the replaced content - Given all Phase 4 pointer replacements in ARCHITECTURE.md - When each pointer target is checked - Then every pointer links to an existing generated document - And the generated document contains the technical facts from the replaced section diff --git a/architect/specs/claude-module-generation.feature b/architect/specs/claude-module-generation.feature deleted file mode 100644 index 6db146c8..00000000 --- a/architect/specs/claude-module-generation.feature +++ /dev/null @@ -1,444 +0,0 @@ -@architect -@architect-pattern:ClaudeModuleGeneration -@architect-status:completed -@architect-unlock-reason:Skip-Feature-description-in-module-output -@architect-phase:25 -@architect-effort:1.5d -@architect-product-area:Generation -@architect-business-value:automated-claude-md-modules-from-source -@architect-priority:high -@architect-executable-specs:tests/features/behavior/claude-modules -Feature: CLAUDE.md Module Generation from Source Annotations - - **Problem:** CLAUDE.md modules are hand-written markdown files that drift from source - code over time. When behavior specs or implementation details change, module content - becomes stale. Manual synchronization is tedious and error-prone. Different consumers - need different detail levels (compact for AI context, detailed for human reference). - - **Solution:** Generate CLAUDE.md modules directly from behavior spec feature files using - dedicated `claude-*` tags. The same source generates both: - - Compact modules for `_claude-md/` (AI context optimized) - - Detailed documentation for `docs/` (human reference, progressive disclosure) - - Three tags control module generation: - - `@architect-claude-module` - Module identifier (becomes filename) - - `@architect-claude-section` - Target section directory in `_claude-md/` - - `@architect-claude-tags` - Tags for variation filtering in modular-claude-md - - **Why It Matters:** - | Benefit | How | - | Single source of truth | Behavior specs ARE the module content | - | Always-current modules | Generated on each docs build | - | Progressive disclosure | Same source → compact module + detailed docs | - | Preserves Rule structure | `Rule:` blocks become module sections | - | Extracts decision tables | `Scenario Outline Examples:` become lookup tables | - | CLI integration | `pnpm docs:claude-modules` via generator registry | - - **Prototype Example:** - The Process Guard behavior spec (`tests/features/validation/process-guard.feature`) - generates both `_claude-md/architect/process-guard.md` and detailed docs. - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | Tests | Test Type | - | claude-module tag definition | complete | taxonomy/registry-builder.ts | Yes | unit | - | claude-section tag definition | complete | taxonomy/registry-builder.ts | Yes | unit | - | claude-tags tag definition | complete | taxonomy/registry-builder.ts | Yes | unit | - | DocDirective schema fields | complete | validation-schemas/doc-directive.ts | Yes | unit | - | ExtractedPattern schema fields | complete | validation-schemas/extracted-pattern.ts | Yes | unit | - | Gherkin parser tag extraction | complete | extractor/gherkin-extractor.ts | Yes | unit | - | ClaudeModuleCodec | complete | renderable/codecs/claude-module.ts | Yes | unit | - | Claude module generator | complete | generators/built-in/codec-generators.ts | Yes | unit | - | Generator registry integration | complete | generators/built-in/codec-generators.ts | Yes | unit | - | Process Guard annotated example | n/a | tests/features/validation/process-guard.feature | No | - | - | Example generated module | n/a | _example-output/process-guard.md | No | - | - - # ============================================================================ - # RULE 1: Claude Module Tags in Registry - # ============================================================================ - - Rule: Claude module tags exist in the tag registry - - **Invariant:** Three claude-specific tags (`claude-module`, `claude-section`, - `claude-tags`) must exist in the tag registry with correct format and values. - - **Rationale:** Module generation requires metadata to determine output path, - section placement, and variation filtering. Standard tag infrastructure enables - consistent extraction via the existing Gherkin parser. - - **Verified by:** Tag registry contains claude-module, Tag registry contains - claude-section, Tag registry contains claude-tags, claude-section has enum values - - @acceptance-criteria @happy-path - Scenario: Tag registry contains claude-module - Given the tag registry is loaded - When querying for tag "claude-module" - Then the tag should exist - And the tag format should be "value" - And the tag purpose should contain "filename" - - @acceptance-criteria @happy-path - Scenario: Tag registry contains claude-section - Given the tag registry is loaded - When querying for tag "claude-section" - Then the tag should exist - And the tag format should be "enum" - And the tag should have values including "core", "process", "testing", "infrastructure", "workflow" - - @acceptance-criteria @happy-path - Scenario: Tag registry contains claude-tags - Given the tag registry is loaded - When querying for tag "claude-tags" - Then the tag should exist - And the tag format should be "csv" - And the tag purpose should contain "variation filtering" - - # ============================================================================ - # RULE 2: Gherkin Parser Extraction - # ============================================================================ - - Rule: Gherkin parser extracts claude module tags from feature files - - **Invariant:** The Gherkin extractor must extract `claude-module`, `claude-section`, - and `claude-tags` from feature file tags into ExtractedPattern objects. - - **Rationale:** Behavior specs are the source of truth for CLAUDE.md module content. - Parser must extract module metadata alongside existing pattern metadata. - - **Verified by:** Extract claude-module from feature tags, Extract claude-section - from feature tags, Extract claude-tags as array, Handle missing claude tags gracefully - - @acceptance-criteria @happy-path - Scenario: Extract claude-module from feature tags - Given a feature file with tags: - """gherkin - @architect-claude-module:process-guard - @architect-claude-section:process - Feature: Process Guard - """ - When the Gherkin extractor processes the file - Then the pattern should have claudeModule "process-guard" - - @acceptance-criteria @happy-path - Scenario: Extract claude-section from feature tags - Given a feature file with tags: - """gherkin - @architect-claude-module:fsm-validator - @architect-claude-section:testing - Feature: FSM Validator - """ - When the Gherkin extractor processes the file - Then the pattern should have claudeSection "testing" - - @acceptance-criteria @happy-path - Scenario: Extract claude-tags as array - Given a feature file with tags: - """gherkin - @architect-claude-tags:core-mandatory,process,platform-packages - Feature: Multi-tag Example - """ - When the Gherkin extractor processes the file - Then the pattern should have claudeTags ["core-mandatory", "process", "platform-packages"] - - @acceptance-criteria @validation - Scenario: Patterns without claude tags are not module candidates - Given a feature file without claude-module tag - When the Gherkin extractor processes the file - Then the pattern should have claudeModule undefined - And the pattern should not be included in module generation - - # ============================================================================ - # RULE 3: Content Extraction from Feature Structure - # ============================================================================ - - Rule: Module content is extracted from feature file structure - - **Invariant:** The codec extracts content from Rule blocks and Scenario Outline - Examples only. Feature descriptions (Problem/Solution preamble) are skipped because - they contain meta-documentation about why the spec exists, not operational content - for AI sessions. - - **Rationale:** Behavior specs contain well-structured, prescriptive content in Rule - blocks. Feature descriptions waste context in compact AI modules — the invariants - and rationale in Rule blocks are the actionable content. - - **Verified by:** Feature description is excluded, Rule names become section headers, - Rule descriptions become content, Scenario Outline Examples become tables - - @acceptance-criteria @happy-path - Scenario: Feature description is excluded from module output - Given a feature file with description: - """gherkin - Feature: Process Guard - Pure validation for enforcing delivery process rules. - - **Problem:** - - Completed specs modified without unlock reason - - Invalid status transitions - - **Solution:** - - checkProtectionLevel() enforces unlock-reason - - checkStatusTransitions() validates FSM - """ - When generating the claude module - Then the module should start with "### Process Guard" - And the module should not contain the Problem section - And the module should not contain the Solution section - - @acceptance-criteria @happy-path - Scenario: Rule blocks become module sections - Given a feature file with rules: - """gherkin - Rule: Completed files require unlock-reason to modify - - **Invariant:** Modification of completed spec requires explicit unlock. - - **Rationale:** Prevents accidental changes to approved work. - """ - When generating the claude module - Then the module should contain "#### Completed files require unlock-reason to modify" - And the module should contain the invariant statement - And the module should contain the rationale - - @acceptance-criteria @happy-path - Scenario: Scenario Outline Examples become decision tables - Given a feature file with scenario outline: - """gherkin - Scenario Outline: Protection level from status - Given a file with status "" - Then protection level is "" - - Examples: - | status | protection | - | completed | hard | - | active | scope | - | roadmap | none | - """ - When generating the claude module - Then the module should contain a markdown table with headers "status" and "protection" - And the table should have 3 data rows - - @acceptance-criteria @validation - Scenario: Scenarios without Examples tables are not extracted - Given a feature file with only simple scenarios (no Examples) - When generating the claude module - Then the scenarios are not included in output - And only Rule descriptions and Examples tables appear - - # ============================================================================ - # RULE 4: Claude Module Codec Output Format - # ============================================================================ - - Rule: ClaudeModuleCodec produces compact markdown modules - - **Invariant:** The codec transforms patterns with claude tags into markdown files - suitable for the `_claude-md/` directory structure. - - **Rationale:** CLAUDE.md modules must be compact and actionable. The codec - produces ready-to-use markdown without truncation (let modular-claude-md - handle token budget warnings). - - **Verified by:** Output uses H3 for title, Output uses H4 for rules, Tables are - preserved, Code blocks in descriptions are preserved, See-also link is included - - @acceptance-criteria @happy-path - Scenario: Module uses correct heading levels - Given a pattern with claude-module "process-guard" - When generating the claude module - Then the module title should use "###" (H3) - And rule sections should use "####" (H4) - - @acceptance-criteria @happy-path - Scenario: Tables from rule descriptions are preserved - Given a rule with embedded markdown table: - """ - | From | To | Valid | - | roadmap | active | Yes | - | roadmap | complete | No | - """ - When generating the claude module - Then the table should appear in output unchanged - - @acceptance-criteria @happy-path - Scenario: Code blocks in descriptions are preserved - Given a feature description with code block: - """ - ```bash - pnpm lint-process --staged - ``` - """ - When generating the claude module - Then the code block should appear in output with language tag - - @acceptance-criteria @happy-path - Scenario: See-also link to full documentation is included - Given a pattern with claude-module "process-guard" - And the fullDocsPath option is "docs/PROCESS-GUARD.md" - When generating the claude module - Then the module should end with "**See:** [Full Documentation](docs/PROCESS-GUARD.md)" - - # ============================================================================ - # RULE 5: Generator File Output - # ============================================================================ - - Rule: Claude module generator writes files to correct locations - - **Invariant:** The generator must write module files to `{outputDir}/{section}/{module}.md` - based on the `claude-section` and `claude-module` tags. - - **Rationale:** Output path structure must match modular-claude-md expectations. - The `claude-section` determines the subdirectory, `claude-module` determines filename. - - **Verified by:** Output path uses section as directory, Output filename uses module name, - Multiple modules from single run, Generator respects --overwrite flag - - @acceptance-criteria @happy-path - Scenario: Output path uses section as directory - Given a pattern with: - | Tag | Value | - | claude-module | process-guard | - | claude-section | process | - And output directory is "_claude-md" - When the generator runs - Then file should be written to "_claude-md/architect/process-guard.md" - - @acceptance-criteria @happy-path - Scenario: Multiple modules generated from single run - Given patterns with different claude-section values: - | Pattern | claude-module | claude-section | - | ProcessGuard | process-guard | process | - | FsmValidator | fsm-validator | testing | - | LayerInference | layer-inference | testing | - When the generator runs - Then 3 module files should be created - And "_claude-md/architect/process-guard.md" should exist - And "_claude-md/testing/fsm-validator.md" should exist - And "_claude-md/testing/layer-inference.md" should exist - - @acceptance-criteria @validation - Scenario: Generator skips patterns without claude-module tag - Given 5 patterns where only 2 have claude-module tags - When the generator runs - Then only 2 module files should be created - And non-claude patterns should be ignored - - @acceptance-criteria @happy-path - Scenario: Generator creates section directories if missing - Given claude-section "new-section" does not exist - When generating a module with claude-section "new-section" - Then directory "_claude-md/new-section" should be created - And the module file should be written inside it - - # ============================================================================ - # RULE 6: Generator Registry Integration - # ============================================================================ - - Rule: Claude module generator is registered with generator registry - - **Invariant:** A "claude-modules" generator must be registered with the generator - registry to enable `pnpm docs:claude-modules` via the existing CLI. - - **Rationale:** Consistent with architecture-diagram-generation pattern. New - generators register with the orchestrator rather than creating separate commands. - - **Verified by:** Generator is registered, CLI command works, Generator options supported - - @acceptance-criteria @happy-path - Scenario: Generator is registered with name "claude-modules" - Given the generator registry - When listing available generators - Then "claude-modules" should be in the list - - @acceptance-criteria @happy-path - Scenario: CLI command generates modules - When running: - """bash - generate-docs \ - --features 'tests/features/behavior/**/*.feature' \ - --generators claude-modules \ - --output _claude-md - """ - Then command exits successfully - And module files are written to _claude-md subdirectories - - @acceptance-criteria @happy-path - Scenario: Generator supports fullDocsPath option - When running with option "--full-docs-path docs/" - Then generated modules include See-also links with that path prefix - - # ============================================================================ - # RULE 7: Progressive Disclosure for Full Docs - # ============================================================================ - - Rule: Same source generates detailed docs with progressive disclosure - - **Invariant:** When running with `detailLevel: "detailed"`, the codec produces - expanded documentation including all Rule content, code examples, and scenario details. - - **Rationale:** Single source generates both compact modules (AI context) and - detailed docs (human reference). Progressive disclosure is already a codec capability. - - **Verified by:** Detailed mode includes scenarios, Detailed mode includes code examples, - Summary mode produces compact output - - @acceptance-criteria @happy-path - Scenario: Detailed mode includes scenario descriptions - Given detailLevel is "detailed" - When generating documentation - Then individual scenario titles should appear - And scenario steps should be summarized - - @acceptance-criteria @happy-path - Scenario: Summary mode produces compact output for modules - Given detailLevel is "summary" - When generating the claude module - Then only Rules and Examples tables should appear - And individual scenarios should be omitted - - @acceptance-criteria @happy-path - Scenario: Standard mode is default for module generation - Given no detailLevel is specified - When generating the claude module - Then output should use standard detail level - And Rules with Invariant/Rationale should appear - And Examples tables should appear - - # ============================================================================ - # EXAMPLE: Process Guard Module Output - # ============================================================================ - - # The following shows expected output for process-guard.feature: - # - # ### Process Guard Linter - # - # Pure validation for enforcing delivery process rules per PDR-005. - # - # **Problem:** - # - Completed specs modified without unlock reason - # - Invalid status transitions bypass FSM rules - # - Active specs expand scope with new deliverables - # - # **Solution:** - # - `checkProtectionLevel()` → enforces unlock-reason for completed - # - `checkStatusTransitions()` → validates FSM transitions - # - `checkScopeCreep()` → prevents deliverable addition to active specs - # - # #### Protection Levels - # - # | Status | Protection | Restriction | - # |--------|------------|-------------| - # | `completed` | hard | Requires unlock-reason | - # | `active` | scope | No new deliverables | - # | `roadmap` | none | Fully editable | - # | `deferred` | none | Fully editable | - # - # #### Valid Transitions - # - # | From | To | Notes | - # |------|-----|-------| - # | `roadmap` | `active`, `deferred` | Start or postpone | - # | `active` | `completed`, `roadmap` | Finish or regress | - # | `deferred` | `roadmap` | Resume planning | - # | `completed` | _(terminal)_ | Use unlock-reason | - # - # **See:** [Full Documentation](docs/PROCESS-GUARD.md) diff --git a/architect/specs/cli-recipe-codec.feature b/architect/specs/cli-recipe-codec.feature deleted file mode 100644 index 9f7df61e..00000000 --- a/architect/specs/cli-recipe-codec.feature +++ /dev/null @@ -1,265 +0,0 @@ -@architect -@architect-pattern:CliRecipeCodec -@architect-status:completed -@architect-unlock-reason:Initial-commit-with-all-deliverables-complete -@architect-phase:35 -@architect-effort:2w -@architect-product-area:Generation -@architect-depends-on:DocsConsolidationStrategy -@architect-depends-on:CliReferenceGeneration -@architect-business-value:replaces-460-lines-of-manual-CLI-md-prose-with-generated-recipe-and-narrative-content -@architect-priority:medium -Feature: CLI Recipe Codec - - **Problem:** - `docs/CLI.md` (~509 lines) retains ~460 lines of editorial prose after - Phase 43 (CliReferenceGeneration) extracted 3 reference tables to - `docs-live/reference/CLI-REFERENCE.md`. The remaining content includes: - "Why Use This" motivation (30 lines), Quick Start with example output (32 lines), - Session Types decision tree (12 lines), Session Workflow Commands with 6 narrative - command descriptions and output examples (125 lines), Pattern Discovery with 8 - command descriptions (95 lines), Architecture Queries reference (28 lines), - Metadata and Inventory (39 lines), and Common Recipes with 5 recipe blocks - (42 lines). This prose is manually maintained and risks drifting from the CLI - implementation when commands are added, renamed, or removed. - - **Solution:** - Create a standalone `CliRecipeGenerator` that extends CLI_SCHEMA with recipe - definitions and narrative metadata, producing `docs-live/reference/CLI-RECIPES.md`. - The generator is a sibling to `CliReferenceGenerator` -- both are standalone - (ADR-006 compliant) and consume CLI_SCHEMA directly. Editorial content that cannot - be derived from schema (motivation prose, session decision tree) uses the preamble - mechanism. `docs/CLI.md` retains a slim editorial introduction and links - to both generated files (reference tables + recipes). - - **Why It Matters:** - | Benefit | How | - | Zero-drift recipes | Recipe command sequences regenerate from schema when CLI changes | - | Session decision tree stays current | Session types defined in schema, decision tree generated | - | Command narratives from schema | Each command group carries description and example output in schema | - | Hybrid integrity preserved | Editorial "Why Use This" prose lives in preamble, not duplicated | - | Two generated files complement each other | Reference tables (what flags exist) + recipes (how to use them) | - - **Design Questions (for design session):** - | Question | Options | Recommendation | - | How to structure recipe definitions in schema? | (A) Inline in CLIOptionGroup, (B) Separate RecipeGroup[] | (B) Separate -- recipes are multi-command sequences, not per-option | - | Should command narrative descriptions come from schema? | (A) Extend CLIOptionGroup.description, (B) New CommandNarrative type | (A) Extend -- description field already exists and is rendered | - | How to handle example CLI output blocks? | (A) Static strings in schema, (B) Live execution at gen time | (A) Static -- deterministic output, no build-time side effects | - | Where does Quick Start content belong? | (A) Preamble, (B) First recipe group | (A) Preamble -- it is introductory editorial with example output | - | Should the generator produce claude-md output? | (A) Yes via ReferenceDocConfig, (B) No, standalone only | (B) No -- CLAUDE.md already has Data API CLI section from CLAUDE.md authoring | - - **Design Session Findings (2026-03-06):** - | Finding | Impact | Resolution | - | DD-1: Recipes need separate RecipeGroup[] field, not inline per-option | Recipes span multiple option groups (e.g., "Starting a Session" uses overview + scope-validate + context) | Added RecipeGroup[] and CommandNarrativeGroup[] as optional fields on CLISchema -- existing consumers unchanged | - | DD-2: CLI_SCHEMA extension is additive with two new optional fields | CliReferenceGenerator and showHelp ignore unknown fields | recipes and commandNarratives fields added to CLISchema interface, not a separate extended type | - | DD-3: Preamble mechanism proven by ReferenceDocConfig and ErrorGuideCodec stubs | Why Use This (30 lines), Quick Start (32 lines), Session Types (12 lines) are editorial judgment | Generator accepts preamble SectionBlock[] via CliRecipeGeneratorConfig, configured in architect.config.ts | - | DD-4: CommandNarrative type needed, not just CLIOptionGroup.description extension | Session Workflow has 6 commands each needing description + usage example + expected output | New CommandNarrative interface with command, description, usageExample, details, expectedOutput fields | - | DD-5: Recipes grouped by task intent, not session type or command | Matches existing Common Recipes structure in CLI.md | 5 groups: Starting a Session, Finding Work, Investigating, Design Prep, Ending a Session | - | Content audit: ~460 lines map to 3 schema locations + preamble | Zero information loss from manual to generated | recipes (42 lines), commandNarratives (287 lines), preamble (74 lines), kept in manual (70 lines) | - | CliReferenceGenerator is 113 lines and proven stable | Extending it risks regressions on Phase 43 deliverables | CliRecipeGenerator is a separate sibling class, same DocumentGenerator interface | - | Generator registration follows cli-reference pattern | generatorOverrides already has cli-reference entry | Add cli-recipe entry with same outputDirectory: docs-live | - - **Design Stubs:** - | Stub | Location | Key Decisions | - | Recipe schema types | architect/stubs/cli-recipe-codec/recipe-schema.ts | DD-1 RecipeGroup/RecipeExample/RecipeStep, DD-4 CommandNarrative/CommandNarrativeGroup, CLISchema extension | - | Generator class | architect/stubs/cli-recipe-codec/cli-recipe-generator.ts | DD-1 separate generator, DD-3 preamble config, DD-5 no claude-md output | - | Recipe data examples | architect/stubs/cli-recipe-codec/recipe-data.ts | DD-2 schema data mapping, DD-4 narrative examples, preamble content examples | - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | Tests | Test Type | - | Extend CLI_SCHEMA with recipe definitions per command group | complete | src/cli/cli-schema.ts | Yes | unit | - | Create CliRecipeGenerator producing CLI-RECIPES.md | complete | src/generators/built-in/cli-recipe-generator.ts | Yes | integration | - | Register generator in orchestrator config | complete | architect.config.ts | Yes | integration | - | Preamble content for Why Use This and session decision tree | complete | architect.config.ts | No | n/a | - | Replace CLI.md prose sections with pointers to generated files | complete | docs/CLI.md | No | n/a | - | Behavior spec with scenarios for recipe generation | n/a | tests/features/behavior/cli/cli-recipe-generation.feature | Yes | acceptance | - - Rule: CLI recipes are a separate generator from reference tables - - **Invariant:** The `CliRecipeGenerator` is a standalone sibling to - `CliReferenceGenerator`, not an extension of it. Both implement - `DocumentGenerator`, both consume `CLI_SCHEMA` directly, and both produce - independent `OutputFile[]` via the standard orchestrator write path. The recipe - generator produces `docs-live/reference/CLI-RECIPES.md` while the - reference generator produces `docs-live/reference/CLI-REFERENCE.md`. - - **Rationale:** Reference tables and recipe guides serve different audiences and - change at different cadences. Reference tables change when CLI flags are added - or removed. Recipes change when workflow recommendations evolve. Coupling them - in one generator would force both to change together and make the generator - responsible for two distinct content types. CliReferenceGenerator is - already completed and tested (Phase 43) -- extending it risks regressions. Two - small standalone generators are easier to test and maintain than one large one. - - **Verified by:** Two separate generator classes exist, - Each produces its own output file independently - - @acceptance-criteria @happy-path - Scenario: CliRecipeGenerator produces recipe file independently - Given the CliRecipeGenerator is registered in the orchestrator - And the CliReferenceGenerator is also registered - When docs:all runs - Then docs-live/reference/CLI-RECIPES.md is created - And docs-live/reference/CLI-REFERENCE.md is also created - And neither generator imports nor depends on the other - - @acceptance-criteria @validation - Scenario: Recipe generator has no PatternGraph dependency - Given the CliRecipeGenerator source file - When inspecting its import statements - Then it does not import PatternGraph or any pipeline module - And it imports only from src/cli/cli-schema.ts and generator infrastructure - - Rule: Recipe content uses a structured schema extension - - **Invariant:** `CLI_SCHEMA` is extended with a `recipes` field containing - `RecipeGroup[]`. Each `RecipeGroup` has a title, optional description, and an - array of `RecipeExample` objects. Each `RecipeExample` has a title, a purpose - description, an array of RecipeStep entries (each with a command string and optional comment), and an optional expected output block. - The schema extension is additive -- existing `CLIOptionGroup` types are unchanged. - - **Rationale:** Recipes are multi-command sequences ("run these 3 commands in - order") with explanatory context. They do not fit into `CLIOptionGroup` which - models individual flags. A separate `RecipeGroup[]` keeps the schema type-safe - and makes recipes independently testable. Static expected output strings in the - schema are deterministic -- no build-time CLI execution needed. - - **Verified by:** Schema type includes RecipeGroup definition, - Recipe data drives generated output - - @acceptance-criteria @happy-path - Scenario: CLI schema includes recipe definitions - Given the CLI_SCHEMA constant in src/cli/cli-schema.ts - When recipe groups are added for session startup and pattern investigation - Then each recipe group has a title and at least one recipe example - And each recipe example includes a title, purpose, and command array - And the schema TypeScript compiles without errors - - @acceptance-criteria @happy-path - Scenario: Generated recipe file renders multi-command sequences - Given a RecipeGroup titled "Starting a Session" with 3 recipe commands - And each command has a trailing comment explaining its purpose - When the CliRecipeGenerator renders this group - Then the output contains a section heading "Starting a Session" - And a code block with all 3 commands in sequence - And purpose text appears before the code block - - @acceptance-criteria @validation - Scenario: Recipe with expected output renders output block - Given a RecipeExample with an expectedOutput string - When the CliRecipeGenerator renders this recipe - Then the output contains the command code block - And a separate "Example output" code block follows with the expected output text - - Rule: Narrative prose uses preamble mechanism - - **Invariant:** Editorial content that cannot be derived from the CLI schema -- - specifically "Why Use This" motivational prose, the Quick Start example with - output, and the session type decision tree -- uses a preamble mechanism in the - generator configuration. Preamble content is manually authored in - `architect.config.ts` as structured section data and appears before all - generated recipe content in the output file. - - **Rationale:** The "Why Use This" section explains the value proposition of the - Data API CLI with a comparison table (CLI vs reading markdown). This is editorial - judgment, not derivable from command metadata. The Quick Start shows a specific - 3-command workflow with example terminal output. The session decision tree maps - cognitive states ("Starting to code?") to session types. None of these have a - source annotation -- they are instructional content authored for human - understanding. The preamble mechanism exists precisely for this (proven by - DocsConsolidationStrategy Phase 2 preamble implementation). - - **Verified by:** Preamble sections appear before recipe content, - Preamble content is not duplicated in schema recipe definitions - - @acceptance-criteria @happy-path - Scenario: Generated file starts with preamble editorial content - Given a CliRecipeGenerator with preamble containing Why Use This prose - And the preamble includes a comparison table and Quick Start example - When the generator produces CLI-RECIPES.md - Then the file begins with the Why Use This section - And the Quick Start section follows with command examples and output - And generated recipe sections appear after the preamble content - - @acceptance-criteria @validation - Scenario: Empty preamble produces no extra content - Given a CliRecipeGenerator with no preamble configured - When the generator produces the recipe file - Then the file begins directly with the first recipe group heading - And no empty sections or separators appear at the top - - Rule: Generated recipe file complements manual CLI.md - - **Invariant:** After this pattern completes, `docs/CLI.md` is trimmed to - a slim editorial introduction (~30 lines) containing the document title, a - one-paragraph purpose statement, and links to both generated files: - `docs-live/reference/CLI-REFERENCE.md` (option tables from Phase 43) and - `docs-live/reference/CLI-RECIPES.md` (recipes and narratives from this - pattern). The manual file retains the JSON Envelope, Exit Codes, and JSON Piping - sections (~40 lines) which are operational reference unlikely to drift. - All other prose sections are replaced by the generated recipe file. - - **Rationale:** Phase 43 established the hybrid pattern: keep editorial prose in - the manual file, extract derivable content to generated files. This pattern - extends the hybrid by recognizing that recipe content IS derivable from a - structured schema. The ~460 lines of command descriptions, example output, - and recipe blocks can be maintained as schema data rather than freeform markdown. - What remains in the manual file (~70 lines total) is true operational reference - (JSON envelope format, exit codes, piping tips) that changes rarely and has no - schema source. - - **Verified by:** Manual file links to both generated files, - Recipe sections no longer duplicated in manual file - - @acceptance-criteria @happy-path - Scenario: CLI.md links to both generated files - Given CLI.md has been trimmed after CliRecipeCodec completion - When reading the manual file - Then it contains a link to docs-live/reference/CLI-REFERENCE.md - And it contains a link to docs-live/reference/CLI-RECIPES.md - And the total line count is under 100 lines - - @acceptance-criteria @validation - Scenario: No recipe content duplicated between manual and generated files - Given CLI.md and CLI-RECIPES.md both exist - When comparing their content - Then the Common Recipes section does not appear in CLI.md - And Session Workflow Commands section does not appear in CLI.md - And Pattern Discovery section does not appear in CLI.md - And these sections appear in CLI-RECIPES.md - - Rule: Command narrative descriptions are sourced from schema metadata - - **Invariant:** Each command group in the generated recipe file includes a - narrative description sourced from the CLI schema, not hardcoded in the generator. - The existing `CLIOptionGroup.description` and `CLIOptionGroup.postNote` fields - carry per-group narrative text. For command groups not currently in CLI_SCHEMA - (Session Workflow Commands, Pattern Discovery, Architecture Queries, Metadata - and Inventory), new `CommandGroup` entries are added to the schema with title, - description, and per-command narrative metadata. - - **Rationale:** The manual CLI.md contains narrative descriptions for each - command ("Highest-impact command. Pre-flight readiness check that prevents wasted - sessions.") that are valuable developer context. Hardcoding these in the generator - would create a second maintenance location. Placing them in CLI_SCHEMA co-locates - command metadata (what the command does) with command definition (what flags it - accepts), following the same single-source-of-truth principle that drove Phase 43. - - **Verified by:** Command narratives render from schema data, - Generator contains no hardcoded command descriptions - - @acceptance-criteria @happy-path - Scenario: Command descriptions render from schema metadata - Given CLI_SCHEMA contains a command group for Session Workflow Commands - And the overview command has a description "Executive summary: progress, active phases, blocking patterns" - When the CliRecipeGenerator renders the Session Workflow Commands section - Then the overview command appears with its schema-sourced description - And no description text is hardcoded in the generator source - - @acceptance-criteria @happy-path - Scenario: All six session workflow commands have narrative descriptions - Given CLI_SCHEMA command groups include all 6 session workflow commands - When the CliRecipeGenerator renders the session workflow section - Then overview, scope-validate, context, dep-tree, files, and handoff each have descriptions - And each description includes a usage example code block diff --git a/architect/specs/cli-reference-generation.feature b/architect/specs/cli-reference-generation.feature deleted file mode 100644 index 520c8d87..00000000 --- a/architect/specs/cli-reference-generation.feature +++ /dev/null @@ -1,158 +0,0 @@ -@architect -@architect-pattern:CliReferenceGeneration -@architect-status:completed -@architect-unlock-reason:Retroactive-completion-during-rebrand -@architect-phase:43 -@architect-effort:1d -@architect-product-area:Generation -@architect-depends-on:DocsConsolidationStrategy -@architect-business-value:keeps-cli-reference-tables-in-sync-with-cli-schema-automatically -@architect-priority:low -Feature: CLI.md Hybrid Generation - - **Problem:** - `docs/CLI.md` (509 lines) contains three reference tables that manually - mirror CLI definitions in source code: Global Options (lines 382-389, 6 rows), - Output Modifiers (lines 397-403, 5 rows), and List Filters (lines 415-424, 8 rows). - These ~41 lines are pure data derived from code constants in `src/cli/pattern-graph-cli.ts` - and `src/cli/output-pipeline.ts`. When CLI options change, these tables require - manual updates and risk falling out of sync with the implementation. - - Additionally, the `showHelp()` function (lines 271-370 of `src/cli/pattern-graph-cli.ts`) - is a hardcoded third copy of the same information, creating three-way drift risk: - parser code, help text, and markdown tables. - - **Solution:** - Create a declarative CLI schema (`src/cli/cli-schema.ts`) as the single source of - truth. A standalone `CliReferenceGenerator` reads this schema and produces - a complete generated reference file at `docs-live/reference/CLI-REFERENCE.md`. - The "Output Reference" section in `docs/CLI.md` (lines 376-424) is replaced - with a heading and link to the generated file. The `showHelp()` function is refactored - to consume the same schema, eliminating three-way sync. - - **Why It Matters:** - | Benefit | How | - | Zero drift | Reference tables regenerate automatically from schema | - | Three-way sync eliminated | Schema drives both help text and generated docs | - | Consistent with existing pattern | Same OutputFile approach as ARCHITECTURE-CODECS.md | - - **Design Findings (2026-03-05):** - | Finding | Impact | Resolution | - | Original spec references src/cli/parser.ts | File does not exist | Fix to src/cli/pattern-graph-cli.ts + src/cli/output-pipeline.ts | - | Orchestrator only does full-file writes | Marker-based partial replacement not supported | Split Output Reference into separate generated file | - | ReferenceDocConfig is PatternGraph-sourced | CLI schema data is not annotation-derived | Standalone generator, not ReferenceDocConfig (ADR-006) | - | --format in Output Modifiers table but not in OutputModifiers interface | Would produce incomplete table | Schema includes --format alongside modifiers | - | --session parsed as global option but absent from Global Options table | Intentional, documented in Session Types | Schema captures in separate sessionOptions group | - | showHelp() lines 271-370 is third copy of same data | Three-way sync risk | Schema drives both help text and doc generation | - | Inter-table prose is only ~10 lines total | Must appear in generated file | Encode as description/postNote fields in schema | - - **Section Audit — docs/CLI.md (509 lines):** - | Section | Lines | Action | Rationale | - | Intro + Why Use This | 1-30 | KEEP | Editorial context | - | Quick Start | 31-62 | KEEP | Examples with output | - | Session Types | 65-76 | KEEP | Decision tree | - | Session Workflow Commands | 80-204 | KEEP | Narrative descriptions | - | Pattern Discovery | 207-301 | KEEP | Narrative descriptions | - | Architecture Queries | 305-332 | KEEP | Reference with examples | - | Metadata and Inventory | 336-374 | KEEP | Command descriptions | - | Output Reference heading | 376-378 | TRIM | Replace with link to generated file | - | Global Options table | 380-391 | EXTRACT | Generate from CLI schema | - | Output Modifiers table | 393-409 | EXTRACT | Generate from CLI schema | - | List Filters table | 411-424 | EXTRACT | Generate from CLI schema | - | JSON Envelope | 426-449 | KEEP | Operational reference | - | Exit Codes | 451-456 | KEEP | Operational reference | - | JSON Piping | 458-465 | KEEP | Operational tip | - | Common Recipes | 468-509 | KEEP | Editorial recipes | - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | Tests | Test Type | - | Create declarative CLI schema with option groups | complete | src/cli/cli-schema.ts | Yes | unit | - | Sync test verifying schema entries match parseArgs behavior | complete | tests/features/behavior/cli/ | Yes | integration | - | CliReferenceGenerator producing complete reference file | complete | src/generators/built-in/cli-reference-generator.ts | Yes | integration | - | Register generator in orchestrator config | complete | architect.config.ts | Yes | integration | - | Trim CLI.md Output Reference to link to generated file | complete | docs/CLI.md | Yes | manual | - | Refactor showHelp to consume CLI schema | complete | src/cli/pattern-graph-cli.ts | Yes | integration | - | Behavior spec with scenarios for all 3 generated tables | complete | tests/features/behavior/cli/cli-reference.feature | Yes | integration | - - Rule: CLI schema is single source of truth for reference tables - - **Invariant:** A declarative CLI schema in `src/cli/cli-schema.ts` defines all - global options, output modifiers, and list filters with their flags, descriptions, - defaults, and value types. The three reference tables in - `docs-live/reference/CLI-REFERENCE.md` are generated from this schema by - a standalone `CliReferenceGenerator`. The schema also drives `showHelp()`. - - **Rationale:** CLI options are defined imperatively in `parseArgs()` (lines 132-265 - of `src/cli/pattern-graph-cli.ts`) and `OutputModifiers`/`ListFilters` interfaces - (lines 43-83 of `src/cli/output-pipeline.ts`). A declarative schema extracts this - into a single structured definition that both documentation and help text consume. - The existing `ReferenceDocConfig` system cannot be used because it sources from - PatternGraph (annotation-derived data), not static constants (ADR-006). - - **Verified by:** Tables match parser definitions, showHelp output matches schema, - sync test catches drift - - @acceptance-criteria @happy-path - Scenario: Generated tables match CLI schema definitions - Given a CLI schema defining global options, output modifiers, and list filters - When the CliReferenceGenerator runs - Then CLI-REFERENCE.md contains a Global Options table with all defined flags - And the table includes flag name, short alias, description, and default columns - And CLI-REFERENCE.md contains an Output Modifiers table with all defined modifiers - And CLI-REFERENCE.md contains a List Filters table with all defined filter keys - - @acceptance-criteria @validation - Scenario: CLI schema stays in sync with parser - Given a CLI schema entry for each flag recognized by parseArgs - When a new flag is added to parseArgs without updating the schema - Then the sync test fails with a mismatch report - And when the schema is updated to include the new flag - Then the sync test passes - - Rule: Narrative prose sections remain manual - - **Invariant:** CLI.md sections covering "Why Use This", session type - decision tree, workflow recipes, worked examples with expected output, and - "Common Recipes" are not generated. They require editorial judgment and context - that cannot be extracted from code annotations. The document's value comes from - these sections — the generated reference tables are supporting material only. - - **Rationale:** Generated docs without prose context would be a bare options - table — usable as reference but not as a learning resource. The hybrid approach - gives both: accurate tables from code, readable narrative from editorial work. - - **Verified by:** Prose sections identical after regeneration, - Tables updated when CLI schema changes - - @acceptance-criteria @validation - Scenario: Prose sections unchanged after regeneration - Given CLI.md with narrative sections including "Why Use This" and "Common Recipes" - When the CliReferenceGenerator runs - Then CLI.md is not modified by the generator - And only CLI-REFERENCE.md is created or updated - And CLI.md contains a link to CLI-REFERENCE.md in the Output Reference section - - Rule: Standalone generator respects ADR-006 single read model - - **Invariant:** The `CliReferenceGenerator` imports CLI schema data directly - from `src/cli/cli-schema.ts`. It does NOT inject CLI data into PatternGraph or - consume PatternGraph for table generation. It implements `DocumentGenerator` and - returns `OutputFile[]` via the standard orchestrator write path. - - **Rationale:** ADR-006 establishes PatternGraph as the sole read model for - annotation-sourced data. CLI schema is a static TypeScript constant, not extracted - from annotations. Forcing it through PatternGraph would violate the "no parallel - pipeline" anti-pattern. A standalone generator with its own data source is - architecturally correct. - - **Verified by:** Generator has no PatternGraph import, output file written by orchestrator - - @acceptance-criteria @integration - Scenario: Generator produces complete reference file - Given the CliReferenceGenerator is registered in the orchestrator - When docs:all runs - Then docs-live/reference/CLI-REFERENCE.md is created - And the file contains three sections: Global Options, Output Modifiers, List Filters - And each section includes a markdown table with headers and data rows - And inter-table prose (config auto-detection, valid fields, precedence) is included diff --git a/architect/specs/codec-driven-reference-generation.feature b/architect/specs/codec-driven-reference-generation.feature deleted file mode 100644 index 1abf901e..00000000 --- a/architect/specs/codec-driven-reference-generation.feature +++ /dev/null @@ -1,159 +0,0 @@ -@architect -@architect-pattern:CodecDrivenReferenceGeneration -@architect-status:completed -@architect-unlock-reason:Retroactive-spec-for-completed-work -@architect-phase:27 -@architect-effort:5d -@architect-product-area:Generation -@architect-depends-on:DocGenerationProofOfConcept,ScopedArchitecturalView -@architect-business-value:eliminates-per-document-recipe-features-with-config-driven-generation -@architect-priority:high -Feature: Codec-Driven Reference Generation - - **Problem:** - Each reference document (Process Guard, Taxonomy, Validation, etc.) required a - hand-coded recipe feature that duplicated codec setup, rendering, and file output - logic. Adding a new reference document meant creating a new feature file, a new - codec wrapper, and a new generator class -- all following the same pattern. - - **Solution:** - A single `createReferenceCodec` factory driven by `ReferenceDocConfig` objects. - Each config declares four content sources -- convention tags, diagram scopes, - shape source globs, and behavior categories -- that compose automatically in - AD-5 order. 13 configs produce 27 generators (13 detailed for `docs/` + - 13 summary for `_claude-md/` + 1 meta-generator). - - **Why It Matters:** - | Benefit | How | - | Zero-code new documents | Add a config object, get two output files | - | Consistent structure | Every reference doc follows the same composition order | - | Two detail levels | Detailed (full source, diagrams) and summary (compact tables) | - | Convention-driven content | Decision records auto-populate via tag matching | - | Shape extraction | TypeScript types rendered from AST, not duplicated in prose | - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | - | ReferenceDocConfig interface | complete | src/renderable/codecs/reference.ts | - | createReferenceCodec factory | complete | src/renderable/codecs/reference.ts | - | Convention section builder | complete | src/renderable/codecs/reference.ts | - | Shape section builder (AD-6) | complete | src/renderable/codecs/reference.ts | - | Behavior section builder | complete | src/renderable/codecs/reference.ts | - | AD-5 composition order | complete | src/renderable/codecs/reference.ts | - | 13 reference configs | complete | src/generators/built-in/reference-generators.ts | - | ReferenceDocGenerator class | complete | src/generators/built-in/reference-generators.ts | - | ReferenceDocsGenerator meta-generator | complete | src/generators/built-in/reference-generators.ts | - | Convention extractor | complete | src/renderable/codecs/convention-extractor.ts | - - Rule: Config-driven codec replaces per-document recipe features - - **Invariant:** A single `ReferenceDocConfig` object is sufficient to produce - a complete reference document. No per-document codec subclass or recipe feature - is required. - - **Rationale:** The codec composition logic is identical across all reference - documents. Only the content sources differ. Extracting this into a config-driven - factory eliminates N duplicated recipe features and makes adding new documents - a one-line config addition. - - **Verified by:** All 13 configs produce valid documents, - Empty config produces fallback content - - @acceptance-criteria @happy-path - Scenario: Config with matching data produces a complete document - Given a ReferenceDocConfig with convention tags and shape sources - And a PatternGraph with patterns matching those tags and sources - When the reference codec renders the document - Then the output contains convention sections, shape sections, and metadata - - @acceptance-criteria @edge-case - Scenario: Config with no matching data produces fallback content - Given a ReferenceDocConfig with tags that match no patterns - And an empty PatternGraph - When the reference codec renders the document - Then the output contains "No content found" fallback message - - Rule: Four content sources compose in AD-5 order - - **Invariant:** Reference documents always compose content in this order: - conventions, then scoped diagrams, then shapes, then behaviors. Empty sources - are omitted without placeholder sections. - - **Rationale:** AD-5 established that conceptual context (conventions and - architectural diagrams) should precede implementation details (shapes and - behaviors). This reading order helps developers understand the "why" before - the "what". - - **Verified by:** Composition order follows conventions-diagrams-shapes-behaviors, - Convention and behavior content compose together - - @acceptance-criteria @happy-path - Scenario: Composition follows AD-5 order - Given a config with all four content sources populated - When the reference codec renders at detailed level - Then conventions appear before diagrams - And diagrams appear before shapes - And shapes appear before behaviors - - @acceptance-criteria @happy-path - Scenario: Empty sources are omitted gracefully - Given a config with only convention tags (no shapes, no behaviors, no diagrams) - And a PatternGraph with matching conventions - When the reference codec renders the document - Then only convention sections appear - And no empty placeholder sections exist - - Rule: Detail level controls output density - - **Invariant:** Three detail levels produce progressively more content from the - same config. Summary: type tables only, no diagrams, no narrative. Standard: - narrative and code examples, no rationale. Detailed: full rationale, property - documentation, and scoped diagrams. - - **Rationale:** AI context windows need compact summaries. Human readers need - full documentation. The same config serves both audiences by parameterizing - the detail level at generation time. - - **Verified by:** Summary produces compact tables, - Detailed includes full rationale - - @acceptance-criteria @happy-path - Scenario: Summary level produces compact type tables - Given a config with shape sources matching TypeScript types - When the reference codec renders at summary level - Then shapes appear as a two-column table (Type, Kind) - And no source code blocks appear - And no mermaid diagrams appear - - @acceptance-criteria @happy-path - Scenario: Detailed level includes full source and rationale - Given a config with conventions and shape sources - When the reference codec renders at detailed level - Then convention sections include rationale text - And shapes include full source code blocks - And scoped diagrams are rendered as mermaid - - Rule: Generator registration produces paired detailed and summary outputs - - **Invariant:** Each ReferenceDocConfig produces exactly two generators - (detailed for `docs/`, summary for `_claude-md/`) plus a meta-generator - that invokes all pairs. Total: N configs x 2 + 1 = 2N + 1 generators. - - **Rationale:** Every reference document needs both a human-readable detailed - version and an AI-optimized compact version. The meta-generator enables - `pnpm docs:all` to produce every reference document in one pass. - - **Verified by:** All 27 generators are registered, - Generators follow naming convention - - @acceptance-criteria @happy-path - Scenario: All 27 generators are registered from 13 configs - Given 13 ReferenceDocConfig entries - When reference generators are registered - Then 27 generators exist in the registry - - @acceptance-criteria @happy-path - Scenario: Detailed generators use kebab-case-reference naming - Given the registered reference generators - Then detailed generators end with "-reference" - And summary generators end with "-reference-claude" diff --git a/architect/specs/config-based-workflow-definition.feature b/architect/specs/config-based-workflow-definition.feature deleted file mode 100644 index 793fcec6..00000000 --- a/architect/specs/config-based-workflow-definition.feature +++ /dev/null @@ -1,171 +0,0 @@ -@architect -@architect-pattern:ConfigBasedWorkflowDefinition -@architect-status:completed -@architect-unlock-reason:Terminology-alignment-rebrand -@architect-phase:99 -@architect-effort:2h -@architect-product-area:Configuration -@architect-include:reference-sample,process-workflow -@architect-depends-on:MvpWorkflowImplementation -@architect-business-value:eliminate-broken-workflow-loading -@architect-priority:high -Feature: Config-Based Workflow Definition - - **Problem:** - Every `pnpm architect:query` and `pnpm docs:*` invocation prints: - `Failed to load default workflow (6-phase-standard): Workflow file not found` - - The `loadDefaultWorkflow()` function resolves to `catalogue/workflows/` - which does not exist. The directory was deleted during monorepo extraction. - The system already degrades gracefully (workflow = undefined), but the - warning is noise for both human CLI use and future hook consumers (HUD). - - The old `6-phase-standard.json` conflated three concerns: - - Taxonomy vocabulary (status names) — already in `src/taxonomy/` - - FSM behavior (transitions) — already in `src/validation/fsm/` - - Workflow structure (phases) — orphaned, no proper home - - **Solution:** - Inline the default workflow as a constant in `workflow-loader.ts`, built - from canonical taxonomy values. Make `loadDefaultWorkflow()` synchronous. - Preserve `loadWorkflowFromPath()` for custom `--workflow ` overrides. - - The workflow definition uses only the 4 canonical statuses from ADR-001 - (roadmap, active, completed, deferred) — not the stale 5-status set from - the deleted JSON (which included non-canonical `implemented` and `partial`). - - Phase definitions (Inception, Elaboration, Session, Construction, - Validation, Retrospective) move from a missing JSON file to an inline - constant, making the default workflow always available without file I/O. - - Design Decisions (DS-1, 2026-02-15): - - | ID | Decision | Rationale | - | DD-1 | Inline constant in workflow-loader.ts, not preset integration | Minimal correct fix, zero type regression risk. Preset integration deferred. | - | DD-2 | Constant satisfies existing WorkflowConfig type | Reuse createLoadedWorkflow() from workflow-config.ts. No new types needed. | - | DD-3 | Remove dead code: getCatalogueWorkflowsPath, loadWorkflowConfig, DEFAULT_WORKFLOW_NAME | Dead since monorepo extraction. Public API break is safe (function always threw). | - | DD-4 | loadDefaultWorkflow() returns LoadedWorkflow synchronously | Infallible constant needs no async or error handling. | - | DD-5 | Amend ADR-001 with canonical phase definitions | Phase names are canonical values; fits existing governance in ADR-001. | - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | - | Inline default workflow constant | complete | src/config/workflow-loader.ts | - | Make loadDefaultWorkflow synchronous | complete | src/config/workflow-loader.ts | - | Remove dead code paths | complete | src/config/workflow-loader.ts | - | Update public API exports | complete | src/config/index.ts | - | Remove async and try-catch in orchestrator | complete | src/generators/orchestrator.ts | - | Remove async and try-catch in pattern-graph-cli | complete | src/cli/pattern-graph-cli.ts | - | Delete orphaned JSON file | n/a | architect/6-phase-standard.json | - | Amend ADR-001 with phase definitions rule | complete | architect/decisions/adr-001-taxonomy-canonical-values.feature | - - # ============================================================================ - # RULE 1: Default workflow is always available without file I/O - # ============================================================================ - - Rule: Default workflow is built from an inline constant - - **Invariant:** `loadDefaultWorkflow()` returns a `LoadedWorkflow` without - file system access. It cannot fail. The default workflow constant uses - only canonical status values from `src/taxonomy/status-values.ts`. - - **Rationale:** The file-based loading path (`catalogue/workflows/`) has - been dead code since monorepo extraction. Both callers (orchestrator, - pattern-graph-cli) already handle the failure gracefully, proving the system - works without it. Making the function synchronous and infallible removes - the try-catch ceremony and the warning noise. - - **Verified by:** Default workflow loads without warning, - Workflow constant uses canonical statuses only - - Implementation approach: - - | Step | Change | Impact | - | Add DEFAULT_WORKFLOW_CONFIG constant | WorkflowConfig literal with 4 statuses, 6 phases | New code in workflow-loader.ts | - | Change loadDefaultWorkflow() to sync | Returns createLoadedWorkflow(DEFAULT_WORKFLOW_CONFIG) | Signature: Promise to sync | - | Remove dead code paths | Delete getCatalogueWorkflowsPath, loadWorkflowConfig, DEFAULT_WORKFLOW_NAME, dead imports | workflow-loader.ts cleanup | - | Remove loadWorkflowConfig from public API | Update src/config/index.ts exports | Breaking change (safe: function always threw) | - | Update orchestrator call site | Remove await and try-catch (lines 410-418) | orchestrator.ts | - | Update pattern-graph-cli call site | Remove await and try-catch (lines 549-555) | pattern-graph-cli.ts | - - @acceptance-criteria @happy-path - Scenario: Default workflow loads without warning - Given the Architect package with no workflow JSON file - When the pattern-graph-cli runs an overview command - Then no workflow warning appears in output - And the overview displays progress, active phases, and blocking info - - @acceptance-criteria @validation - Scenario: Workflow constant uses canonical statuses only - Given the inline DEFAULT_WORKFLOW_CONFIG constant - Then it defines exactly 4 statuses: roadmap, active, completed, deferred - And it defines 6 phases with order 1 through 6 - And each status name exists in PROCESS_STATUS_VALUES from taxonomy - - # ============================================================================ - # RULE 2: Custom workflow override is preserved - # ============================================================================ - - Rule: Custom workflow files still work via --workflow flag - - **Invariant:** `loadWorkflowFromPath()` remains available for projects - that need custom workflow definitions. The `--workflow ` CLI flag - and `workflowPath` config field continue to work. - - **Rationale:** The inline default replaces file-based *default* loading, - not file-based *custom* loading. Projects may define custom phases or - additional statuses via JSON files. - - **Verified by:** Custom workflow file overrides default - - @acceptance-criteria @happy-path - Scenario: Custom workflow file overrides default - Given a project with workflowPath set to a custom JSON file - When the orchestrator loads workflow configuration - Then it uses the custom workflow from the file path - And the default inline workflow is not used - - # ============================================================================ - # RULE 3: No FSM or Process Guard changes - # ============================================================================ - - Rule: FSM validation and Process Guard are not affected - - **Invariant:** The FSM transition matrix, protection levels, and Process - Guard rules remain hardcoded in `src/validation/fsm/` and - `src/lint/process-guard/`. They do not read from `LoadedWorkflow`. - - **Rationale:** FSM and workflow are separate concerns. FSM enforces - status transitions (4-state model from PDR-005). Workflow defines phase - structure (6-phase USDP). The workflow JSON declared `transitionsTo` on - its statuses, but no code ever read those values — the FSM uses its own - `VALID_TRANSITIONS` constant. This separation is correct and intentional. - - Blast radius analysis confirmed zero workflow imports in: - - src/validation/fsm/ (4 files) - - src/lint/process-guard/ (5 files) - - src/taxonomy/ (all files) - - # ============================================================================ - # DEFERRED: Workflow in preset/config system - # ============================================================================ - - Rule: Workflow as a configurable preset field is deferred - - **Invariant:** The inline default workflow constant is the only workflow source until preset integration is implemented. No preset or project config field exposes workflow customization. - **Rationale:** Coupling workflow into the preset/config system before the inline fix ships would widen the blast radius and risk type regressions across all config consumers. - - **Verified by:** N/A - deferred until preset integration - - Adding `workflow` as a field on `ArchitectConfig` (presets) and - `ArchitectProjectConfig` (project config) is a natural next step - but NOT required for the MVP fix. - - The inline constant in `workflow-loader.ts` resolves the warning. Moving - workflow into the preset/config system enables: - - Different presets with different default phases (e.g., 3-phase libar-generic) - - Per-project phase customization in architect.config.ts - - Phase definitions appearing in generated documentation - - See ideation artifact for design options: - architect/ideations/2026-02-15-workflow-config-and-fsm-extensibility.feature diff --git a/architect/specs/cross-cutting-document-inclusion.feature b/architect/specs/cross-cutting-document-inclusion.feature deleted file mode 100644 index 492b174a..00000000 --- a/architect/specs/cross-cutting-document-inclusion.feature +++ /dev/null @@ -1,358 +0,0 @@ -@architect -@architect-pattern:CrossCuttingDocumentInclusion -@architect-status:completed -@architect-unlock-reason:compatibility-contract-cleanup -@architect-phase:32 -@architect-effort:2d -@architect-product-area:Generation -@architect-depends-on:DeclarationLevelShapeTagging,ReferenceDocShowcase -@architect-business-value:enables-universal-content-routing-to-any-generated-document -@architect-priority:high -Feature: Cross-Cutting Document Inclusion - - **Problem:** - The reference doc codec assembles content from four sources, each with its - own selection mechanism: conventionTags filters by convention tag values, - behaviorCategories filters by pattern category, shapeSelectors filters by - shape group or source, and diagramScopes filters by archContext or explicit - pattern names. These selectors operate at different granularity levels. - Convention and behavior selectors are coarse -- they pull ALL items matching - a tag or category, with no way to select a single convention rule or a - single behavior pattern for a focused showcase. - - More fundamentally, content-to-document is a many-to-many relationship. - A CategoryDefinition interface should be includable in a Taxonomy Reference, - a Configuration Guide, AND a claude.md architecture section simultaneously. - However, the `architect-shape` tag only supports one group, and behaviorCategories only - supports one category per pattern. There is no cross-cutting tag that says - "include this specific item in these specific documents." - - The experimental `architect-include` tag partially solved this for diagram - scoping but its name is misleading -- it routes content, not architectural - views. It should be replaced by a general-purpose include tag. - - **Solution:** - Replace arch-view with `architect-include` as a general-purpose - CSV tag on both patterns and shape declarations. This tag acts as a - document-routing mechanism alongside existing selectors. The tag controls - two things: (1) diagram scoping -- DiagramScope gains an include field - replacing archView, and (2) content routing -- ReferenceDocConfig gains an - includeTags field. Content matching logic becomes: include if item matches - existing selectors OR has a matching `architect-include` tag value. The - include tag is purely additive -- it never removes content that would be - selected by existing filters. - - The tag is CSV format, so one item can appear in multiple documents: - `@architect-include:reference-sample,codec-system,config-guide` - - This gives every content type (conventions, behaviors, shapes, diagrams) - uniform per-item opt-in without changing how existing selectors work. - - **Design Decisions:** - - DD-1: Additive semantics (OR, not AND) - The includeTags filter is unioned with existing selectors, not - intersected. A pattern appears in a reference doc if it matches - behaviorCategories OR has a matching include tag. Configs without - includeTags behave identically to today. Configs with includeTags - can pull in additional items that existing selectors cannot reach, - without disrupting what existing selectors already select. - - DD-2: One tag replaces arch-view and adds content routing - The `architect-include` tag replaces the experimental arch-view tag - entirely. DiagramScope.archView is renamed to DiagramScope.include. - The same tag values that scope diagrams can also route content via - ReferenceDocConfig.includeTags. One concept, one name. The arch-view - tag, field names, registry entry, and all references are removed. - - DD-3: Works on both patterns and declarations - For patterns (conventions, behaviors), the include tag lives in the - file-level or feature-level `@architect` block and is extracted as - part of the directive. For shapes, the include tag lives in the - declaration-level JSDoc alongside `architect-shape`. The shape - extractor (discoverTaggedShapes) extracts both tags from the same - JSDoc comment. The include values are stored on ExtractedShape as - an optional includes: readonly string[] field. - - DD-4: Content type determines rendering, include tag determines routing - The include tag does not change HOW content renders -- only WHERE - it appears. A pattern with rules still renders as a behavior section. - A shape still renders as a type code block. A convention still - renders as convention tables. The include tag is orthogonal to - content type. The codec determines rendering based on what the - item IS, not how it was selected. - - **Pragmatic Constraints:** - | Constraint | Rationale | - | Include values are single tokens (no spaces) | Standard tag value convention, hyphen-separated | - | No wildcard or glob matching on include values | Exact string match keeps selection predictable | - | Additive only, no exclusion mechanism | Exclusion adds complexity; use separate configs instead | - | Shape include requires `architect-shape` tag too | Include routes a shape, but `architect-shape` triggers extraction | - - **Implementation Path:** - | Layer | Change | Effort | - | registry-builder.ts | Replace arch-view with include in metadataTags (format: csv) | ~5 lines | - | extracted-pattern.ts | Rename archView to include on directive schema | ~5 lines | - | extracted-shape.ts | Add optional includes: readonly string[] field | ~3 lines | - | doc-directive.ts | Rename archView to include on DocDirective | ~5 lines | - | shape-extractor.ts | Extract `architect-include` CSV from declaration JSDoc | ~15 lines | - | doc-extractor.ts | Rename archView references to include | ~10 lines | - | ast-parser.ts | Rename arch-view extraction to include | ~5 lines | - | gherkin-ast-parser.ts | Rename archView field to include | ~5 lines | - | reference.ts | Rename DiagramScope.archView to include, add includeTags to ReferenceDocConfig, add inclusion pass | ~35 lines | - | project-config-schema.ts | Rename archView to include, add includeTags | ~5 lines | - | transform-dataset.ts | Rename archView references to include in dataset views | ~10 lines | - | pattern-graph.ts | Rename byArchView to byInclude in dataset schema | ~5 lines | - | reference-generators.ts | Update built-in configs from archView to include | ~5 lines | - | pattern-scanner.ts | Rename arch-view extraction to include | ~3 lines | - | architect.config.ts | Update showcase config: rename archView, add includeTags | ~5 lines | - | Source files (~8 files) | Replace arch-view annotations with `architect-include` | ~8 lines | - - **Integration with Existing Selectors:** - The reference codec decode method gains a new inclusion pass after the - existing four content assembly steps. For each content type, the flow is: - - 1. Existing selector produces initial content set - 2. Include tag pass finds additional items tagged for this document - 3. Results are merged (deduplicated by pattern name or shape name) - 4. Merged set is rendered using the existing section builders - - This means the include tag can pull a single behavior pattern into a - reference doc without needing to create a dedicated behaviorCategory - for it. It can pull a single convention rule without a unique - conventionTag. The include tag closes the granularity gap for all - content types uniformly. - - # =========================================================================== - # DELIVERABLES - # =========================================================================== - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | - | Replace arch-view with include in tag registry | Complete | src/taxonomy/registry-builder.ts | - | Rename archView to include on directive and pattern schemas | Complete | src/validation-schemas/ | - | Includes field on ExtractedShape | Complete | src/validation-schemas/extracted-shape.ts | - | Rename arch-view extraction to include in parsers | Complete | src/scanner/ | - | Rename and extract include in doc extractor | Complete | src/extractor/doc-extractor.ts | - | Extract include CSV from declaration JSDoc | Complete | src/extractor/shape-extractor.ts | - | Rename DiagramScope.archView to include | Complete | src/renderable/codecs/reference.ts | - | Add includeTags to ReferenceDocConfig with inclusion pass | Complete | src/renderable/codecs/reference.ts | - | Rename archView in dataset views and transform | Complete | src/generators/pipeline/transform-dataset.ts | - | Update all source file annotations from arch-view to include | Complete | src/**/*.ts | - | Update configs: rename archView, add includeTags | Complete | architect.config.ts | - - # =========================================================================== - # RULE 1: Include Tag Routes Content - # =========================================================================== - - Rule: Include tag routes content to named documents - - **Invariant:** A pattern or shape with `architect-include:X` appears in - any reference document whose includeTags contains X. The tag is CSV, - so `architect-include:X,Y` routes the item to both document X and - document Y. This is additive -- the item also appears in any document - whose existing selectors (conventionTags, behaviorCategories, - shapeSelectors) would already select it. - - **Rationale:** Content-to-document is a many-to-many relationship. - A type definition may be relevant to an architecture overview, a - configuration guide, and an AI context section. The include tag - expresses this routing at the source, next to the code, without - requiring the document configs to enumerate every item by name. - - **Verified by:** Pattern with include tag appears in matching doc, - CSV include routes to multiple docs, - Include is additive with existing selectors, - Pattern without include tag is unaffected - - @acceptance-criteria @happy-path - Scenario: Pattern with include tag appears in reference doc - Given a pattern with tags: - """ - @architect - @architect-pattern:MyCodec - @architect-include:codec-system - @architect-core - """ - And a reference doc config with includeTags "codec-system" - And behaviorCategories is empty - When the reference codec renders - Then the behavior section includes "MyCodec" - - @acceptance-criteria @happy-path - Scenario: CSV include routes pattern to multiple documents - Given a pattern with tags: - """ - @architect - @architect-pattern:SharedType - @architect-include:codec-system,config-guide - """ - And two reference doc configs: - | Config | includeTags | - | Codec System | codec-system | - | Config Guide | config-guide | - When each reference codec renders - Then "SharedType" appears in both documents - - @acceptance-criteria @happy-path - Scenario: Include is additive with existing selectors - Given a pattern "ExistingBehavior" with category "infra" - And a pattern "IncludedBehavior" with include tag "reference-sample" - And a reference doc config with: - | Field | Value | - | behaviorCategories | infra | - | includeTags | reference-sample | - When the reference codec renders - Then the behavior section includes both "ExistingBehavior" and "IncludedBehavior" - - @acceptance-criteria @edge-case - Scenario: Pattern without include tag is unaffected - Given a pattern "PlainPattern" with category "core" and no include tag - And a reference doc config with includeTags "reference-sample" - And behaviorCategories is empty - When the reference codec renders - Then "PlainPattern" does not appear in the behavior section - - # =========================================================================== - # RULE 2: Include Tag Scopes Diagrams - # =========================================================================== - - Rule: Include tag scopes diagrams (replaces arch-view) - - **Invariant:** DiagramScope.include matches patterns whose `@architect-include` values contain the specified scope value. This is the same field that existed as archView -- renamed for consistency with the general-purpose include tag. Patterns with `@architect-include:pipeline-stages` appear in any DiagramScope with include: pipeline-stages. - - **Rationale:** The experimental arch-view tag was diagram-specific - routing under a misleading name. Renaming to include unifies the - vocabulary: one tag, two consumption points (diagram scoping via - DiagramScope.include, content routing via ReferenceDocConfig.includeTags). - - **Verified by:** Diagram scope with include matches tagged patterns, - Existing diagram configurations work after rename - - @acceptance-criteria @happy-path - Scenario: Diagram scope uses include to select patterns - Given patterns with include tags: - | Pattern | include | - | ConfigFactory | reference-sample | - | DefineConfig | reference-sample | - | PatternScanner | pipeline-stages | - And a diagram scope with include "reference-sample" - When the diagram is rendered - Then it contains nodes for "ConfigFactory" and "DefineConfig" - And it does not contain a node for "PatternScanner" - - @acceptance-criteria @happy-path - Scenario: Pattern in diagram and content via same include tag - Given a pattern "DefineConfig" with include tag "reference-sample" - And a reference doc config with: - | Field | Value | - | includeTags | reference-sample | - | diagramScopes | include: reference-sample | - When the reference codec renders - Then "DefineConfig" appears in the behavior section - And "DefineConfig" appears as a diagram node - - # =========================================================================== - # RULE 3: Shapes Use Include Tag - # =========================================================================== - - Rule: Shapes use include tag for document routing - - **Invariant:** A declaration tagged with both `architect-shape` and `architect-include` has its include values stored on the ExtractedShape. The reference codec uses these values alongside shapeSelectors for shape filtering. A shape with `architect-include:X` appears in any document whose includeTags contains X, regardless of whether the shape matches any shapeSelector. - - **Rationale:** Shape extraction (via `architect-shape`) and document - routing (via `architect-include`) are orthogonal concerns. A shape - must be extracted before it can be routed. The shape tag triggers - extraction; the include tag controls which documents render it. - This separation allows one shape to appear in multiple documents - without needing multiple group values. - - **Verified by:** Shape with include appears in matching doc, - Shape with both group and include works, - Shape without include but with group still works - - @acceptance-criteria @happy-path - Scenario: Shape with include tag appears in reference doc - Given a TypeScript declaration: - """typescript - /** - * @architect-shape - * @architect-include reference-sample - */ - export interface CategoryDefinition { - readonly tag: string; - } - """ - And a reference doc config with includeTags "reference-sample" - And shapeSelectors is empty - When the reference codec renders - Then the API Types section includes "CategoryDefinition" - - @acceptance-criteria @happy-path - Scenario: Shape with both group and include works - Given a TypeScript declaration: - """typescript - /** - * @architect-shape api-types - * @architect-include reference-sample,codec-system - */ - export type SectionBlock = HeadingBlock | TableBlock; - """ - And a reference doc config A with shapeSelectors group "api-types" - And a reference doc config B with includeTags "codec-system" - When each reference codec renders - Then "SectionBlock" appears in both documents - - @acceptance-criteria @edge-case - Scenario: Shape without include but with matching group still works - Given a TypeScript declaration: - """typescript - /** @architect-shape api-types */ - export type RiskLevel = 'low' | 'medium' | 'high'; - """ - And a reference doc config with shapeSelectors group "api-types" - And no includeTags configured - When the reference codec renders - Then the API Types section includes "RiskLevel" - - # =========================================================================== - # RULE 4: Conventions Use Include Tag - # =========================================================================== - - Rule: Conventions use include tag for selective inclusion - - **Invariant:** A decision record or convention pattern with `architect-include:X` appears in a reference document whose includeTags contains X. This allows selecting a single convention rule for a focused document without pulling all conventions matching a broad conventionTag. - - **Rationale:** Convention content is currently selected by - conventionTags, which pulls all decision records tagged with a - given convention value. For showcase documents or focused guides, - this is too coarse. The include tag enables cherry-picking - individual conventions alongside broad tag-based selection. - - **Verified by:** Convention with include appears in matching doc, - Include works alongside conventionTags - - @acceptance-criteria @happy-path - Scenario: Convention with include tag appears in reference doc - Given a decision record with tags: - """ - @architect - @architect-convention:fsm-rules - @architect-include:reference-sample - """ - And a reference doc config with includeTags "reference-sample" - And conventionTags is empty - When the reference codec renders - Then the convention section includes the decision record - - @acceptance-criteria @happy-path - Scenario: Include works alongside conventionTags - Given a decision record "BroadConvention" with convention tag "output-format" - And a decision record "IncludedConvention" with include tag "reference-sample" - And a reference doc config with: - | Field | Value | - | conventionTags | output-format | - | includeTags | reference-sample | - When the reference codec renders - Then both "BroadConvention" and "IncludedConvention" appear in the convention section diff --git a/architect/specs/data-api-architecture-queries.feature b/architect/specs/data-api-architecture-queries.feature deleted file mode 100644 index 2ad46ccd..00000000 --- a/architect/specs/data-api-architecture-queries.feature +++ /dev/null @@ -1,190 +0,0 @@ -@architect -@architect-pattern:DataAPIArchitectureQueries -@architect-status:completed -@architect-unlock-reason:Normalize-deliverable-status-taxonomy -@architect-phase:25b -@architect-product-area:DataAPI -@architect-effort:2d -@architect-priority:high -@architect-depends-on:DataAPIOutputShaping -@architect-business-value:deep-architecture-exploration-for-design-sessions -Feature: Data API Architecture Queries - Deep Architecture Exploration - - **Problem:** - The current `arch` subcommand provides basic queries (roles, context, layer, graph) - but lacks deeper analysis needed for design sessions: pattern neighborhoods (what's - directly connected), cross-context comparison, annotation coverage gaps, and - taxonomy discovery. Agents exploring architecture must make multiple queries and - mentally assemble the picture, wasting context tokens. - - **Solution:** - Extend the `arch` subcommand and add new discovery commands: - 1. `arch neighborhood ` shows 1-hop relationships (direct uses/usedBy) - 2. `arch compare ` shows shared deps and integration points - 3. `arch coverage` reports annotation completeness with gaps - 4. `tags` lists all tags in use with counts - 5. `sources` shows file inventory by type - 6. `unannotated [--path glob]` finds files without the @architect opt-in marker - - **Business Value:** - | Benefit | Impact | - | Pattern neighborhoods | Understand local architecture in one call | - | Coverage gaps | Find unannotated files that need attention | - | Taxonomy discovery | Know what tags and categories are available | - | Cross-context analysis | Compare bounded contexts for integration | - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | Tests | Test Type | - | arch neighborhood handler | complete | src/cli/pattern-graph-cli.ts | Yes | integration | - | arch compare handler | complete | src/cli/pattern-graph-cli.ts | Yes | integration | - | arch coverage analyzer | complete | src/api/coverage-analyzer.ts | Yes | unit | - | tags subcommand | complete | src/cli/pattern-graph-cli.ts | Yes | integration | - | sources subcommand | complete | src/cli/pattern-graph-cli.ts | Yes | integration | - | unannotated subcommand | complete | src/cli/pattern-graph-cli.ts | Yes | integration | - - # ============================================================================ - # RULE 1: Extended Architecture Queries - # ============================================================================ - - Rule: Arch subcommand provides neighborhood and comparison views - - **Invariant:** Architecture queries resolve pattern names to concrete - relationships and file paths, not just abstract names. - - **Rationale:** The current `arch graph ` returns dependency and - relationship names but not the full picture of what surrounds a pattern. - Design sessions need to understand: "If I'm working on X, what else is - directly connected?" and "How do contexts A and B relate?" - - **Neighborhood output:** - | Section | Content | - | Triggered by | Patterns whose `usedBy` includes this pattern | - | Uses | Patterns this calls directly | - | Used by | Patterns that call this directly | - | Same context | Sibling patterns in the same bounded context | - - **Verified by:** Neighborhood view, Cross-context comparison - - @acceptance-criteria @happy-path - Scenario: Pattern neighborhood shows direct connections - Given a pattern "OrderSaga" in the "orders" context - And "OrderSaga" uses "CommandBus" and "EventStore" - And "OrderSaga" is used by "SagaRouter" - When running "pattern-graph-cli arch neighborhood OrderSaga" - Then the output shows "Uses: CommandBus, EventStore" - And the output shows "Used by: SagaRouter" - And the output shows sibling patterns in the "orders" context - - @acceptance-criteria @happy-path - Scenario: Cross-context comparison - Given contexts "orders" and "inventory" with some shared dependencies - When running "pattern-graph-cli arch compare orders inventory" - Then the output shows shared dependencies between contexts - And the output shows unique dependencies per context - And the output identifies integration points - - @acceptance-criteria @validation - Scenario: Neighborhood for nonexistent pattern returns error - Given no pattern named "NonExistent" exists - When running "pattern-graph-cli arch neighborhood NonExistent" - Then the command fails with a pattern-not-found error - And the error message suggests checking the pattern name - - # ============================================================================ - # RULE 2: Architecture Coverage - # ============================================================================ - - Rule: Coverage analysis reports annotation completeness with gaps - - **Invariant:** Coverage reports identify unannotated files that should have - the @architect opt-in marker based on their location and content. - - **Rationale:** Annotation completeness directly impacts the quality of all - generated documentation and API queries. Files without the opt-in marker are - invisible to the pipeline. Coverage gaps mean missing patterns in the - registry, incomplete dependency graphs, and blind spots in architecture views. - - **Coverage output:** - | Metric | Source | - | Annotated files | Files with @architect opt-in | - | Total scannable files | All .ts files in input globs | - | Coverage percentage | annotated / total | - | Missing files | Scannable files without annotations | - | Unused roles/categories | Values defined in taxonomy but not used | - - **Verified by:** Coverage report, Unannotated file discovery - - @acceptance-criteria @happy-path - Scenario: Architecture coverage report - Given 41 annotated files out of 50 scannable files - When running "pattern-graph-cli arch coverage" - Then the output shows "41/50 files annotated (82%)" - And the output lists the 9 unannotated files - And the output shows unused taxonomy values - - @acceptance-criteria @happy-path - Scenario: Find unannotated files with path filter - Given some TypeScript files without the @architect opt-in marker - When running "pattern-graph-cli unannotated --path 'src/generators/**/*.ts'" - Then the output lists only unannotated files matching the glob - And each file shows its location relative to base directory - - @acceptance-criteria @validation - Scenario: Coverage with no scannable files returns zero coverage - Given the input globs match 0 files - When running "pattern-graph-cli arch coverage" - Then the output shows "0/0 files annotated (0%)" - And the unannotated files list is empty - - # ============================================================================ - # RULE 3: Taxonomy Discovery - # ============================================================================ - - Rule: Tags and sources commands provide taxonomy and inventory views - - **Invariant:** All tag values in use are discoverable without reading - configuration files. Source file inventory shows the full scope of - annotated and scanned content. - - **Rationale:** Agents frequently need to know "what categories exist?" - or "how many feature files are there?" without reading taxonomy - configuration. These are meta-queries about the annotation system itself, - essential for writing new annotations correctly and understanding scope. - - **Tags output:** - | Tag | Count | Example Values | - | status | 69 | completed(36), roadmap(30), active(3) | - | category | 41 | core(16), api(13), infra(12) | - - **Sources output:** - | Source Type | Count | Location Pattern | - | TypeScript (annotated) | 47 | src/**/*.ts | - | Gherkin (feature files) | 37 | specs/**/*.feature | - | Stub files | 22 | stubs/**/*.ts | - | Decision files | 13 | decisions/**/*.feature | - - **Verified by:** Tags listing, Sources inventory - - @acceptance-criteria @happy-path - Scenario: List all tags with usage counts - Given patterns with various tags applied - When running "pattern-graph-cli tags" - Then the output lists each tag name with its usage count - And category tags show their value distribution - And status tags show their value distribution - - @acceptance-criteria @happy-path - Scenario: Source file inventory - Given TypeScript, Gherkin, and stub files in the pipeline - When running "pattern-graph-cli sources" - Then the output shows file counts by type - And the output shows location patterns for each type - And the total matches the pipeline scan count - - @acceptance-criteria @validation - Scenario: Tags listing with no patterns returns empty report - Given the pipeline has 0 patterns - When running "pattern-graph-cli tags" - Then the output shows an empty tag report with 0 pattern count - And no tag entries are listed diff --git a/architect/specs/data-api-cli-ergonomics.feature b/architect/specs/data-api-cli-ergonomics.feature deleted file mode 100644 index ba437a12..00000000 --- a/architect/specs/data-api-cli-ergonomics.feature +++ /dev/null @@ -1,145 +0,0 @@ -@architect -@architect-pattern:DataAPICLIErgonomics -@architect-status:completed -@architect-unlock-reason:Final-deliverable-status-update -@architect-phase:25d -@architect-product-area:DataAPI -@architect-effort:2d -@architect-priority:medium -@architect-business-value:fast-interactive-cli-for-repeated-queries -Feature: Data API CLI Ergonomics - Performance and Interactive Mode - - **Problem:** - The pattern-graph-cli CLI runs the full pipeline (scan, extract, transform) on every - invocation, taking 2-5 seconds. During design sessions with 10-20 queries, this - adds up to 1-2 minutes of waiting. There is no way to keep the pipeline loaded - between queries. Per-subcommand help is missing -- `pattern-graph-cli context --help` - does not work. FSM-only queries (like `isValidTransition`) run the full pipeline - even though FSM rules are static. - - **Solution:** - Add performance and ergonomic improvements: - 1. **Pipeline caching** -- Cache PatternGraph to temp file with mtime invalidation - 2. **REPL mode** -- `pattern-graph-cli repl` keeps pipeline loaded for interactive queries - 3. **FSM short-circuit** -- FSM queries skip the scan pipeline entirely - 4. **Per-subcommand help** -- `pattern-graph-cli --help` with examples - 5. **Dry-run mode** -- `--dry-run` shows what would be scanned without running - 6. **Validation summary** -- Include pipeline health in response metadata - - **Business Value:** - | Benefit | Impact | - | Cached queries | 2-5s to <100ms for repeated queries | - | REPL mode | Interactive exploration during sessions | - | FSM short-circuit | Instant transition checks | - | Per-subcommand help | Self-documenting for AI agents | - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | Tests | Test Type | - | PatternGraph cache with mtime invalidation | complete | src/cli/dataset-cache.ts | Yes | unit | - | REPL mode handler | complete | src/cli/repl.ts | Yes | integration | - | FSM short-circuit for static queries | complete | src/cli/pattern-graph-cli.ts | Yes | unit | - | Per-subcommand help system | complete | src/cli/pattern-graph-cli.ts | Yes | integration | - | Dry-run mode | complete | src/cli/pattern-graph-cli.ts | Yes | integration | - | Validation summary in metadata | complete | src/cli/pattern-graph-cli.ts | Yes | unit | - - # ============================================================================ - # RULE 1: Pipeline Caching - # ============================================================================ - - Rule: PatternGraph is cached between invocations with file-change invalidation - - **Invariant:** Cache is automatically invalidated when any source file - (TypeScript or Gherkin) has a modification time newer than the cache. - - **Rationale:** The pipeline (scan -> extract -> transform) runs fresh on every - invocation (~2-5 seconds). Most queries during a session don't need fresh data - -- the source files haven't changed between queries. Caching the PatternGraph - to a temp file with file-modification-time invalidation makes subsequent - queries instant while ensuring staleness is impossible. - - **Verified by:** Cache hit on unchanged files, Cache invalidation on file change - - @acceptance-criteria @happy-path - Scenario: Second query uses cached dataset - Given a previous query has cached the PatternGraph - And no source files have been modified since - When running "pattern-graph-cli status" - Then the query completes in under 200ms - And the response metadata indicates cache hit - - @acceptance-criteria @happy-path - Scenario: Cache invalidated on source file change - Given a cached PatternGraph exists - And a source TypeScript file has been modified - When running "pattern-graph-cli status" - Then the pipeline runs fresh (cache miss) - And the new dataset is cached for subsequent queries - - # ============================================================================ - # RULE 2: REPL Mode - # ============================================================================ - - Rule: REPL mode keeps pipeline loaded for interactive multi-query sessions - - **Invariant:** REPL mode loads the pipeline once and accepts multiple queries - on stdin, with optional tab completion for pattern names and subcommands. - - **Rationale:** Design sessions often involve 10-20 exploratory queries in - sequence (check status, look up pattern, check deps, look up another pattern). - REPL mode eliminates per-query pipeline overhead entirely. - - **Verified by:** REPL multi-query session, REPL with reload - - @acceptance-criteria @happy-path - Scenario: REPL accepts multiple queries - Given REPL mode is started with "pattern-graph-cli repl" - When entering "status" then "pattern OrderSaga" then "dep-tree OrderSaga" - Then each query returns results without pipeline re-initialization - And "quit" exits the REPL - - @acceptance-criteria @happy-path - Scenario: REPL reloads on source change notification - Given REPL mode is running with loaded dataset - When entering "reload" - Then the pipeline is re-run with fresh source files - And subsequent queries use the new dataset - - # ============================================================================ - # RULE 3: Help and Diagnostic Features - # ============================================================================ - - Rule: Per-subcommand help and diagnostic modes aid discoverability - - **Invariant:** Every subcommand supports `--help` with usage, flags, and - examples. Dry-run shows pipeline scope without executing. - - **Rationale:** AI agents read `--help` output to discover available - commands and flags. Without per-subcommand help, agents must read external - documentation. Dry-run mode helps diagnose "why no patterns found?" issues - by showing what would be scanned. - - **Verified by:** Subcommand help, Dry-run output, Validation summary - - @acceptance-criteria @happy-path - Scenario: Per-subcommand help output - When running "pattern-graph-cli context --help" - Then the output shows the context subcommand usage - And the output lists available flags (--session, --related) - And the output includes example commands - - @acceptance-criteria @happy-path - Scenario: Dry-run shows pipeline scope - When running "pattern-graph-cli --dry-run status" - Then the output shows the number of files that would be scanned - And the output shows the config file being used - And the output shows input glob patterns - And no actual pipeline processing occurs - - @acceptance-criteria @happy-path - Scenario: Validation summary in response metadata - Given the pipeline detects 2 dangling references - When running "pattern-graph-cli status" - Then the response metadata includes pattern count - And the response metadata includes dangling reference count - And the response metadata includes any pipeline warnings diff --git a/architect/specs/data-api-context-assembly.feature b/architect/specs/data-api-context-assembly.feature deleted file mode 100644 index 03168463..00000000 --- a/architect/specs/data-api-context-assembly.feature +++ /dev/null @@ -1,281 +0,0 @@ -@architect -@architect-pattern:DataAPIContextAssembly -@architect-status:completed -@architect-unlock-reason:Fix-deliverable-gate-description-preservation-tag-parsing -@architect-phase:25b -@architect-product-area:DataAPI -@architect-effort:3d -@architect-priority:high -@architect-depends-on:DataAPIOutputShaping,DataAPIStubIntegration -@architect-business-value:replace-explore-agents-with-one-command -Feature: Data API Context Assembly - One-Command Session Context - - **Problem:** - Starting a Claude Code design or implementation session requires assembling - 30-100KB of curated, multi-source context from hundreds of annotated files. - Today this requires either manual context compilation by the user or 5-10 - explore agents burning context and time. The Architect pipeline already - has rich data (PatternGraph with archIndex, relationshipIndex, byPhase, - byStatus views) but no command combines data from multiple indexes around - a focal pattern into a compact, session-oriented context bundle. - - **Solution:** - Add context assembly subcommands that answer "what should I read next?" - rather than "what data exists?": - 1. `context ` assembles metadata + spec path + stub paths + - dependency chain + related patterns into ~1.5KB of file paths - 2. `files ` returns only file paths organized by relevance - 3. `dep-tree ` walks dependency chains recursively with status - 4. `overview` gives executive project summary - 5. Session type tailoring via `--session planning|design|implement` - - Implementation readiness checks (`scope-validate`) live in DataAPIDesignSessionSupport. - - **Business Value:** - | Benefit | Impact | - | Replace 5-10 explore agents | One command provides curated context | - | 1.5KB vs 100KB context | 98% reduction in context assembly tokens | - | Session-type tailoring | Right context for the right workflow | - | Dependency chain visibility | Know blocking status before starting | - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | Tests | Test Type | - | ContextBundle type | complete | src/api/context-assembler.ts | Yes | unit | - | Context assembler | complete | src/api/context-assembler.ts | Yes | unit | - | context subcommand | complete | src/cli/pattern-graph-cli.ts | Yes | integration | - | files subcommand | complete | src/cli/pattern-graph-cli.ts | Yes | integration | - | dep-tree subcommand | complete | src/cli/pattern-graph-cli.ts | Yes | integration | - | overview subcommand | complete | src/cli/pattern-graph-cli.ts | Yes | integration | - | Context text renderer | complete | src/api/context-formatter.ts | Yes | unit | - - # ============================================================================ - # RULE 1: Single Pattern Context - # ============================================================================ - - Rule: Context command assembles curated context for a single pattern - - **Invariant:** Given a pattern name, `context` returns everything needed to - start working on that pattern: metadata, file locations, dependency status, - and architecture position -- in ~1.5KB of structured text. - - **Rationale:** This is the core value proposition. The command crosses five - gaps simultaneously: it assembles data from multiple PatternGraph indexes, - shapes it compactly, resolves file paths from pattern names, discovers stubs - by convention, and tailors output by session type. - - **Assembly steps:** - 1. Find pattern in PatternGraph via `getPattern()` - 2. Resolve spec file from `pattern.filePath` - 3. Find stubs via `implementedBy` in relationshipIndex - 4. Walk `dependsOn` chain with status for each dependency - 5. Find consumers via `usedBy` - 6. Get architecture neighborhood from `archIndex.byContext` - 7. Resolve all references to file paths - 8. Format as structured text sections - - **Session type tailoring:** - | Session | Includes | Typical Size | - | planning | Brief + deps + status | ~500 bytes | - | design | Spec + stubs + deps + architecture + consumers | ~1.5KB | - | implement | Spec + stubs + deliverables + FSM + tests | ~1KB | - - **Verified by:** Design session context, Planning session context, Implementation context - - @acceptance-criteria @happy-path - Scenario: Assemble design session context - Given a pattern "AgentLLMIntegration" with dependencies and stubs - When running "pattern-graph-cli context AgentLLMIntegration --session design" - Then the output contains the pattern metadata section - And the output contains the spec file path - And the output contains dependency stubs with target paths - And the output contains consumer specs for outside-in validation - And the output contains the architecture neighborhood - And the output contains the dependency chain with status markers - - @acceptance-criteria @happy-path - Scenario: Assemble planning session context - Given a pattern "AgentLLMIntegration" with dependencies - When running "pattern-graph-cli context AgentLLMIntegration --session planning" - Then the output contains pattern metadata and status - And the output contains the dependency chain with status - And the output does NOT contain stubs or architecture details - And the output is under 500 bytes - - @acceptance-criteria @happy-path - Scenario: Assemble implementation session context - Given a pattern "ProcessGuardLinter" with completed deliverables - When running "pattern-graph-cli context ProcessGuardLinter --session implement" - Then the output contains the spec file path - And the output contains the deliverables checklist with status - And the output contains FSM state and valid transitions - And the output contains test file locations - - @acceptance-criteria @validation - Scenario: Context for nonexistent pattern returns error with suggestion - Given a pattern "AgentLLMIntegration" exists - When running "pattern-graph-cli context NonExistentPattern --session design" - Then the command fails with a pattern-not-found error - And the error message suggests similar pattern names - - # ============================================================================ - # RULE 2: File Reading List - # ============================================================================ - - Rule: Files command returns only file paths organized by relevance - - **Invariant:** `files` returns the most token-efficient output possible -- - just file paths that Claude Code can read directly. - - **Rationale:** Most context tokens are spent reading actual files, not - metadata. The `files` command tells Claude Code *which* files to read, - organized by importance. Claude Code then reads what it needs. This is - more efficient than `context` when the agent already knows the pattern - and just needs the file list. - - **Organization:** - | Section | Contents | - | Primary | Spec file, stub files | - | Dependencies (completed) | Implementation files of completed deps | - | Dependencies (roadmap) | Spec files of incomplete deps | - | Architecture neighbors | Same-context patterns | - - **Verified by:** Files with related patterns, Files without related - - @acceptance-criteria @happy-path - Scenario: File reading list with related patterns - Given a pattern "OrderSaga" with uses and usedBy relationships - When running "pattern-graph-cli files OrderSaga --related" - Then the output lists primary files first - And the output lists completed dependency files - And the output lists architecture neighbor files - And each file path is relative to the base directory - - @acceptance-criteria @happy-path - Scenario: File reading list without related patterns - Given a pattern "OrderSaga" exists - When running "pattern-graph-cli files OrderSaga" - Then the output lists only the primary spec and stub files - And no dependency or neighbor files are included - - @acceptance-criteria @validation - Scenario: Files for pattern with no resolvable paths returns minimal output - Given a pattern "MinimalPattern" with no stubs or dependencies - When running "pattern-graph-cli files MinimalPattern --related" - Then the output lists only the primary spec file - And the completed, roadmap, and neighbor sections are empty - - # ============================================================================ - # RULE 3: Dependency Tree - # ============================================================================ - - Rule: Dep-tree command shows recursive dependency chain with status - - **Invariant:** The dependency tree walks both `dependsOn`/`enables` (planning) - and `uses`/`usedBy` (implementation) relationships with configurable depth. - - **Rationale:** Before starting work on a pattern, agents need to know the - full dependency chain: what must be complete first, what this unblocks, and - where the current pattern sits in the sequence. A tree visualization with - status markers makes blocking relationships immediately visible. - - **Output format:** - ``` - AgentAsBoundedContext (22, completed) - -> AgentBCComponentIsolation (22a, completed) - -> AgentLLMIntegration (22b, roadmap) - -> [*] AgentCommandInfrastructure (22c, roadmap) <- YOU ARE HERE - -> AgentChurnRiskCompletion (22d, roadmap) - ``` - - **Verified by:** Dep-tree with status, Dep-tree with depth limit - - @acceptance-criteria @happy-path - Scenario: Dependency tree with status markers - Given a dependency chain: A (completed) -> B (completed) -> C (roadmap) - When running "pattern-graph-cli dep-tree C --status" - Then the output shows the tree with completion markers - And completed dependencies are marked as such - And the focal pattern is highlighted - - @acceptance-criteria @happy-path - Scenario: Dependency tree with depth limit - Given a deep dependency chain with 5 levels - When running "pattern-graph-cli dep-tree C --depth 2" - Then the output shows at most 2 levels of dependencies - And truncated branches are indicated - - @acceptance-criteria @validation - Scenario: Dependency tree handles circular dependencies safely - Given patterns A depends on B and B depends on A - When running "pattern-graph-cli dep-tree A" - Then the output shows the cycle without infinite recursion - And the visited node is marked to indicate a cycle - - # ============================================================================ - # RULE 4: Multi-Pattern Context - # ============================================================================ - - Rule: Context command supports multiple patterns with merged output - - **Invariant:** Multi-pattern context deduplicates shared dependencies and - highlights overlap between patterns. - - **Rationale:** Design sessions often span multiple related patterns - (e.g., reviewing DS-2 through DS-5 together). Separate `context` calls - would duplicate shared dependencies. Merged context shows the union of - all dependencies with overlap analysis. - - **Verified by:** Multi-pattern context - - @acceptance-criteria @happy-path - Scenario: Multi-pattern context merges dependencies - Given patterns "AgentLLM" and "AgentCommand" sharing dependency "AgentBC" - When running "pattern-graph-cli context AgentLLM AgentCommand --session design" - Then shared dependencies appear once with a "shared" marker - And unique dependencies are listed per pattern - And the combined context is smaller than two separate calls - - @acceptance-criteria @validation - Scenario: Multi-pattern context with one invalid name reports error - Given a pattern "AgentLLM" exists but "InvalidName" does not - When running "pattern-graph-cli context AgentLLM InvalidName --session design" - Then the command fails with a pattern-not-found error for "InvalidName" - And no partial context is returned - - # ============================================================================ - # RULE 5: Executive Overview - # ============================================================================ - - Rule: Overview provides executive project summary - - **Invariant:** `overview` returns project-wide health in one command. - - **Rationale:** Planning sessions start with "where are we?" This command - answers that question without needing to run multiple queries and mentally - aggregate results. Implementation readiness checks for specific patterns - live in DataAPIDesignSessionSupport's `scope-validate` command. - - **Overview output** (uses normalizeStatus display aliases: planned = roadmap + deferred): - | Section | Content | - | Progress | N patterns (X completed, Y active, Z planned) = P% | - | Active phases | Currently in-progress phases with pattern counts | - | Blocking | Patterns that cannot proceed due to incomplete deps | - - **Verified by:** Executive overview - - @acceptance-criteria @happy-path - Scenario: Executive overview - Given 36 completed, 3 active, and 30 planned patterns - When running "pattern-graph-cli overview" - Then the output shows "69 patterns (36 completed, 3 active, 30 planned) = 52%" - And the output lists active phases with counts - And the output shows blocking relationships - - @acceptance-criteria @validation - Scenario: Overview with empty pipeline returns zero-state summary - Given the pipeline has 0 patterns - When running "pattern-graph-cli overview" - Then the output shows "0 patterns (0 completed, 0 active, 0 planned) = 0%" - And the active phases section is empty - And the blocking section is empty diff --git a/architect/specs/data-api-output-shaping.feature b/architect/specs/data-api-output-shaping.feature deleted file mode 100644 index 632083cd..00000000 --- a/architect/specs/data-api-output-shaping.feature +++ /dev/null @@ -1,299 +0,0 @@ -@architect -@architect-pattern:DataAPIOutputShaping -@architect-status:completed -@architect-unlock-reason:All-8-deliverables-implemented-and-verified -@architect-phase:25a -@architect-product-area:DataAPI -@architect-effort:4d -@architect-priority:high -@architect-business-value:compact-output-for-ai-agents -Feature: Data API Output Shaping - Compact Output for AI Agents - - **Problem:** - The PatternGraphAPI CLI returns raw `ExtractedPattern` objects via `JSON.stringify`. - List queries (e.g., `getCurrentWork`) produce ~594KB of JSON because each pattern - includes full `directive` (raw JSDoc AST), `code` (source text), and dozens of - empty/null fields. AI agents waste context tokens parsing verbose output that is - 99% noise. There is no way to request compact summaries, filter fields, or get - counts without downloading the full dataset. - - **Solution:** - Add an output shaping pipeline that transforms raw API responses into compact, - AI-optimized formats: - 1. `summarizePattern()` projects patterns to ~100 bytes (vs ~3.5KB raw) - 2. Global output modifiers: `--names-only`, `--count`, `--fields` - 3. Format control: `--format compact|json` with empty field stripping - 4. `list` subcommand with composable filters (`--status`, `--phase`, `--category`) - 5. `search` subcommand with fuzzy pattern name matching - 6. CLI ergonomics: config file defaults, `-f` shorthand, pnpm banner fix - - **Business Value:** - | Benefit | Impact | - | 594KB to 4KB list output | 99% context reduction for list queries | - | Fuzzy matching | Eliminates agent retry loops on typos | - | Config defaults | No more repeating --input and --features paths | - | Composable filters | One command replaces multiple API method calls | - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | Tests | Test Type | - | summarizePattern() projection | complete | src/api/summarize.ts | Yes | unit | - | Output modifier pipeline | complete | src/cli/output-pipeline.ts | Yes | unit | - | QueryResult envelope wiring | complete | src/cli/pattern-graph-cli.ts | Yes | unit | - | list subcommand | complete | src/cli/pattern-graph-cli.ts | Yes | integration | - | search subcommand | complete | src/cli/pattern-graph-cli.ts | Yes | integration | - | Fuzzy pattern matching | complete | src/api/fuzzy-match.ts | Yes | unit | - | Config file default resolution | complete | src/cli/pattern-graph-cli.ts | Yes | unit | - | pnpm banner fix | complete | package.json | No | N/A | - - # ============================================================================ - # RULE 1: Pattern Summarization - # ============================================================================ - - Rule: List queries return compact pattern summaries by default - - **Invariant:** List-returning API methods produce summaries, not full ExtractedPattern - objects, unless `--full` is explicitly requested. - - **Rationale:** The single biggest usability problem. `getCurrentWork` returns 3 active - patterns at ~3.5KB each = 10.5KB. Summarized: ~300 bytes total. The `directive` field - (raw JSDoc AST) and `code` field (full source) are almost never needed for list queries. - AI agents need name, status, category, phase, and file path -- nothing more. - - **Summary projection fields:** - | Field | Source | Size | - | patternName | pattern.patternName | ~30 chars | - | status | pattern.status | ~8 chars | - | category | pattern.categories | ~15 chars | - | phase | pattern.phase | ~3 chars | - | file | pattern.filePath | ~40 chars | - | source | pattern.source | ~7 chars | - - **Verified by:** List returns summaries, Full flag returns raw patterns, Pattern detail unchanged - - @acceptance-criteria @happy-path - Scenario: List queries return compact summaries - Given patterns exist in the dataset - When running "pattern-graph-cli query getCurrentWork" - Then each pattern in the output contains only summary fields - And the output does not contain "directive" or "code" fields - And total output size is under 1KB for typical results - - @acceptance-criteria @happy-path - Scenario: Full flag returns complete patterns - Given patterns exist in the dataset - When running "pattern-graph-cli query getCurrentWork --full" - Then each pattern contains all ExtractedPattern fields - And the output includes "directive" and "code" fields - - @acceptance-criteria @happy-path - Scenario: Single pattern detail is unaffected - Given a pattern "MyPattern" exists - When running "pattern-graph-cli pattern MyPattern" - Then the output contains full pattern detail - And the output includes deliverables, dependencies, and relationships - - @acceptance-criteria @validation - Scenario: Full flag combined with names-only is rejected - Given patterns exist in the dataset - When running "pattern-graph-cli query getCurrentWork --full --names-only" - Then the command fails with an error about conflicting modifiers - And the error message lists the conflicting flags - - # ============================================================================ - # RULE 2: Output Modifiers - # ============================================================================ - - Rule: Global output modifier flags apply to any list-returning command - - **Invariant:** Output modifiers are composable and apply uniformly across all - list-returning subcommands and query methods. - - **Rationale:** AI agents frequently need just pattern names (for further queries), - just counts (for progress checks), or specific fields (for focused analysis). - These are post-processing transforms that should work with any data source. - - **Modifier flags:** - | Flag | Effect | Example Output | - | --names-only | Array of pattern name strings | ["OrderSaga", "EventStore"] | - | --count | Single integer | 6 | - | --fields name,status | Selected fields only | [{"name":"X","status":"active"}] | - - **Verified by:** Names-only output, Count output, Field selection - - @acceptance-criteria @happy-path - Scenario: Names-only output for list queries - Given 5 patterns exist with status "roadmap" - When running "pattern-graph-cli query getRoadmapItems --names-only" - Then the output is a JSON array of 5 strings - And each string is a pattern name - - @acceptance-criteria @happy-path - Scenario: Count output for list queries - Given 3 active patterns and 5 roadmap patterns - When running "pattern-graph-cli query getCurrentWork --count" - Then the output is the integer 3 - - @acceptance-criteria @happy-path - Scenario: Field selection for list queries - Given patterns exist in the dataset - When running "pattern-graph-cli query getCurrentWork --fields patternName,status,phase" - Then each pattern in the output contains only the requested fields - And no other fields are present - - @acceptance-criteria @validation - Scenario: Invalid field name in field selection is rejected - Given patterns exist in the dataset - When running "pattern-graph-cli query getCurrentWork --fields patternName,nonExistentField" - Then the command fails with an error about invalid field names - And the error message lists valid field names for the current output mode - - # ============================================================================ - # RULE 3: Output Format and Envelope - # ============================================================================ - - Rule: Output format is configurable with typed response envelope - - **Invariant:** All CLI output uses the QueryResult envelope for success/error - discrimination. The compact format strips empty and null fields. - - **Rationale:** The existing `QueryResult` types (`QuerySuccess`, `QueryError`) are - defined in `src/api/types.ts` but not wired into the CLI output. Agents cannot - distinguish success from error without try/catch on JSON parsing. Empty arrays, - null values, and empty strings add noise to every response. - - **Envelope structure:** - | Field | Type | Purpose | - | success | boolean | Discriminator for success/error | - | data | T | The query result | - | metadata | object | Pattern count, timestamp, pipeline health | - | error | string | Error message (only on failure) | - - **Verified by:** Success envelope, Error envelope, Compact format strips nulls - - @acceptance-criteria @happy-path - Scenario: Successful query returns typed envelope - Given patterns exist in the dataset - When running "pattern-graph-cli status" - Then the output JSON has "success" set to true - And the output JSON has a "data" field with the result - And the output JSON has a "metadata" field with pattern count - - @acceptance-criteria @validation - Scenario: Failed query returns error envelope - When running "pattern-graph-cli query nonExistentMethod" - Then the output JSON has "success" set to false - And the output JSON has an "error" field with a message - - @acceptance-criteria @happy-path - Scenario: Compact format strips empty fields - Given a pattern with empty arrays and null values - When running "pattern-graph-cli pattern MyPattern" - Then the output does not contain empty arrays - And the output does not contain null values - And the output does not contain empty strings - - # ============================================================================ - # RULE 4: Filtering and Search - # ============================================================================ - - Rule: List subcommand provides composable filters and fuzzy search - - **Invariant:** The `list` subcommand replaces the need to call specific - `getPatternsByX` methods. Filters are composable via AND logic. - The `query` subcommand remains available for programmatic/raw access. - - **Rationale:** Currently, filtering by status AND category requires calling - `getPatternsByCategory` then manually filtering by status. A single `list` - command with composable filters eliminates multi-step queries. Fuzzy search - reduces agent retry loops when pattern names are approximate. - - **Filter flags:** - | Flag | Filters by | Example | - | --status | FSM status | --status active | - | --phase | Phase number | --phase 22 | - | --category | Category tag | --category projection | - | --source | Source type | --source gherkin | - | --limit N | Max results | --limit 10 | - | --offset N | Skip results | --offset 5 | - - **Verified by:** Single filter, Composed filters, Fuzzy search, Pagination - - @acceptance-criteria @happy-path - Scenario: List with single filter - Given patterns with various statuses and categories - When running "pattern-graph-cli list --status active" - Then only active patterns are returned - And results use the compact summary format - - @acceptance-criteria @happy-path - Scenario: List with composed filters - Given patterns with various statuses and categories - When running "pattern-graph-cli list --status roadmap --category projection" - Then only roadmap patterns in the projection category are returned - - @acceptance-criteria @happy-path - Scenario: Search with fuzzy matching - Given a pattern named "AgentCommandInfrastructure" - When running "pattern-graph-cli search AgentCommand" - Then the result includes "AgentCommandInfrastructure" - And results are ranked by match quality - - @acceptance-criteria @happy-path - Scenario: Pagination with limit and offset - Given 20 roadmap patterns exist - When running "pattern-graph-cli list --status roadmap --limit 5 --offset 10" - Then exactly 5 patterns are returned - And they start from the 11th pattern - - @acceptance-criteria @validation - Scenario: Search with no results returns empty with suggestion - Given patterns exist but none match "zzNonexistent" - When running "pattern-graph-cli search zzNonexistent" - Then the result contains an empty matches array - And the output includes a hint that no patterns matched - - # ============================================================================ - # RULE 5: CLI Ergonomics - # ============================================================================ - - Rule: CLI provides ergonomic defaults and helpful error messages - - **Invariant:** Common operations require minimal flags. Pattern name typos - produce actionable suggestions. Empty results explain why. - - **Rationale:** Every extra flag and every retry loop costs AI agent context - tokens. Config file defaults eliminate repetitive path arguments. Fuzzy matching - with suggestions prevents the common "Pattern not found" → retry → still not found - loop. Empty result hints guide agents toward productive queries. - - **Ergonomic features:** - | Feature | Before | After | - | Config defaults | --input 'src/**/*.ts' --features '...' every time | Read from config file | - | -f shorthand | --features 'specs/*.feature' | -f 'specs/*.feature' | - | pnpm banner | Breaks JSON piping | Clean stdout | - | Did-you-mean | "Pattern not found" (dead end) | "Did you mean: AgentCommandInfrastructure?" | - | Empty hints | [] (no context) | "No active patterns. 3 are roadmap. Try: list --status roadmap" | - - **Verified by:** Config file resolution, Fuzzy suggestions, Empty result hints - - @acceptance-criteria @happy-path - Scenario: Config file provides default input paths - Given a architect.config.ts exists with input and features paths - When running "pattern-graph-cli status" without --input or --features flags - Then the pipeline uses paths from the config file - And the output shows correct pattern counts - - @acceptance-criteria @validation - Scenario: Fuzzy pattern name suggestion on not-found - Given a pattern "AgentCommandInfrastructure" exists - When running "pattern-graph-cli pattern AgentCommand" - Then the error message includes "Did you mean: AgentCommandInfrastructure?" - - @acceptance-criteria @validation - Scenario: Empty result provides contextual hint - Given no patterns have status "active" - And 3 patterns have status "roadmap" - When running "pattern-graph-cli list --status active" - Then the output includes a hint about roadmap patterns - And the hint suggests "Try: list --status roadmap" diff --git a/architect/specs/data-api-platform-integration.feature b/architect/specs/data-api-platform-integration.feature deleted file mode 100644 index c7ee23a8..00000000 --- a/architect/specs/data-api-platform-integration.feature +++ /dev/null @@ -1,216 +0,0 @@ -@architect -@architect-pattern:DataAPIPlatformIntegration -@architect-status:completed -@architect-unlock-reason:Split-into-dedicated-specs -@architect-phase:25d -@architect-product-area:DataAPI -@architect-effort:3d -@architect-priority:medium -@architect-business-value:native-claude-code-integration-and-monorepo-support -Feature: Data API Platform Integration - MCP Server and Monorepo Support - - **Problem:** - The pattern-graph-cli CLI requires subprocess invocation for every query, adding - shell overhead and preventing stateful interaction. Claude Code's native tool - integration mechanism is Model Context Protocol (MCP), which the process API - does not support. Additionally, in the monorepo context, queries must specify - input paths for each package manually -- there is no cross-package view or - package-scoped filtering. - - **Solution:** - Two integration capabilities: - 1. **MCP Server Mode** -- Expose PatternGraphAPI as an MCP server that Claude - Code connects to directly. Eliminates CLI overhead and enables stateful - queries (pipeline loaded once, multiple queries without re-scanning). - 2. **Monorepo Support** -- Cross-package dependency views, package-scoped - filtering, multi-package presets, and per-package coverage reports. - - **Business Value:** - | Benefit | Impact | - | MCP integration | Claude Code calls API as native tool | - | Stateful queries | No re-scanning between calls | - | Cross-package views | Understand monorepo-wide dependencies | - | Package-scoped queries | Focus on specific packages | - - **Superseded:** This spec has been split into focused specs: - - MCPServerIntegration (Phase 46) -- MCP server mode (Rule 1) - - MonorepoSupport (Phase 100) -- Cross-package queries (Rule 3) - - Rule 2 (CLAUDE.md context layer) absorbed into existing ClaudeModuleGeneration - - Rule 4 (git hooks/watch) partially exists in lint-process, watch mode deferred - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | Tests | Test Type | - | MCP server entry point | superseded | src/mcp/server.ts | Yes | integration | - | MCP tool definitions | superseded | src/mcp/tools.ts | Yes | unit | - | MCP session state management | superseded | src/mcp/session.ts | Yes | unit | - | CLAUDE.md context layer generator | superseded | src/generators/claude-md-generator.ts | Yes | unit | - | Cross-package dependency analyzer | superseded | src/api/cross-package.ts | Yes | unit | - | Package-scoped filter flag | superseded | src/cli/pattern-graph-cli.ts | Yes | integration | - | Multi-package config support | superseded | src/config/multi-package.ts | Yes | unit | - | Per-package coverage report | superseded | src/api/coverage-analyzer.ts | Yes | unit | - - # ============================================================================ - # RULE 1: MCP Server Mode - # ============================================================================ - - Rule: PatternGraphAPI is accessible as an MCP server for Claude Code - - **Invariant:** The MCP server exposes all PatternGraphAPI methods as MCP tools - with typed input/output schemas. The pipeline is loaded once on server start - and refreshed on source file changes. - - **Rationale:** MCP is Claude Code's native tool integration protocol. An MCP - server eliminates the CLI subprocess overhead (2-5s per query) and enables - Claude Code to call process queries as naturally as it calls other tools. - Stateful operation means the pipeline loads once and serves many queries. - - **MCP configuration:** - ``` - // .mcp.json or claude_desktop_config.json - { - "mcpServers": { - "architect": { - "command": "npx", - "args": ["tsx", "src/mcp/server.ts", "--input", "src/**/*.ts", ...] - } - } - } - ``` - - **Verified by:** MCP server starts, MCP tool invocation, Auto-refresh on change - - @acceptance-criteria @happy-path - Scenario: MCP server exposes PatternGraphAPI tools - Given the MCP server is started with input globs - When Claude Code requests tool listing - Then all PatternGraphAPI methods appear as MCP tools - And each tool has typed input and output schemas - - @acceptance-criteria @happy-path - Scenario: MCP tool invocation returns structured result - Given the MCP server is running with loaded dataset - When Claude Code invokes the "getCurrentWork" tool - Then the response contains active patterns in summary format - And the response includes metadata (pattern count, cache status) - - @acceptance-criteria @edge-case - Scenario: MCP tool invocation with invalid parameters returns error - Given the MCP server is running with loaded dataset - When Claude Code invokes a tool with invalid parameters - Then the response contains a structured error with code and message - And the MCP server remains operational for subsequent requests - - # ============================================================================ - # RULE 2: CLAUDE.md Context Layer Generation - # ============================================================================ - - Rule: Process state can be auto-generated as CLAUDE.md context sections - - **Invariant:** Generated CLAUDE.md sections are additive layers that provide - pattern metadata, relationships, and reading lists for specific scopes. - - **Rationale:** CLAUDE.md is the primary mechanism for providing persistent - context to Claude Code sessions. Auto-generating CLAUDE.md sections from - process state ensures the context is always fresh and consistent with the - source annotations. This applies the "code-first documentation" principle - to AI context itself. - - **Verified by:** Generate context layer, Context layer is up-to-date - - @acceptance-criteria @happy-path - Scenario: Generate CLAUDE.md context layer for bounded context - Given annotated patterns in the "orders" bounded context - When running "pattern-graph-cli generate-context-layer --context orders" - Then a CLAUDE.md section is generated with pattern metadata - And the section includes relationship summaries - And the section includes a file reading list - - @acceptance-criteria @happy-path - Scenario: Context layer reflects current process state - Given a pattern transitioned from "roadmap" to "active" - When regenerating the context layer - Then the CLAUDE.md section shows the updated status - And the session workflow section reflects the new state - - @acceptance-criteria @edge-case - Scenario: Context layer for bounded context with no annotations - Given a bounded context directory with no @architect annotations - When running "pattern-graph-cli generate-context-layer --context empty-context" - Then the output indicates no patterns found in the context - And the CLAUDE.md section contains a placeholder with discovery guidance - - # ============================================================================ - # RULE 3: Monorepo Cross-Package Queries - # ============================================================================ - - Rule: Cross-package views show dependencies spanning multiple packages - - **Invariant:** Cross-package queries aggregate patterns from multiple - input sources and resolve cross-package relationships. - - **Rationale:** In the monorepo, patterns in `platform-core` are used by - patterns in `platform-bc`, which are used by the example app. Understanding - these cross-package dependencies is essential for release planning and - impact analysis. Currently each package must be queried independently - with separate input globs. - - **Verified by:** Cross-package dependency view, Package-scoped filtering - - @acceptance-criteria @happy-path - Scenario: Cross-package dependency view - Given patterns across "platform-core" and "platform-bc" packages - When running "pattern-graph-cli cross-package" - Then the output shows which packages depend on which patterns - And completed vs roadmap dependencies are distinguished - - @acceptance-criteria @happy-path - Scenario: Package-scoped query filtering - Given patterns from multiple packages in the dataset - When running "pattern-graph-cli list --package platform-core --status active" - Then only patterns from "platform-core" are returned - And the package filter composes with other filters - - @acceptance-criteria @edge-case - Scenario: Query for non-existent package returns empty result - Given patterns from "platform-core" and "platform-bc" packages - When running "pattern-graph-cli list --package non-existent-package" - Then the output is an empty result set - And no error is raised - - # ============================================================================ - # RULE 4: Git Hook and Watch Integration - # ============================================================================ - - Rule: Process validation integrates with git hooks and file watching - - **Invariant:** Pre-commit hooks validate annotation consistency. Watch mode - re-generates docs on source changes. - - **Rationale:** Git hooks catch annotation errors at commit time (e.g., new - `uses` reference to non-existent pattern, invalid `arch-role` value, stub - `@target` to non-existent directory). Watch mode enables live documentation - regeneration during implementation sessions. - - **Verified by:** Pre-commit annotation validation, Watch mode re-generation - - @acceptance-criteria @happy-path - Scenario: Pre-commit validates annotation consistency - Given a staged file adds a uses tag referencing "NonExistentPattern" - When the pre-commit hook runs - Then validation fails with "dangling reference" error - And the error identifies the invalid reference - - @acceptance-criteria @happy-path - Scenario: Watch mode re-generates on file change - Given watch mode is running with "pattern-graph-cli watch --generate architecture" - When a source file is modified - Then the architecture docs are regenerated automatically - And only affected doc sections are updated - - @acceptance-criteria @edge-case - Scenario: Pre-commit on clean commit with no annotation changes - Given staged files contain no @architect annotations - When the pre-commit hook runs - Then validation passes without errors - And no annotation warnings are emitted diff --git a/architect/specs/data-api-session-support.feature b/architect/specs/data-api-session-support.feature deleted file mode 100644 index 39c8a617..00000000 --- a/architect/specs/data-api-session-support.feature +++ /dev/null @@ -1,139 +0,0 @@ -@architect -@architect-pattern:DataAPIDesignSessionSupport -@architect-status:completed -@architect-unlock-reason:Normalize-deliverable-status-taxonomy -@architect-phase:25c -@architect-product-area:DataAPI -@architect-effort:1d -@architect-priority:high -@architect-business-value:automate-session-context-compilation -@architect-depends-on:DataAPIContextAssembly,DataAPIStubIntegration -Feature: Data API Design Session Support - Automated Session Workflows - - **Problem:** - Starting a design or implementation session requires manually compiling - elaborate context prompts. For example, DS-3 (LLM Integration) needs: - - The spec to design against (agent-llm-integration.feature) - - Dependency stubs from DS-1 and DS-2 (action-handler, event-subscription, schema) - - Consumer specs for outside-in validation (churn-risk, admin-frontend) - - Existing infrastructure (CommandOrchestrator, EventBus) - - Dependency chain status and design decisions from prior sessions - - This manual compilation takes 10-15 minutes per session start and is - error-prone (missing dependencies, stale context). Multi-session work - requires handoff documentation that is also manually maintained. - - **Solution:** - Add session workflow commands that automate two critical session moments: - 1. **Pre-flight check:** `scope-validate ` verifies implementation readiness - 2. **Session end:** `handoff [--pattern X]` generates handoff documentation - - Session context assembly (the "session start" moment) lives in DataAPIContextAssembly - via `context --session design|implement|planning`. This spec focuses on - the validation and handoff capabilities that build on top of context assembly. - - **Business Value:** - | Benefit | Impact | - | 10-15 min session start -> 1 command | Eliminates manual context compilation | - | Pre-flight catches blockers early | No wasted sessions on unready patterns | - | Automated handoff | Consistent multi-session state tracking | - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | Tests | Test Type | - | Scope validation logic | complete | src/api/scope-validator.ts | Yes | unit | - | scope-validate subcommand | complete | src/cli/pattern-graph-cli.ts | Yes | integration | - | Handoff document generator | complete | src/api/handoff-generator.ts | Yes | unit | - | handoff subcommand | complete | src/cli/pattern-graph-cli.ts | Yes | integration | - - # ============================================================================ - # RULE 1: Scope Validation - # ============================================================================ - - Rule: Scope-validate checks implementation prerequisites before session start - - **Invariant:** Scope validation surfaces all blocking conditions before - committing to a session, preventing wasted effort on unready patterns. - - **Rationale:** Starting implementation on a pattern with incomplete - dependencies wastes an entire session. Starting a design session without - prior session deliverables means working with incomplete context. Pre-flight - validation catches these issues in seconds rather than discovering them - mid-session. - - **Validation checklist:** - | Check | Required For | Source | - | Dependencies completed | implement | dependsOn chain status | - | Stubs from dependency sessions exist | design | implementedBy lookup | - | Deliverables defined | implement | Background table in spec | - | FSM allows transition to active | implement | isValidTransition() | - | Design decisions recorded | implement | PDR references in stubs | - | Executable specs location set | implement | @executable-specs tag | - - **Verified by:** All checks pass, Dependency blocker detected, FSM blocker detected - - @acceptance-criteria @happy-path - Scenario: All scope validation checks pass - Given a pattern with all prerequisites met - When running "pattern-graph-cli scope-validate MyPattern --type implement" - Then all checklist items show green/passing - And the output indicates "Ready for implementation session" - - @acceptance-criteria @validation - Scenario: Dependency blocker detected - Given a pattern "X" depending on "Y" with status "roadmap" - When running "pattern-graph-cli scope-validate X --type implement" - Then the dependencies check shows "BLOCKED" - And the output identifies "Y (roadmap)" as the blocker - And the output suggests "Complete Y first or change session type to design" - - @acceptance-criteria @validation - Scenario: FSM transition blocker detected - Given a pattern with status "completed" - When running "pattern-graph-cli scope-validate CompletedPattern --type implement" - Then the FSM check shows "BLOCKED" - And the output indicates transition to active is not valid from completed - - # ============================================================================ - # RULE 2: Session Handoff - # ============================================================================ - - Rule: Handoff generates compact session state summary for multi-session work - - **Invariant:** Handoff documentation captures everything the next session - needs to continue work without context loss. - - **Rationale:** Multi-session work (common for design phases spanning DS-1 - through DS-7) requires state transfer between sessions. Without automated - handoff, critical information is lost: what was completed, what's in - progress, what blockers were discovered, and what should happen next. - Manual handoff documentation is inconsistent and often forgotten. - - **Handoff output:** - | Section | Source | - | Session summary | Pattern name, session type, date | - | Completed | Deliverables with status "complete" | - | In progress | Deliverables with status not "complete" and not "pending" | - | Files modified | Git diff file list (if available) | - | Discovered items | @discovered-gap, @discovered-improvement tags | - | Blockers | Incomplete dependencies, open questions | - | Next session priorities | Remaining deliverables, suggested order | - - **Verified by:** Handoff for in-progress pattern, Handoff with discoveries - - @acceptance-criteria @happy-path - Scenario: Generate handoff for in-progress pattern - Given an active pattern with 3 completed and 2 remaining deliverables - When running "pattern-graph-cli handoff --pattern MyPattern" - Then the output shows the session summary - And the output lists 3 completed deliverables - And the output lists 2 remaining deliverables as next priorities - And the output suggests the recommended order - - @acceptance-criteria @happy-path - Scenario: Handoff captures discovered items - Given a pattern with discovery tags in feature file comments - When running "pattern-graph-cli handoff --pattern MyPattern" - Then the output includes discovered gaps - And the output includes discovered improvements - And the output includes discovered learnings diff --git a/architect/specs/data-api-stub-integration.feature b/architect/specs/data-api-stub-integration.feature deleted file mode 100644 index eaca53e6..00000000 --- a/architect/specs/data-api-stub-integration.feature +++ /dev/null @@ -1,206 +0,0 @@ -@architect -@architect-pattern:DataAPIStubIntegration -@architect-status:completed -@architect-unlock-reason:Implementation-complete-all-deliverables-done -@architect-phase:25a -@architect-product-area:DataAPI -@architect-effort:2d -@architect-priority:high -@architect-business-value:unlock-design-session-stub-metadata -Feature: Data API Stub Integration - Unlocking Design Session Data - - **Problem:** - Design sessions produce code stubs in `architect/stubs/` with rich - metadata: `@architect-target` (destination file path), `@architect-since` (design session ID), - `@see` (PDR references), and `AD-N` numbered decisions. But 14 of 22 stubs - lack the @architect opt-in marker, making them invisible to the scanner pipeline. - The 8 stubs that ARE scanned silently drop the target and see annotations because - they are not prefixed with the @architect namespace. - - This means: the richest source of design context (stubs with architectural - decisions, target paths, and session provenance) is invisible to the API. - - **Solution:** - A three-phase integration approach: - 1. **Phase A (Annotation):** Add the @architect opt-in + implements tag to - the 14 non-annotated stubs. This makes them scannable with zero pipeline changes. - 2. **Phase B (Taxonomy):** Register @architect-target and @architect-since - as new taxonomy tags. Rename existing `@target` and `@since` annotations in - all stubs. This gives structured access to stub-specific metadata. - - 3. **Phase C (Commands):** Add query commands: - - `stubs [pattern]` lists design stubs with target paths - - `decisions [pattern]` surfaces PDR references and AD-N items - - `pdr ` finds all patterns referencing a specific PDR - - **Business Value:** - | Benefit | Impact | - | 14 invisible stubs become visible | Full design context available to API | - | Target path tracking | Know where stubs will be implemented | - | Design decision queries | Surface AD-N decisions for review | - | PDR cross-referencing | Find all patterns related to a decision | - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | Tests | Test Type | - | Scan path configuration (pre-existing) | complete | package.json | No | N/A | - | @architect-target taxonomy tag | complete | src/taxonomy/registry-builder.ts | Yes | unit | - | @architect-since taxonomy tag | complete | src/taxonomy/registry-builder.ts | Yes | unit | - | stubs subcommand | complete | src/cli/pattern-graph-cli.ts | Yes | integration | - | decisions subcommand | complete | src/cli/pattern-graph-cli.ts | Yes | integration | - | pdr subcommand | complete | src/cli/pattern-graph-cli.ts | Yes | integration | - | Stub-to-implementation resolver | complete | src/api/stub-resolver.ts | Yes | unit | - - # ============================================================================ - # RULE 1: Stub Annotation for Pipeline Visibility - # ============================================================================ - - Rule: All stubs are visible to the scanner pipeline - - **Invariant:** Every stub file in `architect/stubs/` has `@architect` - opt-in and `@architect-implements` linking it to its parent pattern. - - **Rationale:** The scanner requires `@architect` opt-in marker to include a - file. Without it, stubs are invisible regardless of other annotations. The - `@architect-implements` tag creates the bidirectional link: spec defines the - pattern (via `@architect-pattern`), stub implements it. Per PDR-009, stubs - must NOT use `@architect-pattern` -- that belongs to the feature file. - - **Boundary note:** Phase A (annotating stubs with `@architect` opt-in and - `@architect-implements` tags) is consumer-side work done in each consuming repo. - Package.json scan paths (`-i 'architect/stubs/**/*.ts'`) are already - pre-configured in 15 scripts. This spec covers Phase B: taxonomy tag - registration (@architect-target, @architect-since) and CLI query subcommands. - - **Verified by:** All stubs scanned, Stub metadata extracted - - @acceptance-criteria @happy-path - Scenario: Annotated stubs are discoverable by the scanner - Given stub files with @architect and @architect-implements tags - When running the scanner pipeline with stubs input glob - Then all annotated stubs appear in the PatternGraph - And each stub has an implementsPatterns relationship - - @acceptance-criteria @happy-path - Scenario: Stub target path is extracted as structured field - Given a stub with "@architect-target:platform-core/src/agent/router.ts" - When the stub is scanned and extracted - Then the pattern's targetPath field contains "platform-core/src/agent/router.ts" - And the targetPath is available via PatternGraphAPI queries - - @acceptance-criteria @validation - Scenario: Stub without @architect opt-in is invisible to scanner - Given a stub file without the @architect marker - When running the scanner pipeline with stubs input glob - Then the stub does NOT appear in the PatternGraph - And no error is raised for the missing marker - - # ============================================================================ - # RULE 2: Stubs Subcommand - # ============================================================================ - - Rule: Stubs subcommand lists design stubs with implementation status - - **Invariant:** `stubs` returns stub files with their target paths, design - session origins, and whether the target file already exists. - - **Rationale:** Before implementation, agents need to know: which stubs - exist for a pattern, where they should be moved to, and which have already - been implemented. The stub-to-implementation resolver compares - `@architect-target` paths against actual files to determine status. - - **Output per stub:** - | Field | Source | - | Stub file | Pattern filePath | - | Target | @architect-target value | - | Implemented? | Target file exists? | - | Since | @architect-since (design session ID) | - | Pattern | @architect-implements value | - - **Verified by:** List all stubs, List stubs for pattern, Filter unresolved - - @acceptance-criteria @happy-path - Scenario: List all stubs with implementation status - Given stubs exist for 4 patterns with targets - When running "pattern-graph-cli stubs" - Then the output lists each stub with its target path - And each stub shows whether the target file exists - And stubs are grouped by parent pattern - - @acceptance-criteria @happy-path - Scenario: List stubs for a specific pattern - Given 5 stubs implement "AgentCommandInfrastructure" - When running "pattern-graph-cli stubs AgentCommandInfrastructure" - Then only stubs for that pattern are returned - And each stub shows target, session, and implementation status - - @acceptance-criteria @happy-path - Scenario: Filter unresolved stubs - Given 3 stubs with existing targets and 2 without - When running "pattern-graph-cli stubs --unresolved" - Then only the 2 stubs without existing target files are returned - - @acceptance-criteria @validation - Scenario: Stubs for nonexistent pattern returns empty result - Given no stubs implement "NonExistentPattern" - When running "pattern-graph-cli stubs NonExistentPattern" - Then the result is empty - And the error message suggests checking the pattern name - - # ============================================================================ - # RULE 3: Design Decision Queries - # ============================================================================ - - Rule: Decisions and PDR commands surface design rationale - - **Invariant:** Design decisions (AD-N items) and PDR references from stub - annotations are queryable by pattern name or PDR number. - - **Rationale:** Design sessions produce numbered decisions (AD-1, AD-2, etc.) - and reference PDR decision records (see PDR-012). When reviewing designs - or starting implementation, agents need to find these decisions without - reading every stub file manually. - - **decisions output:** - ``` - Pattern: AgentCommandInfrastructure - Source: DS-4 (stubs/agent-command-routing/) - Decisions: - AD-1: Unified action model (PDR-011) - AD-5: Router maps command types to orchestrator (PDR-012) - PDRs referenced: PDR-011, PDR-012 - ``` - - **pdr output:** - ``` - PDR-012: Agent Command Routing - Referenced by: - AgentCommandInfrastructure (5 stubs) - CommandRouter (spec) - Decision file: decisions/pdr-012-agent-command-routing.feature - ``` - - **Verified by:** Decisions for pattern, PDR cross-reference - - @acceptance-criteria @happy-path - Scenario: Query design decisions for a pattern - Given stubs for "AgentCommandInfrastructure" with AD-N items - When running "pattern-graph-cli decisions AgentCommandInfrastructure" - Then the output lists each AD-N decision with its description - And the output shows referenced PDR numbers - And the output shows the source design session - - @acceptance-criteria @happy-path - Scenario: Cross-reference a PDR number - Given patterns and stubs referencing "PDR-012" - When running "pattern-graph-cli pdr 012" - Then the output lists all patterns referencing PDR-012 - And the output shows the decision feature file location - And the output shows stub count per pattern - - @acceptance-criteria @validation - Scenario: PDR query for nonexistent number returns empty - Given no patterns or stubs reference "PDR-999" - When running "pattern-graph-cli pdr 999" - Then the result indicates no references found - And the output includes "No patterns reference PDR-999" diff --git a/architect/specs/declaration-level-shape-tagging.feature b/architect/specs/declaration-level-shape-tagging.feature deleted file mode 100644 index a5386f17..00000000 --- a/architect/specs/declaration-level-shape-tagging.feature +++ /dev/null @@ -1,391 +0,0 @@ -@architect -@architect-pattern:DeclarationLevelShapeTagging -@architect-status:completed -@architect-unlock-reason:'reference-render-contract-cleanup' -@architect-phase:31 -@architect-effort:3d -@architect-product-area:Annotation -@architect-depends-on:ShapeExtraction,ReferenceDocShowcase -@architect-business-value:enables-focused-shape-extraction-without-whole-file-dumping -@architect-priority:high -Feature: Declaration-Level Shape Tagging - - **Problem:** - The current shape extraction system operates at file granularity. The - the `architect-extract-shapes` tag on a pattern block extracts named declarations - from the entire file, and the reference doc config shapeSelectors field selects - shapes by source selector only. There is no way for a reference document to request - "only RiskLevel and RISK_LEVELS from risk-levels.ts" -- it gets every shape - the file exports. This produces noisy reference documents that include - irrelevant types alongside the focused content the document is trying to - present. - - The reference doc system is designed for composing focused documents from - cherry-picked content: conventionTags filters by tag, behaviorCategories - filters by category, diagramScopes filters by arch metadata. But source - selectors provide the coarse file-level axis with content-level filtering. - - **Solution:** - Introduce a lightweight @architect-shape annotation tag on individual - TypeScript declarations. Each tagged declaration self-identifies as a - documentable shape, optionally belonging to a named group. On the consumer - side, add shapeSelectors to ReferenceDocConfig for fine-grained selection - by name or group. - - This follows how real API doc generators work: they build a symbol graph - from annotated declarations, not from whole-file text dumps. The tag lives - next to the code it describes, so refactoring (rename/move) does not break - extraction. Code remains the single source of truth with one line of - annotation overhead per declaration. - - **Design Decisions:** - - DD-1: Tag format is value (not flag) - The @architect-shape tag works bare (no value) for simple opt-in, but - also accepts an optional group name like @architect-shape api-types. - This enables group-based selection in shapeSelectors without a second - tag. Using format: value means undefined when bare, string when - provided. Registry entry: tag: 'shape', format: 'value', with example - '@architect-shape api-types'. Placed in metadataTags array in - buildRegistry() at src/taxonomy/registry-builder.ts. - - DD-2: Stay on typescript-estree parser (no TS compiler API switch) - The existing extractPrecedingJsDoc() in shape-extractor.ts already finds - JSDoc above declarations by scanning the AST comments array. Checking - that JSDoc text for the @architect-shape tag is a string search on - already-extracted content -- zero parser changes needed. The TS compiler - APIs node.jsDoc property is not available on estree nodes, but the - comment-based approach is equivalent for declaration-level tag detection. - Cross-file resolution via parseAndGenerateServices or ts.createProgram - is deferred to a future pattern when barrel file re-exports become a - problem. - - DD-3: shapeSelectors is the canonical selector surface - shapeSelectors provides three selection modes: by source + names, by - group tag, or by source alone (all tagged shapes from a file). New - configs should use shapeSelectors for all shape selection. - - DD-4: Top-level declarations only in v1 - Only interface, type, enum, function, and const declarations at the - module top level are eligible. No namespace-internal, class-internal, - or function-local declarations. The codebase does not use namespaces - or nested type declarations, so this constraint matches reality. - Const must be identifier-based (const X = ...), no destructuring. - - DD-5: Group stored on ExtractedShape schema - The ExtractedShapeSchema gains an optional group: string field from - the @architect-shape tag value. This enables downstream filtering - by shapeSelectors without re-parsing source files. - - DD-6: ShapeSelector is a structural discriminated union - ShapeSelector is not a tagged union with an explicit kind field. - Discrimination uses structural key presence: - - group key present: group selector (select all shapes with this group) - - source key present, names key present: source+names selector - - source key present, no names key: source-only selector (all tagged - shapes from that source file) - Zod schema uses z.union() with three z.object() variants. The source - field uses the same glob syntax as source selectors (exact path, single - wildcard, or recursive glob). The names field is a readonly string - array of declaration names to include. The group field is a string - matching the @architect-shape tag value. - This lives on ReferenceDocConfig as: - readonly shapeSelectors?: readonly ShapeSelector[] - - DD-7: Tagged non-exported declarations are included - The existing findDeclarations() in shape-extractor.ts discovers all - top-level declarations regardless of export status. When a declaration - has the @architect-shape tag in its JSDoc, it is extracted even if not - exported. This is intentional: the tag is an explicit documentation - opt-in that overrides the export-based filtering used by the - extractAllExportedShapes() auto-discovery mode. A module-internal - type tagged for documentation is a valid use case (documenting - internal architecture in reference docs). - - **Pragmatic Constraints:** - | Constraint | Rationale | - | Top-level declarations only | Codebase convention, avoids namespace recursion | - | 5 declaration kinds | interface, type, enum, function, const -- matches existing shape extractor | - | No cross-file resolution | Deferred to future pattern using parseAndGenerateServices | - | JSDoc must be within MAX_JSDOC_LINE_DISTANCE (3 lines) | Matches existing extractPrecedingJsDoc logic | - | const must be identifier-based | No destructuring support -- rare in type documentation | - | Group names are single tokens | No spaces in tag values (hyphen-separated convention) | - - **Implementation Path:** - | Layer | Change | Effort | - | registry-builder.ts | Add shape tag to metadataTags array | ~5 lines | - | extracted-shape.ts | Add optional group field to ExtractedShapeSchema | ~2 lines | - | shape-extractor.ts | Add discoverTaggedShapes() and extractShapeTag() | ~50 lines | - | doc-extractor.ts | Call discoverTaggedShapes() alongside processExtractShapesTag() | ~15 lines | - | reference.ts | Add ShapeSelectorSchema + shapeSelectors to ReferenceDocConfig | ~20 lines | - | shape-matcher.ts | Add filterShapesBySelectors() function | ~30 lines | - | architect.config.ts | Update showcase config to use shapeSelectors | ~5 lines | - - **Integration Wiring (doc-extractor.ts):** - The existing shape extraction at doc-extractor.ts lines 167-178 handles the `architect-extract-shapes` tag (pattern-level tag, names shapes by name). The new discoverTaggedShapes() is called in addition to that path: after parsing the source file, scan all declarations for the `architect-shape` JSDoc tag and merge any found shapes into the patterns extractedShapes - array. Both paths contribute to the same ExtractedPattern.extractedShapes - field. Deduplication by shape name (existing behavior in shape-matcher.ts - line 86) prevents duplicates when both paths find the same declaration. - - **Explored Alternatives:** - | Alternative | Why not (for v1) | - | TypeScript compiler API (ts.createProgram) | Full type resolution but requires tsconfig, slower, overkill for tag detection | - | ts-morph wrapper | Additional 2MB dependency for nicer API, same capabilities as compiler API | - | parseAndGenerateServices | Zero new deps, same package, but cross-file resolution not needed yet | - | Custom ESLint rule | ESLint infrastructure already has type checker, but rules are for linting not extraction | - | LSP protocol | Designed for IDE interactions, overkill for batch extraction | - | Name filter only (no tag) | shapeNames on config without source-side tag -- works but loses explicitness | - | Tagged union for ShapeSelector | kind field adds noise; structural discrimination is idiomatic for Zod unions | - - **Future Upgrade Path:** - When cross-file resolution is needed (barrel file re-exports in monorepo), - switch shape-extractor.ts from parse() to parseAndGenerateServices() -- - same typescript-eslint/typescript-estree dependency, different function - call. This gives full TypeScript type checker access: resolve re-exports - via checker.getAliasedSymbol(), expand type aliases, follow import chains. - The @architect-shape tag and shapeSelectors config remain unchanged. - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | - | Registry entry for shape tag | Complete | src/taxonomy/registry-builder.ts | - | Group field on ExtractedShapeSchema | Complete | src/validation-schemas/extracted-shape.ts | - | discoverTaggedShapes function | Complete | src/extractor/shape-extractor.ts | - | Wire tagged discovery into doc extractor | Complete | src/extractor/doc-extractor.ts | - | ShapeSelector schema and shapeSelectors on ReferenceDocConfig | Complete | src/renderable/codecs/reference.ts | - | Selector-based filtering in shape matcher | Complete | src/renderable/codecs/shape-matcher.ts | - | Showcase config using declaration-level shapes | Complete | architect.config.ts | - - Rule: Declarations opt in via @architect-shape tag - - **Invariant:** Only declarations with the `architect-shape` tag in their immediately preceding JSDoc are collected as tagged shapes. Declarations without the tag are ignored even if they are exported. The tag value is optional -- bare `architect-shape` opts in without a group, while `architect-shape group-name` assigns the declaration to a named group. Tagged non-exported declarations are included (DD-7). - - **Rationale:** Explicit opt-in prevents over-extraction of internal - helpers. Unlike auto-discovery mode (extract-shapes *) which grabs all - exports, declaration-level tagging gives precise control. This matches - how TypeDoc uses public/internal tags -- the annotation lives next to - the code it describes, surviving refactors without breaking extraction. - - **Verified by:** Tagged declaration is extracted, - Untagged export is ignored, - Group name is captured from tag value, - Bare tag works without group, - Non-exported tagged declaration is extracted - - @acceptance-criteria @happy-path - Scenario: Tagged declaration is extracted as shape - Given a TypeScript source file containing: - """typescript - /** @architect-shape */ - export interface RiskLevel { - readonly name: string; - readonly severity: number; - } - """ - When discoverTaggedShapes runs on the source - Then 1 shape is returned - And the shape has name "RiskLevel" and kind "interface" - - @acceptance-criteria @happy-path - Scenario: Untagged exported declaration is not extracted - Given a TypeScript source file containing: - """typescript - /** Internal helper, not tagged for docs */ - export function normalizeInput(raw: string): string { - return raw.trim().toLowerCase(); - } - - export type InternalState = 'idle' | 'busy'; - """ - When discoverTaggedShapes runs on the source - Then 0 shapes are returned - - @acceptance-criteria @happy-path - Scenario: Group name is captured from tag value - Given a TypeScript source file containing: - """typescript - /** @architect-shape api-types */ - export type RiskLevel = 'low' | 'medium' | 'high' | 'critical'; - """ - When discoverTaggedShapes runs on the source - Then 1 shape is returned - And the shape has name "RiskLevel" and group "api-types" - - @acceptance-criteria @edge-case - Scenario: Bare tag works without group name - Given a TypeScript source file containing: - """typescript - /** @architect-shape */ - export enum Priority { Low, Medium, High } - """ - When discoverTaggedShapes runs on the source - Then 1 shape is returned - And the shape has name "Priority" and no group - - @acceptance-criteria @edge-case - Scenario: Non-exported tagged declaration is extracted - Given a TypeScript source file containing: - """typescript - /** @architect-shape internal-types */ - interface InternalConfig { - readonly maxRetries: number; - } - """ - When discoverTaggedShapes runs on the source - Then 1 shape is returned - And the shape has name "InternalConfig" and kind "interface" - And the shape has exported false - - Rule: Reference doc configs select shapes via shapeSelectors - - **Invariant:** shapeSelectors provides three selection modes: by - source path + specific names (DD-6 source+names variant), by group - tag (DD-6 group variant), or by source path alone (DD-6 source-only - variant). shapeSelectors provides the coarse file-level filter and - optional fine-grained name/group filtering on top. - - **Rationale:** The reference doc system composes focused documents - from cherry-picked content. Every other content axis (conventions, - behaviors, diagrams) has content-level filtering. shapeSelectors - closes the file-level granularity gap with the same explicitness as - conventionTags. - - **Verified by:** Select by source and names, - Select by group, - Select by source alone - - @acceptance-criteria @happy-path - Scenario: Select specific shapes by source and names - Given a PatternGraph with patterns containing these extracted shapes: - | Pattern Source | Shape Name | Group | Kind | - | src/taxonomy/risk-levels.ts | RiskLevel | api-types | type | - | src/taxonomy/risk-levels.ts | RISK_LEVELS | api-types | const | - | src/taxonomy/risk-levels.ts | RiskCalculator | | function | - And a reference doc config with shapeSelectors: - """json - [{ "source": "src/taxonomy/risk-levels.ts", "names": ["RiskLevel", "RISK_LEVELS"] }] - """ - When the shape selector filtering runs - Then 2 shapes are returned: "RiskLevel" and "RISK_LEVELS" - And "RiskCalculator" is not included - - @acceptance-criteria @happy-path - Scenario: Select all shapes in a group - Given a PatternGraph with patterns containing these extracted shapes: - | Pattern Source | Shape Name | Group | Kind | - | src/taxonomy/risk-levels.ts | RiskLevel | api-types | type | - | src/taxonomy/status-values.ts | ProcessStatus | api-types | type | - | src/taxonomy/status-values.ts | StatusHelper | | function | - And a reference doc config with shapeSelectors: - """json - [{ "group": "api-types" }] - """ - When the shape selector filtering runs - Then 2 shapes are returned: "RiskLevel" and "ProcessStatus" - And "StatusHelper" is not included - - @acceptance-criteria @happy-path - Scenario: Select all tagged shapes from a source file - Given a PatternGraph with patterns containing these extracted shapes: - | Pattern Source | Shape Name | Group | Kind | - | src/taxonomy/risk-levels.ts | RiskLevel | api-types | type | - | src/taxonomy/risk-levels.ts | RISK_LEVELS | api-types | const | - | src/taxonomy/risk-levels.ts | RiskCalculator | | function | - | src/taxonomy/status-values.ts | ProcessStatus | api-types | type | - And a reference doc config with shapeSelectors: - """json - [{ "source": "src/taxonomy/risk-levels.ts" }] - """ - When the shape selector filtering runs - Then 3 shapes are returned from risk-levels.ts - And "ProcessStatus" from status-values.ts is not included - - @acceptance-criteria @happy-path - Scenario: Source-only selector returns all matching shapes - Given a PatternGraph with patterns containing extracted shapes - And a reference doc config with shapeSelectors [{"source":"src/taxonomy/*.ts"}] - When the reference codec renders - Then all extracted shapes from matching files appear - - Rule: Discovery uses existing estree parser with JSDoc comment scanning - - **Invariant:** The discoverTaggedShapes function uses the existing - typescript-estree parse() and extractPrecedingJsDoc() approach. It - does not require the TypeScript compiler API, ts-morph, or - parseAndGenerateServices. Tag detection is a regex match on the - JSDoc comment text already extracted by the existing infrastructure. - The tag regex pattern is: /@architect-shape(?:\s+(\S+))?/ - where capture group 1 is the optional group name. - - **Rationale:** The shape extractor already traverses declarations - and extracts their JSDoc. Adding @architect-shape detection is a - string search on content that is already available -- approximately - 15 lines of new logic. Switching parsers would introduce churn with - no benefit for the v1 use case of tag detection on top-level - declarations. - - **Verified by:** All 5 declaration kinds supported, - JSDoc gap enforcement, - Tag with other JSDoc content - - @acceptance-criteria @happy-path - Scenario: All five declaration kinds are discoverable - Given a TypeScript source file containing: - """typescript - /** @architect-shape core-types */ - export interface Config { - readonly name: string; - } - - /** @architect-shape core-types */ - export type Status = 'active' | 'inactive'; - - /** @architect-shape core-types */ - export enum Priority { Low, Medium, High } - - /** @architect-shape core-types */ - export function validate(input: string): boolean { - return input.length > 0; - } - - /** @architect-shape core-types */ - export const MAX_RETRIES: number = 3; - """ - When discoverTaggedShapes runs on the source - Then 5 shapes are returned - And the shapes have kinds "interface", "type", "enum", "function", "const" - And all shapes have group "core-types" - - @acceptance-criteria @edge-case - Scenario: JSDoc with gap larger than MAX_JSDOC_LINE_DISTANCE is not matched - Given a TypeScript source file containing: - """typescript - /** @architect-shape */ - - - // unrelated comment - - - export interface TooFar { - readonly value: string; - } - """ - When discoverTaggedShapes runs on the source - Then 0 shapes are returned - - @acceptance-criteria @edge-case - Scenario: Tag coexists with other JSDoc content - Given a TypeScript source file containing: - """typescript - /** - * Represents risk severity levels. - * - * @architect-shape risk-types - * @see RiskCalculator - */ - export type RiskLevel = 'low' | 'medium' | 'high' | 'critical'; - """ - When discoverTaggedShapes runs on the source - Then 1 shape is returned - And the shape has name "RiskLevel" and group "risk-types" - And the shape JSDoc contains "Represents risk severity levels" diff --git a/architect/specs/docs-consolidation-strategy.feature b/architect/specs/docs-consolidation-strategy.feature deleted file mode 100644 index fec57b4c..00000000 --- a/architect/specs/docs-consolidation-strategy.feature +++ /dev/null @@ -1,186 +0,0 @@ -@architect -@architect-pattern:DocsConsolidationStrategy -@architect-status:completed -@architect-unlock-reason:Retroactive-completion -@architect-phase:35 -@architect-effort:4w -@architect-product-area:Generation -@architect-depends-on:CodecDrivenReferenceGeneration -@architect-business-value:right-size-all-14-manual-docs-via-generation-relocation-and-audience-alignment -@architect-priority:high -Feature: Documentation Consolidation Strategy - - **Problem:** - 14 manually-maintained docs (~5,400 lines in `docs/`) duplicate information that - already exists in annotated source code and generated reference documents. Code - changes require updating both source annotations and manual docs, creating - maintenance burden and inevitable drift. - - **Solution:** - A 13-phase consolidation that replaces manual doc sections with generated equivalents - using convention tags, reference doc configs, product area absorption, and the - preamble capability. Each phase validates that a generated equivalent exists or - creates one, then replaces the manual content with a pointer to the generated output. - - **Why It Matters:** - | Benefit | How | - | Single source of truth | Manual docs cannot drift from code when generated from annotations | - | Reduced maintenance | ~2,400 fewer manual lines to maintain across 13 phases | - | Consistent quality | Generated docs always reflect current annotation state | - | AI context accuracy | Compact claude-md versions stay current automatically | - | Incremental delivery | Each phase is independently deliverable as a single PR | - - **Scope:** - | Document | Lines | Disposition | - | ARCHITECTURE.md | 1,287 | Phases 2 + 4: codec listings extracted, remaining sections decomposed to ~320 lines | - | PROCESS-GUARD.md | 341 | Phase 3: enhanced ValidationRulesCodec | - | TAXONOMY.md | 105 | Phase 1: redirect to generated taxonomy output | - | ANNOTATION-GUIDE.md | 268 | Phase 5: trim 30 lines of duplicated tag reference | - | CONFIGURATION.md | 357 | Phase 5: trim 67 lines of duplicated preset detail | - | INDEX.md | 354 | Phase 6: update navigation for hybrid manual+generated structure | - | METHODOLOGY.md | 238 | Keep: philosophy and core thesis | - | SESSION-GUIDES.md | 389 | Phase 39: retained as public reference; CLAUDE.md session section generated from annotated behavior specs | - | GHERKIN-PATTERNS.md | 515 | Phase 41: trim to ~250 lines, Step Linting moves to VALIDATION.md | - | CLI.md | 507 | Phase 43: keep prose, generate 3 reference tables from CLI schema | - | PUBLISHING.md | 144 | Phase 40: relocate to MAINTAINERS.md at repo root | - | README.md | ~504 | Phase 42: trim to ~150 lines, move pitch content to website | - | docs-generated/ structure | n/a | Phase 37: consolidate to docs-live/ as single output directory | - | Generated doc quality | n/a | Phase 38: fix REFERENCE-SAMPLE duplication, enrich Generation compact, add TOC | - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | Tests | Test Type | - | Preamble capability on ReferenceDocConfig | complete | src/renderable/codecs/reference.ts | Yes | unit | - | Phase 1 - Taxonomy consolidation | complete | docs/TAXONOMY.md | No | n/a | - | Phase 2 - Codec listings extraction | complete | architect.config.ts, src/renderable/codecs/*.ts | Yes | integration | - | Phase 3 - Process Guard consolidation | complete | src/renderable/codecs/validation-rules.ts | Yes | integration | - | Phase 4 - Architecture decomposition | complete | docs/ARCHITECTURE.md | Yes | integration | - | Phase 5 - Guide trimming | complete | docs/ANNOTATION-GUIDE.md, docs/CONFIGURATION.md | No | n/a | - | Phase 6 - Index navigation update | complete | docs-live/INDEX.md, docs/INDEX.md | No | n/a | - | Phase 37 - docs-live/ directory consolidation | complete | architect.config.ts | Yes | integration | - | Phase 38 - Generated doc quality improvements | complete | src/renderable/codecs/reference.ts | Yes | integration | - | Phase 39 - Session workflow CLAUDE.md module generation | complete | architect/specs/, _claude-md/workflow/ | No | n/a | - | Phase 40 - PUBLISHING.md relocation to MAINTAINERS.md | complete | docs/PUBLISHING.md | No | n/a | - | Phase 41 - GHERKIN-PATTERNS.md restructure | complete | docs/GHERKIN-PATTERNS.md, docs/VALIDATION.md | No | n/a | - | Phase 42 - README.md rationalization | complete | README.md | No | n/a | - | Phase 43 - CLI.md hybrid generation | complete | docs/CLI.md, src/cli/ | Yes | integration | - | Promote architecture generator from preview to docs:all | complete | package.json, architect.config.ts | No | n/a | - | Promote changelog generator from preview to docs:all | complete | package.json, architect.config.ts | No | n/a | - - Rule: Convention tags are the primary consolidation mechanism - - **Invariant:** Each consolidation phase follows the same pattern: register a - convention tag value in `src/taxonomy/conventions.ts`, annotate source files with - `@architect-convention` tags using structured JSDoc, add a `ReferenceDocConfig` - entry in `architect.config.ts`, and replace the manual doc section with a - pointer to the generated reference document. - - **Rationale:** Convention-tagged annotations are the only sustainable way to keep - docs in sync with implementation. The reference codec (`createReferenceCodec`) - already handles the 4-layer composition so each phase only needs annotation work - and config — no new codec infrastructure required. - - **Verified by:** Convention tag produces generated reference, - Phase 2 demonstrates the pattern end-to-end - - @acceptance-criteria @happy-path - Scenario: Convention tag produces a generated reference document - Given source files annotated with a convention tag value - And a ReferenceDocConfig entry matching that convention tag - When the reference codec generates output - Then a detailed docs-live/ file and a compact _claude-md/ file are produced - And both contain the convention content extracted from source JSDoc - - Rule: Preamble preserves editorial context in generated docs - - **Invariant:** `ReferenceDocConfig.preamble` accepts `readonly SectionBlock[]` - that are prepended before all generated content. Preamble sections appear in both - detailed and summary (claude-md) outputs, followed by a separator. A config - without preamble produces no extra separator or empty sections. - - **Rationale:** Not all documentation content can be extracted from code annotations. - Introductory prose, cross-cutting context, and reading guides require human - authorship. The preamble provides a designated place for this content within the - generated document structure, avoiding a separate hand-maintained file. - - **Verified by:** Preamble appears in both detail levels, - Empty preamble produces no artifacts - - @acceptance-criteria @happy-path - Scenario: Preamble sections appear before generated content - Given a ReferenceDocConfig with preamble containing heading and paragraph blocks - When the reference codec generates at both detail levels - Then preamble sections appear first in both outputs - And a separator follows the preamble before generated content - - Rule: Each consolidation phase is independently deliverable - - **Invariant:** Each phase can be implemented and validated independently. A phase - is complete when: the manual doc section has been replaced with a pointer to the - generated equivalent, `pnpm docs:all` produces the generated output without errors, - and the generated content covers the replaced manual content. No phase requires - another uncompleted phase to function. - - **Rationale:** Independent phases allow incremental consolidation without blocking - on the full initiative. Each merged PR reduces manual maintenance immediately. - Phase ordering in the plan is a suggested sequence (simplest first), not a - dependency chain. - - **Verified by:** Phases have no inter-dependencies, - Each phase validates independently - - @acceptance-criteria @happy-path - Scenario: Completed phase validates independently - Given Phase 2 (codec listings) is complete - And Phase 1 (taxonomy) is not started - When running documentation generation - Then Phase 2 generated output is correct - And no errors relate to incomplete phases - - Rule: Manual docs retain editorial and tutorial content - - **Invariant:** Documents containing philosophy (METHODOLOGY.md) remain fully manual - with no generated equivalent (~238 lines). Documents that were originally manual but - now have generated equivalents or have been restructured (SESSION-GUIDES.md, - GHERKIN-PATTERNS.md, CLI.md) retain their editorial content as preamble - within generated outputs. PUBLISHING.md was relocated to MAINTAINERS.md at the - repository root. - - **Rationale:** The consolidation targets sections most likely to drift when code - changes: reference tables, codec listings, validation rules, API types. Editorial - content changes at a different cadence and requires human judgment to update. - Forcing this into annotations would produce worse documentation. Documents that - transitioned to hybrid generation preserve their editorial voice via preamble - while keeping reference content in sync with source annotations. - - **Verified by:** METHODOLOGY.md has no generated equivalent, - Consolidated docs preserve information completeness - - @acceptance-criteria @happy-path - Scenario: Fully manual documents have no generated equivalent - Given METHODOLOGY.md as the retained fully-manual document - Then no ReferenceDocConfig exists targeting its content - And its sections do not duplicate any generated output - - Rule: Audience alignment determines document location - - **Invariant:** Each document lives in the location matching its primary audience: - `docs/` (deployed to libar.dev) for content that serves package users and developers; - repo root for GitHub-visible metadata (CONTRIBUTING.md, SECURITY.md, MAINTAINERS.md); - CLAUDE.md for AI session context. A document appearing in docs/ must be useful to - a developer or user visiting the website — maintainer-only operational procedures - (npm publishing workflow, GitHub Actions setup) belong at the repo root. - - **Rationale:** The audit found PUBLISHING.md (maintainer-only) in docs/ alongside - user-facing guides. SESSION-GUIDES.md (AI session procedures) duplicates CLAUDE.md - with 95% overlap. Audience mismatches increase website noise for users and - create drift risk when the same content lives in two locations. - - **Verified by:** No maintainer-only content in docs/, - No AI-session content duplicated between docs/ and CLAUDE.md - - @acceptance-criteria @happy-path - Scenario: Maintainer content does not appear in website docs - Given the docs/ directory after Phase 40 (PublishingRelocation) - Then no file in docs/ contains npm publishing or GitHub Actions workflow instructions - And those instructions exist in MAINTAINERS.md at the repo root diff --git a/architect/specs/docs-live-consolidation.feature b/architect/specs/docs-live-consolidation.feature deleted file mode 100644 index 209b404e..00000000 --- a/architect/specs/docs-live-consolidation.feature +++ /dev/null @@ -1,95 +0,0 @@ -@architect -@architect-pattern:DocsLiveConsolidation -@architect-status:completed -@architect-phase:37 -@architect-effort:0.5d -@architect-product-area:Generation -@architect-depends-on:DocsConsolidationStrategy -@architect-business-value:single-output-directory-for-all-website-published-and-claude-readable-content -@architect-priority:high -@architect-unlock-reason:Move-business-rules-taxonomy-to-docs-live -Feature: Docs Live Directory Consolidation - - **Problem:** - `docs-generated/` mixes production reference documents (ARCHITECTURE-CODECS.md, - ARCHITECTURE-TYPES.md at 19 KB and 14 KB) with intermediate build artifacts - (business-rules/, taxonomy/). The `_claude-md/architecture/` compact context - files live in `docs-generated/` while the equivalent product-area compacts live - in `docs-live/`. Website visitors and Claude agents have no single location for - all generated reference content — they must know which directory holds which type. - - **Solution:** - Establish `docs-live/` as the single output directory for all website-published - and Claude-readable content. Move reference docs to `docs-live/reference/` and - architecture compact files to `docs-live/_claude-md/architecture/` by updating - output directory configs in `architect.config.ts`. - After consolidation, `docs-generated/` contains no production artifacts — all generated reference content lives in `docs-live/`. - - **Why It Matters:** - | Benefit | How | - | Clear contract | One directory (docs-live/) for all generated reference content | - | No missed content | Claude sessions directed to docs-live/ find all compacts | - | Simpler gitignore | docs-generated/ can be fully ignored; docs-live/ is committed | - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | Tests | Test Type | - | Reference docs output → docs-live/reference/ | complete | architect.config.ts | Yes | integration | - | Architecture _claude-md/ → docs-live/_claude-md/architecture/ | complete | architect.config.ts | Yes | integration | - | Remove root-level compact duplicates from docs-generated/ | complete | architect.config.ts | No | n/a | - | Update .gitignore: docs-generated/ ignored, docs-live/ committed | complete | .gitignore | No | n/a | - - Rule: docs-live/ is the single directory for website-published content - - **Invariant:** Every file appearing on `libar.dev` or referenced by CLAUDE.md - comes from `docs-live/`. No production reference document is published from - `docs-generated/`. The `docs-generated/` directory contains no production reference - content after `docs:all` runs. Business-rules, taxonomy, and - validation-rules output to `docs-live/` alongside other reference docs. - - **Rationale:** DD-1: Splitting production output across two directories creates - ambiguity about where authoritative content lives. Website configuration, CLAUDE.md - path references, and team navigation all benefit from a single source directory. - `docs-generated/` name signals "build cache", not "publishable output". - - **Verified by:** All reference docs accessible from docs-live/, - docs-generated/ contains no website-published files - - @acceptance-criteria @happy-path - Scenario: Reference docs are generated into docs-live/reference/ - Given ARCHITECTURE-CODECS.md and ARCHITECTURE-TYPES.md configured with docs-live/reference/ output - When pnpm docs:all runs successfully - Then docs-live/reference/ARCHITECTURE-CODECS.md exists - And docs-live/reference/ARCHITECTURE-TYPES.md exists - And docs-generated/ contains no reference document .md files - - Rule: Architecture reference compacts generate under docs-live/_claude-md/ - - **Invariant:** Architecture reference summary files live under - `docs-live/_claude-md/architecture/`. Architecture-scoped compacts (architecture-codecs, - architecture-types) move from `docs-generated/_claude-md/architecture/` to - `docs-live/_claude-md/architecture/`. This consolidation does not affect the - separate claude-modules output at the repository root `_claude-md/`. - - **Rationale:** DD-2: `_claude-md/` compact versions are the Claude consumption - contract — agents read compacts, not full product area docs. Having compacts - split across two directories (docs-generated/ and docs-live/) means Claude - sessions following "read from docs-live/" miss the architecture compacts entirely. - - **Verified by:** All compact files under docs-live/_claude-md/, - No _claude-md/ files remain under docs-generated/ - - @acceptance-criteria @happy-path - Scenario: Architecture compact files output to docs-live/_claude-md/architecture/ - Given reference doc configs with claudeMdSection: architecture - When pnpm docs:all runs - Then docs-live/_claude-md/architecture/architecture-codecs.md exists - And docs-live/_claude-md/architecture/architecture-types.md exists - And docs-generated/_claude-md/ directory does not exist - - @acceptance-criteria @validation - Scenario: docs-generated/ contains no Markdown artifacts after standard generation - Given consolidation config changes applied - When pnpm docs:all runs - Then docs-generated/ contains no .md files - And all business-rules, taxonomy, and validation-rules output is in docs-live/ diff --git a/architect/specs/enhanced-index-generation.feature b/architect/specs/enhanced-index-generation.feature deleted file mode 100644 index df9df176..00000000 --- a/architect/specs/enhanced-index-generation.feature +++ /dev/null @@ -1,235 +0,0 @@ -@architect -@architect-pattern:EnhancedIndexGeneration -@architect-status:completed -@architect-unlock-reason:WP-2-implementation-complete -@architect-phase:35 -@architect-effort:2w -@architect-product-area:Generation -@architect-depends-on:DocsConsolidationStrategy -@architect-business-value:replaces-354-line-manual-INDEX-md-with-auto-generated-navigation-hub-combining-statistics-and-editorial-reading-paths -@architect-priority:medium -Feature: Enhanced Index Generation - - **Problem:** - `docs/INDEX.md` (354 lines) is a manually maintained navigation hub with audience-based - reading orders, per-document detailed TOC, document roles matrix, quick navigation - table, and key concepts glossary. The auto-generated `docs-live/INDEX.md` (112 lines) - is a simple file listing with regeneration commands. It lacks audience navigation, - document role context, pattern statistics, and phase progress summaries. When documents - are added, renamed, or restructured, the manual index drifts from the actual doc set. - - **Solution:** - Create an `IndexCodec` that generates a comprehensive navigation hub by composing - auto-generated statistics from PatternGraph pre-computed views with editorial - navigation content via the preamble mechanism. The codec produces document listings, - pattern counts per product area, and phase progress from `byCategory`, `byPhase`, - `byProductArea`, and `byStatus` views. Audience reading paths, the document roles - matrix, and the quick finder table use `ReferenceDocConfig.preamble` as manually - authored `SectionBlock[]`. The generated output replaces both `docs/INDEX.md` and - `docs-live/INDEX.md` with a single unified navigation document. - - **Why It Matters:** - | Benefit | How | - | Single navigation hub | Unifies manual docs/ and generated docs-live/ listings in one document | - | Zero-drift statistics | Pattern counts, phase progress, product area coverage regenerated from PatternGraph | - | Audience paths preserved | Editorial reading orders carried via preamble, not duplicated manually | - | Document roles matrix | Audience-to-document mapping maintained in config, rendered in output | - | Closes Phase 6 | Completes DocsConsolidationStrategy Phase 6 (Index navigation update, pending) | - - **Scope:** - | Content Type | Auto-generatable? | Source | - | Product area and generated doc listing | Yes | Static documentEntries config plus PatternGraph views | - | Pattern statistics per area | Yes | dataset.byProductArea view | - | Phase progress summary | Yes | dataset.byStatus plus dataset.byPhase | - | Audience reading paths (New User, Developer, Team Lead) | No | Preamble SectionBlock[] | - | Document roles matrix (Audience x Document x Focus) | No | Preamble SectionBlock[] | - | Quick finder table (If you want X, read Y) | No | Preamble SectionBlock[] | - | Key concepts glossary | Partially | Could derive from pattern metadata or use preamble | - | Per-document section inventory with line ranges | Partially | Would need markdown AST parsing | - - **Design Questions (for design session):** - | Question | Options | Recommendation | - | Create new IndexCodec or extend existing index generator? | (A) New IndexCodec, (B) Extend docs-live/INDEX.md generator | (A) New codec -- current generator is a simple file lister with no PatternGraph access | - | How to merge manual and generated doc listings? | (A) Unified table, (B) Separate sections | (A) Unified -- users should not need to know which docs are manual vs generated | - | Should audience paths be preamble or a new annotation type? | (A) Preamble, (B) New annotation | (A) Preamble -- reading orders are editorial judgment, not code-derivable | - | Can key concepts be derived from pattern metadata? | (A) Yes from descriptions, (B) No, use preamble | (B) Preamble -- pattern descriptions are too granular for a glossary | - | How to handle hybrid docs/ and docs-live/ structure? | (A) Single merged listing, (B) Two sections with cross-links | (A) Merged -- audience sees one doc set, not two directories | - - **Design Session Findings (2026-03-06):** - | Finding | Impact | Resolution | - | DD-1: New IndexCodec registered in CodecRegistry as document type index | Enables PatternGraph access via standard codec.decode(dataset) pipeline and free integration with generateDocument, generateAllDocuments, CodecOptions | Create createIndexCodec() factory following OverviewCodec pattern, register in CodecRegistry and DOCUMENT_TYPES | - | DD-2: Document entries configured statically, not via filesystem discovery | Codec remains pure (no I/O), deterministic, testable. Config updated alongside document changes | IndexCodecOptions.documentEntries: readonly DocumentEntry[] with title, path, description, audience, topic | - | DD-3: Audience reading paths are full preamble SectionBlock arrays | Reading order is editorial judgment -- no annotation can express pedagogical sequencing. Most-cited navigation aid preserved | IndexCodecOptions.preamble contains READING_ORDER_SECTIONS with 3 audience profiles | - | DD-4: Key concepts glossary uses preamble, not annotation extraction | Pattern descriptions too granular for reader-friendly glossary. Future @architect-glossary annotation could replace this | KEY_CONCEPTS_SECTIONS in preamble with 6 core concept definitions | - | DD-5: Standalone IndexCodec, NOT a ReferenceDocConfig entry | ReferenceDocConfig 4-layer composition (conventions, diagrams, shapes, behaviors) does not apply to navigation documents. Index has no convention tags, scoped diagrams, shapes, or behavior categories | IndexCodec registered directly in CodecRegistry. Reuses preamble pattern from ReferenceDocConfig without type coupling | - | docs-live/INDEX.md is a static file, not code-generated | No existing generator to extend or replace. The current file was manually authored | New codec produces INDEX.md as its output, replacing the static file entirely | - | Section ordering: preamble first, statistics second | Reading paths and quick finder are highest-value navigation. Statistics are supplementary context | Matches existing manual INDEX.md structure. Preamble appears before auto-generated sections | - | computeStatusCounts and completionPercentage utilities already exist | No new utility code needed for statistics sections | Import from src/renderable/utils.ts, same as buildProductAreaIndex in reference-generators.ts | - - **Design Stubs:** - | Stub | Location | Purpose | - | index-codec-options.ts | architect/stubs/enhanced-index-generation/index-codec-options.ts | IndexCodecOptions interface, DocumentEntry type, section visibility toggles, DD-1 and DD-5 rationale | - | index-codec.ts | architect/stubs/enhanced-index-generation/index-codec.ts | createIndexCodec() factory, buildIndexDocument pipeline, section builder signatures, DD-1 rationale | - | index-preamble-config.ts | architect/stubs/enhanced-index-generation/index-preamble-config.ts | Example preamble SectionBlock arrays, document entries, DD-2 DD-3 DD-4 rationale | - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | Tests | Test Type | - | Create IndexCodec with PatternGraph-driven statistics | complete | src/renderable/codecs/index-codec.ts | Yes | unit | - | Register IndexCodec in codec registry and generator config | complete | src/renderable/generate.ts | Yes | integration | - | Preamble content for audience paths, document roles, quick finder | complete | docs-sources/index-navigation.md | No | n/a | - | CodecOptions entry for enhanced INDEX.md | complete | architect.config.ts | Yes | integration | - | Replace docs/INDEX.md with pointer to generated output | complete | docs/INDEX.md | No | n/a | - | Behavior spec with scenarios for index generation | superseded | n/a | No | n/a | - - Rule: IndexCodec composes generated statistics with editorial navigation - - **Invariant:** The IndexCodec generates document listings and pattern statistics - from PatternGraph pre-computed views (`byCategory`, `byPhase`, `byProductArea`, - `byStatus`), while audience reading paths, the document roles matrix, and the - quick finder table use the `ReferenceDocConfig.preamble` mechanism as manually - authored `SectionBlock[]`. The codec does not hardcode document metadata -- all - statistics are derived from the dataset at generation time. Editorial content - changes at authorial cadence via config edits, not code changes. - - **Rationale:** Approximately 40% of INDEX.md content (product area lists, file - inventories, pattern statistics, phase progress) is directly derivable from - PatternGraph views and drifts when patterns change status or new patterns are - added. The remaining 60% (audience paths, document roles, quick finder) requires - human editorial judgment about which documents serve which readers. The preamble - mechanism cleanly separates these two content types within a single generated - output, as proven by CodecDrivenReferenceGeneration and DocsConsolidationStrategy - Phase 2. - - **Verified by:** Codec produces statistics from PatternGraph, - Preamble editorial content appears before generated sections - - @acceptance-criteria @happy-path - Scenario: IndexCodec generates pattern statistics from PatternGraph - Given a PatternGraph with patterns across 7 product areas - And patterns have statuses including roadmap, active, and completed - When the IndexCodec generates the index document - Then a product area statistics table shows pattern counts per area - And a phase progress summary shows counts by status - And all statistics match the PatternGraph view contents - - @acceptance-criteria @validation - Scenario: Statistics update when patterns change status - Given a PatternGraph where 3 patterns moved from roadmap to completed - When the IndexCodec regenerates the index document - Then the phase progress summary reflects the updated status counts - And product area statistics reflect the new completed count - - Rule: Audience reading paths are first-class sections - - **Invariant:** Three audience profiles exist in the generated index: New User, - Developer/AI, and Team Lead/CI. Each profile has a curated reading order that - lists documents in recommended sequence with a one-line description of what each - document provides for that audience. Reading paths appear prominently after the - quick navigation table and before the auto-generated statistics sections. The - reading paths are sourced from preamble, not derived from pattern metadata. - - **Rationale:** The manual INDEX.md reading orders are consistently cited as the - most useful navigation aid by developers onboarding to the project. A flat - alphabetical file listing (as in the current docs-live/INDEX.md) forces readers - to guess which documents are relevant to their role. Audience-specific paths - reduce time-to-relevance from minutes of scanning to seconds of following a - curated sequence. This content is inherently editorial -- no annotation can - express "read this third because it builds on concepts from document two." - - **Verified by:** Three audience reading paths appear in output, - Reading paths precede auto-generated statistics - - @acceptance-criteria @happy-path - Scenario: Generated index contains three audience reading paths - Given an IndexCodec with preamble containing three audience profiles - And the profiles are New User and Developer/AI and Team Lead/CI - When the IndexCodec generates the index document - Then three reading order sections appear with curated document sequences - And each reading order lists documents with one-line descriptions - And reading paths appear before auto-generated statistics sections - - @acceptance-criteria @validation - Scenario: Reading paths are not derived from pattern metadata - Given an IndexCodec with audience paths defined in preamble - When inspecting the codec source code - Then no audience path content is computed from PatternGraph - And all reading order content originates from the preamble SectionBlock array - - Rule: Index unifies manual and generated doc listings - - **Invariant:** The generated index covers both `docs/` (manual reference documents) - and `docs-live/` (generated reference documents) in a single unified navigation - structure. Documents are organized by topic or audience, not by source directory. - The reader does not need to know whether a document is manually authored or - auto-generated. Each document entry includes its title, a brief description, and - its primary audience. The directory source (docs/ or docs-live/) appears only in - the link path, not as a section heading or organizational axis. - - **Rationale:** The current documentation set splits across two directories for - implementation reasons (manual vs generated), but this split is meaningless to - readers. A developer looking for architecture documentation should find one entry, - not separate entries under "Manual Docs" and "Generated Docs" sections. The unified - listing follows the same principle as a library catalog -- books are organized by - subject, not by whether they were hand-typeset or digitally printed. - - **Verified by:** No section heading references docs/ or docs-live/ as category, - Documents from both directories appear in unified tables - - @acceptance-criteria @happy-path - Scenario: Documents from both directories appear in unified navigation - Given manual documents exist in docs/ including ARCHITECTURE.md and METHODOLOGY.md - And generated documents exist in docs-live/ including PRODUCT-AREAS.md and DECISIONS.md - When the IndexCodec generates the index document - Then all documents appear in topic-organized sections - And no section heading uses docs/ or docs-live/ as an organizational label - And each document entry includes title, description, and audience - - @acceptance-criteria @validation - Scenario: Quick navigation table includes both manual and generated documents - Given the preamble contains a quick finder table - When the IndexCodec generates the index document - Then the quick finder table maps goals to documents regardless of source directory - And links resolve correctly to both docs/ and docs-live/ paths - - Rule: Document metadata drives auto-generated sections - - **Invariant:** Pattern counts per product area, phase progress summaries, and - product area coverage percentages are derived from PatternGraph pre-computed views - at generation time. The IndexCodec accesses `dataset.byProductArea` for area - statistics, `dataset.byStatus` for status distribution, and `dataset.byPhase` for - phase ordering. No statistics are hardcoded in the codec or config. When a pattern - changes status or a new pattern is added, regenerating the index reflects the - change without any manual update. - - **Rationale:** The manual INDEX.md has no statistics section because maintaining - accurate counts manually is unsustainable across 196+ patterns. The PatternGraph - pre-computed views provide O(1) access to grouped pattern data. Surfacing these - statistics in the index gives readers an at-a-glance project health overview - (how many patterns per area, what percentage are completed, which phases are - active) that was previously only available via the Process Data API CLI. - - **Verified by:** Statistics section renders from PatternGraph views, - No hardcoded counts exist in codec or config - - @acceptance-criteria @happy-path - Scenario: Product area statistics render from PatternGraph - Given a PatternGraph with byProductArea containing 7 product areas - And each area has between 5 and 40 patterns - When the IndexCodec generates the auto-generated statistics section - Then a table shows each product area with its pattern count - And the total across all areas matches the dataset pattern count - - @acceptance-criteria @happy-path - Scenario: Phase progress summary shows status distribution - Given a PatternGraph with byStatus containing roadmap, active, and completed patterns - When the IndexCodec generates the phase progress section - Then a summary shows the count of patterns in each status - And a completion percentage is calculated from completed vs total - - @acceptance-criteria @validation - Scenario: Empty product area still appears in statistics - Given a PatternGraph where the CoreTypes product area has zero patterns - When the IndexCodec generates the statistics section - Then CoreTypes appears in the table with a count of zero - And no error occurs due to the empty area diff --git a/architect/specs/error-guide-codec.feature b/architect/specs/error-guide-codec.feature deleted file mode 100644 index b0966cab..00000000 --- a/architect/specs/error-guide-codec.feature +++ /dev/null @@ -1,224 +0,0 @@ -@architect -@architect-pattern:ErrorGuideCodec -@architect-status:completed -@architect-unlock-reason:Initial-commit-with-all-deliverables-complete -@architect-phase:35 -@architect-effort:2w -@architect-product-area:Generation -@architect-depends-on:DocsConsolidationStrategy -@architect-business-value:replaces-341-line-manual-PROCESS-GUARD-md-with-auto-generated-error-diagnosis-guides -@architect-priority:medium -Feature: Error Guide Codec - - **Problem:** - `docs/PROCESS-GUARD.md` (341 lines) is manually maintained with per-error-code - diagnosis guides, escape hatch documentation, pre-commit setup instructions, and - programmatic API examples. When validation rules change in `src/lint/`, the manual - doc drifts. The existing `ValidationRulesCodec` generates `docs-live/validation/` - files (error-catalog.md, fsm-transitions.md, protection-levels.md) covering ~35% - of PROCESS-GUARD.md content, but these lack fix rationale ("why this rule exists"), - alternative approaches, integration recipes (Husky, CI), and the programmatic API. - - **Solution:** - Enhance the `ValidationRulesCodec` to generate error diagnosis guide content by: - (1) registering a `process-guard-errors` convention tag in `conventions.ts`, - (2) annotating error-handling source files in `src/lint/` with structured JSDoc - convention annotations, (3) adding new `ValidationRulesCodecOptions` toggles for - error guide sections, (4) adding a `ReferenceDocConfig` entry that composes - convention-tagged content with the existing error catalog, and (5) using preamble - for Husky/CI setup content that cannot come from source annotations. - - **Why It Matters:** - | Benefit | How | - | Zero-drift error docs | Error codes, causes, fixes, and rationale generated from annotated source | - | Fix rationale included | Each error code explains why the rule exists, not just how to fix it | - | Integration recipes | Husky pre-commit and CI pipeline setup carried via preamble | - | Progressive disclosure | Overview links to per-error detail pages with examples and alternatives | - | Replaces manual doc | PROCESS-GUARD.md sections replaced with pointers to generated output | - - **Scope:** - | Content Section | Source | Mechanism | - | Error codes with cause/fix | RULE_DEFINITIONS constant | Already generated (error-catalog.md) | - | Fix rationale per error | New convention annotations on src/lint/ | Convention tag extraction | - | Escape hatch alternatives | New convention annotations | Convention tag extraction | - | FSM transitions and protection levels | VALID_TRANSITIONS, PROTECTION_LEVELS | Already generated | - | Pre-commit setup (Husky) | Cannot come from annotations | Preamble SectionBlock[] | - | Programmatic API guide | Cannot come from annotations | Preamble SectionBlock[] | - | Architecture diagram (Decider pattern) | Cannot come from annotations | Preamble SectionBlock[] | - | CLI usage and options | Hardcoded in buildCLISection | Already generated | - - **Design Questions (for design session):** - | Question | Options | Recommendation | - | Enhance ValidationRulesCodec or create separate codec? | (A) Extend existing, (B) New ErrorGuideCodec | (A) Extend -- RULE_DEFINITIONS and section builders already exist | - | Convention tag approach? | (A) New process-guard-errors tag, (B) Reuse fsm-rules | (A) New tag -- error diagnosis content is distinct from FSM rule definitions | - | Where does rationale come from? | (A) Convention JSDoc on src/lint/, (B) Rule: blocks in ProcessGuardLinter spec | (A) Convention JSDoc -- rationale belongs near the error-handling code | - | How to handle Husky/CI content? | (A) Preamble, (B) New annotation type | (A) Preamble -- integration recipes are editorial, not code-derived | - - **Design Session Findings (2026-03-06):** - | Finding | Decision | Rationale | - | DD-1: Extend ValidationRulesCodec | Confirmed (A) Extend existing | ValidationRulesCodec owns RULE_DEFINITIONS, 4 boolean option toggles, buildDetailFiles(), and 6 section builders. A separate ErrorGuideCodec would duplicate all of these. New includeErrorGuide toggle follows established pattern. | - | DD-2: New process-guard-errors convention tag | Confirmed (A) New tag | fsm-rules covers FSM structure (transitions, states, protection). Error diagnosis (rationale, alternatives, debugging hints) is a distinct content domain. 13 existing convention values, this becomes the 14th. | - | DD-3: Convention JSDoc on decider.ts | Confirmed (A) Convention JSDoc | decider.ts already has 450-line JSDoc. Convention extractor decomposes by ## Heading sections into ConventionRuleContent entries. Each of 6 error rules gets a ## heading with Invariant/Rationale/table. Proven by orchestrator.ts and reference.ts convention annotations. | - | DD-4: Preamble for Husky/CI content | Confirmed (A) Preamble | ReferenceDocConfig.preamble is SectionBlock[] prepended before generated content. Already proven by product-area docs. Husky setup, programmatic API (6 functions), and Decider architecture diagram are editorial content at editorial cadence. | - | DD-5: Two-document composition strategy | ReferenceDocConfig entry creates unified PROCESS-GUARD.md | The reference codec composes preamble + convention content. The validation-rules generator continues producing error-catalog.md, fsm-transitions.md, protection-levels.md independently. The reference doc links to these detail files. | - | DD-6: Fallback strategy for missing annotations | description field as fallback rationale | composeRationaleIntoRules() enriches RULE_DEFINITIONS from convention bundles. If no convention annotation exists for a rule ID, rationale defaults to description. No empty rationale sections in output. | - - **Design Stubs:** - | Stub | Location | Purpose | - | enhanced-validation-options.ts | architect/stubs/error-guide-codec/ | DD-1: Extended ValidationRulesCodecOptions with includeErrorGuide toggle and EnhancedRuleDefinition interface | - | error-guide-config.ts | architect/stubs/error-guide-codec/ | DD-2/DD-4: ReferenceDocConfig entry with preamble SectionBlocks and convention tag registration | - | convention-annotation-example.ts | architect/stubs/error-guide-codec/ | DD-3: Example convention annotation format for all 6 error rules on decider.ts | - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | Tests | Test Type | - | Register process-guard-errors convention tag value | complete | src/taxonomy/conventions.ts | Yes | unit | - | Annotate error-handling source files with convention tags | complete | src/lint/process-guard/decider.ts | No | n/a | - | Add ValidationRulesCodecOptions toggles for error guide sections | complete | src/renderable/codecs/validation-rules.ts | Yes | unit | - | ReferenceDocConfig entry for PROCESS-GUARD generated reference | complete | architect.config.ts | Yes | integration | - | Preamble content for Husky/CI setup and programmatic API | complete | architect.config.ts | Yes | integration | - | Replace PROCESS-GUARD.md reference sections with pointer to generated output | complete | docs/PROCESS-GUARD.md | No | n/a | - | Behavior spec with scenarios for error guide generation | n/a | tests/features/generation/error-guide-codec.feature | Yes | acceptance | - - Rule: Error guide extends the existing ValidationRulesCodec - - **Invariant:** Error diagnosis guide content is produced by enhancing the existing - `ValidationRulesCodec` and its `RULE_DEFINITIONS` constant, not by creating a - parallel codec. The enhanced codec adds fix rationale, alternative approaches, and - integration context to the existing error catalog, FSM transitions, and protection - level detail files. A separate `ErrorGuideCodec` class is not created. - - **Rationale:** `ValidationRulesCodec` already owns `RULE_DEFINITIONS` with error - codes, causes, and fixes. It generates `error-catalog.md`, `fsm-transitions.md`, - and `protection-levels.md`. Creating a parallel codec would duplicate RULE_DEFINITIONS - access and fragment validation documentation across two codecs. Extending the existing - codec keeps all validation reference content in one place. - - **Verified by:** Enhanced codec produces error guide sections, - No parallel ErrorGuideCodec class exists - - @acceptance-criteria @happy-path - Scenario: Enhanced ValidationRulesCodec produces error guide content - Given the ValidationRulesCodec with error guide options enabled - And RULE_DEFINITIONS contains error codes with causes and fixes - And convention-tagged source files provide fix rationale - When the codec generates the validation rules document - Then error guide sections appear with rationale for each error code - And each error code entry includes cause, fix, and why-this-rule-exists - - @acceptance-criteria @validation - Scenario: Error guide options are independently toggleable - Given the ValidationRulesCodec with includeErrorGuide set to false - When the codec generates the validation rules document - Then no error guide rationale sections appear - And the existing error catalog, FSM, and protection level sections still render - - Rule: Each error code has fix rationale explaining why the rule exists - - **Invariant:** Every error code in the generated output includes not just a fix - command but a "why this rule exists" rationale. The rationale is sourced from - `@architect-convention:process-guard-errors` JSDoc annotations on the error-handling - code in `src/lint/process-guard/`. The `RuleDefinition` interface is extended with - a `rationale` field, or rationale is composed from convention-extracted content. - - **Rationale:** The existing `error-catalog.md` tells developers what to do (fix - command) but not why the rule exists. Without rationale, developers reach for escape - hatches instead of understanding the workflow constraint. PROCESS-GUARD.md includes - rationale like "Prevents scope creep during implementation. Plan fully before - starting; implement what was planned." -- this must survive in the generated output. - - **Verified by:** All error codes have rationale in output, - Convention annotations are the rationale source - - @acceptance-criteria @happy-path - Scenario: Generated error catalog includes rationale for each rule - Given source files in src/lint/process-guard/ annotated with process-guard-errors convention - And each annotation includes a rationale section in its JSDoc - When the enhanced ValidationRulesCodec generates the error catalog detail file - Then each error code entry includes a "Why this rule exists" section - And the rationale text matches the convention annotation content - - @acceptance-criteria @validation - Scenario: Missing convention annotation falls back to description - Given a RULE_DEFINITIONS entry with no matching convention annotation - When the enhanced ValidationRulesCodec generates the error catalog - Then the error code entry uses the description field as fallback rationale - And no empty rationale section appears in the output - - Rule: Preamble carries integration content that cannot come from annotations - - **Invariant:** Pre-commit setup instructions (Husky configuration, package.json - scripts), CI pipeline patterns, programmatic API examples, and the Decider pattern - architecture diagram use the `ReferenceDocConfig.preamble` mechanism. These are - `SectionBlock[]` defined in the config entry, prepended before all generated content. - Preamble content is manually authored and changes at editorial cadence, not code cadence. - - **Rationale:** Integration recipes (Husky hook setup, CI YAML patterns, API usage - examples) are not extractable from source annotations because they describe how - external systems consume Process Guard, not how Process Guard is implemented. - The preamble mechanism exists precisely for this: editorial prose that lives in - the config, not in a separate manual file, and appears in the generated output. - - **Verified by:** Preamble includes Husky setup section, - Preamble includes programmatic API section - - @acceptance-criteria @happy-path - Scenario: Generated document includes Husky pre-commit setup from preamble - Given a ReferenceDocConfig with preamble containing Husky setup instructions - When the reference codec generates the PROCESS-GUARD reference document - Then the Husky setup section appears before generated validation rules content - And the section includes package.json script examples - - @acceptance-criteria @happy-path - Scenario: Generated document includes programmatic API guide from preamble - Given a ReferenceDocConfig with preamble containing programmatic API examples - When the reference codec generates the PROCESS-GUARD reference document - Then the API guide section appears in the preamble area - And the section includes import paths and function signatures - - @acceptance-criteria @validation - Scenario: Preamble content appears in both detail levels - Given a ReferenceDocConfig with preamble and convention tags - When the reference codec generates at detailed and summary levels - Then preamble sections appear in both outputs - And convention-derived content follows the preamble in both outputs - - Rule: Convention tags source error context from annotated lint code - - **Invariant:** Error-handling code in `src/lint/process-guard/` is annotated with - `@architect-convention:process-guard-errors` using structured JSDoc that includes - rationale, alternative approaches, and common mistake patterns. The convention tag - value `process-guard-errors` is registered in `src/taxonomy/conventions.ts` in the - `CONVENTION_VALUES` array. The `createReferenceCodec` factory extracts this content - via the existing convention extractor pipeline. - - **Rationale:** Convention-tagged annotations on the error-handling code co-locate - rationale with implementation. When a developer changes an error rule in the decider, - the convention JSDoc is right there -- they update both in the same commit. This is - the same pattern used by `codec-registry`, `pipeline-architecture`, and - `taxonomy-rules` convention tags, all proven by CodecDrivenReferenceGeneration. - - **Verified by:** Convention tag is registered in CONVENTION_VALUES, - Convention extraction produces error context sections - - @acceptance-criteria @happy-path - Scenario: Convention tag value is registered and extractable - Given the CONVENTION_VALUES array in src/taxonomy/conventions.ts - When process-guard-errors is added to the array - Then the convention extractor recognizes the tag value - And source files tagged with process-guard-errors produce convention sections - - @acceptance-criteria @happy-path - Scenario: Convention-tagged decider code produces structured error context - Given the decider.ts file annotated with process-guard-errors convention - And the JSDoc includes rationale and alternative-approach sections - When the reference codec extracts convention content - Then each annotated block produces a section with rationale and alternatives - And sections are ordered by error code identifier - - @acceptance-criteria @validation - Scenario: Unannotated error-handling files produce no convention content - Given error-handling files in src/lint/ without convention tags - When the reference codec extracts convention content for process-guard-errors - Then no convention sections are produced for unannotated files - And the generated document still includes RULE_DEFINITIONS-based content diff --git a/architect/specs/generated-doc-quality.feature b/architect/specs/generated-doc-quality.feature deleted file mode 100644 index 33df689f..00000000 --- a/architect/specs/generated-doc-quality.feature +++ /dev/null @@ -1,124 +0,0 @@ -@architect -@architect-pattern:GeneratedDocQuality -@architect-status:completed -@architect-unlock-reason:Retroactive-completion-during-rebrand -@architect-phase:38 -@architect-effort:2d -@architect-product-area:Generation -@architect-depends-on:DocsLiveConsolidation -@architect-business-value:removes-500-lines-duplication-and-fixes-claude-context-coverage-for-generation-area -@architect-priority:high -Feature: Generated Documentation Quality Improvements - - **Problem:** - Four quality issues reduce the usefulness of generated docs for both Claude agents - and human developers: (1) REFERENCE-SAMPLE.md re-renders canonical value tables - twice — 500+ duplicate lines with zero information gain; (2) the Generation product - area compact file is 1.4 KB for a 233 KB area — critically undersized; (3) - ARCHITECTURE-TYPES.md opens with orchestrator prose instead of type definitions, - burying the content Claude most needs; (4) product area docs (GENERATION.md 233 KB, - DATA-API.md 102 KB) have no navigation TOC, making browser traversal impractical. - - **Solution:** - Fix the reference codec's behavior-specs renderer to stop duplicating convention - tables. Enrich the Generation product area compact template. Reorder - ARCHITECTURE-TYPES.md to lead with type definitions. Add a generated TOC block - to product area doc headers. - - **Why It Matters:** - | Benefit | Audience | - | Removes ~200 wasted token-lines per REFERENCE-SAMPLE.md read | Claude | - | Generation compact usable as standalone context (1.4 KB → 4+ KB) | Claude | - | ARCHITECTURE-TYPES.md answers "what is PatternGraph?" immediately | Claude | - | 233 KB product area docs become navigable in a browser | Human devs | - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | Tests | Test Type | - | Fix behavior-specs renderer: no duplicate convention tables | complete | src/renderable/codecs/reference.ts | Yes | unit | - | Enrich Generation _claude-md/ compact (target: 4+ KB) | complete | src/renderable/codecs/reference.ts | Yes | integration | - | Reorder ARCHITECTURE-TYPES.md: types first, convention content second | complete | architect.config.ts, src/renderable/codecs/reference.ts | Yes | integration | - | Add generated TOC block to product area doc headers | complete | src/renderable/codecs/reference.ts | Yes | integration | - - Rule: Behavior-specs renderer does not duplicate convention table content - - **Invariant:** When the reference codec renders a convention rule that contains - a table, the table appears exactly once in the output: in the main convention - section. The behavior-specs (expanded rule detail) section shows only the - Invariant, Rationale, and Verified-by metadata — not the table body. A - convention section with N tables produces exactly N table instances in the - generated document, regardless of detail level. - - **Rationale:** DD-4: The current renderer re-includes the full convention - table when rendering the expanded rule detail section. For REFERENCE-SAMPLE.md - with 5 canonical value tables, this produces 500+ lines of exact duplication. - Agents consuming this file waste context on content they already parsed. - Human readers see the same table twice in the same scroll view. - - **Verified by:** Convention tables appear once in output, - Behavior-specs shows rule metadata only - - @acceptance-criteria @happy-path - Scenario: Convention rule table appears exactly once in generated output - Given a ReferenceDocConfig with a convention rule containing a markdown table - When the reference codec generates at detailed level - Then the table appears once in the convention section - And the behavior-specs expanded detail shows invariant and rationale only - And no duplicate table rows exist in the document - - @acceptance-criteria @validation - Scenario: REFERENCE-SAMPLE.md contains no duplicate table content after fix - Given the reference-sample config regenerated after codec fix - When the output is compared line by line - Then each canonical value table appears exactly once - And total document length is under 966 lines (down from 1166) - - Rule: Compact _claude-md/ files are self-sufficient for their product area - - **Invariant:** Each product area compact (`_claude-md//-overview.md`) - is self-sufficient as a standalone context file — an agent reading only the - compact can answer: what does this area do, what are its key patterns, what are - its invariants, and what files to read for details. Minimum target: 4 KB. - The Generation compact is a specific gap: 1.4 KB for an area with 20+ codecs - and the entire rendering pipeline. - - **Rationale:** DD-2: `_claude-md/` compacts are the Claude consumption contract. - A 1.4 KB compact for the largest product area (233 KB) means agents have no - usable summary context for Generation. They fall back to reading the full file - or hallucinating based on names alone. The contract requires each compact to be - a genuine summary, not a stub. - - **Verified by:** Generation compact >= 4 KB with codec list and pipeline summary, - All area compacts self-sufficient without full product area doc - - @acceptance-criteria @happy-path - Scenario: Generation compact contains codec inventory and pipeline summary - Given the Generation product area compact regenerated with enriched template - When its content is checked - Then it contains a list of all major codecs with one-line purposes - And it contains the four-stage pipeline summary (Scanner-Extractor-Transformer-Codec) - And its file size is at least 4 KB - - Rule: ARCHITECTURE-TYPES.md leads with type definitions, not convention content - - **Invariant:** ARCHITECTURE-TYPES.md opens with the PatternGraph type definitions - section before any pipeline-architecture convention content. An agent querying - "what is PatternGraph" finds the type definition within the first 30 lines. - The pipeline-architecture convention prose (orchestrator responsibilities, pipeline - steps) follows the type definitions section. - - **Rationale:** The file is named ARCHITECTURE-TYPES — type definitions are the - primary content. The pipeline-architecture convention content was added as a - secondary layer. Current output opens with orchestrator prose, burying the type - definitions that both Claude and human developers are most likely seeking. - Section ordering in ReferenceDocConfig determines render order. - - **Verified by:** Type definitions appear in first 30 lines, - Pipeline convention content follows types section - - @acceptance-criteria @happy-path - Scenario: PatternGraph type definition appears before orchestrator prose - Given ARCHITECTURE-TYPES.md generated with shapes section ordered before conventions - When the first 30 lines are read - Then PatternGraph or a related type definition appears - And no orchestrator responsibility prose appears before the first type definition diff --git a/architect/specs/gherkin-patterns-restructure.feature b/architect/specs/gherkin-patterns-restructure.feature deleted file mode 100644 index 19810428..00000000 --- a/architect/specs/gherkin-patterns-restructure.feature +++ /dev/null @@ -1,129 +0,0 @@ -@architect -@architect-pattern:GherkinPatternsRestructure -@architect-status:completed -@architect-unlock-reason:Retroactive-completion-during-rebrand -@architect-phase:41 -@architect-effort:0.5d -@architect-product-area:Generation -@architect-depends-on:DocsConsolidationStrategy -@architect-business-value:single-responsibility-per-doc -@architect-priority:medium -Feature: Gherkin Patterns Guide Restructure - - **Problem:** - `docs/GHERKIN-PATTERNS.md` is 515 lines and mixes two distinct concerns: - (a) a writing guide for Gherkin authoring patterns (belongs here), and - (b) the Step Linting reference — 12 rules, 3 categories, examples, and CLI flags (lines 346–493, - ~148 lines) — which is quality tooling and belongs in VALIDATION.md alongside lint-patterns, - lint-process, and validate-patterns. - - The current cross-reference in VALIDATION.md (line 96) already says: "Detailed rules and examples: - See GHERKIN-PATTERNS.md — Step Linting". This is a forward-reference anti-pattern: the content - lives in the wrong file and requires a redirect to find it. - - **Solution:** - Move the Step Linting section (lines 346–493) into VALIDATION.md as a first-class section, - replacing the current redirect pointer (line 96) with the actual content. Trim GHERKIN-PATTERNS.md - from 515 lines to approximately 370 lines, retaining all authoring guide content. Update all - cross-references between the two files and in INDEX.md to reflect the new locations. - - **Design Finding — Revised Line Target (250 → ~370):** - - | Finding | Impact | Resolution | - | Original target was ~250 lines | Section audit shows only Step Linting (148 lines) is misplaced | Revised target to ~370 lines | - | Remaining 366 lines are ALL authoring content | Essential Patterns, Rich Content, Tag Conventions are referenced by CLAUDE.md and SESSION-GUIDES.md | No further trimming — removing would damage the guide | - | CLAUDE.md overlap is intentional | Testing section (274 lines) covers same rules but for AI debugging context, not tool reference | No CLAUDE.md trim in this phase | - - **Why It Matters:** - | Benefit | How | - | Single responsibility | Each doc covers one concern: writing vs. quality tooling | - | Reduced navigation | Developers find lint rules in VALIDATION.md, not GHERKIN-PATTERNS.md | - | Accurate cross-refs | VALIDATION.md becomes self-contained for all validation tooling | - | Smaller writing guide | 370-line doc is easier to scan during authoring sessions | - - **Section Disposition (from design session audit):** - - | Section | Lines | Line Range | Action | - | Header + intro | 7 | 1-7 | KEEP | - | Essential Patterns | 144 | 9-152 | KEEP | - | DataTable and DocString Usage | 50 | 154-203 | KEEP | - | Tag Conventions | 39 | 205-243 | KEEP | - | Feature File Rich Content | 99 | 246-344 | KEEP | - | Step Linting | 148 | 346-493 | MOVE to VALIDATION.md | - | Quick Reference | 12 | 495-506 | KEEP, remove lint-steps row | - | Related Documentation | 8 | 508-515 | KEEP, update descriptions | - - **VALIDATION.md Integration Point:** - - Current lint-steps section (lines 76-97) has a redirect pointer at line 96. - Replace lines 76-98 with: keep intro (76-95), delete redirect (96), insert - moved content (Feature File Rules, Step Definition Rules, Cross-File Rules, - CLI Reference from GHERKIN-PATTERNS.md lines 356-492). Result: ~430 lines. - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | Tests | Test Type | - | Move Step Linting section (lines 346-493) to VALIDATION.md, replacing redirect at line 96 | complete | docs/VALIDATION.md | No | n/a | - | Remove Step Linting section from GHERKIN-PATTERNS.md (result: ~370 lines) | complete | docs/GHERKIN-PATTERNS.md | No | n/a | - | Update cross-references between the two docs | complete | docs/GHERKIN-PATTERNS.md, docs/VALIDATION.md | No | n/a | - | Verify related-documentation tables in both files | complete | docs/GHERKIN-PATTERNS.md, docs/VALIDATION.md | No | n/a | - | Update INDEX.md section tables and line counts for both docs | complete | docs/INDEX.md | No | n/a | - | Add lint-steps cross-reference row in GHERKIN-PATTERNS.md Quick Reference | complete | docs/GHERKIN-PATTERNS.md | No | n/a | - - Rule: Step Linting content belongs in VALIDATION.md - - **Invariant:** All validation tooling reference content lives in VALIDATION.md. - - **Rationale:** VALIDATION.md already documents lint-patterns, lint-process, and validate-patterns. - Step Linting is a fourth quality tool in the same family — it must follow the same pattern. - Redirecting from VALIDATION.md to GHERKIN-PATTERNS.md for lint rules breaks the principle that - VALIDATION.md is the single place to find quality tooling documentation. - - **Verified by:** Step Linting section appears in VALIDATION.md after restructure - - @acceptance-criteria @happy-path - Scenario: Step Linting section appears in VALIDATION.md after restructure - Given VALIDATION.md currently contains a redirect pointer to GHERKIN-PATTERNS.md for Step Linting rules - When the restructure is complete - Then VALIDATION.md contains the full Step Linting section including all 12 rules and the CLI reference - And the redirect pointer is removed from VALIDATION.md - And GHERKIN-PATTERNS.md no longer contains the Step Linting section - - Rule: GHERKIN-PATTERNS.md remains the authoring guide - - **Invariant:** GHERKIN-PATTERNS.md covers only Gherkin writing patterns, not tooling reference. - - **Rationale:** The writing guide is useful during spec authoring. Quality tool reference is - useful during CI setup and debugging. Mixing them forces authors to scroll past 148 lines of - tooling reference they do not need during writing, and forces CI engineers to look in the - wrong file for lint rule documentation. - - **Verified by:** Trimmed doc retains all authoring patterns, cross-references updated correctly - - @acceptance-criteria @happy-path - Scenario: Trimmed doc retains all authoring patterns and cross-references updated correctly - Given GHERKIN-PATTERNS.md is 515 lines containing authoring patterns and Step Linting content - When the Step Linting section is moved to VALIDATION.md - Then GHERKIN-PATTERNS.md is approximately 370 lines - And it retains Essential Patterns, DataTable and DocString usage, Tag Conventions, and Rich Content sections - And its Quick Reference table links to VALIDATION.md for lint-steps - And its Related Documentation table links to VALIDATION.md for the full lint tool suite - - Rule: INDEX.md reflects current document structure - - **Invariant:** INDEX.md section tables and line counts must be updated when content moves between docs. - - **Rationale:** INDEX.md serves as the navigation hub for all documentation. Stale line counts - and missing section entries cause developers to land in the wrong part of a document or miss - content entirely. Both GHERKIN-PATTERNS.md and VALIDATION.md entries must reflect the restructure. - - **Verified by:** INDEX.md entries match post-restructure line counts and sections - - @acceptance-criteria @validation - Scenario: INDEX.md entries match post-restructure line counts and sections - Given INDEX.md lists GHERKIN-PATTERNS.md at lines 1-515 and VALIDATION.md at lines 1-281 - When the restructure moves Step Linting content between the two docs - Then INDEX.md lists GHERKIN-PATTERNS.md at approximately 370 lines - And INDEX.md lists VALIDATION.md at approximately 430 lines - And the GHERKIN-PATTERNS.md section table no longer includes Step Linting - And the VALIDATION.md section table includes Step Linting with rules and examples diff --git a/architect/specs/gherkin-rules-support.feature b/architect/specs/gherkin-rules-support.feature deleted file mode 100644 index 12fcd1ec..00000000 --- a/architect/specs/gherkin-rules-support.feature +++ /dev/null @@ -1,128 +0,0 @@ -@architect -@architect-pattern:GherkinRulesSupport -@architect-status:completed -@architect-unlock-reason:Add-architect-opt-in-marker -@architect-phase:100 -@architect-release:v1.0.0 -@architect-effort:4h -@architect-product-area:Annotation -@architect-business-value:enable-human-readable-documentation-from-feature-files -@architect-priority:high -Feature: Gherkin Rules and Custom Content Support - - **Problem:** - Feature files were limited to flat scenario lists. Business rules, rationale, - and rich descriptions could not be captured in a way that: - - Tests ignore (vitest-cucumber skips descriptions) - - Generators render (PRD shows business context) - - Maintains single source of truth (one file, two purposes) - - The Gherkin `Rule:` keyword was parsed by @cucumber/gherkin but our pipeline - dropped the data at scanner/extractor stages. - - **Solution:** - Extended the documentation pipeline to capture and render: - - `Rule:` keyword as Business Rules sections - - Rule descriptions (rationale, exceptions, context) - - DataTables in steps as Markdown tables - - DocStrings in steps as code blocks - - Infrastructure changes (schema, scanner, extractor) are shared by all generators. - Rendering was added to PRD generator as reference implementation. - - Confirmed vitest-cucumber supports Rules via `Rule()` + `RuleScenario()` syntax. - No migration to alternative frameworks needed. - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Tests | Location | - | GherkinRuleSchema | complete | No | validation-schemas/feature.ts | - | Rule parsing in AST parser | complete | No | scanner/gherkin-ast-parser.ts | - | Rules passthrough in scanner | complete | No | scanner/gherkin-scanner.ts | - | Rules field in ExtractedPattern | complete | No | validation-schemas/extracted-pattern.ts | - | Rules mapping in extractor | complete | No | extractor/gherkin-extractor.ts | - | Business Rules rendering | complete | No | generators/sections/prd-features.ts | - | DataTable rendering in acceptance criteria | complete | No | generators/sections/prd-features.ts | - | DocString rendering in acceptance criteria | complete | No | generators/sections/prd-features.ts | - - Rule: Rules flow through the entire pipeline without data loss - - **Invariant:** Rule data (name, description, tags, scenarios) must be preserved through every pipeline stage from parser to ExtractedPattern. - **Rationale:** Any data loss at an intermediate stage makes rule content invisible to all downstream generators, silently producing incomplete documentation. - - The @cucumber/gherkin parser extracts Rules natively. Our pipeline must - preserve this data through scanner, extractor, and into ExtractedPattern - so generators can access rule names, descriptions, and nested scenarios. - - @acceptance-criteria - Scenario: Rules are captured by AST parser - Given a feature file with Rule: keyword - When parsed by gherkin-ast-parser - Then the ParsedFeatureFile contains rules array - And each rule has name, description, tags, scenarios, line - - @acceptance-criteria - Scenario: Rules pass through scanner - Given a parsed feature file with rules - When processed by gherkin-scanner - Then the ScannedGherkinFile includes rules - And scenarios inside rules are also in flat scenarios array - - @acceptance-criteria - Scenario: Rules are mapped to ExtractedPattern - Given a scanned feature file with rules - When processed by gherkin-extractor - Then the ExtractedPattern contains rules field - And each rule has name, description, scenarioCount, scenarioNames - - Rule: Generators can render rules as business documentation - - **Invariant:** Rules must render as human-readable Business Rules sections, not as raw Given/When/Then syntax. - **Rationale:** Business stakeholders cannot interpret Gherkin step definitions; without rendering transformation, feature files remain developer-only artifacts. - - Business stakeholders see rule names and descriptions as "Business Rules" - sections, not Given/When/Then syntax. This enables human-readable PRDs - from the same files used for test execution. - - @acceptance-criteria - Scenario: PRD generator renders Business Rules section - Given an ExtractedPattern with rules - When rendered by prd-features section - Then output contains "Business Rules" heading - And each rule name appears as bold text - And rule descriptions appear as paragraphs - And verification scenarios are listed - - Rule: Custom content blocks render in acceptance criteria - - **Invariant:** DataTables and DocStrings attached to steps must appear in generated documentation as Markdown tables and fenced code blocks respectively. - **Rationale:** Without rendering custom content blocks, acceptance criteria lose the structured data and code examples that make them self-contained and verifiable. - - DataTables and DocStrings in steps should appear in generated documentation, - providing structured data and code examples alongside step descriptions. - - @acceptance-criteria - Scenario: DataTables render as Markdown tables - Given a scenario step with DataTable - When rendered in acceptance criteria - Then output contains Markdown table with headers and rows - - @acceptance-criteria - Scenario: DocStrings render as code blocks - Given a scenario step with DocString - When rendered in acceptance criteria - Then output contains fenced code block with content - - Rule: vitest-cucumber executes scenarios inside Rules - - **Invariant:** Scenarios nested inside Rule blocks must be executable by vitest-cucumber using the Rule() and RuleScenario() API. - **Rationale:** If Rule-scoped scenarios cannot execute, adding Rule blocks to feature files would break the test suite, forcing a choice between documentation structure and test coverage. - - Test execution must work for scenarios inside Rule blocks. - Use Rule() function with RuleScenario() instead of Scenario(). - - @acceptance-criteria - Scenario: Rule scenarios execute with vitest-cucumber - Given a feature file with scenarios inside Rule blocks - When step definitions use Rule() and RuleScenario() syntax - Then all scenarios execute and pass diff --git a/architect/specs/mvp-workflow-implementation.feature b/architect/specs/mvp-workflow-implementation.feature deleted file mode 100644 index e69eeb72..00000000 --- a/architect/specs/mvp-workflow-implementation.feature +++ /dev/null @@ -1,85 +0,0 @@ -@architect -@architect-pattern:MvpWorkflowImplementation -@architect-status:completed -@architect-unlock-reason:Add-process-workflow-include-tag -@architect-phase:99 -@architect-release:v1.0.0 -@architect-effort:8h -@architect-product-area:Process -@architect-include:process-workflow -@architect-business-value:align-package-with-pdr005-fsm -@architect-priority:high -Feature: MVP Workflow Implementation - - **Problem:** - PDR-005 defines a 4-state workflow FSM (`roadmap, active, completed, deferred`) - but the Architect package validation schemas and generators may still - reference legacy status values. Need to ensure alignment. - - **Solution:** - Implement PDR-005 status values via taxonomy module refactor: - 1. Create taxonomy module as single source of truth (src/taxonomy/status-values.ts) - 2. Update validation schemas to import from taxonomy module - 3. Update generators to use normalizeStatus() for display bucket mapping - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | - | Taxonomy module as single source of truth | complete | src/taxonomy/status-values.ts | - | Update DefaultPatternStatusSchema | complete | src/validation-schemas/doc-directive.ts | - | Update ProcessMetadataSchema status | complete | src/validation-schemas/dual-source.ts | - | Update generator status mapping | complete | src/renderable/codecs/ | - | Fix type errors from status change | complete | src/ (typecheck passes) | - | Run pnpm typecheck | complete | 0 errors | - | Run pnpm test | complete | 1972 tests pass | - - Rule: PDR-005 status values are recognized - - **Invariant:** The scanner and validation schemas must accept exactly the four PDR-005 status values: roadmap, active, completed, deferred. - **Rationale:** Unrecognized status values silently drop patterns from generated documents, causing missing documentation across the entire monorepo. - - **Verified by:** Scanner extracts new status values; Scenario Outline: All four status values are valid - - @acceptance-criteria - Scenario: Scanner extracts new status values - Given a feature file with @architect-status:roadmap - When the scanner processes the file - Then the status field is "roadmap" - - @acceptance-criteria - Scenario Outline: All four status values are valid - Given a feature file with @architect-status: - When validating the pattern - Then validation passes - - Examples: - | status | - | roadmap | - | active | - | completed | - | deferred | - - Rule: Generators map statuses to documents - - **Invariant:** Each status value must route to exactly one target document: roadmap/deferred to ROADMAP.md, active to CURRENT-WORK.md, completed to CHANGELOG-GENERATED.md. - **Rationale:** Incorrect status-to-document mapping causes patterns to appear in the wrong document or be omitted entirely, breaking the project overview for all consumers. - - **Verified by:** Roadmap and deferred appear in ROADMAP.md; Active appears in CURRENT-WORK.md; Completed appears in CHANGELOG-GENERATED.md - - @acceptance-criteria - Scenario: Roadmap and deferred appear in ROADMAP.md - Given patterns with status "roadmap" or "deferred" - When generating ROADMAP.md - Then they appear as planned work - - @acceptance-criteria - Scenario: Active appears in CURRENT-WORK.md - Given patterns with status "active" - When generating CURRENT-WORK.md - Then they appear as active work - - @acceptance-criteria - Scenario: Completed appears in CHANGELOG-GENERATED.md - Given patterns with status "completed" - When generating CHANGELOG-GENERATED.md - Then they appear in the changelog diff --git a/architect/specs/orchestrator-pipeline-factory-migration.feature b/architect/specs/orchestrator-pipeline-factory-migration.feature deleted file mode 100644 index a6349ffa..00000000 --- a/architect/specs/orchestrator-pipeline-factory-migration.feature +++ /dev/null @@ -1,313 +0,0 @@ -@architect -@architect-pattern:OrchestratorPipelineFactoryMigration -@architect-status:completed -@architect-unlock-reason:PR28-review-structural-fixes -@architect-phase:101 -@architect-effort:2d -@architect-product-area:Generation -@architect-include:process-workflow,codec-transformation -@architect-depends-on:PatternGraphLayeredExtraction -@architect-business-value:eliminate-last-parallel-pipeline-and-unify-pipeline-definition -@architect-priority:high -Feature: Orchestrator Pipeline Factory Migration - - **Problem:** - `orchestrator.ts` is the last feature consumer that wires the 8-step - scan-extract-merge-transform pipeline inline (lines 282-427). This is - the Parallel Pipeline anti-pattern identified in ADR-006. The shared - pipeline factory in `build-pipeline.ts` already serves `pattern-graph-cli.ts` - and `validate-patterns.ts`, but the orchestrator — the original pipeline - host — was deferred (PatternGraphLayeredExtraction DD-3) because it - collects structured warnings (scan errors with file details, extraction - error counts, Gherkin parse errors with line/column) that the factory's - flat `readonly string[]` warnings cannot represent. - - **Current violations in orchestrator.ts:** - - | Anti-Pattern | Location | Evidence | - | Parallel Pipeline | Lines 282-427 | 8-step pipeline: loadConfig, scanPatterns, extractPatterns, scanGherkinFiles, extractPatternsFromGherkin, mergePatterns, computeHierarchyChildren, transformToPatternGraph | - - Additionally, `mergePatterns()` is defined in orchestrator.ts (line 701) - but imported by `build-pipeline.ts` from `../orchestrator.js`. This - creates a misplaced-dependency: the factory depends on the consumer it - is meant to replace. When the orchestrator migrates to the factory, the - import direction inverts correctly. - - **What the orchestrator does beyond the pipeline:** - - | Responsibility | Lines | Stays in orchestrator | - | Pipeline (steps 1-8) | 282-427 | No — delegates to factory | - | PR Changes git detection | 429-469 | Yes — generator-specific option | - | Generator dispatch + file writing | 471-645 | Yes — core orchestrator job | - | Session file cleanup | 647-679 | Yes — post-generation lifecycle | - | mergePatterns utility | 701-727 | No — moves to pipeline/ | - | cleanupOrphanedSessionFiles | 761-809 | Yes — lifecycle utility | - | generateFromConfig | 922-998 | Yes — config-based entry point | - | groupGenerators, mergeGenerateResults | 850-898 | Yes — batching utilities | - - **Solution:** - Enrich the pipeline factory's `PipelineResult` with structured warnings - that capture the granularity the orchestrator needs, then migrate - `generateDocumentation()` to call `buildPatternGraph()`. Move - `mergePatterns()` to `src/generators/pipeline/merge-patterns.ts` as a - standalone pipeline step. - - The orchestrator retains: generator dispatch, file writing, PR-changes - detection, codec option assembly, session cleanup, and the - `generateFromConfig` entry point. - - **Design Decisions:** - - DD-1: Structured warnings replace flat strings in PipelineResult. - The factory's `PipelineResult.warnings` changes from `readonly string[]` - to `readonly PipelineWarning[]` where `PipelineWarning` is: - - See PipelineWarning and PipelineWarningDetail interfaces in - src/generators/pipeline/build-pipeline.ts. PipelineWarning has a - discriminated type field ('scan' | 'extraction' | 'gherkin-parse'), - a message, optional count, and optional details array. - - This is structurally similar to `GenerationWarning` + `WarningDetail` - from orchestrator.ts. The orchestrator maps `PipelineWarning` to - `GenerationWarning` in a thin adapter — `'gherkin-parse'` maps to - `'scan'`, and generator-level warning types (`'overwrite-skipped'`, - `'config'`, `'cleanup'`) are produced by the orchestrator itself, not - the pipeline. Existing consumers (pattern-graph-cli, validate-patterns) that - ignore warnings or use flat strings are unaffected — they can read - `.message` only. - - DD-2: mergePatterns moves to src/generators/pipeline/merge-patterns.ts. - Currently defined in orchestrator.ts (line 701), imported by - build-pipeline.ts. After the move: - - `build-pipeline.ts` imports from `./merge-patterns.js` (sibling) - - `orchestrator.ts` no longer exports `mergePatterns` - - `generators/index.ts` re-exports from `pipeline/merge-patterns.js` - - The public API (`mergePatterns`) stays available, just moves home - - DD-3: Pipeline factory gains an includeValidation option. - The orchestrator calls `transformToPatternGraph` (no validation), - while pattern-graph-cli calls `transformToPatternGraphWithValidation`. - The factory already calls the validation variant. Adding - `includeValidation?: boolean` (default true) lets the orchestrator - opt out, since doc generation doesn't need validation summaries. - This was foreshadowed in PatternGraphLayeredExtraction DD-3. - - DD-4: Scan result counts flow through PipelineResult. - The orchestrator needs scan result counts for constructing its warning - messages: how many files were scanned, how many had errors, how many - had skipped directives, how many Gherkin files had parse errors. The - factory adds an optional `scanMetadata` field: - - See ScanMetadata interface in src/generators/pipeline/build-pipeline.ts. - It carries scannedFileCount, scanErrorCount, skippedDirectiveCount, - and gherkinErrorCount. - - This avoids exposing raw `ScannedFile[]` (which would be a Parallel - Pipeline enabler) while providing the counts the orchestrator needs - for its warning messages. The merged patterns array for - `GenerateResult.patterns` and generator context comes from - `PipelineResult.dataset.patterns`, not from scan metadata. - - DD-5: The factory supports partial success for scan errors. - Today the factory returns `Result.err` on total scanner failure - (e.g., invalid glob), which remains unchanged — total infrastructure - failures are always fatal. For partial failures (individual files - with parse errors within an otherwise successful scan), the new - `failOnScanErrors?: boolean` option controls behavior. When true - (default for pattern-graph-cli), partial scan errors produce `Result.err`. - When false (orchestrator), partial errors are captured in - `PipelineResult.warnings` as structured `PipelineWarning` objects - and the pipeline continues with successfully scanned files. - - DD-6: generateDocumentation signature is unchanged. - The public `GenerateOptions` and `GenerateResult` interfaces don't - change. The orchestrator's `generateDocumentation()` becomes a thinner - function: build PipelineOptions from GenerateOptions, call factory, - map PipelineWarnings to GenerationWarnings, then proceed with generator - dispatch. The programmatic API is stable. The orchestrator's config - loading (`loadConfig`) is replaced by the factory's internal config - step — `tagRegistry` is accessed via `dataset.tagRegistry`. The merged - patterns array for `GenerateResult.patterns` and generator context is - `dataset.patterns` from the PatternGraph. - - DD-7: validate-patterns.ts and pattern-graph-cli.ts are unaffected. - They already consume the factory. The only change they see is - `PipelineResult.warnings` widening from `readonly string[]` to - `readonly PipelineWarning[]`, which is backward-compatible (they - currently ignore or stringify warnings). - - **Implementation Order:** - - | Step | What | Verification | - | 1 | Move mergePatterns to src/generators/pipeline/merge-patterns.ts | pnpm typecheck | - | 2 | Update imports in build-pipeline.ts, orchestrator.ts, generators/index.ts, orchestrator.steps.ts | pnpm typecheck, pnpm lint | - | 3 | Add PipelineWarning types to build-pipeline.ts | pnpm typecheck | - | 4 | Enrich factory to collect structured warnings and scan metadata | pnpm typecheck | - | 5 | Add includeValidation and failOnScanErrors options to factory | pnpm typecheck | - | 6 | Migrate generateDocumentation pipeline to factory call | pnpm build, pnpm test | - | 7 | Remove unused scanner/extractor imports from orchestrator.ts | pnpm lint | - | 8 | Full verification | pnpm build, pnpm test, pnpm lint, pnpm validate:patterns, pnpm docs:all | - - **Files Modified:** - - | File | Change | Lines Affected | - | src/generators/pipeline/merge-patterns.ts | NEW: mergePatterns moved from orchestrator | +~30 | - | src/generators/pipeline/build-pipeline.ts | Enrich PipelineResult, add options, collect warnings | +~60 | - | src/generators/pipeline/index.ts | Re-export merge-patterns | +2 | - | src/generators/orchestrator.ts | Replace pipeline with factory call, remove mergePatterns | -~170 net | - | src/generators/index.ts | Update mergePatterns re-export source | ~2 | - | tests/steps/generators/orchestrator.steps.ts | Update mergePatterns import to pipeline/merge-patterns | ~1 | - - **What does NOT change:** - - - GenerateOptions, GenerateResult, GeneratedFile interfaces (stable public API) - - Generator dispatch, file writing, PR-changes detection (orchestrator core) - - Session cleanup, generateFromConfig, groupGenerators (orchestrator utilities) - - generate-docs CLI (calls generateDocumentation unchanged) - - pattern-graph-cli.ts, validate-patterns.ts (already migrated) - - Existing test scenarios for orchestrator (same observable behavior) - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | - | Move mergePatterns to pipeline/merge-patterns.ts | complete | src/generators/pipeline/merge-patterns.ts | - | Add PipelineWarning structured types | complete | src/generators/pipeline/build-pipeline.ts | - | Enrich factory with structured warnings and scan metadata | complete | src/generators/pipeline/build-pipeline.ts | - | Add includeValidation and failOnScanErrors options | complete | src/generators/pipeline/build-pipeline.ts | - | Migrate generateDocumentation to factory call | complete | src/generators/orchestrator.ts | - | Remove unused scanner/extractor imports from orchestrator | complete | src/generators/orchestrator.ts | - | Full end-to-end verification | complete | CLI output | - - Rule: Orchestrator delegates pipeline to factory - - **Invariant:** `generateDocumentation()` calls `buildPatternGraph()` - for the scan-extract-merge-transform sequence. It does not import - from `scanner/` or `extractor/` for pipeline orchestration. Direct - imports are permitted only for types used in GenerateResult (e.g., - `ExtractedPattern`). - - **Rationale:** The orchestrator is the original host of the inline - pipeline. After this migration, the pipeline factory is the sole - definition of the 8-step sequence. Any future changes to pipeline - steps (adding caching, parallel scanning, incremental extraction) - happen in one place and all consumers benefit. - - **Verified by:** No pipeline imports in orchestrator, Factory is sole pipeline definition - - @acceptance-criteria - Scenario: No pipeline imports in orchestrator - Given the refactored orchestrator.ts - When inspecting import statements - Then no imports from scanner/ exist (except type imports) - And no imports from extractor/ exist (except type imports) - And the scanPatterns function is not called - And the extractPatterns function is not called - - @acceptance-criteria - Scenario: Factory is sole pipeline definition - Given the three CLI consumers: pattern-graph-cli, validate-patterns, orchestrator - When each needs a PatternGraph - Then each calls buildPatternGraph from build-pipeline.ts - And no consumer wires the 8-step pipeline inline - - Rule: mergePatterns lives in pipeline module - - **Invariant:** The `mergePatterns()` function lives in - `src/generators/pipeline/merge-patterns.ts` as a pipeline step. It is - not defined in consumer code (orchestrator or CLI files). - - **Rationale:** `mergePatterns` is step 5 of the 8-step pipeline. It - was defined in orchestrator.ts for historical reasons (the - orchestrator was the first pipeline host). Now that the pipeline - factory exists, the function belongs alongside other pipeline steps - (scan, extract, transform). The public API re-export in - `generators/index.ts` preserves backward compatibility. - - **Verified by:** mergePatterns location, Public API preserved - - @acceptance-criteria - Scenario: mergePatterns location - Given the refactored codebase - When inspecting src/generators/pipeline/merge-patterns.ts - Then mergePatterns is defined and exported there - And build-pipeline.ts imports it from ./merge-patterns.js - And orchestrator.ts does not define or export mergePatterns - - @acceptance-criteria - Scenario: Public API preserved - Given the generators barrel export in generators/index.ts - When inspecting mergePatterns re-export - Then mergePatterns is re-exported (from pipeline module) - And existing callers of mergePatterns compile without changes - - Rule: Factory provides structured warnings for all consumers - - **Invariant:** `PipelineResult.warnings` contains typed warning - objects with `type`, `message`, optional `count`, and optional - `details` (file, line, column, message). Consumers that need - granular diagnostics (orchestrator) use the full structure. Consumers - that need simple messages (pattern-graph-cli) read `.message` only. - - **Rationale:** The orchestrator collects scan errors, skipped - directives, extraction errors, and Gherkin parse errors as structured - `GenerationWarning` objects. The factory must provide equivalent - structure to eliminate the orchestrator's need to run the pipeline - directly. The `PipelineWarning` type is structurally similar to - `GenerationWarning` to minimize mapping complexity. - - **Verified by:** Orchestrator warnings preserved, Existing consumers unaffected - - @acceptance-criteria - Scenario: Orchestrator warnings preserved - Given a codebase with scan errors and Gherkin parse failures - When generateDocumentation runs via the factory - Then GenerationWarnings include scan error counts - And GenerationWarnings include Gherkin parse error details with file, line, column - And the warning output is identical to pre-refactor behavior - - @acceptance-criteria - Scenario: Existing consumers unaffected - Given pattern-graph-cli.ts and validate-patterns.ts consuming the factory - When PipelineResult.warnings changes from string[] to PipelineWarning[] - Then both consumers compile without changes - And runtime behavior is unchanged - - Rule: Pipeline factory supports partial success mode - - **Invariant:** When `failOnScanErrors` is false, the factory captures - scan errors and extraction errors as warnings and continues with - successfully processed files. When true (default), the factory returns - `Result.err` on the first scan failure. - - **Rationale:** The orchestrator treats scan errors as non-fatal - warnings — documentation generation should succeed for all scannable - files even if some files have syntax errors. The pattern-graph-cli treats - scan errors as fatal because the query layer requires a complete - dataset. The factory must support both strategies via configuration. - - **Verified by:** Partial success mode works - - @acceptance-criteria - Scenario: Partial success mode works - Given a codebase where 1 of 10 TypeScript files has a syntax error - When the factory runs with failOnScanErrors false - Then the result is Result.ok with 9 patterns - And warnings include the scan error for the failing file - And the pipeline does not return Result.err - - Rule: End-to-end verification confirms behavioral equivalence - - **Invariant:** After migration, all CLI commands and doc generation - produce identical output to pre-refactor behavior. - - **Rationale:** The migration must not change observable behavior for any - consumer. Full verification confirms the factory migration is a pure refactor. - - **Verified by:** Full verification passes - - @acceptance-criteria - Scenario: Full verification passes - Given the complete refactored codebase - When running pnpm build, pnpm test, pnpm lint, and pnpm validate:patterns - Then all pass with zero errors - And pnpm docs:all produces identical output to pre-refactor diff --git a/architect/specs/pattern-graph-api-cli.feature b/architect/specs/pattern-graph-api-cli.feature deleted file mode 100644 index be278b41..00000000 --- a/architect/specs/pattern-graph-api-cli.feature +++ /dev/null @@ -1,293 +0,0 @@ -@architect -@architect-pattern:PatternGraphAPICLI -@architect-status:completed -@architect-completed:2026-02-09 -@architect-unlock-reason:Terminology-alignment-rebrand -@architect-phase:24 -@architect-product-area:DataAPI -@architect-effort:2d -@architect-priority:high -@architect-business-value:direct-api-queries-for-planning -@architect-executable-specs:tests/features/api -Feature: PatternGraphAPI CLI - Direct Queries for Planning Sessions - - **Problem:** - The PatternGraphAPI provides 27 typed query methods for efficient state queries, but - Claude Code sessions cannot use it directly: - - Import paths require built packages with correct ESM resolution - - No CLI command exposes the API for shell invocation - - Current workaround requires regenerating markdown docs and reading them - - Documentation claims API is "directly usable" but practical usage is blocked - - **Solution:** - Add a CLI command `pnpm architect:query` that exposes key PatternGraphAPI methods: - - `--status active|roadmap|completed` - Filter patterns by status - - `--phase N` - Get patterns in specific phase - - `--progress` - Show completion percentage and counts - - `--current-work` - Show active patterns (shorthand for --status active) - - `--roadmap-items` - Show available items (roadmap + deferred) - - `--format text|json` - Output format (default: text, json for AI parsing) - - **Business Value:** - | Benefit | Impact | - | AI-native planning | Claude Code can query state in one command vs reading markdown | - | Reduced context usage | JSON output is 5-10x smaller than generated docs | - | Real-time accuracy | Queries source directly, no stale documentation | - | Session efficiency | "What's next?" answered in 100ms vs 10s regeneration | - | Completes API promise | Makes CLAUDE.md documentation accurate | - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | Tests | Test Type | - | architect:query CLI command | complete | src/cli/pattern-graph-cli.ts | Yes | integration | - | CLI argument parser | complete | src/cli/pattern-graph-cli.ts | Yes | integration | - | JSON output formatter | complete | src/cli/pattern-graph-cli.ts | Yes | integration | - | Text output formatter | n/a | N/A | No | N/A | - | Root package.json script | complete | package.json | No | N/A | - | CLAUDE.md documentation update | complete | CLAUDE.md | No | N/A | - - # ═══════════════════════════════════════════════════════════════════════════════ - # RULE 1: Status Queries - # ═══════════════════════════════════════════════════════════════════════════════ - - Rule: CLI supports status-based pattern queries - - **Invariant:** Every PatternGraphAPI status query method is accessible via CLI. - - **Rationale:** The most common planning question is "what's the current state?" - Status queries (active, roadmap, completed) answer this directly without reading docs. - Without CLI access, Claude Code must regenerate markdown and parse unstructured text. - - | Flag | API Method | Use Case | - | --status active | getCurrentWork() | "What am I working on?" | - | --status roadmap | getRoadmapItems() | "What can I start next?" | - | --status completed | getRecentlyCompleted() | "What's done recently?" | - | --current-work | getCurrentWork() | Shorthand for active | - | --roadmap-items | getRoadmapItems() | Shorthand for roadmap | - - **API:** See `@libar-dev/architect/src/cli/query-state.ts` - - **Verified by:** Query active patterns, Query roadmap items, Query completed patterns with limit - - @acceptance-criteria @happy-path - Scenario: Query active patterns - Given feature files with patterns in various statuses - When running "pnpm architect:query --status active" - Then output shows only patterns with status "active" - And each pattern shows name, phase, and categories - - @acceptance-criteria @happy-path - Scenario: Query roadmap items - Given feature files with roadmap and deferred patterns - When running "pnpm architect:query --roadmap-items" - Then output shows patterns with status "roadmap" or "deferred" - And output excludes completed and active patterns - - @acceptance-criteria @happy-path - Scenario: Query completed patterns with limit - Given many completed patterns - When running "pnpm architect:query --status completed --limit 5" - Then output shows at most 5 patterns - And patterns are sorted by completion recency - - # ═══════════════════════════════════════════════════════════════════════════════ - # RULE 2: Phase Queries - # ═══════════════════════════════════════════════════════════════════════════════ - - Rule: CLI supports phase-based queries - - **Invariant:** Patterns can be filtered by phase number. - - **Rationale:** Phase 18 (Event Durability) is the current focus per roadmap priorities. - Quick phase queries help assess progress and remaining work within a phase. - Phase-based planning is the primary organization method for roadmap work. - - | Flag | API Method | Use Case | - | --phase N | getPatternsByPhase(N) | "What's in Phase 18?" | - | --phase N --progress | getPhaseProgress(N) | "How complete is Phase 18?" | - | --phases | getAllPhases() | "List all phases with counts" | - - **API:** See `@libar-dev/architect/src/cli/query-state.ts` - - **Verified by:** Query patterns in a specific phase, Query phase progress, List all phases - - @acceptance-criteria @happy-path - Scenario: Query patterns in a specific phase - Given patterns in Phase 18 with various statuses - When running "pnpm architect:query --phase 18" - Then output shows all patterns tagged with phase 18 - And each pattern shows its status - - @acceptance-criteria @happy-path - Scenario: Query phase progress - Given Phase 18 with 3 completed and 2 roadmap patterns - When running "pnpm architect:query --phase 18 --progress" - Then output shows "Phase 18: 3/5 complete (60%)" - And output lists pattern names by status - - @acceptance-criteria @happy-path - Scenario: List all phases - Given patterns across phases 14, 18, 19, 20, 21, 22 - When running "pnpm architect:query --phases" - Then output shows each phase with pattern count - And phases are sorted numerically - - # ═══════════════════════════════════════════════════════════════════════════════ - # RULE 3: Progress Queries - # ═══════════════════════════════════════════════════════════════════════════════ - - Rule: CLI provides progress summary queries - - **Invariant:** Overall and per-phase progress is queryable in a single command. - - **Rationale:** Planning sessions need quick answers to "where are we?" without - reading the full PATTERNS.md generated file. Progress metrics drive prioritization - and help identify where to focus effort. - - | Flag | API Method | Use Case | - | --progress | getStatusCounts() + getCompletionPercentage() | Overall progress | - | --distribution | getStatusDistribution() | Detailed status breakdown | - - **API:** See `@libar-dev/architect/src/cli/query-state.ts` - - **Verified by:** Overall progress summary, Status distribution with percentages - - @acceptance-criteria @happy-path - Scenario: Overall progress summary - Given 62 completed, 3 active, 26 planned patterns - When running "pnpm architect:query --progress" - Then output shows: - """ - Overall Progress: 62/91 (68%) - - Status Counts: - Completed: 62 - Active: 3 - Planned: 26 - """ - - @acceptance-criteria @happy-path - Scenario: Status distribution with percentages - Given patterns in various statuses - When running "pnpm architect:query --distribution" - Then output shows each status with count and percentage - And percentages sum to 100% - - # ═══════════════════════════════════════════════════════════════════════════════ - # RULE 4: Output Formats - # ═══════════════════════════════════════════════════════════════════════════════ - - Rule: CLI supports multiple output formats - - **Invariant:** JSON output is parseable by AI agents without transformation. - - **Rationale:** Claude Code can parse JSON directly. Text format is for human reading. - JSON format enables scripting and integration with other tools. The primary use case - is AI agent parsing where structured output reduces context and errors. - - | Flag | Output | Use Case | - | --format text | Human-readable tables | Terminal usage | - | --format json | Structured JSON | AI agent parsing, scripting | - - **API:** See `@libar-dev/architect/src/cli/formatters/` - - **Verified by:** JSON output format, Text output format (default), Invalid format flag - - @acceptance-criteria @happy-path - Scenario: JSON output format - Given active patterns exist - When running "pnpm architect:query --current-work --format json" - Then output is valid JSON - And JSON contains array of pattern objects - And each pattern has: name, status, phase, categories - - @acceptance-criteria @happy-path - Scenario: Text output format (default) - Given active patterns exist - When running "pnpm architect:query --current-work" - Then output is human-readable text - And patterns are formatted in a table - - @acceptance-criteria @validation - Scenario: Invalid format flag - When running "pnpm architect:query --format xml" - Then command exits with error - And error message suggests valid formats: text, json - - # ═══════════════════════════════════════════════════════════════════════════════ - # RULE 5: Pattern Lookup - # ═══════════════════════════════════════════════════════════════════════════════ - - Rule: CLI supports individual pattern lookup - - **Invariant:** Any pattern can be queried by name with full details. - - **Rationale:** During implementation, Claude Code needs to check specific pattern - status, deliverables, and dependencies without reading the full spec file. - Pattern lookup is essential for focused implementation work. - - | Flag | API Method | Use Case | - | --pattern NAME | getPattern(name) | "Show DCB pattern details" | - | --pattern NAME --deliverables | getPatternDeliverables(name) | "What needs to be built?" | - | --pattern NAME --deps | getPatternDependencies(name) | "What does this depend on?" | - - **API:** See `@libar-dev/architect/src/cli/query-state.ts` - - **Verified by:** Lookup pattern by name, Query pattern deliverables, Pattern not found - - @acceptance-criteria @happy-path - Scenario: Lookup pattern by name - Given a pattern "DurableFunctionAdapters" exists - When running "pnpm architect:query --pattern DurableFunctionAdapters" - Then output shows pattern name, status, phase - And output shows categories and description - - @acceptance-criteria @happy-path - Scenario: Query pattern deliverables - Given a pattern with 4 deliverables - When running "pnpm architect:query --pattern EventStoreDurability --deliverables" - Then output shows each deliverable with status and location - - @acceptance-criteria @validation - Scenario: Pattern not found - Given no pattern named "NonExistent" - When running "pnpm architect:query --pattern NonExistent" - Then command exits with error - And error message says "Pattern 'NonExistent' not found" - And suggests using --status roadmap to see available patterns - - # ═══════════════════════════════════════════════════════════════════════════════ - # RULE 6: Help and Discovery - # ═══════════════════════════════════════════════════════════════════════════════ - - Rule: CLI provides discoverable help - - **Invariant:** All flags are documented via --help with examples. - - **Rationale:** Claude Code can read --help output to understand available queries - without needing external documentation. Self-documenting CLIs reduce the need - for Claude Code to read additional context files. - - **API:** See `@libar-dev/architect/src/cli/query-state.ts` - - **Verified by:** Help output shows all flags, Help shows examples - - @acceptance-criteria @happy-path - Scenario: Help output shows all flags - When running "pnpm architect:query --help" - Then output lists all available flags - And each flag has a description - And common use cases are shown as examples - - @acceptance-criteria @happy-path - Scenario: Help shows examples - When running "pnpm architect:query --help" - Then output includes example commands: - """ - Examples: - pnpm architect:query --current-work # What's active? - pnpm architect:query --roadmap-items # What can I start? - pnpm architect:query --phase 18 --progress # Phase 18 status - pnpm architect:query --pattern DCB --deliverables # Pattern details - pnpm architect:query --progress --format json # For AI parsing - """ diff --git a/architect/specs/pattern-graph-api-relationship-queries.feature b/architect/specs/pattern-graph-api-relationship-queries.feature deleted file mode 100644 index b03d13e5..00000000 --- a/architect/specs/pattern-graph-api-relationship-queries.feature +++ /dev/null @@ -1,191 +0,0 @@ -@architect -@architect-pattern:PatternGraphAPIRelationshipQueries -@architect-status:completed -@architect-unlock-reason:Relationships-available-via-getPatternRelationships-superseded-by-DataAPIRelationshipGraph -@architect-phase:24 -@architect-product-area:DataAPI -@architect-effort:3d -Feature: PatternGraphAPI Relationship Queries - - **Problem:** PatternGraphAPI currently supports dependency queries (`uses`, `usedBy`, `dependsOn`, - `enables`) but lacks implementation relationship queries. Claude Code cannot ask "what code - implements this pattern?" or "what pattern does this file implement?" - - **Solution:** Extend PatternGraphAPI with relationship query methods that leverage the new - `implements`/`extends` tags from PatternRelationshipModel: - - Bidirectional traceability: spec → code and code → spec - - Inheritance hierarchy navigation: base → specializations - - Implementation discovery: pattern → implementing files - - **Business Value:** - | Benefit | How | - | Reduced context usage | Query exact relationships vs reading multiple files | - | Faster exploration | "Show implementations" in one call vs grep + read | - | Accurate traceability | Real-time from source annotations, not stale docs | - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | Tests | Test Type | - | Implementation relationship queries | superseded | src/api/pattern-graph-api.ts | No | N/A | - | Inheritance hierarchy queries | superseded | src/api/pattern-graph-api.ts | No | N/A | - | PatternGraphAPI type extensions | complete | src/api/types.ts | Yes | unit | - | Relationship query step definitions | superseded | N/A | No | N/A | - - # ═══════════════════════════════════════════════════════════════════════════════ - # RULE 1: Implementation Relationship Queries - # ═══════════════════════════════════════════════════════════════════════════════ - - Rule: API provides implementation relationship queries - - **Invariant:** Every pattern with `implementedBy` entries is discoverable via the API. - - **Rationale:** Claude Code needs to navigate from abstract patterns to concrete code. - Without this, exploration requires manual grep + file reading, wasting context tokens. - - | Query | Returns | Use Case | - | getImplementations(pattern) | File paths implementing the pattern | "Show me the code for EventStoreDurability" | - | getImplementedPatterns(file) | Patterns the file implements | "What patterns does outbox.ts implement?" | - | hasImplementations(pattern) | boolean | Filter patterns with/without implementations | - - **Verified by:** Query implementations for pattern, Query implemented patterns for file - - @acceptance-criteria @happy-path - Scenario: Query implementations for a pattern - Given a pattern "ProcessGuardLinter" exists - And files implement this pattern: - | File | Via Tag | - | src/lint/process-guard/decider.ts | @architect-implements:ProcessGuardLinter | - | src/lint/process-guard/derive-state.ts | @architect-implements:ProcessGuardLinter | - When querying getImplementations("ProcessGuardLinter") - Then the result should contain both file paths - And the result should be sorted alphabetically - - @acceptance-criteria @happy-path - Scenario: Query implemented patterns for a file - Given a file "decider.ts" with tag "@architect-implements:ProcessGuardLinter, ProcessGuardDecider" - When querying getImplementedPatterns("decider.ts") - Then the result should contain ["ProcessGuardLinter", "ProcessGuardDecider"] - - @acceptance-criteria @validation - Scenario: Query implementations for pattern with none - Given a pattern "FuturePattern" with no implementations - When querying getImplementations("FuturePattern") - Then the result should be an empty array - - # ═══════════════════════════════════════════════════════════════════════════════ - # RULE 2: Inheritance Hierarchy Queries - # ═══════════════════════════════════════════════════════════════════════════════ - - Rule: API provides inheritance hierarchy queries - - **Invariant:** Pattern inheritance chains are fully navigable in both directions. - - **Rationale:** Patterns form specialization hierarchies (e.g., ReactiveProjections extends - ProjectionCategories). Claude Code needs to understand what specializes a base pattern - and what a specialized pattern inherits from. - - | Query | Returns | Use Case | - | getExtensions(pattern) | Patterns extending this one | "What specializes ProjectionCategories?" | - | getBasePattern(pattern) | Pattern this extends (or null) | "What does ReactiveProjections inherit from?" | - | getInheritanceChain(pattern) | Full chain to root | "Show full hierarchy for CachedProjections" | - - **Verified by:** Query extensions, Query base pattern, Full inheritance chain - - @acceptance-criteria @happy-path - Scenario: Query extensions for a base pattern - Given patterns with inheritance: - | Pattern | Extends | - | ProjectionCategories | (none) | - | ReactiveProjections | ProjectionCategories | - | CachedProjections | ProjectionCategories | - When querying getExtensions("ProjectionCategories") - Then the result should contain ["ReactiveProjections", "CachedProjections"] - - @acceptance-criteria @happy-path - Scenario: Query base pattern - Given a pattern "ReactiveProjections" that extends "ProjectionCategories" - When querying getBasePattern("ReactiveProjections") - Then the result should be "ProjectionCategories" - - @acceptance-criteria @happy-path - Scenario: Full inheritance chain - Given patterns: - | Pattern | Extends | - | BaseProjection | (none) | - | ProjectionCategories | BaseProjection | - | ReactiveProjections | ProjectionCategories | - When querying getInheritanceChain("ReactiveProjections") - Then the result should be ["ReactiveProjections", "ProjectionCategories", "BaseProjection"] - - # ═══════════════════════════════════════════════════════════════════════════════ - # RULE 3: Combined Relationship Queries - # ═══════════════════════════════════════════════════════════════════════════════ - - Rule: API provides combined relationship views - - **Invariant:** All relationship types are accessible through a unified interface. - - **Rationale:** Claude Code often needs the complete picture: dependencies AND implementations - AND inheritance. A single call reduces round-trips and context switching. - - **API:** See `@libar-dev/architect/src/api/pattern-graph-api.ts` - - **Verified by:** Get all relationships, Filter by relationship type - - @acceptance-criteria @happy-path - Scenario: Get all relationships for a pattern - Given a pattern "DCB" with: - | Relationship | Values | - | uses | CMSDualWrite, CommandBus | - | usedBy | CommandOrchestrator | - | implementedBy | dcb-executor.ts | - | extends | (none) | - When querying getAllRelationships("DCB") - Then the result should include all relationship types - And each type should have its values populated - - @acceptance-criteria @happy-path - Scenario: Filter patterns by relationship existence - Given multiple patterns with varying relationships - When querying getPatternsWithImplementations() - Then only patterns with non-empty implementedBy should be returned - - # ═══════════════════════════════════════════════════════════════════════════════ - # RULE 4: Traceability Support - # ═══════════════════════════════════════════════════════════════════════════════ - - Rule: API supports bidirectional traceability queries - - **Invariant:** Navigation from spec to code and code to spec is symmetric. - - **Rationale:** Traceability is bidirectional by definition. If a spec links to code, - the code should link back to the spec. The API should surface broken links. - - | Query | Returns | Use Case | - | getTraceabilityStatus(pattern) | {hasSpecs, hasImplementations, isSymmetric} | Audit traceability completeness | - | getBrokenLinks() | Patterns with asymmetric traceability | Find missing back-links | - - **Verified by:** Check traceability status, Detect broken links - - @acceptance-criteria @happy-path - Scenario: Check traceability status for well-linked pattern - Given a pattern "DCB" with: - | Attribute | Value | - | executableSpecs | platform-core/tests/features/behavior/dcb | - | implementedBy | dcb-executor.ts, dcb-state.ts | - When querying getTraceabilityStatus("DCB") - Then hasSpecs should be true - And hasImplementations should be true - And isSymmetric should be true - - @acceptance-criteria @validation - Scenario: Detect broken traceability links - Given patterns with asymmetric links: - | Pattern | Has executableSpecs | Has implementedBy | - | PatternA | Yes | No | - | PatternB | No | Yes | - | PatternC | Yes | Yes | - When querying getBrokenLinks() - Then the result should include "PatternA" (missing implementations) - And the result should include "PatternB" (missing specs) - And the result should NOT include "PatternC" diff --git a/architect/specs/pattern-graph-layered-extraction.feature b/architect/specs/pattern-graph-layered-extraction.feature deleted file mode 100644 index a1924df0..00000000 --- a/architect/specs/pattern-graph-layered-extraction.feature +++ /dev/null @@ -1,324 +0,0 @@ -@architect -@architect-pattern:PatternGraphLayeredExtraction -@architect-status:completed -@architect-unlock-reason:Terminology-alignment-rebrand -@architect-phase:100 -@architect-effort:2d -@architect-product-area:DataAPI -@architect-include:process-workflow -@architect-depends-on:ValidatorReadModelConsolidation -@architect-business-value:separate-cli-shell-from-domain-logic-in-pattern-graph-cli -@architect-priority:high -Feature: Pattern Graph Layered Extraction - - **Problem:** - `pattern-graph-cli.ts` is 1,700 lines containing two remaining architectural - violations of ADR-006: - - 1. **Parallel Pipeline**: `buildPipeline()` (lines 488-561) wires the - same 8-step scan-extract-transform sequence that `validate-patterns.ts` - and `orchestrator.ts` also wire independently. Three consumers, three - copies of identical pipeline orchestration code. - - 2. **Inline Domain Logic**: `handleRules()` (lines 1096-1279, 184 lines) - builds nested `Map` hierarchies (area -> phase -> feature -> rules), - parses business rule annotations via codec-layer imports - (`parseBusinessRuleAnnotations`, `deduplicateScenarioNames`), and - computes aggregate statistics. This is query logic that belongs in the - API layer, not the CLI file. - - Most subcommand handlers already delegate correctly. Of the 16 handlers - in pattern-graph-cli.ts, 13 are thin wrappers over `src/api/` modules: - - | Handler | Delegates To | - | handleStatus | PatternGraphAPI methods | - | handleQuery | Dynamic API method dispatch | - | handlePattern | PatternGraphAPI methods | - | handleList | output-pipeline.ts | - | handleSearch | fuzzy-match.ts, pattern-helpers.ts | - | handleStubs | stub-resolver.ts | - | handleDecisions | stub-resolver.ts, pattern-helpers.ts | - | handlePdr | stub-resolver.ts | - | handleContext | context-assembler.ts, context-formatter.ts | - | handleFiles | context-assembler.ts, context-formatter.ts | - | handleDepTreeCmd | context-assembler.ts, context-formatter.ts | - | handleOverviewCmd | context-assembler.ts, context-formatter.ts | - | handleScopeValidate | scope-validator.ts | - - The remaining violations are: - - | Handler | Issue | Lines | - | handleRules | Inline domain logic: nested Maps, codec imports | 184 | - | handleArch | Partial: 6 sub-handlers delegate, 3 have trivial inline projections | 121 | - | buildPipeline | Parallel Pipeline: duplicates 8-step sequence | 74 | - - **Solution:** - Extract the two remaining violations into their proper layers: - - | Layer | Extraction | Location | - | Pipeline Factory | Shared scan-extract-transform sequence from buildPipeline | src/generators/pipeline/build-pipeline.ts | - | Query Handler | Business rules domain logic from handleRules | src/api/rules-query.ts | - - The CLI retains its routing responsibility: parse args, call pipeline - factory, route subcommand to API module, format output. - - **Design Decisions:** - - DD-1: Pipeline factory location and return type. - Location: `src/generators/pipeline/build-pipeline.ts`, re-exported from - `src/generators/pipeline/index.ts`. The factory returns - `Result` so each consumer can map errors - to its own strategy (pattern-graph-cli calls `process.exit(1)`, - validate-patterns throws, orchestrator returns `Result.err()`). - `PipelineResult` contains `{ dataset: RuntimePatternGraph, validation: - ValidationSummary }`. The `TagRegistry` is accessible via - `dataset.tagRegistry` and does not need a separate field. - - DD-2: Merge conflict strategy as a pipeline option. - The factory accepts `mergeConflictStrategy: 'fatal' | 'concatenate'`. - `'fatal'` returns `Result.err()` on conflicts (pattern-graph-cli behavior). - `'concatenate'` falls back to `[...ts, ...gherkin]` (validate-patterns - behavior per DD-1 in ValidatorReadModelConsolidation). This is the most - significant semantic difference between consumers. - - DD-3: Factory interface designed for future orchestrator migration. - The `PipelineOptions` interface includes `exclude`, `contextInferenceRules`, - and `includeValidation` fields that orchestrator.ts needs. However, the - actual orchestrator migration is deferred to a follow-up spec. The - orchestrator has 155 lines of pipeline with structured warning collection - (scan errors, extraction errors, Gherkin parse errors as - `GenerationWarning[]`). Integrating this into the factory adds risk to a - first extraction. This spec migrates pattern-graph-cli.ts and - validate-patterns.ts only. - - DD-4: handleRules domain logic extracts to `src/api/rules-query.ts`. - The new module exports `queryBusinessRules(dataset: RuntimePatternGraph, - filters: RulesFilters): RulesQueryResult`. The `RulesFilters` interface, - `RuleOutput` interface, and all nested Map construction move to this module. - The `parseBusinessRuleAnnotations` and `deduplicateScenarioNames` imports - move from CLI to API layer, which is the correct placement per ADR-006. - The CLI handler becomes: parse filters from args, call - `queryBusinessRules`, apply output modifiers, return. - - DD-5: handleStubs, handleDecisions, handlePdr already delegate correctly. - These handlers are thin CLI wrappers over `stub-resolver.ts` functions - (`findStubPatterns`, `resolveStubs`, `groupStubsByPattern`, - `extractDecisionItems`, `findPdrReferences`). The residual CLI code is - argument parsing and error formatting, which is CLI-shell responsibility. - No extraction needed. The original deliverables are marked n/a. - - DD-6: handleArch inline logic stays in CLI. - The `roles`, `context`, and `layer` listing sub-handlers have 3-5 line - `.map()` projections over `archIndex` pre-computed views. These are trivial - view formatting, not domain logic. The `dangling`, `orphans`, `blocking`, - `neighborhood`, `compare`, and `coverage` sub-handlers already delegate - to `arch-queries.ts` and `context-assembler.ts`. Extracting 3-line `.map()` - calls would add indirection with no architectural benefit. - - DD-7: validate-patterns.ts partially adopts the pipeline factory. - The factory replaces the PatternGraph construction pipeline (steps 1-8). - DoD validation and anti-pattern detection remain as direct stage-1 - consumers using raw scanned files (`scanResult.value.files`, - `gherkinScanResult.value.files`). This is correct per ADR-006: the - exception for `lint-patterns.ts` ("pure stage-1 consumer, no - relationships, no cross-source resolution, direct scanner consumption is - correct") applies equally to DoD validation (checking deliverable - completeness on raw Gherkin) and anti-pattern detection (checking tag - placement on raw scanned files). - - DD-8: Line count invariant replaced with qualitative criterion. - The original 500-line target for pattern-graph-cli.ts is unrealistic. After - extracting buildPipeline (74 lines) and handleRules (184 lines), the - file is ~1,400 lines. The remaining code is legitimate CLI responsibility: - parseArgs (134), showHelp (143), routeSubcommand (96), main (59), 13 thin - delegation handlers (~350), config defaults (50), types (60), imports (120). - Reaching 500 lines would require extracting arg parsing and help text to - separate files, which is file hygiene, not architectural layering. - The invariant becomes: no Map/Set construction in handler functions, each - domain query delegates to an `src/api/` module. - - **Implementation Order:** - - | Step | What | Verification | - | 1 | Create src/generators/pipeline/build-pipeline.ts with PipelineOptions and factory | pnpm typecheck | - | 2 | Export from src/generators/pipeline/index.ts barrel | pnpm typecheck | - | 3 | Migrate pattern-graph-cli.ts buildPipeline to factory call | pnpm typecheck, pnpm architect:query -- overview | - | 4 | Remove unused scanner/extractor imports from pattern-graph-cli.ts | pnpm lint | - | 5 | Migrate validate-patterns.ts PatternGraph pipeline to factory call | pnpm validate:patterns (0 errors, 0 warnings) | - | 6 | Create src/api/rules-query.ts with queryBusinessRules | pnpm typecheck | - | 7 | Slim handleRules in pattern-graph-cli.ts to thin delegation | pnpm architect:query -- rules | - | 8 | Export from src/api/index.ts barrel | pnpm typecheck | - | 9 | Full verification | pnpm build, pnpm test, pnpm lint, pnpm validate:patterns | - - **Files Modified:** - - | File | Change | Lines Affected | - | src/generators/pipeline/build-pipeline.ts | NEW: shared pipeline factory | +~100 | - | src/generators/pipeline/index.ts | Add re-export of build-pipeline | +2 | - | src/api/rules-query.ts | NEW: business rules query from handleRules | +~200 | - | src/api/index.ts | Add re-exports for rules-query | +5 | - | src/cli/pattern-graph-cli.ts | Replace buildPipeline + handleRules with delegations | -~280 net | - | src/cli/validate-patterns.ts | Replace PatternGraph pipeline with factory call | -~30 net | - - **What does NOT change:** - - - parseArgs(), showHelp(), routeSubcommand(), main() (CLI shell) - - handleArch inline logic (trivial projections per DD-6) - - handleStubs/handleDecisions/handlePdr (already delegate per DD-5) - - generateEmptyHint (UX concern, correctly in CLI) - - DoD validation and anti-pattern detection in validate-patterns.ts (stage-1 consumers per DD-7) - - orchestrator.ts pipeline wiring (deferred per DD-3) - - parseListFilters, parseRulesFilters (arg parsing, not domain logic) - - ValidationIssue, ValidationSummary, ValidateCLIConfig (stable API in validate-patterns) - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | - | Create shared pipeline factory | complete | src/generators/pipeline/build-pipeline.ts | - | pattern-graph-cli.ts consumes pipeline factory | complete | src/cli/pattern-graph-cli.ts | - | validate-patterns.ts consumes pipeline factory (PatternGraph only) | complete | src/cli/validate-patterns.ts | - | Extract handleRules to rules-query.ts | complete | src/api/rules-query.ts | - | Update barrel exports | complete | src/api/index.ts, src/generators/pipeline/index.ts | - | End-to-end verification | complete | CLI output | - - Rule: CLI file contains only routing, no domain logic - - **Invariant:** `pattern-graph-cli.ts` parses arguments, calls the pipeline - factory for the PatternGraph, routes subcommands to API modules, and - formats output. It does not build Maps, filter patterns, group data, - or resolve relationships. Thin view projections (3-5 line `.map()` - calls over pre-computed archIndex views) are acceptable as formatting. - - **Rationale:** Domain logic in the CLI file is only accessible via the - command line. Extracting it to `src/api/` makes it programmatically - testable, reusable by future consumers (MCP server, watch mode), and - aligned with the feature-consumption layer defined in ADR-006. - - **Verified by:** No domain data structures in handlers, All domain queries delegate - - @acceptance-criteria - Scenario: No domain data structures in handlers - Given the refactored pattern-graph-cli.ts - When inspecting handler functions - Then no Map or Set construction exists for domain data grouping - And no imports from renderable/codecs/ exist in the CLI file - And each subcommand with domain logic delegates to an src/api/ module - - @acceptance-criteria - Scenario: All domain queries delegate - Given handleRules business rules grouping - When extracted to src/api/rules-query.ts - Then the CLI handler parses filters, calls queryBusinessRules, and formats output - And the queryBusinessRules function is a pure function taking RuntimePatternGraph - And the nested Map construction lives in rules-query.ts, not pattern-graph-cli.ts - - Rule: Pipeline factory is shared across CLI consumers - - **Invariant:** The scan-extract-transform sequence is defined once in - `src/generators/pipeline/build-pipeline.ts`. CLI consumers that need a - PatternGraph call the factory rather than wiring the pipeline - independently. The factory accepts `mergeConflictStrategy` to handle - behavioral differences between consumers. - - **Rationale:** Three consumers (pattern-graph-cli, validate-patterns, - orchestrator) independently wire the same 8-step sequence: loadConfig, - scanPatterns, extractPatterns, scanGherkinFiles, - extractPatternsFromGherkin, mergePatterns, computeHierarchyChildren, - transformToPatternGraph. The only semantic difference is merge-conflict - handling (fatal vs concatenate). This is a Parallel Pipeline anti-pattern - per ADR-006. - - **Verified by:** CLI consumers use factory, Orchestrator migration deferred - - @acceptance-criteria - Scenario: CLI consumers use factory - Given pattern-graph-cli.ts and validate-patterns.ts - When each needs a PatternGraph - Then each calls the shared pipeline factory from build-pipeline.ts - And pattern-graph-cli.ts does not import from scanner/ or extractor/ - And validate-patterns.ts uses the factory for PatternGraph but retains direct scans for DoD and anti-patterns - - @acceptance-criteria - Scenario: Orchestrator migration deferred - Given the pipeline factory interface - When inspecting PipelineOptions - Then it includes exclude, contextInferenceRules, and includeValidation fields - And orchestrator.ts is not yet migrated (follow-up spec) - And the factory API surface supports orchestrator migration without breaking changes - - Rule: Domain logic lives in API modules - - **Invariant:** Query logic that operates on PatternGraph lives in - `src/api/` modules. The `rules-query.ts` module provides business rules - querying with the same grouping logic that was inline in handleRules: - filter by product area and pattern, group by area -> phase -> feature -> - rules, parse annotations, compute totals. - - **Rationale:** `handleRules` is 184 lines with 5 Map/Set constructions, - codec-layer imports (`parseBusinessRuleAnnotations`, - `deduplicateScenarioNames`), and a complex 3-level grouping algorithm. - This is the last significant inline domain logic in pattern-graph-cli.ts. - Moving it to `src/api/` follows the same pattern as the 12 existing API - modules (context-assembler, arch-queries, scope-validator, etc.). - - **Verified by:** rules-query module exports, handleRules slim wrapper - - @acceptance-criteria - Scenario: rules-query module exports - Given the new src/api/rules-query.ts - When inspecting the module - Then it exports queryBusinessRules taking RuntimePatternGraph and RulesFilters - And it exports RulesQueryResult, RulesFilters, and RuleOutput types - And it is re-exported from src/api/index.ts - - @acceptance-criteria - Scenario: handleRules slim wrapper - Given the refactored handleRules in pattern-graph-cli.ts - When inspecting the function - Then it parses filters from CLI sub-args - And calls queryBusinessRules for the domain result - And applies output modifiers (count, namesOnly) on the result - And contains no Map or Set construction - - Rule: Pipeline factory returns Result for consumer-owned error handling - - **Invariant:** The factory returns `Result` - rather than throwing or calling `process.exit()`. Each consumer maps the - error to its own strategy: pattern-graph-cli.ts calls `process.exit(1)`, - validate-patterns.ts throws, and orchestrator.ts (future) returns - `Result.err()`. - - **Rationale:** The current `buildPipeline()` in pattern-graph-cli.ts calls - `process.exit(1)` on errors, making it non-reusable. The factory must - work across consumers with different error handling models. The Result - monad is the project's established pattern for this (see - `src/types/result.ts`). - - **Verified by:** Factory uses Result monad - - @acceptance-criteria - Scenario: Factory uses Result monad - Given the pipeline factory buildPatternGraph - When a config error, scan error, or merge conflict occurs - Then the factory returns Result.err with a structured PipelineError - And it does not call process.exit or throw - And the PipelineError includes the step that failed and the error details - - Rule: End-to-end verification confirms behavioral equivalence - - **Invariant:** After extraction, all CLI commands produce identical output - to pre-refactor behavior with zero build, test, lint, and validation errors. - - **Rationale:** The refactor must not change observable behavior. Full CLI - verification confirms the extraction is a pure refactor. - - **Verified by:** Full verification passes - - @acceptance-criteria - Scenario: Full verification passes - Given the complete refactored codebase - When running pnpm build, pnpm test, pnpm lint, and pnpm validate:patterns - Then all pass with zero errors - And pnpm architect:query -- overview produces the same output as before - And pnpm architect:query -- rules produces the same output as before - And pnpm architect:query -- rules --product-area DataAPI produces the same output as before diff --git a/architect/specs/pattern-relationship-model.feature b/architect/specs/pattern-relationship-model.feature deleted file mode 100644 index 3fd699b2..00000000 --- a/architect/specs/pattern-relationship-model.feature +++ /dev/null @@ -1,356 +0,0 @@ -@architect -@architect-pattern:PatternRelationshipModel -@architect-status:completed -@architect-unlock-reason:Normalize-deliverable-status-taxonomy -@architect-phase:99 -@architect-release:v1.0.0 -@architect-effort:2w -@architect-product-area:Annotation -@architect-level:epic -@architect-executable-specs:tests/features/behavior/pattern-relationships -Feature: Pattern Relationship Model - - **Problem:** The delivery process lacks a comprehensive relationship model between artifacts. - Code files, roadmap specs, executable specs, and patterns exist but their relationships - are implicit or limited to basic dependency tracking (`uses`, `depends-on`). - - **Solution:** Implement a relationship taxonomy inspired by UML/TML modeling practices: - - **Realization** (`implements`) - Code realizes a pattern specification - - **Generalization** (`extends`) - Pattern extends another pattern's capabilities - - **Dependency** (`uses`, `used-by`) - Technical dependencies between patterns - - **Composition** (`parent`, `level`) - Hierarchical pattern organization - - **Traceability** (`roadmap-spec`, `executable-specs`) - Cross-tier linking - - **Business Value:** - | Benefit | How | - | Complete dependency graphs | All relationships rendered in Mermaid with distinct arrow styles | - | Implementation tracking | `implements` links code stubs to roadmap specs | - | Code-sourced documentation | Generated docs pull from both .feature files AND code stubs | - | Impact analysis | Know what code breaks when pattern spec changes | - | Agentic workflows | Claude can navigate from pattern to implementations and back | - | UML-grade modeling | Professional relationship semantics enable rich tooling | - - # =========================================================================== - # DELIVERABLES - # =========================================================================== - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | Tests | Test Type | - | Implements tag in taxonomy registry | complete | src/taxonomy/registry-builder.ts | Yes | unit | - | Extends tag in taxonomy registry | complete | src/taxonomy/registry-builder.ts | Yes | unit | - | DocDirective schema update | complete | src/validation-schemas/doc-directive.ts | Yes | unit | - | ExtractedPattern schema update | complete | src/validation-schemas/extracted-pattern.ts | Yes | unit | - | RelationshipEntry schema update | complete | src/validation-schemas/pattern-graph.ts | Yes | unit | - | Relationship index enhancement | complete | src/generators/pipeline/transform-dataset.ts | Yes | unit | - | Mermaid graph enhancement | complete | src/renderable/codecs/patterns.ts | Yes | unit | - | Pattern detail implementations section | complete | src/renderable/codecs/patterns.ts | Yes | unit | - | Linter rules for relationship validation | complete | src/lint/rules.ts | Yes | unit | - - # ============================================================================ - # RULE 1: Realization Relationship (implements) - # ============================================================================ - - Rule: Code files declare pattern realization via implements tag - - **Invariant:** Files with `@architect-implements:PatternName,OtherPattern` are linked - to the specified patterns without causing conflicts. Pattern definitions remain in - roadmap specs; implementation files provide supplementary metadata. Multiple files can - implement the same pattern, and one file can implement multiple patterns. - - **Rationale:** This mirrors UML's "realization" relationship where a class implements - an interface. Code realizes the specification. Direction is code→spec (backward link). - CSV format allows a single implementation file to realize multiple patterns when - implementing a pattern family (e.g., durability primitives). - - **API:** See `src/taxonomy/registry-builder.ts` - - **Verified by:** Implements tag parsed, Multiple patterns supported, No conflict with pattern definition, Multiple implementations of same pattern - - @acceptance-criteria @happy-path - Scenario: Implements tag parsed from TypeScript - Given a TypeScript file with annotations: - """typescript - /** - * @architect - * @architect-implements EventStoreDurability - * @architect-status roadmap - * @architect-uses idempotentAppend, Workpool - */ - """ - When the scanner processes the file - Then the file is linked to pattern "EventStoreDurability" - And the relationship type is "implements" - And the file's `uses` metadata is preserved - - @acceptance-criteria @happy-path - Scenario: Multiple patterns implemented by one file - Given a TypeScript file with annotations: - """typescript - /** - * @architect - * @architect-implements EventStoreDurability, IdempotentAppend - */ - """ - When the scanner processes the file - Then the file is linked to both "EventStoreDurability" and "IdempotentAppend" - And both patterns list this file as an implementation - - @acceptance-criteria @happy-path - Scenario: No conflict with pattern definition - Given a roadmap spec with `@architect-pattern:EventStoreDurability` - And a TypeScript file with `@architect-implements:EventStoreDurability` - When the generator processes both - Then no conflict error is raised - And the implementation file is associated with the pattern - - @acceptance-criteria @happy-path - Scenario: Multiple files implement same pattern - Given three TypeScript files each with `@architect-implements:EventStoreDurability` - When the generator processes all files - Then all three are listed as implementations of "EventStoreDurability" - And each file's metadata is preserved separately - - # ============================================================================ - # RULE 2: Generalization Relationship (extends) - # ============================================================================ - - Rule: Pattern inheritance uses extends relationship tag - - **Invariant:** Files with `@architect-extends:BasePattern` declare that they extend - another pattern's capabilities. This is a generalization relationship where the - extending pattern is a specialization of the base pattern. - - **Rationale:** Pattern families exist where specialized patterns build on base patterns. - For example, `ReactiveProjections` extends `ProjectionCategories`. The extends - relationship enables inheritance-based documentation and validates pattern hierarchy. - - **API:** See `src/taxonomy/registry-builder.ts` - - **Verified by:** Extends tag parsed, Extended-by computed, Inheritance chain validated - - @acceptance-criteria @happy-path - Scenario: Extends tag parsed from feature file - Given a roadmap spec with: - """gherkin - @architect - @architect-pattern:ReactiveProjections - @architect-extends:ProjectionCategories - """ - When the scanner processes the file - Then the pattern "ReactiveProjections" is linked to base "ProjectionCategories" - And the relationship type is "extends" - - @acceptance-criteria @happy-path - Scenario: Extended-by reverse lookup computed - Given pattern A with `@architect-extends:B` - When the relationship index is built - Then pattern B's `extendedBy` includes "A" - - @acceptance-criteria @validation - Scenario: Circular inheritance detected - Given pattern A with `@architect-extends:B` - And pattern B with `@architect-extends:A` - When the linter runs - Then an error is emitted about circular inheritance - - # ============================================================================ - # RULE 3: Dependency Relationships (uses, used-by) - # ============================================================================ - - Rule: Technical dependencies use directed relationship tags - - **Invariant:** `@architect-uses` declares outbound dependencies (what this - pattern depends on). `@architect-used-by` declares inbound dependencies - (what depends on this pattern). Both are CSV format. - - **Rationale:** These represent technical coupling between patterns. The - distinction matters for impact analysis: changing a pattern affects its - `used-by` consumers but not its `uses` dependencies. - - **Verified by:** Uses rendered as solid arrows, Used-by aggregated correctly - - @acceptance-criteria @happy-path - Scenario: Uses rendered as solid arrows in graph - Given a pattern with `@architect-uses:CommandBus,EventStore` - When the Mermaid graph is generated - Then solid arrows point from pattern to "CommandBus" and "EventStore" - - @acceptance-criteria @happy-path - Scenario: Used-by aggregated in pattern detail - Given pattern A with `@architect-used-by:B,C` - When the pattern detail page is generated - Then the "Used By" section lists "B" and "C" - - # ============================================================================ - # RULE 4: Sequencing Relationships (depends-on, enables) - # ============================================================================ - - Rule: Roadmap sequencing uses ordering relationship tags - - **Invariant:** `@architect-depends-on` declares what must be completed first - (roadmap sequencing). `@architect-enables` declares what this unlocks when - completed. These are planning relationships, not technical dependencies. - - **Rationale:** Sequencing is about order of work, not runtime coupling. - A pattern may depend on another being complete without using its code. - - **Verified by:** Depends-on rendered as dashed arrows, Enables is inverse - - @acceptance-criteria @happy-path - Scenario: Depends-on rendered as dashed arrows - When the Mermaid graph is generated - Then a dashed arrow points from pattern to "EventStoreFoundation" - - @acceptance-criteria @happy-path - Scenario: Enables is inverse of depends-on - When the relationship index is built - Then pattern B's `enables` includes "A" - - # ============================================================================ - # RULE 5: Traceability Relationships (roadmap-spec, executable-specs) - # ============================================================================ - - Rule: Cross-tier linking uses traceability tags (PDR-007) - - **Invariant:** `@architect-executable-specs` on roadmap specs points to test - locations. `@architect-roadmap-spec` on package specs points back to the - pattern. These create bidirectional traceability. - - **Rationale:** Two-tier architecture (PDR-007) separates planning specs from - executable tests. Traceability tags maintain the connection for navigation - and completeness checking. - - **Verified by:** Bidirectional links established, Orphan detection - - @acceptance-criteria @happy-path - Scenario: Bidirectional links established - Given a roadmap spec with `@architect-executable-specs:platform-core/tests/features/durability` - And a package spec with `@architect-roadmap-spec:EventStoreDurability` - When the traceability index is built - Then the roadmap spec links forward to the package location - And the package spec links back to the pattern - - @acceptance-criteria @validation - Scenario: Orphan executable spec detected - Given a package spec with `@architect-roadmap-spec:NonExistentPattern` - When the linter runs - Then a warning is emitted about orphan executable spec - - # ============================================================================ - # RULE 6: Hierarchy Relationships (parent, level) - # ============================================================================ - - Rule: Epic/Phase/Task hierarchy uses parent-child relationships - - **Invariant:** `@architect-level` declares the hierarchy tier (epic, phase, task). - `@architect-parent` links to the containing pattern. This enables rollup - progress tracking. - - **Rationale:** Large initiatives decompose into phases and tasks. The hierarchy - allows progress aggregation (e.g., "Epic 80% complete based on child phases"). - - **Verified by:** Parent link validated, Progress rollup calculated - - @acceptance-criteria @happy-path - Scenario: Parent link validated - Given a phase spec with `@architect-parent:ProcessEnhancements` - And an epic spec with `@architect-pattern:ProcessEnhancements` - When the hierarchy is validated - Then the parent link is confirmed valid - - @acceptance-criteria @validation - Scenario: Invalid parent detected - Given a task spec with `@architect-parent:NonExistentEpic` - When the linter runs - Then an error is emitted about invalid parent reference - - # ============================================================================ - # RULE 7: Relationship Rendering in Generated Docs - # ============================================================================ - - Rule: All relationships appear in generated documentation - - **Invariant:** The PATTERNS.md dependency graph renders all relationship types - with distinct visual styles. Pattern detail pages list all related artifacts - grouped by relationship type. - - **Rationale:** Visualization makes the relationship model accessible. Different - arrow styles distinguish relationship semantics at a glance. - - | Relationship | Arrow Style | Direction | Description | - | uses | --> (solid) | OUT | Technical dependency | - | depends-on | -.-> (dashed) | OUT | Roadmap sequencing | - | implements | ..-> (dotted) | CODE→SPEC | Realization | - | extends | -->> (solid open) | CHILD→PARENT | Generalization | - - **Verified by:** Graph uses distinct styles, Detail page sections - - @acceptance-criteria @happy-path - Scenario: Graph uses distinct arrow styles - Given patterns with `uses`, `depends-on`, `implements`, and `extends` relationships - When the Mermaid graph is generated - Then `uses` renders as solid arrows (`-->`) - And `depends-on` renders as dashed arrows (`-.->`) - And `implements` renders as dotted arrows (`..->`) - And `extends` renders as solid open arrows (`-->>`) - - @acceptance-criteria @happy-path - Scenario: Pattern detail page shows all relationships - Given a pattern with implementations, dependencies, and tests - When the pattern detail page is generated - Then sections appear for "Implementations", "Dependencies", "Used By", "Tests" - - # ============================================================================ - # RULE 8: Linter Validates Relationship Integrity - # ============================================================================ - - Rule: Linter detects relationship violations - - **Invariant:** The pattern linter validates that all relationship targets exist, - implements files don't have pattern tags, and bidirectional links are consistent. - - **Rationale:** Broken relationships cause confusion and incorrect generated docs. - Early detection during linting prevents propagation of errors. - - **Verified by:** Missing target detected, Pattern conflict detected, Asymmetric link detected - - @acceptance-criteria @validation - Scenario: Missing relationship target detected - Given a file with `@architect-uses:NonExistentPattern` - When the linter runs with strict mode - Then a warning is emitted about unresolved relationship target - - @acceptance-criteria @validation - Scenario: Pattern tag in implements file causes error - Given a file with both `@architect-implements:X` and `@architect-pattern:X` - When the linter runs - Then an error is emitted about conflicting tags - And the message explains that implements files must not define patterns - - @acceptance-criteria @validation - Scenario: Asymmetric traceability detected - Given a roadmap spec with `@architect-executable-specs:path/to/tests` - And no package spec at that path with `@architect-roadmap-spec` back-link - When the linter runs with strict mode - Then a warning is emitted about missing back-link - - # ============================================================================ - # RELATIONSHIP TAXONOMY REFERENCE - # ============================================================================ - - # The following table summarizes all relationship types: - # - # | Tag | UML Analog | Direction | Format | Source | Target | Arrow | - # |-----|------------|-----------|--------|--------|--------|-------| - # | pattern | Identity | DEFINES | value | Spec | (self) | - | - # | implements | Realization | CODE→SPEC | csv | TypeScript | Pattern | ..-> | - # | extends | Generalization | CHILD→PARENT | value | Any | Pattern | -->> | - # | uses | Dependency | OUT | csv | Any | Pattern | --> | - # | used-by | Dependency | IN | csv | Any | Pattern | --> | - # | depends-on | Ordering | SEQUENCE | csv | Spec | Spec | -.-> | - # | enables | Ordering | SEQUENCE | csv | Spec | Spec | -.-> | - # | roadmap-spec | Traceability | TEST→SPEC | value | Package | Pattern | - | - # | executable-specs | Traceability | SPEC→TEST | csv | Roadmap | Package | - | - # | parent | Composition | CHILD→PARENT | value | Any | Pattern | - | - # | level | Hierarchy | TIER | enum | Any | (self) | - | diff --git a/architect/specs/phase-state-machine.feature b/architect/specs/phase-state-machine.feature deleted file mode 100644 index 45aea39c..00000000 --- a/architect/specs/phase-state-machine.feature +++ /dev/null @@ -1,101 +0,0 @@ -@architect -@architect-pattern:PhaseStateMachineValidation -@architect-status:completed -@architect-unlock-reason:Add-architect-opt-in-marker -@architect-phase:100 -@architect-release:v1.0.0 -@architect-effort:4h -@architect-product-area:Validation -@architect-business-value:ensure-state-machine-rules-are-enforced-programmatically -@architect-priority:high -Feature: Phase State Machine Validation - - **Problem:** - Phase lifecycle state transitions are not enforced programmatically despite being documented in PROCESS_SETUP.md. - Invalid transitions can occur silently, leading to inconsistent process state. - - **Solution:** - Implement state machine validation that: - - Validates all status transitions - - Enforces required metadata for terminal states - - Provides clear error messages for invalid transitions - - Integrates with generators and linters - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Tests | Location | - | FSM states and protection levels | complete | 123 | @libar-dev/architect/src/validation/fsm/states.ts | - | FSM transition matrix and validator | complete | 123 | @libar-dev/architect/src/validation/fsm/transitions.ts | - | Pure validation functions | complete | 123 | @libar-dev/architect/src/validation/fsm/validator.ts | - | Status validation lint rule | complete | 2190 | @libar-dev/architect/src/lint/rules.ts | - | PatternGraphAPI for programmatic queries | complete | 95 | @libar-dev/architect/src/api/pattern-graph-api.ts | - - Rule: Valid status values are enforced - - **Invariant:** Phase status must be one of the four canonical values: roadmap, active, completed, or deferred. - **Rationale:** Freeform status strings bypass FSM transition enforcement and produce undefined behavior in downstream generators and validators. - **Verified by:** Only valid status values are accepted; Invalid status values are rejected - - @acceptance-criteria - Scenario: Only valid status values are accepted - Given a feature file with status tag - When the status value is "roadmap", "active", "completed", or "deferred" - Then validation passes - - @acceptance-criteria - Scenario: Invalid status values are rejected - Given a feature file with status tag - When the status value is "done" or "in-progress" - Then validation fails with "Invalid status: must be roadmap, active, completed, or deferred" - - Rule: Status transitions follow state machine rules - - **Invariant:** Every status transition must follow a permitted edge in the FSM transition matrix. - **Rationale:** Skipping states (e.g., roadmap to completed) breaks scope-lock enforcement and allows incomplete deliverables to reach terminal status. - **Verified by:** Scenario Outline: Valid transitions are allowed; Scenario Outline: Invalid transitions are rejected - - @acceptance-criteria - Scenario Outline: Valid transitions are allowed - Given a phase with current status "" - When transitioning to status "" - Then the transition is valid - - Examples: - | from | to | - | roadmap | active | - | roadmap | deferred | - | roadmap | roadmap | - | active | completed | - | active | roadmap | - | deferred | roadmap | - - @acceptance-criteria - Scenario Outline: Invalid transitions are rejected - Given a phase with current status "" - When transitioning to status "" - Then the transition is rejected - And error message indicates valid transitions from "" - - Examples: - | from | to | - | completed | active | - | completed | roadmap | - | roadmap | completed| - - Rule: Terminal states require completion metadata - - **Invariant:** Phases reaching completed status must carry a completion date and actual effort tag. - **Rationale:** Without completion metadata, effort variance tracking and timeline reporting produce gaps that undermine delivery process visibility. - **Verified by:** Completed status requires completion date; Completed phases should have effort-actual - - @acceptance-criteria - Scenario: Completed status requires completion date - Given a phase transitioning to "completed" status - When the @architect-completed tag is missing - Then validation warns "Completed phases should have @architect-completed date" - - @acceptance-criteria - Scenario: Completed phases should have effort-actual - Given a phase transitioning to "completed" status - When the @architect-effort-actual tag is missing - Then validation warns "Completed phases should have @architect-effort-actual for variance tracking" diff --git a/architect/specs/procedural-guide-codec.feature b/architect/specs/procedural-guide-codec.feature deleted file mode 100644 index 3ba9fd34..00000000 --- a/architect/specs/procedural-guide-codec.feature +++ /dev/null @@ -1,307 +0,0 @@ -@architect -@architect-pattern:ProceduralGuideCodec -@architect-status:completed -@architect-unlock-reason:DD7-DD8-preamble-migration-complete -@architect-phase:35 -@architect-effort:3w -@architect-product-area:Generation -@architect-depends-on:DocsConsolidationStrategy -@architect-business-value:replaces-757-lines-of-manual-SESSION-GUIDES-and-ANNOTATION-GUIDE-with-generated-procedural-guides-using-dual-source-codec -@architect-priority:medium -Feature: Procedural Guide Codec - - **Problem:** - Two manual docs contain procedural content with no annotation source for generation: - `docs/SESSION-GUIDES.md` (389 lines) has session decision trees, per-session checklists, - prohibition lists, handoff templates, and discovery tag formats. `docs/ANNOTATION-GUIDE.md` - (268 lines) has a getting-started walkthrough, shape extraction mode explanations, the Zod - schema gotcha, file-type-specific annotation patterns, verification CLI recipes, and a - troubleshooting table. Gap analysis (WP-7) found only ~5% of this content is - auto-generatable from existing sources -- the remaining ~95% is procedural and editorial. - - The SessionGuidesModuleSource spec (Phase 39, completed) established 9 Rule: blocks with - session workflow invariants and generates compact AI context to `_claude-md/workflow/`. - However, these produce summary-level invariant statements for AI sessions, not the - developer-facing step-by-step checklists and decision trees that SESSION-GUIDES.md provides. - No generation path exists for the public-facing procedural guide content. - - **Solution:** - Create a `ProceduralGuideCodec` that uses a dual-source composition pattern: auto-generated - reference sections (tag reference tables, pattern statistics, session type contracts) are - derived from PatternGraph and taxonomy sources, while procedural content (checklists, - decision trees, getting-started walkthrough, troubleshooting tables) is authored as markdown - files in `docs-sources/` and parsed into `SectionBlock[]` at config load time by - `loadPreambleFromMarkdown()`. The codec produces two separate generated files -- one for - session workflow guides and one for annotation guides -- since these serve different - audiences (workflow practitioners vs annotation authors). - - Session workflow checklists are extracted from SessionGuidesModuleSource Rule: blocks and - rendered as developer-facing checklists at the detailed level. Decision trees render as - Mermaid flowchart diagrams, providing visual navigation that the manual docs express as - ASCII text trees. The generated output supersedes the manual files only after reaching - quality parity, respecting the SessionGuidesModuleSource invariant that SESSION-GUIDES.md - "is not deleted, shortened, or replaced with a redirect" during the transition period. - - **Why It Matters:** - | Benefit | How | - | Zero-drift session contracts | Session type table, FSM error reference, execution order regenerated from Rule: blocks | - | Dual audience from single source | SessionGuidesModuleSource Rule: blocks produce AI compact AND public checklists | - | Visual decision trees | Mermaid flowcharts replace ASCII art, render correctly in Starlight website | - | Separate guides for separate audiences | Session workflow guide and annotation guide are independent documents | - | Quality-gated transition | Manual files retained until generated equivalents match or exceed quality | - | Closes largest gap | WP-7 is the largest content gap (757 lines across 2 files with no generation source) | - - **Scope:** - | Content Section | Source | Mechanism | - | Session type decision tree | SessionGuidesModuleSource Rule 3 table | Auto-generated + Mermaid flowchart | - | Per-session checklists (Planning, Design, Implementation) | SessionGuidesModuleSource Rules 4-6 tables | Auto-generated from Rule: block tables | - | Session prohibition lists (Do NOT tables) | SessionGuidesModuleSource Rules 4, 6 tables | Auto-generated from Rule: block tables | - | FSM error reference and escape hatches | SessionGuidesModuleSource Rule 7 tables | Auto-generated from Rule: block tables | - | Handoff documentation template | SessionGuidesModuleSource Rule 8 | Auto-generated from Rule: block content | - | Context gathering CLI commands | Cannot derive from annotations | Markdown source -> loadPreambleFromMarkdown() | - | Getting-started annotation walkthrough | Cannot derive from annotations | Markdown source -> loadPreambleFromMarkdown() | - | Shape extraction mode explanations | Cannot derive from annotations | Markdown source -> loadPreambleFromMarkdown() | - | Zod schema gotcha and troubleshooting | Cannot derive from annotations | Markdown source -> loadPreambleFromMarkdown() | - | Tag reference summary table | Taxonomy registry data | Auto-generated from PatternGraph | - | Verification CLI recipes | Cannot derive from annotations | Markdown source -> loadPreambleFromMarkdown() | - - **Design Questions (for design session):** - | Question | Options | Recommendation | - | Should procedural content use new markers or preamble? | (A) New markers in Rule: blocks, (B) Preamble SectionBlock[] | (B) Preamble -- procedural content is editorial, not code-derivable | - | Can SessionGuidesModuleSource serve both AI and public output? | (A) Yes with detail levels, (B) No, separate sources | (A) Yes -- Rule: blocks have structured tables extractable at both levels | - | One combined codec or two separate codecs? | (A) One ProceduralGuideCodec with two configs, (B) Two separate codecs | (A) One codec -- same composition pattern, different ReferenceDocConfig entries | - | Should ANNOTATION-GUIDE content stay manual? | (A) Fully manual, (B) Hybrid with tag reference auto-generated | (B) Hybrid -- tag reference tables derive from taxonomy, walkthrough uses preamble | - | How to handle GHERKIN-PATTERNS.md overlap? | (A) Absorb into annotation guide, (B) Keep separate | (B) Keep separate -- GHERKIN-PATTERNS serves a different audience (spec authors vs annotation authors) | - | Should preamble be authored as markdown or inline SectionBlock[]? | (A) Markdown parsed at config time, (B) Inline SectionBlock[] in config | (A) Markdown -- natural authoring format, reduces config by ~540 lines, preserves codec purity | - - **Design Session Findings (2026-03-06):** - | Finding | Impact | Resolution | - | DD-1: No new codec class needed -- reuse createReferenceCodec() with two ReferenceDocConfig entries | Eliminates codec implementation deliverable; reduces to config-only work | Two ReferenceDocConfig entries in architect.config.ts with different preamble, includeTags, and output paths | - | DD-2: SessionGuidesModuleSource Rules 3-8 tables already machine-extractable | buildBehaviorSectionsFromPatterns() + parseBusinessRuleAnnotations() + extractTablesFromDescription() handle all table formats | Use includeTags:session-workflows on SessionGuidesModuleSource to route behavior content to session guide | - | DD-3: Checklists and decision trees use existing SectionBlock types | No new ChecklistBlock or DecisionTreeBlock needed; ListBlock with [ ] prefix = checkbox syntax; MermaidBlock = flowchart. SectionBlock[] produced by parsing markdown via loadPreambleFromMarkdown() | Zero schema/renderer changes required | - | DD-4: Preamble is flat SectionBlock[] produced from markdown source files | No new named-section abstraction; heading blocks provide structure. Content authored as markdown in docs-sources/, parsed into SectionBlock[] at config import time -- not inline TypeScript object literals | Preserves same preamble composition pattern; authoring ergonomics improved | - | DD-5: Annotation guide hybrid -- 95% preamble + 5% auto-generated tag tables | Stable editorial content as preamble; only tag reference tables auto-generated from taxonomy | Avoids circular dependency (guide about annotations needing annotations to generate) | - | DD-6: Generated files in docs-live/reference/ alongside manual files in docs/ | No violation of SessionGuidesModuleSource Rule 1 invariant; side-by-side quality comparison possible | Manual files retained until quality audit confirms parity; then superseded with unlock-reason | - | DD-7: Editorial content authored as markdown in docs-sources/ | Preamble SectionBlock[] parsed from markdown files at config import time by loadPreambleFromMarkdown(). Codec purity preserved -- codecs still receive in-memory SectionBlock[]. Config file reduced from 853 to ~310 lines (63% reduction). Natural authoring format for checklists, code blocks, tables, Mermaid diagrams | Two markdown source files: docs-sources/session-workflow-guide.md and docs-sources/annotation-guide.md | - | DD-8: loadPreambleFromMarkdown() is a shared utility in src/renderable/ | Uses readFileSync (sync, runs at module import). Line-by-line state machine parses headings, paragraphs, code/mermaid blocks, tables, lists into SectionBlock[]. Available to all preamble consumers (ErrorGuideCodec, CliRecipeCodec) | Resolves path relative to project root. CollapsibleBlock and LinkOutBlock not parsed (no standard markdown syntax; current preamble content does not use them) | - - **Design Stubs:** - | Stub | Purpose | Target | - | architect/stubs/procedural-guide-codec/procedural-codec-options.ts | Documents DD-1,DD-3,DD-4: no new options type, reuses ReferenceDocConfig | src/renderable/codecs/procedural-guide.ts | - | architect/stubs/procedural-guide-codec/procedural-codec.ts | Documents DD-1,DD-2,DD-5,DD-6,DD-7,DD-8: config entries with loadPreambleFromMarkdown() | architect.config.ts | - | architect/stubs/procedural-guide-codec/session-guide-preamble.ts | DD-7: Markdown source file example + loadPreambleFromMarkdown() usage | architect.config.ts | - | architect/stubs/procedural-guide-codec/annotation-guide-preamble.ts | DD-7: Markdown source file example + loadPreambleFromMarkdown() usage | architect.config.ts | - | architect/stubs/procedural-guide-codec/load-preamble.ts | DD-8: loadPreambleFromMarkdown() utility interface and parsing spec | src/renderable/load-preamble.ts | - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | Tests | Test Type | - | ReferenceDocConfig entry for session workflow guide (DD-1: reuses createReferenceCodec) | complete | architect.config.ts | Yes | integration | - | ReferenceDocConfig entry for annotation guide (DD-1: reuses createReferenceCodec) | complete | architect.config.ts | Yes | integration | - | Add @architect-include:session-workflows tag to SessionGuidesModuleSource (DD-2) | complete | architect/specs/session-guides-module-source.feature | No | n/a | - | Create loadPreambleFromMarkdown() utility (DD-8) | complete | src/renderable/load-preamble.ts | Yes | unit | - | Create session workflow guide markdown source (DD-7) | complete | docs-sources/session-workflow-guide.md | No | n/a | - | Create annotation guide markdown source (DD-7) | complete | docs-sources/annotation-guide.md | No | n/a | - | Migrate session workflow preamble to loadPreambleFromMarkdown() call (DD-7) | complete | architect.config.ts | Yes | integration | - | Migrate annotation guide preamble to loadPreambleFromMarkdown() call (DD-7) | complete | architect.config.ts | Yes | integration | - | Behavior spec with scenarios for procedural guide generation | n/a | tests/features/generation/procedural-guide-codec.feature | Yes | acceptance | - | Quality comparison: generated vs manual content audit (DD-6) | n/a | docs/SESSION-GUIDES.md | No | n/a | - - Rule: Procedural guides use a dual-source codec - - **Invariant:** The ProceduralGuideCodec composes auto-generated reference sections - (from PatternGraph and taxonomy) with manually-authored procedural content (from - preamble `SectionBlock[]`). Auto-generated content covers ~5% of the output (tag - reference tables, pattern statistics, session type contract tables extracted from - Rule: blocks). The remaining ~95% is editorial preamble: checklists, decision trees, - getting-started walkthroughs, troubleshooting tables, and verification recipes -- - authored as markdown files in `docs-sources/` and parsed into `SectionBlock[]` by - `loadPreambleFromMarkdown()` at config load time. The codec does not attempt to - generate procedural prose from annotations -- it provides a structured delivery - vehicle that ensures preamble and reference content are composed in a consistent - order with consistent formatting across both guide documents. - - **Rationale:** Gap analysis found that SESSION-GUIDES.md and ANNOTATION-GUIDE.md - content is overwhelmingly procedural and editorial. Attempting to annotate checklists - and walkthroughs as source code would produce worse documentation than hand-authoring. - The dual-source pattern (proven by CodecDrivenReferenceGeneration, ErrorGuideCodec, - and CliRecipeCodec) composes preamble editorial content with auto-generated reference - sections. The codec's value is not in generating the procedural content but in - providing a single output pipeline that keeps reference tables current while carrying - editorial content in a consistent structure. - - **Verified by:** Codec output contains both preamble and generated sections, - Generated reference sections update when source data changes - - @acceptance-criteria @happy-path - Scenario: ProceduralGuideCodec composes preamble with generated reference - Given a ProceduralGuideCodec configured with preamble checklist content - And the PatternGraph contains session type metadata from SessionGuidesModuleSource - When the codec generates the session workflow guide - Then preamble checklist sections appear first in the output - And auto-generated session type contract tables follow the preamble - And tag reference tables from taxonomy data appear in the reference section - - @acceptance-criteria @validation - Scenario: Generated reference sections update when source data changes - Given the SessionGuidesModuleSource spec adds a new session type to Rule 3 - When the ProceduralGuideCodec regenerates the session workflow guide - Then the session type contract table includes the new session type - And preamble content is unchanged - - Rule: Session workflow checklists derive from annotated Rule: blocks - - **Invariant:** The SessionGuidesModuleSource spec's Rule: blocks (Rules 3-8) are the - canonical source for session workflow invariants. The ProceduralGuideCodec extracts - structured tables from these Rule: blocks and renders them as developer-facing - checklists at the detailed level. The same Rule: blocks produce compact invariant - statements for `_claude-md/workflow/` modules at the summary level. Two audiences - (public developers and AI sessions) are served from a single annotated source with - different rendering detail levels. The codec does not duplicate or re-derive Rule: - block content -- it reads from PatternGraph's behavior extraction views. - - **Rationale:** SessionGuidesModuleSource already captures session type contracts - (Rule 3), planning constraints (Rule 4), design constraints (Rule 5), implementation - execution order (Rule 6), FSM error reference (Rule 7), and handoff patterns (Rule 8) - as structured tables within Rule: block descriptions. These tables contain the same - information as the manual SESSION-GUIDES.md checklists, but in a machine-extractable - format. Rendering these as developer-facing checklists eliminates the maintenance - burden of keeping the manual file in sync with the spec, while the compact rendering - for AI context was already delivered by Phase 39. - - **Verified by:** Checklists render from SessionGuidesModuleSource Rule: blocks, - Both detail levels render from the same source - - @acceptance-criteria @happy-path - Scenario: Session checklists render from Rule: block extraction - Given SessionGuidesModuleSource contains Rule 4 with a planning Do/Do-NOT table - And Rule 6 with an implementation execution order list - When the ProceduralGuideCodec renders the session workflow guide at detailed level - Then a Planning Session section contains a checklist derived from Rule 4 - And an Implementation Session section contains a numbered execution order from Rule 6 - And the checklist items match the Rule: block table content - - @acceptance-criteria @validation - Scenario: Summary level produces compact invariants not full checklists - Given the ProceduralGuideCodec configured for summary detail level - When rendering the session workflow guide - Then session type contracts appear as a compact table - And full checklists are omitted in favor of invariant statements - And the summary output is suitable for AI context consumption - - Rule: Annotation guide content remains separate from session guides - - **Invariant:** The ProceduralGuideCodec produces two separate generated files via two - `ReferenceDocConfig` entries: one for session workflow guides (replacing SESSION-GUIDES.md) - and one for annotation guides (replacing ANNOTATION-GUIDE.md). The session workflow guide - targets workflow practitioners who need to know session type selection, execution order, - and FSM error recovery. The annotation guide targets annotation authors who need to know - opt-in markers, tag syntax, shape extraction modes, and verification steps. These - audiences overlap but have distinct primary needs. The codec class is shared; the config - entries and preamble content differ. - - **Rationale:** SESSION-GUIDES.md and ANNOTATION-GUIDE.md serve different audiences at - different points in the development lifecycle. Merging them into a single guide would - force annotation authors to navigate session workflow content and vice versa. The - existing DocsConsolidationStrategy Phase 5 (Guide trimming) already treats them as - separate documents. Using one codec class with two config entries follows the same - pattern as `createReferenceCodec` producing multiple documents from different configs. - - **Verified by:** Two separate generated files from two config entries, - Session guide has no annotation walkthrough content - - @acceptance-criteria @happy-path - Scenario: Two separate guide files are generated - Given the ProceduralGuideCodec with two ReferenceDocConfig entries - And one entry targets session workflow guide output - And the other entry targets annotation guide output - When the codec generates both documents - Then docs-live/reference/SESSION-WORKFLOW-GUIDE.md is created - And docs-live/reference/ANNOTATION-REFERENCE.md is created - And the two files have no duplicated sections - - @acceptance-criteria @validation - Scenario: Session guide contains no annotation walkthrough content - Given the generated session workflow guide - When inspecting its sections - Then no getting-started annotation walkthrough appears - And no shape extraction mode explanation appears - And the content focuses exclusively on session types, checklists, and FSM reference - - Rule: Decision trees render as Mermaid flowcharts - - **Invariant:** Session type decision trees and annotation workflow decision trees render - as Mermaid flowchart diagrams in the detailed output level. The session type decision - tree replaces the ASCII art tree in SESSION-GUIDES.md with a Mermaid `graph TD` diagram - that renders as an interactive flowchart on the Starlight website. Decision tree content - is authored as fenced mermaid code blocks in the markdown source file, parsed into - `MermaidBlock` entries by `loadPreambleFromMarkdown()` at config load time. At summary - level, decision trees render as compact text tables instead of diagrams. - - **Rationale:** The manual SESSION-GUIDES.md uses an ASCII art tree for the session - decision flow, which renders poorly on the website and cannot be interacted with. - Mermaid flowcharts are already supported by the Starlight website (proven by product - area docs with C4Context and graph LR diagrams). Converting decision trees to Mermaid - provides visual clarity, click-through navigation, and consistent rendering across - platforms. The content block type `mermaid` is already one of the 9 supported - SectionBlock types (proven by ReferenceDocShowcase). - - **Verified by:** Decision tree renders as Mermaid flowchart, - Summary level uses text table instead of diagram - - @acceptance-criteria @happy-path - Scenario: Session decision tree renders as Mermaid flowchart - Given the session workflow guide preamble contains a Mermaid graph TD diagram - And the diagram models the session type decision flow - When the ProceduralGuideCodec renders at detailed level - Then the output contains a Mermaid code block with the decision tree - And the diagram includes nodes for Planning, Design, Implementation, and Planning+Design - And decision edges use conditional labels - - @acceptance-criteria @validation - Scenario: Summary level renders decision tree as text table - Given the ProceduralGuideCodec configured for summary detail level - When rendering the session workflow guide - Then the decision tree appears as a compact text table mapping conditions to session types - And no Mermaid code block appears in the summary output - - Rule: Generated guide supersedes manual only at quality parity - - **Invariant:** The manual `docs/SESSION-GUIDES.md` is retained in the repository - until the generated equivalent matches or exceeds its quality across all content - dimensions: completeness (all checklists present), accuracy (all FSM states current), - visual clarity (decision trees render correctly), and usability (verified by comparison - audit). The SessionGuidesModuleSource invariant ("not deleted, shortened, or replaced - with a redirect") is respected during the transition period. The quality comparison - deliverable produces an explicit audit document recording which sections have parity - and which gaps remain. Only after the audit confirms full parity is the manual file - replaced with a pointer to the generated output. - - **Rationale:** SESSION-GUIDES.md is cited in the SessionGuidesModuleSource spec as - "the authoritative public human reference" serving developers on libar.dev. Replacing - it prematurely with a generated equivalent that lacks checklists, has formatting issues, - or omits edge cases would degrade the developer experience. The quality-gated approach - ensures the generated version earns its place as the replacement by demonstrating - equivalent or better quality, not merely by existing. This is the same principle applied - by DocsConsolidationStrategy: "Manual docs retain editorial and tutorial content" until - generation quality is sufficient. - - **Verified by:** Manual file retained during transition, - Quality audit produces explicit parity assessment - - @acceptance-criteria @happy-path - Scenario: Manual SESSION-GUIDES.md is retained during transition - Given the ProceduralGuideCodec has generated docs-live/reference/SESSION-WORKFLOW-GUIDE.md - And the quality audit has not yet confirmed parity - When inspecting the repository - Then docs/SESSION-GUIDES.md still exists with its original content - And docs/SESSION-GUIDES.md is not shortened or replaced with a redirect - And docs-live/reference/SESSION-WORKFLOW-GUIDE.md exists alongside it - - @acceptance-criteria @validation - Scenario: Quality audit produces explicit parity assessment - Given the generated session workflow guide and the manual SESSION-GUIDES.md - When performing the quality comparison audit - Then an audit record documents each section of SESSION-GUIDES.md - And each section is marked as parity-achieved or gap-remaining - And sections with gaps include a description of what is missing diff --git a/architect/specs/process-guard-linter.feature b/architect/specs/process-guard-linter.feature deleted file mode 100644 index 3b4d2ed4..00000000 --- a/architect/specs/process-guard-linter.feature +++ /dev/null @@ -1,332 +0,0 @@ -@architect -@architect-pattern:ProcessGuardLinter -@architect-status:completed -@architect-unlock-reason:Complete-deliverables-for-v1.0.0-release -@architect-phase:99 -@architect-release:v1.0.0 -@architect-effort:1d -@architect-product-area:Validation -@architect-business-value:prevent-accidental-scope-creep-and-locked-file-modifications -@architect-priority:high -Feature: Process Guard Linter - - **Problem:** - During planning and implementation sessions, accidental modifications occur: - - Specs outside the intended scope get modified in bulk - - Completed/approved work gets inadvertently changed - - No enforcement boundary between "planning what to do" and "doing it" - - The delivery process has implicit states (planning, implementing) but no - programmatic guard preventing invalid state transitions or out-of-scope changes. - - **Solution:** - Implement a Decider-based linter that: - 1. Derives process state from existing file annotations (no separate state file) - 2. Validates proposed changes (git diff) against derived state - 3. Enforces file protection levels per PDR-005 state machine - 4. Supports explicit session scoping via session definition files - 5. Protects taxonomy from changes that would break protected specs - - **Design Principles:** - - State is derived from annotations, not maintained separately - - Decider logic is pure (no I/O), enabling unit testing - - Integrates with existing lint infrastructure (`lint-process.ts`) - - Warnings for soft rules, errors for hard rules - - Escape hatch via `@architect-unlock-reason` annotation - - **Relationship to PDR-005:** - Uses the phase-state-machine FSM as protection levels: - - `roadmap`: Fully editable, no restrictions (planning phase) - - `active`: Scope-locked, errors on new deliverables (work in progress) - - `completed`: Hard-locked, requires explicit unlock to modify - - `deferred`: Fully editable, no restrictions (parked work) - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | - | State derivation from annotations | complete | src/lint/process-guard/derive-state.ts | - | Git diff change detection | complete | src/lint/process-guard/detect-changes.ts | - | Process Decider (pure validation) | complete | src/lint/process-guard/decider.ts | - | Protection level rules | complete | src/lint/process-guard/decider.ts | - | Session scope validation | complete | src/lint/process-guard/decider.ts | - | Taxonomy stability validation | complete | src/lint/process-guard/decider.ts | - | CLI integration (lint-process.ts) | complete | src/cli/lint-process.ts | - | Pre-commit hook integration | complete | .husky/pre-commit | - - # ============================================================================ - # PROTECTION LEVELS - # ============================================================================ - - Rule: Protection levels determine modification restrictions - - **Invariant:** Every file's modification restrictions are determined solely by its `@architect-status` tag, with `completed` requiring an explicit unlock reason for any change. - **Rationale:** Without status-derived protection, completed and approved work can be silently overwritten by bulk edits or accidental modifications. - **Verified by:** Scenario Outline: Protection level from status; Completed file modification without unlock fails; Completed file modification with unlock passes; Active file modification is allowed but scope-locked - - Files inherit protection from their `@architect-status` tag. Higher - protection levels require explicit unlock to modify. - - @acceptance-criteria - Scenario Outline: Protection level from status - Given a feature file with @architect-status: - When deriving protection level - Then protection level is "" - And modification restriction is "" - - Examples: - | status | protection | restriction | - | roadmap | none | Fully editable | - | deferred | none | Fully editable | - | active | scope | Errors on new deliverables | - | completed | hard | Requires @architect-unlock-reason | - - @acceptance-criteria - Scenario: Completed file modification without unlock fails - Given a feature file with @architect-status:completed - When modifying the file without @architect-unlock-reason - Then linting fails with "completed-protection" violation - And message is "Cannot modify completed spec without unlock reason" - - @acceptance-criteria - Scenario: Completed file modification with unlock passes - Given a feature file with @architect-status:completed - Then linting passes - And warning indicates "Modifying completed spec: Critical bug fix" - - @acceptance-criteria - Scenario: Active file modification is allowed but scope-locked - Given a feature file with @architect-status:active - When modifying existing content - Then linting passes - But adding new deliverables triggers scope-creep violation - - # ============================================================================ - # SESSION SCOPE ENFORCEMENT - # ============================================================================ - - Rule: Session definition files scope what can be modified - - **Invariant:** When an active session exists, only specs explicitly listed in the session definition may be modified without warning, and excluded specs cannot be modified at all. - **Rationale:** Without session scoping, bulk operations and context switches cause unintended modifications to specs outside the current work focus. - **Verified by:** Session file defines modification scope; Modifying spec outside active session scope warns; Modifying explicitly excluded spec fails; No active session allows all modifications - - Optional session files (`architect/sessions/*.feature`) explicitly - declare which specs are in-scope for modification during a work session. - If active, modifications outside scope trigger warnings or errors. - - @acceptance-criteria - Scenario: Session file defines modification scope - Given a session file with @architect-session-id:S-2026-01-09 - And session status is "active" - And in-scope specs are: - | spec | intent | - | mvp-workflow-implementation | modify | - | short-form-tag-migration | review | - When deriving process state - Then session "S-2026-01-09" is active - And "mvp-workflow-implementation" is modifiable - And "short-form-tag-migration" is review-only - - @acceptance-criteria - Scenario: Modifying spec outside active session scope warns - Given session "S-2026-01-09" is active with scoped specs: - | spec | - | mvp-workflow-implementation | - When modifying "phase-state-machine.feature" - Then linting warns with "session-scope" - And message contains "not in session scope" - And suggestion is "Add to session scope or use --ignore-session flag" - - @acceptance-criteria - Scenario: Modifying explicitly excluded spec fails - Given session "S-2026-01-09" explicitly excludes "cross-source-validation" - When modifying "cross-source-validation.feature" - Then linting fails with "session-excluded" violation - And message is "Spec explicitly excluded from session S-2026-01-09" - - @acceptance-criteria - Scenario: No active session allows all modifications - Given no session file exists with status "active" - When modifying any spec file - Then session scope rules do not apply - And only protection level rules are checked - - # ============================================================================ - # STATUS TRANSITION VALIDATION - # ============================================================================ - - Rule: Status transitions follow PDR-005 FSM - - **Invariant:** Every status change must follow a valid edge in the PDR-005 finite state machine; no transition may skip intermediate states. - **Rationale:** Skipping states (e.g., `roadmap` directly to `completed`) bypasses scope-locking and review gates, allowing incomplete work to be marked as done. - **Verified by:** Scenario Outline: Valid status transitions; Scenario Outline: Invalid status transitions - - Status changes in a file must follow a valid transition per PDR-005. - This extends phase-state-machine.feature to the linter context. - - @acceptance-criteria - Scenario Outline: Valid status transitions - Given a spec with current @architect-status: - When changing status to - Then transition validation passes - - Examples: - | from | to | - | roadmap | active | - | roadmap | deferred | - | active | completed | - | active | roadmap | - | deferred | roadmap | - | roadmap | roadmap | - - @acceptance-criteria - Scenario Outline: Invalid status transitions - Given a spec with current @architect-status: - When changing status to - Then linting fails with "invalid-status-transition" violation - And message indicates valid transitions from "" - - Examples: - | from | to | - | roadmap | completed | - | deferred | active | - | deferred | completed | - | completed | active | - | completed | roadmap | - | completed | deferred | - - # ============================================================================ - # DELIVERABLE INTEGRITY - # ============================================================================ - - Rule: Active specs cannot add new deliverables - - **Invariant:** The deliverables table of an `active` spec is immutable with respect to new rows; only existing deliverable statuses may change. - **Rationale:** Adding deliverables after work has begun constitutes scope creep, undermining effort estimates and blocking completion. - **Verified by:** Adding deliverable to active spec fails; Updating deliverable status in active spec passes; Removing deliverable from active spec warns - - Once a spec transitions to `active`, its deliverables table is - considered scope-locked. Adding new rows indicates scope creep. - - @acceptance-criteria - Scenario: Adding deliverable to active spec fails - Given a spec with @architect-status:active - And existing deliverables: - | Deliverable | Status | - | Task A | complete | - | Task B | pending | - When adding new deliverable "Task C" - Then linting fails with "scope-creep" violation - And message is "Cannot add deliverables to active spec" - And suggestion is "Create new spec or revert to roadmap status" - - @acceptance-criteria - Scenario: Updating deliverable status in active spec passes - Given a spec with @architect-status:active - And existing deliverables: - | Deliverable | Status | - | Task A | pending | - When changing Task A status to "Done" - Then linting passes - - @acceptance-criteria - Scenario: Removing deliverable from active spec warns - Given a spec with @architect-status:active - When removing a deliverable row - Then linting warns with "deliverable-removed" - And message is "Deliverable removed from active spec - was it completed or descoped?" - - # ============================================================================ - # CLI INTERFACE - # ============================================================================ - - Rule: CLI provides flexible validation modes - - **Invariant:** The CLI must support both pre-commit (staged-only) and CI (all-files) validation modes with deterministic exit codes reflecting violation severity. - **Rationale:** Without flexible modes, teams cannot integrate process guard into both local developer workflows and CI pipelines with appropriate strictness levels. - **Verified by:** Validate staged changes (pre-commit default); Validate all tracked files; Show derived state for debugging; Strict mode treats warnings as errors; Ignore session flag bypasses session rules - - @acceptance-criteria - Scenario: Validate staged changes (pre-commit default) - When running "pnpm lint:process --staged" - Then only git-staged files are validated - And exit code is 1 if violations exist - - @acceptance-criteria - Scenario: Validate all tracked files - When running "pnpm lint:process --all" - Then all Architect files are validated - And summary shows total violations and warnings - - @acceptance-criteria - Scenario: Show derived state for debugging - When running "pnpm lint:process --show-state" - Then output includes: - | Section | Content | - | Active Session | Session ID and status, or "none" | - | Scoped Specs | List of specs in scope | - | Protected Specs | Specs with active/completed status | - - @acceptance-criteria - Scenario: Strict mode treats warnings as errors - When running "pnpm lint:process --staged --strict" - Then warnings are promoted to errors - And exit code is 1 if any warnings exist - - @acceptance-criteria - Scenario: Ignore session flag bypasses session rules - Given an active session with limited scope - When running "pnpm lint:process --staged --ignore-session" - Then session scope rules are skipped - And only protection level rules apply - - # ============================================================================ - # INTEGRATION - # ============================================================================ - - Rule: Integrates with existing lint infrastructure - - **Invariant:** Process guard output format and exit code semantics must be consistent with the existing `lint-patterns` tool. - **Rationale:** Inconsistent output formats force consumers to maintain separate parsers, and inconsistent exit codes break combined lint pipelines. - **Verified by:** Output format matches lint-patterns; Can run alongside lint-patterns - - @acceptance-criteria - Scenario: Output format matches lint-patterns - When lint-process reports violations - Then output format is consistent with lint-patterns output - And includes file path, rule name, message, and suggestion - - @acceptance-criteria - Scenario: Can run alongside lint-patterns - When running "pnpm lint:all" - Then both lint:patterns and lint:process execute - And combined exit code reflects both results - - # ============================================================================ - # TAG REGISTRY EXTENSIONS - # ============================================================================ - - Rule: New tags support process guard functionality - - **Invariant:** Session and protection tags must be registered in the TypeScript taxonomy with defined formats before use in feature files. - **Rationale:** Unregistered tags bypass schema validation and are silently ignored by the scanner, causing process guard rules to fail without diagnostics. - **Verified by:** Session-related tags are recognized; Protection-related tags are recognized - - The following tags are defined in the TypeScript taxonomy to support process guard: - - @acceptance-criteria - Scenario: Session-related tags are recognized - Given the taxonomy includes session tags - Then the following tags are valid: - | Tag | Format | Purpose | - | session-id | value | Unique session identifier | - | session-status | enum | Session lifecycle: draft, active, closed | - | session-scope | flag | Marks file as session definition | - - @acceptance-criteria - Scenario: Protection-related tags are recognized - Given the taxonomy includes protection tags - Then the following tags are valid: - | Tag | Format | Purpose | - | unlock-reason | quoted-value | Required to modify protected files | - | locked-by | value | Session ID that locked the file | diff --git a/architect/specs/publishing-relocation.feature b/architect/specs/publishing-relocation.feature deleted file mode 100644 index 5696bd17..00000000 --- a/architect/specs/publishing-relocation.feature +++ /dev/null @@ -1,155 +0,0 @@ -@architect -@architect-pattern:PublishingRelocation -@architect-status:completed -@architect-unlock-reason:Retroactive-completion-during-rebrand -@architect-phase:40 -@architect-effort:0.25d -@architect-product-area:Generation -@architect-depends-on:DocsConsolidationStrategy -@architect-business-value:move-maintainer-only-npm-and-ci-publishing-procedures-to-correct-repo-root-audience -@architect-priority:medium -Feature: PUBLISHING.md Relocation to MAINTAINERS.md - - **Problem:** - `docs/PUBLISHING.md` (144 lines) is deployed to libar.dev as part of the `docs/` - directory, but its content is exclusively maintainer-only operational procedure: - npm authentication setup, 2FA workflow, version bump commands (pre-releases, - patch/minor/major), GitHub Actions release configuration, pre-commit and pre-push - hook descriptions, dry-run verification, and post-publish troubleshooting. A - developer or user browsing libar.dev has no use for these procedures — they are - targeted at the one or two people with npm publish access to the `@libar-dev` - organization. Placing maintainer procedures in the user-facing docs/ directory - creates audience misalignment and adds noise to the website. - - **Solution:** - Move the full content of `docs/PUBLISHING.md` into a new `MAINTAINERS.md` file - at the repository root. MAINTAINERS.md is a standard GitHub-visible location for - maintainer guidance — it appears in the repository root alongside CONTRIBUTING.md - and README.md, is findable by maintainers, and is not deployed to the website. - Delete `docs/PUBLISHING.md` after the content is moved. Update `docs/INDEX.md` - to remove all PUBLISHING.md references (3 locations). Update the website content - manifest to remove the dead sync target and add a link rewrite so any existing - cross-references resolve to the GitHub-hosted MAINTAINERS.md. - - **Why It Matters:** - | Benefit | How | - | Correct audience | Maintainers find procedures at the repo root, not buried in website docs | - | Cleaner website | docs/ contains only content useful to package users and developers | - | Standard convention | MAINTAINERS.md is a recognized GitHub repository metadata file | - | Zero information loss | All 144 lines move intact — no content is deleted, only relocated | - - **Design Session Findings (2026-03-05):** - | Finding | Impact | Resolution | - | PUBLISHING.md has zero relative links to other docs | No link rewriting needed in MAINTAINERS.md | Simplifies move to pure copy with header rename | - | Original spec references non-existent Phase 6 | False dependency for INDEX.md cleanup | INDEX.md update is now deliverable #3 of this phase | - | Website manifest maps PUBLISHING.md to /guides/publishing/ | Dead sync target after deletion | Deliverable #4 removes manifest entry | - | docs-live/GENERATION.md references PUBLISHING.md 4 times | Generated content, auto-updated by pnpm docs:all | No manual action needed | - | INDEX.md has 3 PUBLISHING.md references (lines 32, 260-272, 338) | Broken links and stale navigation after deletion | All 3 removed in deliverable #3 | - - **Section Audit (docs/PUBLISHING.md):** - | Section | Lines | Level | - | Publishing Guide (title) | 1 | H1 | - | Prerequisites | 5-9 | H2 | - | Version Strategy | 11-18 | H2 | - | Publishing Workflow | 20-67 | H2 | - | Pre-releases (Recommended for Initial Releases) | 22-36 | H3 | - | Subsequent Pre-releases | 38-44 | H3 | - | Stable Releases | 46-67 | H3 | - | Automated Publishing (GitHub Actions) | 69-85 | H2 | - | Pre-commit and Pre-push Hooks | 87-99 | H2 | - | Pre-commit | 91-95 | H3 | - | Pre-push | 98-99 | H3 | - | Dry Run | 101-109 | H2 | - | Verifying a Published Package | 111-126 | H2 | - | Troubleshooting | 128-144 | H2 | - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | Tests | Test Type | - | Create MAINTAINERS.md at repo root with all PUBLISHING.md content | complete | MAINTAINERS.md | No | n/a | - | Delete docs/PUBLISHING.md | complete | docs/PUBLISHING.md | No | n/a | - | Remove PUBLISHING.md entries from docs/INDEX.md (lines 32, 260-272, 338) | complete | docs/INDEX.md | No | n/a | - | Remove PUBLISHING.md from website content-manifest.mjs guides array | complete | libar-dev-website/scripts/content-manifest.mjs | No | n/a | - | Add MAINTAINERS.md link rewrite to content-manifest.mjs | complete | libar-dev-website/scripts/content-manifest.mjs | No | n/a | - - Rule: All publishing content moves to MAINTAINERS.md intact - - **Invariant:** MAINTAINERS.md at the repository root contains all 8 H2 sections - previously in docs/PUBLISHING.md: Prerequisites, Version Strategy, Publishing - Workflow (with Pre-releases, Subsequent Pre-releases, and Stable Releases - subsections), Automated Publishing (GitHub Actions), Pre-commit and Pre-push - Hooks, Dry Run, Verifying a Published Package, and Troubleshooting. No content - is summarized, condensed, or omitted during the move. The H1 title changes from - "Publishing Guide" to "Maintainer Guide" to reflect the broader MAINTAINERS.md - convention. PUBLISHING.md contains zero relative links to other docs/ files, so - no link rewriting is required. - - **Rationale:** The relocation is a pure audience-alignment fix, not a content - review. Condensing content during the move would conflate two concerns. The - maintainer procedures are complete and accurate — they simply live in the wrong - location. A faithful copy ensures no institutional knowledge is lost in - translation. - - **Verified by:** MAINTAINERS.md contains all PUBLISHING.md sections, - No content omitted or summarized during relocation - - @acceptance-criteria @happy-path - Scenario: MAINTAINERS.md contains all publishing procedure sections - Given the content of docs/PUBLISHING.md before Phase 40 - When MAINTAINERS.md is created at the repository root - Then MAINTAINERS.md contains the Prerequisites section - And MAINTAINERS.md contains the Version Strategy table - And MAINTAINERS.md contains the Publishing Workflow section with pre-release and stable release commands - And MAINTAINERS.md contains the Automated Publishing section describing the GitHub Actions workflow - And MAINTAINERS.md contains the Dry Run section - And MAINTAINERS.md contains the Verifying a Published Package section - And MAINTAINERS.md contains the Troubleshooting section - - Rule: docs/PUBLISHING.md is deleted after relocation - - **Invariant:** After Phase 40 completes, `docs/PUBLISHING.md` does not exist. - The file is not kept as a redirect stub or summary pointer. MAINTAINERS.md at - the repo root is the sole location for publishing procedures. - - **Rationale:** A deleted file cannot serve the wrong audience. Keeping - docs/PUBLISHING.md as a stub pointing to MAINTAINERS.md would still deploy - a maintainer-only page to the website. The correct fix is deletion, not - redirection. Maintainers navigating to the repo root will find MAINTAINERS.md - via standard GitHub repository conventions. - - **Verified by:** File deleted from docs/, No broken links in retained docs - - @acceptance-criteria @validation - Scenario: docs/PUBLISHING.md is absent after Phase 40 completes - Given Phase 40 (PublishingRelocation) is complete - Then docs/PUBLISHING.md does not exist in the repository - And MAINTAINERS.md exists at the repository root - - Rule: Cross-references and website manifest are updated - - **Invariant:** After Phase 40 completes, docs/INDEX.md contains zero references - to PUBLISHING.md. The 3 locations that previously referenced it are removed: - the Quick Navigation table row (line 32), the Detailed Table of Contents - subsection (lines 260-272), and the Document Roles Summary row (line 338). - The website content manifest no longer includes PUBLISHING.md in the guides - array. A link rewrite entry maps "./PUBLISHING.md" to the GitHub blob URL for - MAINTAINERS.md so any remaining cross-references in other docs resolve correctly - after website deployment. - - **Rationale:** Deleting a file without updating its references creates broken - links in both the docs/ index and the website. The INDEX.md references are - removed entirely (not redirected) because the content is no longer in the docs/ - directory. The website manifest removal prevents a dead sync target. The link - rewrite handles any generated docs that reference PUBLISHING.md — they will - link to the GitHub-hosted MAINTAINERS.md instead of a 404. - - **Verified by:** INDEX.md has zero PUBLISHING.md references, - Website manifest guides array excludes PUBLISHING.md, - Link rewrite maps to MAINTAINERS.md GitHub URL - - @acceptance-criteria @validation - Scenario: INDEX.md and website manifest are updated - Given Phase 40 (PublishingRelocation) is complete - Then docs/INDEX.md Quick Navigation table has no PUBLISHING.md row - And docs/INDEX.md has no "PUBLISHING.md (Lines 1-144)" subsection - And docs/INDEX.md Document Roles Summary has no PUBLISHING.md row diff --git a/architect/specs/readme-rationalization.feature b/architect/specs/readme-rationalization.feature deleted file mode 100644 index be3683ae..00000000 --- a/architect/specs/readme-rationalization.feature +++ /dev/null @@ -1,159 +0,0 @@ -@architect -@architect-pattern:ReadmeRationalization -@architect-status:completed -@architect-unlock-reason:Retroactive-completion-during-rebrand -@architect-phase:42 -@architect-effort:0.5d -@architect-product-area:Generation -@architect-depends-on:DocsConsolidationStrategy -@architect-business-value:focused-npm-landing-page -@architect-priority:medium -Feature: README Rationalization - - **Problem:** - `README.md` is 504 lines and serves three different audiences in one document: - (a) npm package consumers who need installation, quick start, and CLI commands (~150 lines -- keep), - (b) enterprise pitch content -- "Proven at Scale", comparison table, "How It Compares" -- better - suited for the libar.dev website where it can be formatted properly and kept up to date, - (c) configuration reference (lines 440-474) that duplicates docs/CONFIGURATION.md with identical - preset tables and code examples. - - Mixing these concerns produces a README that is too long for npm discovery, too shallow for - enterprise evaluation, and redundant with the configuration doc. npm consumers scanning the - package page are most impacted -- they hit 504 lines before finding the install command. - - **Solution:** - Trim README.md from 504 lines to approximately 150 lines, keeping only the npm-appropriate - content: badges, one-paragraph value proposition, install instructions, quick start (annotate, - generate, enforce), one annotated code example, content block summary table, CLI command table, - and a documentation index. Enterprise pitch sections are already fully covered by 9 website - landing page components (Metrics.astro, Pillars.astro, DataAPI.astro, Workflows.astro, - CodeExamples.astro, Pipeline.astro, Hero.astro, McpCallout.astro, FooterCta.astro). Remove the - Configuration section entirely -- it duplicates docs/CONFIGURATION.md. - - **Why It Matters:** - | Benefit | How | - | Faster npm discovery | 150-line README places install within first 20 lines | - | No configuration duplication | Single source of truth in docs/CONFIGURATION.md | - | Better getting-started page | Trimmed README aligns with /architect/getting-started/ URL | - | Zero content loss | All enterprise pitch content already lives on the website | - - **Section Disposition (18 sections):** - | Section | Lines | Range | Action | Target | Rationale | - | Title + badges | 15 | 1-15 | KEEP | 12 | Essential npm identity | - | Why This Exists | 15 | 17-31 | TRIM | 6 | Keep thesis paragraph, remove comparison table | - | Built for AI-Assisted Development | 17 | 33-49 | REMOVE | 0 | Website DataAPI.astro + CodeExamples.astro | - | Quick Start | 57 | 52-108 | TRIM | 45 | Core npm content, trim tag prefix note | - | How It Works | 54 | 111-164 | TRIM | 20 | Keep one TS example + pipeline one-liner | - | What Gets Generated | 17 | 167-183 | TRIM | 10 | Keep content block table, remove prose | - | CLI Commands | 68 | 186-253 | TRIM | 25 | Keep command table, remove flags + deprecated | - | Proven at Scale | 47 | 256-302 | EXTRACT | 0 | Identical to Metrics.astro | - | FSM-Enforced Workflow | 32 | 305-336 | EXTRACT | 0 | Pillars.astro + Workflows.astro | - | Data API CLI | 26 | 339-364 | EXTRACT | 0 | DataAPI.astro (richer interactive demo) | - | Rich Relationship Model | 23 | 367-389 | EXTRACT | 0 | Pillars.astro pillar 04 | - | How It Compares | 21 | 392-412 | EXTRACT | 0 | No npm equivalent needed | - | Design-First Development | 4 | 416-419 | REMOVE | 0 | Pointer to METHODOLOGY.md already in doc index | - | Document Durability Model | 4 | 422-425 | REMOVE | 0 | Pointer to METHODOLOGY.md already in doc index | - | Use Cases | 11 | 428-438 | REMOVE | 0 | Covered by Quick Start + website | - | Configuration | 34 | 441-474 | REMOVE | 0 | Exact duplicate of docs/CONFIGURATION.md | - | Documentation | 23 | 477-499 | TRIM | 15 | Merge two tables into one, remove self-reference | - | License | 3 | 502-504 | KEEP | 3 | Required | - - Line count math: KEEP (15) + TRIM (121) + separators (6) = ~142 lines. - - **Design Findings:** - | Finding | Impact | Resolution | - | Website has 9 landing components, not only Hero | No content creation needed -- extraction is deletion | Deliverable 3 becomes mapping doc, not content brief | - | Metrics.astro has identical Proven at Scale claims | Section 8 (47 lines) is 100% redundant | Safe EXTRACT with zero information loss | - | Pillars.astro covers FSM, dual-source, relationships | Sections 9, 11, 12 redundant with website | Safe EXTRACT | - | generate-docs flags table duplicates --help output | CLI section is 68 lines but only command table is unique | Trim flags table, retain command summary only | - | INDEX.md line 22 references README as 1-504 | Stale line count after trim | Add deliverable 5 for INDEX.md update | - | README maps to /getting-started/ via content-manifest.mjs | Trimmed README is better getting-started page | No manifest change needed, add Rule 3 | - | Line 93 Configuration anchor breaks when section removed | Internal link to deleted section | Replace with docs/CONFIGURATION.md link | - - **README-to-Website Component Mapping:** - | README Section (EXTRACT) | Website Component | Coverage | - | Proven at Scale (S8, lines 256-302) | Metrics.astro | Identical: 5x throughput, 50-65% context, 0 ESLint | - | FSM-Enforced Workflow (S9, lines 305-336) | Pillars.astro pillar 02 + Workflows.astro | FSM concept + session patterns | - | Data API CLI (S10, lines 339-364) | DataAPI.astro | Three-tab interactive demo, richer than README | - | Rich Relationship Model (S11, lines 367-389) | Pillars.astro pillar 04 | Relationship tags + Mermaid diagrams | - | How It Compares (S12, lines 392-412) | Pillars.astro (implicit) | Four pillars position against competitors | - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | Tests | Test Type | - | Trim README.md to ~150 lines per section disposition table | complete | README.md | No | n/a | - | Remove Configuration section (lines 441-474) duplicating docs/CONFIGURATION.md | complete | README.md | No | n/a | - | Document README-to-website component mapping for extracted enterprise sections | complete | architect/specs/readme-rationalization.feature | No | n/a | - | Verify all retained links in trimmed README resolve to valid targets | complete | README.md | No | n/a | - | Update INDEX.md Quick Navigation line count for README (1-504 to ~1-150) | complete | docs/INDEX.md | No | n/a | - | Verify trimmed README serves as effective getting-started page at /getting-started/ | complete | README.md | No | n/a | - - Rule: README must be an npm package landing page - - **Invariant:** README.md content is scoped to what an npm package consumer needs: title and badges, - one-paragraph value proposition, install instructions, quick start (annotate, generate, enforce), - one annotated code example, content block summary table, CLI command table, and documentation index. - - **Rationale:** npm package pages are scanned by developers evaluating installation decisions. - Content above 150-200 lines increases time-to-value. Enterprise pitch content (benchmark tables, - methodology comparisons, session workflows, relationship models, comparison matrices) is not - actionable at install time and belongs on the project website where it receives proper formatting, - navigation, and updates without coupling to the package release cycle. The libar.dev website - already contains 9 landing page components covering all enterprise pitch content: Metrics.astro - (Proven at Scale), Pillars.astro (FSM, dual-source, relationships, codecs), DataAPI.astro - (Data API CLI), Workflows.astro (session types), CodeExamples.astro (annotation examples), - and Pipeline.astro (four-stage pipeline). - - **Verified by:** Trimmed README contains only npm-appropriate sections per disposition table - - @acceptance-criteria @happy-path - Scenario: Trimmed README contains only npm-appropriate sections per disposition table - Given README.md is 504 lines mixing npm content, enterprise pitch, and configuration reference - When the rationalization is complete - Then README.md is approximately 150 lines - And it contains these sections: Title, Why This Exists, Quick Start, How It Works, What Gets Generated, CLI Commands, Documentation, License - And it does not contain these sections: Built for AI-Assisted Development, Proven at Scale, FSM-Enforced Workflow, Data API CLI, Rich Relationship Model, How It Compares, Design-First Development, Document Durability Model, Use Cases, Configuration - - Rule: Configuration reference must not be duplicated in README - - **Invariant:** docs/CONFIGURATION.md is the single source of truth for preset and tag configuration. - - **Rationale:** README.md lines 441-474 reproduce the exact same preset table and config code - examples that appear in docs/CONFIGURATION.md. Duplicate reference content diverges over time - -- when a new preset is added, both files require updates. Removing the README copy and pointing - to CONFIGURATION.md eliminates the divergence risk and removes approximately 34 lines from the - README with no loss of information. - - **Verified by:** README references docs/CONFIGURATION.md instead of duplicating config content - - @acceptance-criteria @happy-path - Scenario: README references docs/CONFIGURATION.md instead of duplicating config content - Given README.md contains a Configuration section that duplicates docs/CONFIGURATION.md - When the rationalization is complete - Then README.md does not contain a Configuration code block or preset table - And README.md contains a link to docs/CONFIGURATION.md in the documentation index - And docs/CONFIGURATION.md remains unchanged as the authoritative configuration reference - - Rule: Trimmed README must serve as an effective getting-started page - - **Invariant:** The website publishes README.md as /architect/getting-started/ via - content-manifest.mjs (line 57). After trimming, the remaining content must serve a first-time - visitor arriving at that URL: install instructions, a quick annotated code example, CLI commands - to run, and navigation links to deeper documentation. - - **Rationale:** The current 504-line README is a poor getting-started page because the install - command is buried after 50+ lines of marketing content. The trimmed 150-line version places - install instructions within the first 20 lines and follows with practical steps -- this is a - better getting-started experience than the current version. No manifest changes are needed; - the trim improves alignment with the URL. - - **Verified by:** Trimmed README has install instructions within first 20 lines and links to all guide documents - - @acceptance-criteria @happy-path - Scenario: Trimmed README has install instructions within first 20 lines and links to all guide documents - Given the website publishes README.md as /architect/getting-started/ - When the rationalization is complete - Then install instructions appear within the first 20 lines of README.md - And Quick Start steps cover annotate, generate, and enforce - And the Documentation section links to CONFIGURATION.md, METHODOLOGY.md, ARCHITECTURE.md, SESSION-GUIDES.md, GHERKIN-PATTERNS.md, PROCESS-GUARD.md, VALIDATION.md, CLI.md, and TAXONOMY.md diff --git a/architect/specs/reference-doc-showcase.feature b/architect/specs/reference-doc-showcase.feature deleted file mode 100644 index 3d6664aa..00000000 --- a/architect/specs/reference-doc-showcase.feature +++ /dev/null @@ -1,390 +0,0 @@ -@architect -@architect-pattern:ReferenceDocShowcase -@architect-status:completed -@architect-unlock-reason:'reference-render-contract-cleanup' -@architect-phase:30 -@architect-effort:13d -@architect-product-area:Generation -@architect-depends-on:CodecDrivenReferenceGeneration,ScopedArchitecturalView,ShapeExtraction -@architect-business-value:validates-all-content-blocks-via-single-integration-document -@architect-priority:high -Feature: Reference Document Showcase - - **Problem:** - The Reference Generation Sample document exercises a small fraction of the - reference codec's capabilities: 2 convention rules, 1 flowchart diagram, - 2 shapes from a single file, and 1 shallow behavior pattern. Of the 9 - renderable block types (heading, paragraph, separator, table, list, code, - mermaid, collapsible, link-out), only 6 are used. Behavior rendering truncates - rule descriptions to 120 characters, discarding invariants, rationale, and - verified-by content that is already extracted. Shape rendering omits JSDoc - prose at standard detail level. Diagrams support only flowcharts with no - edge labels, layer filtering, or alternative diagram types. The extraction - pipeline drops function signatures, param/returns/throws documentation, and - full property-level JSDoc. - - **Solution:** - Expand the reference sample into a comprehensive showcase that exercises every - content block type across all three detail levels. This requires three tiers - of work: codec rendering enhancements (deep behavior, full shapes, rich - diagrams), extraction pipeline improvements (function signatures, param docs, - auto-shape discovery), and infrastructure enablers (codec composition, - AI-optimized rendering, data-driven tag extraction). - - The sample document serves as the integration test: if REFERENCE-SAMPLE.md - renders every block type correctly at every detail level, the codec system - works end-to-end. - - **Why It Matters:** - | Benefit | How | - | Integration validation | Single document tests all 9 renderable block types | - | Deep behavior content | Full rule descriptions with invariant/rationale replace 120-char truncation | - | Complete shape documentation | JSDoc prose at standard level, property tables at detailed | - | Rich diagram vocabulary | Sequence, state, C4, and class diagrams alongside flowcharts | - | Progressive disclosure | Collapsible sections for large content blocks | - | Complete API surface | Function signatures and param docs without source navigation | - | Token-efficient AI context | Dedicated renderer for LLM consumption | - | Flexible composition | CompositeCodec assembles docs from multiple codec outputs | - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | - | Remove 120-char rule description truncation | Complete | src/renderable/codecs/reference.ts | - | Deep behavior rendering with parsed invariant/rationale | Complete | src/renderable/codecs/reference.ts | - | JSDoc prose in shape sections at standard level | Complete | src/renderable/codecs/reference.ts | - | archLayer filter in DiagramScope | Complete | src/renderable/codecs/reference.ts | - | Edge labels on diagram relationships | Complete | src/renderable/codecs/reference.ts | - | Custom node shapes per archRole | Complete | src/renderable/codecs/reference.ts | - | diagramType field in DiagramScope | Complete | src/renderable/codecs/reference.ts | - | Sequence diagram rendering | Complete | src/renderable/codecs/reference.ts | - | State machine diagram rendering | Complete | src/renderable/codecs/reference.ts | - | C4 diagram rendering | Complete | src/renderable/codecs/reference.ts | - | Class diagram rendering | Complete | src/renderable/codecs/reference.ts | - | List block usage for scenario names under rules | Complete | src/renderable/codecs/reference.ts | - | Collapsible block for progressive disclosure | Complete | src/renderable/codecs/reference.ts | - | Link-out block for cross-references | Complete | src/renderable/codecs/reference.ts | - | Function signature surfacing in ExportInfo | Complete | src/scanner/ast-parser.ts | - | Param/returns/throws extraction from JSDoc | Complete | src/extractor/shape-extractor.ts | - | Full property-level JSDoc without truncation | Complete | src/extractor/shape-extractor.ts | - | Auto-shape discovery mode | Complete | src/extractor/shape-extractor.ts | - | Convention content from TypeScript JSDoc | Complete | src/scanner/ast-parser.ts | - | CompositeCodec for multi-codec assembly | Complete | src/renderable/codecs/ | - | Data-driven Gherkin tag extraction | Complete | src/scanner/gherkin-ast-parser.ts | - | Expanded sample config with all content sources | Complete | architect.config.ts | - | Sample convention decision with rich content | Complete | architect/decisions/ | - - Rule: Deep behavior rendering replaces shallow truncation - - **Invariant:** At standard and detailed levels, behavior sections render full - rule descriptions with parsed invariant, rationale, and verified-by content. - At summary level, the 120-character truncation is preserved for compact output. - Behavior rendering reuses parseBusinessRuleAnnotations from the convention - extractor rather than reimplementing structured content parsing. - - **Rationale:** The current 120-character truncation discards invariants, - rationale, and verified-by content that is already extracted and available - in BusinessRule.description. Reference documents need the full rule content - to serve as authoritative documentation. The convention extractor already - parses this structured content via parseBusinessRuleAnnotations -- the - behavior builder should delegate to the same function. - - **Verified by:** Full rule descriptions at detailed level, - Truncated descriptions at summary level, - Scenario names appear as list blocks under rules - - @acceptance-criteria @happy-path - Scenario: Detailed level renders full rule descriptions with structured content - Given a behavior pattern with rules containing invariant and rationale - When the reference codec renders at detailed level - Then each rule description appears without truncation - And invariant text is rendered as a bold paragraph - And rationale text is rendered as a bold paragraph - And verified-by scenarios are rendered as a list block - - @acceptance-criteria @happy-path - Scenario: Summary level preserves compact truncation - Given a behavior pattern with rules containing long descriptions - When the reference codec renders at summary level - Then rule descriptions are truncated to 120 characters - And no invariant or rationale paragraphs appear - - @acceptance-criteria @happy-path - Scenario: Standard level renders full descriptions without rationale - Given a behavior pattern with rules containing invariant and rationale - When the reference codec renders at standard level - Then each rule description appears without truncation - And invariant text is rendered as a bold paragraph - And rationale text is not rendered - - Rule: Shape sections include JSDoc prose and property documentation - - **Invariant:** At standard level, shape code blocks are preceded by JSDoc - prose when available. At detailed level, interface shapes additionally render - a property documentation table. At summary level, only the type-kind table - appears. Shapes without JSDoc render code blocks without preceding paragraph. - - **Rationale:** JSDoc on shapes contains design rationale and usage guidance - that is already extracted by the shape extractor. Gating it behind detailed - level wastes the data at the most common detail level (standard). The fix is - a single condition change: reference.ts line 342 from - detailLevel === 'detailed' to detailLevel !== 'summary'. - - **Verified by:** JSDoc renders at standard level, - Property table renders at detailed level, - Summary shows only type-kind table - - @acceptance-criteria @happy-path - Scenario: Standard level includes JSDoc prose above code blocks - Given shapes with JSDoc comments extracted from source - When the reference codec renders at standard level - Then JSDoc text appears as a paragraph before each code block - - @acceptance-criteria @happy-path - Scenario: Detailed level adds property documentation table - Given an interface shape with property-level JSDoc - When the reference codec renders at detailed level - Then a property documentation table appears after the code block - And the table has columns "Property" and "Description" - - @acceptance-criteria @edge-case - Scenario: Shapes without JSDoc render code blocks only - Given shapes with no JSDoc comments - When the reference codec renders at standard level - Then code blocks render without a preceding paragraph - - Rule: Diagram scope supports archLayer filtering and multiple diagram types - - **Invariant:** DiagramScope gains optional archLayer and diagramType fields. - The archLayer filter selects patterns by their architectural layer (domain, - application, infrastructure) and composes with archContext and archView via - OR logic, consistent with existing filter dimensions. The diagramType field - controls Mermaid output format: graph (default), sequenceDiagram, - stateDiagram-v2, C4Context, classDiagram. Each diagram type has its own - node and edge syntax appropriate to the Mermaid specification. - - **Rationale:** Layer-based views are fundamental to layered architecture - documentation -- a developer reviewing the domain layer wants only deciders - and value objects, not infrastructure adapters. Multiple diagram types unlock - event flow documentation (sequence), FSM visualization (state), architecture - overview (C4), and type hierarchy views (class) that flowcharts cannot - express naturally. - - **Verified by:** archLayer filter selects domain-layer patterns, - archLayer composes with archContext via OR, - Sequence diagram renders participant-message format, - State diagram renders state transitions, - diagramType field controls Mermaid output - - @acceptance-criteria @happy-path - Scenario: archLayer filter selects patterns by layer - Given patterns annotated with archLayer "domain" - And patterns annotated with archLayer "infrastructure" - And a DiagramScope with archLayer "domain" - When the scope filter runs - Then only patterns in the domain layer appear - - @acceptance-criteria @edge-case - Scenario: archLayer and archContext compose via OR - Given a pattern with archLayer "domain" and archContext "orders" - And a pattern with archLayer "infrastructure" and archContext "shared" - And a DiagramScope with archLayer "domain" and archContext "shared" - When the scope filter runs - Then both patterns appear in the result - - @acceptance-criteria @happy-path - Scenario: Sequence diagram renders participant-message format - Given a DiagramScope with diagramType "sequenceDiagram" - And patterns with uses relationships representing event flow - When the scoped diagram is built - Then the mermaid output starts with "sequenceDiagram" - And patterns appear as participants - And relationships appear as messages between participants - - @acceptance-criteria @happy-path - Scenario: State diagram renders state transitions - Given a DiagramScope with diagramType "stateDiagram-v2" - And patterns representing FSM states with transition relationships - When the scoped diagram is built - Then the mermaid output starts with "stateDiagram-v2" - And states and transitions render in state diagram syntax - - @acceptance-criteria @happy-path - Scenario: Default diagramType produces flowchart - Given a DiagramScope without diagramType specified - When the scoped diagram is built - Then the mermaid output starts with "graph" - - Rule: Every renderable block type appears in the showcase document - - **Invariant:** The generated REFERENCE-SAMPLE.md at detailed level must - contain at least one instance of each of the 9 block types: heading, - paragraph, separator, table, list, code, mermaid, collapsible, link-out. - At summary level, progressive disclosure blocks (collapsible, link-out) - are omitted for compact output. - - **Rationale:** The sample document is the integration test for the reference - codec. If any block type is missing, there is no automated verification that - the codec can produce it. Coverage of all 9 types validates the full - rendering pipeline from PatternGraph through codec through renderer. - - **Verified by:** All 9 block types present in detailed output, - Summary output uses compact block subset - - @acceptance-criteria @happy-path - Scenario: Detailed output contains all 9 block types - Given the expanded sample config with all content sources populated - When the reference codec renders at detailed level - Then the output contains heading blocks - And the output contains paragraph blocks - And the output contains separator blocks - And the output contains table blocks - And the output contains list blocks - And the output contains code blocks - And the output contains mermaid blocks - And the output contains collapsible blocks - And the output contains link-out blocks - - @acceptance-criteria @happy-path - Scenario: Summary output uses compact block subset - Given the expanded sample config with all content sources populated - When the reference codec renders at summary level - Then the output contains heading, paragraph, separator, and table blocks - And the output does not contain collapsible or link-out blocks - - Rule: Edge labels and custom node shapes enrich diagram readability - - **Invariant:** Relationship edges in scoped diagrams display labels - describing the relationship semantics (uses, dependsOn, implements, extends). - Edge labels are enabled by default and can be disabled via a showEdgeLabels - option for compact diagrams. Node shapes vary by archRole value -- services - use rounded rectangles, bounded contexts use subgraphs, projections use - cylinders, and sagas use hexagons. - - **Rationale:** Unlabeled edges are ambiguous -- a reader seeing a solid - arrow cannot distinguish "uses" from "implements" without consulting an - edge style legend. Custom node shapes leverage Mermaid's shape vocabulary - to make archRole visually distinguishable without color reliance, - improving accessibility. - - **Verified by:** Edge labels appear on diagram edges, - Edge labels can be disabled, - archRole controls node shape - - @acceptance-criteria @happy-path - Scenario: Relationship edges display type labels by default - Given scope patterns with uses and dependsOn relationships - When the scoped diagram is built - Then edges include relationship type labels in Mermaid syntax - - @acceptance-criteria @happy-path - Scenario: Edge labels can be disabled for compact diagrams - Given scope patterns with relationships - And edge labels are disabled via showEdgeLabels false - When the scoped diagram is built - Then edges use the standard unlabeled arrow syntax - - @acceptance-criteria @happy-path - Scenario: archRole controls Mermaid node shape - Given a pattern with archRole "service" and a pattern with archRole "projection" - When the scoped diagram is built - Then the service node uses rounded rectangle syntax - And the projection node uses cylinder syntax - - Rule: Extraction pipeline surfaces complete API documentation - - **Invariant:** ExportInfo.signature shows full function parameter types and - return type instead of the placeholder value. JSDoc param, returns, and - throws tags are extracted and stored on ExtractedShape. Property-level JSDoc - preserves full multi-line content without first-line truncation. Auto-shape - discovery mode extracts all exported types from files matching source-selector globs - globs without requiring explicit extract-shapes annotations. - - **Rationale:** Function signatures are the most valuable API surface -- they - show what a pattern exports without source navigation. The ExportInfo.signature - field already exists in the schema but holds a lossy placeholder. The fix is - approximately 15 lines in ast-parser.ts: threading sourceCode into - extractFromDeclaration and slicing parameter ranges. Auto-shape discovery - eliminates manual annotation burden for files that match source-selector globs. - - **Verified by:** Function signatures populate ExportInfo, - Param and returns tags appear in shape sections, - Full property JSDoc preserved, - Auto-shape discovery extracts without explicit tags - - @acceptance-criteria @happy-path - Scenario: Function signatures populate ExportInfo - Given a TypeScript file with exported functions having typed parameters - When the AST parser extracts pattern metadata - Then ExportInfo.signature contains full parameter types and return type - - @acceptance-criteria @happy-path - Scenario: JSDoc param and returns tags appear in shape sections - Given a shape with @param and @returns JSDoc tags - When the reference codec renders at detailed level - Then parameter documentation appears in the shape section - And return type documentation appears in the shape section - - @acceptance-criteria @happy-path - Scenario: Full property-level JSDoc preserved without truncation - Given an interface shape with multi-line property JSDoc - When the shape extractor processes the file - Then the full property JSDoc text is preserved - And no first-line truncation occurs - - @acceptance-criteria @happy-path - Scenario: Auto-shape discovery extracts exports from source-selector files - Given a TypeScript file matching a source-selector glob pattern - And the file has exported types but no extract-shapes annotation - When shape extraction runs in auto-discovery mode - Then all exported types from the file are included as shapes - - Rule: Infrastructure enables flexible document composition and AI-optimized output - - **Invariant:** CompositeCodec assembles reference documents from multiple - codec outputs by concatenating RenderableDocument sections. The - modular claude-md renderer produces token-efficient output using section - markers optimized for LLM consumption. The Gherkin tag extractor uses - TagRegistry metadata instead of hardcoded if/else branches, making new tag - addition a zero-code-change operation. Convention content can be extracted - from TypeScript JSDoc blocks containing structured Invariant/Rationale - annotations, not only from Gherkin Rule blocks. - - **Rationale:** CompositeCodec enables referenceDocConfigs to include content - from any codec, not just the current 4 sources. The modular claude-md - renderer unifies two formatting paths (codec-based markdown vs hand-written - markers in context-formatter.ts). Data-driven tag extraction cuts the - maintenance burden of the 40-branch if/else in gherkin-ast-parser.ts roughly - in half. TypeScript convention extraction enables self-documenting business - rules in implementation files alongside their code. - - **Verified by:** CompositeCodec combines multiple codec outputs, - Claude context renderer produces marker-delimited output, - New tags work via registry without code changes, - TypeScript JSDoc conventions extracted alongside Gherkin - - @acceptance-criteria @happy-path - Scenario: CompositeCodec combines multiple codec outputs - Given two codec instances producing different RenderableDocuments - When CompositeCodec assembles them - Then the output contains sections from both codecs in order - - @acceptance-criteria @happy-path - Scenario: modular claude-md renderer produces token-efficient output - Given a RenderableDocument with multiple section types - When rendered via the modular claude-md renderer - Then the output uses section markers instead of markdown headers - And token count is lower than equivalent markdown output - - @acceptance-criteria @happy-path - Scenario: New Gherkin tags work via registry without code changes - Given a tag defined in the TagRegistry with format and purpose - When a feature file uses that tag - Then the Gherkin extractor parses it using registry metadata - And no new if/else branch is needed in the parser - - @acceptance-criteria @happy-path - Scenario: TypeScript JSDoc conventions extracted alongside Gherkin - Given a TypeScript file with Invariant and Rationale in JSDoc - And a convention tag on the same file - When convention extraction runs - Then structured content from TypeScript JSDoc appears in convention output diff --git a/architect/specs/scoped-architectural-view.feature b/architect/specs/scoped-architectural-view.feature deleted file mode 100644 index 0c7d6d7f..00000000 --- a/architect/specs/scoped-architectural-view.feature +++ /dev/null @@ -1,144 +0,0 @@ -@architect -@architect-pattern:ScopedArchitecturalView -@architect-status:completed -@architect-unlock-reason:Retroactive-spec-for-completed-work -@architect-phase:28 -@architect-effort:3d -@architect-product-area:Generation -@architect-depends-on:ArchitectureDiagramGeneration,ShapeExtraction -@architect-business-value:enables-selective-pattern-composition-with-architecture-diagrams -@architect-priority:high -Feature: Scoped Architectural View - - **Problem:** - Full architecture diagrams show every annotated pattern in the project. For focused - use cases -- design session context, PR descriptions, CLAUDE.md module sections -- - developers need views scoped to a small set of relevant patterns with their immediate - neighbors. Manually curating diagram content defeats the code-first principle. - - **Solution:** - A `DiagramScope` filter interface that selects patterns by three dimensions - (`archContext`, `archView`, or explicit pattern names), automatically discovers - neighbor patterns via relationship edges, and renders scoped Mermaid diagrams - with subgraph grouping and distinct neighbor styling. - - The `arch-view` tag enables patterns to declare membership in named architectural - views (e.g., `codec-transformation`, `pipeline-stages`). A single pattern can - belong to multiple views. The transformer groups patterns by view in the - `ArchIndex.byView` pre-computed index for O(1) access at render time. - - **Why It Matters:** - | Benefit | How | - | Focused context for AI sessions | Select 3-5 patterns instead of 50+ | - | Automatic neighbor discovery | Related patterns appear without explicit listing | - | Multiple views per pattern | One annotation, many documents | - | Two detail levels from one config | Detailed (with diagram) and summary (table only) | - | Reusable across document types | PR descriptions, CLAUDE.md, design context | - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | - | arch-view tag in taxonomy | complete | src/taxonomy/registry-builder.ts | - | archView in DocDirective schema | complete | src/validation-schemas/doc-directive.ts | - | archView in ExtractedPattern schema | complete | src/validation-schemas/extracted-pattern.ts | - | archView extraction in AST parser | complete | src/scanner/ast-parser.ts | - | archView propagation in doc-extractor | complete | src/extractor/doc-extractor.ts | - | byView grouping in ArchIndex | complete | src/generators/pipeline/transform-dataset.ts | - | DiagramScope interface | complete | src/renderable/codecs/reference.ts | - | collectScopePatterns filter | complete | src/renderable/codecs/reference.ts | - | collectNeighborPatterns discovery | complete | src/renderable/codecs/reference.ts | - | buildScopedDiagram builder | complete | src/renderable/codecs/reference.ts | - | diagramScopes (plural) support | complete | src/renderable/codecs/reference.ts | - | sanitizeNodeId shared utility | complete | src/renderable/codecs/diagram-utils.ts | - - Rule: Scope filtering selects patterns by context, view, or name - - **Invariant:** A pattern matches a DiagramScope if ANY of three conditions hold: - its name is in `scope.patterns`, its `archContext` is in `scope.archContext`, - or any of its `archView` entries is in `scope.archView`. These dimensions are - OR'd together -- a pattern need only match one. - - **Rationale:** Three filter dimensions cover different authoring workflows. - Explicit names for ad-hoc documents, archContext for bounded context views, - archView for cross-cutting architectural perspectives. - - **Verified by:** archContext filter matches patterns, - archView filter matches patterns, combined filters OR together - - @acceptance-criteria @happy-path - Scenario: archContext filter matches patterns in that context - Given patterns annotated with archContext "renderer" - And a DiagramScope with archContext "renderer" - When the scope filter runs - Then only patterns in the "renderer" context appear - - @acceptance-criteria @happy-path - Scenario: archView filter matches patterns with that view - Given patterns annotated with archView "codec-transformation" - And a DiagramScope with archView "codec-transformation" - When the scope filter runs - Then patterns belonging to the "codec-transformation" view appear - - @acceptance-criteria @edge-case - Scenario: Multiple filter dimensions OR together - Given a pattern with archContext "scanner" and no archView - And a pattern with archView "pipeline-stages" and no archContext - And a DiagramScope with archContext "scanner" and archView "pipeline-stages" - When the scope filter runs - Then both patterns appear in the result - - Rule: Neighbor discovery finds connected patterns outside scope - - **Invariant:** Patterns connected to scope patterns via relationship edges - (uses, dependsOn, implementsPatterns, extendsPattern) but NOT themselves in - scope appear in a "Related" subgraph with dashed border styling. - - **Rationale:** Scoped views need context. Showing only in-scope patterns - without their dependencies loses critical relationship information. - Neighbor patterns provide this context without cluttering the main view. - - **Verified by:** Neighbor patterns appear in diagram, Self-contained scope has no neighbors - - @acceptance-criteria @happy-path - Scenario: Neighbor patterns appear with dashed styling - Given scope patterns that use a pattern outside the scope - When the scoped diagram is built - Then the neighbor appears in a "Related" subgraph - And the neighbor node has dashed border styling - - @acceptance-criteria @edge-case - Scenario: Self-contained scope produces no neighbor subgraph - Given scope patterns with no external relationships - When the scoped diagram is built - Then no "Related" subgraph appears - - Rule: Multiple diagram scopes compose in sequence - - **Invariant:** When `diagramScopes` is an array, each scope produces its own - Mermaid diagram section with independent title, direction, and pattern selection. - At summary detail level, all diagrams are suppressed. - - **Rationale:** A single reference document may need multiple architectural - perspectives. Pipeline Overview shows both a codec transformation view (TB) - and a pipeline data flow view (LR) in the same document. - - **Verified by:** Two scopes produce two mermaid blocks, - Direction controls diagram orientation, Summary level omits diagrams - - @acceptance-criteria @happy-path - Scenario: Two diagram scopes produce two mermaid blocks - Given a config with two diagramScopes entries - When the reference codec renders at detailed level - Then the output contains two separate mermaid code blocks - - @acceptance-criteria @happy-path - Scenario: Direction controls diagram orientation - Given a DiagramScope with direction "LR" - When the scoped diagram is built - Then the mermaid block contains "graph LR" - - @acceptance-criteria @happy-path - Scenario: Summary detail level omits all diagrams - Given a config with diagramScopes entries - When the reference codec renders at summary level - Then the output contains no mermaid code blocks diff --git a/architect/specs/session-guides-module-source.feature b/architect/specs/session-guides-module-source.feature deleted file mode 100644 index 8bb6045d..00000000 --- a/architect/specs/session-guides-module-source.feature +++ /dev/null @@ -1,353 +0,0 @@ -@architect -@architect-pattern:SessionGuidesModuleSource -@architect-status:completed -@architect-unlock-reason:Terminology-alignment-rebrand -@architect-phase:39 -@architect-effort:0.5d -@architect-product-area:Generation -@architect-depends-on:ClaudeModuleGeneration,DocsConsolidationStrategy -@architect-business-value:session-workflow-CLAUDE-md-section-generated-from-annotated-specs -@architect-priority:medium -@architect-claude-module:session-workflows -@architect-claude-section:workflow -@architect-claude-tags:core -@architect-include:session-workflows -Feature: Session Guides as Annotated Module Source - - **Problem:** - CLAUDE.md contains a "Session Workflows" section (~160 lines) that is hand-maintained - with no link to any annotated source. Three hand-written files in `_claude-md/workflow/` - (session-workflows.md, session-details.md, fsm-handoff.md) are equally opaque: no - machine-readable origin, no regeneration from source annotations. - - The prior plan proposed tagging ADR-001, ADR-003, and PDR-001 with `@architect-claude-module` - to make them the source for generated workflow modules. Design analysis revealed this is - fundamentally flawed: `claude-module` is a file-level tag that pulls ALL Rules from a file, - but most Rules in those decision specs are irrelevant to session workflows (ADR-001 has 9 - Rules, only 2-3 are workflow-relevant; PDR-001 has 7 Rules about CLI implementation - decisions, not workflow guidance). - - **Solution:** - This spec file itself becomes the annotated source for session workflow content. - Session workflow invariants are captured as Rule: blocks here, covering session type - contracts, FSM protection, execution order, error recovery, and handoff patterns. - - Once ClaudeModuleGeneration (Phase 25) ships, adding `@architect-claude-module` and - `@architect-claude-section:workflow` tags to this spec will cause the codec to produce - `_claude-md/workflow/` modules automatically. The hand-written files are then deleted - and the CLAUDE.md section becomes a generated include. - - Retain `docs/SESSION-GUIDES.md` (389 lines) as the authoritative public human reference - deployed to libar.dev. It serves developers with comprehensive checklists and full CLI - examples — content that cannot be expressed as compact invariants. - - Three-layer architecture after Phase 39: - - | Layer | Location | Content | Maintenance | - | Public human reference | docs/SESSION-GUIDES.md | Full checklists, CLI examples, decision trees | Manual (editorial) | - | Compact AI context | _claude-md/workflow/ | Invariants, session contracts, FSM reference | Generated from this spec | - | Machine-queryable source | Process Data API | Rules from this spec via `rules` command | Derived from annotations | - - **Why It Matters:** - | Benefit | How | - | No CLAUDE.md drift | Session workflow section generated, not hand-authored | - | Single annotated source | This spec owns all session workflow invariants | - | Correct audience alignment | Public guide stays in docs/, AI context in _claude-md/ | - | Process API coverage | Session workflow content queryable via `pnpm architect:query -- rules` | - | Immediately useful | Rule: blocks are queryable today, generation follows when Phase 25 ships | - - **Design Session Findings (2026-03-05):** - | Finding | Impact | - | claude-module is file-level, not Rule-level | Cannot selectively tag individual Rules in ADR/PDR files | - | ADR-001 has 9 Rules, only 2-3 workflow-relevant | Tagging ADR-001 would create noisy, diluted context | - | PDR-001 Rules are CLI implementation decisions | Not session workflow guidance, wrong audience | - | Phase 25 claude-section enum lacks workflow value | Must add workflow to enum before annotation | - | Self-referential spec is correct source | This spec captures invariants, SESSION-GUIDES.md has editorial content | - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | Tests | Test Type | - | Session workflow behavior spec with Rule blocks (session types, FSM contracts, escape hatches, handoff) | complete | architect/specs/session-guides-module-source.feature | No | n/a | - | Verify SESSION-GUIDES.md retained with correct INDEX.md links | complete | docs/SESSION-GUIDES.md | No | n/a | - | Add workflow to Phase 25 claude-section enum | complete | architect/specs/claude-module-generation.feature | No | n/a | - | Add claude-module and claude-section:workflow tags to this spec | complete | architect/specs/session-guides-module-source.feature | No | n/a | - | Generated _claude-md/workflow/session-workflows.md replaces hand-written version | complete | _claude-md/workflow/session-workflows.md | No | n/a | - | Generated _claude-md/workflow/fsm-handoff.md replaces hand-written version | complete | _claude-md/workflow/fsm-handoff.md | No | n/a | - | CLAUDE.md Session Workflows section replaced with modular-claude-md include | complete | CLAUDE.md | No | n/a | - - # =========================================================================== - # RULE 1: SESSION-GUIDES.MD IS THE PUBLIC HUMAN REFERENCE - # =========================================================================== - - Rule: SESSION-GUIDES.md is the authoritative public human reference - - **Invariant:** `docs/SESSION-GUIDES.md` exists and is not deleted, shortened, or - replaced with a redirect. Its comprehensive checklists, CLI command examples, and - session decision trees serve developers on libar.dev. - - **Rationale:** Session workflow guidance requires two formats for two audiences. - Public developers need comprehensive checklists with full examples. AI sessions - need compact invariants they can apply without reading 389 lines. - - **Verified by:** SESSION-GUIDES.md exists after Phase 39, - No broken links after Phase 39 - - @acceptance-criteria @happy-path - Scenario: SESSION-GUIDES.md exists after Phase 39 completes - Given Phase 39 (SessionGuidesModuleSource) is complete - Then docs/SESSION-GUIDES.md exists in the repository - And docs/INDEX.md contains a link to SESSION-GUIDES.md - And SESSION-GUIDES.md contains no fewer lines than it did before Phase 39 - - @acceptance-criteria @validation - Scenario: No broken links after Phase 39 - Given Phase 39 (SessionGuidesModuleSource) is complete - Then no retained file in docs/ contains a broken link to a deleted file - And docs/INDEX.md navigation is consistent with docs/ directory contents - - # =========================================================================== - # RULE 2: CLAUDE.MD SESSION CONTENT IS DERIVED - # =========================================================================== - - Rule: CLAUDE.md session workflow content is derived, not hand-authored - - **Invariant:** After Phase 39 generation deliverables complete, the "Session - Workflows" section in CLAUDE.md contains no manually-authored content. It is - composed from generated `_claude-md/workflow/` modules. - - **Rationale:** A hand-maintained CLAUDE.md session section creates two copies of - session workflow guidance with no synchronization mechanism. Regeneration from - annotated source eliminates drift. - - **Verified by:** CLAUDE.md session section is a generated module reference - - @acceptance-criteria @happy-path - Scenario: CLAUDE.md session section is a generated module reference - Given Phase 39 generation deliverables are complete - When inspecting CLAUDE.md under the Session Workflows heading - Then the section contains a modular-claude-md include reference to the generated module - And the section contains no manually-authored do/do-not tables or checklist steps - - # =========================================================================== - # RULE 3: SESSION TYPE DETERMINES ARTIFACTS AND FSM CHANGES - # =========================================================================== - - Rule: Session type determines artifacts and FSM changes - - **Invariant:** Four session types exist, each with defined input, output, and - FSM impact. Mixing outputs across session types (e.g., writing code in a planning - session) violates session discipline. - - **Rationale:** Session type confusion causes wasted work — a design mistake - discovered mid-implementation wastes the entire session. Clear contracts prevent - scope bleeding between session types. - - **Verified by:** Session type contracts are enforced - - | Session | Input | Output | FSM Change | - | Planning | Pattern brief | Roadmap spec (.feature) | Creates roadmap | - | Design | Complex requirement | Decision specs + code stubs | None | - | Implementation | Roadmap spec | Code + tests | roadmap to active to completed | - | Planning + Design | Pattern brief | Spec + stubs | Creates roadmap | - - @acceptance-criteria @happy-path - Scenario: Session type contracts are enforced - Given a planning session is active - Then the session produces only a roadmap spec - And no TypeScript implementation code is created - And the FSM status is set to roadmap - - # =========================================================================== - # RULE 4: PLANNING SESSIONS PRODUCE SPECS ONLY - # =========================================================================== - - Rule: Planning sessions produce roadmap specs only - - **Invariant:** A planning session creates a roadmap spec with metadata, deliverables - table, Rule: blocks with invariants, and scenarios. It must not produce implementation - code, transition to active, or prompt for implementation readiness. - - **Rationale:** Planning is the cheapest session type — it produces .feature file - edits, no compilation needed. Mixing implementation into planning defeats the cost - advantage and introduces untested code without a locked scope. - - **Verified by:** Planning session output constraints - - | Do | Do NOT | - | Extract metadata from pattern brief | Create .ts implementation | - | Create spec file with proper tags | Transition to active | - | Add deliverables table in Background | Ask Ready to implement | - | Convert constraints to Rule: blocks | Write full implementations | - | Add scenarios: 1 happy-path + 1 validation per Rule | | - - @acceptance-criteria @happy-path - Scenario: Planning session output constraints - Given a planning session for a new pattern - When the session completes - Then a .feature file exists with @architect-status:roadmap - And the file contains a Background with deliverables table - And no .ts files were created in src/ - - # =========================================================================== - # RULE 5: DESIGN SESSIONS PRODUCE DECISIONS AND STUBS - # =========================================================================== - - Rule: Design sessions produce decisions and stubs only - - **Invariant:** A design session makes architectural decisions and creates code stubs - with interfaces. It must not produce implementation code. Context gathering via the - Process Data API must precede any explore agent usage. - - **Rationale:** Design sessions resolve ambiguity before implementation begins. Code - stubs in architect/stubs/ live outside src/ to avoid TypeScript compilation - and ESLint issues, making them zero-risk artifacts. - - **Verified by:** Design session output constraints - - | Use Design Session | Skip Design Session | - | Multiple valid approaches | Single obvious path | - | New patterns/capabilities | Bug fix | - | Cross-context coordination | Clear requirements | - - @acceptance-criteria @happy-path - Scenario: Design session output constraints - Given a design session for a pattern with multiple valid approaches - When the session completes - Then code stubs exist in architect/stubs/ - And no implementation code was written in src/ - And decision rationale is captured in Rule: blocks - - # =========================================================================== - # RULE 6: IMPLEMENTATION FOLLOWS FSM-ENFORCED EXECUTION ORDER - # =========================================================================== - - Rule: Implementation sessions follow FSM-enforced execution order - - **Invariant:** Implementation sessions must follow a strict 5-step execution order. - Transition to active must happen before any code changes. Transition to completed - must happen only when ALL deliverables are done. Skipping steps causes Process Guard - rejection at commit time. - - **Rationale:** The execution order ensures FSM state accurately reflects work state - at every point. Writing code before transitioning to active means Process Guard - sees changes to a roadmap spec (no scope protection). Marking completed with - incomplete work creates a hard-locked state that requires unlock-reason to fix. - - **Verified by:** Implementation execution order is enforced - - Execution order: - 1. Transition to active FIRST (before any code changes) - 2. Create executable spec stubs (if @architect-executable-specs present) - 3. For each deliverable: implement, test, update status to complete - 4. Transition to completed (only when ALL deliverables done) - 5. Regenerate docs: pnpm docs:all - - | Do NOT | Why | - | Add new deliverables to active spec | Scope-locked state prevents scope creep | - | Mark completed with incomplete work | Hard-locked state cannot be undone | - | Skip FSM transitions | Process Guard will reject | - | Edit generated docs directly | Regenerate from source | - - @acceptance-criteria @happy-path - Scenario: Implementation execution order is enforced - Given an implementation session for a roadmap pattern - When the session begins - Then the first action is transitioning status to active - And code changes follow the FSM transition - And completed is only set after all deliverables are done - - # =========================================================================== - # RULE 7: FSM ERRORS HAVE DOCUMENTED FIXES - # =========================================================================== - - Rule: FSM errors have documented fixes - - **Invariant:** Every Process Guard error code has a defined cause and fix. The - error codes, causes, and fixes form a closed set — no undocumented error states - exist. - - **Rationale:** Undocumented FSM errors cause session-blocking confusion. A lookup - table from error code to fix eliminates guesswork and prevents workarounds that - bypass process integrity. - - **Verified by:** All FSM errors have documented recovery paths - - | Error | Cause | Fix | - | completed-protection | File has completed status but no unlock tag | Add @architect-unlock-reason tag | - | invalid-status-transition | Skipped FSM state (e.g., roadmap to completed) | Follow path: roadmap to active to completed | - | scope-creep | Added deliverable to active spec | Remove deliverable OR revert to roadmap | - | session-scope (warning) | Modified file outside session scope | Add to scope OR use --ignore-session | - | session-excluded | Modified excluded pattern during session | Remove from exclusion OR override | - - Escape hatches for exceptional situations: - - | Situation | Solution | Example | - | Fix bug in completed spec | Add unlock reason tag | @architect-unlock-reason:Fix-typo | - | Modify outside session scope | Use ignore flag | architect-guard --staged --ignore-session | - | CI treats warnings as errors | Use strict flag | architect-guard --all --strict | - - @acceptance-criteria @happy-path - Scenario: All FSM errors have documented recovery paths - Given Process Guard reports a validation error - Then the error code appears in the FSM error reference table - And the table entry includes both cause and fix - - # =========================================================================== - # RULE 8: HANDOFF CAPTURES SESSION-END STATE - # =========================================================================== - - Rule: Handoff captures session-end state for continuity - - **Invariant:** Multi-session work requires handoff documentation generated from - the Process Data API. Handoff output always reflects actual annotation state, - not manual notes. - - **Rationale:** Manual session notes drift from actual deliverable state. The - handoff command derives state from annotations, ensuring the next session starts - from ground truth rather than stale notes. - - **Verified by:** Handoff output reflects annotation state - - Generate handoff via: pnpm architect:query -- handoff --pattern PatternName - Options: --git (include recent commits), --session (session identifier) - - Output includes: deliverable statuses, blockers, modification date, and next - steps — all derived from current annotation state. - - @acceptance-criteria @happy-path - Scenario: Handoff output reflects annotation state - Given a multi-session implementation with 3 deliverables - When running the handoff command after completing 2 deliverables - Then the output shows 2 complete and 1 pending - And the output reflects the current annotation state, not manual notes - - # =========================================================================== - # RULE 9: CLAUDE MODULE GENERATION IS THE MECHANISM (DEFERRED) - # =========================================================================== - - Rule: ClaudeModuleGeneration is the generation mechanism - - **Invariant:** Phase 39 depends on ClaudeModuleGeneration (Phase 25). Adding - `@architect-claude-module` and `@architect-claude-section:workflow` tags to - this spec will cause ClaudeModuleGeneration to produce `_claude-md/workflow/` - output files. The hand-written `_claude-md/workflow/` files are deleted after - successful verified generation. - - **Rationale:** The annotation work (Rule blocks in this spec) is immediately - useful — queryable via `pnpm architect:query -- rules`. Generation deliverables - cannot complete until Phase 25 ships the ClaudeModuleCodec. This sequencing is - intentional: the annotation investment has standalone value regardless of - whether the codec exists yet. - - **Prerequisite:** Phase 25 must add `workflow` to the `claude-section` enum - values (currently: core, process, testing, infrastructure). - - **Verified by:** Generated modules replace hand-written workflow files - - @acceptance-criteria @happy-path - Scenario: Generated modules replace hand-written workflow files - Given ClaudeModuleGeneration (Phase 25) is complete - And this spec is annotated with claude-module and claude-section tags - When running pnpm docs:claude-modules - Then _claude-md/workflow/ contains generated files derived from this spec - And the generated files replace the prior hand-written versions diff --git a/architect/specs/shape-extraction.feature b/architect/specs/shape-extraction.feature deleted file mode 100644 index ca1fbdc1..00000000 --- a/architect/specs/shape-extraction.feature +++ /dev/null @@ -1,600 +0,0 @@ -@architect -@architect-pattern:ShapeExtraction -@architect-status:completed -@architect-unlock-reason:Fix-code-fence-formatting-per-PR-review -@architect-phase:26 -@architect-effort:2d -@architect-product-area:Annotation -@architect-enables:DocGenerationProofOfConcept -@architect-business-value:eliminates-type-duplication-in-documentation -@architect-priority:high -Feature: TypeScript Shape Extraction for Documentation - - **Problem:** - Documentation comments duplicate type definitions that exist in the same file. - As interfaces change, the JSDoc examples drift. Maintaining two copies of the - same type information violates DRY and creates documentation rot. - - **Relationship to Documentation Generation:** - This capability is a critical enabler for ADR-021 (DocGenerationProofOfConcept). - Shape extraction allows code to own API type documentation while decisions own - intro/context and behavior specs own rules/examples. See the source mapping - pattern in doc-generation-proof-of-concept.feature. - - Current pattern (duplication): - """typescript - /** - * @architect - * - * ## API - * - * ```typescript - * // DUPLICATED from actual interface below - * interface DeciderInput { - * state: ProcessState; - * changes: ChangeDetection; - * } - * ``` - */ - - // The actual source of truth - export interface DeciderInput { - state: ProcessState; - changes: ChangeDetection; - } - """ - - **Solution:** - New tag `@architect-extract-shapes` lists type names to extract from the same file. - The extractor pulls actual TypeScript definitions from AST and inserts them into - generated documentation as fenced code blocks. - - Target pattern (single source): - """typescript - /** - * @architect - * @architect-extract-shapes DeciderInput, ValidationResult - * - * ## API - * - * (shapes inserted at generation time) - */ - - export interface DeciderInput { - state: ProcessState; - changes: ChangeDetection; - } - """ - - **Why It Matters:** - | Benefit | How | - | Single source of truth | Types defined once, extracted for docs | - | Always-current docs | Generated from actual code definitions | - | Reduced maintenance | Change type once, docs update automatically | - | API documentation | Public interfaces documented without duplication | - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | Tests | Test Type | - | extract-shapes tag definition | complete | taxonomy/registry-builder.ts | Yes | unit | - | AST shape extractor | complete | extractor/shape-extractor.ts | Yes | unit | - | Interface extraction | complete | extractor/shape-extractor.ts | Yes | unit | - | Type alias extraction | complete | extractor/shape-extractor.ts | Yes | unit | - | Enum extraction | complete | extractor/shape-extractor.ts | Yes | unit | - | Function signature extraction | complete | extractor/shape-extractor.ts | Yes | unit | - | ExtractedPattern schema extension | complete | validation-schemas/extracted-pattern.ts | Yes | unit | - | Shape rendering in codecs | complete | renderable/codecs/*.ts | Yes | unit | - | Shape extraction behavior test | complete | tests/features/extraction/shape-extraction.feature | Yes | behavior | - - # ============================================================================ - # RULE 1: Tag Definition - # ============================================================================ - - Rule: extract-shapes tag is defined in registry - - **Invariant:** The `extract-shapes` tag must exist with CSV format to list - multiple type names for extraction. - **Rationale:** Without a CSV-format tag, there is no mechanism to specify which type names to extract, and the extractor cannot discover shapes from source files. - - @acceptance-criteria @happy-path - Scenario: Tag registry contains extract-shapes - Given the tag registry is loaded - When querying for tag "extract-shapes" - Then the tag should exist - And the tag format should be "csv" - And the tag purpose should contain "type extraction" - - # ============================================================================ - # RULE 2: Interface Extraction - # ============================================================================ - - Rule: Interfaces are extracted from TypeScript AST - - **Invariant:** When `@architect-extract-shapes` lists an interface name, - the extractor must find and extract the complete interface definition - including JSDoc comments, generics, and extends clauses. - **Rationale:** Partial extraction (missing generics, JSDoc, or extends clauses) produces incomplete API documentation that misleads consumers about a type's actual contract. - - @acceptance-criteria @happy-path - Scenario: Extract simple interface - Given a TypeScript file with: - """typescript - /** - * @architect - * @architect-extract-shapes MyConfig - */ - - export interface MyConfig { - timeout: number; - retries: number; - } - """ - When extracting shapes - Then the extracted shapes contain "MyConfig" - And the shape includes: - """typescript - interface MyConfig { - timeout: number; - retries: number; - } - """ - - @acceptance-criteria @happy-path - Scenario: Extract interface with JSDoc - Given a TypeScript file with: - """typescript - /** - * @architect - * @architect-extract-shapes ConfigOptions - */ - - /** Configuration for the processor. */ - export interface ConfigOptions { - /** Timeout in milliseconds. */ - timeout: number; - } - """ - When extracting shapes - Then the shape includes the JSDoc comment "Configuration for the processor" - And field JSDoc "Timeout in milliseconds" is preserved - - @acceptance-criteria @happy-path - Scenario: Extract interface with generics - Given a TypeScript file with: - """typescript - /** - * @architect - * @architect-extract-shapes Result - */ - - export interface Result { - value?: T; - error?: E; - } - """ - When extracting shapes - Then the shape preserves generic parameters "" - - @acceptance-criteria @happy-path - Scenario: Extract interface with extends - Given a TypeScript file with: - """typescript - /** - * @architect - * @architect-extract-shapes ExtendedConfig - */ - - export interface ExtendedConfig extends BaseConfig { - extra: string; - } - """ - When extracting shapes - Then the shape includes "extends BaseConfig" - - @acceptance-criteria @validation - Scenario: Non-existent shape produces warning - Given a TypeScript file with: - """typescript - /** - * @architect - * @architect-extract-shapes NonExistent - */ - """ - When extracting shapes - Then a warning is logged: "Shape 'NonExistent' not found" - And extraction continues without error - - # ============================================================================ - # RULE 3: Type Alias Extraction - # ============================================================================ - - Rule: Type aliases are extracted from TypeScript AST - - **Invariant:** Type aliases (including union types, intersection types, - and mapped types) are extracted when listed in extract-shapes. - **Rationale:** Type aliases define domain vocabulary (status enums, branded types, utility types) that consumers need to understand API signatures; omitting them leaves gaps in generated documentation. - - @acceptance-criteria @happy-path - Scenario: Extract union type alias - Given a TypeScript file with: - """typescript - /** - * @architect - * @architect-extract-shapes Status - */ - - export type Status = 'pending' | 'active' | 'completed'; - """ - When extracting shapes - Then the extracted shapes contain "Status" - And the shape includes: - """typescript - type Status = 'pending' | 'active' | 'completed'; - """ - - @acceptance-criteria @happy-path - Scenario: Extract mapped type - Given a TypeScript file with: - """typescript - /** - * @architect - * @architect-extract-shapes Readonly - */ - - export type Readonly = { readonly [K in keyof T]: T[K] }; - """ - When extracting shapes - Then the shape preserves the mapped type syntax - - @acceptance-criteria @happy-path - Scenario: Extract conditional type - Given a TypeScript file with: - """typescript - /** - * @architect - * @architect-extract-shapes Unwrap - */ - - export type Unwrap = T extends Promise ? U : T; - """ - When extracting shapes - Then the shape preserves conditional type syntax - - # ============================================================================ - # RULE 4: Enum Extraction - # ============================================================================ - - Rule: Enums are extracted from TypeScript AST - - **Invariant:** Both string and numeric enums are extracted with their - complete member definitions. - **Rationale:** Enum members define the closed set of valid values for a type; extracting only the enum name without its members provides no useful information to documentation consumers. - - @acceptance-criteria @happy-path - Scenario: Extract string enum - Given a TypeScript file with: - """typescript - /** - * @architect - * @architect-extract-shapes Severity - */ - - export enum Severity { - Error = 'error', - Warning = 'warning', - Info = 'info', - } - """ - When extracting shapes - Then the extracted shapes contain "Severity" - And the shape includes all enum members - - @acceptance-criteria @happy-path - Scenario: Extract const enum - Given a TypeScript file with: - """typescript - /** - * @architect - * @architect-extract-shapes Direction - */ - - export const enum Direction { - Up, - Down, - Left, - Right, - } - """ - When extracting shapes - Then the shape includes "const enum" - - # ============================================================================ - # RULE 5: Function Signature Extraction - # ============================================================================ - - Rule: Function signatures are extracted (body omitted) - - **Invariant:** When a function name is listed in extract-shapes, only the - signature (parameters, return type, generics) is extracted. The function - body is replaced with ellipsis for documentation purposes. - **Rationale:** Including implementation bodies in generated documentation exposes internal logic, bloats output size, and creates a maintenance burden when internals change without API changes. - - @acceptance-criteria @happy-path - Scenario: Extract function signature - Given a TypeScript file with: - """typescript - /** - * @architect - * @architect-extract-shapes validateChanges - */ - - export function validateChanges(input: DeciderInput): DeciderOutput { - // 50 lines of implementation - return { result, events }; - } - """ - When extracting shapes - Then the extracted shapes contain "validateChanges" - And the shape includes: - """typescript - function validateChanges(input: DeciderInput): DeciderOutput; - """ - And the function body is not included - - @acceptance-criteria @happy-path - Scenario: Extract async function signature - Given a TypeScript file with: - """typescript - /** - * @architect - * @architect-extract-shapes fetchData - */ - - export async function fetchData(url: string): Promise { - // implementation - } - """ - When extracting shapes - Then the shape includes "async" and "Promise" - - @acceptance-criteria @happy-path - Scenario: Extract arrow function with type annotation - Given a TypeScript file with: - """typescript - /** - * @architect - * @architect-extract-shapes createValidator - */ - - export const createValidator: (rules: Rule[]) => Validator = (rules) => { - // implementation - }; - """ - When extracting shapes - Then the shape includes the type annotation - - # ============================================================================ - # RULE 6: Multiple Shapes in Order - # ============================================================================ - - Rule: Multiple shapes are extracted in specified order - - **Invariant:** When multiple shapes are listed, they appear in the - documentation in the order specified in the tag, not source order. - **Rationale:** Authors intentionally order shapes for progressive disclosure (e.g., output before input); using source order would break the author's intended documentation narrative. - - @acceptance-criteria @happy-path - Scenario: Shapes appear in tag order - Given a TypeScript file with: - """typescript - /** - * @architect - * @architect-extract-shapes Output, Input, Options - */ - - export interface Input { /* first in source */ } - export interface Options { /* second in source */ } - export interface Output { /* third in source */ } - """ - When extracting shapes - Then shapes appear in order: Output, Input, Options - - @acceptance-criteria @happy-path - Scenario: Mixed shape types in specified order - Given a TypeScript file with: - """typescript - /** - * @architect - * @architect-extract-shapes Status, Config, validate - */ - - export type Status = 'ok' | 'error'; - export interface Config { timeout: number; } - export function validate(input: unknown): boolean { return true; } - """ - When extracting shapes - Then shapes appear in order: Status (type), Config (interface), validate (function) - - # ============================================================================ - # RULE 7: Shape Rendering in Codecs - # ============================================================================ - - Rule: Extracted shapes render as fenced code blocks - - **Invariant:** Codecs render extracted shapes as TypeScript fenced code - blocks, grouped under an "API Types" or similar section. - **Rationale:** Rendering shapes as plain text or without language hints prevents syntax highlighting and makes API types unreadable in generated markdown documentation. - - @acceptance-criteria @happy-path - Scenario: Shapes render in claude module - Given a pattern with extracted shapes "Input" and "Output" - When generating claude module - Then the module contains: - """markdown - #### API Types - - ```typescript - interface Input { - // ... - } - - interface Output { - // ... - } - ``` - """ - - @acceptance-criteria @happy-path - Scenario: Shapes render in detailed docs - Given a pattern with extracted shapes - And detailLevel is "detailed" - When generating documentation - Then each shape appears in its own code block - And JSDoc comments are preserved above each shape - - # ============================================================================ - # RULE 8: Cross-File Shape References - # ============================================================================ - - Rule: Shapes can reference types from imports - - **Invariant:** Extracted shapes may reference types from imports. The - extractor does NOT resolve imports - it extracts the shape as-is. - Consumers understand that referenced types are defined elsewhere. - **Rationale:** Resolving imports would require full dependency graph traversal across the codebase, dramatically increasing complexity and coupling the extractor to the project's module structure. - - @acceptance-criteria @happy-path - Scenario: Shape with imported type reference - Given a TypeScript file with: - """typescript - /** - * @architect - * @architect-extract-shapes MyHandler - */ - - import { Request, Response } from './types.js'; - - export interface MyHandler { - handle(req: Request): Response; - } - """ - When extracting shapes - Then the shape includes "Request" and "Response" as type references - And imports are NOT included in extracted shape - - @acceptance-criteria @validation - Scenario: Shape extraction does not follow imports - Given `@architect-extract-shapes Request` where Request is imported - When extracting shapes - Then warning: "Shape 'Request' is imported, not defined in this file" - And suggestion: "Add extract-shapes to the source file" - - @acceptance-criteria @validation - Scenario: Re-exported type produces same warning as import - Given a TypeScript file with: - """typescript - /** - * @architect - * @architect-extract-shapes Foo - */ - - // Re-export from another file - export { Foo } from './types.js'; - export type { Bar } from './other.js'; - """ - When extracting shapes for "Foo" - Then warning: "Shape 'Foo' is re-exported, not defined in this file" - And the shape is NOT extracted - And suggestion: "Add @architect-extract-shapes to ./types.js instead" - - # ============================================================================ - # RULE 9: Overloaded Functions - # ============================================================================ - - Rule: Overloaded function signatures are all extracted - - **Invariant:** When a function has multiple overload signatures, all - signatures are extracted together as they represent the complete API. - **Rationale:** Extracting only one overload signature hides valid call patterns from consumers, leading to incorrect usage assumptions about the function's capabilities. - - @acceptance-criteria @happy-path - Scenario: Extract overloaded function signatures - Given a TypeScript file with: - """typescript - /** - * @architect - * @architect-extract-shapes validate - */ - - export function validate(input: string): boolean; - export function validate(input: number): boolean; - export function validate(input: string | number): boolean { - return typeof input === 'string' ? input.length > 0 : input > 0; - } - """ - When extracting shapes - Then the extracted shape includes all overload signatures: - """typescript - function validate(input: string): boolean; - function validate(input: number): boolean; - """ - And the implementation signature is NOT included - - @acceptance-criteria @happy-path - Scenario: Extract method overloads in interface - Given a TypeScript file with: - """typescript - /** - * @architect - * @architect-extract-shapes Parser - */ - - export interface Parser { - parse(input: string): Result; - parse(input: Buffer): Result; - } - """ - When extracting shapes - Then both method signatures are preserved in the interface - - # ============================================================================ - # RULE 10: Rendering Options - # ============================================================================ - - Rule: Shape rendering supports grouping options - - **Invariant:** Codecs can render shapes grouped in a single code block - or as separate code blocks, depending on detail level. - **Rationale:** Compact claude-md modules need grouped blocks to minimize token usage, while detailed human docs benefit from separate blocks with individual JSDoc annotations. - - @acceptance-criteria @happy-path - Scenario: Grouped rendering for compact output - Given extracted shapes "Input", "Output", "Options" - And rendering with groupInSingleBlock: true - When generating markdown - Then output is: - """markdown - ```typescript - interface Input { ... } - - interface Output { ... } - - interface Options { ... } - ``` - """ - - @acceptance-criteria @happy-path - Scenario: Separate rendering for detailed output - Given extracted shapes "Input", "Output" - And rendering with groupInSingleBlock: false - When generating markdown - Then output is: - """markdown - ```typescript - interface Input { ... } - ``` - - ```typescript - interface Output { ... } - ``` - """ diff --git a/architect/specs/step-lint-extended-rules.feature b/architect/specs/step-lint-extended-rules.feature deleted file mode 100644 index faf55b71..00000000 --- a/architect/specs/step-lint-extended-rules.feature +++ /dev/null @@ -1,149 +0,0 @@ -@architect -@architect-pattern:StepLintExtendedRules -@architect-status:completed -@architect-unlock-reason:Retroactive-completion -@architect-phase:51 -@architect-effort:1d -@architect-depends-on:StepLintVitestCucumber -@architect-product-area:Validation -@architect-business-value:catch-remaining-vitest-cucumber-traps-statically -@architect-priority:high -Feature: Step Lint Extended Rules - Additional vitest-cucumber Traps - - **Problem:** - The initial lint-steps CLI catches 8 vitest-cucumber traps, but 4 documented - traps from _claude-md/testing/vitest-cucumber.md remain uncovered: - - Hash in step text (mid-line) truncates the step at runtime - - Feature descriptions starting with Given/When/Then break the parser - - Scenario Outline steps using quoted values (the feature-file side of the - Two-Pattern Problem — the step-file side is already caught) - - Repeated identical step patterns in the same scenario overwrite registrations - - These cause cryptic runtime failures that are statically detectable. - - **Solution:** - Extend lint-steps with 4 new rules using the same pure-function architecture. - Two are feature-only checks, one is a step-only check, and one is a - cross-file check. All reuse the existing LintViolation/LintSummary types - and integrate into the existing runner pipeline. - - | New Rule | Category | Severity | Trap Caught | - | hash-in-step-text | feature-only | warning | Mid-line hash in step text interpreted as Gherkin comment | - | keyword-in-description | feature-only | error | Description line starting with Given/When/Then breaks parser | - | outline-quoted-values | cross-file | warning | Scenario Outline feature steps with quoted values suggest wrong pattern | - | repeated-step-pattern | step-only | error | Same step pattern registered twice in one scenario block | - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Tests | Location | - | Hash-in-step-text check | complete | Yes | src/lint/steps/feature-checks.ts | - | Keyword-in-description check | complete | Yes | src/lint/steps/feature-checks.ts | - | Outline-quoted-values check | complete | Yes | src/lint/steps/cross-checks.ts | - | Repeated-step-pattern check | complete | Yes | src/lint/steps/step-checks.ts | - | Rule definitions for 4 new rules | complete | No | src/lint/steps/types.ts | - | Gherkin executable specs | complete | Yes | tests/features/lint/step-lint-extended.feature | - - Rule: Hash in step text is detected - - **Invariant:** A hash character in the middle of a Gherkin step line - can be interpreted as a comment by some parsers, silently truncating - the step text. This differs from hash-in-description (which catches - hash inside description pseudo-code-blocks). - - **Rationale:** We encountered this exact trap while writing the - lint-steps test suite. Step text like "Given a file with # inside" - was silently truncated to "Given a file with". - - **Verified by:** Hash in step text produces warning, - Hash at start of comment line is not flagged - - @acceptance-criteria @happy-path - Scenario: Hash in step text produces warning - Given a feature file with hash in a Given step text - When the step linter checks the feature file - Then a hash-in-step-text warning is reported - - @acceptance-criteria @edge-case - Scenario: Hash at start of comment line is not flagged - Given a feature file with hash comment lines between scenarios - When the step linter checks the feature file - Then no hash-in-step-text warnings are reported - - Rule: Gherkin keywords in description text are detected - - **Invariant:** A Feature or Rule description line that starts with - Given, When, Then, And, or But breaks the Gherkin parser because it - interprets the line as a step definition rather than description text. - - **Rationale:** This is documented in vitest-cucumber quirks but has - no static detection. Authors writing natural language descriptions - accidentally start sentences with these keywords. - - **Verified by:** Description starting with Given is flagged, - Step lines with Given are not flagged - - @acceptance-criteria @happy-path - Scenario: Description starting with Given is flagged - Given a feature file with a description line starting with Given - When the step linter checks the feature file - Then a keyword-in-description error is reported - - @acceptance-criteria @validation - Scenario: Step lines with Given are not flagged - Given a feature file with Given only in step lines - When the step linter checks the feature file - Then no keyword-in-description errors are reported - - Rule: Scenario Outline steps with quoted values are detected - - **Invariant:** When a feature file has a Scenario Outline and its - steps use quoted values instead of angle-bracket placeholders, this - indicates the author may be using the Scenario pattern (function - params) instead of the ScenarioOutline pattern (variables object). - This is the feature-file side of the Two-Pattern Problem. - - **Rationale:** The existing scenario-outline-function-params rule - catches the step-file side. This rule catches the feature-file side - where quoted values in Scenario Outline steps suggest the author - expects Cucumber expression matching rather than variable substitution. - - **Verified by:** Outline step with quoted value produces warning, - Outline step with angle bracket is not flagged - - @acceptance-criteria @happy-path - Scenario: Outline step with quoted value produces warning - Given a feature file with a Scenario Outline using quoted step values - When the step linter checks the feature file - Then an outline-quoted-values warning is reported - - @acceptance-criteria @validation - Scenario: Outline step with angle bracket is not flagged - Given a feature file with a Scenario Outline using angle-bracket placeholders - When the step linter checks the feature file - Then no outline-quoted-values warnings are reported - - Rule: Repeated step patterns in the same scenario are detected - - **Invariant:** Registering the same step pattern twice in one - Scenario block causes vitest-cucumber to overwrite the first - registration. Only the last callback runs, causing silent test - failures where assertions appear to pass but the setup was wrong. - - **Rationale:** This happens when authors copy-paste step - definitions within a scenario and forget to change the pattern. - The failure is silent — tests pass but with wrong assertions. - - **Verified by:** Duplicate Given pattern in one scenario is flagged, - Same pattern in different scenarios is not flagged - - @acceptance-criteria @happy-path - Scenario: Duplicate Given pattern in one scenario is flagged - Given a step file with the same Given pattern registered twice in one scenario - When the step linter checks the step file - Then a repeated-step-pattern error is reported - - @acceptance-criteria @edge-case - Scenario: Same pattern in different scenarios is not flagged - Given a step file with the same pattern in separate scenario blocks - When the step linter checks the step file - Then no repeated-step-pattern errors are reported diff --git a/architect/specs/step-lint-vitest-cucumber.feature b/architect/specs/step-lint-vitest-cucumber.feature deleted file mode 100644 index d3930317..00000000 --- a/architect/specs/step-lint-vitest-cucumber.feature +++ /dev/null @@ -1,260 +0,0 @@ -@architect -@architect-pattern:StepLintVitestCucumber -@architect-status:completed -@architect-unlock-reason:Retroactive-completion-during-rebrand -@architect-phase:50 -@architect-effort:1d -@architect-product-area:Validation -@architect-business-value:prevent-hours-lost-debugging-vitest-cucumber-traps -@architect-priority:high -Feature: Step Lint - vitest-cucumber Static Compatibility Checker - - **Problem:** - Hours are lost debugging vitest-cucumber-specific issues that only surface - at test runtime. These are semantic traps at the boundary between .feature - files and .steps.ts files: using {string} function params inside - ScenarioOutline (should use variables object), forgetting to destructure - the And keyword (causes StepAbleUnknowStepError), missing Rule() wrappers, and hash - comments inside description pseudo-code-blocks. All are statically - detectable but no existing linter catches them. - - **Solution:** - A dedicated lint-steps CLI that statically analyzes .feature and .steps.ts - files for vitest-cucumber compatibility. Three check categories: - - Feature-only: hash-in-description, duplicate-and-step, dollar-in-step-text - - Step-only: regex-step-pattern, unsupported-phrase-type - - Cross-file: scenario-outline-function-params, missing-and-destructuring, - missing-rule-wrapper - - Reuses LintViolation/LintSummary from the existing lint engine for - consistent output formatting. Regex-based scanning (no TypeScript AST - needed). Feature-to-step pairing via loadFeature() path extraction. - - # =========================================================================== - # DELIVERABLES - # =========================================================================== - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Tests | Location | - | Step lint types and rule definitions | complete | No | src/lint/steps/types.ts | - | Feature-only checks (3 rules) | complete | Yes | src/lint/steps/feature-checks.ts | - | Step-only checks (2 rules) | complete | Yes | src/lint/steps/step-checks.ts | - | Cross-file checks (3 rules) | complete | Yes | src/lint/steps/cross-checks.ts | - | Feature-to-step pair resolver | complete | Yes | src/lint/steps/pair-resolver.ts | - | Lint runner orchestrator | complete | Yes | src/lint/steps/runner.ts | - | Barrel exports | complete | No | src/lint/steps/index.ts | - | CLI entry point | complete | No | src/cli/lint-steps.ts | - | Gherkin executable specs | complete | Yes | tests/features/lint/step-lint.feature | - - # =========================================================================== - # FEATURE-ONLY CHECKS - # =========================================================================== - - Rule: Hash comments inside description pseudo-code-blocks are detected - - **Invariant:** A # at the start of a line inside a """ block within a - Feature or Rule description terminates the description context, because - the Gherkin parser treats # as a comment even inside descriptions. - The """ delimiters in descriptions are NOT real DocStrings. - - **Rationale:** This is the most confusing Gherkin parser trap. Authors - embed code examples using """ and expect # comments to be protected. - The resulting parse error gives no hint about the actual cause. - - **Verified by:** Hash inside description pseudo-code-block is flagged, - Hash in step DocString is not flagged, - Section separator comments are not flagged - - @acceptance-criteria @happy-path - Scenario: Hash inside description pseudo-code-block is flagged - Given a feature file with a Rule description containing a """ block with a hash character - When the step linter checks the file - Then a hash-in-description error is reported - - @acceptance-criteria @validation - Scenario: Hash in step DocString is not flagged - Given a feature file with a hash character inside a Given step DocString - When the step linter checks the file - Then no hash-in-description errors are reported - - @acceptance-criteria @edge-case - Scenario: Section separator comments are not flagged - Given a feature file with hash section separators between keywords - When the step linter checks the file - Then no hash-in-description errors are reported - - Rule: Duplicate And steps in the same scenario are detected - - **Invariant:** Multiple And steps with identical text in the same - scenario cause vitest-cucumber step matching failures. The fix is - to consolidate into a single step with a DataTable. - - **Rationale:** Duplicate step text silently overwrites step registrations, causing the second And to match the first handler and produce wrong or undefined behavior at runtime. - - **Verified by:** Duplicate And step text is flagged, - Same And text in different scenarios is allowed - - @acceptance-criteria @happy-path - Scenario: Duplicate And step text is flagged - Given a feature file with two And steps having identical text in one scenario - When the step linter checks the file - Then a duplicate-and-step error is reported - - @acceptance-criteria @edge-case - Scenario: Same And text in different scenarios is allowed - Given a feature file with identical And text in separate scenarios - When the step linter checks the file - Then no duplicate-and-step errors are reported - - Rule: Dollar sign in step text is detected - - **Invariant:** The $ character in step text causes matching issues - in vitest-cucumber's expression parser. - - **Rationale:** The dollar sign is interpreted as a special character in expression parsing, causing steps to silently fail to match and producing confusing StepAbleUnknowStepError messages. - - **Verified by:** Dollar in step text produces warning - - @acceptance-criteria @happy-path - Scenario: Dollar in step text produces warning - Given a feature file with a dollar sign in a When step - When the step linter checks the file - Then a dollar-in-step-text warning is reported - - # =========================================================================== - # STEP-ONLY CHECKS - # =========================================================================== - - Rule: Regex step patterns are detected - - **Invariant:** vitest-cucumber only supports string patterns with - {string} and {int}. Regex patterns throw StepAbleStepExpressionError. - - **Rationale:** Regex patterns are a common Cucumber.js habit that compiles without error but throws at runtime in vitest-cucumber, wasting debugging time. - - **Verified by:** Regex pattern in Given is flagged - - @acceptance-criteria @happy-path - Scenario: Regex pattern in Given is flagged - Given a step file with "Given(/pattern/, ...)" - When the step linter checks the file - Then a regex-step-pattern error is reported - - Rule: Unsupported phrase type is detected - - **Invariant:** vitest-cucumber does not support {phrase}. Use {string} - with quoted values in the feature file. - - **Rationale:** The {phrase} type is valid in standard Cucumber but unsupported in vitest-cucumber, causing silent parameter capture failures that are difficult to trace. - - **Verified by:** Phrase type in step string is flagged - - @acceptance-criteria @happy-path - Scenario: Phrase type in step string is flagged - Given a step file with "{phrase}" in a step pattern string - When the step linter checks the file - Then an unsupported-phrase-type error is reported - - # =========================================================================== - # CROSS-FILE CHECKS - # =========================================================================== - - Rule: ScenarioOutline function params are detected - - **Invariant:** ScenarioOutline step callbacks must use the variables - object, not function params. Using (_ctx, value: string) means - value will be undefined at runtime. - - **Rationale:** This is the most common vitest-cucumber trap. Function params compile and even type-check, but the values are always undefined at runtime because ScenarioOutline injects data through the variables object, not positional arguments. - - **Verified by:** Function params in ScenarioOutline are flagged, - Function params in regular Scenario are not flagged - - @acceptance-criteria @happy-path - Scenario: Function params in ScenarioOutline are flagged - Given a feature file with a Scenario Outline - And a step file using ScenarioOutline with (_ctx, value: string) callback - When the step linter checks the paired files - Then a scenario-outline-function-params error is reported - - @acceptance-criteria @validation - Scenario: Function params in regular Scenario are not flagged - Given a feature file with a regular Scenario - And a step file using Scenario with (_ctx, value: string) callback - When the step linter checks the paired files - Then no scenario-outline-function-params errors are reported - - Rule: Missing And destructuring is detected - - **Invariant:** If a feature file has And steps, the step definition - must destructure And from the scenario callback. - - **Rationale:** Without destructuring And, vitest-cucumber cannot bind And steps and throws StepAbleUnknowStepError at runtime with no indication that a missing destructure is the cause. - - **Verified by:** Missing And destructuring is flagged, - Present And destructuring passes - - @acceptance-criteria @happy-path - Scenario: Missing And destructuring is flagged - Given a feature file with And steps - And a step file that does not destructure And - When the step linter checks the paired files - Then a missing-and-destructuring error is reported - - @acceptance-criteria @validation - Scenario: Present And destructuring passes - Given a feature file with And steps - And a step file that destructures And - When the step linter checks the paired files - Then no missing-and-destructuring errors are reported - - Rule: Missing Rule wrapper is detected - - **Invariant:** If a feature file has Rule: blocks, the step definition - must destructure Rule from describeFeature. - - **Rationale:** Without the Rule() wrapper, scenarios inside Rule: blocks are invisible to vitest-cucumber and silently never execute, giving a false green test suite. - - **Verified by:** Missing Rule wrapper is flagged, - Present Rule wrapper passes - - @acceptance-criteria @happy-path - Scenario: Missing Rule wrapper is flagged - Given a feature file with Rule: blocks - And a step file that does not destructure Rule - When the step linter checks the paired files - Then a missing-rule-wrapper error is reported - - @acceptance-criteria @validation - Scenario: Present Rule wrapper passes - Given a feature file with Rule: blocks - And a step file that destructures Rule from describeFeature - When the step linter checks the paired files - Then no missing-rule-wrapper errors are reported - - # =========================================================================== - # PAIR RESOLVER - # =========================================================================== - - Rule: Feature-to-step pairing resolves both loadFeature patterns - - **Invariant:** Step files use two loadFeature patterns: simple string - paths and resolve(__dirname, relative) paths. Both must be paired. - - **Rationale:** Unpaired feature files cannot be cross-checked for compatibility issues, leaving ScenarioOutline param misuse and missing destructures undetected. - - **Verified by:** Simple loadFeature path is paired, - Resolve-based loadFeature path is paired - - @acceptance-criteria @happy-path - Scenario: Simple loadFeature path is paired - Given a step file with "loadFeature('tests/features/foo.feature')" - When the pair resolver processes the file - Then the feature path is extracted as "tests/features/foo.feature" - - @acceptance-criteria @happy-path - Scenario: Resolve-based loadFeature path is paired - Given a step file with "loadFeature(resolve(__dirname, '../features/foo.feature'))" - When the pair resolver processes the file - Then the feature path is extracted as a relative path diff --git a/architect/specs/typescript-taxonomy-implementation.feature b/architect/specs/typescript-taxonomy-implementation.feature deleted file mode 100644 index c77233f1..00000000 --- a/architect/specs/typescript-taxonomy-implementation.feature +++ /dev/null @@ -1,164 +0,0 @@ -@architect -@architect-pattern:TypeScriptTaxonomyImplementation -@architect-status:completed -@architect-unlock-reason:PR28-acceptance-criteria-tagging -@architect-phase:99 -@architect-release:v1.0.0 -@architect-effort:4h -@architect-business-value:compile-time-taxonomy-protection -@architect-product-area:Annotation -@architect-user-role:Developer -Feature: TypeScript Taxonomy Implementation - - As an Architect developer - I want taxonomy defined in TypeScript with Zod integration - So that I get compile-time safety and runtime validation - - **Note (D12):** Implementation uses TypeScript as the single source of truth, - with consumers importing directly rather than generating intermediate JSON files. - - Background: Definition of Done - Given the following deliverables are complete: - | Deliverable | Status | Location | - | Status values constants | complete | src/taxonomy/status-values.ts | - | Format types constants | complete | src/taxonomy/format-types.ts | - | Category definitions | complete | src/taxonomy/categories.ts | - | Metadata tag definitions | complete | src/taxonomy/registry-builder.ts | - | Registry builder | complete | src/taxonomy/registry-builder.ts | - | Updated Zod schemas | complete | src/validation-schemas/tag-registry.ts | - And the following acceptance criteria are verified: - | Scenario | Status | - | Constants provide compile-time safety | complete | - | Zod schemas use TypeScript constants | complete | - | Existing consumers work unchanged | complete | - - # ───────────────────────────────────────────────────────────────────────────── - # Status Values - # ───────────────────────────────────────────────────────────────────────────── - - @happy-path @acceptance-criteria - Scenario: Define status values as TypeScript constant - Given a file "src/taxonomy/status-values.ts" - When I define the status values - Then it exports PROCESS_STATUS_VALUES as const array - And it exports ProcessStatusValue type inferred from the array - And Zod schemas use z.enum() with the constant - - Scenario: Invalid status value caught at compile time - Given code that uses ProcessStatusValue type - When I assign an invalid value like "draft" - Then TypeScript compilation fails - And the error message shows valid options - - Scenario: Status values match registry purpose - Given the package-level taxonomy - Then PROCESS_STATUS_VALUES contains ["roadmap", "active", "completed", "deferred"] - And the repo-level taxonomy follows PDR-005 FSM - - # ───────────────────────────────────────────────────────────────────────────── - # Format Types - # ───────────────────────────────────────────────────────────────────────────── - - Scenario: Define format types as TypeScript constant - Given a file "src/taxonomy/format-types.ts" - When I define the format types - Then it exports FORMAT_TYPES as const array - """ - ["value", "enum", "quoted-value", "csv", "number", "flag"] - """ - And it exports FormatType type - - # ───────────────────────────────────────────────────────────────────────────── - # Category Definitions - # ───────────────────────────────────────────────────────────────────────────── - - Scenario: Define categories as typed array - Given a file "src/taxonomy/categories.ts" - When I define the default categories - Then each category has tag, domain, priority, description, aliases - And categories are typed as CategoryDefinition[] - And category tags can be extracted as a union type (CategoryTag) - - Scenario: Category satisfies CategoryDefinitionSchema - Given a category definition in TypeScript - When validated against CategoryDefinitionSchema - Then it passes runtime validation - And the TypeScript type matches the Zod inference - - # ───────────────────────────────────────────────────────────────────────────── - # Metadata Tag Definitions - # ───────────────────────────────────────────────────────────────────────────── - - Scenario: Define metadata tags with typed format - Given the registry-builder.ts file - When I define a metadata tag with format "enum" - Then the values property is provided - And the values reference TypeScript constants - And TypeScript enforces type consistency - - Scenario: Metadata tag with invalid format rejected - Given a metadata tag definition - When format is "enum" but values is missing - Then Zod runtime validation fails - And TypeScript provides partial compile-time checking - - # ───────────────────────────────────────────────────────────────────────────── - # Registry Builder - # ───────────────────────────────────────────────────────────────────────────── - - Scenario: Build registry from TypeScript constants - Given all taxonomy constants are defined - When buildRegistry() is called - Then it returns a valid TagRegistry - And it uses imported constants for all values - And the result passes TagRegistrySchema validation - - Scenario: Registry builder is the single source - Given the registry builder function - When createDefaultTagRegistry() is called - Then it delegates to buildRegistry() - And no hardcoded values exist outside taxonomy/ - - # ───────────────────────────────────────────────────────────────────────────── - # Zod Schema Updates - # ───────────────────────────────────────────────────────────────────────────── - - @acceptance-criteria - Scenario: MetadataTagDefinitionSchema uses FORMAT_TYPES - Given the updated validation schema - When defining the format field - Then it uses z.enum(FORMAT_TYPES) not hardcoded strings - And changes to FORMAT_TYPES propagate automatically - - @acceptance-criteria - Scenario: Status field validation uses constant - Given a pattern with status field - When validated against schema - Then the schema references PROCESS_STATUS_VALUES - And invalid status values are rejected - - # ───────────────────────────────────────────────────────────────────────────── - # Developer Experience - # ───────────────────────────────────────────────────────────────────────────── - - Scenario: IDE autocomplete for status values - Given code that accepts ProcessStatusValue parameter - When typing the argument - Then IDE shows autocomplete with all valid values - And TypeScript inference provides the options - - Scenario: Refactoring propagates changes - Given a status value "roadmap" in constants - When I rename it to "planned" using IDE refactor - Then all TypeScript usages are updated automatically - - # ───────────────────────────────────────────────────────────────────────────── - # Registry Builder - # ───────────────────────────────────────────────────────────────────────────── - - @acceptance-criteria - Scenario: buildRegistry returns expected structure - Given the taxonomy module - When buildRegistry() is called - Then it returns the expected TagRegistry structure - And all existing generators work without modification diff --git a/architect/specs/universal-doc-generator-robustness.feature b/architect/specs/universal-doc-generator-robustness.feature deleted file mode 100644 index 96db9120..00000000 --- a/architect/specs/universal-doc-generator-robustness.feature +++ /dev/null @@ -1,247 +0,0 @@ -@architect -@architect-pattern:UniversalDocGeneratorRobustness -@architect-status:completed -@architect-unlock-reason:All-deliverables-implemented-and-tested -@architect-phase:28 -@architect-effort:2d -@architect-product-area:Generation -@architect-depends-on:DocGenerationProofOfConcept -@architect-business-value:enables-monorepo-scale-doc-generation -@architect-priority:high -Feature: Universal Document Generator - Robustness Foundation - - This feature transforms the PoC document generator into a production-ready - universal generator capable of operating at monorepo scale (~210 manual docs - to be replaced across the convex-event-sourcing repository). - - **GitHub Issue:** libar-ai/convex-event-sourcing#134 - - # ============================================================================ - # CONTEXT: Why Robustness Before New Features - # ============================================================================ - - Rule: Context - PoC limitations prevent monorepo-scale operation - - **Invariant:** The document generator must produce correct, deduplicated output and surface all errors explicitly before operating at monorepo scale. - **Rationale:** Silent failures and duplicated content in the PoC corrupt generated docs across all 210 target files, making bugs invisible until downstream consumers encounter broken documentation. - - **The Problem:** - - The DecisionDocGenerator PoC (Phase 27) successfully demonstrated code-first - documentation generation, but has reliability issues that prevent scaling: - - | Issue | Impact | Example | - | Content duplication | Confusing output | "Protection Levels" appears twice | - | No validation | Silent failures | Missing files produce empty sections | - | Scattered warnings | Hard to debug | console.warn in source-mapper.ts:149,339 | - | No file validation | Runtime errors | Invalid paths crash extraction | - - **Why Fix Before Adding Features:** - - The monorepo has 210 manually maintained docs. Before adding ADR generation - (33 files), guide generation (6 files), or glossary extraction, the foundation - must be reliable. A bug at the source mapper level corrupts ALL generated docs. - - **Target State:** - - | Metric | Current | Target | - | Duplicate sections | Common | Zero (fingerprint dedup) | - | Invalid mapping errors | Silent | Explicit validation errors | - | Warning visibility | console.warn | Structured Result warnings | - | File validation | None | Pre-flight existence check | - - # ============================================================================ - # DECISION: Four Robustness Deliverables - # ============================================================================ - - Rule: Decision - Robustness requires four coordinated improvements - - **Invariant:** Robustness improvements must be implemented as four distinct, coordinated modules (deduplication, validation, warning collection, file validation) rather than ad-hoc fixes. - **Rationale:** Scattering reliability fixes across existing code creates coupling and makes individual concerns untestable; isolated modules enable independent verification and replacement. - - **Architecture:** - - ``` - Source Mapping Table - │ - ▼ - ┌─────────────────────────────┐ - │ Validation Layer (NEW) │ ◄── Pre-flight checks - │ - File existence │ - │ - Method validity │ - │ - Format validation │ - └─────────────────────────────┘ - │ - ▼ - ┌─────────────────────────────┐ - │ Source Mapper │ - │ - Warning collector (NEW) │ ◄── Structured warnings - │ - Extraction dispatch │ - └─────────────────────────────┘ - │ - ▼ - ┌─────────────────────────────┐ - │ Content Assembly │ - │ - Deduplication (NEW) │ ◄── Fingerprint-based - │ - Section ordering │ - └─────────────────────────────┘ - │ - ▼ - ┌─────────────────────────────┐ - │ RenderableDocument │ - └─────────────────────────────┘ - ``` - - **Deliverable Ownership:** - - | Deliverable | Module | Responsibility | - | Content Deduplication | src/generators/content-deduplicator.ts | Remove duplicate sections | - | Validation Layer | src/generators/source-mapping-validator.ts | Pre-flight checks | - | Warning Collector | src/generators/warning-collector.ts | Unified warning handling | - | File Validation | Integrated into validator | Existence + readability | - - # ============================================================================ - # DELIVERABLES - # ============================================================================ - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | - | Content Deduplication | complete | src/generators/content-deduplicator.ts | - | Source Mapping Validator | complete | src/generators/source-mapping-validator.ts | - | Warning Collector | complete | src/generators/warning-collector.ts | - | Migrate console.warn calls | complete | src/generators/source-mapper.ts | - | Integration tests | complete | tests/features/doc-generation/robustness-integration.feature | - - # ============================================================================ - # SCENARIOS: Content Deduplication - # ============================================================================ - - Rule: Duplicate content must be detected and merged - - **Invariant:** No two sections in a generated document may have identical content fingerprints; duplicates must be merged into a single section with source attribution. - **Rationale:** Duplicate sections confuse readers and inflate document size, undermining trust in generated documentation as a reliable replacement for manually maintained docs. - - Content fingerprinting identifies duplicate sections extracted from multiple - sources. When duplicates are found, the system merges them intelligently - based on source priority. - - @acceptance-criteria @happy-path - Scenario: Identical sections are deduplicated - Given a source mapping that extracts "Protection Levels" from two sources - When the document is generated - Then only one "Protection Levels" section appears in output - And the section includes source attribution - - @acceptance-criteria @edge-case - Scenario: Similar but non-identical sections are preserved - Given a source mapping with "Overview" from TypeScript - And another "Overview" from a feature file with different content - When the document is generated - Then both sections appear with distinct names - And each section has source attribution - - # ============================================================================ - # SCENARIOS: Source Mapping Validation - # ============================================================================ - - Rule: Invalid source mappings must fail fast with clear errors - - **Invariant:** Every source mapping must pass pre-flight validation (file existence, method validity, readability) before any extraction is attempted. - **Rationale:** Without pre-flight validation, invalid mappings produce silent failures or cryptic runtime errors, making it impossible to diagnose configuration problems at monorepo scale. - - Pre-flight validation catches configuration errors before extraction begins. - This prevents silent failures and provides actionable error messages. - - @acceptance-criteria @happy-path - Scenario: Valid source mapping passes validation - Given a source mapping with: - | Section | Source File | Extraction Method | - | API Types | src/types.ts | @extract-shapes tag | - And the source file exists - When validating the source mapping - Then validation succeeds - And no warnings are produced - - @acceptance-criteria @validation - Scenario: Missing file produces validation error - Given a source mapping referencing "src/nonexistent.ts" - When validating the source mapping - Then validation fails with error "File not found: src/nonexistent.ts" - And no extraction is attempted - - @acceptance-criteria @validation - Scenario: Invalid extraction method produces validation error - Given a source mapping with method "invalid-method" - When validating the source mapping - Then validation fails with error containing "Unknown extraction method" - And suggestions for valid methods are provided - - @acceptance-criteria @validation - Scenario: Unreadable file produces validation error - Given a source mapping referencing a file without read permission - When validating the source mapping - Then validation fails with error "Cannot read file" - - # ============================================================================ - # SCENARIOS: Warning Collector - # ============================================================================ - - Rule: Warnings must be collected and reported consistently - - **Invariant:** All non-fatal issues during extraction must be captured in a structured warning collector grouped by source, never emitted via console.warn. - **Rationale:** Scattered console.warn calls are lost in CI output and lack source context, making it impossible to trace warnings back to the configuration entry that caused them. - - The warning collector replaces scattered console.warn calls with a - structured system that aggregates warnings and reports them consistently. - - @acceptance-criteria @happy-path - Scenario: Warnings are collected during extraction - Given extraction encounters a non-fatal issue - When extraction completes - Then the warning is captured in the warning collector - And the warning includes source location and context - - @acceptance-criteria @happy-path - Scenario: Multiple warnings from different sources are aggregated - Given extraction from source A produces warning "Missing JSDoc" - And extraction from source B produces warning "Empty rule block" - When extraction completes - Then both warnings are present in the collector - And warnings are grouped by source file - - @acceptance-criteria @integration - Scenario: Warnings are included in Result type - Given the source mapper returns a Result - When warnings were collected during extraction - Then Result.warnings contains all collected warnings - And the Result is still successful if no errors occurred - - # ============================================================================ - # CONSEQUENCES - # ============================================================================ - - Rule: Consequence - Improved reliability at cost of stricter validation - - **Invariant:** Existing source mappings that previously succeeded silently may now fail validation and must be updated to conform to the stricter checks. - **Rationale:** Allowing invalid mappings to bypass validation would preserve the silent-failure behavior the robustness work was designed to eliminate. - - **Positive:** - - - Duplicate content eliminated from generated docs - - Configuration errors caught before extraction - - Debugging simplified with structured warnings - - Ready for monorepo-scale operation - - **Negative:** - - - Existing source mappings may need updates to pass validation - - Strict validation may require more upfront configuration - - Additional processing overhead for deduplication - - **Migration:** - - Existing decision documents using the PoC generator may need updates: - 1. Run validation in dry-run mode to identify issues - 2. Fix file paths and extraction methods - 3. Re-run generation with new robustness checks diff --git a/architect/specs/validator-read-model-consolidation.feature b/architect/specs/validator-read-model-consolidation.feature deleted file mode 100644 index a48d3b47..00000000 --- a/architect/specs/validator-read-model-consolidation.feature +++ /dev/null @@ -1,203 +0,0 @@ -@architect -@architect-pattern:ValidatorReadModelConsolidation -@architect-status:completed -@architect-unlock-reason:Retroactive-completion-during-rebrand -@architect-phase:100 -@architect-effort:3d -@architect-product-area:Validation -@architect-include:process-workflow,codec-transformation -@architect-depends-on:ADR006SingleReadModelArchitecture -@architect-business-value:eliminate-parallel-pipeline-and-relationship-blind-spots-in-validator -@architect-priority:high -Feature: Validator Read Model Consolidation - - **Problem:** - `validate-patterns.ts` is the only feature consumer that bypasses the - PatternGraph. It wires its own mini-pipeline (scan + extract + ad-hoc - matching), creates a lossy local type (`GherkinPatternInfo`) that discards - relationship data, and then fails to resolve `@architect-implements` - links — producing 7 false-positive warnings. - - This is the Parallel Pipeline anti-pattern identified in ADR-006. The - validator re-derives pattern identity and cross-source matching from raw - scanner/extractor output, ignoring the relationship index that the - PatternGraph already computes with full forward and reverse edges. - - **Current violations in validate-patterns.ts (lines refer to pre-refactor):** - - | Anti-Pattern | Location | Evidence | - | Parallel Pipeline | Lines 32-35 | Imports scanPatterns, scanGherkinFiles, extractPatterns, extractProcessMetadata | - | Lossy Local Type | Lines 82-88 | GherkinPatternInfo keeps 5 of 30+ ExtractedPattern fields | - | Re-derived Relationship | Lines 373-384 | Builds Map by name-equality, cannot resolve implements links | - - **Current 7 warnings decomposed:** - - | Warning Pattern | Root Cause | Fix Category | - | ShapeExtractor | Has @architect-implements ShapeExtraction — only resolvable via relationshipIndex | Relationship-blind | - | DecisionDocGenerator | Test feature DecisionDocGeneratorTesting has @architect-implements:DecisionDocGenerator | Relationship-blind | - | ContentDeduplicator | Utility with @architect-phase 28 but no Gherkin spec | Spurious phase tag | - | FileCache | Utility with @architect-phase 27 but no Gherkin spec | Spurious phase tag | - | WarningCollector | Utility with @architect-phase 28 but no Gherkin spec | Spurious phase tag | - | SourceMappingValidator | Utility with @architect-phase 28 but no Gherkin spec | Spurious phase tag | - | SourceMapper | Utility with @architect-phase 27 but no Gherkin spec | Spurious phase tag | - - **Solution:** - Refactor `validate-patterns.ts` to consume the PatternGraph as its - data source for cross-source validation. The validator becomes a feature - consumer like codecs and the PatternGraphAPI — querying pre-computed - views and the relationship index instead of building its own maps from - raw data. - - This eliminates: - - `GherkinPatternInfo` (Lossy Local Type) - - `extractGherkinPatternInfo()` (duplicate extractor) - - Ad-hoc name-matching maps that miss implements relationships - - The need for any `buildImplementsLookup()` helper - - The validator retains its own validation logic (what to check, what - severity to assign). Only its data access changes — from raw state - to the read model. - - **Design Decisions:** - - DD-1: Reuse the same pipeline as pattern-graph-cli.ts — not a shared factory yet. - The validator will wire scan-extract-merge-transform inline, mirroring - how pattern-graph-cli.ts does it today (lines 490-558). Extracting a shared - pipeline factory is scoped to PatternGraphLayeredExtraction, not this spec. - This keeps the refactoring focused on data-access only. - - DD-2: The validatePatterns() function signature changes from - (tsPatterns, gherkinPatterns) to (dataset: RuntimePatternGraph). - All cross-source matching uses dataset.patterns + dataset.relationshipIndex. - The function remains exported for testability. - - DD-3: Cross-source matching uses a two-phase approach: - Phase 1 — Build a name-based Map from dataset.patterns (same as today). - Phase 2 — For each TS pattern not matched by name, check if it appears - in any relationshipIndex entry's implementedBy array. This resolves - the ShapeExtractor and DecisionDocGenerator false positives. - - DD-4: The validator will import transformToPatternGraphWithValidation - from generators/pipeline/index.js, plus the merge and hierarchy helpers - already used by pattern-graph-cli.ts. This is a temporary parallel pipeline - (acknowledged) that will be replaced when the pipeline factory exists. - - DD-5: Phase tag removal from utility patterns is a separate atomic step - done first — it reduces warnings from 7 to 2 and is independently - verifiable before touching any validator code. - - **Implementation Order:** - - | Step | What | Verification | - | 1 | Remove @architect-phase from 5 utility files | pnpm build, warnings drop from 7 to 2 | - | 2 | Wire PatternGraph pipeline in main() | pnpm typecheck | - | 3 | Rewrite validatePatterns() to consume RuntimePatternGraph | pnpm typecheck | - | 4 | Delete GherkinPatternInfo, extractGherkinPatternInfo | pnpm typecheck, pnpm test | - | 5 | Remove unused scanner/extractor imports | pnpm lint | - | 6 | Run pnpm validate:patterns — verify 0 errors, 0 warnings | Full verification | - - **Files Modified:** - - | File | Change | Lines Affected | - | src/cli/validate-patterns.ts | Major: rewrite pipeline + validatePatterns() | ~200 lines net reduction | - | src/generators/content-deduplicator.ts | Remove @architect-phase 28 | Line 6 | - | src/cache/file-cache.ts | Remove @architect-phase 27 | Line 5 | - | src/generators/warning-collector.ts | Remove @architect-phase 28 | Line 6 | - | src/generators/source-mapping-validator.ts | Remove @architect-phase 28 | Line 6 | - | src/generators/source-mapper.ts | Remove @architect-phase 27 | Line 6 | - - **What does NOT change:** - - - ValidationIssue, ValidationSummary, ValidateCLIConfig interfaces (stable API) - - parseArgs(), printHelp(), formatPretty(), formatJson() (CLI shell — untouched) - - DoD validation (already consumes scanned Gherkin files directly — correct for its purpose) - - Anti-pattern detection (already consumes scanned files — correct for its purpose) - - Exit code logic (unchanged) - - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | - | Remove phase tags from 5 utility patterns | complete | 5 TS files (see Files Modified) | - | Wire PatternGraph pipeline in main() | complete | src/cli/validate-patterns.ts | - | Rewrite validatePatterns() to consume RuntimePatternGraph | complete | src/cli/validate-patterns.ts | - | Delete GherkinPatternInfo and extractGherkinPatternInfo | complete | src/cli/validate-patterns.ts | - | Remove unused scanner/extractor imports | complete | src/cli/validate-patterns.ts | - | Zero warnings on pnpm validate:patterns | complete | CLI output | - - Rule: Validator queries the read model for cross-source matching - - **Invariant:** Pattern identity resolution — including implements - relationships in both directions — uses `PatternGraph.relationshipIndex` - rather than ad-hoc name-equality maps built from raw scanner output. - - **Rationale:** The PatternGraph computes implementedBy reverse lookups - in transform-dataset.ts (second pass, lines 488-546). The validator's - current name-equality Map cannot resolve ShapeExtractor -> ShapeExtraction - or DecisionDocGeneratorTesting -> DecisionDocGenerator because these are - implements relationships, not name matches. - - **Verified by:** Implements resolve bidirectionally, TS implementing Gherkin resolves - - @acceptance-criteria - Scenario: Implements relationships resolve in both directions - Given a TS pattern "DecisionDocGenerator" - And a Gherkin feature "DecisionDocGeneratorTesting" with @architect-implements:DecisionDocGenerator - When running cross-source validation - Then no warning is produced for "DecisionDocGenerator" - And the relationship is resolved via PatternGraph.relationshipIndex - - @acceptance-criteria - Scenario: TS pattern implementing a Gherkin spec resolves - Given a TS pattern "ShapeExtractor" with @architect-implements ShapeExtraction - And a Gherkin feature "ShapeExtraction" - When running cross-source validation - Then no warning is produced for "ShapeExtractor" - - Rule: No lossy local types in the validator - - **Invariant:** The validator operates on `ExtractedPattern` from the - PatternGraph, not a consumer-local DTO that discards fields. - - **Rationale:** GherkinPatternInfo keeps only name, phase, status, file, - and deliverables — discarding uses, dependsOn, implementsPatterns, - include, productArea, rules, and 20+ other fields. When the validator - needs relationship data, it cannot access it through the lossy type. - - **Verified by:** GherkinPatternInfo type is eliminated - - @acceptance-criteria - Scenario: GherkinPatternInfo type is eliminated - Given the refactored validate-patterns.ts - When inspecting the module - Then no GherkinPatternInfo interface exists - And no extractGherkinPatternInfo function exists - And pattern data comes from PatternGraph.patterns - - Rule: Utility patterns without specs are not false positives - - **Invariant:** Internal utility patterns that have a `@architect-phase` - but will never have a Gherkin spec should not carry phase metadata. - Phase tags signal roadmap participation. - - **Rationale:** Five utility patterns (ContentDeduplicator, FileCache, - WarningCollector, SourceMappingValidator, SourceMapper) have phase tags - from the phase when they were built. They are infrastructure, not roadmap - features. The validator correctly reports missing Gherkin for patterns - with phases — the fix is removing the phase tag, not suppressing the - warning. - - **Verified by:** Utility patterns do not trigger warnings - - @acceptance-criteria - Scenario: Utility patterns do not trigger warnings - Given ContentDeduplicator and FileCache without phase tags - When running cross-source validation - Then no warning is produced for either pattern - - @acceptance-criteria - Scenario: Full validation suite passes with zero warnings - Given the complete codebase with all annotated patterns - When running pnpm validate:patterns - Then exit code is 0 - And warning count is 0 - And error count is 0 diff --git a/architect/stubs/DataAPIDesignSessionSupport/handoff-generator.ts b/architect/stubs/DataAPIDesignSessionSupport/handoff-generator.ts deleted file mode 100644 index 0a3ca5b2..00000000 --- a/architect/stubs/DataAPIDesignSessionSupport/handoff-generator.ts +++ /dev/null @@ -1,171 +0,0 @@ -/** - * @architect - * @architect-status roadmap - * @architect-implements DataAPIDesignSessionSupport - * @architect-uses PatternGraphAPI, PatternGraph, ContextFormatterImpl - * @architect-used-by PatternGraphCLIImpl - * @architect-target src/api/handoff-generator.ts - * @architect-since DS-E - * - * ## HandoffGenerator — Session-End State Summary - * - * Pure function that assembles a handoff document from PatternGraphAPI - * and PatternGraph. Captures everything the next session needs to - * continue work without context loss. - * - * ### Algorithm - * - * 1. Resolve focal pattern via api.getPattern(name) — error if not found - * 2. Infer session type from FSM status (PDR-002 DD-3): - * active → implement, roadmap → design, completed → review, deferred → design - * Explicit sessionType option overrides inference. - * 3. Build sections in order: - * a. Session summary (name, type, date, status) - * b. Completed deliverables (status matches complete indicators) - * c. In-progress deliverables (not complete, not planned/Pending) - * d. Files modified (from modifiedFiles param, omitted if empty) - * e. Discovered items (discoveredGaps/Improvements/Learnings) - * f. Blockers (incomplete dependencies) - * g. Next session priorities (remaining deliverables, ordered) - * 4. Return HandoffDocument with all populated sections - * - * ### Reused Building Blocks - * - * - api.getPattern(name) — pattern metadata + discovery tags - * - api.getPatternDeliverables(name) — deliverable status split - * - api.getPatternDependencies(name) — blocker identification - * - isDeliverableComplete() logic from context-formatter.ts - * (reuse the COMPLETE_STATUSES set: done, complete, completed, check, x) - * - * ### Date Handling (PDR-002 DD-5) - * - * Always uses current date: new Date().toISOString().slice(0, 10). - * No --date flag. Handoff is run at session end. - * - * ### Git Integration (PDR-002 DD-2) - * - * This module has NO shell dependency. The modifiedFiles parameter is - * populated by the CLI handler when --git flag is present. The CLI calls: - * execSync('git diff --name-only HEAD', { encoding: 'utf-8' }) - * and passes the resulting file list. Without --git, the section is omitted. - * - * See: PDR-002 (DD-1 through DD-7), DataAPIDesignSessionSupport spec Rule 2 - * - * **When to Use:** When ending a work session and capturing state for the next session via the `handoff` CLI subcommand. - */ - -import type { SessionType } from '../data-api-context-assembly/context-assembler.js'; - -// --------------------------------------------------------------------------- -// Types -// --------------------------------------------------------------------------- - -/** - * Options for generating a handoff document. - */ -export interface HandoffOptions { - /** Pattern name to generate handoff for. */ - readonly patternName: string; - /** - * Session type override. If not provided, inferred from FSM status: - * active → implement, roadmap → design, completed → review, deferred → design. - */ - readonly sessionType?: SessionType; - /** - * Files modified during this session (from git diff). - * Populated by CLI handler when --git flag is present. - * Omitted section if undefined or empty. - */ - readonly modifiedFiles?: readonly string[]; -} - -/** - * A section of the handoff document. - */ -export interface HandoffSection { - /** Section title (e.g., "COMPLETED", "BLOCKERS"). */ - readonly title: string; - /** Section content lines. */ - readonly items: readonly string[]; -} - -/** - * Assembled handoff document. - */ -export interface HandoffDocument { - /** Pattern this handoff is for. */ - readonly pattern: string; - /** Session type (inferred or explicit). */ - readonly sessionType: SessionType; - /** Session date (YYYY-MM-DD). */ - readonly date: string; - /** Current pattern status. */ - readonly status: string | undefined; - /** Ordered sections of the handoff. */ - readonly sections: readonly HandoffSection[]; -} - -// --------------------------------------------------------------------------- -// Main Entry Point -// --------------------------------------------------------------------------- - -/** - * Generate a handoff document for a pattern's current session state. - * - * Assembles completed/in-progress deliverables, discovered items, - * blockers, and next priorities into a structured document. - * - * @param api - PatternGraphAPI for pattern/deliverable/dependency queries - * @param dataset - PatternGraph (unused currently, reserved for future) - * @param options - Pattern name, optional session type override, optional git files - * @returns Assembled handoff document - */ -export function generateHandoff( - _api: unknown, - _dataset: unknown, - _options: HandoffOptions -): HandoffDocument { - throw new Error('DataAPIDesignSessionSupport not yet implemented - roadmap pattern'); -} - -// --------------------------------------------------------------------------- -// Text Formatter (co-located per PDR-002 DD-7) -// --------------------------------------------------------------------------- - -/** - * Format a HandoffDocument as structured text with === markers. - * - * Output format: - * ``` - * === HANDOFF: PatternName (implement) === - * Date: 2026-02-07 | Status: active - * - * === COMPLETED === - * [x] Output pipeline (src/api/output-pipeline.ts) - * [x] Fuzzy search (src/api/fuzzy-match.ts) - * - * === IN PROGRESS === - * [ ] Field selection (src/api/field-selector.ts) - * - * === FILES MODIFIED === - * src/api/output-pipeline.ts - * src/api/fuzzy-match.ts - * tests/steps/output-shaping.steps.ts - * - * === DISCOVERED === - * Gaps: Missing-edge-case-for-empty-input - * Improvements: Cache-parsed-results - * - * === BLOCKERS === - * None - * - * === NEXT SESSION === - * 1. Field selection (src/api/field-selector.ts) - * ``` - * - * @param doc - Handoff document to format - * @returns Formatted text string - */ -export function formatHandoff(_doc: HandoffDocument): string { - throw new Error('DataAPIDesignSessionSupport not yet implemented - roadmap pattern'); -} diff --git a/architect/stubs/DataAPIDesignSessionSupport/scope-validator.ts b/architect/stubs/DataAPIDesignSessionSupport/scope-validator.ts deleted file mode 100644 index 5797da1b..00000000 --- a/architect/stubs/DataAPIDesignSessionSupport/scope-validator.ts +++ /dev/null @@ -1,284 +0,0 @@ -/** - * @architect - * @architect-status roadmap - * @architect-implements DataAPIDesignSessionSupport - * @architect-uses PatternGraphAPI, PatternGraph, StubResolver - * @architect-used-by PatternGraphCLIImpl - * @architect-target src/api/scope-validator.ts - * @architect-since DS-E - * - * ## ScopeValidator — Pre-flight Session Readiness Checker - * - * Pure function composition over PatternGraphAPI and PatternGraph. - * Runs a checklist of prerequisite validations before starting a - * design or implementation session. - * - * ### Algorithm - * - * 1. Resolve the focal pattern via api.getPattern(name) — error if not found - * 2. Select check functions based on scopeType: - * - implement: dependencies, deliverables, FSM, PDR refs, executable specs - * - design: stubs-from-deps - * 3. Execute each check function (pure, no I/O) → ValidationCheck - * 4. Aggregate: count BLOCKEDs and WARNs → determine verdict - * 5. Return ScopeValidationResult - * - * ### Check Composition - * - * Each check is an independent pure function returning ValidationCheck. - * This enables: - * - Individual unit testing per check - * - Easy addition of new checks without modifying existing ones - * - Selective check execution per scope type - * - * ### Reused Building Blocks - * - * - api.getPatternDependencies(name) — dependency status check - * - api.getPatternDeliverables(name) — deliverable existence check - * - api.isValidTransition(from, to) / api.checkTransition(from, to) — FSM check - * - findStubPatterns(dataset) + extractDecisionItems() from stub-resolver.ts — PDR check - * - resolveStubs(stubs, baseDir) from stub-resolver.ts — stub existence check - * - * ### Severity Model (PDR-002 DD-4) - * - * | Severity | Meaning | Blocks Session | - * |----------|---------|----------------| - * | PASS | Check passed | No | - * | BLOCKED | Hard prerequisite missing | Yes | - * | WARN | Recommendation not met | No (unless --strict) | - * - * See: PDR-002 (DD-1 through DD-7), DataAPIDesignSessionSupport spec Rule 1 - * - * **When to Use:** When running pre-flight checks before a session via the `scope-validate` CLI subcommand. - */ - -// --------------------------------------------------------------------------- -// Types -// --------------------------------------------------------------------------- - -/** - * Severity level for a single validation check. - * PASS = prerequisite met, BLOCKED = hard blocker, WARN = recommendation. - */ -export type CheckSeverity = 'PASS' | 'BLOCKED' | 'WARN'; - -/** - * Identifier for each validation check. Maps to a specific prerequisite. - */ -export type ScopeCheckId = - | 'dependencies-completed' - | 'stubs-from-deps-exist' - | 'deliverables-defined' - | 'fsm-allows-transition' - | 'design-decisions-recorded' - | 'executable-specs-set'; - -/** - * Result of a single validation check. - */ -export interface ValidationCheck { - /** Which check this result is for. */ - readonly id: ScopeCheckId; - /** Human-readable label (e.g., "Dependencies completed"). */ - readonly label: string; - /** PASS, BLOCKED, or WARN. */ - readonly severity: CheckSeverity; - /** Explanation of the result (e.g., "3/3 dependencies completed"). */ - readonly detail: string; - /** Names of blocking items, if any (e.g., dependency names). */ - readonly blockerNames?: readonly string[]; -} - -/** - * Session type to validate for. - * - implement: checks deps, deliverables, FSM, PDR refs, executable specs - * - design: checks stubs-from-deps - */ -export type ScopeType = 'implement' | 'design'; - -/** - * Options for scope validation. - */ -export interface ScopeValidationOptions { - /** Pattern name to validate. */ - readonly patternName: string; - /** Session type to validate for. */ - readonly scopeType: ScopeType; - /** Base directory for resolving stub file paths. */ - readonly baseDir: string; - /** When true, WARN checks are promoted to BLOCKED (DD-4, matches lint-process --strict). */ - readonly strict?: boolean; -} - -/** - * Aggregated result of all validation checks. - */ -export interface ScopeValidationResult { - /** Pattern that was validated. */ - readonly pattern: string; - /** Session type that was checked. */ - readonly scopeType: ScopeType; - /** All check results in order. */ - readonly checks: readonly ValidationCheck[]; - /** Overall verdict: ready (no blockers), blocked, or warnings (pass with caveats). */ - readonly verdict: 'ready' | 'blocked' | 'warnings'; - /** Count of BLOCKED checks. */ - readonly blockerCount: number; - /** Count of WARN checks. */ - readonly warnCount: number; -} - -// --------------------------------------------------------------------------- -// Main Entry Point -// --------------------------------------------------------------------------- - -/** - * Validate scope readiness for a pattern before starting a session. - * - * Selects and runs checks based on scopeType, then aggregates results - * into a verdict. - * - * @param api - PatternGraphAPI for pattern/FSM queries - * @param dataset - PatternGraph for stub resolution - * @param options - Pattern name, scope type, base directory - * @returns Aggregated validation result with verdict - */ -export function validateScope( - _api: unknown, - _dataset: unknown, - _options: ScopeValidationOptions -): ScopeValidationResult { - throw new Error('DataAPIDesignSessionSupport not yet implemented — roadmap pattern'); -} - -// --------------------------------------------------------------------------- -// Text Formatter (co-located per PDR-002 DD-7) -// --------------------------------------------------------------------------- - -/** - * Format a ScopeValidationResult as structured text with === markers. - * - * Output format: - * ``` - * === SCOPE VALIDATION: PatternName (implement) === - * - * === CHECKLIST === - * [PASS] Dependencies completed: Dep1, Dep2 - * [BLOCKED] FSM allows transition: completed cannot transition to active - * [WARN] Design decisions: no PDR references found - * - * === VERDICT === - * BLOCKED: 1 blocker(s) prevent implementation session - * - FSM: completed cannot transition to active - * ``` - * - * @param result - Validation result to format - * @returns Formatted text string - */ -export function formatScopeValidation(_result: ScopeValidationResult): string { - throw new Error('DataAPIDesignSessionSupport not yet implemented — roadmap pattern'); -} - -// --------------------------------------------------------------------------- -// Composable Check Functions — Implementation Session -// --------------------------------------------------------------------------- - -/** - * Check that all dependsOn patterns have status "completed". - * - * Uses: api.getPatternDependencies(name).dependsOn - * For each dependency: api.getPattern(dep).status === 'completed' - * - * PASS: All deps completed (or no deps). - * BLOCKED: Any dep not completed. Lists blocker names + their statuses. - */ -export function checkDependenciesCompleted( - _api: unknown, - _patternName: string -): ValidationCheck { - throw new Error('DataAPIDesignSessionSupport not yet implemented — roadmap pattern'); -} - -/** - * Check that the pattern has deliverables defined in its Background table. - * - * Uses: api.getPatternDeliverables(name) - * - * PASS: At least one deliverable exists. - * BLOCKED: No deliverables found (empty Background table or missing). - */ -export function checkDeliverablesDefined( - _api: unknown, - _patternName: string -): ValidationCheck { - throw new Error('DataAPIDesignSessionSupport not yet implemented — roadmap pattern'); -} - -/** - * Check that the FSM allows transitioning to "active" from current status. - * - * Uses: api.isValidTransition(currentStatus, 'active') - * api.checkTransition(currentStatus, 'active') for error details - * - * PASS: Transition is valid (e.g., roadmap → active). - * BLOCKED: Transition is invalid. Shows current status, valid alternatives. - */ -export function checkFsmAllowsTransition( - _api: unknown, - _patternName: string -): ValidationCheck { - throw new Error('DataAPIDesignSessionSupport not yet implemented — roadmap pattern'); -} - -/** - * Check whether design decisions (PDR references) exist in stubs. - * - * Uses: findStubPatterns(dataset) to get stubs for this pattern - * extractDecisionItems(description) to find PDR references - * - * PASS: At least one PDR reference found. - * WARN: No PDR references found (recommended but not required). - */ -export function checkDesignDecisionsRecorded( - _dataset: unknown, - _patternName: string -): ValidationCheck { - throw new Error('DataAPIDesignSessionSupport not yet implemented — roadmap pattern'); -} - -/** - * Check whether the pattern has an @executable-specs tag pointing to test location. - * - * Uses: pattern.behaviorFile or executableSpecs metadata field - * - * PASS: Executable specs location is set. - * WARN: No executable specs location (recommended but not required). - */ -export function checkExecutableSpecsSet( - _api: unknown, - _patternName: string -): ValidationCheck { - throw new Error('DataAPIDesignSessionSupport not yet implemented — roadmap pattern'); -} - -// --------------------------------------------------------------------------- -// Composable Check Functions — Design Session -// --------------------------------------------------------------------------- - -/** - * Check that dependency patterns have stubs from prior design sessions. - * - * Uses: api.getPatternDependencies(name).dependsOn - * For each dep: check implementedBy entries (stubs exist) - * resolveStubs(stubs, baseDir) to verify files exist on disk - * - * PASS: All dependencies have stubs. - * WARN: Some dependencies lack stubs (design sessions may not have run yet). - */ -export function checkStubsFromDepsExist( - _dataset: unknown, - _patternName: string, - _baseDir: string -): ValidationCheck { - throw new Error('DataAPIDesignSessionSupport not yet implemented — roadmap pattern'); -} diff --git a/architect/stubs/cli-recipe-codec/cli-recipe-generator.ts b/architect/stubs/cli-recipe-codec/cli-recipe-generator.ts deleted file mode 100644 index f34bd2e3..00000000 --- a/architect/stubs/cli-recipe-codec/cli-recipe-generator.ts +++ /dev/null @@ -1,310 +0,0 @@ -/** - * @architect - * @architect-status roadmap - * @architect-implements CliRecipeCodec - * @architect-target src/generators/built-in/cli-recipe-generator.ts - * - * ## CliRecipeGenerator — Standalone Generator for CLI Recipes and Narratives - * - * Produces `docs-live/reference/CLI-RECIPES.md` from the declarative - * CLI schema. Sibling to `CliReferenceGenerator` — both implement - * `DocumentGenerator`, both consume `CLI_SCHEMA` directly, neither depends - * on PatternGraph (ADR-006 compliant). - * - * **Design Decision DD-1 (Separate generator, not extension):** - * Reference tables and recipe guides serve different audiences and change at - * different cadences. Reference tables change when CLI flags are added or - * removed. Recipes change when workflow recommendations evolve. Coupling - * them in one generator would force both to change together. - * `CliReferenceGenerator` is already completed and tested (Phase 43) — - * extending it risks regressions. Two small standalone generators are easier - * to test and maintain than one large one. - * - * **Design Decision DD-2 (Schema-sourced content):** - * Recipe definitions and command narratives live in `CLI_SCHEMA` as structured - * data (see `recipe-schema.ts` for type definitions). The generator reads - * these fields and transforms them to `SectionBlock[]` using the renderable - * schema block builders. No domain knowledge is hardcoded in the generator. - * - * **Design Decision DD-3 (Preamble mechanism for editorial prose):** - * Editorial content ("Why Use This", Quick Start, session decision tree) is - * passed via a `preamble` field in the generator's config — an array of - * `SectionBlock[]` that is prepended before all generated content. This - * follows the proven pattern from `ReferenceDocConfig.preamble` and - * `ErrorGuideCodec` design. The preamble is configured in - * `architect.config.ts`, not in the generator source. - * - * **Design Decision DD-5 (No claude-md output):** - * The generator produces only `docs-live/reference/CLI-RECIPES.md`. - * It does NOT produce `_claude-md/` output because CLAUDE.md already has - * a manually-authored "Data API CLI" section that serves the AI context use - * case. Adding generated claude-md modules would create duplicate content. - * - * ### Output File Structure - * - * The generated `CLI-RECIPES.md` has this structure: - * - * ``` - * # Pattern Graph CLI Recipes & Workflow Guide - * > Auto-generated from CLI schema. - * - * [Preamble: Why Use This, Quick Start, Session Types] - * --- - * ## Session Workflow Commands ← from commandNarratives[0] - * ### overview ← from CommandNarrative entries - * ### scope-validate - * ... - * --- - * ## Pattern Discovery ← from commandNarratives[1] - * ### status - * ### list - * ... - * --- - * ## Common Recipes ← from recipes[0] - * ### Starting a Session ← from RecipeExample entries - * ### Finding What to Work On - * ... - * ``` - * - * ### Generator Architecture - * - * ``` - * CLI_SCHEMA.recipes → buildRecipeSections() → SectionBlock[] - * CLI_SCHEMA.commandNarratives → buildNarrativeSections() → SectionBlock[] - * config.preamble → prepended as-is → SectionBlock[] - * ↓ - * document() + renderToMarkdown() - * ↓ - * OutputFile { path, content } - * ``` - */ - -// Imports shown for design reference — actual paths resolve during implementation -// import type { DocumentGenerator, GeneratorContext, GeneratorOutput } from '../types.js'; -// import { CLI_SCHEMA } from '../../cli/cli-schema.js'; -// import type { RecipeGroup, CommandNarrativeGroup } from '../../cli/cli-schema.js'; -// import type { SectionBlock } from '../../renderable/schema.js'; -// import { heading, paragraph, code, separator, document } from '../../renderable/schema.js'; -// import { renderToMarkdown } from '../../renderable/render.js'; - -import type { RecipeGroup, CommandNarrativeGroup } from './recipe-schema.js'; - -// ============================================================================= -// Section Building — Recipes -// ============================================================================= - -/** - * Transform a RecipeGroup into SectionBlock[]. - * - * Each RecipeGroup becomes an H2 heading + optional description + recipe entries. - * Each RecipeExample becomes an H3 heading + purpose paragraph + code block. - * If expectedOutput is present, a separate "Example output" code block follows. - */ -function buildRecipeSections(_group: RecipeGroup): unknown[] { - // Implementation transforms RecipeGroup → SectionBlock[] using block builders: - // - // sections.push(heading(2, group.title)); - // if (group.description) sections.push(paragraph(group.description)); - // - // for (const recipe of group.recipes) { - // sections.push(heading(3, recipe.title)); - // sections.push(paragraph(recipe.purpose)); - // - // // Build code block from steps: - // // "pnpm process:query -- overview # project health" - // const codeContent = recipe.steps - // .map(s => s.comment ? `${s.command} # ${s.comment}` : s.command) - // .join('\n'); - // sections.push(code(codeContent, 'bash')); - // - // if (recipe.expectedOutput) { - // sections.push(paragraph('Example output:')); - // sections.push(code(recipe.expectedOutput)); - // } - // } - - throw new Error('CliRecipeCodec not yet implemented - roadmap pattern'); -} - -// ============================================================================= -// Section Building — Command Narratives -// ============================================================================= - -/** - * Transform a CommandNarrativeGroup into SectionBlock[]. - * - * Each group becomes an H2 heading + optional description. - * Each CommandNarrative becomes an H3 heading (command name) + description - * paragraph + usage example code block + optional details + optional output. - */ -function buildNarrativeSections(_group: CommandNarrativeGroup): unknown[] { - // Implementation transforms CommandNarrativeGroup → SectionBlock[] using block builders: - // - // sections.push(heading(2, group.title)); - // if (group.description) sections.push(paragraph(group.description)); - // - // for (const cmd of group.commands) { - // sections.push(heading(3, `\`${cmd.command}\``)); - // sections.push(paragraph(cmd.description)); - // sections.push(code(cmd.usageExample, 'bash')); - // if (cmd.details) sections.push(paragraph(cmd.details)); - // if (cmd.expectedOutput) { - // sections.push(paragraph('Example output:')); - // sections.push(code(cmd.expectedOutput)); - // } - // } - - throw new Error('CliRecipeCodec not yet implemented - roadmap pattern'); -} - -// ============================================================================= -// Document Assembly -// ============================================================================= - -/** - * Build the complete recipe document from CLI schema and preamble. - * - * Assembly order: - * 1. Auto-generation notice - * 2. Preamble sections (Why Use This, Quick Start, Session Types) - * 3. Command narrative sections (Session Workflow, Pattern Discovery, etc.) - * 4. Recipe sections (Common Recipes) - * - * @param _preamble - Editorial SectionBlock[] from generator config - */ -function buildRecipeDocument( - _preamble: readonly unknown[] -): string { - // Implementation: - // - // const sections: SectionBlock[] = []; - // - // // 1. Auto-generation notice - // sections.push(paragraph( - // '> Auto-generated from CLI schema. See [CLI Reference](./CLI-REFERENCE.md) for flag tables.' - // )); - // - // // 2. Preamble (editorial prose) - // if (preamble.length > 0) { - // sections.push(...preamble); - // sections.push(separator()); - // } - // - // // 3. Command narratives from schema - // if (CLI_SCHEMA.commandNarratives) { - // for (const group of CLI_SCHEMA.commandNarratives) { - // sections.push(...buildNarrativeSections(group)); - // sections.push(separator()); - // } - // } - // - // // 4. Recipes from schema - // if (CLI_SCHEMA.recipes) { - // for (const group of CLI_SCHEMA.recipes) { - // sections.push(...buildRecipeSections(group)); - // sections.push(separator()); - // } - // } - // - // const doc = document('Pattern Graph CLI Recipes & Workflow Guide', sections); - // return renderToMarkdown(doc); - - throw new Error('CliRecipeCodec not yet implemented - roadmap pattern'); -} - -// ============================================================================= -// Generator Configuration -// ============================================================================= - -/** - * Configuration for the CliRecipeGenerator. - * - * This is NOT a ReferenceDocConfig — this generator is standalone and does - * not go through the reference codec pipeline. The config shape is minimal: - * just preamble content and output path. - */ -export interface CliRecipeGeneratorConfig { - /** - * Static editorial sections prepended before all generated content. - * Contains "Why Use This", Quick Start example, and session decision tree. - * Configured in architect.config.ts. - */ - readonly preamble: readonly unknown[]; // SectionBlock[] — see src/renderable/schema.ts -} - -// ============================================================================= -// Generator Class -// ============================================================================= - -/** - * Standalone generator producing CLI-RECIPES.md from CLI schema. - * - * Follows the same pattern as CliReferenceGenerator: - * - Implements DocumentGenerator interface - * - Consumes CLI_SCHEMA directly (no PatternGraph dependency) - * - Returns OutputFile[] via standard orchestrator write path - * - Registered in architect.config.ts generatorOverrides - * - * Key difference from CliReferenceGenerator: - * - CliReferenceGenerator reads CLIOptionGroup → produces flag tables - * - CliRecipeGenerator reads RecipeGroup[] + CommandNarrativeGroup[] → produces recipes - * - Both read from the same CLI_SCHEMA constant - */ -class CliRecipeGeneratorImpl { - readonly name = 'cli-recipe'; - readonly description = 'Generate CLI recipe guide and command narratives from schema'; - - private readonly config: CliRecipeGeneratorConfig; - - constructor(config: CliRecipeGeneratorConfig) { - this.config = config; - } - - generate( - _patterns: readonly unknown[], - _context: unknown - ): Promise<{ files: readonly { path: string; content: string }[] }> { - const content = buildRecipeDocument(this.config.preamble); - - return Promise.resolve({ - files: [ - { - path: 'reference/CLI-RECIPES.md', - content, - }, - ], - }); - } -} - -/** - * Factory function following the createXxxGenerator() convention. - * - * Called from architect.config.ts or generator registration. - * Receives preamble content from config. - */ -export function createCliRecipeGenerator( - _config: CliRecipeGeneratorConfig -): unknown { - // Returns DocumentGenerator from src/generators/types.ts - throw new Error('CliRecipeCodec not yet implemented - roadmap pattern'); -} - -// ============================================================================= -// Config Registration Example -// ============================================================================= - -/** - * Registration follows the programmatic pattern from codec-generators.ts. - * The generator is registered similarly to createCliReferenceGenerator(). - * - * Output directory override is set in architect.config.ts: - * ```typescript - * generatorOverrides: { - * 'cli-recipe': { outputDirectory: 'docs-live' }, - * } - * ``` - */ - -// Exported only for design stub documentation purposes -export const _recipeExamples = { buildRecipeSections, buildNarrativeSections }; diff --git a/architect/stubs/cli-recipe-codec/recipe-data.ts b/architect/stubs/cli-recipe-codec/recipe-data.ts deleted file mode 100644 index 5644ef22..00000000 --- a/architect/stubs/cli-recipe-codec/recipe-data.ts +++ /dev/null @@ -1,270 +0,0 @@ -/** - * @architect - * @architect-status roadmap - * @architect-implements CliRecipeCodec - * @architect-target src/cli/cli-schema.ts - * - * ## Recipe Data — Example Definitions for CLI_SCHEMA Extension - * - * Demonstrates how recipe content from docs/CLI.md maps to the - * structured `RecipeGroup[]` and `CommandNarrativeGroup[]` schema types - * defined in `recipe-schema.ts`. - * - * **Content source:** All recipe and narrative content below is extracted from - * the manually-maintained `docs/CLI.md` (509 lines). During - * implementation, this content moves into `CLI_SCHEMA` in - * `src/cli/cli-schema.ts` and the manual prose sections in CLI.md - * are replaced with links to the generated file. - * - * **Coverage:** This stub shows 2 of 5 recipe groups and 2 of 6 command - * narratives to validate the schema design. The full implementation will - * include all content from CLI.md sections: - * - * | CLI.md Section | Schema Location | Content Type | - * |------------------------|-----------------|--------------| - * | Common Recipes (5 blocks, 42 lines) | `CLI_SCHEMA.recipes` | RecipeGroup[] | - * | Session Workflow Commands (6 cmds, 125 lines) | `CLI_SCHEMA.commandNarratives[0]` | CommandNarrativeGroup | - * | Pattern Discovery (8 cmds, 95 lines) | `CLI_SCHEMA.commandNarratives[1]` | CommandNarrativeGroup | - * | Architecture Queries (11 cmds, 28 lines) | `CLI_SCHEMA.commandNarratives[2]` | CommandNarrativeGroup | - * | Metadata and Inventory (4 cmds, 39 lines) | `CLI_SCHEMA.commandNarratives[3]` | CommandNarrativeGroup | - * | Why Use This (30 lines) | Generator preamble | SectionBlock[] | - * | Quick Start (32 lines) | Generator preamble | SectionBlock[] | - * | Session Types (12 lines) | Generator preamble | SectionBlock[] | - * - * **DD-4 validation:** Each command narrative below carries its description - * and usage example as structured data, not freeform prose. The generator - * renders these fields into markdown without any hardcoded command text. - */ - -import type { - RecipeGroup, - RecipeExample, - RecipeStep, - CommandNarrativeGroup, - CommandNarrative, -} from './recipe-schema.js'; - -// ============================================================================= -// Recipe Group Examples (2 of 5) -// ============================================================================= - -/** - * "Starting a Session" recipe — the recommended 3-command startup sequence. - * - * Source: docs/CLI.md lines 470-476 (Common Recipes section). - */ -const startingASessionRecipe: RecipeExample = { - title: 'Starting a Session', - purpose: 'The recommended session startup is three commands.', - steps: [ - { - command: 'pnpm process:query -- overview', - comment: 'project health', - }, - { - command: 'pnpm process:query -- scope-validate MyPattern implement', - comment: 'pre-flight', - }, - { - command: 'pnpm process:query -- context MyPattern --session implement', - comment: 'curated context', - }, - ] satisfies readonly RecipeStep[], -}; - -/** - * "Finding What to Work On" recipe — discover available work. - * - * Source: docs/CLI.md lines 478-484. - */ -const findingWorkRecipe: RecipeExample = { - title: 'Finding What to Work On', - purpose: 'Discover available patterns, blockers, and missing implementations.', - steps: [ - { - command: 'pnpm process:query -- list --status roadmap --names-only', - comment: 'available patterns', - }, - { - command: 'pnpm process:query -- arch blocking', - comment: 'stuck patterns', - }, - { - command: 'pnpm process:query -- stubs --unresolved', - comment: 'missing implementations', - }, - ] satisfies readonly RecipeStep[], -}; - -/** - * Example RecipeGroup composing the two recipe examples above. - * - * During implementation, all 5 recipe groups from CLI.md are defined: - * 1. Starting a Session - * 2. Finding What to Work On - * 3. Investigating a Pattern - * 4. Design Session Prep - * 5. Ending a Session - */ -const COMMON_RECIPES: RecipeGroup = { - title: 'Common Recipes', - description: 'Frequently-used command sequences for daily workflow.', - recipes: [startingASessionRecipe, findingWorkRecipe], -}; - -// ============================================================================= -// Command Narrative Examples (2 of 6 session workflow commands) -// ============================================================================= - -/** - * Narrative for the `overview` command. - * - * Source: docs/CLI.md lines 86-91. - */ -const overviewNarrative: CommandNarrative = { - command: 'overview', - description: - 'Executive summary: progress percentage, active phases, blocking patterns, and a CLI cheat sheet.', - usageExample: 'pnpm process:query -- overview', - expectedOutput: [ - '=== PROGRESS ===', - '318 patterns (224 completed, 47 active, 47 planned) = 70%', - '', - '=== ACTIVE PHASES ===', - 'Phase 24: PatternGraphAPIRelationshipQueries (1 active)', - 'Phase 25: DataAPIStubIntegration (1 active)', - '', - '=== BLOCKING ===', - 'StepLintExtendedRules blocked by: StepLintVitestCucumber', - '', - '=== DATA API ===', - 'pnpm process:query -- ', - ' overview, context, scope-validate, dep-tree, list, stubs, files, rules, arch blocking', - ].join('\n'), -}; - -/** - * Narrative for the `scope-validate` command. - * - * Source: docs/CLI.md lines 94-117. - */ -const scopeValidateNarrative: CommandNarrative = { - command: 'scope-validate', - description: - 'Highest-impact command. Pre-flight readiness check that prevents wasted sessions. Returns a PASS/BLOCKED/WARN verdict covering: dependency completion, deliverable definitions, FSM transition validity, and design decisions.', - usageExample: 'pnpm process:query -- scope-validate MyPattern implement', - details: - 'Checks: dependency completion, deliverable definitions, FSM transition validity, design decisions, executable spec location. Valid session types: `implement`, `design`.', - expectedOutput: [ - '=== SCOPE VALIDATION: DataAPIDesignSessionSupport (implement) ===', - '', - '=== CHECKLIST ===', - '[PASS] Dependencies completed: 2/2 completed', - '[PASS] Deliverables defined: 4 deliverable(s) found', - '[BLOCKED] FSM allows transition: completed -> active is not valid.', - '[WARN] Design decisions recorded: No PDR/AD references found in stubs', - '', - '=== VERDICT ===', - 'BLOCKED: 1 blocker(s) prevent implement session', - ].join('\n'), -}; - -/** - * Example CommandNarrativeGroup for Session Workflow Commands. - * - * During implementation, all 6 session workflow commands are included: - * overview, scope-validate, context, dep-tree, files, handoff. - * - * Additional CommandNarrativeGroups are created for: - * - Pattern Discovery (status, list, search, pattern, stubs, decisions, pdr, rules) - * - Architecture Queries (arch roles, context, layer, neighborhood, compare, coverage, dangling, orphans, blocking) - * - Metadata and Inventory (tags, sources, unannotated, query) - */ -const SESSION_WORKFLOW_NARRATIVES: CommandNarrativeGroup = { - title: 'Session Workflow Commands', - description: - 'These 6 commands output structured text (not JSON). They are designed for terminal reading and AI context consumption.', - commands: [overviewNarrative, scopeValidateNarrative], -}; - -// ============================================================================= -// Preamble Content Example (configured in architect.config.ts) -// ============================================================================= - -/** - * Example preamble sections for the CliRecipeGenerator config. - * - * These are SectionBlock[] that get prepended before generated content. - * During implementation, the full preamble includes: - * - * 1. "Why Use This" — comparison table (CLI vs reading markdown) - * 2. Quick Start — 3-command sequence with example `overview` output - * 3. Session Types — table + decision tree sentence - * - * Source: docs/CLI.md lines 13-77. - * - * Note: The preamble is configured in architect.config.ts, NOT in - * CLI_SCHEMA. This keeps editorial prose separate from structured command - * metadata and follows the proven pattern from ReferenceDocConfig.preamble. - */ -const EXAMPLE_PREAMBLE = [ - // --- Why Use This --- - { - type: 'heading' as const, - level: 2, - text: 'Why Use This', - }, - { - type: 'paragraph' as const, - text: 'Traditional approach: read generated Markdown, parse it mentally, hope it\'s current. This CLI queries the **same annotated sources** that generate those docs -- in real time, with typed output.', - }, - { - type: 'table' as const, - columns: ['Approach', 'Context Cost', 'Accuracy', 'Speed'], - rows: [ - ['Parse generated Markdown', 'High', 'Snapshot at gen time', 'Slow'], - ['**Data API CLI**', '**Low**', 'Real-time from source', 'Instant'], - ], - }, - { - type: 'paragraph' as const, - text: [ - 'The CLI has two output modes:', - '', - '- **Text commands** (6) -- formatted for terminal reading or AI context. Use `===` section markers for structure.', - '- **JSON commands** (12+) -- wrapped in a `QueryResult` envelope. Pipeable to `jq`.', - ].join('\n'), - }, - - // --- Session Types --- - { - type: 'heading' as const, - level: 2, - text: 'Session Types', - }, - { - type: 'paragraph' as const, - text: 'The `--session` flag tailors output to what you need right now:', - }, - { - type: 'table' as const, - columns: ['Type', 'Includes', 'When to Use'], - rows: [ - ['`planning`', 'Pattern metadata and spec file only', 'Creating a new roadmap spec'], - ['`design`', 'Full: metadata, stubs, deps, deliverables', 'Making architectural decisions'], - ['`implement`', 'Focused: deliverables, FSM state, test files', 'Writing code from an existing spec'], - ], - }, - { - type: 'paragraph' as const, - text: '**Decision tree:** Starting to code? `implement`. Complex decisions? `design`. New pattern? `planning`. Not sure? Run `overview` first.', - }, -] as const; - -// ============================================================================= -// Placeholder -// ============================================================================= - -export function _recipeDataPlaceholder(): never { - throw new Error('CliRecipeCodec not yet implemented - roadmap pattern'); -} diff --git a/architect/stubs/cli-recipe-codec/recipe-schema.ts b/architect/stubs/cli-recipe-codec/recipe-schema.ts deleted file mode 100644 index c90c437d..00000000 --- a/architect/stubs/cli-recipe-codec/recipe-schema.ts +++ /dev/null @@ -1,219 +0,0 @@ -/** - * @architect - * @architect-status roadmap - * @architect-implements CliRecipeCodec - * @architect-target src/cli/cli-schema.ts - * - * ## Recipe Schema — Structured Data Model for CLI Recipes - * - * Defines `RecipeGroup`, `RecipeExample`, and `RecipeStep` interfaces that - * extend `CLISchema` with multi-command recipe sequences. - * - * **Design Decision DD-1 (Separate schema extension, not inline per-option):** - * Recipes are multi-command sequences ("run these 3 commands in order") with - * explanatory context. They do not fit into `CLIOptionGroup` which models - * individual flags. A separate `RecipeGroup[]` field on `CLISchema` keeps - * the type system clean — existing `CLIOptionGroup` types are unchanged, - * and recipes are independently testable. - * - * Alternatives considered: - * - (A) Inline recipes in `CLIOptionGroup` — rejected because recipes span - * multiple option groups (e.g., "Starting a Session" uses `overview` + - * `scope-validate` + `context` which span session and global options). - * - (C) Feature file Rule: blocks — rejected because recipe content is - * procedural ("do X then Y"), not behavioral invariants. Feature files - * define what IS true; recipes define what to DO. - * - * **Design Decision DD-3 (Preamble for editorial prose):** - * The "Why Use This" motivation (~30 lines), Quick Start with example output - * (~32 lines), and session type decision tree (~12 lines) use the preamble - * mechanism in generator config, NOT fields in the recipe schema. These are - * editorial prose requiring human judgment, not structured data that can be - * derived from CLI metadata. The preamble mechanism is proven by - * DocsConsolidationStrategy Phase 2 and ErrorGuideCodec design stubs. - * - * **Design Decision DD-4 (Extended descriptions from schema):** - * Narrative command descriptions ("Highest-impact command. Pre-flight readiness - * check...") are sourced from `CommandNarrative` entries in the schema, not - * hardcoded in the generator. Each `CommandNarrative` carries a title, rich - * description, and usage example. This extends the existing `CLIOptionGroup` - * pattern: `CLIOptionGroup.description` carries per-group prose, and - * `CommandNarrative` carries per-command prose. - * - * We chose a separate `CommandNarrative` type rather than extending - * `CLIOptionGroup.description` because: - * - Command groups (Session Workflow, Pattern Discovery, Architecture) contain - * heterogeneous commands that each need their own narrative - * - `CLIOptionGroup` is designed for flag tables, not command catalogs - * - Narrative entries need usage examples (code blocks) which don't fit - * in a single description string - * - * **Design Decision DD-5 (Recipe organization and output format):** - * Recipes are grouped by task intent, not by session type or command name. - * Groups: "Starting a Session", "Finding What to Work On", "Investigating a - * Pattern", "Design Session Prep", "Ending a Session". Each `RecipeExample` - * has a title, purpose string, array of `RecipeStep` (command + comment), - * and optional expected output. This mirrors the existing Common Recipes - * section structure in CLI.md, ensuring zero information loss. - * - * ### Integration with CLISchema - * - * The existing `CLISchema` interface gains two new fields: - * - * | Field | Type | Purpose | - * |-------|------|---------| - * | `recipes` | `RecipeGroup[]` | Multi-command recipe sequences | - * | `commandNarratives` | `CommandNarrativeGroup[]` | Per-command narrative descriptions | - * - * Both are optional to preserve backward compatibility with existing consumers - * (CliReferenceGenerator, showHelp). - */ - -// ============================================================================= -// Recipe Schema Types -// ============================================================================= - -/** - * A single step in a recipe — one CLI command with an explanatory comment. - * - * @example - * ```typescript - * const step: RecipeStep = { - * command: 'pnpm process:query -- overview', - * comment: 'project health', - * }; - * ``` - */ -export interface RecipeStep { - /** The CLI command to run */ - readonly command: string; - - /** Short inline comment explaining what this step does */ - readonly comment?: string; -} - -/** - * A complete recipe example — a titled sequence of commands with context. - * - * @example - * ```typescript - * const recipe: RecipeExample = { - * title: 'Starting a Session', - * purpose: 'The recommended session startup is three commands.', - * steps: [ - * { command: 'pnpm process:query -- overview', comment: 'project health' }, - * { command: 'pnpm process:query -- scope-validate MyPattern implement', comment: 'pre-flight' }, - * { command: 'pnpm process:query -- context MyPattern --session implement', comment: 'curated context' }, - * ], - * }; - * ``` - */ -export interface RecipeExample { - /** Recipe title (becomes H3 or H4 heading) */ - readonly title: string; - - /** One-line purpose description rendered before the code block */ - readonly purpose: string; - - /** Ordered sequence of CLI commands */ - readonly steps: readonly RecipeStep[]; - - /** - * Optional expected output block rendered after the commands. - * Static string — no build-time CLI execution. - */ - readonly expectedOutput?: string; -} - -/** - * A group of related recipes under a shared heading. - * - * @example - * ```typescript - * const group: RecipeGroup = { - * title: 'Common Recipes', - * description: 'Frequently-used command sequences for daily workflow.', - * recipes: [startingASession, findingWork], - * }; - * ``` - */ -export interface RecipeGroup { - /** Group heading (becomes H2 heading) */ - readonly title: string; - - /** Optional intro prose rendered below the heading */ - readonly description?: string; - - /** Recipe examples in this group */ - readonly recipes: readonly RecipeExample[]; -} - -// ============================================================================= -// Command Narrative Types -// ============================================================================= - -/** - * Narrative metadata for a single CLI command. - * - * Carries the rich description and usage example that appears in the - * generated recipe file alongside the command. This replaces the manually - * maintained prose in docs/CLI.md sections like "Session Workflow - * Commands" and "Pattern Discovery". - * - * @example - * ```typescript - * const narrative: CommandNarrative = { - * command: 'scope-validate', - * description: 'Highest-impact command. Pre-flight readiness check that prevents wasted sessions.', - * usageExample: 'pnpm process:query -- scope-validate MyPattern implement', - * details: 'Checks: dependency completion, deliverable definitions, FSM transition validity, design decisions.', - * }; - * ``` - */ -export interface CommandNarrative { - /** Command name (e.g., 'overview', 'scope-validate', 'context') */ - readonly command: string; - - /** Rich narrative description of what this command does and why */ - readonly description: string; - - /** Primary usage example as a CLI command string */ - readonly usageExample: string; - - /** Additional detail text rendered below the usage example */ - readonly details?: string; - - /** Optional expected output block for this command */ - readonly expectedOutput?: string; -} - -/** - * A group of related command narratives under a shared section heading. - * - * Maps to sections like "Session Workflow Commands" (6 text commands) - * and "Pattern Discovery" (8 JSON commands) in docs/CLI.md. - */ -export interface CommandNarrativeGroup { - /** Section heading (e.g., 'Session Workflow Commands') */ - readonly title: string; - - /** Intro prose for the section */ - readonly description?: string; - - /** Individual command narratives */ - readonly commands: readonly CommandNarrative[]; -} - -// ============================================================================= -// CLISchema Extension -// ============================================================================= - -/** - * CLISchema already includes `recipes` and `commandNarratives` fields - * (added during Phase 43 implementation). See `src/cli/cli-schema.ts` - * for the canonical interface. No separate extended type needed. - */ - -export function _recipeSchemaPlaceholder(): never { - throw new Error('CliRecipeCodec not yet implemented - roadmap pattern'); -} diff --git a/architect/stubs/config-based-workflow-definition/default-workflow-config.ts b/architect/stubs/config-based-workflow-definition/default-workflow-config.ts deleted file mode 100644 index 4806c3dc..00000000 --- a/architect/stubs/config-based-workflow-definition/default-workflow-config.ts +++ /dev/null @@ -1,65 +0,0 @@ -/** - * @architect - * @architect-status roadmap - * @architect-implements ConfigBasedWorkflowDefinition - * @architect-product-area Configuration - * @architect-target src/config/workflow-loader.ts - * @architect-since DS-1 - * - * ## DEFAULT_WORKFLOW_CONFIG — Inline Default Workflow Constant - * - * Replaces the dead file-based loading path (`catalogue/workflows/6-phase-standard.json`) - * with an inline constant that satisfies the existing `WorkflowConfig` type. - * - * The constant uses only the 4 canonical statuses from `PROCESS_STATUS_VALUES` - * (roadmap, active, completed, deferred) — not the stale 5-status set from - * the deleted JSON (which included non-canonical `implemented` and `partial`). - * - * DD-1: Inline constant in workflow-loader.ts, not preset integration. - * DD-2: Constant satisfies existing WorkflowConfig type from workflow-config.ts. - * DD-4: loadDefaultWorkflow() returns LoadedWorkflow synchronously (not Promise). - * - * **When to Use:** When the workflow loader needs a default workflow config — import this constant instead of loading from a JSON file. - */ - -import type { WorkflowConfig } from '../../src/validation-schemas/workflow-config.js'; - -// DD-2: Satisfies existing WorkflowConfig type — no new types needed. -// Fields included: status name + emoji, phase name + order, top-level name/version/defaultStatus. -// Fields omitted: transitionsTo, terminal, artifacts, statusOnEntry, description — all optional -// in WorkflowConfigSchema and never consumed by any code path. -// -// The sole functional consumer is transform-dataset.ts:610: -// workflow?.config.phases.find((p) => p.order === phaseNumber)?.name -export const DEFAULT_WORKFLOW_CONFIG: WorkflowConfig = { - name: '6-phase-standard', - version: '1.0.0', - statuses: [ - { name: 'roadmap', emoji: '\u{1F4CB}' }, - { name: 'active', emoji: '\u{1F6A7}' }, - { name: 'completed', emoji: '\u2705' }, - { name: 'deferred', emoji: '\u23F8\uFE0F' }, - ], - phases: [ - { name: 'Inception', order: 1 }, - { name: 'Elaboration', order: 2 }, - { name: 'Session', order: 3 }, - { name: 'Construction', order: 4 }, - { name: 'Validation', order: 5 }, - { name: 'Retrospective', order: 6 }, - ], - defaultStatus: 'roadmap', -}; - -// DD-4: loadDefaultWorkflow() becomes synchronous and infallible. -// Implementation will call createLoadedWorkflow(DEFAULT_WORKFLOW_CONFIG) directly. -// The function signature changes from: -// export async function loadDefaultWorkflow(): Promise -// To: -// export function loadDefaultWorkflow(): LoadedWorkflow -// -// DD-3: Dead code to remove from workflow-loader.ts: -// - getCatalogueWorkflowsPath() — resolves to non-existent catalogue/workflows/ -// - loadWorkflowConfig(name) — loads by name from dead catalogue path -// - DEFAULT_WORKFLOW_NAME constant — only used by loadWorkflowConfig -// - fs, path, fileURLToPath, import.meta.url imports — only used by above diff --git a/architect/stubs/data-api-architecture-queries/arch-queries.ts b/architect/stubs/data-api-architecture-queries/arch-queries.ts deleted file mode 100644 index 257cd885..00000000 --- a/architect/stubs/data-api-architecture-queries/arch-queries.ts +++ /dev/null @@ -1,318 +0,0 @@ -/** - * @architect - * @architect-status roadmap - * @architect-implements DataAPIArchitectureQueries - * @architect-uses PatternGraphAPI, PatternGraph, Pattern Scanner - * @architect-used-by PatternGraphCLIImpl - * @architect-target src/api/arch-queries.ts - * @architect-since DS-D - * - * ## ArchQueries — Neighborhood, Comparison, Tags, Sources, and CLI Context - * - * Extends the existing `arch` subcommand with deeper analysis and adds - * new top-level discovery commands (tags, sources). Also defines the - * SubcommandContext type used by all new CLI handlers (ADR-008). - * - * ### Design Decisions - * - * - DS-D-2: Neighborhood is fixed 1-hop (spec says "1-hop relationships") - * - DS-D-3: Source categorization uses path heuristics (no re-scan) - * - DS-D-4: Tag aggregation is single-pass over patterns - * - * ### CLI Integration - * - * New cases in handleArch(): neighborhood, compare, coverage - * New top-level subcommands: tags, sources, unannotated - * All use SubcommandContext for access to CLI config and registry. - * - * Note: SubcommandContext should be defined in src/cli/types.ts (cross-cutting CLI type). - * NeighborEntry should be unified in src/api/types.ts (shared with ContextAssembler). - * See: DataAPIArchitectureQueries spec, Rules 1-3 - * - * **When to Use:** When exploring architecture structure (neighborhoods, comparisons, tags, sources) via the Data API CLI. - */ - -// --------------------------------------------------------------------------- -// SubcommandContext (Cross-cutting, ADR-008) -// --------------------------------------------------------------------------- - -/** - * Broader context for subcommand handlers replacing the narrow - * routeSubcommand(api, cmd, args) signature. - * - * Needed because coverage and unannotated commands require: - * - CLI config (input globs, baseDir) for file discovery - * - TagRegistry for opt-in detection and taxonomy queries - * - * See ADR-008 for rationale. - */ -export interface SubcommandContext { - /** PatternGraphAPI instance for pattern queries. */ - readonly api: unknown; - /** CLI config with input globs, features, baseDir. */ - readonly cliConfig: { - readonly input: readonly string[]; - readonly features: readonly string[]; - readonly baseDir: string; - }; - /** TagRegistry for taxonomy queries and opt-in detection. */ - readonly registry: unknown; -} - -// --------------------------------------------------------------------------- -// Neighborhood Types (DS-D-2: fixed 1-hop) -// --------------------------------------------------------------------------- - -/** - * Entry for a neighboring pattern with context, role, and file metadata. - * - * IMPLEMENTATION NOTE: Unify with ContextAssembler's NeighborEntry into a single - * shared type in src/api/types.ts. Both modules should import from there. - * Fields: name, status, archRole, archContext, file. - */ -export interface NeighborEntry { - readonly name: string; - readonly archContext: string | undefined; - readonly archRole: string | undefined; - readonly status: string | undefined; - readonly file: string | undefined; -} - -/** - * 1-hop neighborhood result for a focal pattern. - * - * Resolves: uses, usedBy, same-context siblings, implements/implementedBy. - * All from pre-computed PatternGraph views (no additional scanning). - */ -export interface NeighborhoodResult { - /** Focal pattern name. */ - readonly pattern: string; - /** Bounded context of the focal pattern. */ - readonly context: string | undefined; - /** Architecture role. */ - readonly role: string | undefined; - /** Architecture layer. */ - readonly layer: string | undefined; - /** Patterns this directly uses (from relationshipIndex.uses). */ - readonly uses: readonly NeighborEntry[]; - /** Patterns that directly use this (from relationshipIndex.usedBy). */ - readonly usedBy: readonly NeighborEntry[]; - /** Patterns in the same bounded context (excluding self). */ - readonly sameContext: readonly NeighborEntry[]; - /** Patterns this implements (realization relationship). */ - readonly implements: readonly string[]; - /** Patterns that implement this (implemented-by relationship). */ - readonly implementedBy: readonly string[]; -} - -// --------------------------------------------------------------------------- -// Context Comparison Types -// --------------------------------------------------------------------------- - -/** - * Summary of a bounded context for comparison. - */ -export interface ContextSummary { - readonly name: string; - readonly patternCount: number; - readonly patterns: readonly string[]; - /** All external dependencies (uses + dependsOn) aggregated across patterns. */ - readonly allDependencies: readonly string[]; -} - -/** - * Integration point between two bounded contexts. - * A relationship where one endpoint is in ctx1 and the other in ctx2. - */ -export interface IntegrationPoint { - readonly from: string; - readonly fromContext: string; - readonly to: string; - readonly toContext: string; - /** Relationship type. */ - readonly relationship: 'uses' | 'usedBy' | 'dependsOn' | 'enables'; -} - -/** - * Comparison result for two bounded contexts. - * - * Shows shared deps, unique deps, and direct integration points. - * Dependencies are the union of uses + dependsOn for all patterns in a context. - */ -export interface ContextComparison { - readonly context1: ContextSummary; - readonly context2: ContextSummary; - /** Dependencies shared by both contexts. */ - readonly sharedDependencies: readonly string[]; - /** Dependencies only in context1. */ - readonly uniqueToContext1: readonly string[]; - /** Dependencies only in context2. */ - readonly uniqueToContext2: readonly string[]; - /** Direct relationships crossing the context boundary. */ - readonly integrationPoints: readonly IntegrationPoint[]; -} - -// --------------------------------------------------------------------------- -// Tag Usage Types (DS-D-4: single-pass aggregation) -// --------------------------------------------------------------------------- - -/** - * Count of a specific tag value. - */ -export interface TagValueCount { - readonly value: string; - readonly count: number; -} - -/** - * Usage statistics for a single tag. - */ -export interface TagUsageEntry { - /** Tag name (e.g., "status", "arch-role", "category"). */ - readonly tag: string; - /** Number of patterns with this tag set. */ - readonly count: number; - /** For enum-valued tags: distribution of values. Null for non-enum tags. */ - readonly values: readonly TagValueCount[] | null; -} - -/** - * Aggregate tag usage across all patterns. - * - * Output for `tags` subcommand: - * status: 69 patterns — completed(36), roadmap(30), active(3) - * category: 41 patterns — projection(6), saga(4), handler(5) - */ -export interface TagUsageReport { - /** Tags sorted by usage count descending. */ - readonly tags: readonly TagUsageEntry[]; - /** Total patterns analyzed. */ - readonly patternCount: number; -} - -// --------------------------------------------------------------------------- -// Source Inventory Types (DS-D-3: path heuristics) -// --------------------------------------------------------------------------- - -/** - * A source type with file count and paths. - */ -export interface SourceTypeEntry { - /** Human-readable type name (e.g., "TypeScript (annotated)"). */ - readonly type: string; - /** Number of files of this type. */ - readonly count: number; - /** Representative glob pattern (e.g., "src/**\/*.ts"). */ - readonly locationPattern: string; - /** Actual file paths. */ - readonly files: readonly string[]; -} - -/** - * File inventory grouped by source type. - * - * Source types detected by path heuristics: - * - TypeScript (annotated): .ts AND NOT /stubs/ - * - Gherkin (features): .feature AND NOT /decisions/ - * - Stubs: path contains /stubs/ - * - Decisions: .feature AND (path contains /decisions/ OR pattern has adr field) - * - * Output for `sources` subcommand: - * TypeScript (annotated): 47 files — src/**\/*.ts - * Gherkin (features): 37 files — specs/**\/*.feature - * Stubs: 22 files — stubs/**\/*.ts - * Decisions: 13 files — decisions/**\/*.feature - */ -export interface SourceInventory { - /** Source types with file counts and paths. */ - readonly types: readonly SourceTypeEntry[]; - /** Total files across all types. */ - readonly totalFiles: number; -} - -// --------------------------------------------------------------------------- -// Functions -// --------------------------------------------------------------------------- - -/** - * Compute 1-hop neighborhood for a pattern. - * - * Algorithm: - * 1. Look up pattern by name (case-insensitive) - * 2. Read uses/usedBy from relationshipIndex[name] - * 3. Read archContext, filter archIndex.byContext[ctx] for siblings (excl self) - * 4. Read implements/implementedBy from relationshipIndex - * 5. Resolve NeighborEntry metadata for each neighbor - * - * @param name - Pattern name to get neighborhood for - * @param dataset - PatternGraph with archIndex and relationshipIndex - * @returns Neighborhood result, or undefined if pattern not found - */ -export function computeNeighborhood( - _name: string, - _dataset: unknown -): NeighborhoodResult | undefined { - throw new Error('DataAPIArchitectureQueries not yet implemented - roadmap pattern'); -} - -/** - * Compare two bounded contexts for shared dependencies and integration points. - * - * Algorithm: - * 1. Get patterns for each context from archIndex.byContext - * 2. For each context, aggregate external deps (uses + dependsOn) via relationshipIndex - * 3. Compute set intersection (shared) and differences (unique) - * 4. Find integration points: relationships where one end is in ctx1, other in ctx2 - * - * @param ctx1 - First context name - * @param ctx2 - Second context name - * @param dataset - PatternGraph with archIndex and relationshipIndex - * @returns Comparison result, or undefined if either context not found - */ -export function compareContexts( - _ctx1: string, - _ctx2: string, - _dataset: unknown -): ContextComparison | undefined { - throw new Error('DataAPIArchitectureQueries not yet implemented - roadmap pattern'); -} - -/** - * Aggregate tag usage across all patterns in a single pass. - * - * Algorithm: - * 1. Iterate dataset.patterns once - * 2. For each pattern, check which optional fields are set - * 3. Increment counters per tag - * 4. For enum fields (status, archRole, archLayer), track value distribution - * 5. Cross-reference with tagRegistry.metadataTags for tag names - * 6. Sort by count descending - * - * @param dataset - PatternGraph with patterns and tagRegistry - * @returns Tag usage report sorted by count - */ -export function aggregateTagUsage( - _dataset: unknown -): TagUsageReport { - throw new Error('DataAPIArchitectureQueries not yet implemented - roadmap pattern'); -} - -/** - * Build source inventory from pattern source metadata. - * - * Categorizes files by path heuristics (DS-D-3): - * - /stubs/ in path → Stubs - * - /decisions/ in path or adr field set → Decisions - * - .feature extension → Gherkin - * - .ts extension → TypeScript - * - * No re-scan needed — all data from PatternGraph.patterns[].source.file. - * - * @param dataset - PatternGraph with patterns - * @returns Source inventory grouped by type - */ -export function buildSourceInventory( - _dataset: unknown -): SourceInventory { - throw new Error('DataAPIArchitectureQueries not yet implemented - roadmap pattern'); -} diff --git a/architect/stubs/data-api-architecture-queries/coverage-analyzer.ts b/architect/stubs/data-api-architecture-queries/coverage-analyzer.ts deleted file mode 100644 index 415f3e8d..00000000 --- a/architect/stubs/data-api-architecture-queries/coverage-analyzer.ts +++ /dev/null @@ -1,151 +0,0 @@ -/** - * @architect - * @architect-status roadmap - * @architect-implements DataAPIArchitectureQueries - * @architect-uses Pattern Scanner, PatternGraph - * @architect-used-by PatternGraphCLIImpl - * @architect-target src/api/coverage-analyzer.ts - * @architect-since DS-D - * - * ## CoverageAnalyzer — Annotation Coverage and Taxonomy Gap Detection - * - * Reports annotation completeness by comparing scannable files (from glob) - * against annotated patterns in PatternGraph. Also detects unused taxonomy - * values defined in TagRegistry but never applied. - * - * ### Coverage Data Access Strategy (DS-D-1) - * - * Uses independent glob via findFilesToScan() from src/scanner/pattern-scanner.ts. - * Re-running a glob is cheap (~1ms) and avoids changing buildPipeline() to - * thread scan results. The coverage analyzer receives CLI config (input globs, - * baseDir) and TagRegistry via SubcommandContext. - * - * findUnannotatedFiles() also reads file content to check hasFileOptIn() — - * this is a fast regex check, not AST parsing. - * - * ### What Counts as "Scannable" - * - * - TypeScript files matching input globs (e.g., src/**\/*.ts) - * - Excluding: node_modules, dist, test files, declaration files - * - Same exclusion rules as the scanner: findFilesToScan() defaults - * - * See: DataAPIArchitectureQueries spec, Rule 2 (Architecture Coverage) - * - * **When to Use:** When checking annotation completeness or finding unannotated files via `arch coverage` or `unannotated` CLI subcommands. - */ - -// --------------------------------------------------------------------------- -// Types -// --------------------------------------------------------------------------- - -/** - * Report on unused taxonomy values. - * - * Compares tagRegistry definitions against actual usage in patterns. - * "Unused" means defined in the registry but not applied to any pattern. - */ -export interface UnusedTaxonomyReport { - /** Category names defined in registry but not used by any pattern. */ - readonly unusedCategories: readonly string[]; - /** Architecture role values defined but not applied. */ - readonly unusedRoles: readonly string[]; - /** Architecture layer values defined but not applied. */ - readonly unusedLayers: readonly string[]; - /** Status values defined but not applied. */ - readonly unusedStatuses: readonly string[]; -} - -/** - * Full coverage report combining file coverage and taxonomy gaps. - * - * Output for `arch coverage` subcommand: - * 41/50 files annotated (82%) - * 9 unannotated files: [list] - * Unused taxonomy: [categories, roles, layers] - */ -export interface CoverageReport { - /** Count of files with @architect opt-in that produced patterns. */ - readonly annotatedFileCount: number; - /** Total .ts files found by glob (before opt-in filter). */ - readonly totalScannableFiles: number; - /** annotatedFileCount / totalScannableFiles * 100. */ - readonly coveragePercentage: number; - /** Files matching input globs but lacking @architect marker. */ - readonly unannotatedFiles: readonly string[]; - /** Taxonomy values defined but never used. */ - readonly unusedTaxonomy: UnusedTaxonomyReport; -} - -// --------------------------------------------------------------------------- -// Functions -// --------------------------------------------------------------------------- - -/** - * Analyze annotation coverage by comparing glob results against extracted patterns. - * - * Algorithm: - * 1. Call findFilesToScan() with input globs to get all scannable files - * 2. Collect unique source files from dataset.patterns - * 3. Compute difference: scannable - annotated = unannotated - * 4. Compute unused taxonomy values - * 5. Return CoverageReport - * - * Async because findFilesToScan() uses glob (filesystem I/O). - * - * @param dataset - PatternGraph with extracted patterns - * @param inputGlobs - CLI --input glob patterns - * @param baseDir - Base directory for file discovery - * @param registry - TagRegistry for unused taxonomy detection - * @returns Coverage report with annotated/total counts and gaps - */ -export async function analyzeCoverage( - _dataset: unknown, - _inputGlobs: readonly string[], - _baseDir: string, - _registry: unknown -): Promise { - throw new Error('DataAPIArchitectureQueries not yet implemented - roadmap pattern'); -} - -/** - * Find unannotated files matching an optional path filter. - * - * Calls findFilesToScan() for file discovery, then reads each file - * to check hasFileOptIn() (fast regex, no AST parsing). - * - * @param inputGlobs - Glob patterns for file discovery - * @param baseDir - Base directory for scanning - * @param registry - TagRegistry for opt-in detection - * @param pathFilter - Optional additional glob to narrow results (e.g., 'src/generators/**\/*.ts') - * @returns Relative paths of files without @architect marker - */ -export async function findUnannotatedFiles( - _inputGlobs: readonly string[], - _baseDir: string, - _registry: unknown, - _pathFilter?: string -): Promise { - throw new Error('DataAPIArchitectureQueries not yet implemented - roadmap pattern'); -} - -/** - * Compute unused taxonomy values by comparing registry definitions - * against actual tag usage in patterns. - * - * Algorithm: - * 1. Collect all category names used: dataset.patterns.map(p => p.category) - * 2. Collect all arch roles used: dataset.patterns.map(p => p.archRole).filter(defined) - * 3. Collect all arch layers used: similarly - * 4. Collect all statuses used: similarly - * 5. Diff against registry definitions - * - * @param dataset - PatternGraph with patterns - * @param registry - TagRegistry with definitions - * @returns Report of unused taxonomy values - */ -export function findUnusedTaxonomy( - _dataset: unknown, - _registry: unknown -): UnusedTaxonomyReport { - throw new Error('DataAPIArchitectureQueries not yet implemented - roadmap pattern'); -} diff --git a/architect/stubs/data-api-context-assembly/context-assembler.ts b/architect/stubs/data-api-context-assembly/context-assembler.ts deleted file mode 100644 index fa2bce05..00000000 --- a/architect/stubs/data-api-context-assembly/context-assembler.ts +++ /dev/null @@ -1,383 +0,0 @@ -/** - * @architect - * @architect-status roadmap - * @architect-implements DataAPIContextAssembly - * @architect-uses PatternGraphAPI, PatternGraph, PatternSummarizer - * @architect-used-by PatternGraphCLIImpl, ContextFormatter - * @architect-target src/api/context-assembler.ts - * @architect-since DS-C - * - * ## ContextAssembler — Session-Oriented Context Bundle Builder - * - * Pure function composition over PatternGraph. Reads from 5 pre-computed - * views (patterns, relationshipIndex, archIndex, deliverables, FSM) and - * assembles them into a ContextBundle tailored to the session type. - * - * The assembler does NOT format output. It produces structured data that - * the ContextFormatter renders as plain text (see ADR-008). - * - * ### Assembly Algorithm - * - * 1. Resolve focal pattern(s) via getPattern() - * 2. For each pattern: resolve spec file, stubs, deps, consumers, arch neighbors - * 3. Merge multi-pattern results with dedup (union-then-tag for shared deps) - * 4. Populate/omit sections based on SessionType - * - * ### Session Type Inclusion Matrix - * - * | Section | planning | design | implement | - * |---------|----------|--------|-----------| - * | Metadata | yes | yes | yes | - * | Spec path | no | yes | yes | - * | Stubs | no | yes | no | - * | Dependencies | name+status | full | name+status | - * | Consumers | no | yes | no | - * | Architecture | no | yes | no | - * | Deliverables | no | no | yes | - * | FSM state | no | no | yes | - * | Test files | no | no | yes | - * - * See: DataAPIContextAssembly spec, Rules 1-5 - * - * **When to Use:** When building a session context bundle for a pattern — use this instead of manually querying PatternGraph views. - */ - -// --------------------------------------------------------------------------- -// Session Types -// --------------------------------------------------------------------------- - -/** - * Session type controls which sections are populated in the ContextBundle. - * - * - planning: minimal (~500B) — metadata + deps only - * - design: full (~1.5KB) — spec + stubs + deps + arch + consumers - * - implement: focused (~1KB) — spec + deliverables + FSM + tests - */ -export type SessionType = 'planning' | 'design' | 'implement'; - -// --------------------------------------------------------------------------- -// Context Options -// --------------------------------------------------------------------------- - -/** - * Options for assembling a context bundle. - */ -export interface ContextOptions { - /** Focal pattern name(s). Multiple patterns triggers merge with dedup. */ - readonly patterns: readonly string[]; - /** Session type controls what sections are populated. */ - readonly sessionType: SessionType; - /** Base directory for resolving relative file paths. */ - readonly baseDir: string; -} - -/** - * Options for building a dependency tree. - */ -export interface DepTreeOptions { - /** Focal pattern name. */ - readonly pattern: string; - /** Maximum depth to walk (default: 3). Override via --depth flag. */ - readonly maxDepth: number; - /** - * Whether to include implementation deps (uses/usedBy) in addition - * to planning deps (dependsOn/enables). Default: true. - */ - readonly includeImplementationDeps: boolean; -} - -// --------------------------------------------------------------------------- -// Context Bundle Types -// --------------------------------------------------------------------------- - -/** - * Compact metadata for a pattern in the context bundle. - * Lighter than PatternSummary — includes a text summary instead of source type. - */ -export interface PatternContextMeta { - readonly name: string; - readonly status: string | undefined; - readonly phase: number | undefined; - readonly category: string; - readonly file: string; - /** First sentence of the description, for quick orientation. */ - readonly summary: string; -} - -/** - * Reference to a design stub with its target implementation path. - */ -export interface StubRef { - /** Path to the stub file (e.g., stubs/data-api-output-shaping/summarize.ts). */ - readonly stubFile: string; - /** Target implementation path from stub header (e.g., src/api/summarize.ts). */ - readonly targetPath: string; - /** Implementing pattern name from the stub. */ - readonly name: string; -} - -/** - * Dependency entry with status and kind (planning vs implementation). - */ -export interface DepEntry { - readonly name: string; - readonly status: string | undefined; - readonly file: string; - /** 'planning' = dependsOn/enables, 'implementation' = uses/usedBy. */ - readonly kind: 'planning' | 'implementation'; -} - -/** - * Architecture neighbor entry with role, context, and file metadata. - * - * IMPLEMENTATION NOTE: Unify with ArchQueries' NeighborEntry into a single - * shared type in src/api/types.ts. Both modules should import from there. - * Fields: name, status, archRole, archContext, file. - */ -export interface NeighborEntry { - readonly name: string; - readonly status: string | undefined; - readonly archRole: string | undefined; - readonly archContext: string | undefined; - readonly file: string | undefined; -} - -/** - * Deliverable entry with completion status. - */ -export interface DeliverableEntry { - readonly name: string; - readonly status: string; - readonly location: string; -} - -/** - * FSM context for the focal pattern's current state. - */ -export interface FsmContext { - readonly currentStatus: string; - readonly validTransitions: readonly string[]; - readonly protectionLevel: 'none' | 'scope' | 'hard'; -} - -/** - * Assembled context bundle. Flat type with optional sections. - * - * Session tailoring populates/omits sections — no discriminated union needed. - * The formatter renders whatever sections are present. - * - * IMPLEMENTATION NOTE: Use builder functions (createPlanningBundle(), createDesignBundle(), - * createImplementBundle()) to enforce the inclusion matrix at construction time. - * This provides runtime guarantees without the type complexity of a discriminated union. - * - * Design: DS-C-1 (flat type, not discriminated union) - */ -export interface ContextBundle { - /** Focal pattern name(s). */ - readonly patterns: readonly string[]; - /** Session type that shaped this bundle. */ - readonly sessionType: SessionType; - - // --- Metadata (all session types) --- - /** Per-pattern metadata summaries. */ - readonly metadata: readonly PatternContextMeta[]; - - // --- Spec & Stubs (design, implement) --- - /** Spec file paths (from pattern.source.file for .feature sources). */ - readonly specFiles: readonly string[]; - /** Stub file paths with target locations (from implementedBy). */ - readonly stubs: readonly StubRef[]; - - // --- Dependencies (all session types) --- - /** Direct dependencies with status. */ - readonly dependencies: readonly DepEntry[]; - /** Shared dependencies across multiple focal patterns (multi-pattern only). */ - readonly sharedDependencies: readonly string[]; - - // --- Consumers (design only) --- - /** Patterns that consume/use the focal pattern(s). */ - readonly consumers: readonly DepEntry[]; - - // --- Architecture (design only) --- - /** Same-context neighbor patterns. */ - readonly architectureNeighbors: readonly NeighborEntry[]; - - // --- Deliverables (implement only) --- - /** Deliverables checklist with status. */ - readonly deliverables: readonly DeliverableEntry[]; - - // --- FSM (implement only) --- - /** Current FSM state and valid transitions. */ - readonly fsm: FsmContext | undefined; - - // --- Test locations (implement only) --- - /** Paths to test/spec files. */ - readonly testFiles: readonly string[]; -} - -// --------------------------------------------------------------------------- -// Dependency Tree Types -// --------------------------------------------------------------------------- - -/** - * Node in a recursive dependency tree. - * - * Built via BFS with visited-set cycle detection (DS-C-2). - * maxDepth limits walk depth. Truncated branches are marked. - */ -export interface DepTreeNode { - readonly name: string; - readonly status: string | undefined; - readonly phase: number | undefined; - /** Whether this is the focal pattern (marked with <- YOU ARE HERE). */ - readonly isFocal: boolean; - /** Whether this branch was truncated due to depth limit. */ - readonly truncated: boolean; - readonly children: readonly DepTreeNode[]; -} - -// --------------------------------------------------------------------------- -// File Reading List Types -// --------------------------------------------------------------------------- - -/** - * File paths organized by relevance for a focal pattern. - * - * More token-efficient than context — just paths that Claude Code can read. - */ -export interface FileReadingList { - readonly pattern: string; - /** Spec file + stub files. */ - readonly primary: readonly string[]; - /** Implementation files of completed dependencies. */ - readonly completedDeps: readonly string[]; - /** Spec files of incomplete dependencies. */ - readonly roadmapDeps: readonly string[]; - /** Same-context pattern files. */ - readonly architectureNeighbors: readonly string[]; -} - -// --------------------------------------------------------------------------- -// Overview Types -// --------------------------------------------------------------------------- - -/** - * Progress counts and percentage. - */ -export interface ProgressSummary { - readonly total: number; - readonly completed: number; - readonly active: number; - readonly planned: number; - readonly percentage: number; -} - -/** - * Active phase summary with pattern counts. - */ -export interface ActivePhaseSummary { - readonly phase: number; - readonly name: string | undefined; - readonly patternCount: number; - readonly activeCount: number; -} - -/** - * A pattern blocked by incomplete dependencies. - */ -export interface BlockingEntry { - /** Pattern that is blocked. */ - readonly pattern: string; - readonly status: string | undefined; - /** Dependency names that are not yet completed. */ - readonly blockedBy: readonly string[]; -} - -/** - * Executive project overview. - * - * Answers "where are we?" in one command. Includes progress, - * active phases, and blocking relationships. - */ -export interface OverviewSummary { - readonly progress: ProgressSummary; - readonly activePhases: readonly ActivePhaseSummary[]; - readonly blocking: readonly BlockingEntry[]; -} - -// --------------------------------------------------------------------------- -// Assembler Functions -// --------------------------------------------------------------------------- - -/** - * Assemble a curated context bundle for one or more focal patterns. - * - * Pure function: takes PatternGraph + options, returns ContextBundle. - * - * Algorithm: - * 1. Resolve each focal pattern via dataset.patterns lookup - * 2. For each pattern: resolve spec, stubs (implementedBy), deps, consumers, arch - * 3. For multi-pattern: union deps, tag shared (appearing in 2+ sets) - * 4. Populate/omit sections based on sessionType - * - * @param dataset - PatternGraph with patterns, relationshipIndex, archIndex - * @param options - Context assembly options - * @returns Assembled context bundle - */ -export function assembleContext( - _dataset: unknown, - _options: ContextOptions -): ContextBundle { - throw new Error('DataAPIContextAssembly not yet implemented - roadmap pattern'); -} - -/** - * Build a recursive dependency tree for a focal pattern. - * - * Uses iterative BFS with visited-set cycle detection (DS-C-2). - * Walks dependsOn/enables (planning) and optionally uses/usedBy (implementation). - * - * @param dataset - PatternGraph with patterns and relationshipIndex - * @param options - Dep-tree options (pattern, maxDepth, includeImplementationDeps) - * @returns Root node of the dependency tree - */ -export function buildDepTree( - _dataset: unknown, - _options: DepTreeOptions -): DepTreeNode { - throw new Error('DataAPIContextAssembly not yet implemented - roadmap pattern'); -} - -/** - * Generate a file reading list organized by relevance. - * - * Returns file paths grouped by: primary (spec + stubs), completed deps, - * roadmap deps, architecture neighbors. - * - * @param dataset - PatternGraph with patterns and relationshipIndex - * @param pattern - Focal pattern name - * @param includeRelated - Whether to include deps and neighbors (default: false) - * @returns File reading list with paths organized by relevance - */ -export function buildFileReadingList( - _dataset: unknown, - _pattern: string, - _includeRelated: boolean -): FileReadingList { - throw new Error('DataAPIContextAssembly not yet implemented - roadmap pattern'); -} - -/** - * Compute executive project overview summary. - * - * Aggregates: progress counts, active phases, blocking relationships. - * A pattern is "blocked" if any of its dependsOn targets has status !== completed. - * - * @param dataset - PatternGraph with patterns, byStatus, byPhase, relationshipIndex - * @returns Project overview summary - */ -export function buildOverview( - _dataset: unknown -): OverviewSummary { - throw new Error('DataAPIContextAssembly not yet implemented - roadmap pattern'); -} diff --git a/architect/stubs/data-api-context-assembly/context-formatter.ts b/architect/stubs/data-api-context-assembly/context-formatter.ts deleted file mode 100644 index e50d6cd2..00000000 --- a/architect/stubs/data-api-context-assembly/context-formatter.ts +++ /dev/null @@ -1,159 +0,0 @@ -/** - * @architect - * @architect-status roadmap - * @architect-implements DataAPIContextAssembly - * @architect-uses ContextAssembler - * @architect-used-by PatternGraphCLIImpl - * @architect-target src/api/context-formatter.ts - * @architect-since DS-C - * - * ## ContextFormatter — Plain Text Renderer for Context Bundles - * - * First plain-text formatter in the codebase. All other rendering goes - * through the Codec/RenderableDocument/UniversalRenderer markdown pipeline. - * Context bundles are rendered as compact structured text with === section - * markers for easy AI parsing (see ADR-008). - * - * ### Output Format (DS-C-4) - * - * Section markers: `=== SECTION ===` (visually distinct, regex-parseable, - * no collision with markdown # or YAML ---) - * - * Status in brackets: `[completed]`, `[roadmap]`, `[active]` - * Deliverable checkboxes: `[x]` (done), `[ ]` (pending) - * Dep-tree arrows: `->` (compact, no Unicode box-drawing) - * Focal marker: `<- YOU ARE HERE` - * - * ### Reusable Helpers - * - * May reuse from src/renderable/codecs/helpers.ts: - * - extractFirstSentence() for metadata summary - * - truncateText() for long descriptions - * - * See: DataAPIContextAssembly spec, ADR-008 (text output path) - * - * **When to Use:** When rendering a ContextBundle as plain text for CLI output — use this instead of the markdown codec pipeline. - */ - -import type { - ContextBundle, - DepTreeNode, - FileReadingList, - OverviewSummary, -} from './context-assembler.js'; - -// --------------------------------------------------------------------------- -// Bundle Formatter -// --------------------------------------------------------------------------- - -/** - * Format a ContextBundle as compact plain text for AI consumption. - * - * Renders whatever sections are populated. Session tailoring is already - * done by the assembler — the formatter just renders what's there. - * - * Output format example (design session): - * - * === PATTERN: AgentLLMIntegration === - * Status: roadmap | Phase: 22b | Category: agent - * Spec: architect/specs/agent-llm-integration.feature - * - * === STUBS === - * stubs/agent-llm/adapter.ts -> src/agent/adapter.ts - * - * === DEPENDENCIES === - * [completed] AgentBCIsolation (22a) architect/specs/... - * [roadmap] AgentAsBoundedContext (22) - * - * === CONSUMERS === - * AgentCommandInfra (22c, roadmap) - * - * === ARCHITECTURE (context: agent) === - * AgentBCIsolation (completed, bounded-context) - * - * @param bundle - Assembled context bundle from assembleContext() - * @returns Formatted plain text string - */ -export function formatContextBundle(_bundle: ContextBundle): string { - throw new Error('DataAPIContextAssembly not yet implemented - roadmap pattern'); -} - -// --------------------------------------------------------------------------- -// Dep-Tree Formatter -// --------------------------------------------------------------------------- - -/** - * Format a dependency tree as indented text with status markers. - * - * Output format: - * - * AgentAsBoundedContext (22, completed) - * -> AgentBCIsolation (22a, completed) - * -> AgentLLMIntegration (22b, roadmap) - * -> [*] AgentCommandInfra (22c, roadmap) <- YOU ARE HERE - * -> AgentChurnRisk (22d, roadmap) - * - * Truncated branches show: `-> ... (depth limit reached)` - * - * @param tree - Root node from buildDepTree() - * @returns Formatted tree as indented text - */ -export function formatDepTree(_tree: DepTreeNode): string { - throw new Error('DataAPIContextAssembly not yet implemented - roadmap pattern'); -} - -// --------------------------------------------------------------------------- -// File Reading List Formatter -// --------------------------------------------------------------------------- - -/** - * Format a file reading list as plain text with section headers. - * - * Output format: - * - * === PRIMARY === - * architect/specs/order-saga.feature - * architect/stubs/order-saga/saga.ts - * - * === COMPLETED DEPENDENCIES === - * src/events/event-store.ts - * - * === ROADMAP DEPENDENCIES === - * architect/specs/saga-engine.feature - * - * === ARCHITECTURE NEIGHBORS === - * src/orders/command-handler.ts - * - * @param list - File reading list from buildFileReadingList() - * @returns Formatted file list as plain text - */ -export function formatFileReadingList(_list: FileReadingList): string { - throw new Error('DataAPIContextAssembly not yet implemented - roadmap pattern'); -} - -// --------------------------------------------------------------------------- -// Overview Formatter -// --------------------------------------------------------------------------- - -/** - * Format an overview summary as plain text. - * - * Output format: - * - * === PROGRESS === - * 69 patterns (36 completed, 3 active, 30 planned) = 52% - * - * === ACTIVE PHASES === - * Phase 14: Validation (2 active) - * Phase 25: Data API (1 active) - * - * === BLOCKING === - * AgentCommandInfra blocked by: AgentLLMIntegration (roadmap) - * DataAPIDesignSessionSupport blocked by: DataAPIContextAssembly (roadmap) - * - * @param overview - Overview summary from buildOverview() - * @returns Formatted overview as plain text - */ -export function formatOverview(_overview: OverviewSummary): string { - throw new Error('DataAPIContextAssembly not yet implemented - roadmap pattern'); -} diff --git a/architect/stubs/data-api-output-shaping/fuzzy-match.ts b/architect/stubs/data-api-output-shaping/fuzzy-match.ts deleted file mode 100644 index d67ce2d7..00000000 --- a/architect/stubs/data-api-output-shaping/fuzzy-match.ts +++ /dev/null @@ -1,98 +0,0 @@ -/** - * @architect - * @architect-status roadmap - * @architect-implements DataAPIOutputShaping - * @architect-used-by PatternGraphCLIImpl - * @architect-target src/api/fuzzy-match.ts - * @architect-since DS-A - * - * ## FuzzyMatcher — Pattern Name Fuzzy Search - * - * Provides fuzzy matching for pattern names with tiered scoring: - * exact (1.0) > prefix (0.9) > substring (0.7) > Levenshtein (distance-based). - * - * No external dependencies — Levenshtein implementation is ~20 lines. - * - * Used by: - * - `search` subcommand: ranked results via fuzzyMatchPatterns() - * - `pattern` subcommand: "Did you mean...?" fallback via findBestMatch() - * - * See: DataAPIOutputShaping spec, Rule 4 (Filtering and Search) - * - * **When to Use:** When resolving user-typed pattern names that may contain typos or partial matches. - */ - -// --------------------------------------------------------------------------- -// Types -// --------------------------------------------------------------------------- - -/** - * Result of a fuzzy match against a pattern name. - */ -export interface FuzzyMatch { - /** The matched pattern name */ - readonly patternName: string; - /** Match quality score (0-1, higher is better) */ - readonly score: number; - /** How the match was achieved */ - readonly matchType: 'exact' | 'prefix' | 'substring' | 'fuzzy'; -} - -// --------------------------------------------------------------------------- -// Functions -// --------------------------------------------------------------------------- - -/** - * Find patterns matching a query with fuzzy matching. - * - * Scoring tiers (all case-insensitive): - * 1. Exact match: score = 1.0 - * 2. Prefix match: score = 0.9 - * 3. Substring match: score = 0.7 - * 4. Levenshtein distance <= 3: score = 1 - (distance / max(len1, len2)) - * - * Results are sorted by score descending, limited to maxResults. - * - * @param query - Search query string - * @param patternNames - All available pattern names to search - * @param maxResults - Maximum number of results to return (default: 10) - * @returns Sorted array of FuzzyMatch results - */ -export function fuzzyMatchPatterns( - _query: string, - _patternNames: readonly string[], - _maxResults?: number -): readonly FuzzyMatch[] { - throw new Error('DataAPIOutputShaping not yet implemented - roadmap pattern'); -} - -/** - * Find the single best match for a query. - * - * Used for "Did you mean...?" suggestions when an exact pattern lookup fails. - * Returns undefined if no match scores above the minimum threshold (0.3). - * - * @param query - Pattern name that wasn't found - * @param patternNames - All available pattern names - * @returns Best matching FuzzyMatch, or undefined if no good match - */ -export function findBestMatch( - _query: string, - _patternNames: readonly string[] -): FuzzyMatch | undefined { - throw new Error('DataAPIOutputShaping not yet implemented - roadmap pattern'); -} - -/** - * Compute Levenshtein edit distance between two strings. - * - * Pure implementation with no external dependencies. - * Uses dynamic programming O(m*n) approach. - * - * @param a - First string - * @param b - Second string - * @returns Edit distance (0 = identical) - */ -export function levenshteinDistance(_a: string, _b: string): number { - throw new Error('DataAPIOutputShaping not yet implemented - roadmap pattern'); -} diff --git a/architect/stubs/data-api-output-shaping/output-pipeline.ts b/architect/stubs/data-api-output-shaping/output-pipeline.ts deleted file mode 100644 index f2407964..00000000 --- a/architect/stubs/data-api-output-shaping/output-pipeline.ts +++ /dev/null @@ -1,190 +0,0 @@ -/** - * @architect - * @architect-status roadmap - * @architect-implements DataAPIOutputShaping - * @architect-uses PatternSummarizer - * @architect-used-by PatternGraphCLIImpl - * @architect-target src/cli/output-pipeline.ts - * @architect-since DS-A - * - * ## OutputPipeline — CLI Output Shaping and Formatting - * - * Post-processing pipeline that transforms raw API results into shaped CLI output. - * Applies output modifiers (--names-only, --count, --fields, --full) and wraps - * results in QueryResult envelopes. - * - * Architecture decision: This is a single post-processing function, NOT a - * middleware chain. The 4 modifiers are mutually exclusive with clear precedence: - * count > namesOnly > fields > default summarize. - * - * The pipeline discriminates pattern arrays from scalars using a PipelineInput - * discriminated union — the router knows which methods return ExtractedPattern[] - * via a static PATTERN_ARRAY_METHODS set. - * - * See: DataAPIOutputShaping spec, Rule 2 (Output Modifiers), Rule 3 (Output Format) - * - * **When to Use:** When processing CLI query results that need output shaping via --names-only, --count, --fields, or --full modifiers. - */ - -// --------------------------------------------------------------------------- -// Types -// --------------------------------------------------------------------------- - -/** - * Output modifier flags parsed from CLI arguments. - * - * Precedence: count > namesOnly > fields > default summarize. - * When --full is set, summarization is bypassed. - */ -export interface OutputModifiers { - /** --names-only: return array of pattern name strings */ - readonly namesOnly: boolean; - /** --count: return single integer count */ - readonly count: boolean; - /** --fields name,status: return only selected fields per pattern */ - readonly fields: readonly string[] | null; - /** --full: bypass summarization, return raw ExtractedPattern[] */ - readonly full: boolean; -} - -export const DEFAULT_OUTPUT_MODIFIERS: OutputModifiers = { - namesOnly: false, - count: false, - fields: null, - full: false, -}; - -/** - * Composable list filters for the `list` subcommand. - * - * Filters combine via AND logic. Each filter narrows the result set. - * The pipeline uses Set-based intersection on pre-computed PatternGraph views. - */ -export interface ListFilters { - /** Filter by FSM status (roadmap, active, completed, deferred) */ - readonly status: string | null; - /** Filter by roadmap phase number */ - readonly phase: number | null; - /** Filter by category name */ - readonly category: string | null; - /** Filter by source type */ - readonly source: 'typescript' | 'gherkin' | null; - /** Maximum number of results */ - readonly limit: number | null; - /** Number of results to skip */ - readonly offset: number | null; -} - -export const DEFAULT_LIST_FILTERS: ListFilters = { - status: null, - phase: null, - category: null, - source: null, - limit: null, - offset: null, -}; - -/** - * Discriminated union for pipeline input. - * - * The router determines `kind` based on which API method was called. - * Pattern arrays get summarization + modifiers; scalars pass through. - */ -export type PipelineInput = - | { readonly kind: 'patterns'; readonly data: readonly unknown[] } - | { readonly kind: 'scalar'; readonly data: unknown }; - -/** - * Set of PatternGraphAPI method names that return ExtractedPattern[]. - * - * Used by the router to tag results with `kind: 'patterns'` for the pipeline. - */ -export const PATTERN_ARRAY_METHODS = new Set([ - 'getPatternsByNormalizedStatus', - 'getPatternsByStatus', - 'getPatternsByPhase', - 'getPatternsByCategory', - 'getPatternsByQuarter', - 'getCurrentWork', - 'getRoadmapItems', - 'getRecentlyCompleted', -]); - -// --------------------------------------------------------------------------- -// Functions -// --------------------------------------------------------------------------- - -/** - * Apply output modifiers to pipeline input. - * - * For pattern arrays: - * - Default: summarize each pattern to ~100 bytes - * - --full: bypass summarization - * - --names-only: extract pattern names as string[] - * - --count: return array length as number - * - --fields: pick specific fields from each summary - * - * For scalars: pass through unchanged (modifiers do not apply). - * - * @param input - Discriminated pipeline input (patterns or scalar) - * @param modifiers - Output modifier flags from CLI args - * @returns Shaped output ready for JSON serialization - */ -export function applyOutputPipeline( - _input: PipelineInput, - _modifiers: OutputModifiers -): unknown { - throw new Error('DataAPIOutputShaping not yet implemented - roadmap pattern'); -} - -/** - * Apply composable filters to the pattern list using PatternGraph views. - * - * Uses Set-based intersection for O(n) composition across pre-computed views. - * Pagination (offset/limit) applies after all filters. - * - * @param dataset - PatternGraph with pre-computed views - * @param filters - Composable list filters - * @returns Filtered array of ExtractedPatterns - */ -export function applyListFilters( - _dataset: unknown, - _filters: ListFilters -): readonly unknown[] { - throw new Error('DataAPIOutputShaping not yet implemented - roadmap pattern'); -} - -/** - * Strip null, undefined, and empty values from an object for compact output. - * - * Recursively removes: - * - null and undefined values - * - empty strings - * - empty arrays - * - empty objects - * - * Used by formatOutput() when compact mode is active. - * - * @param obj - Object to strip - * @returns Object with empty values removed - */ -export function stripEmpty(_obj: unknown): unknown { - throw new Error('DataAPIOutputShaping not yet implemented - roadmap pattern'); -} - -/** - * Format a QueryResult envelope for CLI output. - * - * - json mode: pretty-printed with 2-space indent - * - compact mode: minified with empty values stripped - * - * @param envelope - QueryResult envelope - * @param format - Output format ('json' or 'compact') - * @returns Formatted JSON string - */ -export function formatOutput( - _envelope: unknown, - _format: 'json' | 'compact' -): string { - throw new Error('DataAPIOutputShaping not yet implemented - roadmap pattern'); -} diff --git a/architect/stubs/data-api-output-shaping/summarize.ts b/architect/stubs/data-api-output-shaping/summarize.ts deleted file mode 100644 index 584a769f..00000000 --- a/architect/stubs/data-api-output-shaping/summarize.ts +++ /dev/null @@ -1,80 +0,0 @@ -/** - * @architect - * @architect-status roadmap - * @architect-implements DataAPIOutputShaping - * @architect-uses PatternGraphAPI - * @architect-used-by OutputPipeline, PatternGraphCLIImpl - * @architect-target src/api/summarize.ts - * @architect-since DS-A - * - * ## PatternSummarizer — Compact Pattern Projection - * - * Projects the full ExtractedPattern (~3.5KB per pattern) down to a - * PatternSummary (~100 bytes) for list queries. Reduces CLI output - * from ~594KB to ~4KB for typical codebases. - * - * Uses Zod schema-first pattern: PatternSummarySchema defines the type, - * and PatternSummary is inferred from it. - * - * See: DataAPIOutputShaping spec, Rule 1 (Pattern Summarization) - * - * **When to Use:** When projecting full ExtractedPattern data down to compact summaries for list and overview queries. - */ - -import { z } from 'zod'; - -// --------------------------------------------------------------------------- -// Schema -// --------------------------------------------------------------------------- - -/** - * Compact projection of ExtractedPattern for list queries. - * - * Fields selected for maximum information density at minimum size: - * - patternName: identifies the pattern - * - status: FSM state (roadmap/active/completed/deferred) - * - category: domain classification - * - phase: roadmap phase number (for sequencing) - * - file: source file path (for navigation) - * - source: typescript or gherkin (for filtering) - */ -export const PatternSummarySchema = z.object({ - patternName: z.string(), - status: z.enum(['roadmap', 'active', 'completed', 'deferred']).optional(), - category: z.string(), - phase: z.number().int().optional(), - file: z.string(), - source: z.enum(['typescript', 'gherkin']), -}); - -export type PatternSummary = z.infer; - -// --------------------------------------------------------------------------- -// Functions -// --------------------------------------------------------------------------- - -/** - * Project an ExtractedPattern to a compact PatternSummary. - * - * - `patternName` prefers explicit @architect-pattern tag, falls back to `name` - * - `source` is derived from file extension (`.feature` → gherkin, else typescript) - * - Optional fields (status, phase) are included when present, omitted when undefined - * - * @param pattern - Full ExtractedPattern from the pipeline - * @returns Compact PatternSummary (~100 bytes JSON) - */ -export function summarizePattern(_pattern: unknown): PatternSummary { - throw new Error('DataAPIOutputShaping not yet implemented - roadmap pattern'); -} - -/** - * Project an array of ExtractedPatterns to compact summaries. - * - * Convenience wrapper over summarizePattern() for list operations. - * - * @param patterns - Array of ExtractedPatterns - * @returns Array of PatternSummary objects - */ -export function summarizePatterns(_patterns: readonly unknown[]): readonly PatternSummary[] { - throw new Error('DataAPIOutputShaping not yet implemented - roadmap pattern'); -} diff --git a/architect/stubs/data-api-stub-integration/stub-resolver.ts b/architect/stubs/data-api-stub-integration/stub-resolver.ts deleted file mode 100644 index 5c335357..00000000 --- a/architect/stubs/data-api-stub-integration/stub-resolver.ts +++ /dev/null @@ -1,150 +0,0 @@ -/** - * @architect - * @architect-status roadmap - * @architect-implements DataAPIStubIntegration - * @architect-uses PatternGraphAPI - * @architect-used-by PatternGraphCLIImpl - * @architect-target src/api/stub-resolver.ts - * @architect-since DS-B - * - * ## StubResolver — Design Stub Discovery and Resolution - * - * Identifies design session stubs in the PatternGraph and resolves them - * against the filesystem to determine implementation status. - * - * Stub identification heuristic: - * - Source file path contains `/stubs/` (lives in stubs directory), OR - * - Pattern has a `targetPath` field (from @architect-target tag) - * - * Resolution uses a `fileExists` callback (defaulting to `fs.existsSync()`) on - * targetPath — not pipeline data — because target files may not have `@architect` - * annotations. The callback enables testing without filesystem side effects. - * - * See: DataAPIStubIntegration spec, Rule 2 (Stubs Subcommand) - * - * **When to Use:** When querying design stub status via the `stubs` CLI subcommand or when checking stub resolution in scope validation. - */ - -// --------------------------------------------------------------------------- -// Types -// --------------------------------------------------------------------------- - -/** - * Result of resolving a single stub against the filesystem. - */ -export interface StubResolution { - /** The stub's pattern name (from @architect-implements or patternName) */ - readonly stubName: string; - /** Source file path of the stub */ - readonly stubFile: string; - /** Target implementation path (from @architect-target) */ - readonly targetPath: string; - /** Design session that created this stub (from @architect-since) */ - readonly since: string | undefined; - /** Parent pattern this stub implements (from @architect-implements) */ - readonly implementsPattern: string | undefined; - /** Whether the target file exists on disk */ - readonly targetExists: boolean; -} - -/** - * Summary of all stubs grouped by the pattern they implement. - */ -export interface StubSummary { - /** Pattern name that stubs implement */ - readonly pattern: string; - /** All stubs for this pattern */ - readonly stubs: readonly StubResolution[]; - /** Count of resolved (target exists) stubs */ - readonly resolvedCount: number; - /** Count of unresolved (target missing) stubs */ - readonly unresolvedCount: number; -} - -// --------------------------------------------------------------------------- -// Functions -// --------------------------------------------------------------------------- - -/** - * Identify stub patterns from the PatternGraph. - * - * A pattern is a stub if: - * 1. Its source file path contains '/stubs/' (lives in stubs directory), OR - * 2. It has a `targetPath` field (from @architect-target tag) - * - * @param dataset - PatternGraph with all patterns - * @returns Array of patterns identified as stubs - */ -export function findStubPatterns(_dataset: unknown): readonly unknown[] { - throw new Error('DataAPIStubIntegration not yet implemented - roadmap pattern'); -} - -/** - * Resolve stubs against the filesystem to determine implementation status. - * - * For each stub pattern with a `targetPath`: - * - Resolves the path relative to baseDir - * - Checks if the target file exists via `fileExists` callback - * - Extracts stub metadata (since, implementsPattern) - * - * @param stubs - Stub patterns to resolve - * @param baseDir - Base directory for resolving target paths - * @param fileExists - Optional callback for checking file existence (default: fs.existsSync). - * Inject a Map lookup for testing without filesystem side effects. - * @returns Array of StubResolution objects - */ -export function resolveStubs( - _stubs: readonly unknown[], - _baseDir: string, - _fileExists?: (path: string) => boolean -): readonly StubResolution[] { - throw new Error('DataAPIStubIntegration not yet implemented - roadmap pattern'); -} - -/** - * Group stub resolutions by the pattern they implement. - * - * Stubs that share the same `implementsPattern` value are grouped together. - * Each group includes resolution counts for quick status overview. - * - * @param resolutions - Individual stub resolutions - * @returns Array of StubSummary objects, sorted by pattern name - */ -export function groupStubsByPattern( - _resolutions: readonly StubResolution[] -): readonly StubSummary[] { - throw new Error('DataAPIStubIntegration not yet implemented - roadmap pattern'); -} - -/** - * Extract AD-N decision items from a pattern's description text. - * - * Parses JSDoc description for references like: - * - `AD-1: Unified action model (PDR-011)` - * - `AD-5: Router maps command types to orchestrator` - * - * @param description - Pattern's directive description text - * @returns Array of extracted decision items - */ -export function extractDecisionItems( - _description: string -): readonly { id: string; description: string; pdr: string | undefined }[] { - throw new Error('DataAPIStubIntegration not yet implemented - roadmap pattern'); -} - -/** - * Cross-reference all patterns that mention a specific PDR number. - * - * Scans pattern descriptions, ADR fields, and seeAlso references - * for `PDR-{number}` occurrences. - * - * @param patterns - All patterns from PatternGraph - * @param pdrNumber - PDR number to search for (e.g., "012") - * @returns Patterns referencing this PDR - */ -export function findPdrReferences( - _patterns: readonly unknown[], - _pdrNumber: string -): readonly { pattern: string; source: 'description' | 'seeAlso'; filePath: string }[] { - throw new Error('DataAPIStubIntegration not yet implemented - roadmap pattern'); -} diff --git a/architect/stubs/enhanced-index-generation/index-codec-options.ts b/architect/stubs/enhanced-index-generation/index-codec-options.ts deleted file mode 100644 index 6413e462..00000000 --- a/architect/stubs/enhanced-index-generation/index-codec-options.ts +++ /dev/null @@ -1,175 +0,0 @@ -/** - * @architect - * @architect-status completed - * @architect-implements EnhancedIndexGeneration - * @architect-target src/renderable/codecs/index-codec.ts - * - * ## IndexCodecOptions — DD-1, DD-5 Decisions - * - * **Decision DD-1 (New IndexCodec vs extend existing):** Create a new IndexCodec - * registered in CodecRegistry, NOT a standalone generator or extension of the - * current docs-live/INDEX.md (which is a static file, not generated by any code). - * - * **Rationale (DD-1):** The index needs PatternGraph pre-computed views - * (`byProductArea`, `byPhase`, `byStatus`, `byCategory`) to generate statistics. - * Only codecs registered in CodecRegistry receive PatternGraph via the - * `codec.decode(dataset)` pipeline. A standalone generator (like - * CliReferenceGenerator) would need to wire its own PatternGraph access, - * duplicating what CodecBasedGenerator already provides. The codec approach also - * gets free integration with `generateDocument('index', dataset)`, - * `generateAllDocuments()`, and the `CodecOptions` type-safe options pipeline. - * - * **Decision DD-5 (ReferenceDocConfig vs standalone codec):** Use a standalone - * IndexCodec rather than a ReferenceDocConfig entry. The IndexCodec is registered - * directly in CodecRegistry as document type `'index'`, not routed through the - * reference codec's 4-layer composition pipeline. - * - * **Rationale (DD-5):** ReferenceDocConfig's 4-layer composition (conventions, - * diagrams, shapes, behaviors) is designed for scoped reference documents that - * assemble content from annotated sources. The index document is fundamentally - * different — it is a NAVIGATION document that lists OTHER documents, computes - * cross-cutting statistics from PatternGraph views, and composes them with - * editorial preamble sections. None of the 4 layers apply: - * - No convention tags to extract (the index doesn't document conventions) - * - No scoped diagrams (the index doesn't visualize architecture) - * - No TypeScript shapes (the index doesn't expose API surfaces) - * - No behavior categories (the index doesn't describe behaviors) - * - * However, the IndexCodec DOES reuse the `preamble` concept from - * ReferenceDocConfig — editorial `SectionBlock[]` prepended before generated - * content. This is passed via `IndexCodecOptions.preamble`, not via - * ReferenceDocConfig. The preamble mechanism is a pattern, not a type coupling. - * - * ### Integration Points - * - * | Integration | How | - * |-------------|-----| - * | CodecRegistry | `CodecRegistry.register('index', IndexCodec)` | - * | DOCUMENT_TYPES | Add `index: { outputPath: 'INDEX.md', description: '...' }` | - * | CodecOptions | Add `index?: IndexCodecOptions` to CodecOptions interface | - * | architect.config.ts | Add `generatorOverrides.index.outputDirectory: 'docs-live'` | - * | generateAllDocuments() | Automatically included via DOCUMENT_TYPES iteration | - */ - -import type { SectionBlock } from '../../src/renderable/schema.js'; -import type { BaseCodecOptions } from '../../src/renderable/codecs/types/base.js'; - -// --------------------------------------------------------------------------- -// IndexCodecOptions -// --------------------------------------------------------------------------- - -/** - * Options for the IndexCodec. - * - * Controls which sections appear in the generated index and provides - * the editorial preamble content (audience reading paths, document - * roles matrix, quick finder table). - * - * The codec composes two content types: - * 1. **Auto-generated** — Statistics and document listings from PatternGraph - * 2. **Editorial** — Preamble sections authored in config - * - * This separation follows the same principle as ReferenceDocConfig.preamble - * but is specific to the index document's navigation-focused structure. - */ -export interface IndexCodecOptions extends BaseCodecOptions { - // ─── Editorial Preamble ────────────────────────────────────────────────── - - /** - * Static preamble sections prepended before all generated content. - * - * Expected to contain: - * - Quick navigation table (If you want X, read Y) - * - Audience reading paths (New User, Developer/AI, Team Lead/CI) - * - Document roles matrix (Audience x Document x Focus) - * - Key concepts glossary - * - * These sections require editorial judgment and cannot be derived - * from PatternGraph metadata. - */ - readonly preamble?: readonly SectionBlock[]; - - // ─── Section Visibility Toggles ────────────────────────────────────────── - - /** Include product area statistics table (default: true) */ - readonly includeProductAreaStats?: boolean; - - /** Include phase progress summary with completion percentage (default: true) */ - readonly includePhaseProgress?: boolean; - - /** Include unified document inventory table (default: true) */ - readonly includeDocumentInventory?: boolean; - - /** Include package metadata header (default: true) */ - readonly includePackageMetadata?: boolean; - - // ─── Document Inventory Configuration ──────────────────────────────────── - - /** - * Document entries for the unified inventory. - * - * Each entry describes a document from either docs/ or docs-live/. - * The codec renders this static inventory and combines it with - * statistics derived from PatternGraph views. - * - * Documents are organized by topic, NOT by source directory. - * The reader should not need to know whether a document is manual - * or generated. - */ - readonly documentEntries?: readonly DocumentEntry[]; -} - -/** - * A document entry for the unified inventory. - * - * Describes a single document in the navigation index. - * Used for both manual docs/ and generated docs-live/ documents. - */ -export interface DocumentEntry { - /** Document title (e.g., "Architecture Overview") */ - readonly title: string; - - /** Relative path from project root (e.g., "docs/ARCHITECTURE.md" or "docs-live/PRODUCT-AREAS.md") */ - readonly path: string; - - /** Brief description of what the document covers */ - readonly description: string; - - /** Primary audience for this document */ - readonly audience: 'Everyone' | 'Developers' | 'AI/Devs' | 'Users' | 'Writers' | 'Team Leads' | 'CI/CD' | 'Maintainers' | 'Reference'; - - /** - * Topic category for grouping in the index. - * Documents with the same topic appear in the same section. - */ - readonly topic: string; -} - -// --------------------------------------------------------------------------- -// Default Options -// --------------------------------------------------------------------------- - -/** - * Default options for IndexCodec. - * - * All auto-generated sections are enabled by default. - * Preamble and document entries are empty by default — they must be - * provided via architect.config.ts. - */ -export const DEFAULT_INDEX_OPTIONS: Required> & { - preamble: readonly SectionBlock[]; - documentEntries: readonly DocumentEntry[]; -} = { - generateDetailFiles: false, - detailLevel: 'detailed', - includeProductAreaStats: true, - includePhaseProgress: true, - includeDocumentInventory: true, - includePackageMetadata: true, - preamble: [], - documentEntries: [], -}; - -export function _indexCodecOptionsPlaceholder(): never { - throw new Error('EnhancedIndexGeneration not yet implemented - roadmap pattern'); -} diff --git a/architect/stubs/enhanced-index-generation/index-codec.ts b/architect/stubs/enhanced-index-generation/index-codec.ts deleted file mode 100644 index 46cf5cef..00000000 --- a/architect/stubs/enhanced-index-generation/index-codec.ts +++ /dev/null @@ -1,210 +0,0 @@ -/** - * @architect - * @architect-status completed - * @architect-implements EnhancedIndexGeneration - * @architect-target src/renderable/codecs/index-codec.ts - * - * ## IndexCodec Factory — DD-1 Implementation Stub - * - * Creates the IndexCodec as a Zod codec (PatternGraph -> RenderableDocument). - * Follows the same factory pattern as all other codecs in the system: - * `createIndexCodec(options?) -> DocumentCodec`. - * - * ### Codec Decode Pipeline - * - * ``` - * PatternGraph - * | - * +--> [Package Metadata Header] (optional, from options) - * | - * +--> [Preamble Sections] (editorial, from options.preamble) - * | - Quick Navigation Table - * | - Audience Reading Paths (3) - * | - Document Roles Matrix - * | - Key Concepts Glossary - * | - * +--> [Unified Document Inventory] (merged manual + generated) - * | - Organized by topic - * | - Each entry: title, description, audience, path - * | - * +--> [Product Area Statistics] (auto-generated from byProductArea) - * | - Per-area pattern counts - * | - Totals row - * | - * +--> [Phase Progress Summary] (auto-generated from byStatus) - * | - Status distribution counts - * | - Completion percentage - * | - * +--> [Regeneration Commands] (static footer) - * - pnpm docs:all - * - Individual generator commands - * ``` - * - * ### Key Design Choices - * - * 1. **Preamble first, statistics second.** Reading paths and the quick finder - * table are the most useful navigation aids (per spec Rule 2). Auto-generated - * statistics are supplementary context. This ordering matches how the manual - * INDEX.md is structured. - * - * 2. **Unified document inventory merges manual + generated.** The codec accepts - * `documentEntries` from config (covering both docs/ and docs-live/) and - * does NOT perform filesystem discovery at generation time (DD-2 decision). - * This keeps the codec pure (no I/O) and deterministic. - * - * 3. **Product area stats reuse `computeStatusCounts()`.** The same utility used - * by `buildProductAreaIndex()` in reference-generators.ts. No re-derivation - * from raw patterns (ADR-006). - * - * 4. **No detail files.** The index is a single-page navigation document. - * `generateDetailFiles` defaults to false. - */ - -import type { PatternGraph } from '../../src/validation-schemas/pattern-graph.js'; -import type { RenderableDocument, SectionBlock } from '../../src/renderable/schema.js'; -import type { IndexCodecOptions, DocumentEntry } from './index-codec-options.js'; -import type { StatusCounts } from '../../src/api/types.js'; - -// --------------------------------------------------------------------------- -// Codec Factory -// --------------------------------------------------------------------------- - -/** - * Create an IndexCodec with custom options. - * - * The returned codec transforms PatternGraph into a RenderableDocument - * containing the enhanced index. Register in CodecRegistry as: - * - * ```typescript - * CodecRegistry.register('index', createIndexCodec()); - * CodecRegistry.registerFactory('index', createIndexCodec); - * ``` - * - * @param options - IndexCodecOptions with preamble and visibility toggles - * @returns A Zod codec (PatternGraph -> RenderableDocument) - */ -export function createIndexCodec( - _options?: IndexCodecOptions -): unknown { - // DD-1: Registered in CodecRegistry as document type 'index' - // Uses z.codec(PatternGraphSchema, RenderableDocumentOutputSchema, { decode, encode }) - // pattern identical to OverviewCodec, BusinessRulesCodec, etc. - throw new Error('EnhancedIndexGeneration not yet implemented - roadmap pattern'); -} - -// The real implementation exports: export const IndexCodec = createIndexCodec(); -// See src/renderable/codecs/index-codec.ts for the actual codec. -// IndexCodec is created via createIndexCodec() — not eagerly instantiated in stubs - -// --------------------------------------------------------------------------- -// Document Builder (internal) -// --------------------------------------------------------------------------- - -/** - * Builds the enhanced index RenderableDocument from PatternGraph. - * - * Section ordering: - * 1. Package metadata header (if enabled) - * 2. Preamble sections (editorial: quick nav, reading paths, roles, glossary) - * 3. Unified document inventory (merged manual + generated) - * 4. Product area statistics (from byProductArea view) - * 5. Phase progress summary (from byStatus view) - * 6. Regeneration commands footer - * - * @param dataset - PatternGraph with pre-computed views - * @param options - Resolved IndexCodecOptions - * @returns RenderableDocument for the enhanced index - */ -function buildIndexDocument( - _dataset: PatternGraph, - _options: IndexCodecOptions -): RenderableDocument { - throw new Error('EnhancedIndexGeneration not yet implemented - roadmap pattern'); -} - -// --------------------------------------------------------------------------- -// Section Builders (internal) -// --------------------------------------------------------------------------- - -/** - * Build the unified document inventory section. - * - * Organizes documents by topic, NOT by source directory. - * Each topic becomes a heading with a table of documents. - * - * @param entries - Document entries from config (covers both docs/ and docs-live/) - * @returns SectionBlock[] for the document inventory - */ -function buildDocumentInventory( - _entries: readonly DocumentEntry[] -): SectionBlock[] { - // DD-2: Static config, not filesystem discovery. - // Groups entries by topic, renders each group as: - // ## {Topic} - // | Document | Description | Audience | - // | [title](path) | description | audience | - throw new Error('EnhancedIndexGeneration not yet implemented - roadmap pattern'); -} - -/** - * Build the product area statistics section. - * - * Uses dataset.byProductArea view and computeStatusCounts() to produce - * a table identical in structure to buildProductAreaIndex() in - * reference-generators.ts, but scoped to the index context. - * - * @param dataset - PatternGraph with byProductArea view - * @returns SectionBlock[] for the product area statistics - */ -function buildProductAreaStats( - _dataset: PatternGraph -): SectionBlock[] { - // Reuses computeStatusCounts() from src/renderable/utils.ts - // Produces table: | Area | Patterns | Completed | Active | Planned | - // Plus totals row. Same proven pattern as buildProductAreaIndex(). - throw new Error('EnhancedIndexGeneration not yet implemented - roadmap pattern'); -} - -/** - * Build the phase progress summary section. - * - * Uses dataset.byStatus view to show status distribution and - * completion percentage via completionPercentage() utility. - * - * @param dataset - PatternGraph with byStatus view - * @returns SectionBlock[] for the phase progress summary - */ -function buildPhaseProgress( - _dataset: PatternGraph -): SectionBlock[] { - // Uses dataset.byStatus (StatusGroupsSchema: { roadmap, active, completed, deferred }) - // Renders: "X patterns total: Y completed (Z%), A active, B planned" - // Plus per-phase breakdown from dataset.byPhase if available - throw new Error('EnhancedIndexGeneration not yet implemented - roadmap pattern'); -} - -/** - * Build the regeneration commands footer. - * - * Static section with pnpm commands for regenerating docs. - * - * @returns SectionBlock[] for the regeneration footer - */ -function buildRegenerationFooter(): SectionBlock[] { - // Static content: pnpm docs:all, individual generator commands - // Same content as current docs-live/INDEX.md "Regeneration" section - throw new Error('EnhancedIndexGeneration not yet implemented - roadmap pattern'); -} - -// Suppress unused variable warnings for internal functions -void buildIndexDocument; -void buildDocumentInventory; -void buildProductAreaStats; -void buildPhaseProgress; -void buildRegenerationFooter; - -// Suppress unused import warnings -void (undefined as unknown as PatternGraph); -void (undefined as unknown as SectionBlock); -void (undefined as unknown as DocumentEntry); -void (undefined as unknown as StatusCounts); diff --git a/architect/stubs/enhanced-index-generation/index-preamble-config.ts b/architect/stubs/enhanced-index-generation/index-preamble-config.ts deleted file mode 100644 index 119e4e79..00000000 --- a/architect/stubs/enhanced-index-generation/index-preamble-config.ts +++ /dev/null @@ -1,403 +0,0 @@ -/** - * @architect - * @architect-status completed - * @architect-implements EnhancedIndexGeneration - * @architect-target architect.config.ts - * - * ## Index Preamble Configuration — DD-3, DD-4 Decisions - * - * **Decision DD-3 (Audience paths: preamble vs annotation-derived):** Use full - * preamble for audience reading paths. The reading order within each audience - * profile is editorial judgment — "read this third because it builds on concepts - * from document two" cannot be computed from pattern metadata. - * - * **Rationale (DD-3):** The three audience profiles (New User, Developer/AI, - * Team Lead/CI) and their curated reading sequences are the most-cited - * navigation aid in the existing manual INDEX.md. Each reading path is a - * deliberate pedagogical ordering: foundational concepts first, then - * architecture, then workflow, then enforcement. No annotation can express - * "this document builds on the mental model established by reading METHODOLOGY - * before ARCHITECTURE." The preamble mechanism is designed precisely for this - * case — editorial content that changes at authorial cadence, not code cadence. - * - * **Decision DD-4 (Key concepts: annotation-derived vs preamble):** Use preamble - * for the key concepts glossary. Pattern descriptions are too granular and - * technical to serve as glossary definitions for a navigation document. - * - * **Rationale (DD-4):** A glossary entry for "Delivery Workflow FSM" needs a - * reader-friendly 2-sentence explanation plus an ASCII state diagram. Pattern - * descriptions are structured for PatternGraph consumers (codecs, API queries), - * not for human onboarding. Attempting to derive glossary content from pattern - * metadata would produce entries like "FSM enforcement, pre-commit hooks" — - * accurate but unhelpful for someone encountering the concept for the first - * time. A future `@architect-glossary` annotation type could solve this, but - * it would require a new scanner capability and extraction pipeline. The - * preamble approach works today with zero new infrastructure. - * - * **Decision DD-2 (Merge manual + generated listings):** Document entries are - * configured statically in `documentEntries`, not discovered at generation time. - * The codec is pure (no filesystem I/O) and deterministic. - * - * **Rationale (DD-2):** Filesystem discovery at generation time would couple - * the codec to the filesystem, break deterministic testing, and require - * heuristics to extract titles/descriptions from markdown files. The existing - * docs are a stable, slowly-changing set (~14 manual docs + ~30 generated). - * When a document is added or renamed, updating the config entry is trivial - * and happens at the same time as the document creation. This is the same - * pattern used by `PRODUCT_AREA_META` in reference.ts — manually curated - * metadata for a stable set of entities. - * - * ### Preamble Structure - * - * The preamble composes four editorial sections as `SectionBlock[]`: - * - * | Section | SectionBlock Types | Source | - * |---------|-------------------|--------| - * | Quick Navigation | heading + table | "If you want X, read Y" lookup | - * | Reading Order: New User | heading + paragraph + list | 3-step onboarding path | - * | Reading Order: Developer/AI | heading + paragraph + list | 5-step deep-dive path | - * | Reading Order: Team Lead/CI | heading + paragraph + list | 2-step governance path | - * | Document Roles Matrix | heading + table | Audience x Document x Focus | - * | Key Concepts | heading + paragraphs | Glossary definitions | - * - * ### Config Integration - * - * This preamble is provided via `CodecOptions` in architect.config.ts: - * - * ```typescript - * // In architect.config.ts (future) - * export default defineConfig({ - * // ... existing config ... - * codecOptions: { - * index: { - * preamble: INDEX_PREAMBLE_SECTIONS, - * documentEntries: INDEX_DOCUMENT_ENTRIES, - * }, - * }, - * }); - * ``` - * - * Alternatively, the preamble could be passed via generatorOverrides - * with a custom codec options mechanism, following the pattern used by - * `pr-changes` codec options (changedFiles passed at runtime). - */ - -import type { SectionBlock } from '../../src/renderable/schema.js'; -import type { DocumentEntry } from './index-codec-options.js'; - -// --------------------------------------------------------------------------- -// Example Preamble Sections -// --------------------------------------------------------------------------- - -/** - * Quick navigation table — "If you want X, read Y" lookup. - * - * This is the highest-value section of the index. Users scan this first - * to find the document relevant to their immediate need. - */ -export const QUICK_NAVIGATION_SECTIONS: readonly SectionBlock[] = [ - { - type: 'heading' as const, - level: 2, - text: 'Quick Navigation', - }, - { - type: 'table' as const, - columns: ['If you want to...', 'Read this'], - rows: [ - ['Get started quickly', '[README.md](../README.md)'], - ['Configure presets and tags', '[CONFIGURATION.md](docs/CONFIGURATION.md)'], - ['Understand the "why"', '[METHODOLOGY.md](docs/METHODOLOGY.md)'], - ['Learn the architecture', '[ARCHITECTURE.md](docs/ARCHITECTURE.md)'], - ['Run AI coding sessions', '[SESSION-GUIDES.md](docs/SESSION-GUIDES.md)'], - ['Write Gherkin specs', '[GHERKIN-PATTERNS.md](docs/GHERKIN-PATTERNS.md)'], - ['Enforce delivery process rules', '[PROCESS-GUARD.md](docs/PROCESS-GUARD.md)'], - ['Validate annotation quality', '[VALIDATION.md](docs/VALIDATION.md)'], - ['Query process state via CLI', '[CLI.md](docs/CLI.md)'], - ['Browse product area overviews', '[PRODUCT-AREAS.md](docs-live/PRODUCT-AREAS.md)'], - ['Review architecture decisions', '[DECISIONS.md](docs-live/DECISIONS.md)'], - ['Check business rules', '[BUSINESS-RULES.md](docs-live/BUSINESS-RULES.md)'], - ], - }, -]; - -/** - * Audience reading paths — curated sequences for three reader profiles. - * - * DD-3: These are full preamble sections because reading order is - * editorial judgment, not computable from metadata. - */ -export const READING_ORDER_SECTIONS: readonly SectionBlock[] = [ - { - type: 'heading' as const, - level: 2, - text: 'Reading Order', - }, - - // --- New User Path --- - { - type: 'heading' as const, - level: 3, - text: 'For New Users', - }, - { - type: 'paragraph' as const, - text: [ - '1. **[README.md](../README.md)** -- Installation, quick start, Data API CLI overview', - '2. **[CONFIGURATION.md](docs/CONFIGURATION.md)** -- Presets, tag prefixes, config files', - '3. **[METHODOLOGY.md](docs/METHODOLOGY.md)** -- Core thesis, dual-source architecture', - ].join('\n'), - }, - - // --- Developer / AI Path --- - { - type: 'heading' as const, - level: 3, - text: 'For Developers / AI', - }, - { - type: 'paragraph' as const, - text: [ - '4. **[ARCHITECTURE.md](docs/ARCHITECTURE.md)** -- Four-stage pipeline, codecs, PatternGraph', - '5. **[CLI.md](docs/CLI.md)** -- Data API CLI query interface', - '6. **[SESSION-GUIDES.md](docs/SESSION-GUIDES.md)** -- Planning/Design/Implementation workflows', - '7. **[GHERKIN-PATTERNS.md](docs/GHERKIN-PATTERNS.md)** -- Writing effective Gherkin specs', - '8. **[ANNOTATION-GUIDE.md](docs/ANNOTATION-GUIDE.md)** -- Annotation mechanics, shape extraction', - ].join('\n'), - }, - - // --- Team Lead / CI Path --- - { - type: 'heading' as const, - level: 3, - text: 'For Team Leads / CI', - }, - { - type: 'paragraph' as const, - text: [ - '9. **[PROCESS-GUARD.md](docs/PROCESS-GUARD.md)** -- FSM enforcement, pre-commit hooks', - '10. **[VALIDATION.md](docs/VALIDATION.md)** -- Lint rules, DoD checks, anti-patterns', - ].join('\n'), - }, -]; - -/** - * Document roles matrix — Audience x Document x Focus. - * - * Maps each document to its primary audience and focus area. - * This section helps readers who know their role find all relevant docs. - */ -export const DOCUMENT_ROLES_SECTIONS: readonly SectionBlock[] = [ - { - type: 'heading' as const, - level: 2, - text: 'Document Roles', - }, - { - type: 'table' as const, - columns: ['Document', 'Audience', 'Focus'], - rows: [ - ['README.md', 'Everyone', 'Quick start, value proposition'], - ['METHODOLOGY.md', 'Everyone', 'Why -- core thesis, principles'], - ['CONFIGURATION.md', 'Users', 'Setup -- presets, tags, config'], - ['ARCHITECTURE.md', 'Developers', 'How -- pipeline, codecs, schemas'], - ['CLI.md', 'AI/Devs', 'Data API CLI query interface'], - ['SESSION-GUIDES.md', 'AI/Devs', 'Workflow -- day-to-day usage'], - ['GHERKIN-PATTERNS.md', 'Writers', 'Specs -- writing effective Gherkin'], - ['PROCESS-GUARD.md', 'Team Leads', 'Governance -- enforcement rules'], - ['VALIDATION.md', 'CI/CD', 'Quality -- automated checks'], - ['TAXONOMY.md', 'Reference', 'Lookup -- tag taxonomy and API'], - ['ANNOTATION-GUIDE.md', 'Developers', 'Reference -- annotation mechanics'], - ['MAINTAINERS.md', 'Maintainers', 'Project maintenance and release workflow'], - ['PRODUCT-AREAS.md', 'Everyone', 'Generated -- product area overviews'], - ['DECISIONS.md', 'Developers', 'Generated -- architecture decisions'], - ['BUSINESS-RULES.md', 'Developers', 'Generated -- business rules and invariants'], - ], - }, -]; - -/** - * Key concepts glossary — reader-friendly definitions. - * - * DD-4: Full preamble, not annotation-derived. Pattern descriptions - * are too granular for glossary use. - */ -export const KEY_CONCEPTS_SECTIONS: readonly SectionBlock[] = [ - { - type: 'heading' as const, - level: 2, - text: 'Key Concepts', - }, - { - type: 'paragraph' as const, - text: [ - '**Delivery Process** -- A code-first documentation and workflow toolkit. Extracts patterns from annotated TypeScript and Gherkin sources, generates markdown documentation, and validates delivery workflow via pre-commit hooks.', - '', - '**Pattern** -- An annotated unit of work tracked by the delivery process. Each pattern has a status (roadmap, active, completed, deferred), belongs to a product area, and has deliverables. Patterns are the atomic unit of the PatternGraph.', - '', - '**PatternGraph** -- The single read model (ADR-006) containing all extracted patterns with pre-computed views (byProductArea, byPhase, byStatus, byCategory). All codecs and the Data API consume this dataset. No consumer re-derives data from raw scanner output.', - '', - '**Codec** -- A Zod-based transformer that decodes PatternGraph into a RenderableDocument. Each codec produces a specific document type (e.g., PatternsDocumentCodec produces PATTERNS.md). Codecs are pure functions with no I/O.', - '', - '**Dual-Source Architecture** -- Feature files own planning metadata (status, phase, dependencies). TypeScript files own implementation metadata (uses, used-by, category). This split prevents ownership conflicts and enables independent annotation cadences.', - '', - '**Delivery Workflow FSM** -- A finite state machine enforcing pattern lifecycle: roadmap -> active -> completed. Transitions are validated by Process Guard at commit time. The FSM prevents scope creep (no adding deliverables to active specs) and ensures completion integrity.', - ].join('\n'), - }, -]; - -/** - * Complete preamble for the IndexCodec. - * - * Composes all editorial sections in display order: - * 1. Quick Navigation (highest-value lookup table) - * 2. Reading Order (audience-specific paths) - * 3. Document Roles (audience x document matrix) - * 4. Key Concepts (glossary) - */ -export const INDEX_PREAMBLE_SECTIONS: readonly SectionBlock[] = [ - ...QUICK_NAVIGATION_SECTIONS, - { type: 'separator' as const }, - ...READING_ORDER_SECTIONS, - { type: 'separator' as const }, - ...DOCUMENT_ROLES_SECTIONS, - { type: 'separator' as const }, - ...KEY_CONCEPTS_SECTIONS, -]; - -// --------------------------------------------------------------------------- -// Example Document Entries (DD-2: static config, not filesystem discovery) -// --------------------------------------------------------------------------- - -/** - * Document entries for the unified inventory. - * - * DD-2: Configured statically. The codec does not discover files at - * generation time. When documents are added or renamed, this list - * is updated alongside the document change. - * - * Documents are organized by topic, not by source directory. - * The reader sees one unified set of documentation. - */ -export const INDEX_DOCUMENT_ENTRIES: readonly DocumentEntry[] = [ - // --- Getting Started --- - { - title: 'README', - path: 'README.md', - description: 'Installation, quick start, value proposition', - audience: 'Everyone', - topic: 'Getting Started', - }, - { - title: 'Configuration', - path: 'docs/CONFIGURATION.md', - description: 'Presets, tag prefixes, config files', - audience: 'Users', - topic: 'Getting Started', - }, - { - title: 'Methodology', - path: 'docs/METHODOLOGY.md', - description: 'Core thesis, dual-source architecture principles', - audience: 'Everyone', - topic: 'Getting Started', - }, - - // --- Architecture --- - { - title: 'Architecture', - path: 'docs/ARCHITECTURE.md', - description: 'Four-stage pipeline, codecs, PatternGraph, schemas', - audience: 'Developers', - topic: 'Architecture', - }, - { - title: 'Product Areas', - path: 'docs-live/PRODUCT-AREAS.md', - description: 'Product area overviews with live statistics and diagrams', - audience: 'Everyone', - topic: 'Architecture', - }, - { - title: 'Architecture Decisions', - path: 'docs-live/DECISIONS.md', - description: 'ADRs extracted from decision specs', - audience: 'Developers', - topic: 'Architecture', - }, - - // --- Development Workflow --- - { - title: 'Session Guides', - path: 'docs/SESSION-GUIDES.md', - description: 'Planning, Design, Implementation session workflows', - audience: 'AI/Devs', - topic: 'Development Workflow', - }, - { - title: 'Process API', - path: 'docs/CLI.md', - description: 'Data API CLI query interface for session context', - audience: 'AI/Devs', - topic: 'Development Workflow', - }, - - // --- Authoring --- - { - title: 'Gherkin Patterns', - path: 'docs/GHERKIN-PATTERNS.md', - description: 'Writing effective Gherkin specs, Rule blocks, DataTables', - audience: 'Writers', - topic: 'Authoring', - }, - { - title: 'Annotation Guide', - path: 'docs/ANNOTATION-GUIDE.md', - description: 'Annotation mechanics, shape extraction, tag reference', - audience: 'Developers', - topic: 'Authoring', - }, - { - title: 'Taxonomy', - path: 'docs/TAXONOMY.md', - description: 'Tag taxonomy structure and format types', - audience: 'Reference', - topic: 'Authoring', - }, - - // --- Governance --- - { - title: 'Process Guard', - path: 'docs/PROCESS-GUARD.md', - description: 'FSM enforcement, pre-commit hooks, error codes', - audience: 'Team Leads', - topic: 'Governance', - }, - { - title: 'Validation', - path: 'docs/VALIDATION.md', - description: 'Lint rules, DoD checks, anti-pattern detection', - audience: 'CI/CD', - topic: 'Governance', - }, - { - title: 'Business Rules', - path: 'docs-live/BUSINESS-RULES.md', - description: 'Business rules and invariants extracted from specs', - audience: 'Developers', - topic: 'Governance', - }, - - // --- Operations --- - { - title: 'Maintainers', - path: 'MAINTAINERS.md', - description: 'Project maintenance, release workflow, versioning, CI setup', - audience: 'Maintainers', - topic: 'Operations', - }, -]; - -export function _indexPreambleConfigPlaceholder(): never { - throw new Error('EnhancedIndexGeneration not yet implemented - roadmap pattern'); -} diff --git a/architect/stubs/error-guide-codec/convention-annotation-example.ts b/architect/stubs/error-guide-codec/convention-annotation-example.ts deleted file mode 100644 index 4ecec58b..00000000 --- a/architect/stubs/error-guide-codec/convention-annotation-example.ts +++ /dev/null @@ -1,153 +0,0 @@ -/** - * @architect - * @architect-status roadmap - * @architect-implements ErrorGuideCodec - * @architect-target src/lint/process-guard/decider.ts - * - * ## Convention Annotation Example — DD-3 Decision - * - * **Decision DD-3 (Rationale source):** Rationale comes from convention - * JSDoc annotations on `src/lint/process-guard/decider.ts`, not from - * `Rule:` blocks in the ProcessGuardLinter Gherkin spec. - * - * **Rationale (DD-3):** The rationale content belongs near the error-handling - * code, not in a planning spec. When a developer changes an error rule in - * the decider, the convention JSDoc is right there -- they update both in - * the same commit. This follows the proven pattern used by: - * - `src/generators/orchestrator.ts` with `@architect-convention pipeline-architecture` - * - `src/renderable/codecs/reference.ts` with `@architect-convention codec-registry` - * - `src/renderable/codecs/validation-rules.ts` with `@architect-convention codec-registry` - * - * All three use TypeScript JSDoc convention annotations with `## Heading` - * decomposition. The convention extractor's `extractConventionRulesFromDescription()` - * splits by `## Heading` sections, parsing each for `**Invariant:**`, - * `**Rationale:**`, and tables -- exactly the structure needed for error guides. - * - * **Annotation format:** - * Each error rule gets a `## ` heading in the JSDoc with structured - * content below it. The convention extractor decomposes by heading and - * produces one `ConventionRuleContent` per error code. - * - * **Content structure per error code:** - * - `**Invariant:**` — The rule statement (maps to "Why this rule exists") - * - `**Rationale:**` — Why the constraint exists (detailed explanation) - * - Table with `| Situation | Solution | Example |` for alternatives - * - * ### Annotation Placement - * - * The convention annotation is added to the EXISTING JSDoc block on - * `src/lint/process-guard/decider.ts`. The file already has extensive - * JSDoc describing the decider's design principles and rules. The - * convention annotation extends this JSDoc, not replaces it. - * - * Specifically, `@architect-convention process-guard-errors` is added - * to the file-level JSDoc alongside the existing annotations: - * - `@architect-pattern ProcessGuardDecider` - * - `@architect-arch-role decider` - * - etc. - * - * Then the `## ` headings for each error rule are added below the existing - * design documentation. - */ - -// --------------------------------------------------------------------------- -// Example: How decider.ts would be annotated (partial) -// --------------------------------------------------------------------------- - -/** - * This stub shows the PATTERN of convention annotation that would be - * added to `src/lint/process-guard/decider.ts`. The actual annotation - * content goes in the decider's file-level JSDoc block. - * - * Key insight: The convention extractor splits by `## Heading` and parses - * each section for `**Invariant:**`, `**Rationale:**`, and tables. So - * each error rule becomes a separate `ConventionRuleContent` entry in - * the extracted `ConventionBundle`. - * - * The annotation below demonstrates the format for all 6 error rules. - * In the actual decider.ts, these would follow the existing `### Rules - * Implemented` section. - * - * @architect-convention process-guard-errors - * - * ## completed-protection - * - * **Invariant:** Completed specs are immutable without an explicit unlock - * reason. The unlock reason must be at least 10 characters and cannot be - * a placeholder. - * - * **Rationale:** The `completed` status represents verified, accepted work. - * Allowing silent modification undermines the terminal-state guarantee. - * Requiring an unlock reason creates an audit trail and forces the developer - * to justify why completed work needs revisiting. - * - * | Situation | Solution | Example | - * |-----------|----------|---------| - * | Fix typo in completed spec | Add unlock reason tag | `@architect-unlock-reason:Fix-typo-in-FSM-diagram` | - * | Spec needs rework | Create new spec instead | New feature file with `roadmap` status | - * | Legacy import | Multiple transitions in one commit | Set `roadmap` then `completed` | - * - * ## invalid-status-transition - * - * **Invariant:** Status transitions must follow the PDR-005 FSM path. - * The only valid paths are: roadmap->active, roadmap->deferred, - * active->completed, active->roadmap, deferred->roadmap. - * - * **Rationale:** The FSM enforces a deliberate progression through - * planning, implementation, and completion. Skipping states (e.g., - * roadmap->completed) means work was never tracked as active, breaking - * session scoping and deliverable validation. - * - * | Attempted | Why Invalid | Valid Path | - * |-----------|-------------|------------| - * | roadmap->completed | Must go through active | roadmap->active->completed | - * | deferred->active | Must return to roadmap first | deferred->roadmap->active | - * | deferred->completed | Cannot skip two states | deferred->roadmap->active->completed | - * - * ## scope-creep - * - * **Invariant:** Active specs cannot add new deliverables. Scope is locked - * when status transitions to `active`. - * - * **Rationale:** Prevents scope creep during implementation. Plan fully - * before starting; implement what was planned. Adding deliverables mid- - * implementation signals inadequate planning and risks incomplete work. - * - * | Situation | Solution | Example | - * |-----------|----------|---------| - * | Need new deliverable | Revert to roadmap first | Change status to roadmap, add deliverable, then back to active | - * | Discovered work during implementation | Create new spec | New feature file for the discovered work | - * - * ## session-scope - * - * **Invariant:** Files outside the active session scope trigger warnings - * to prevent accidental cross-session modifications. - * - * **Rationale:** Session scoping ensures focused work. Modifying files - * outside the session scope often indicates scope creep or working on - * the wrong task. The warning is informational (not blocking) to allow - * intentional cross-scope changes with `--ignore-session`. - * - * ## session-excluded - * - * **Invariant:** Files explicitly excluded from a session cannot be - * modified in that session. This is a hard error, not a warning. - * - * **Rationale:** Explicit exclusion is a deliberate decision to protect - * certain files from modification during a session. Unlike session-scope - * (warning), exclusion represents a conscious boundary that should not - * be violated without changing the session configuration. - * - * ## deliverable-removed - * - * **Invariant:** Removing a deliverable from an active spec triggers a - * warning to ensure the removal is intentional and documented. - * - * **Rationale:** Deliverable removal during active implementation may - * indicate descoping or completion elsewhere. The warning ensures - * visibility -- the commit message should document why the deliverable - * was removed. - */ -export function _conventionAnnotationExample(): never { - throw new Error('ErrorGuideCodec not yet implemented - roadmap pattern'); -} diff --git a/architect/stubs/error-guide-codec/enhanced-validation-options.ts b/architect/stubs/error-guide-codec/enhanced-validation-options.ts deleted file mode 100644 index 89c01ff5..00000000 --- a/architect/stubs/error-guide-codec/enhanced-validation-options.ts +++ /dev/null @@ -1,155 +0,0 @@ -/** - * @architect - * @architect-status roadmap - * @architect-implements ErrorGuideCodec - * @architect-target src/renderable/codecs/validation-rules.ts - * - * ## Enhanced ValidationRulesCodecOptions — DD-1 Decision - * - * **Decision:** Extend the existing `ValidationRulesCodec` rather than creating - * a separate `ErrorGuideCodec`. The `ValidationRulesCodec` already owns - * `RULE_DEFINITIONS` with error codes, causes, and fixes, and generates - * `error-catalog.md`, `fsm-transitions.md`, and `protection-levels.md`. - * Creating a parallel codec would duplicate `RULE_DEFINITIONS` access and - * fragment validation documentation across two codecs. - * - * **Rationale (DD-1):** The existing ValidationRulesCodec has the right - * extension points: - * - `ValidationRulesCodecOptions` for feature toggles (pattern already - * established by `includeFSMDiagram`, `includeCLIUsage`, etc.) - * - `RULE_DEFINITIONS` constant for error code metadata - * - `buildDetailFiles()` for progressive disclosure - * - Section builder functions for composing document parts - * - * A new `ErrorGuideCodec` class would need to duplicate access to all of - * these, and consumers (orchestrator, config) would need to wire two codecs - * for what is logically one validation reference document. - * - * **What changes in validation-rules.ts:** - * 1. `RuleDefinition` interface gains optional `rationale` field - * 2. `ValidationRulesCodecOptions` gains `includeErrorGuide` toggle - * 3. `buildErrorCatalogDetailDocument()` conditionally renders rationale - * 4. New `buildErrorGuideSections()` builder for the rationale+alternatives layer - * - * **What does NOT change:** - * - No new class or codec file is created - * - Existing option defaults remain `true` (backward compatible) - * - `RULE_DEFINITIONS` entries without rationale fall back to `description` - */ - -import type { BaseCodecOptions } from '../../../src/renderable/codecs/types/base.js'; - -// --------------------------------------------------------------------------- -// DD-1: Extended RuleDefinition interface -// --------------------------------------------------------------------------- - -/** - * Extended rule definition for documentation, adding error guide fields. - * - * The `rationale` field is populated from convention-extracted content - * at generation time. If no convention annotation exists for a rule, - * the codec falls back to the `description` field. - * - * The `alternatives` field documents escape hatches and alternative - * approaches, also sourced from convention annotations. - */ -export interface EnhancedRuleDefinition { - /** Unique rule ID matching ProcessGuardRule union type */ - readonly id: string; - /** Default severity level */ - readonly severity: 'error' | 'warning'; - /** Human-readable rule description */ - readonly description: string; - /** What triggers this error */ - readonly cause: string; - /** How to fix this error */ - readonly fix: string; - /** - * Why this rule exists - sourced from convention annotation rationale. - * Falls back to `description` if no convention annotation exists. - */ - readonly rationale?: string; - /** - * Alternative approaches / escape hatches for this rule. - * Sourced from convention annotation alternatives section. - */ - readonly alternatives?: readonly string[]; -} - -// --------------------------------------------------------------------------- -// DD-1: Extended ValidationRulesCodecOptions -// --------------------------------------------------------------------------- - -/** - * Enhanced options for ValidationRulesCodec with error guide toggles. - * - * New toggles follow the established pattern: boolean flags with `true` - * defaults, independently toggleable. The `includeErrorGuide` flag - * controls whether rationale and alternative-approach content from - * convention annotations is merged into the error catalog detail file. - * - * When `includeErrorGuide` is `false`, the codec produces the same - * output as before this enhancement (backward compatible). - */ -export interface EnhancedValidationRulesCodecOptions extends BaseCodecOptions { - /** Include FSM state diagram (default: true) */ - readonly includeFSMDiagram?: boolean; - /** Include CLI usage section (default: true) */ - readonly includeCLIUsage?: boolean; - /** Include escape hatches section (default: true) */ - readonly includeEscapeHatches?: boolean; - /** Include protection levels matrix (default: true) */ - readonly includeProtectionMatrix?: boolean; - - /** - * DD-1: Include error guide rationale and alternatives in the error - * catalog detail file. When enabled, each error code entry in - * `validation/error-catalog.md` gains "Why this rule exists" and - * "Alternative approaches" sections sourced from convention annotations. - * - * Default: true - */ - readonly includeErrorGuide?: boolean; -} - -/** - * Default options with error guide enabled. - */ -export const ENHANCED_DEFAULT_OPTIONS: EnhancedValidationRulesCodecOptions = { - detailLevel: 'detailed', - generateDetailFiles: true, - includeFSMDiagram: true, - includeCLIUsage: true, - includeEscapeHatches: true, - includeProtectionMatrix: true, - includeErrorGuide: true, -}; - -// --------------------------------------------------------------------------- -// DD-3: Rationale composition from convention bundles -// --------------------------------------------------------------------------- - -/** - * Compose rationale into RuleDefinition entries from convention-extracted content. - * - * This function takes the static `RULE_DEFINITIONS` array and enriches each - * entry with rationale and alternatives from convention bundles extracted by - * the convention extractor pipeline. - * - * Matching strategy: Convention rule names are matched to RULE_DEFINITIONS - * entries by normalizing to the `id` field (e.g., convention rule name - * "completed-protection" matches `RULE_DEFINITIONS[0].id`). - * - * Fallback: If no convention content exists for a rule, `rationale` defaults - * to the `description` field. No empty rationale sections appear in output. - * - * @param rules - Static RULE_DEFINITIONS array - * @param conventionRationale - Map of rule ID to convention-extracted rationale - * @returns Enhanced rule definitions with rationale populated - */ -export function composeRationaleIntoRules( - _rules: readonly EnhancedRuleDefinition[], - _conventionRationale: ReadonlyMap -): EnhancedRuleDefinition[] { - throw new Error('ErrorGuideCodec not yet implemented - roadmap pattern'); -} diff --git a/architect/stubs/error-guide-codec/error-guide-config.ts b/architect/stubs/error-guide-codec/error-guide-config.ts deleted file mode 100644 index 3d46f93a..00000000 --- a/architect/stubs/error-guide-codec/error-guide-config.ts +++ /dev/null @@ -1,222 +0,0 @@ -/** - * @architect - * @architect-status roadmap - * @architect-implements ErrorGuideCodec - * @architect-target architect.config.ts - * - * ## ReferenceDocConfig Entry for Process Guard Error Guide — DD-2, DD-4 Decisions - * - * **Decision DD-2 (Convention tag approach):** Register a new `process-guard-errors` - * convention tag value in `CONVENTION_VALUES` rather than reusing `fsm-rules`. - * - * **Rationale (DD-2):** The `fsm-rules` tag covers FSM state definitions, - * transition matrices, and protection levels — structural FSM documentation. - * Error diagnosis content (rationale for why a rule exists, alternative - * approaches, common mistake patterns) is a distinct concern. Co-locating - * both under `fsm-rules` would conflate "how the FSM works" with "how to - * debug Process Guard errors". A dedicated tag keeps convention bundles - * focused and enables independent content routing. - * - * Existing convention tags for reference: - * - `fsm-rules` — FSM structure (transitions, states, protection levels) - * - `cli-patterns` — CLI argument parsing conventions - * - `codec-registry` — Codec catalog and factory patterns - * - `pipeline-architecture` — Pipeline stage responsibilities - * - * The new `process-guard-errors` tag covers: - * - Per-error-code rationale ("why this rule exists") - * - Alternative approaches and escape hatches - * - Common mistake patterns and debugging hints - * - * **Decision DD-4 (Husky/CI content):** Use the `ReferenceDocConfig.preamble` - * mechanism for integration recipes. Preamble is `SectionBlock[]` prepended - * before all generated content. This is the established pattern — no new - * annotation type is needed. - * - * **Rationale (DD-4):** Integration recipes (Husky hook setup, CI YAML - * patterns, programmatic API examples, architecture diagrams) describe how - * external systems consume Process Guard, not how Process Guard is - * implemented. This content cannot come from `@architect-convention` - * annotations because it is not attached to any source code entity. - * The preamble mechanism was designed precisely for this case: - * - Already proven by product-area docs (e.g., `PRODUCT_AREA_META` preamble) - * - Appears in both detailed and summary outputs - * - Lives in the config, not in a separate manual file - * - Changes at editorial cadence, not code cadence - * - * ### Config Structure - * - * The `ReferenceDocConfig` entry composes three content layers: - * - * | Layer | Source | Content | - * |-------|--------|---------| - * | Preamble | Config `preamble: SectionBlock[]` | Husky setup, CI recipes, programmatic API, architecture diagram | - * | Conventions | `conventionTags: ['process-guard-errors']` | Per-error rationale, alternatives, debugging hints | - * | Existing codec | `validation-rules` generator override | Error catalog, FSM transitions, protection levels | - * - * **Integration with ValidationRulesCodec:** - * The ReferenceDocConfig uses `conventionTags: ['process-guard-errors']` to - * pull rationale content through the reference codec's convention extraction - * pipeline. The `validation-rules` generator continues to produce its - * existing detail files (`error-catalog.md`, `fsm-transitions.md`, - * `protection-levels.md`) independently. The reference doc entry creates - * a unified PROCESS-GUARD.md that composes preamble + convention content + - * links to the validation-rules detail files. - */ - -// --------------------------------------------------------------------------- -// Example ReferenceDocConfig entry (would be added to architect.config.ts) -// --------------------------------------------------------------------------- - -/** - * This stub demonstrates the config entry shape. The actual entry goes in - * `architect.config.ts` under the `referenceDocConfigs` array. - * - * The preamble sections below show the editorial content structure for - * Husky setup, programmatic API, and architecture diagram. Each preamble - * entry is a SectionBlock (heading, paragraph, code, table, or mermaid). - */ -export const ERROR_GUIDE_REFERENCE_CONFIG = { - title: 'Process Guard Reference', - conventionTags: ['process-guard-errors'], - shapeSelectors: [], - behaviorCategories: [], - claudeMdSection: 'validation', - docsFilename: 'PROCESS-GUARD.md', - claudeMdFilename: 'process-guard.md', - preamble: [ - // --- Husky Pre-commit Setup --- - { - type: 'heading' as const, - level: 2, - text: 'Pre-commit Setup', - }, - { - type: 'paragraph' as const, - text: 'Configure Process Guard as a pre-commit hook using Husky.', - }, - { - type: 'code' as const, - language: 'bash', - content: [ - '# .husky/pre-commit', - '#!/usr/bin/env sh', - '. "$(dirname -- "$0")/_/husky.sh"', - '', - 'npx lint-process --staged', - ].join('\n'), - }, - { - type: 'heading' as const, - level: 3, - text: 'package.json Scripts', - }, - { - type: 'code' as const, - language: 'json', - content: JSON.stringify( - { - scripts: { - 'lint:process': 'lint-process --staged', - 'lint:process:ci': 'lint-process --all --strict', - }, - }, - null, - 2 - ), - }, - - // --- Programmatic API --- - { - type: 'heading' as const, - level: 2, - text: 'Programmatic API', - }, - { - type: 'paragraph' as const, - text: 'Use Process Guard programmatically for custom validation workflows.', - }, - { - type: 'code' as const, - language: 'typescript', - content: [ - "import {", - " deriveProcessState,", - " detectStagedChanges,", - " validateChanges,", - " hasErrors,", - " summarizeResult,", - "} from '@libar-dev/architect/lint';", - "", - "// 1. Derive state from annotations", - "const state = (await deriveProcessState({ baseDir: '.' })).value;", - "", - "// 2. Detect changes", - "const changes = detectStagedChanges('.').value;", - "", - "// 3. Validate", - "const { result } = validateChanges({", - " state,", - " changes,", - " options: { strict: false, ignoreSession: false },", - "});", - "", - "// 4. Handle results", - "if (hasErrors(result)) {", - " console.log(summarizeResult(result));", - " process.exit(1);", - "}", - ].join('\n'), - }, - { - type: 'heading' as const, - level: 3, - text: 'API Functions', - }, - { - type: 'table' as const, - headers: ['Category', 'Function', 'Description'], - rows: [ - ['State', 'deriveProcessState(cfg)', 'Build state from file annotations'], - ['Changes', 'detectStagedChanges(dir)', 'Parse staged git diff'], - ['Changes', 'detectBranchChanges(dir)', 'Parse all changes vs main'], - ['Validate', 'validateChanges(input)', 'Run all validation rules'], - ['Results', 'hasErrors(result)', 'Check for blocking errors'], - ['Results', 'summarizeResult(result)', 'Human-readable summary'], - ], - }, - - // --- Architecture Diagram --- - { - type: 'heading' as const, - level: 2, - text: 'Architecture', - }, - { - type: 'paragraph' as const, - text: 'Process Guard uses the Decider pattern: pure functions with no I/O.', - }, - { - type: 'mermaid' as const, - content: [ - 'graph LR', - ' A[deriveProcessState] --> C[validateChanges]', - ' B[detectStagedChanges / detectBranchChanges] --> C', - ' C --> D[ValidationResult]', - ].join('\n'), - }, - ], -} as const; - -// --------------------------------------------------------------------------- -// Convention tag registration (goes in src/taxonomy/conventions.ts) -// --------------------------------------------------------------------------- - -/** - * DD-2: 'process-guard-errors' is already registered in - * `src/taxonomy/conventions.ts` CONVENTION_VALUES. - * No additional registration needed. - */ -export function _conventionTagRegistrationPlaceholder(): never { - throw new Error('ErrorGuideCodec not yet implemented - roadmap pattern'); -} diff --git a/architect/stubs/procedural-guide-codec/annotation-guide-preamble.ts b/architect/stubs/procedural-guide-codec/annotation-guide-preamble.ts deleted file mode 100644 index 21de2c0a..00000000 --- a/architect/stubs/procedural-guide-codec/annotation-guide-preamble.ts +++ /dev/null @@ -1,126 +0,0 @@ -/** - * @architect - * @architect-status roadmap - * @architect-implements ProceduralGuideCodec - * @architect-target architect.config.ts - * - * ## Annotation Guide — Markdown Source File Example - * - * **Design Decision DD-7 (Markdown source files):** - * The annotation guide preamble content (~265 lines of inline `SectionBlock[]` - * TypeScript) is replaced by a plain markdown file at - * `docs-sources/annotation-guide.md`. This file is read and parsed into - * `SectionBlock[]` at config import time by `loadPreambleFromMarkdown()`. - * - * **Design Decision DD-5 (Hybrid approach):** - * The annotation guide uses a hybrid approach. Most content (getting-started - * walkthrough, shape extraction modes, Zod gotcha, file-type annotation - * patterns, verification CLI recipes, troubleshooting table) is stable - * editorial content that changes at editorial cadence, not code cadence. - * This content is authored as markdown. The tag reference summary table is - * the one section that changes when tags are added or modified -- it is - * auto-generated from taxonomy data. - * - * **Rationale (DD-5):** Attempting to annotate "how to annotate" as source - * code creates a circular dependency -- the guide that teaches annotation - * would need annotations to generate itself. The markdown source file - * breaks this circularity: the walkthrough is editorial content authored - * once and maintained manually. The tag reference table IS derivable - * from the taxonomy registry (tag names, format types, enum values) and - * should be auto-generated to stay current. - * - * ### Content Mapping from ANNOTATION-GUIDE.md - * - * | Manual Section (ANNOTATION-GUIDE.md) | Markdown Element | Lines | - * |--------------------------------------|------------------|-------| - * | Getting Started: File-Level Opt-In | Code fences + paragraphs | 9-42 | - * | Tag Prefix by Preset | Markdown table | 44-54 | - * | Dual-Source Ownership | Markdown table | 56-65 | - * | Shape Extraction: Mode 1 (Explicit) | Code fence | 71-82 | - * | Shape Extraction: Mode 2 (Wildcard) | Code fence | 84-98 | - * | Shape Extraction: Mode 3 (Declaration) | Code fence | 99-114 | - * | Critical Gotcha: Zod Schemas | Markdown table | 116-124 | - * | Verification CLI Commands | Bash code fence | 229-246 | - * | Common Issues / Troubleshooting | Markdown table | 250-257 | - * - * Content NOT in preamble (auto-generated from taxonomy): - * - Tag Groups Quick Reference table (lines 196-212) - * - Format Types table (lines 214-224) - * - * ### Config Usage Example - * - * ```typescript - * // In architect.config.ts: - * import { loadPreambleFromMarkdown } from './src/renderable/load-preamble.js'; - * - * const annotationPreamble = loadPreambleFromMarkdown( - * 'docs-sources/annotation-guide.md' - * ); - * - * // In referenceDocConfigs: - * { - * title: 'Annotation Reference Guide', - * conventionTags: ['annotation-system'], - * preamble: [...annotationPreamble], - * docsFilename: 'ANNOTATION-REFERENCE.md', - * // ... - * } - * ``` - * - * ### Example Markdown Source File (abbreviated) - * - * The full file at `docs-sources/annotation-guide.md` contains all sections - * from the content mapping table above. This example shows a representative - * section to illustrate the authoring format: - * - * ```markdown - * ## Getting Started - * - * Every file that participates in the annotation system must have a - * `@architect` opt-in marker. Files without this marker are invisible - * to the scanner. - * - * ### File-Level Opt-In - * - * **TypeScript** -- file-level JSDoc block: - * - * \`\`\`typescript - * /** - * * @architect - * * @architect-pattern MyPattern - * * @architect-status roadmap - * * / - * \`\`\` - * - * ### Tag Prefix by Preset - * - * | Preset | Prefix | Categories | Use Case | - * |--------|--------|------------|----------| - * | `libar-generic` (default) | `@architect-` | 3 | Simple projects | - * | `ddd-es-cqrs` | `@architect-` | 21 | DDD/Event Sourcing monorepos | - * - * --- - * - * ## Critical Gotcha: Zod Schemas - * - * For Zod files, extract the **schema constant** (with `Schema` suffix), - * not the inferred type alias: - * - * | Wrong (type alias) | Correct (schema constant) | - * |--------------------|---------------------------| - * | `@extract-shapes PatternGraph` | `@extract-shapes PatternGraphSchema` | - * - * --- - * - * ## Common Issues - * - * | Symptom | Cause | Fix | - * |---------|-------|-----| - * | Pattern not in scanner output | Missing `@architect` opt-in | Add file-level `@architect` JSDoc/tag | - * | Shape shows `z.infer<>` wrapper | Extracted type alias, not schema | Use schema constant name | - * ``` - */ - -export function _annotationGuidePreambleDesignStub(): never { - throw new Error('ProceduralGuideCodec not yet implemented - roadmap pattern'); -} diff --git a/architect/stubs/procedural-guide-codec/load-preamble.ts b/architect/stubs/procedural-guide-codec/load-preamble.ts deleted file mode 100644 index fc28511a..00000000 --- a/architect/stubs/procedural-guide-codec/load-preamble.ts +++ /dev/null @@ -1,133 +0,0 @@ -/** - * @architect - * @architect-status roadmap - * @architect-implements ProceduralGuideCodec - * @architect-target src/renderable/load-preamble.ts - * - * ## loadPreambleFromMarkdown() — Shared Utility Stub - * - * **Design Decision DD-8 (Shared markdown-to-SectionBlock parser):** - * A `loadPreambleFromMarkdown()` function in `src/renderable/load-preamble.ts` - * reads a markdown file via `readFileSync` (synchronous, runs at module import - * time) and parses it into a `readonly SectionBlock[]` array using a line-by-line - * state machine. This utility is available to all preamble consumers: - * ProceduralGuideCodec, ErrorGuideCodec, CliRecipeCodec. - * - * **Rationale (DD-8):** Preamble content is naturally authored as markdown — - * headings, tables, code fences, lists, and Mermaid diagrams all have standard - * markdown syntax. Converting this to inline TypeScript `SectionBlock[]` object - * literals (e.g., `{ type: 'heading', level: 2, text: '...' }`) is verbose - * and harder to review. A shared parser eliminates 540+ lines of inline - * TypeScript per codec config while preserving the same `SectionBlock[]` - * shape that codecs receive in memory. - * - * **Codec purity preserved:** The parser runs at config import time (before - * any codec `decode()` call). Codecs receive `SectionBlock[]` in memory via - * `ReferenceDocConfig.preamble` — they never know whether the preamble came - * from inline TypeScript or a parsed markdown file. No filesystem I/O occurs - * during codec execution. - * - * ### Parsing Rules (Line-by-Line State Machine) - * - * The parser processes the markdown file line by line, maintaining a state - * that tracks whether it is inside a code fence, accumulating a table, or - * collecting paragraph text. - * - * | Markdown Construct | SectionBlock Type | Detection Rule | - * |--------------------|-------------------|----------------| - * | `# Heading` through `###### Heading` | HeadingBlock | Line starts with 1-6 `#` chars followed by space | - * | Plain text paragraphs | ParagraphBlock | Consecutive non-empty lines separated by blank lines | - * | `---` (horizontal rule) | SeparatorBlock | Line is exactly `---`, `***`, or `___` | - * | `\| col \| col \|` with separator row | TableBlock | Line starts with `\|`, second line has `\|---` pattern | - * | `- item` or `* item` | ListBlock (unordered) | Line starts with `- ` or `* ` | - * | `1. item` | ListBlock (ordered) | Line starts with `\d+. ` | - * | ` ```language ` ... ` ``` ` | CodeBlock | Fenced code block with language info string | - * | ` ```mermaid ` ... ` ``` ` | MermaidBlock | Special case: code fence with `mermaid` info string | - * - * ### State Machine States - * - * | State | Entered When | Exited When | - * |-------|-------------|-------------| - * | `idle` | Start, after emitting a block | Any non-blank line | - * | `in-code-fence` | Line matches ` ``` ` with optional info string | Line matches closing ` ``` ` | - * | `in-table` | Line starts with `\|` and next line is separator | Line does not start with `\|` | - * | `in-paragraph` | Non-blank line that doesn't match other patterns | Blank line encountered | - * | `in-list` | Line starts with `- `, `* `, or `\d+. ` | Line does not match list pattern | - * - * ### Edge Cases - * - * | Case | Behavior | - * |------|----------| - * | `- [ ] Step text` | Parsed as ListBlock item with `[ ] ` prefix preserved (GFM checkbox) | - * | Nested lists | Not supported — flattened to single-level list | - * | `**bold**` in paragraphs | Preserved as-is in ParagraphBlock text (markdown inline formatting) | - * | Empty code fence | Produces CodeBlock with empty content string | - * | Table alignment (`:---:`) | Alignment markers stripped, columns extracted from header row | - * | Consecutive headings | Each produces a separate HeadingBlock | - * | YAML frontmatter (`---` ... `---`) | Not parsed — not needed for preamble content | - * - * ### Blocks NOT Produced - * - * | SectionBlock Type | Why Not Parsed | - * |-------------------|---------------| - * | CollapsibleBlock | No standard markdown syntax; codec adds these for progressive disclosure | - * | LinkOutBlock | No standard markdown syntax; codec adds cross-reference links | - * - * ### Usage - * - * ```typescript - * // In architect.config.ts: - * import { loadPreambleFromMarkdown } from './src/renderable/load-preamble.js'; - * - * const sessionWorkflowPreamble = loadPreambleFromMarkdown( - * 'docs-sources/session-workflow-guide.md' - * ); - * - * const annotationPreamble = loadPreambleFromMarkdown( - * 'docs-sources/annotation-guide.md' - * ); - * - * // In referenceDocConfigs: - * { - * title: 'Session Workflow Guide', - * preamble: [...sessionWorkflowPreamble], - * // ... - * } - * ``` - * - * ### File Resolution - * - * The `filePath` argument is resolved relative to the project root directory - * (the directory containing `package.json`). This matches how other config - * file paths are resolved in `architect.config.ts`. - * - * ```typescript - * // These are equivalent: - * loadPreambleFromMarkdown('docs-sources/session-workflow-guide.md') - * // Resolves to: /absolute/path/to/project/docs-sources/session-workflow-guide.md - * ``` - */ - -import type { SectionBlock } from '../../../src/renderable/schema.js'; - -/** - * Reads a markdown file and parses it into a `readonly SectionBlock[]` array. - * - * Uses `readFileSync` (synchronous) — intended to run at config import time, - * not during codec decode. Resolves `filePath` relative to project root. - * - * @param _filePath - Path to markdown file, relative to project root - * @returns Parsed SectionBlock array suitable for ReferenceDocConfig.preamble - * - * @example - * ```typescript - * const preamble = loadPreambleFromMarkdown('docs-sources/session-workflow-guide.md'); - * // Returns: readonly SectionBlock[] with HeadingBlock, ParagraphBlock, - * // CodeBlock, MermaidBlock, TableBlock, ListBlock, SeparatorBlock - * ``` - */ -export function loadPreambleFromMarkdown( - _filePath: string -): readonly SectionBlock[] { - throw new Error('ProceduralGuideCodec not yet implemented - roadmap pattern'); -} diff --git a/architect/stubs/procedural-guide-codec/procedural-codec-options.ts b/architect/stubs/procedural-guide-codec/procedural-codec-options.ts deleted file mode 100644 index 2794052a..00000000 --- a/architect/stubs/procedural-guide-codec/procedural-codec-options.ts +++ /dev/null @@ -1,135 +0,0 @@ -/** - * @architect - * @architect-status roadmap - * @architect-implements ProceduralGuideCodec - * @architect-target src/renderable/codecs/procedural-guide.ts - * - * ## ProceduralGuideCodecOptions -- Configuration Interface - * - * **Design Decision DD-1 (One codec, two configs):** - * A single `createProceduralGuideCodec()` factory produces both the session - * workflow guide and the annotation guide. The two documents share the same - * dual-source composition pattern (preamble editorial + auto-generated - * reference), but differ in their `ReferenceDocConfig` entries: different - * titles, different preamble content, different behavior source patterns, - * and different output paths. - * - * **Rationale (DD-1):** The codec class contains zero document-specific - * logic. All document-specific content is in the config: the preamble - * `SectionBlock[]` array carries editorial content, while - * `behaviorCategories` and the SessionGuidesModuleSource pattern name - * control which Rule: blocks are extracted. Creating two separate codec - * classes would duplicate the identical composition logic. This follows - * the precedent set by `createReferenceCodec()`, which produces 10+ - * different reference documents from different `ReferenceDocConfig` entries. - * - * **Design Decision DD-4 (Preamble from parsed markdown):** - * The preamble is a flat `SectionBlock[]` array produced by parsing a - * markdown source file via `loadPreambleFromMarkdown()` at config import - * time. Editorial content is organized by section headings in the markdown - * file (e.g., `## Session Decision Tree`, `## Getting Started`). This - * avoids introducing a new "named template section" abstraction -- the - * existing `SectionBlock` types (`heading`, `paragraph`, `table`, - * `mermaid`, `code`, `list`) are sufficient to express all procedural - * content, and standard markdown maps directly to these types. - * - * **Rationale (DD-4):** The preamble IS ~95% of the document, which is - * unusual but not architecturally different from a 10% preamble. The - * `SectionBlock[]` array is already the universal composition unit for - * all reference docs. Authoring this content as markdown (DD-7) instead - * of inline TypeScript object literals reduces config file size by ~540 - * lines while preserving the same `SectionBlock[]` shape that the codec - * receives. - * - * **Design Decision DD-3 (Checklists and decision trees via existing blocks):** - * Checklists use `ListBlock` with `- [ ] Step 1` text items (rendered - * as markdown checkbox syntax). Decision trees use `MermaidBlock` with - * `graph TD` diagrams. No new `ChecklistBlock` or `DecisionTreeBlock` - * types are introduced. - * - * **Rationale (DD-3):** The markdown renderer already emits `ListBlock` - * items as `- item` lines. Prefixing list items with `[ ] ` produces - * valid GitHub/Starlight checkbox syntax without any renderer changes. - * Mermaid `graph TD` diagrams are already a supported `SectionBlock` - * type (proven by product area docs and ReferenceDocShowcase). Adding - * new block types would require schema changes, renderer changes, and - * test updates -- all for rendering that existing types already handle. - * - * ### Integration with ReferenceDocConfig - * - * The ProceduralGuideCodec does NOT introduce a new config type. It - * reuses `ReferenceDocConfig` directly, with these fields populated: - * - * | Field | Session Workflow Guide | Annotation Guide | - * |-------|----------------------|------------------| - * | title | "Session Workflow Guide" | "Annotation Reference Guide" | - * | preamble | Checklists, Mermaid decision tree, Do-NOT tables | Getting-started, shape modes, troubleshooting | - * | behaviorCategories | [] (empty -- uses includeTags instead) | [] | - * | includeTags | ['session-workflows'] | [] | - * | conventionTags | [] | ['annotation-system'] | - * | shapeSelectors | [] | [] | - * | claudeMdSection | 'workflow' | 'annotation' | - * | docsFilename | 'SESSION-WORKFLOW-GUIDE.md' | 'ANNOTATION-REFERENCE.md' | - * | claudeMdFilename | 'session-workflow-guide.md' | 'annotation-reference.md' | - * - * The `includeTags` mechanism is preferred over `behaviorCategories` - * because SessionGuidesModuleSource needs to be explicitly opted-in - * via `@architect-include:session-workflows` rather than category-matched. - * This allows precise control over which patterns contribute behavior - * content to each guide document. - */ - -import type { SectionBlock } from '../../../src/renderable/schema.js'; - -// --------------------------------------------------------------------------- -// No new options type needed -- ProceduralGuideCodec uses ReferenceDocConfig -// --------------------------------------------------------------------------- - -/** - * Type alias documenting the preamble content structure for session guides. - * The actual type is `readonly SectionBlock[]` from ReferenceDocConfig.preamble. - * - * Content organization within the flat SectionBlock[] array: - * - * Session Workflow Guide preamble sections (in order): - * 1. heading(2, 'Session Decision Tree') + MermaidBlock (graph TD) - * 2. heading(2, 'Planning Session') + checklist ListBlocks + Do-NOT table - * 3. heading(2, 'Design Session') + checklist ListBlocks + Do-NOT table - * 4. heading(2, 'Implementation Session') + execution order ListBlock + Do-NOT table - * 5. heading(2, 'Planning + Design Session') + combined checklist - * 6. heading(2, 'Handoff Documentation') + template CodeBlock - * 7. heading(2, 'FSM Protection Quick Reference') + FSM table - * - * Annotation Guide preamble sections (in order): - * 1. heading(2, 'Getting Started') + opt-in examples + prefix table - * 2. heading(2, 'Shape Extraction') + mode explanations + Zod gotcha - * 3. heading(2, 'Annotation Patterns by File Type') + per-type examples - * 4. heading(2, 'Verification') + CLI recipes + troubleshooting table - */ -export type ProceduralGuidePreamble = readonly SectionBlock[]; - -/** - * Validates that a preamble array contains the expected section structure - * for a session workflow guide. Used in tests to verify preamble completeness. - * - * @param _preamble - The preamble SectionBlock[] to validate - * @returns true if all expected sections are present - */ -export function validateSessionGuidePreamble( - _preamble: ProceduralGuidePreamble -): boolean { - throw new Error('ProceduralGuideCodec not yet implemented - roadmap pattern'); -} - -/** - * Validates that a preamble array contains the expected section structure - * for an annotation guide. Used in tests to verify preamble completeness. - * - * @param _preamble - The preamble SectionBlock[] to validate - * @returns true if all expected sections are present - */ -export function validateAnnotationGuidePreamble( - _preamble: ProceduralGuidePreamble -): boolean { - throw new Error('ProceduralGuideCodec not yet implemented - roadmap pattern'); -} diff --git a/architect/stubs/procedural-guide-codec/procedural-codec.ts b/architect/stubs/procedural-guide-codec/procedural-codec.ts deleted file mode 100644 index 9cdb848a..00000000 --- a/architect/stubs/procedural-guide-codec/procedural-codec.ts +++ /dev/null @@ -1,209 +0,0 @@ -/** - * @architect - * @architect-status roadmap - * @architect-implements ProceduralGuideCodec - * @architect-target src/renderable/codecs/procedural-guide.ts - * - * ## ProceduralGuideCodec -- Factory Stub for Dual-Source Procedural Guides - * - * **Design Decision DD-1 (One codec, two configs):** - * This codec IS `createReferenceCodec()`. The ProceduralGuideCodec does not - * introduce a new codec class. Instead, it adds two new `ReferenceDocConfig` - * entries to the `referenceDocConfigs` array in `architect.config.ts`. - * Each entry configures `createReferenceCodec()` with document-specific - * preamble content and behavior extraction settings. - * - * **Why no new codec class is needed:** - * The existing `createReferenceCodec()` already supports all required - * composition: - * - `preamble: SectionBlock[]` -- carries ~95% editorial content - * - `includeTags: string[]` -- pulls Rule: blocks from SessionGuidesModuleSource - * - `behaviorCategories: string[]` -- category-based behavior extraction - * - `conventionTags: string[]` -- convention content extraction - * - Detail level rendering (summary vs detailed) -- already built - * - * The ProceduralGuideCodec "pattern" is therefore a configuration pattern, - * not a code pattern. The implementation deliverables are: - * 1. `loadPreambleFromMarkdown()` utility in `src/renderable/load-preamble.ts` - * 2. Two markdown source files in `docs-sources/` - * 3. Two `ReferenceDocConfig` entries in `architect.config.ts` - * 4. `@architect-include:session-workflows` tag on SessionGuidesModuleSource - * - * **Design Decision DD-2 (SessionGuidesModuleSource as behavior source):** - * The SessionGuidesModuleSource spec's Rule: blocks (Rules 3-8) are extracted - * via the existing `buildBehaviorSectionsFromPatterns()` function. This - * function already: - * - Extracts Invariant/Rationale via `parseBusinessRuleAnnotations()` - * - Extracts tables via `extractTablesFromDescription()` - * - Renders at two detail levels (summary: compact table, detailed: full rules) - * - Wraps 3+ rules in collapsible blocks for progressive disclosure - * - * The Rule: block tables in SessionGuidesModuleSource (session type contracts, - * Do/Do-NOT tables, FSM error reference, escape hatches) are ALREADY - * machine-extractable. The existing behavior extraction pipeline handles them - * without modification. - * - * **What the detailed level adds over the existing AI summary:** - * - Full Invariant + Rationale text (summary truncates to 120 chars) - * - Tables rendered as full markdown tables (summary omits tables) - * - Code examples from DocStrings (summary omits code) - * - Scenario names as "Verified by" lists (summary omits) - * - * The preamble content adds what Rule: blocks cannot express: - * - Step-by-step numbered checklists with checkbox syntax - * - Mermaid flowchart decision trees - * - CLI command examples with full bash code blocks - * - Cross-references to other docs - * - * **Design Decision DD-5 (Annotation guide: hybrid approach):** - * The annotation guide uses a hybrid approach: - * - ~95% preamble: getting-started walkthrough, shape extraction mode - * explanations, Zod gotcha, file-type annotation examples, verification - * CLI recipes, troubleshooting table - * - ~5% auto-generated: Tag reference summary table derived from taxonomy - * registry data via `createReferenceCodec()`'s existing convention or - * shape extraction. Tag groups, format types, and example values are - * already in PatternGraph. - * - * **Rationale (DD-5):** The annotation guide content is highly stable -- - * the getting-started walkthrough, shape extraction modes, and Zod gotcha - * have not changed since initial authoring. Making them preamble avoids - * the annotation overhead for content that changes at editorial cadence. - * The tag reference table is the one section that DOES change when tags - * are added -- auto-generating it eliminates a maintenance burden. - * - * **Design Decision DD-6 (Transition strategy):** - * The generated files output to `docs-live/reference/` (not `docs/`). - * The manual files (`docs/SESSION-GUIDES.md`, `docs/ANNOTATION-GUIDE.md`) - * are retained alongside the generated files during the transition period. - * The quality comparison deliverable produces an audit document recording - * section-by-section parity. Only after the audit confirms full parity - * are the manual files replaced with redirects to the generated output. - * - * **Rationale (DD-6):** The SessionGuidesModuleSource invariant (Rule 1) - * explicitly states SESSION-GUIDES.md "is not deleted, shortened, or - * replaced with a redirect." The generated file lives in a DIFFERENT - * directory (`docs-live/reference/`) and has a DIFFERENT name - * (`SESSION-WORKFLOW-GUIDE.md`). This means: - * - No violation of the Rule 1 invariant during transition - * - Both files can be compared side-by-side for quality audit - * - The manual file continues serving developers until parity is confirmed - * - After parity, Rule 1 can be explicitly superseded with an unlock-reason - * - * **Design Decision DD-7 (Markdown source files for editorial content):** - * Preamble content is authored as plain markdown files in `docs-sources/` - * and parsed into `SectionBlock[]` at config import time by - * `loadPreambleFromMarkdown()`. This replaces inline `SectionBlock[]` - * TypeScript object literals in the config file, reducing it from 853 - * to ~310 lines (63% reduction). Markdown is the natural authoring format - * for checklists, code blocks, tables, and Mermaid diagrams. - * - * **Rationale (DD-7):** The previous approach required ~541 lines of nested - * TypeScript object literals (`{ type: 'heading', level: 2, text: '...' }`) - * to express content that is more naturally written as markdown. The codec - * still receives `SectionBlock[]` in memory -- it never knows whether - * the preamble came from inline TypeScript or a parsed markdown file. - * Codec purity is preserved. - * - * **Design Decision DD-8 (loadPreambleFromMarkdown() shared utility):** - * A `loadPreambleFromMarkdown()` function in `src/renderable/load-preamble.ts` - * uses `readFileSync` (synchronous, runs at module import time) and a - * line-by-line state machine to parse markdown into `SectionBlock[]`. - * Available to all preamble consumers (ErrorGuideCodec, CliRecipeCodec). - * - * ### Implementation Plan - * - * Step 1: Create `loadPreambleFromMarkdown()` in `src/renderable/load-preamble.ts` - * Step 2: Create `docs-sources/session-workflow-guide.md` (content from current inline preamble) - * Step 3: Create `docs-sources/annotation-guide.md` (content from current inline preamble) - * Step 4: Update `architect.config.ts` to use `loadPreambleFromMarkdown()` calls - * Step 5: Verify generated output matches current output (regression test) - * Step 6: Quality audit document comparing generated vs manual - */ - -// --------------------------------------------------------------------------- -// Example ReferenceDocConfig entries for architect.config.ts -// --------------------------------------------------------------------------- - -import type { SectionBlock } from '../../../src/renderable/schema.js'; - -/** - * Placeholder interface showing the shape of a ReferenceDocConfig entry. - * The actual type is imported from `src/renderable/codecs/reference.ts`. - * This stub exists to document the design -- the real implementation adds - * entries directly to the `referenceDocConfigs` array. - */ -interface ReferenceDocConfigEntry { - readonly title: string; - readonly conventionTags: readonly string[]; - readonly shapeSelectors: readonly string[]; - readonly behaviorCategories: readonly string[]; - readonly includeTags?: readonly string[]; - readonly preamble?: readonly SectionBlock[]; - readonly claudeMdSection: string; - readonly docsFilename: string; - readonly claudeMdFilename: string; - readonly excludeSourcePaths?: readonly string[]; -} - -/** - * ReferenceDocConfig entry for the Session Workflow Guide. - * - * DD-7: Preamble loaded from markdown source file, not inline SectionBlock[]. - * - * ```typescript - * // In architect.config.ts: - * import { loadPreambleFromMarkdown } from './src/renderable/load-preamble.js'; - * - * const sessionWorkflowPreamble = loadPreambleFromMarkdown( - * 'docs-sources/session-workflow-guide.md' - * ); - * - * // In referenceDocConfigs array: - * { - * title: 'Session Workflow Guide', - * conventionTags: [], - * shapeSelectors: [], - * behaviorCategories: [], - * includeTags: ['session-workflows'], - * claudeMdSection: 'workflow', - * docsFilename: 'SESSION-WORKFLOW-GUIDE.md', - * claudeMdFilename: 'session-workflow-guide.md', - * preamble: [...sessionWorkflowPreamble], - * } - * ``` - * - * Output: docs-live/reference/SESSION-WORKFLOW-GUIDE.md - */ -export function createSessionWorkflowGuideConfig( - _preamble: readonly SectionBlock[] -): ReferenceDocConfigEntry { - throw new Error('ProceduralGuideCodec not yet implemented - roadmap pattern'); -} - -/** - * ReferenceDocConfig entry for the Annotation Guide. - * - * DD-7: Preamble loaded from markdown source file. - * - * ```typescript - * const annotationPreamble = loadPreambleFromMarkdown( - * 'docs-sources/annotation-guide.md' - * ); - * - * // In referenceDocConfigs array: - * { - * title: 'Annotation Reference Guide', - * conventionTags: ['annotation-system'], - * preamble: [...annotationPreamble], - * // ... - * } - * ``` - * - * Output: docs-live/reference/ANNOTATION-REFERENCE.md - */ -export function createAnnotationGuideConfig( - _preamble: readonly SectionBlock[] -): ReferenceDocConfigEntry { - throw new Error('ProceduralGuideCodec not yet implemented - roadmap pattern'); -} diff --git a/architect/stubs/procedural-guide-codec/session-guide-preamble.ts b/architect/stubs/procedural-guide-codec/session-guide-preamble.ts deleted file mode 100644 index a33ab6ab..00000000 --- a/architect/stubs/procedural-guide-codec/session-guide-preamble.ts +++ /dev/null @@ -1,146 +0,0 @@ -/** - * @architect - * @architect-status roadmap - * @architect-implements ProceduralGuideCodec - * @architect-target architect.config.ts - * - * ## Session Workflow Guide — Markdown Source File Example - * - * **Design Decision DD-7 (Markdown source files):** - * The session workflow guide preamble content (~276 lines of inline - * `SectionBlock[]` TypeScript) is replaced by a plain markdown file at - * `docs-sources/session-workflow-guide.md`. This file is read and parsed - * into `SectionBlock[]` at config import time by `loadPreambleFromMarkdown()`. - * - * **Design Decision DD-3 (Checklists as ListBlock items):** - * Checklist items written as `- [ ] Step description` in markdown are parsed - * into `ListBlock` items with the `[ ] ` prefix preserved. The markdown - * renderer emits `- [ ] Step description` -- valid GitHub Flavored Markdown - * checkbox syntax rendered by Starlight as interactive checkboxes. - * - * **Design Decision DD-3 (Decision trees as MermaidBlock):** - * Mermaid code fences in the markdown source file are parsed into - * `MermaidBlock` entries (not `CodeBlock`). The session type decision tree - * renders as an interactive flowchart on the Starlight website. - * - * ### Content Mapping from SESSION-GUIDES.md - * - * | Manual Section (SESSION-GUIDES.md) | Markdown Element | Lines | - * |-----------------------------------|--------------------|-------| - * | Session Decision Tree (ASCII art) | Mermaid code fence (graph TD) | 9-16 | - * | Session type table | Markdown table | 18-23 | - * | Planning Session checklist | Unordered list with [ ] prefix | 40-79 | - * | Planning Do NOT list | Unordered list | 82-85 | - * | Design Session checklist | Unordered list with [ ] prefix | 117-153 | - * | Design Do NOT list | Unordered list | 154-159 | - * | Implementation execution order | Ordered list | 186-226 | - * | Implementation Do NOT table | Markdown table | 230-233 | - * | Planning+Design checklist | Unordered list | 249-276 | - * | Handoff template | Bash code fence | 333-350 | - * | FSM Protection table | Markdown table | 369-374 | - * - * Content NOT in preamble (auto-generated from SessionGuidesModuleSource): - * - Session type contract invariants (Rule 3) - * - FSM error reference table (Rule 7) - * - Escape hatches table (Rule 7) - * - * ### Config Usage Example - * - * ```typescript - * // In architect.config.ts: - * import { loadPreambleFromMarkdown } from './src/renderable/load-preamble.js'; - * - * const sessionWorkflowPreamble = loadPreambleFromMarkdown( - * 'docs-sources/session-workflow-guide.md' - * ); - * - * // In referenceDocConfigs: - * { - * title: 'Session Workflow Guide', - * includeTags: ['session-workflows'], - * preamble: [...sessionWorkflowPreamble], - * docsFilename: 'SESSION-WORKFLOW-GUIDE.md', - * // ... - * } - * ``` - * - * ### Example Markdown Source File (abbreviated) - * - * The full file at `docs-sources/session-workflow-guide.md` contains all - * sections from the content mapping table above. This example shows the - * first few sections to illustrate the authoring format: - * - * ```markdown - * ## Session Decision Tree - * - * Use this flowchart to determine which session type to run. - * - * \`\`\`mermaid - * graph TD - * A[Starting from pattern brief?] -->|Yes| B[Need code stubs now?] - * A -->|No| C[Ready to code?] - * B -->|Yes| D[Planning + Design Session] - * B -->|No| E[Planning Session] - * C -->|Yes| F[Complex decisions?] - * C -->|No| E - * F -->|Yes| G[Design Session] - * F -->|No| H[Implementation Session] - * - * style D fill:#e1f5fe - * style E fill:#e8f5e9 - * style G fill:#fff3e0 - * style H fill:#fce4ec - * \`\`\` - * - * ## Session Type Contracts - * - * | Session | Input | Output | FSM Change | - * |---------|-------|--------|------------| - * | Planning | Pattern brief | Roadmap spec (`.feature`) | Creates `roadmap` | - * | Design | Complex requirement | Decision specs + code stubs | None | - * | Implementation | Roadmap spec | Code + tests | `roadmap` -> `active` -> `completed` | - * | Planning + Design | Pattern brief | Spec + stubs | Creates `roadmap` | - * - * --- - * - * ## Planning Session - * - * **Goal:** Create a roadmap spec. Do not write implementation code. - * - * ### Context Gathering - * - * \`\`\`bash - * pnpm process:query -- overview # Project health - * pnpm process:query -- list --status roadmap --names-only # Available patterns - * \`\`\` - * - * ### Planning Checklist - * - * - [ ] **Extract metadata** from pattern brief: phase, dependencies, status - * - [ ] **Create spec file** at `{specs-directory}/{product-area}/{pattern}.feature` - * - [ ] **Convert constraints to Rule: blocks** with Invariant/Rationale - * - [ ] **Add scenarios** per Rule: 1 happy-path + 1 validation minimum - * - * ### Planning Do NOT - * - * - Create `.ts` implementation files - * - Transition to `active` - * - Ask "Ready to implement?" - * - * --- - * ``` - * - * The `loadPreambleFromMarkdown()` parser converts this markdown into the - * same `SectionBlock[]` array that was previously authored inline: - * - `## Heading` -> `HeadingBlock { level: 2, text: '...' }` - * - Paragraphs -> `ParagraphBlock { text: '...' }` - * - `\`\`\`mermaid ... \`\`\`` -> `MermaidBlock { content: '...' }` - * - `\`\`\`bash ... \`\`\`` -> `CodeBlock { language: 'bash', content: '...' }` - * - `| col | col |` tables -> `TableBlock { columns: [...], rows: [...] }` - * - `- [ ] item` -> `ListBlock { items: ['[ ] item', ...] }` - * - `---` -> `SeparatorBlock` - */ - -export function _sessionGuidePreambleDesignStub(): never { - throw new Error('ProceduralGuideCodec not yet implemented - roadmap pattern'); -} diff --git a/src/cli/cli-schema.ts b/src/cli/cli-schema.ts index 3cb6d269..d008fbe6 100644 --- a/src/cli/cli-schema.ts +++ b/src/cli/cli-schema.ts @@ -2,7 +2,6 @@ * @architect * @architect-pattern CLISchema * @architect-status completed - * @architect-unlock-reason:Add-recipe-and-narrative-fields-for-CliRecipeCodec * @architect-implements CliReferenceGeneration * @architect-arch-context cli * @architect-arch-layer domain diff --git a/src/generators/built-in/cli-recipe-generator.ts b/src/generators/built-in/cli-recipe-generator.ts index d2e6caf3..00d1ab5f 100644 --- a/src/generators/built-in/cli-recipe-generator.ts +++ b/src/generators/built-in/cli-recipe-generator.ts @@ -1,7 +1,6 @@ /** * @architect * @architect-pattern CliRecipeGenerator - * @architect-implements CliRecipeCodec * @architect-arch-context generator * @architect-arch-layer application * @architect-product-area:Generation diff --git a/tests/features/api/architecture-queries/arch-queries.feature b/tests/features/api/architecture-queries/arch-queries.feature index 85cbd357..8ebde1d5 100644 --- a/tests/features/api/architecture-queries/arch-queries.feature +++ b/tests/features/api/architecture-queries/arch-queries.feature @@ -1,9 +1,28 @@ @architect -@architect-pattern:ArchQueriesTest -@architect-status:active +@architect-pattern:DataAPIArchitectureQueries +@architect-status:completed +@architect-unlock-reason:Value-transfer-from-spec +@architect-phase:25b +@architect-depends-on:DataAPIOutputShaping @architect-product-area:DataAPI Feature: Architecture Queries - Neighborhood, Comparison, Tags, Sources + **Problem:** + The current `arch` subcommand provides basic queries (roles, context, layer, graph) + but lacks deeper analysis needed for design sessions: pattern neighborhoods (what's + directly connected), cross-context comparison, annotation coverage gaps, and + taxonomy discovery. Agents exploring architecture must make multiple queries and + mentally assemble the picture, wasting context tokens. + + **Solution:** + Extend the `arch` subcommand and add new discovery commands: + 1. `arch neighborhood ` shows 1-hop relationships (direct uses/usedBy) + 2. `arch compare ` shows shared deps and integration points + 3. `arch coverage` reports annotation completeness with gaps + 4. `tags` lists all tags in use with counts + 5. `sources` shows file inventory by type + 6. `unannotated [--path glob]` finds files without the opt-in marker + Background: Deliverables Given the following deliverables: | Deliverable | Status | Location | Tests | Test Type | diff --git a/tests/features/api/context-assembly/context-assembler.feature b/tests/features/api/context-assembly/context-assembler.feature index eed9ae20..436d26d3 100644 --- a/tests/features/api/context-assembly/context-assembler.feature +++ b/tests/features/api/context-assembly/context-assembler.feature @@ -1,9 +1,31 @@ @architect -@architect-pattern:ContextAssemblerTests -@architect-status:active +@architect-pattern:DataAPIContextAssembly +@architect-status:completed +@architect-unlock-reason:Value-transfer-from-spec +@architect-phase:25b +@architect-depends-on:DataAPIOutputShaping,DataAPIStubIntegration @architect-product-area:DataAPI Feature: Context Assembler - Session-Oriented Context Bundle Builder + **Problem:** + Starting a Claude Code design or implementation session requires assembling + 30-100KB of curated, multi-source context from hundreds of annotated files. + Today this requires either manual context compilation by the user or 5-10 + explore agents burning context and time. The Architect pipeline already + has rich data (PatternGraph with archIndex, relationshipIndex, byPhase, + byStatus views) but no command combines data from multiple indexes around + a focal pattern into a compact, session-oriented context bundle. + + **Solution:** + Add context assembly subcommands that answer "what should I read next?" + rather than "what data exists?": + 1. `context ` assembles metadata + spec path + stub paths + + dependency chain + related patterns into ~1.5KB of file paths + 2. `files ` returns only file paths organized by relevance + 3. `dep-tree ` walks dependency chains recursively with status + 4. `overview` gives executive project summary + 5. Session type tailoring via `--session planning|design|implement` + Tests for assembleContext(), buildDepTree(), buildFileReadingList(), and buildOverview() pure functions that operate on PatternGraph. diff --git a/tests/features/api/context-assembly/context-formatter.feature b/tests/features/api/context-assembly/context-formatter.feature index a29b31a5..80b5bf26 100644 --- a/tests/features/api/context-assembly/context-formatter.feature +++ b/tests/features/api/context-assembly/context-formatter.feature @@ -1,6 +1,7 @@ @architect @architect-pattern:ContextFormatterTests @architect-status:active +@architect-implements:DataAPIContextAssembly @architect-product-area:DataAPI Feature: Context Formatter - Plain Text Rendering diff --git a/tests/features/api/output-shaping/fuzzy-match.feature b/tests/features/api/output-shaping/fuzzy-match.feature index c2e60a6f..5b9f35d0 100644 --- a/tests/features/api/output-shaping/fuzzy-match.feature +++ b/tests/features/api/output-shaping/fuzzy-match.feature @@ -1,5 +1,6 @@ @architect @architect-pattern:FuzzyMatchTests +@architect-implements:DataAPIOutputShaping @architect-status:active @architect-product-area:DataAPI Feature: Fuzzy Pattern Matching diff --git a/tests/features/api/output-shaping/output-pipeline.feature b/tests/features/api/output-shaping/output-pipeline.feature index 3efc1c9c..1cc3d187 100644 --- a/tests/features/api/output-shaping/output-pipeline.feature +++ b/tests/features/api/output-shaping/output-pipeline.feature @@ -1,6 +1,8 @@ @architect -@architect-pattern:OutputPipelineTests -@architect-status:active +@architect-pattern:DataAPIOutputShaping +@architect-status:completed +@architect-unlock-reason:Value-transfer-from-spec +@architect-phase:25a @architect-product-area:DataAPI Feature: Output Modifier Pipeline diff --git a/tests/features/api/output-shaping/pattern-helpers.feature b/tests/features/api/output-shaping/pattern-helpers.feature index f74c690a..3289481d 100644 --- a/tests/features/api/output-shaping/pattern-helpers.feature +++ b/tests/features/api/output-shaping/pattern-helpers.feature @@ -1,5 +1,6 @@ @architect @architect-pattern:PatternHelpersTests +@architect-implements:DataAPIOutputShaping @architect-status:active @architect-phase:25a @architect-product-area:DataAPI diff --git a/tests/features/api/output-shaping/summarize.feature b/tests/features/api/output-shaping/summarize.feature index c7872a94..838bb8bd 100644 --- a/tests/features/api/output-shaping/summarize.feature +++ b/tests/features/api/output-shaping/summarize.feature @@ -1,5 +1,6 @@ @architect @architect-pattern:PatternSummarizeTests +@architect-implements:DataAPIOutputShaping @architect-status:active @architect-product-area:DataAPI Feature: Pattern Summarization diff --git a/tests/features/api/pattern-graph-api.feature b/tests/features/api/pattern-graph-api.feature index e0eb2f38..266ddfc9 100644 --- a/tests/features/api/pattern-graph-api.feature +++ b/tests/features/api/pattern-graph-api.feature @@ -3,7 +3,8 @@ @architect-status:completed @architect-unlock-reason:Retroactive-completion-during-rebrand @behavior @pattern-graph-api -@architect-pattern:PatternGraphAPITesting +@architect-pattern:PatternGraphAPIRelationshipQueries +@architect-phase:24 @architect-product-area:DataAPI Feature: Pattern Graph API Programmatic interface for querying the pattern graph and delivery process state. diff --git a/tests/features/api/session-support/handoff-generator.feature b/tests/features/api/session-support/handoff-generator.feature index 5ffb8248..26645a09 100644 --- a/tests/features/api/session-support/handoff-generator.feature +++ b/tests/features/api/session-support/handoff-generator.feature @@ -1,5 +1,6 @@ @architect @architect-pattern:HandoffGeneratorTests +@architect-implements:DataAPIDesignSessionSupport @architect-status:completed @architect-unlock-reason:Retroactive-completion-during-rebrand @architect-product-area:DataAPI diff --git a/tests/features/api/session-support/scope-validator.feature b/tests/features/api/session-support/scope-validator.feature index 19232995..c5bb2cc7 100644 --- a/tests/features/api/session-support/scope-validator.feature +++ b/tests/features/api/session-support/scope-validator.feature @@ -1,15 +1,23 @@ @architect -@architect-pattern:ScopeValidatorTests +@architect-pattern:DataAPIDesignSessionSupport @architect-status:completed @architect-unlock-reason:Retroactive-completion-during-rebrand +@architect-phase:25c @architect-product-area:DataAPI +@architect-depends-on:DataAPIContextAssembly,DataAPIStubIntegration Feature: Scope Validator - Pre-flight Session Readiness Checks **Problem:** - Starting an implementation or design session without checking prerequisites - wastes time when blockers are discovered mid-session. + Starting a design or implementation session requires manually compiling + elaborate context prompts. This manual compilation takes 10-15 minutes per + session start and is error-prone (missing dependencies, stale context). + Starting without checking prerequisites wastes time when blockers are + discovered mid-session. **Solution:** + Session workflow commands automate two critical session moments: + 1. **Pre-flight check:** `scope-validate ` verifies implementation readiness + 2. **Session end:** `handoff [--pattern X]` generates handoff documentation ScopeValidator runs composable checks and aggregates results into a verdict (ready, blocked, or warnings) before a session starts. diff --git a/tests/features/api/stub-integration/stub-resolver.feature b/tests/features/api/stub-integration/stub-resolver.feature index 18814332..0daa17ae 100644 --- a/tests/features/api/stub-integration/stub-resolver.feature +++ b/tests/features/api/stub-integration/stub-resolver.feature @@ -1,6 +1,8 @@ @architect -@architect-pattern:StubResolverTests -@architect-status:active +@architect-pattern:DataAPIStubIntegration +@architect-status:completed +@architect-unlock-reason:Value-transfer-from-spec +@architect-phase:25a @architect-product-area:DataAPI Feature: Stub Resolver - Design Stub Discovery and Resolution diff --git a/tests/features/api/stub-integration/taxonomy-tags.feature b/tests/features/api/stub-integration/taxonomy-tags.feature index d3e54ab6..01583ac7 100644 --- a/tests/features/api/stub-integration/taxonomy-tags.feature +++ b/tests/features/api/stub-integration/taxonomy-tags.feature @@ -1,5 +1,6 @@ @architect @architect-pattern:StubTaxonomyTagTests +@architect-implements:DataAPIStubIntegration @architect-status:active @architect-product-area:DataAPI Feature: Stub Integration Taxonomy Tags diff --git a/tests/features/behavior/architecture-diagrams/arch-index.feature b/tests/features/behavior/architecture-diagrams/arch-index.feature index adc8abe9..35626b1e 100644 --- a/tests/features/behavior/architecture-diagrams/arch-index.feature +++ b/tests/features/behavior/architecture-diagrams/arch-index.feature @@ -2,7 +2,7 @@ @architect-pattern:ArchIndexDataset @architect-status:completed @architect-unlock-reason:Retroactive-completion-during-rebrand -@architect-implements:ArchitectureDiagramGeneration +@architect-implements:ArchitectureDiagramAdvanced @architect-product-area:Generation @architecture Feature: Architecture Index in PatternGraph diff --git a/tests/features/behavior/architecture-diagrams/arch-tag-extraction.feature b/tests/features/behavior/architecture-diagrams/arch-tag-extraction.feature index 0ed38dc9..917ff935 100644 --- a/tests/features/behavior/architecture-diagrams/arch-tag-extraction.feature +++ b/tests/features/behavior/architecture-diagrams/arch-tag-extraction.feature @@ -2,7 +2,7 @@ @architect-pattern:ArchTagExtraction @architect-status:completed @architect-unlock-reason:Retroactive-completion-during-rebrand -@architect-implements:ArchitectureDiagramGeneration +@architect-implements:ArchitectureDiagramCore @architect-product-area:Generation @architecture Feature: Architecture Tag Extraction diff --git a/tests/features/behavior/architecture-diagrams/component-diagram.feature b/tests/features/behavior/architecture-diagrams/component-diagram.feature index 1720c4e2..6a6becf5 100644 --- a/tests/features/behavior/architecture-diagrams/component-diagram.feature +++ b/tests/features/behavior/architecture-diagrams/component-diagram.feature @@ -1,15 +1,24 @@ @architect -@architect-pattern:ComponentDiagramGeneration +@architect-pattern:ArchitectureDiagramCore @architect-status:completed @architect-unlock-reason:Retroactive-completion-during-rebrand -@architect-implements:ArchitectureDiagramGeneration +@architect-phase:23 @architect-product-area:Generation @architecture -Feature: Component Diagram Generation +Feature: Architecture Diagram Generation - Core (Component Diagrams) - As a documentation generator - I want to generate component diagrams from architecture metadata - So that system architecture is automatically visualized with bounded context subgraphs + **Problem:** Architecture documentation requires manually maintaining mermaid diagrams + that duplicate information already encoded in source code. When code changes, + diagrams become stale. Manual sync is error-prone and time-consuming. + + **Solution:** Generate architecture diagrams automatically from source code annotations + using dedicated arch-tags for precise control. Three tags classify components: + - arch-role: Component type (preset-configurable: service, handler, repository, etc.) + - arch-context: Bounded context for subgraph grouping + - arch-layer: Architectural layer (domain, application, infrastructure) + + Component diagrams group patterns by bounded context into Mermaid subgraphs, + with relationship arrows using UML-inspired styles. Background: Dataset with architecture metadata Given an architecture codec with default options diff --git a/tests/features/behavior/architecture-diagrams/generator-registration.feature b/tests/features/behavior/architecture-diagrams/generator-registration.feature index 6d471a10..377ef449 100644 --- a/tests/features/behavior/architecture-diagrams/generator-registration.feature +++ b/tests/features/behavior/architecture-diagrams/generator-registration.feature @@ -2,7 +2,7 @@ @architect-pattern:ArchGeneratorRegistration @architect-status:completed @architect-unlock-reason:Retroactive-completion-during-rebrand -@architect-implements:ArchitectureDiagramGeneration +@architect-implements:ArchitectureDiagramCore @architect-product-area:Generation @architecture Feature: Architecture Generator Registration diff --git a/tests/features/behavior/architecture-diagrams/layered-diagram.feature b/tests/features/behavior/architecture-diagrams/layered-diagram.feature index def17d8c..366b0c4f 100644 --- a/tests/features/behavior/architecture-diagrams/layered-diagram.feature +++ b/tests/features/behavior/architecture-diagrams/layered-diagram.feature @@ -1,12 +1,23 @@ @architect -@architect-pattern:LayeredDiagramGeneration +@architect-pattern:ArchitectureDiagramAdvanced @architect-status:completed @architect-unlock-reason:Retroactive-completion-during-rebrand -@architect-implements:ArchitectureDiagramGeneration +@architect-phase:23 @architect-product-area:Generation @architecture Feature: Layered Architecture Diagram Generation + **Problem:** Core diagram generation (see ArchitectureDiagramCore) produces + component-level diagrams from `arch-*` tags. However, large codebases need + additional visualization modes: layered views grouping patterns by architectural + layer, CLI-integrated generation via the generator registry, and sequence + diagrams showing runtime interaction flows between components. + + **Solution:** Extend the architecture diagram system with advanced capabilities: + - Layered diagrams that group patterns by `@architect-arch-layer` (domain, application, infrastructure) + - Generator registry integration for CLI-driven generation via `pnpm docs:architecture` + - Sequence diagram support for modeling runtime interactions between components + As a documentation generator I want to generate layered architecture diagrams from metadata So that system architecture is visualized by layer hierarchy diff --git a/tests/features/behavior/cli/cli-reference.feature b/tests/features/behavior/cli/cli-reference.feature index f32566d0..cae77cef 100644 --- a/tests/features/behavior/cli/cli-reference.feature +++ b/tests/features/behavior/cli/cli-reference.feature @@ -1,11 +1,23 @@ @architect -@architect-pattern:PatternGraphCliReferenceTests -@architect-implements:CliReferenceGeneration +@architect-pattern:CliReferenceGeneration @architect-status:completed @architect-unlock-reason:Retroactive-completion-during-rebrand -@architect-product-area:DataAPI +@architect-phase:43 +@architect-product-area:Generation @behavior @cli @cli-reference -Feature: Pattern Graph CLI Reference Generation +Feature: CLI.md Hybrid Generation + + **Problem:** + `docs/CLI.md` contains three reference tables that manually mirror CLI definitions + in source code. When CLI options change, these tables require manual updates and + risk falling out of sync with the implementation. The `showHelp()` function is a + hardcoded third copy of the same information, creating three-way drift risk. + + **Solution:** + A declarative CLI schema (`src/cli/cli-schema.ts`) serves as the single source of + truth. A standalone `CliReferenceGenerator` reads this schema and produces a + complete generated reference file at `docs-live/reference/CLI-REFERENCE.md`. + The `showHelp()` function consumes the same schema, eliminating three-way sync. Verifies that the declarative CLI schema drives reference table generation and stays in sync with the parser implementation. diff --git a/tests/features/behavior/codecs/composite-codec.feature b/tests/features/behavior/codecs/composite-codec.feature index a882cbb7..739bfb1f 100644 --- a/tests/features/behavior/codecs/composite-codec.feature +++ b/tests/features/behavior/codecs/composite-codec.feature @@ -1,11 +1,21 @@ @architect -@architect-pattern:CompositeCodecTesting +@architect-pattern:CrossCuttingDocumentInclusion @architect-status:completed @architect-unlock-reason:Retroactive-completion-during-rebrand @architect-implements:ReferenceDocShowcase +@architect-phase:32 +@architect-depends-on:DeclarationLevelShapeTagging,ReferenceDocShowcase @architect-product-area:Generation Feature: Composite Codec + Content-to-document is a many-to-many relationship. A type definition + may be relevant to an architecture overview, a configuration guide, and + an AI context section. The `architect-include` tag enables cross-cutting + document inclusion by routing content to named documents at the source, + next to the code, without requiring document configs to enumerate every + item by name. The include tag is purely additive -- it never removes + content that would be selected by existing filters. + Assembles reference documents from multiple codec outputs by concatenating RenderableDocument sections. Enables building documents composed from any combination of existing codecs. diff --git a/tests/features/behavior/codecs/generated-doc-quality.feature b/tests/features/behavior/codecs/generated-doc-quality.feature index 27b3b2bc..62a7d558 100644 --- a/tests/features/behavior/codecs/generated-doc-quality.feature +++ b/tests/features/behavior/codecs/generated-doc-quality.feature @@ -1,15 +1,29 @@ @architect @behavior @reference-codec -@architect-pattern:GeneratedDocQualityTests +@architect-pattern:GeneratedDocQuality @architect-status:completed @architect-unlock-reason:Retroactive-completion-during-rebrand -@architect-implements:GeneratedDocQuality +@architect-phase:38 @architect-product-area:Generation Feature: Generated Documentation Quality Improvements - Tests for the four quality fixes in GeneratedDocQuality (Phase 38): - duplicate table removal, Generation compact enrichment, types-first - ordering, and product area TOC generation. + **Problem:** + Four quality issues reduce the usefulness of generated docs for both Claude agents + and human developers: (1) REFERENCE-SAMPLE.md re-renders canonical value tables + twice — 500+ duplicate lines with zero information gain; (2) the Generation product + area compact file is 1.4 KB for a 233 KB area — critically undersized; (3) + ARCHITECTURE-TYPES.md opens with orchestrator prose instead of type definitions, + burying the content Claude most needs; (4) product area docs (GENERATION.md 233 KB, + DATA-API.md 102 KB) have no navigation TOC, making browser traversal impractical. + + **Solution:** + Fix the reference codec's behavior-specs renderer to stop duplicating convention + tables. Enrich the Generation product area compact template. Reorder + ARCHITECTURE-TYPES.md to lead with type definitions. Add a generated TOC block + to product area doc headers. + + Tests for the four quality fixes: duplicate table removal, Generation compact + enrichment, types-first ordering, and product area TOC generation. Background: Given a reference codec test context diff --git a/tests/features/behavior/codecs/reference-codec-core.feature b/tests/features/behavior/codecs/reference-codec-core.feature index cffb9ac3..34d11890 100644 --- a/tests/features/behavior/codecs/reference-codec-core.feature +++ b/tests/features/behavior/codecs/reference-codec-core.feature @@ -1,12 +1,26 @@ @architect @behavior @reference-codec -@architect-pattern:ReferenceCodecCoreTesting +@architect-pattern:ReferenceDocShowcase @architect-status:completed @architect-unlock-reason:'Split-from-original' -@architect-implements:ReferenceDocShowcase +@architect-phase:30 +@architect-depends-on:CodecDrivenReferenceGeneration,ScopedArchitecturalView,ShapeExtraction @architect-product-area:Generation Feature: Reference Codec - Core Behavior + **Problem:** + The Reference Generation Sample document exercises a small fraction of the + reference codec's capabilities: 2 convention rules, 1 flowchart diagram, + 2 shapes from a single file, and 1 shallow behavior pattern. Of the 9 + renderable block types (heading, paragraph, separator, table, list, code, + mermaid, collapsible, link-out), only 6 are used. + + **Solution:** + Expand the reference sample into a comprehensive showcase that exercises every + content block type across all three detail levels. The sample document serves + as the integration test: if REFERENCE-SAMPLE.md renders every block type + correctly at every detail level, the codec system works end-to-end. + Parameterized codec factory that creates reference document codecs from configuration objects. Core behavior including empty datasets, conventions, detail levels, shapes, composition, and mermaid blocks. diff --git a/tests/features/behavior/codecs/reference-codec-diagram-types.feature b/tests/features/behavior/codecs/reference-codec-diagram-types.feature index 3fd44f2e..693b137e 100644 --- a/tests/features/behavior/codecs/reference-codec-diagram-types.feature +++ b/tests/features/behavior/codecs/reference-codec-diagram-types.feature @@ -1,12 +1,26 @@ @architect @behavior @reference-codec -@architect-pattern:ReferenceCodecDiagramTypeTesting +@architect-pattern:ScopedArchitecturalView @architect-status:completed @architect-unlock-reason:'Split-from-original' @architect-implements:ReferenceDocShowcase +@architect-phase:28 +@architect-depends-on:ArchitectureDiagramGeneration,ShapeExtraction @architect-product-area:Generation Feature: Reference Codec - Diagram Type Rendering + **Problem:** + Full architecture diagrams show every annotated pattern in the project. For focused + use cases -- design session context, PR descriptions, CLAUDE.md module sections -- + developers need views scoped to a small set of relevant patterns with their immediate + neighbors. Manually curating diagram content defeats the code-first principle. + + **Solution:** + A `DiagramScope` filter interface that selects patterns by three dimensions + (`archContext`, `archView`, or explicit pattern names), automatically discovers + neighbor patterns via relationship edges, and renders scoped Mermaid diagrams + with subgraph grouping and distinct neighbor styling. + Diagram type controls Mermaid output format including flowchart, sequenceDiagram, stateDiagram-v2, C4Context, and classDiagram. Edge labels and custom node shapes enrich diagram readability. diff --git a/tests/features/behavior/codecs/reference-generators.feature b/tests/features/behavior/codecs/reference-generators.feature index 0af551af..32dfcb2d 100644 --- a/tests/features/behavior/codecs/reference-generators.feature +++ b/tests/features/behavior/codecs/reference-generators.feature @@ -1,12 +1,26 @@ @architect @behavior @reference-generators -@architect-pattern:ReferenceGeneratorTesting +@architect-pattern:CodecDrivenReferenceGeneration @architect-status:completed @architect-unlock-reason:Retroactive-completion-during-rebrand @architect-implements:ReferenceDocShowcase +@architect-phase:27 +@architect-depends-on:DocGenerationProofOfConcept,ScopedArchitecturalView @architect-product-area:Generation Feature: Reference Document Generator Registration + **Problem:** + Each reference document (Process Guard, Taxonomy, Validation, etc.) required a + hand-coded recipe feature that duplicated codec setup, rendering, and file output + logic. Adding a new reference document meant creating a new feature file, a new + codec wrapper, and a new generator class -- all following the same pattern. + + **Solution:** + A single `createReferenceCodec` factory driven by `ReferenceDocConfig` objects. + Each config declares four content sources -- convention tags, diagram scopes, + shape source globs, and behavior categories -- that compose automatically in + AD-5 order. + Registers reference document generators from project config. Configs with `productArea` set are routed to a "product-area-docs" meta-generator; configs without `productArea` go to "reference-docs". Each config also diff --git a/tests/features/behavior/pattern-relationships/implements-tag.feature b/tests/features/behavior/pattern-relationships/implements-tag.feature index c948c809..75620dad 100644 --- a/tests/features/behavior/pattern-relationships/implements-tag.feature +++ b/tests/features/behavior/pattern-relationships/implements-tag.feature @@ -1,10 +1,21 @@ @architect -@architect-pattern:ImplementsTagProcessing +@architect-pattern:PatternRelationshipModel @architect-status:completed @architect-unlock-reason:Retroactive-completion-during-rebrand -@architect-implements:PatternRelationshipModel +@architect-phase:99 @architect-product-area:Annotation -Feature: Implements Tag Extraction and Processing +Feature: Pattern Relationship Model — Implements Tag Extraction and Processing + + **Problem:** The delivery process lacks a comprehensive relationship model between artifacts. + Code files, roadmap specs, executable specs, and patterns exist but their relationships + are implicit or limited to basic dependency tracking (`uses`, `depends-on`). + + **Solution:** Implement a relationship taxonomy inspired by UML/TML modeling practices: + - **Realization** (`implements`) - Code realizes a pattern specification + - **Generalization** (`extends`) - Pattern extends another pattern's capabilities + - **Dependency** (`uses`, `used-by`) - Technical dependencies between patterns + - **Composition** (`parent`, `level`) - Hierarchical pattern organization + - **Traceability** (`roadmap-spec`, `executable-specs`) - Cross-tier linking Tests for the @architect-implements tag which links implementation files to their corresponding roadmap pattern specifications. diff --git a/tests/features/cli/data-api-help.feature b/tests/features/cli/data-api-help.feature index 1260dda6..58e33832 100644 --- a/tests/features/cli/data-api-help.feature +++ b/tests/features/cli/data-api-help.feature @@ -1,10 +1,28 @@ @architect -@architect-pattern:PatternGraphCliHelp -@architect-implements:DataAPICLIErgonomics -@architect-status:active +@architect-pattern:DataAPICLIErgonomics +@architect-status:completed +@architect-unlock-reason:Value-transfer-from-spec +@architect-phase:25d @architect-product-area:DataAPI @cli @pattern-graph-cli @help -Feature: Pattern Graph CLI - Per-Subcommand Help +Feature: Data API CLI Ergonomics - Performance and Interactive Mode + **Problem:** + The pattern-graph-cli CLI runs the full pipeline (scan, extract, transform) on every + invocation, taking 2-5 seconds. During design sessions with 10-20 queries, this + adds up to 1-2 minutes of waiting. There is no way to keep the pipeline loaded + between queries. Per-subcommand help is missing -- `pattern-graph-cli context --help` + does not work. FSM-only queries (like `isValidTransition`) run the full pipeline + even though FSM rules are static. + + **Solution:** + Add performance and ergonomic improvements: + 1. Pipeline caching -- Cache PatternGraph to temp file with mtime invalidation + 2. REPL mode -- `pattern-graph-cli repl` keeps pipeline loaded for interactive queries + 3. FSM short-circuit -- FSM queries skip the scan pipeline entirely + 4. Per-subcommand help -- `pattern-graph-cli --help` with examples + 5. Dry-run mode -- `--dry-run` shows what would be scanned without running + 6. Validation summary -- Include pipeline health in response metadata + Per-subcommand help displays usage, flags, and examples for individual subcommands. Background: diff --git a/tests/features/cli/pattern-graph-cli-core.feature b/tests/features/cli/pattern-graph-cli-core.feature index c2ea3574..fbed0a4d 100644 --- a/tests/features/cli/pattern-graph-cli-core.feature +++ b/tests/features/cli/pattern-graph-cli-core.feature @@ -1,11 +1,24 @@ @architect -@architect-pattern:PatternGraphCliCore -@architect-implements:PatternGraphAPICLI +@architect-pattern:PatternGraphAPICLI @architect-status:completed @architect-unlock-reason:'Split-from-original' +@architect-phase:24 @architect-product-area:DataAPI @cli @pattern-graph-cli Feature: Pattern Graph CLI - Core Infrastructure + + **Problem:** + The PatternGraphAPI provides 27 typed query methods for efficient state queries, but + Claude Code sessions cannot use it directly: + - Import paths require built packages with correct ESM resolution + - No CLI command exposes the API for shell invocation + - Current workaround requires regenerating markdown docs and reading them + - Documentation claims API is "directly usable" but practical usage is blocked + + **Solution:** + Add a CLI command `pnpm architect:query` that exposes key PatternGraphAPI methods + with JSON and text output formats, enabling direct programmatic access from AI sessions. + Core CLI infrastructure: help, version, input validation, status, query, pattern, arch basics, missing args, edge cases. Background: diff --git a/tests/features/cli/validate-patterns.feature b/tests/features/cli/validate-patterns.feature index 6d975c71..3302f8c9 100644 --- a/tests/features/cli/validate-patterns.feature +++ b/tests/features/cli/validate-patterns.feature @@ -1,11 +1,26 @@ @architect -@architect-pattern:ValidatePatternsCli +@architect-pattern:ValidatorReadModelConsolidation @architect-status:completed @architect-unlock-reason:Retroactive-completion-during-rebrand -@architect-product-area:DataAPI +@architect-phase:100 +@architect-product-area:Validation +@architect-depends-on:ADR006SingleReadModelArchitecture @architect-implements:CliBehaviorTesting @cli @validate-patterns -Feature: validate-patterns CLI +Feature: Validator Read Model Consolidation — validate-patterns CLI + + **Problem:** + `validate-patterns.ts` was the only feature consumer that bypassed the + PatternGraph. It wired its own mini-pipeline (scan + extract + ad-hoc + matching), created a lossy local type (`GherkinPatternInfo`) that discarded + relationship data, and failed to resolve `@architect-implements` links. + + **Solution:** + Refactored `validate-patterns.ts` to consume the PatternGraph as its + data source for cross-source validation. The validator became a feature + consumer like codecs and the PatternGraphAPI — querying pre-computed + views and the relationship index instead of building its own maps. + Command-line interface for cross-validating TypeScript patterns vs Gherkin feature files. Background: diff --git a/tests/features/config/config-loader.feature b/tests/features/config/config-loader.feature index 4342b2d8..01c1aa23 100644 --- a/tests/features/config/config-loader.feature +++ b/tests/features/config/config-loader.feature @@ -1,8 +1,10 @@ @architect -@architect-pattern:ConfigLoaderTesting +@architect-pattern:ConfigBasedWorkflowDefinition @architect-implements:ConfigLoader @architect-status:completed @architect-unlock-reason:Retroactive-completion-during-rebrand +@architect-phase:99 +@architect-depends-on:MvpWorkflowImplementation @architect-product-area:Configuration @behavior @config Feature: Config Loader - TypeScript Configuration Discovery @@ -11,14 +13,22 @@ Feature: Config Loader - TypeScript Configuration Discovery taxonomy customization. **Problem:** - - Different directories need different taxonomies - - Package-level config should override repo-level - - CLI tools need automatic config discovery + Every `pnpm architect:query` and `pnpm docs:*` invocation prints: + `Failed to load default workflow (6-phase-standard): Workflow file not found` + + The `loadDefaultWorkflow()` function resolves to `catalogue/workflows/` + which does not exist. The directory was deleted during monorepo extraction. + The system already degrades gracefully (workflow = undefined), but the + warning is noise for both human CLI use and future hook consumers (HUD). **Solution:** - - Walk up directories looking for `architect.config.ts` - - Stop at repo root (.git marker) - - Fall back to libar-generic preset (3 categories) if no config found + Inline the default workflow as a constant in `workflow-loader.ts`, built + from canonical taxonomy values. Make `loadDefaultWorkflow()` synchronous. + Preserve `loadWorkflowFromPath()` for custom `--workflow ` overrides. + + Config discovery walks up directories looking for `architect.config.ts`, + stops at repo root (.git marker), and falls back to libar-generic preset + (3 categories) if no config found. Background: Given a config loader test context with temp directory diff --git a/tests/features/doc-generation/architecture-doc-refactoring.feature b/tests/features/doc-generation/architecture-doc-refactoring.feature index c0b98b70..91f2672d 100644 --- a/tests/features/doc-generation/architecture-doc-refactoring.feature +++ b/tests/features/doc-generation/architecture-doc-refactoring.feature @@ -1,10 +1,27 @@ @architect -@architect-pattern:ArchitectureDocRefactoringTesting -@architect-status:active +@architect-pattern:ArchitectureDocRefactoring +@architect-status:completed +@architect-unlock-reason:Value-transfer-from-spec +@architect-phase:36 @architect-product-area:Generation @integration Feature: Architecture Doc Refactoring Coverage + **Problem:** + ARCHITECTURE.md is 1,287 lines of manually-maintained documentation covering 14 + sections. The codec system already generates much of this content (codec references + via convention tags, PatternGraph types via shape extraction, pipeline diagrams + via architecture annotations). Maintaining parallel manual and generated versions + creates drift and duplication. + + **Solution:** + Decompose ARCHITECTURE.md into a curated architecture overview (~320 lines of + editorial narrative optimized for Claude as primary consumer) that links to generated + reference documents for detailed content. Phase 2 established the convention-tag + pattern by extracting the 368-line Available Codecs section. Phase 4 applies + product area absorption, generated shapes, architecture diagram references, and + usefulness-driven editorial trimming to the remaining consolidatable content. + Validates that ARCHITECTURE.md retains its full reference content and that generated documents in docs-live/ coexist alongside it, covering equivalent content from annotated sources. diff --git a/tests/features/doc-generation/index-codec.feature b/tests/features/doc-generation/index-codec.feature index 9f45e6ee..e6ecf8b2 100644 --- a/tests/features/doc-generation/index-codec.feature +++ b/tests/features/doc-generation/index-codec.feature @@ -1,11 +1,29 @@ @architect -@architect-pattern:IndexCodecTesting -@architect-implements:IndexCodec +@architect-pattern:EnhancedIndexGeneration @architect-status:completed @architect-unlock-reason:Retroactive-completion-regression-safety-net +@architect-phase:35 @architect-product-area:Generation Feature: Index Document Codec + **Problem:** + `docs/INDEX.md` (354 lines) is a manually maintained navigation hub with audience-based + reading orders, per-document detailed TOC, document roles matrix, quick navigation + table, and key concepts glossary. The auto-generated `docs-live/INDEX.md` (112 lines) + is a simple file listing with regeneration commands. It lacks audience navigation, + document role context, pattern statistics, and phase progress summaries. When documents + are added, renamed, or restructured, the manual index drifts from the actual doc set. + + **Solution:** + Create an `IndexCodec` that generates a comprehensive navigation hub by composing + auto-generated statistics from PatternGraph pre-computed views with editorial + navigation content via the preamble mechanism. The codec produces document listings, + pattern counts per product area, and phase progress from `byCategory`, `byPhase`, + `byProductArea`, and `byStatus` views. Audience reading paths, the document roles + matrix, and the quick finder table use `ReferenceDocConfig.preamble` as manually + authored `SectionBlock[]`. The generated output replaces both `docs/INDEX.md` and + `docs-live/INDEX.md` with a single unified navigation document. + Validates the Index Codec that transforms PatternGraph into a RenderableDocument for the main documentation navigation index (INDEX.md). diff --git a/tests/features/doc-generation/poc-integration.feature b/tests/features/doc-generation/poc-integration.feature index aecbc92f..a173fd5f 100644 --- a/tests/features/doc-generation/poc-integration.feature +++ b/tests/features/doc-generation/poc-integration.feature @@ -1,10 +1,16 @@ @architect -@architect-pattern:PocIntegration +@architect-pattern:DocGenerationProofOfConcept @architect-status:completed @architect-unlock-reason:Retroactive-completion-during-rebrand +@architect-phase:27 +@architect-depends-on:ShapeExtraction @architect-product-area:Generation Feature: Documentation Generation POC Integration + This decision establishes the pattern for generating technical documentation + from annotated source files. It serves as both the DECISION (why/how) and + the PROOF OF CONCEPT (demonstrating the pattern works). + End-to-end integration tests that exercise the full documentation generation pipeline using the actual POC decision document and real source files. @@ -26,7 +32,7 @@ Feature: Documentation Generation POC Integration @acceptance-criteria @integration Scenario: Load actual POC decision document - Given the POC decision document at "architect/specs/doc-generation-proof-of-concept.feature" + Given the POC decision document at "tests/fixtures/doc-generation/poc-decision-document.feature" When parsing the decision document Then parsed content should have correct structure @@ -111,7 +117,7 @@ Feature: Documentation Generation POC Integration @acceptance-criteria @integration Scenario: Extract Scenario Outline Examples from process-guard-linter.feature Given the source mapper with base directory at project root - When extracting from "architect/specs/process-guard-linter.feature" with method "Scenario Outline Examples" + When extracting from "tests/features/validation/process-guard.feature" with method "Scenario Outline Examples" Then extracted content should contain protection level table # ============================================================================ diff --git a/tests/features/doc-generation/robustness-integration.feature b/tests/features/doc-generation/robustness-integration.feature index 9315e5d3..004833d4 100644 --- a/tests/features/doc-generation/robustness-integration.feature +++ b/tests/features/doc-generation/robustness-integration.feature @@ -1,9 +1,15 @@ @architect -@architect-pattern:RobustnessIntegration +@architect-pattern:UniversalDocGeneratorRobustness @architect-status:completed @architect-unlock-reason:Retroactive-completion-during-rebrand +@architect-phase:28 @architect-product-area:Generation -Feature: Robustness Integration +@architect-depends-on:DocGenerationProofOfConcept +Feature: Universal Document Generator - Robustness Integration + + This feature transforms the PoC document generator into a production-ready + universal generator capable of operating at monorepo scale (~210 manual docs + to be replaced across the convex-event-sourcing repository). **Context:** Document generation pipeline needs validation, deduplication, and warning collection to work together correctly for production use. diff --git a/tests/features/doc-generation/validation-rules-codec.feature b/tests/features/doc-generation/validation-rules-codec.feature index ee3c4ad6..5ff68d48 100644 --- a/tests/features/doc-generation/validation-rules-codec.feature +++ b/tests/features/doc-generation/validation-rules-codec.feature @@ -1,11 +1,26 @@ @architect -@architect-pattern:ValidationRulesCodecTesting +@architect-pattern:ErrorGuideCodec @architect-implements:ValidationRulesCodec @architect-status:completed @architect-unlock-reason:Retroactive-completion-during-rebrand +@architect-phase:35 @architect-product-area:Generation Feature: Validation Rules Document Codec + **Problem:** + `docs/PROCESS-GUARD.md` (341 lines) is manually maintained with per-error-code + diagnosis guides, escape hatch documentation, pre-commit setup instructions, and + programmatic API examples. When validation rules change in `src/lint/`, the manual + doc drifts. The existing `ValidationRulesCodec` generates `docs-live/validation/` + files (error-catalog.md, fsm-transitions.md, protection-levels.md) covering ~35% + of PROCESS-GUARD.md content, but these lack fix rationale, alternative approaches, + integration recipes, and the programmatic API. + + **Solution:** + Enhance the `ValidationRulesCodec` to generate error diagnosis guide content by + extending its options, annotating error-handling source files with convention tags, + and composing preamble content for Husky/CI setup that cannot come from annotations. + Validates the Validation Rules Codec that transforms PatternGraph into a RenderableDocument for Process Guard validation rules reference (VALIDATION-RULES.md). diff --git a/tests/features/extractor/declaration-level-shape-tagging.feature b/tests/features/extractor/declaration-level-shape-tagging.feature index 1bf0d336..1445fab7 100644 --- a/tests/features/extractor/declaration-level-shape-tagging.feature +++ b/tests/features/extractor/declaration-level-shape-tagging.feature @@ -1,11 +1,34 @@ @architect -@architect-pattern:DeclarationLevelShapeTaggingTesting +@architect-pattern:DeclarationLevelShapeTagging @architect-status:completed @architect-unlock-reason:Retroactive-completion-during-rebrand -@architect-implements:DeclarationLevelShapeTagging +@architect-phase:31 +@architect-depends-on:ShapeExtraction,ReferenceDocShowcase @architect-product-area:Annotation Feature: Declaration-Level Shape Tagging - Extraction + **Problem:** + The current shape extraction system operates at file granularity. The + the `architect-extract-shapes` tag on a pattern block extracts named declarations + from the entire file, and the reference doc config shapeSelectors field selects + shapes by source selector only. There is no way for a reference document to request + "only RiskLevel and RISK_LEVELS from risk-levels.ts" -- it gets every shape + the file exports. This produces noisy reference documents that include + irrelevant types alongside the focused content the document is trying to + present. + + The reference doc system is designed for composing focused documents from + cherry-picked content: conventionTags filters by tag, behaviorCategories + filters by category, diagramScopes filters by arch metadata. But source + selectors provide the coarse file-level axis with content-level filtering. + + **Solution:** + Introduce a lightweight @architect-shape annotation tag on individual + TypeScript declarations. Each tagged declaration self-identifies as a + documentable shape, optionally belonging to a named group. On the consumer + side, add shapeSelectors to ReferenceDocConfig for fine-grained selection + by name or group. + Tests the discoverTaggedShapes function that scans TypeScript source code for declarations annotated with the architect-shape JSDoc tag. diff --git a/tests/features/extractor/dual-source-extraction.feature b/tests/features/extractor/dual-source-extraction.feature index 0c9838c3..e59e84d1 100644 --- a/tests/features/extractor/dual-source-extraction.feature +++ b/tests/features/extractor/dual-source-extraction.feature @@ -1,10 +1,11 @@ @architect @behavior @extraction -@architect-pattern:DualSourceExtractorTesting -@architect-implements:DualSourceExtractor +@architect-pattern:PatternGraphLayeredExtraction @architect-status:completed -@architect-unlock-reason:Retroactive-completion-during-rebrand -@architect-product-area:Annotation +@architect-unlock-reason:Terminology-alignment-rebrand +@architect-phase:100 +@architect-depends-on:ValidatorReadModelConsolidation +@architect-product-area:DataAPI Feature: Dual-Source Extraction Extracts and combines pattern metadata from both TypeScript code stubs (@architect-*) and Gherkin feature files (@libar-process-*), validates diff --git a/tests/features/extractor/shape-extraction-rendering.feature b/tests/features/extractor/shape-extraction-rendering.feature index f75a560a..99a99258 100644 --- a/tests/features/extractor/shape-extraction-rendering.feature +++ b/tests/features/extractor/shape-extraction-rendering.feature @@ -1,6 +1,6 @@ @architect @architect-pattern:ShapeExtractionRenderingTesting -@architect-implements:ReferenceDocShowcase +@architect-implements:ReferenceDocShowcase,ShapeExtraction @architect-status:completed @architect-unlock-reason:'Split-from-original' @architect-product-area:Annotation diff --git a/tests/features/extractor/shape-extraction-types.feature b/tests/features/extractor/shape-extraction-types.feature index e9fc958a..6892bf4a 100644 --- a/tests/features/extractor/shape-extraction-types.feature +++ b/tests/features/extractor/shape-extraction-types.feature @@ -1,9 +1,11 @@ @architect -@architect-pattern:ShapeExtractionTypesTesting +@architect-pattern:ShapeExtraction @architect-implements:ReferenceDocShowcase @architect-status:completed @architect-unlock-reason:Retroactive-completion-during-rebrand +@architect-phase:26 @architect-product-area:Annotation +@architect-enables:DocGenerationProofOfConcept Feature: TypeScript Shape Extraction - Type Extraction Validates the shape extraction system that extracts TypeScript type diff --git a/tests/features/generators/business-rules-codec.feature b/tests/features/generators/business-rules-codec.feature index c4a141eb..0d6ef00a 100644 --- a/tests/features/generators/business-rules-codec.feature +++ b/tests/features/generators/business-rules-codec.feature @@ -4,6 +4,7 @@ @architect-unlock-reason:Retroactive-completion-during-rebrand @architect-product-area:Generation @architect-implements:BusinessRulesGenerator +@architect-implements:GherkinRulesSupport Feature: Business Rules Document Codec Tests the BusinessRulesCodec transformation from PatternGraph to RenderableDocument. diff --git a/tests/features/generators/orchestrator.feature b/tests/features/generators/orchestrator.feature index 341ded2a..e89b4691 100644 --- a/tests/features/generators/orchestrator.feature +++ b/tests/features/generators/orchestrator.feature @@ -1,11 +1,27 @@ @architect -@architect-pattern:DocumentationOrchestrator +@architect-pattern:OrchestratorPipelineFactoryMigration @architect-status:completed @architect-unlock-reason:Retroactive-completion-during-rebrand +@architect-phase:101 @architect-product-area:Generation -@architect-implements:GeneratorInfrastructureTesting +@architect-depends-on:PatternGraphLayeredExtraction Feature: Documentation Generation Orchestrator + **Problem:** + `orchestrator.ts` is the last feature consumer that wires the 8-step + scan-extract-merge-transform pipeline inline. This is the Parallel Pipeline + anti-pattern identified in ADR-006. The shared pipeline factory in + `build-pipeline.ts` already serves `pattern-graph-cli.ts` and + `validate-patterns.ts`, but the orchestrator was deferred because it + collects structured warnings that the factory's flat warnings cannot represent. + + **Solution:** + Enrich the pipeline factory's `PipelineResult` with structured warnings + that capture the granularity the orchestrator needs, then migrate + `generateDocumentation()` to call `buildPatternGraph()`. Move + `mergePatterns()` to `src/generators/pipeline/merge-patterns.ts` as a + standalone pipeline step. + Tests the orchestrator's pattern merging, conflict detection, and generator coordination capabilities. The orchestrator coordinates the full documentation generation pipeline: Scanner -> Extractor -> Generators -> File Writer. diff --git a/tests/features/lint/step-lint-extended.feature b/tests/features/lint/step-lint-extended.feature index beebdcfc..9cd06e55 100644 --- a/tests/features/lint/step-lint-extended.feature +++ b/tests/features/lint/step-lint-extended.feature @@ -1,7 +1,28 @@ +@architect +@architect-pattern:StepLintExtendedRules +@architect-status:completed +@architect-unlock-reason:Retroactive-completion +@architect-phase:51 +@architect-depends-on:StepLintVitestCucumber +@architect-product-area:Validation Feature: Step Lint Extended Rules - Additional vitest-cucumber Traps - Tests for the 4 extended lint-steps rules that catch additional - vitest-cucumber compatibility issues statically. + **Problem:** + The initial lint-steps CLI catches 8 vitest-cucumber traps, but 4 documented + traps from _claude-md/testing/vitest-cucumber.md remain uncovered: + - Hash in step text (mid-line) truncates the step at runtime + - Feature descriptions starting with Given/When/Then break the parser + - Scenario Outline steps using quoted values (the feature-file side of the + Two-Pattern Problem -- the step-file side is already caught) + - Repeated identical step patterns in the same scenario overwrite registrations + + These cause cryptic runtime failures that are statically detectable. + + **Solution:** + Extend lint-steps with 4 new rules using the same pure-function architecture. + Two are feature-only checks, one is a step-only check, and one is a + cross-file check. All reuse the existing LintViolation/LintSummary types + and integrate into the existing runner pipeline. Background: Given a step lint context diff --git a/tests/features/lint/step-lint.feature b/tests/features/lint/step-lint.feature index ddbd86fe..e9107b85 100644 --- a/tests/features/lint/step-lint.feature +++ b/tests/features/lint/step-lint.feature @@ -1,7 +1,27 @@ +@architect +@architect-pattern:StepLintVitestCucumber +@architect-status:completed +@architect-unlock-reason:Value-transfer-from-spec +@architect-phase:50 +@architect-product-area:Validation Feature: Step Lint - vitest-cucumber Compatibility Checks - Tests for the lint-steps static analysis rules that detect - vitest-cucumber compatibility issues before tests run. + **Problem:** + Hours are lost debugging vitest-cucumber-specific issues that only surface + at test runtime. These are semantic traps at the boundary between .feature + files and .steps.ts files: using {string} function params inside + ScenarioOutline (should use variables object), forgetting to destructure + the And keyword (causes StepAbleUnknowStepError), missing Rule() wrappers, and hash + comments inside description pseudo-code-blocks. All are statically + detectable but no existing linter catches them. + + **Solution:** + A dedicated lint-steps CLI that statically analyzes .feature and .steps.ts + files for vitest-cucumber compatibility. Three check categories: + - Feature-only: hash-in-description, duplicate-and-step, dollar-in-step-text + - Step-only: regex-step-pattern, unsupported-phrase-type + - Cross-file: scenario-outline-function-params, missing-and-destructuring, + missing-rule-wrapper Background: Given a step lint context diff --git a/tests/features/poc/rule-keyword-poc.feature b/tests/features/poc/rule-keyword-poc.feature index 85f3af98..f040be8f 100644 --- a/tests/features/poc/rule-keyword-poc.feature +++ b/tests/features/poc/rule-keyword-poc.feature @@ -3,6 +3,7 @@ @architect-status:completed @architect-unlock-reason:Retroactive-completion-during-rebrand @architect-product-area:Generation +@architect-implements:GherkinRulesSupport @poc @rule-keyword Feature: PoC - Rule Keyword Support This feature tests whether vitest-cucumber supports the Rule keyword diff --git a/tests/features/scanner/gherkin-parser.feature b/tests/features/scanner/gherkin-parser.feature index f78579f8..5ad6320d 100644 --- a/tests/features/scanner/gherkin-parser.feature +++ b/tests/features/scanner/gherkin-parser.feature @@ -1,12 +1,22 @@ @architect -@scanner @architect-pattern:GherkinAstParser @unit +@scanner @architect-pattern:GherkinRulesSupport @unit @architect-status:completed @architect-unlock-reason:Retroactive-completion-during-rebrand +@architect-phase:100 @architect-product-area:Annotation Feature: Gherkin AST Parser The Gherkin AST parser extracts feature metadata, scenarios, and steps from .feature files for timeline generation and process documentation. + Extended the documentation pipeline to capture and render: + - Rule: keyword as Business Rules sections + - Rule descriptions (rationale, exceptions, context) + - DataTables in steps as Markdown tables + - DocStrings in steps as code blocks + + Infrastructure changes (schema, scanner, extractor) are shared by all generators. + Confirmed vitest-cucumber supports Rules via Rule() + RuleScenario() syntax. + Background: Given a Gherkin parser context diff --git a/tests/features/types/deliverable-status.feature b/tests/features/types/deliverable-status.feature index 0a99f007..66996adc 100644 --- a/tests/features/types/deliverable-status.feature +++ b/tests/features/types/deliverable-status.feature @@ -1,6 +1,7 @@ @architect @architect-pattern:DeliverableStatusTaxonomyTesting @architect-status:active +@architect-implements:TypeScriptTaxonomyImplementation @architect-product-area:CoreTypes @architect-include:core-types @taxonomy @deliverable diff --git a/tests/features/types/normalized-status.feature b/tests/features/types/normalized-status.feature index 9530abd3..233ffee7 100644 --- a/tests/features/types/normalized-status.feature +++ b/tests/features/types/normalized-status.feature @@ -1,6 +1,7 @@ @architect @architect-pattern:NormalizedStatusTesting @architect-status:active +@architect-implements:TypeScriptTaxonomyImplementation @architect-product-area:CoreTypes @architect-include:core-types @taxonomy @status diff --git a/tests/features/types/tag-registry-builder.feature b/tests/features/types/tag-registry-builder.feature index a2143970..db275e46 100644 --- a/tests/features/types/tag-registry-builder.feature +++ b/tests/features/types/tag-registry-builder.feature @@ -1,10 +1,16 @@ @architect -@architect-pattern:TagRegistryBuilderTesting -@architect-status:active +@architect-pattern:TypeScriptTaxonomyImplementation +@architect-status:completed +@architect-unlock-reason:Value-transfer-from-spec +@architect-phase:99 @architect-product-area:CoreTypes @architect-include:core-types @taxonomy @registry Feature: Tag Registry Builder + As an Architect developer + I want taxonomy defined in TypeScript with Zod integration + So that I get compile-time safety and runtime validation + The tag registry builder constructs a complete TagRegistry from TypeScript constants. It is the single source of truth for the Architect annotation taxonomy, providing tag definitions, categories, and format diff --git a/tests/features/validation/fsm-validator.feature b/tests/features/validation/fsm-validator.feature index 0aa85844..32c966f5 100644 --- a/tests/features/validation/fsm-validator.feature +++ b/tests/features/validation/fsm-validator.feature @@ -1,8 +1,8 @@ @architect -@architect-implements:PhaseStateMachineValidation @behavior @fsm-validation -@architect-pattern:FSMValidatorTesting +@architect-pattern:PhaseStateMachineValidation @architect-status:completed +@architect-phase:100 @architect-unlock-reason:Retroactive-completion-during-rebrand @architect-product-area:Validation @architect-depends-on:FSMTransitions,FSMStates diff --git a/tests/features/validation/process-guard.feature b/tests/features/validation/process-guard.feature index 2dc03361..163710b9 100644 --- a/tests/features/validation/process-guard.feature +++ b/tests/features/validation/process-guard.feature @@ -1,7 +1,8 @@ @architect -@architect-implements:ProcessGuardLinter -@behavior @process-guard @architect-pattern:ProcessGuardTesting +@architect-pattern:ProcessGuardLinter +@behavior @process-guard @architect-status:completed +@architect-phase:99 @architect-unlock-reason:Retroactive-completion-during-rebrand @architect-product-area:Validation @architect-depends-on:PhaseStateMachineValidation,AntiPatternDetector diff --git a/tests/features/validation/status-transition-detection.feature b/tests/features/validation/status-transition-detection.feature index b9a83228..4efa88a0 100644 --- a/tests/features/validation/status-transition-detection.feature +++ b/tests/features/validation/status-transition-detection.feature @@ -1,10 +1,23 @@ @architect -@behavior @status-transitions @architect-pattern:StatusTransitionDetectionTesting +@behavior @status-transitions @architect-pattern:MvpWorkflowImplementation @architect-implements:DetectChanges @architect-status:completed @architect-unlock-reason:Retroactive-completion-during-rebrand -@architect-product-area:Validation +@architect-phase:99 +@architect-product-area:Process Feature: Status Transition Detection from Git Diff + + **Problem:** + PDR-005 defines a 4-state workflow FSM (`roadmap, active, completed, deferred`) + but the Architect package validation schemas and generators may still + reference legacy status values. Need to ensure alignment. + + **Solution:** + Implement PDR-005 status values via taxonomy module refactor: + 1. Create taxonomy module as single source of truth (src/taxonomy/status-values.ts) + 2. Update validation schemas to import from taxonomy module + 3. Update generators to use normalizeStatus() for display bucket mapping + Tests for the detectStatusTransitions function that parses git diff output. Verifies that status tags inside docstrings are ignored and only file-level tags are used for FSM transition validation. diff --git a/tests/features/validation/workflow-config-schemas.feature b/tests/features/validation/workflow-config-schemas.feature index 46e6112f..57eb505a 100644 --- a/tests/features/validation/workflow-config-schemas.feature +++ b/tests/features/validation/workflow-config-schemas.feature @@ -1,5 +1,6 @@ @architect @architect-pattern:WorkflowConfigSchemasValidation +@architect-implements:ConfigBasedWorkflowDefinition @architect-status:active @architect-product-area:Validation @validation @workflow diff --git a/architect/specs/doc-generation-proof-of-concept.feature b/tests/fixtures/doc-generation/poc-decision-document.feature similarity index 99% rename from architect/specs/doc-generation-proof-of-concept.feature rename to tests/fixtures/doc-generation/poc-decision-document.feature index db554365..c31c7ac1 100644 --- a/architect/specs/doc-generation-proof-of-concept.feature +++ b/tests/fixtures/doc-generation/poc-decision-document.feature @@ -1,4 +1,3 @@ -@architect @architect-adr:021 @architect-adr-status:superseded @architect-adr-category:documentation @@ -177,8 +176,8 @@ Feature: ADR-021 - Documentation Generation from Annotated Sources | Intro & Context | THIS DECISION (Rule: Context above) | Decision rule description | | How It Works | THIS DECISION (Rule: Decision above) | Decision rule description | | Validation Rules | tests/features/validation/process-guard.feature | Rule blocks | - | Protection Levels | architect/specs/process-guard-linter.feature | Scenario Outline Examples | - | Valid Transitions | architect/specs/process-guard-linter.feature | Scenario Outline Examples | + | Protection Levels | tests/features/validation/process-guard.feature | Scenario Outline Examples | + | Valid Transitions | tests/features/validation/process-guard.feature | Scenario Outline Examples | | API Types | src/lint/process-guard/types.ts | @extract-shapes tag | | Decider API | src/lint/process-guard/decider.ts | @extract-shapes tag | | CLI Options | src/cli/lint-process.ts | JSDoc section | diff --git a/tests/steps/doc-generation/poc-integration.steps.ts b/tests/steps/doc-generation/poc-integration.steps.ts index 17f6900e..bb9e698b 100644 --- a/tests/steps/doc-generation/poc-integration.steps.ts +++ b/tests/steps/doc-generation/poc-integration.steps.ts @@ -68,7 +68,7 @@ let state: TestState; function resetState(): void { state = { baseDir: process.cwd(), - pocPath: 'architect/specs/doc-generation-proof-of-concept.feature', + pocPath: 'tests/fixtures/doc-generation/poc-decision-document.feature', pocContent: null, parsedFeature: null, decisionContent: null, From 62b3e1bb885b633d407c93b1a5417028dffcb341 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Darko=20Mijic=CC=81?= Date: Thu, 2 Apr 2026 07:05:08 +0200 Subject: [PATCH 2/3] fix(specs): address review findings from spec consolidation PR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove single quotes from @architect-unlock-reason tag values across 14 test files (§03 tag syntax: values use no quotes in Gherkin format) - Remove @ prefix from architect-implements in feature description prose (validate-patterns.feature — forbidden per authoring guidelines) - Fix "The the" duplicated word in declaration-level-shape-tagging.feature - Drop Background: Deliverables section from arch-queries.feature and its step definition (§08: deliverables table dropped during value transfer, implementation IS the deliverable) --- .../features/api/architecture-queries/arch-queries.feature | 7 ------- .../behavior/codecs/pr-changes-codec-options.feature | 2 +- .../features/behavior/codecs/reference-codec-core.feature | 2 +- .../codecs/reference-codec-detail-rendering.feature | 2 +- .../behavior/codecs/reference-codec-diagram-types.feature | 2 +- .../behavior/codecs/reference-codec-diagrams.feature | 2 +- tests/features/behavior/render-blocks.feature | 2 +- tests/features/cli/pattern-graph-cli-core.feature | 2 +- .../features/cli/pattern-graph-cli-modifiers-rules.feature | 2 +- tests/features/cli/pattern-graph-cli-subcommands.feature | 2 +- tests/features/cli/validate-patterns.feature | 2 +- .../extractor/declaration-level-shape-tagging.feature | 2 +- .../features/extractor/shape-extraction-rendering.feature | 2 +- tests/features/lint/lint-rules-individual.feature | 2 +- tests/features/scanner/ast-parser-exports.feature | 2 +- tests/features/scanner/ast-parser-metadata.feature | 2 +- .../scanner/ast-parser-relationships-edges.feature | 2 +- tests/steps/api/architecture-queries/arch-queries.steps.ts | 7 +------ 18 files changed, 17 insertions(+), 29 deletions(-) diff --git a/tests/features/api/architecture-queries/arch-queries.feature b/tests/features/api/architecture-queries/arch-queries.feature index 8ebde1d5..043f92c9 100644 --- a/tests/features/api/architecture-queries/arch-queries.feature +++ b/tests/features/api/architecture-queries/arch-queries.feature @@ -23,13 +23,6 @@ Feature: Architecture Queries - Neighborhood, Comparison, Tags, Sources 5. `sources` shows file inventory by type 6. `unannotated [--path glob]` finds files without the opt-in marker - Background: Deliverables - Given the following deliverables: - | Deliverable | Status | Location | Tests | Test Type | - | arch neighborhood unit tests | pending | tests/steps/api/architecture-queries/ | Yes | unit | - | arch compare unit tests | pending | tests/steps/api/architecture-queries/ | Yes | unit | - | tags and sources unit tests | pending | tests/steps/api/architecture-queries/ | Yes | unit | - Rule: Neighborhood and comparison views **Invariant:** The architecture query API must provide pattern neighborhood views (direct connections) and cross-context comparison views (shared/unique dependencies), returning undefined for nonexistent patterns. diff --git a/tests/features/behavior/codecs/pr-changes-codec-options.feature b/tests/features/behavior/codecs/pr-changes-codec-options.feature index bd7606ba..452a97f0 100644 --- a/tests/features/behavior/codecs/pr-changes-codec-options.feature +++ b/tests/features/behavior/codecs/pr-changes-codec-options.feature @@ -2,7 +2,7 @@ @architect-pattern:PrChangesCodecOptionsTesting @architect-implements:PrChangesCodec @architect-status:completed -@architect-unlock-reason:'Split-from-original' +@architect-unlock-reason:Split-from-original @architect-product-area:Generation @behavior @pr-changes-codec Feature: PR Changes Codec - Options and Filters diff --git a/tests/features/behavior/codecs/reference-codec-core.feature b/tests/features/behavior/codecs/reference-codec-core.feature index 34d11890..f4044f1c 100644 --- a/tests/features/behavior/codecs/reference-codec-core.feature +++ b/tests/features/behavior/codecs/reference-codec-core.feature @@ -2,7 +2,7 @@ @behavior @reference-codec @architect-pattern:ReferenceDocShowcase @architect-status:completed -@architect-unlock-reason:'Split-from-original' +@architect-unlock-reason:Split-from-original @architect-phase:30 @architect-depends-on:CodecDrivenReferenceGeneration,ScopedArchitecturalView,ShapeExtraction @architect-product-area:Generation diff --git a/tests/features/behavior/codecs/reference-codec-detail-rendering.feature b/tests/features/behavior/codecs/reference-codec-detail-rendering.feature index 7685d959..b29e9465 100644 --- a/tests/features/behavior/codecs/reference-codec-detail-rendering.feature +++ b/tests/features/behavior/codecs/reference-codec-detail-rendering.feature @@ -2,7 +2,7 @@ @behavior @reference-codec @architect-pattern:ReferenceCodecDetailRendering @architect-status:completed -@architect-unlock-reason:'Split-from-original' +@architect-unlock-reason:Split-from-original @architect-implements:ReferenceDocShowcase @architect-product-area:Generation Feature: Reference Codec - Detail Level Rendering diff --git a/tests/features/behavior/codecs/reference-codec-diagram-types.feature b/tests/features/behavior/codecs/reference-codec-diagram-types.feature index 693b137e..c49234fe 100644 --- a/tests/features/behavior/codecs/reference-codec-diagram-types.feature +++ b/tests/features/behavior/codecs/reference-codec-diagram-types.feature @@ -2,7 +2,7 @@ @behavior @reference-codec @architect-pattern:ScopedArchitecturalView @architect-status:completed -@architect-unlock-reason:'Split-from-original' +@architect-unlock-reason:Split-from-original @architect-implements:ReferenceDocShowcase @architect-phase:28 @architect-depends-on:ArchitectureDiagramGeneration,ShapeExtraction diff --git a/tests/features/behavior/codecs/reference-codec-diagrams.feature b/tests/features/behavior/codecs/reference-codec-diagrams.feature index 717034e4..68bea843 100644 --- a/tests/features/behavior/codecs/reference-codec-diagrams.feature +++ b/tests/features/behavior/codecs/reference-codec-diagrams.feature @@ -2,7 +2,7 @@ @behavior @reference-codec @architect-pattern:ReferenceCodecDiagramTesting @architect-status:completed -@architect-unlock-reason:'Split-from-original' +@architect-unlock-reason:Split-from-original @architect-implements:ReferenceDocShowcase @architect-product-area:Generation Feature: Reference Codec - Diagram Scoping diff --git a/tests/features/behavior/render-blocks.feature b/tests/features/behavior/render-blocks.feature index cc355b13..0d1d4e6a 100644 --- a/tests/features/behavior/render-blocks.feature +++ b/tests/features/behavior/render-blocks.feature @@ -2,7 +2,7 @@ @architect-pattern:RendererBlockTypes @architect-implements:UniversalMarkdownRenderer @architect-status:completed -@architect-unlock-reason:'Split-from-original' +@architect-unlock-reason:Split-from-original @architect-product-area:Generation @behavior @render Feature: Universal Markdown Renderer - Block Types diff --git a/tests/features/cli/pattern-graph-cli-core.feature b/tests/features/cli/pattern-graph-cli-core.feature index fbed0a4d..0ddc292d 100644 --- a/tests/features/cli/pattern-graph-cli-core.feature +++ b/tests/features/cli/pattern-graph-cli-core.feature @@ -1,7 +1,7 @@ @architect @architect-pattern:PatternGraphAPICLI @architect-status:completed -@architect-unlock-reason:'Split-from-original' +@architect-unlock-reason:Split-from-original @architect-phase:24 @architect-product-area:DataAPI @cli @pattern-graph-cli diff --git a/tests/features/cli/pattern-graph-cli-modifiers-rules.feature b/tests/features/cli/pattern-graph-cli-modifiers-rules.feature index fe8a27d1..33de8fec 100644 --- a/tests/features/cli/pattern-graph-cli-modifiers-rules.feature +++ b/tests/features/cli/pattern-graph-cli-modifiers-rules.feature @@ -2,7 +2,7 @@ @architect-pattern:PatternGraphCliModifiersAndRules @architect-implements:PatternGraphAPICLI @architect-status:completed -@architect-unlock-reason:'Split-from-original' +@architect-unlock-reason:Split-from-original @architect-product-area:DataAPI @cli @pattern-graph-cli Feature: Pattern Graph CLI - Output Modifiers and Rules diff --git a/tests/features/cli/pattern-graph-cli-subcommands.feature b/tests/features/cli/pattern-graph-cli-subcommands.feature index 9632c866..a8e5ca23 100644 --- a/tests/features/cli/pattern-graph-cli-subcommands.feature +++ b/tests/features/cli/pattern-graph-cli-subcommands.feature @@ -2,7 +2,7 @@ @architect-pattern:PatternGraphCliSubcommands @architect-implements:PatternGraphAPICLI @architect-status:completed -@architect-unlock-reason:'Split-from-original' +@architect-unlock-reason:Split-from-original @architect-product-area:DataAPI @cli @pattern-graph-cli Feature: Pattern Graph CLI - Discovery Subcommands diff --git a/tests/features/cli/validate-patterns.feature b/tests/features/cli/validate-patterns.feature index 3302f8c9..c18985c6 100644 --- a/tests/features/cli/validate-patterns.feature +++ b/tests/features/cli/validate-patterns.feature @@ -13,7 +13,7 @@ Feature: Validator Read Model Consolidation — validate-patterns CLI `validate-patterns.ts` was the only feature consumer that bypassed the PatternGraph. It wired its own mini-pipeline (scan + extract + ad-hoc matching), created a lossy local type (`GherkinPatternInfo`) that discarded - relationship data, and failed to resolve `@architect-implements` links. + relationship data, and failed to resolve architect-implements links. **Solution:** Refactored `validate-patterns.ts` to consume the PatternGraph as its diff --git a/tests/features/extractor/declaration-level-shape-tagging.feature b/tests/features/extractor/declaration-level-shape-tagging.feature index 1445fab7..931c770c 100644 --- a/tests/features/extractor/declaration-level-shape-tagging.feature +++ b/tests/features/extractor/declaration-level-shape-tagging.feature @@ -9,7 +9,7 @@ Feature: Declaration-Level Shape Tagging - Extraction **Problem:** The current shape extraction system operates at file granularity. The - the `architect-extract-shapes` tag on a pattern block extracts named declarations + `architect-extract-shapes` tag on a pattern block extracts named declarations from the entire file, and the reference doc config shapeSelectors field selects shapes by source selector only. There is no way for a reference document to request "only RiskLevel and RISK_LEVELS from risk-levels.ts" -- it gets every shape diff --git a/tests/features/extractor/shape-extraction-rendering.feature b/tests/features/extractor/shape-extraction-rendering.feature index 99a99258..9cda6cf2 100644 --- a/tests/features/extractor/shape-extraction-rendering.feature +++ b/tests/features/extractor/shape-extraction-rendering.feature @@ -2,7 +2,7 @@ @architect-pattern:ShapeExtractionRenderingTesting @architect-implements:ReferenceDocShowcase,ShapeExtraction @architect-status:completed -@architect-unlock-reason:'Split-from-original' +@architect-unlock-reason:Split-from-original @architect-product-area:Annotation Feature: TypeScript Shape Extraction - Rendering and Validation diff --git a/tests/features/lint/lint-rules-individual.feature b/tests/features/lint/lint-rules-individual.feature index a30fb2f5..24c7bd2f 100644 --- a/tests/features/lint/lint-rules-individual.feature +++ b/tests/features/lint/lint-rules-individual.feature @@ -2,7 +2,7 @@ @lint @architect-pattern:LintRuleIndividualTesting @architect-implements:LintRules @architect-status:completed -@architect-unlock-reason:'Split-from-original' +@architect-unlock-reason:Split-from-original @architect-product-area:Validation Feature: Pattern Annotation Lint Rules - Individual Rule Validation Individual lint rules that check parsed directives for completeness. diff --git a/tests/features/scanner/ast-parser-exports.feature b/tests/features/scanner/ast-parser-exports.feature index 2ad1809b..fe20cfa4 100644 --- a/tests/features/scanner/ast-parser-exports.feature +++ b/tests/features/scanner/ast-parser-exports.feature @@ -2,7 +2,7 @@ @architect-pattern:AstParserExports @architect-implements:AstParser @architect-status:completed -@architect-unlock-reason:'Split-from-original' +@architect-unlock-reason:Split-from-original @architect-product-area:Annotation Feature: TypeScript AST Parser - Export Type Identification The AST Parser extracts @architect-* directives from TypeScript source files diff --git a/tests/features/scanner/ast-parser-metadata.feature b/tests/features/scanner/ast-parser-metadata.feature index 4d5054f7..96a3219c 100644 --- a/tests/features/scanner/ast-parser-metadata.feature +++ b/tests/features/scanner/ast-parser-metadata.feature @@ -2,7 +2,7 @@ @architect-pattern:AstParserMetadata @architect-implements:AstParser @architect-status:completed -@architect-unlock-reason:'Split-from-original' +@architect-unlock-reason:Split-from-original @architect-product-area:Annotation Feature: TypeScript AST Parser - Metadata Extraction The AST Parser extracts @architect-* directives from TypeScript source files diff --git a/tests/features/scanner/ast-parser-relationships-edges.feature b/tests/features/scanner/ast-parser-relationships-edges.feature index 68b3592c..803dd713 100644 --- a/tests/features/scanner/ast-parser-relationships-edges.feature +++ b/tests/features/scanner/ast-parser-relationships-edges.feature @@ -2,7 +2,7 @@ @architect-pattern:AstParserRelationshipsEdges @architect-implements:AstParser @architect-status:completed -@architect-unlock-reason:'Split-from-original' +@architect-unlock-reason:Split-from-original @architect-product-area:Annotation Feature: TypeScript AST Parser - Relationships and Edge Cases The AST Parser extracts @architect-* directives from TypeScript source files diff --git a/tests/steps/api/architecture-queries/arch-queries.steps.ts b/tests/steps/api/architecture-queries/arch-queries.steps.ts index 360df5ba..1d0a45fa 100644 --- a/tests/steps/api/architecture-queries/arch-queries.steps.ts +++ b/tests/steps/api/architecture-queries/arch-queries.steps.ts @@ -69,12 +69,7 @@ function buildDataset(): void { // Feature // ============================================================================= -describeFeature(feature, ({ Background, Rule }) => { - Background(({ Given }) => { - Given('the following deliverables:', () => { - // Deliverables table is metadata only — no runtime behavior - }); - }); +describeFeature(feature, ({ Rule }) => { // =========================================================================== // Rule 1: Neighborhood and comparison views // =========================================================================== From f9213ed22b17356efcf22d1f323d1e05650f6e8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Darko=20Mijic=CC=81?= Date: Thu, 2 Apr 2026 07:12:42 +0200 Subject: [PATCH 3/3] fix(specs): remove @ prefix from architect-shape in description prose MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same class of fix as the previous commit — @ prefix tokens in feature description text are forbidden per authoring guidelines. --- .../features/extractor/declaration-level-shape-tagging.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/features/extractor/declaration-level-shape-tagging.feature b/tests/features/extractor/declaration-level-shape-tagging.feature index 931c770c..5f158c37 100644 --- a/tests/features/extractor/declaration-level-shape-tagging.feature +++ b/tests/features/extractor/declaration-level-shape-tagging.feature @@ -23,7 +23,7 @@ Feature: Declaration-Level Shape Tagging - Extraction selectors provide the coarse file-level axis with content-level filtering. **Solution:** - Introduce a lightweight @architect-shape annotation tag on individual + Introduce a lightweight architect-shape annotation tag on individual TypeScript declarations. Each tagged declaration self-identifies as a documentable shape, optionally belonging to a named group. On the consumer side, add shapeSelectors to ReferenceDocConfig for fine-grained selection