Part 7: Plan-Level Specs (Gherkin Features)
TypeScript annotations describe what exists. Gherkin features describe what needs to be built — acceptance criteria, deliverables, and business rules that complement your code annotations.
7.1 Reading Gherkin
Section titled “7.1 Reading Gherkin”Quick primer: In Gherkin files, tags before
Feature:are metadata (like JSDoc tags).Background:sets up shared context.Rule:blocks define business constraints.Scenario:blocks are individual test cases with Given/When/Then steps.
7.2 Create src/specs/user-registration.feature
Section titled “7.2 Create src/specs/user-registration.feature”Important: Gherkin features must include the
@libar-docsopt-in tag. Without it, the scanner ignores the file entirely — just like TypeScript files.
@libar-docs@libar-docs-pattern:UserRegistration@libar-docs-status:roadmap@libar-docs-core@libar-docs-phase:1@libar-docs-release:v0.1.0@libar-docs-uses:UserService@libar-docs-implements:UserService@libar-docs-quarter:Q1-2026Feature: User Registration As a new user I want to register an account So that I can access the system
Background: Deliverables Given the following deliverables: | Deliverable | Status | Location | | Registration endpoint | Pending | src/sample-sources/user-service.ts | | Email validation | Pending | src/sample-sources/user-service.ts | | Duplicate check | Pending | src/sample-sources/user-service.ts |
Rule: Valid registrations create new accounts
**Invariant:** Each email address maps to exactly one user account. **Rationale:** Prevents account confusion and ensures unique identity.
@happy-path Scenario: Successful registration with valid email Given a valid email "alice@example.com" When the user submits the registration form Then a new account should be created And a confirmation email should be sent
@happy-path Scenario: Registration assigns a unique user ID Given a valid email "bob@example.com" When the user submits the registration form Then the returned user ID should be a valid UUID And the user should be marked as active
Rule: Invalid input is rejected before account creation
**Invariant:** No user record is created for invalid input. **Rationale:** Prevents polluting the user store with bad data.
@validation @business-rule Scenario: Registration fails with empty email Given an empty email "" When the user submits the registration form Then the registration should be rejected And an error message should indicate the email is invalid
Rule: Duplicate emails are rejected
**Invariant:** Registration with an existing email always fails. **Rationale:** Enforces unique identity constraint at the application boundary.
@business-rule Scenario: Registration fails with duplicate email Given an existing user with email "alice@example.com" When another user tries to register with "alice@example.com" Then the registration should be rejected And an error message should indicate the email is taken7.3 Gherkin annotation anatomy
Section titled “7.3 Gherkin annotation anatomy”Feature-level tags (before Feature:) use colon syntax — not spaces like TypeScript:
| Syntax | Context | Example |
|---|---|---|
| Space-separated | TypeScript JSDoc | @libar-docs-pattern UserService |
| Colon-separated | Gherkin tags | @libar-docs-pattern:UserRegistration |
Key feature-level tags:
| Tag | Purpose |
|---|---|
@libar-docs | Required. Opts the file into scanning. |
@libar-docs-pattern:UserRegistration | Names this as a pattern. |
@libar-docs-implements:UserService | Links this spec to the TypeScript pattern it specifies (dotted arrows in diagrams). |
@libar-docs-depends-on:UserRegistration | Roadmap sequencing between specs. |
Background: Deliverables — A data table under Background: that tracks deliverables. Each row specifies a deliverable name, its status, and the source file where it will be implemented. These show up in roadmap tracking and pattern detail pages.
Rule: blocks — Gherkin Rule: blocks are extracted as business rules. Add structured annotations inside the rule description:
**Invariant:**— The constraint that must hold (extracted verbatim)**Rationale:**— Why the invariant matters- Scenarios under the rule are linked as
Verified by:entries
Semantic scenario tags — Tags like @happy-path, @validation, @business-rule categorize scenarios for reporting.
7.4 Add a second feature spec
Section titled “7.4 Add a second feature spec”Create src/specs/authentication.feature:
@libar-docs@libar-docs-pattern:Authentication@libar-docs-status:roadmap@libar-docs-api@libar-docs-phase:2@libar-docs-release:vNEXT@libar-docs-uses:UserService@libar-docs-implements:AuthHandler@libar-docs-depends-on:UserRegistration@libar-docs-quarter:Q1-2026Feature: Authentication As a registered user I want to log in to my account So that I can access protected resources
Background: Deliverables Given the following deliverables: | Deliverable | Status | Location | | Login endpoint | Pending | src/sample-sources/auth-handler.ts | | Session token creation | Pending | src/sample-sources/auth-handler.ts |
Rule: Valid credentials grant access
**Invariant:** A session token is only issued for valid credential pairs. **Rationale:** Prevents unauthorized access to the system.
@happy-path Scenario: Successful login with valid credentials Given a registered user with email "alice@example.com" When the user submits valid login credentials Then a session token should be returned And the session should be marked as active
Rule: Invalid credentials are rejected securely
**Invariant:** Error messages never reveal whether the email or password was wrong. **Rationale:** Prevents credential enumeration attacks.
@business-rule @validation Scenario: Login fails with wrong password Given a registered user with email "alice@example.com" When the user logs in with an incorrect password Then authentication should fail And the error should say "Invalid credentials"This feature demonstrates cross-pattern traceability:
@libar-docs-implements:AuthHandler— links this spec to the TypeScript implementation@libar-docs-depends-on:UserRegistration— sequencing between specs
7.5 Query business rules
Section titled “7.5 Query business rules”npm run process:rules{ "success": true, "data": { "productAreas": [ { "productArea": "Platform", "ruleCount": 5, "invariantCount": 5, "phases": [ { "phase": "Phase 1", "features": [ { "pattern": "UserRegistration", "source": "src/specs/user-registration.feature", "rules": [ { "name": "Valid registrations create new accounts", "invariant": "Each email address maps to exactly one user account.", "rationale": "Prevents account confusion and ensures unique identity.", "verifiedBy": [ "Successful registration with valid email", "Registration assigns a unique user ID" ], "scenarioCount": 2 }, { "name": "Invalid input is rejected before account creation", "invariant": "No user record is created for invalid input.", "rationale": "Prevents polluting the user store with bad data.", "verifiedBy": ["Registration fails with empty email"], "scenarioCount": 1 }, { "name": "Duplicate emails are rejected", "invariant": "Registration with an existing email always fails.", "rationale": "Enforces unique identity constraint at the application boundary.", "verifiedBy": ["Registration fails with duplicate email"], "scenarioCount": 1 } ] } ] }, { "phase": "Phase 2", "features": [ { "pattern": "Authentication", "source": "src/specs/authentication.feature", "rules": [ { "name": "Valid credentials grant access", "invariant": "A session token is only issued for valid credential pairs.", "rationale": "Prevents unauthorized access to the system.", "verifiedBy": ["Successful login with valid credentials"], "scenarioCount": 1 }, { "name": "Invalid credentials are rejected securely", "invariant": "Error messages never reveal whether the email or password was wrong.", "rationale": "Prevents credential enumeration attacks.", "verifiedBy": ["Login fails with wrong password"], "scenarioCount": 1 } ] } ] } ] } ], "totalRules": 5, "totalInvariants": 5 }}What just happened: The system extracted 5 business rules from 2 Gherkin features, each with invariant statements and scenario verification links. Every
Rule:block with an**Invariant:**becomes a queryable business rule.
7.6 Generate business rules documentation
Section titled “7.6 Generate business rules documentation”npm run docs:business-rulesUsing sources from delivery-process.config.ts...Scanning source files... Found 8 patternsExtracting patterns... Extracted 8 patterns
Running generator: business-rules ✓ BUSINESS-RULES.md ✓ business-rules/platform.md
✅ Documentation generation complete! 2 files writtenBUSINESS-RULES.md shows a summary: “5 rules from 2 features across 1 product area.” The detail page business-rules/platform.md lists every invariant with its rationale and verification scenarios.
7.7 Check the enriched overview
Section titled “7.7 Check the enriched overview”npm run process:overview=== PROGRESS ===8 patterns (0 completed, 1 active, 7 planned) = 0%
=== ACTIVE PHASES ===Phase 1: Inception (1 active)
=== BLOCKING ===UserService blocked by: EventStoreAuthHandler blocked by: UserServiceAuthentication blocked by: UserRegistrationThe Gherkin features added 2 more main patterns (UserRegistration, Authentication). The total is now 8 patterns (not 11 — that count is reached after Part 8 adds the stub file). The blocking analysis now includes spec-level dependencies: Authentication is blocked by UserRegistration.
7.8 Verify all sources
Section titled “7.8 Verify all sources”npm run process:sources{ "success": true, "data": { "types": [ { "type": "TypeScript (annotated)", "count": 3, "locationPattern": "src/sample-sources/**/*.ts", "files": [ "src/sample-sources/user-service.ts", "src/sample-sources/event-store.ts", "src/sample-sources/auth-handler.ts" ] }, { "type": "Gherkin (features)", "count": 2, "locationPattern": "src/specs/**/*.feature", "files": [ "src/specs/user-registration.feature", "src/specs/authentication.feature" ] } ], "totalFiles": 5 }}Checkpoint: Part 7
Section titled “Checkpoint: Part 7”npm run process:sourcesshows 3 TypeScript + 2 Gherkin filesnpm run process:rulesreturns 5 business rulesdocs-generated/BUSINESS-RULES.mdexistsnpm run process:overviewshows 8 patterns
Recap: Part 7
Section titled “Recap: Part 7”- Gherkin features own planning metadata: status, phase, deliverables, business rules
- TypeScript owns implementation metadata: uses, used-by, shapes, architecture
- Together they form a complete picture — neither duplicates the other
Rule:blocks with**Invariant:**/**Rationale:**become queryable business rules- Gherkin tags use colon syntax (
@libar-docs-pattern:Name), TypeScript uses spaces