Repository navigation
feat(extract-config): add module-level extends support - #129
Conversation
Add extends property to extraction config schema allowing modules to inherit component rules from npm packages or file paths. Local rules override inherited rules. Schema changes: - Add extends property with conditional validation - Split types: ModuleConfig (unresolved) vs Module (resolved) - Validation for extends syntax Implementation: - resolveConfig in riviere-extract-ts handles inheritance - createConfigLoader in riviere-cli provides Node.js resolution - Support for both npm package names and relative file paths Tests: - Schema validation for extends syntax - Config resolution with package and file extends - Override behavior (local rules take precedence) - Error handling for missing extends targets - 100% coverage Co-Authored-By: Claude Opus 4.5 <[email protected]>
Deploying living-architecture with
|
| Latest commit: |
4d4b151
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://71154977.living-architecture.pages.dev |
| Branch Preview URL: | https://issue-128-m5-d5-0-add-extend.living-architecture.pages.dev |
PR Compliance Guide 🔍Below is a summary of compliance checks for this PR:
Compliance status legend🟢 - Fully Compliant🟡 - Partial Compliant 🔴 - Not Compliant ⚪ - Requires Further Human Verification 🏷️ - Compliance label |
|||||||||||||||||||||||||||||||||||
PR Code Suggestions ✨Explore these optional code suggestions:
|
||||||||||||||||
- Extract predicate validation logic to dedicated function - Reduce cyclomatic complexity in resolveConfig - Split test fixtures into separate file for reusability - Update anti-patterns documentation - Clean up import organization Co-Authored-By: Claude Opus 4.5 <[email protected]>
📝 WalkthroughWalkthroughAdds module-level "extends" support for extraction configs with schema, types, validation, resolver, CLI loader, and extractor integration. Introduces many domain-specific error classes, centralizes test assertion errors, updates tests, docs, linting, scripts, and Vitest coverage configuration. No unrelated runtime behavior changes. Changes
Sequence Diagram(s)sequenceDiagram
participant CLI as CLI (extract command)
participant Loader as ConfigLoader (createConfigLoader)
participant Resolver as resolveConfig
participant FS as Package/Filesystem
participant Extractor as extractComponents
CLI->>Loader: createConfigLoader(configDir)
CLI->>Resolver: resolveConfig(unresolvedConfig, Loader)
Resolver->>Resolver: iterate modules
alt module has extends
Resolver->>Loader: loader(extends source)
Loader->>FS: resolve package or read relative file
FS-->>Loader: base module config
Loader-->>Resolver: base module
Resolver->>Resolver: merge base module with local overrides
else no extends
Resolver->>Resolver: validate required rule fields present
end
Resolver-->>CLI: ResolvedExtractionConfig
CLI->>Extractor: extractComponents(project, files, resolvedConfig)
Extractor-->>CLI: DraftComponent[]
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Comment |
Inline createMinimalModule to eliminate unused export detected by knip. Co-Authored-By: Claude Opus 4.5 <[email protected]>
There was a problem hiding this comment.
Actionable comments posted: 8
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/riviere-cli/src/output.ts (1)
10-18:ErrorOutput.error.codeshould matchformatError’sCliErrorCode(or vice-versa).Option A (preferred): tighten the output type to the enum/union
export interface ErrorOutput { success: false error: { - code: string + code: CliErrorCode message: string suggestions: string[] } }If the output contract intentionally allows arbitrary string codes, then change
formatError(code: CliErrorCode, ...)toformatError(code: string, ...)instead.Also applies to: 34-53
🤖 Fix all issues with AI agents
In @packages/riviere-cli/src/commands/extract/config-loader.ts:
- Around line 25-31: The parseConfigContent function throws a generic Error when
isExtendedConfig(parsed) fails; improve it to provide specific diagnostics by
including the invalid parsed value and/or validation failures: enhance
parseConfigContent to capture the raw parsed object from parseYaml and, when
isExtendedConfig returns false, throw an Error that contains a short message
plus JSON.stringify(parsed, null, 2) or a list of missing/invalid fields (you
can add a small helper validator or extend isExtendedConfig to return error
details) so callers see what part of the ExtendedConfig is malformed.
- Around line 21-23: The isExtendedConfig type guard only checks for a non-null
object and must be strengthened to validate the actual ExtendedConfig shape:
update isExtendedConfig to assert required keys and types (e.g., check presence
and types of fields like <list the real required properties if known> or at
minimum required properties such as config.mode, config.source, config.output
etc.), return false for invalid shapes, and throw/propagate a clear, descriptive
error at config load time if validation fails; alternatively integrate the
official schema validator from @living-architecture/riviere-extract-config to
validate the parsed config against the extraction schema and surface explicit
validation errors so loaders using isExtendedConfig (function name
isExtendedConfig) never accept arbitrary objects.
- Around line 67-75: Replace brittle string matching in the catch block with a
robust custom error type or error code: define a specific error (e.g.,
MissingPackageError or set error.code = 'MISSING_PACKAGE') where the package
resolution logic (the resolver that may throw for packageName) detects the "does
not contain" condition, then here in config-loader.ts catch check error
instanceof MissingPackageError or error.code === 'MISSING_PACKAGE' instead of
error.message.includes(...), rethrow that custom error unchanged and convert any
other errors into the generic `Cannot resolve package '${packageName}'` Error to
preserve existing behaviour.
- Line 59: The code currently hardcodes the internal file path via
defaultConfigPath = resolve(packageDir, 'src/default-extraction.config.json');
change this to resolve the package export instead—use the package export
specifier (e.g.
'@living-architecture/riviere-extract-conventions/default-config') and locate it
with the module resolver (require.resolve(...) in CJS or
import.meta.resolve/await import.resolve if ESM) to set defaultConfigPath;
update the assignment that references defaultConfigPath and remove the direct
packageDir + src path usage so the loader relies on the package export
entrypoint.
- Around line 89-98: The loader returned by createConfigLoader currently loads
extended configs via loadConfigFile and then blindly calls
extractModuleFromConfig without validating the loaded object; update
loadConfigFile (or add a helper invoked by it) to validate any extended config
against the extraction config schema (the same schema used in extract.ts) when
loadConfigFile receives an extended config, and throw or return a descriptive
error if validation fails so createConfigLoader (which uses isPackageReference,
resolvePackagePath, resolve, loadConfigFile, extractModuleFromConfig) only ever
transforms a config that passes schema validation.
In @packages/riviere-cli/src/output.ts:
- Around line 3-8: The SuccessOutput<T> contract declares warnings as always
present but the docs call them optional; update the type to match the docs by
changing the property on SuccessOutput<T> to warnings?: string[] and do the same
for the other related output interfaces referenced around lines 20-31, then
audit any formatter/serializer that consumes SuccessOutput (search for usages of
SuccessOutput or functions that produce CLI output) to tolerate undefined
warnings (e.g., default to an empty array when formatting) so runtime behavior
stays safe.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (21)
docs/conventions/anti-patterns.mdeslint.config.mjspackages/riviere-cli/src/cli.tspackages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-cli/src/commands/extract/config-loader.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-cli/src/output.tspackages/riviere-extract-config/extraction-config.schema.jsonpackages/riviere-extract-config/src/index.tspackages/riviere-extract-config/src/types.tspackages/riviere-extract-config/src/validation-extends.spec.tspackages/riviere-extract-config/src/validation-fixtures.tspackages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-config/src/validation.tspackages/riviere-extract-ts/src/extractor.spec.tspackages/riviere-extract-ts/src/extractor.tspackages/riviere-extract-ts/src/index.tspackages/riviere-extract-ts/src/predicates/evaluate-predicate.tspackages/riviere-extract-ts/src/resolve-config.spec.tspackages/riviere-extract-ts/src/resolve-config.tspackages/riviere-extract-ts/src/test-fixtures.ts
💤 Files with no reviewable changes (1)
- packages/riviere-extract-config/src/index.ts
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Follow eslint configuration rules defined in
eslint.config.mjsfor all linting
Files:
packages/riviere-cli/src/cli.tspackages/riviere-extract-ts/src/resolve-config.tspackages/riviere-extract-config/src/validation.tspackages/riviere-extract-config/src/validation-fixtures.tspackages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-extract-ts/src/index.tspackages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-ts/src/predicates/evaluate-predicate.tspackages/riviere-extract-ts/src/resolve-config.spec.tspackages/riviere-extract-ts/src/test-fixtures.tspackages/riviere-extract-config/src/validation-extends.spec.tspackages/riviere-cli/src/commands/extract/config-loader.tspackages/riviere-extract-ts/src/extractor.tspackages/riviere-extract-ts/src/extractor.spec.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-extract-config/src/types.tspackages/riviere-cli/src/output.ts
**/*.{ts,tsx,js,jsx,css,scss,html}
📄 CodeRabbit inference engine (CLAUDE.md)
All UI and UX design must conform to global brand guidelines in
/docs/brand/(logo, colors, typography, icons)
Files:
packages/riviere-cli/src/cli.tspackages/riviere-extract-ts/src/resolve-config.tspackages/riviere-extract-config/src/validation.tspackages/riviere-extract-config/src/validation-fixtures.tspackages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-extract-ts/src/index.tspackages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-ts/src/predicates/evaluate-predicate.tspackages/riviere-extract-ts/src/resolve-config.spec.tspackages/riviere-extract-ts/src/test-fixtures.tspackages/riviere-extract-config/src/validation-extends.spec.tspackages/riviere-cli/src/commands/extract/config-loader.tspackages/riviere-extract-ts/src/extractor.tspackages/riviere-extract-ts/src/extractor.spec.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-extract-config/src/types.tspackages/riviere-cli/src/output.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,js,jsx}: Do not log sensitive data (passwords, tokens, PII) in any code
Validate and sanitize all external input
Files:
packages/riviere-cli/src/cli.tspackages/riviere-extract-ts/src/resolve-config.tspackages/riviere-extract-config/src/validation.tspackages/riviere-extract-config/src/validation-fixtures.tspackages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-extract-ts/src/index.tspackages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-ts/src/predicates/evaluate-predicate.tspackages/riviere-extract-ts/src/resolve-config.spec.tspackages/riviere-extract-ts/src/test-fixtures.tspackages/riviere-extract-config/src/validation-extends.spec.tspackages/riviere-cli/src/commands/extract/config-loader.tspackages/riviere-extract-ts/src/extractor.tspackages/riviere-extract-ts/src/extractor.spec.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-extract-config/src/types.tspackages/riviere-cli/src/output.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use cross-project imports with package names (e.g.,
import { X } from '@living-architecture/[pkg-name]') rather than relative paths
Files:
packages/riviere-cli/src/cli.tspackages/riviere-extract-ts/src/resolve-config.tspackages/riviere-extract-config/src/validation.tspackages/riviere-extract-config/src/validation-fixtures.tspackages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-extract-ts/src/index.tspackages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-ts/src/predicates/evaluate-predicate.tspackages/riviere-extract-ts/src/resolve-config.spec.tspackages/riviere-extract-ts/src/test-fixtures.tspackages/riviere-extract-config/src/validation-extends.spec.tspackages/riviere-cli/src/commands/extract/config-loader.tspackages/riviere-extract-ts/src/extractor.tspackages/riviere-extract-ts/src/extractor.spec.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-extract-config/src/types.tspackages/riviere-cli/src/output.ts
packages/riviere-extract-ts/**/*.{ts,tsx}
📄 CodeRabbit inference engine (packages/riviere-extract-ts/CLAUDE.md)
packages/riviere-extract-ts/**/*.{ts,tsx}: Use ts-morph for TypeScript AST parsing instead of other parsers
Implement extraction logic as pure functions with no side effects
Compose detection rules via and/or logic for predicates
Reject invalid extraction configs at load time, not during extraction phase
Use glob pattern matching for module-based organization of extraction rules
Files:
packages/riviere-extract-ts/src/resolve-config.tspackages/riviere-extract-ts/src/index.tspackages/riviere-extract-ts/src/predicates/evaluate-predicate.tspackages/riviere-extract-ts/src/resolve-config.spec.tspackages/riviere-extract-ts/src/test-fixtures.tspackages/riviere-extract-ts/src/extractor.tspackages/riviere-extract-ts/src/extractor.spec.ts
packages/riviere-extract-config/**/*.ts
📄 CodeRabbit inference engine (packages/riviere-extract-config/CLAUDE.md)
Extraction config schema is the source of truth for valid structures. TypeScript types must mirror the schema definition to maintain consistency
Files:
packages/riviere-extract-config/src/validation.tspackages/riviere-extract-config/src/validation-fixtures.tspackages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-config/src/validation-extends.spec.tspackages/riviere-extract-config/src/types.ts
🧠 Learnings (61)
📓 Common learnings
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Use glob pattern matching for module-based organization of extraction rules
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.{json,ts} : Define extraction configuration using the JSON Schema from `living-architecture/riviere-extract-config` DSL
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Applies to packages/riviere-extract-config/**/*.ts : Extraction config schema is the source of truth for valid structures. TypeScript types must mirror the schema definition to maintain consistency
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use `living-architecture/riviere-extract-ts` TypeScript extractor with ts-morph for AST parsing when implementing TypeScript extraction for architecture schema components
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement integration tests for end-to-end extraction from TypeScript code to JSON output
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Reject invalid extraction configs at load time, not during extraction phase
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Implement extraction logic as pure functions with no side effects
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-conventions/CLAUDE.md:0-0
Timestamp: 2026-01-08T07:05:01.766Z
Learning: Import and use the default extraction config from `living-architecture/riviere-extract-conventions/default-config` in extraction tooling to detect all 6 component types
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use the Rivière Builder Node.js library to programmatically construct the schema graph when implementing custom extraction code
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: All extraction rules should come from validated ExtractionConfig provided by riviere-extract-config
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Extraction config schemas must define all six required component types per module: api, useCase, domainOp, event, eventHandler, and ui. Unused component types must be explicitly marked with `notUsed: true` rather than omitted
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: All validation of extraction config must occur at config load time, not during extraction. Invalid configs should fail fast with clear error messages that include paths and descriptive information
📚 Learning: 2026-01-09T20:08:44.180Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 88
File: packages/riviere-cli/src/commands/extract/extract.ts:109-114
Timestamp: 2026-01-09T20:08:44.180Z
Learning: Applies to packages/riviere-cli/src/commands/extract/**/*.{ts,tsx} : CLI extraction commands should only catch and format expected validation errors as structured JSON. System-level exceptions (disk I/O failures, OOM, AST parse errors) should fail loudly with stack traces for debugging rather than being wrapped in try-catch and converted to JSON errors. This follows the fail-fast principle: validate inputs explicitly, then let unexpected failures surface clearly.
Applied to files:
packages/riviere-cli/src/cli.tspackages/riviere-extract-config/src/validation.tspackages/riviere-cli/src/output.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Use ts-morph for TypeScript AST parsing instead of other parsers
Applied to files:
packages/riviere-cli/src/cli.tspackages/riviere-extract-ts/src/resolve-config.tspackages/riviere-extract-ts/src/index.tseslint.config.mjspackages/riviere-extract-ts/src/extractor.tspackages/riviere-extract-ts/src/extractor.spec.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-extract-config/src/types.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement integration tests for end-to-end extraction from TypeScript code to JSON output
Applied to files:
packages/riviere-cli/src/cli.tspackages/riviere-extract-ts/src/resolve-config.tspackages/riviere-extract-config/src/validation.tspackages/riviere-extract-config/src/validation-fixtures.tspackages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-extract-ts/src/index.tspackages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-ts/src/predicates/evaluate-predicate.tspackages/riviere-extract-ts/src/resolve-config.spec.tspackages/riviere-extract-ts/src/test-fixtures.tspackages/riviere-extract-config/src/validation-extends.spec.tspackages/riviere-cli/src/commands/extract/config-loader.tspackages/riviere-extract-ts/src/extractor.spec.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-cli/src/output.ts
📚 Learning: 2026-01-02T11:58:27.018Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-cli/CLAUDE.md:0-0
Timestamp: 2026-01-02T11:58:27.018Z
Learning: After modifying CLI commands, run `nx generate-docs riviere-cli` to regenerate CLI reference documentation
Applied to files:
packages/riviere-cli/src/cli.tspackages/riviere-cli/src/output.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Implement extraction logic as pure functions with no side effects
Applied to files:
packages/riviere-cli/src/cli.tspackages/riviere-extract-ts/src/resolve-config.tspackages/riviere-extract-config/src/validation.tspackages/riviere-extract-config/src/validation-fixtures.tspackages/riviere-extract-ts/src/index.tspackages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-ts/src/predicates/evaluate-predicate.tspackages/riviere-extract-ts/src/test-fixtures.tspackages/riviere-extract-config/src/validation-extends.spec.tspackages/riviere-cli/src/commands/extract/config-loader.tspackages/riviere-extract-ts/src/extractor.tspackages/riviere-extract-ts/src/extractor.spec.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-extract-config/src/types.tspackages/riviere-cli/src/output.ts
📚 Learning: 2026-01-02T11:58:27.018Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-cli/CLAUDE.md:0-0
Timestamp: 2026-01-02T11:58:27.018Z
Learning: When modifying CLI commands in the riviere-cli tool, update the corresponding workflow prompts in docs/workflow/ directory (step-1 through step-6) to keep the extraction workflow in sync
Applied to files:
packages/riviere-cli/src/cli.ts
📚 Learning: 2026-01-06T23:01:34.751Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Applies to packages/riviere-extract-config/**/*.ts : Extraction config schema is the source of truth for valid structures. TypeScript types must mirror the schema definition to maintain consistency
Applied to files:
packages/riviere-cli/src/cli.tspackages/riviere-extract-ts/src/resolve-config.tspackages/riviere-extract-config/extraction-config.schema.jsonpackages/riviere-extract-config/src/validation.tspackages/riviere-extract-config/src/validation-fixtures.tspackages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-extract-ts/src/index.tspackages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-ts/src/resolve-config.spec.tspackages/riviere-extract-ts/src/test-fixtures.tspackages/riviere-extract-config/src/validation-extends.spec.tspackages/riviere-cli/src/commands/extract/config-loader.tspackages/riviere-extract-ts/src/extractor.tspackages/riviere-extract-ts/src/extractor.spec.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-extract-config/src/types.tspackages/riviere-cli/src/output.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Use glob pattern matching for module-based organization of extraction rules
Applied to files:
packages/riviere-cli/src/cli.tspackages/riviere-extract-ts/src/resolve-config.tspackages/riviere-extract-config/extraction-config.schema.jsonpackages/riviere-extract-config/src/validation.tspackages/riviere-extract-config/src/validation-fixtures.tspackages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-extract-ts/src/index.tspackages/riviere-extract-ts/src/resolve-config.spec.tspackages/riviere-extract-ts/src/test-fixtures.tspackages/riviere-extract-config/src/validation-extends.spec.tspackages/riviere-cli/src/commands/extract/config-loader.tseslint.config.mjspackages/riviere-extract-ts/src/extractor.tspackages/riviere-extract-ts/src/extractor.spec.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-extract-config/src/types.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Reject invalid extraction configs at load time, not during extraction phase
Applied to files:
packages/riviere-cli/src/cli.tspackages/riviere-extract-ts/src/resolve-config.tspackages/riviere-extract-config/extraction-config.schema.jsonpackages/riviere-extract-config/src/validation.tspackages/riviere-extract-config/src/validation-fixtures.tspackages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-extract-ts/src/index.tspackages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-ts/src/resolve-config.spec.tspackages/riviere-extract-ts/src/test-fixtures.tspackages/riviere-extract-config/src/validation-extends.spec.tspackages/riviere-cli/src/commands/extract/config-loader.tseslint.config.mjspackages/riviere-extract-ts/src/extractor.tspackages/riviere-extract-ts/src/extractor.spec.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-extract-config/src/types.ts
📚 Learning: 2026-01-08T22:20:13.250Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.{json,ts} : Define extraction configuration using the JSON Schema from `living-architecture/riviere-extract-config` DSL
Applied to files:
packages/riviere-extract-ts/src/resolve-config.tspackages/riviere-extract-config/extraction-config.schema.jsonpackages/riviere-extract-config/src/validation.tspackages/riviere-extract-config/src/validation-fixtures.tspackages/riviere-extract-ts/src/index.tspackages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-ts/src/resolve-config.spec.tspackages/riviere-extract-ts/src/test-fixtures.tspackages/riviere-extract-config/src/validation-extends.spec.tspackages/riviere-cli/src/commands/extract/config-loader.tspackages/riviere-extract-ts/src/extractor.tspackages/riviere-extract-ts/src/extractor.spec.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-extract-config/src/types.ts
📚 Learning: 2026-01-08T22:20:13.250Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use `living-architecture/riviere-extract-ts` TypeScript extractor with ts-morph for AST parsing when implementing TypeScript extraction for architecture schema components
Applied to files:
packages/riviere-extract-ts/src/resolve-config.tspackages/riviere-extract-config/extraction-config.schema.jsonpackages/riviere-extract-config/src/validation-fixtures.tspackages/riviere-extract-ts/src/index.tspackages/riviere-extract-ts/src/resolve-config.spec.tspackages/riviere-extract-ts/src/test-fixtures.tspackages/riviere-cli/src/commands/extract/config-loader.tseslint.config.mjspackages/riviere-extract-ts/src/extractor.tspackages/riviere-extract-ts/src/extractor.spec.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-extract-config/src/types.tspackages/riviere-cli/src/output.ts
📚 Learning: 2026-01-08T07:05:01.766Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-conventions/CLAUDE.md:0-0
Timestamp: 2026-01-08T07:05:01.766Z
Learning: Import and use the default extraction config from `living-architecture/riviere-extract-conventions/default-config` in extraction tooling to detect all 6 component types
Applied to files:
packages/riviere-extract-ts/src/resolve-config.tspackages/riviere-extract-config/extraction-config.schema.jsonpackages/riviere-extract-config/src/validation-fixtures.tspackages/riviere-extract-ts/src/index.tspackages/riviere-extract-ts/src/test-fixtures.tspackages/riviere-cli/src/commands/extract/config-loader.tspackages/riviere-extract-ts/src/extractor.tspackages/riviere-extract-ts/src/extractor.spec.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-extract-config/src/types.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: All extraction rules should come from validated ExtractionConfig provided by riviere-extract-config
Applied to files:
packages/riviere-extract-ts/src/resolve-config.tspackages/riviere-extract-config/extraction-config.schema.jsonpackages/riviere-extract-config/src/validation.tspackages/riviere-extract-config/src/validation-fixtures.tspackages/riviere-extract-ts/src/resolve-config.spec.tspackages/riviere-extract-config/src/validation-extends.spec.tspackages/riviere-extract-ts/src/extractor.tspackages/riviere-extract-ts/src/extractor.spec.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-extract-config/src/types.ts
📚 Learning: 2026-01-08T22:20:13.250Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use the Rivière Builder Node.js library to programmatically construct the schema graph when implementing custom extraction code
Applied to files:
packages/riviere-extract-ts/src/resolve-config.tspackages/riviere-extract-config/extraction-config.schema.jsonpackages/riviere-extract-config/src/validation-fixtures.tspackages/riviere-extract-ts/src/index.tspackages/riviere-extract-ts/src/test-fixtures.tspackages/riviere-cli/src/commands/extract/config-loader.tseslint.config.mjspackages/riviere-extract-ts/src/extractor.spec.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-extract-config/src/types.ts
📚 Learning: 2026-01-08T22:39:00.431Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 84
File: packages/riviere-extract-ts/src/extractor.ts:168-187
Timestamp: 2026-01-08T22:39:00.431Z
Learning: In ts-morph usage within the riviere-extract-ts package, MethodDeclaration.getName() always returns a string (never undefined) because methods cannot be anonymous in TypeScript. Only ClassDeclaration.getName() and FunctionDeclaration.getName() can return undefined. Therefore, remove undefined guards for MethodDeclaration when implementing createMethodComponent, and only keep guards for components that can actually be undefined (class/function components). Apply this guidance to all .ts files under packages/riviere-extract-ts/ (i.e., **/packages/riviere-extract-ts/**/*.ts).
Applied to files:
packages/riviere-extract-ts/src/resolve-config.tspackages/riviere-extract-ts/src/index.tspackages/riviere-extract-ts/src/predicates/evaluate-predicate.tspackages/riviere-extract-ts/src/resolve-config.spec.tspackages/riviere-extract-ts/src/test-fixtures.tspackages/riviere-extract-ts/src/extractor.tspackages/riviere-extract-ts/src/extractor.spec.ts
📚 Learning: 2026-01-06T23:01:34.751Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Extraction config schemas must define all six required component types per module: api, useCase, domainOp, event, eventHandler, and ui. Unused component types must be explicitly marked with `notUsed: true` rather than omitted
Applied to files:
packages/riviere-extract-config/extraction-config.schema.jsonpackages/riviere-extract-config/src/validation.tspackages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-ts/src/test-fixtures.tspackages/riviere-extract-config/src/validation-extends.spec.tspackages/riviere-extract-ts/src/extractor.spec.tspackages/riviere-extract-config/src/types.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Compose detection rules via and/or logic for predicates
Applied to files:
packages/riviere-extract-config/extraction-config.schema.jsonpackages/riviere-extract-ts/src/predicates/evaluate-predicate.tspackages/riviere-extract-ts/src/resolve-config.spec.tseslint.config.mjspackages/riviere-extract-ts/src/extractor.tspackages/riviere-extract-config/src/types.ts
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*-fixtures.ts : Create `<module>-fixtures.ts` fixture files alongside `<module>.spec.ts` to reduce duplication when multiple tests share similar setup data or differ only in specific values being tested.
Applied to files:
docs/conventions/anti-patterns.mdpackages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-ts/src/resolve-config.spec.tspackages/riviere-extract-ts/src/test-fixtures.tspackages/riviere-extract-ts/src/extractor.spec.ts
📚 Learning: 2026-01-08T19:36:17.306Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/codebase-structure.md:0-0
Timestamp: 2026-01-08T19:36:17.306Z
Learning: Applies to docs/conventions/apps/*/src/**/*.test.ts : Test fixtures used across multiple test files may be grouped in shared locations (e.g., test-fixtures.ts), but otherwise test files should be co-located with the code they test.
Applied to files:
docs/conventions/anti-patterns.mdpackages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-extract-ts/src/test-fixtures.ts
📚 Learning: 2026-01-10T10:14:57.499Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-10T10:14:57.499Z
Learning: Avoid anti-patterns documented in `docs/conventions/anti-patterns.md`
Applied to files:
docs/conventions/anti-patterns.md
📚 Learning: 2026-01-11T11:04:34.655Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/anti-patterns.md:0-0
Timestamp: 2026-01-11T11:04:34.655Z
Learning: When hitting max-lines limits, split files into focused modules (e.g., `foo.spec.ts` and `foo.edge-cases.spec.ts`), extract duplicated code into shared modules, or use parameterized tests with `it.each` or `describe.each` instead of removing tests or compressing code.
Applied to files:
docs/conventions/anti-patterns.mdpackages/riviere-extract-ts/src/extractor.spec.ts
📚 Learning: 2026-01-11T11:04:34.655Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/anti-patterns.md:0-0
Timestamp: 2026-01-11T11:04:34.655Z
Learning: Applies to docs/conventions/**/*.{ts,tsx,js,jsx} : Do not pass empty strings into parameters of type string. Empty strings indicate missing values and should trigger errors, use optional types, or reconsider the design. Avoid test cases that verify empty string as a valid expected scenario for string parameters.
Applied to files:
docs/conventions/anti-patterns.md
📚 Learning: 2026-01-11T11:17:09.319Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.319Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test edge cases for string inputs: empty string, whitespace-only strings, very long strings (10K+ characters), Unicode (emojis, RTL text, combining characters), special characters (quotes, backslashes, null bytes), SQL/HTML/script injection patterns, and leading/trailing whitespace.
Applied to files:
docs/conventions/anti-patterns.md
📚 Learning: 2026-01-04T16:47:43.968Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 0
File: :0-0
Timestamp: 2026-01-04T16:47:43.968Z
Learning: JSDoc documentation is only required on public-facing library methods that people who install the packages will use. Do not suggest JSDoc for internal code, test fixtures, or test helpers.
Applied to files:
docs/conventions/anti-patterns.mdeslint.config.mjs
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Avoid implementation coupling in tests. Test behavior, not implementation details. Instead of asserting on mock call arguments with exact SQL, assert on the observable result (e.g., expect(result.user.name).toBe('Alice')).
Applied to files:
docs/conventions/anti-patterns.md
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test violated domain constraints: uniqueness violations (duplicate IDs, emails), missing required relationships (orphaned records), ordering violations (events out of sequence), range breaches (age -1, quantity 1000000), state inconsistencies (shipped but not paid), format mismatches (expected JSON, got XML), and temporal ordering (end before start).
Applied to files:
docs/conventions/anti-patterns.md
📚 Learning: 2026-01-11T11:17:09.319Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.319Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test edge cases for collections (arrays, objects, maps): empty collections, single element, duplicates, nested structures, circular references, very large collections (performance), sparse arrays, and mixed types.
Applied to files:
docs/conventions/anti-patterns.mdpackages/riviere-extract-ts/src/extractor.spec.ts
📚 Learning: 2026-01-11T11:17:09.319Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.319Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : One concept per test. Each test verifies one behavior. If you need 'and' in your test name, split it into multiple tests.
Applied to files:
docs/conventions/anti-patterns.md
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test domain-specific edge cases: email (valid formats, plus signs, subdomains), URLs (protocols, ports, special characters, relative paths), phone numbers (international formats, extensions), addresses (Unicode, multi-line, missing components), currency (rounding, different currencies, zero amounts), percentages (0%, 100%, over 100%).
Applied to files:
docs/conventions/anti-patterns.md
📚 Learning: 2026-01-08T23:16:02.639Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/software-design.md:0-0
Timestamp: 2026-01-08T23:16:02.639Z
Learning: Applies to docs/conventions/**/*.{ts,tsx,js,jsx} : Fail-fast over silent fallbacks. Never use fallback chains (`value ?? backup ?? 'unknown'`). If data should exist, validate and throw a clear error.
Applied to files:
docs/conventions/anti-patterns.md
📚 Learning: 2026-01-06T23:01:34.751Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: All validation of extraction config must occur at config load time, not during extraction. Invalid configs should fail fast with clear error messages that include paths and descriptive information
Applied to files:
packages/riviere-extract-config/src/validation.tspackages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-config/src/validation-extends.spec.tspackages/riviere-extract-config/src/types.ts
📚 Learning: 2026-01-09T20:08:30.350Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 88
File: packages/riviere-cli/src/commands/extract/extract.spec.ts:33-38
Timestamp: 2026-01-09T20:08:30.350Z
Learning: In test files (*.spec.ts, *.test.ts), type guards like `isExtractionOutput(value: unknown): value is ExtractionOutput` should focus on narrowing types for TypeScript rather than comprehensive validation. Actual shape validation is handled through explicit test assertions (e.g., `expect(result).toMatchObject(...)`). This keeps type guards simple while maintaining thorough validation through assertion-based testing.
Applied to files:
packages/riviere-extract-config/src/validation.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement unit tests for each predicate type in isolation with positive and negative cases
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-ts/src/predicates/evaluate-predicate.tspackages/riviere-extract-ts/src/resolve-config.spec.tspackages/riviere-extract-ts/src/test-fixtures.tspackages/riviere-extract-config/src/validation-extends.spec.tspackages/riviere-extract-ts/src/extractor.spec.tspackages/riviere-extract-config/src/types.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Use ts-morph's in-memory file system (`useInMemoryFileSystem: true`) for fast isolated tests
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-ts/src/resolve-config.spec.tspackages/riviere-extract-ts/src/test-fixtures.tspackages/riviere-extract-config/src/validation-extends.spec.tspackages/riviere-extract-ts/src/extractor.spec.ts
📚 Learning: 2026-01-08T12:57:19.167Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 67
File: packages/riviere-extract-ts/tsconfig.spec.json:5-22
Timestamp: 2026-01-08T12:57:19.167Z
Learning: In tsconfig.spec.json files, use expanded types array ["vitest/globals", "vitest/importMeta", "vite/client", "node", "vitest"] for complete test type coverage. Include patterns should cover .test and .spec files, config files (vitest.config.ts/mts, vite.config.ts/mts), multiple extensions (.ts, .tsx, .js, .jsx), and .d.ts files to ensure proper TypeScript coverage across the testing environment.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-ts/src/resolve-config.spec.tspackages/riviere-extract-ts/src/test-fixtures.tspackages/riviere-extract-config/src/validation-extends.spec.tseslint.config.mjspackages/riviere-extract-ts/src/extractor.spec.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/vitest.config.mts : Enforce 100% code coverage using Vitest with v8 coverage and thresholds configured in vitest.config.mts
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-extract-ts/src/resolve-config.spec.tspackages/riviere-extract-config/src/validation-extends.spec.ts
📚 Learning: 2026-01-08T19:36:17.306Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/codebase-structure.md:0-0
Timestamp: 2026-01-08T19:36:17.306Z
Learning: Applies to docs/conventions/packages/*/vitest.config.ts : Each package must include a vitest.config.ts file with 100% coverage thresholds for test configuration.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.ts
📚 Learning: 2026-01-10T10:14:57.499Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-10T10:14:57.499Z
Learning: Applies to **/vitest.config.ts : When creating new projects with tests, add vitest.config.ts with 100% coverage as the default
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-extract-config/src/validation.spec.ts
📚 Learning: 2026-01-08T19:36:17.306Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/codebase-structure.md:0-0
Timestamp: 2026-01-08T19:36:17.306Z
Learning: Applies to docs/conventions/apps/*/vitest.config.ts : Each app must include a vitest.config.ts file with 100% coverage thresholds for test configuration.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.ts
📚 Learning: 2026-01-08T06:46:00.609Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 66
File: packages/riviere-extract-conventions/src/eslint/require-component-decorator.spec.ts:19-21
Timestamp: 2026-01-08T06:46:00.609Z
Learning: In test files using typescript-eslint/rule-tester's RuleTester.run(), ensure there is an explicit it() block with at least one expect() assertion (e.g., expect(rule).toBeDefined()) to satisfy sonarjs/no-empty-test-file and sonarjs/assertions-in-tests lint rules, which don’t recognize RuleTester's internal test blocks. Apply this pattern to all spec.ts test files to maintain consistency and pass lint checks.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-ts/src/resolve-config.spec.tspackages/riviere-extract-config/src/validation-extends.spec.tspackages/riviere-extract-ts/src/extractor.spec.ts
📚 Learning: 2026-01-10T08:54:09.466Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 96
File: apps/docs/.vitepress/theme/eclairLinkHandler.spec.ts:229-249
Timestamp: 2026-01-10T08:54:09.466Z
Learning: In jsdom test environments, window.location.assign cannot be spied on due to TypeError: Cannot redefine property. Use Object.defineProperty to mock the entire window.location object, replacing it with a controlled mock, and restore the original in afterEach. Ensure to clean up the mock after each test to avoid side effects.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-ts/src/resolve-config.spec.tspackages/riviere-extract-config/src/validation-extends.spec.tspackages/riviere-extract-ts/src/extractor.spec.ts
📚 Learning: 2026-01-09T20:08:30.350Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 88
File: packages/riviere-cli/src/commands/extract/extract.spec.ts:33-38
Timestamp: 2026-01-09T20:08:30.350Z
Learning: In test files, keep type guard implementations like isExtractionOutput(value: unknown): value is ExtractionOutput focused on narrowing types for TypeScript. Do not perform comprehensive runtime shape validation in type guards; rely on explicit test assertions (e.g., expect(result).toMatchObject(...)) for shape checks. This keeps type guards simple and rely on assertion-based tests for thorough validation.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-ts/src/resolve-config.spec.tspackages/riviere-extract-config/src/validation-extends.spec.tspackages/riviere-extract-ts/src/extractor.spec.ts
📚 Learning: 2026-01-09T20:08:44.180Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 88
File: packages/riviere-cli/src/commands/extract/extract.ts:109-114
Timestamp: 2026-01-09T20:08:44.180Z
Learning: In packages/riviere-cli/src/commands/extract/**/*.{ts,tsx}, CLI extraction commands should only catch and format expected validation errors as structured JSON. Do not wrap or convert system-level exceptions (e.g., disk I/O failures, OOM, AST parse errors) into JSON errors; instead, fail loudly with stack traces to aid debugging. Follow fail-fast principles: validate inputs explicitly, and surface unexpected failures clearly.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-cli/src/commands/extract/config-loader.tspackages/riviere-cli/src/commands/extract/extract.ts
📚 Learning: 2026-01-10T10:14:57.499Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-10T10:14:57.499Z
Learning: Applies to **/*.{js,ts,jsx,tsx} : Follow eslint configuration rules defined in `eslint.config.mjs` for all linting
Applied to files:
eslint.config.mjs
📚 Learning: 2026-01-07T08:54:48.071Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/workflow/code-review.md:0-0
Timestamp: 2026-01-07T08:54:48.071Z
Learning: Applies to docs/workflow/**/*.{ts,tsx,js,jsx} : Check lint rules (eslint.config.mjs) before providing feedback to ensure suggestions don't contradict lint rules. Never suggest using banned keywords like 'as' or 'let'.
Applied to files:
eslint.config.mjs
📚 Learning: 2026-01-07T08:54:48.071Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/workflow/code-review.md:0-0
Timestamp: 2026-01-07T08:54:48.071Z
Learning: Applies to docs/workflow/**/*.{ts,tsx,js,jsx} : Review usage of `/* v8 ignore next -- preserve */` coverage skip directives. This is only acceptable for unreachable code needed to satisfy the compiler. Most cases should be solved by extracting code or writing tests to mock behavior.
Applied to files:
eslint.config.mjs
📚 Learning: 2026-01-08T22:20:13.250Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*.{ts,tsx} : Enforce the ESLint rule `require-component-decorator` to ensure all classes are annotated with component decorators
Applied to files:
eslint.config.mjspackages/riviere-extract-config/src/types.ts
📚 Learning: 2026-01-07T08:54:48.071Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/workflow/code-review.md:0-0
Timestamp: 2026-01-07T08:54:48.071Z
Learning: Applies to docs/workflow/**/*.{ts,tsx,js,jsx,!(**/*.test.ts,**/*.test.tsx,**/*.test.js,**/*.spec.ts,**/*.spec.tsx,**/*.spec.js)} : All production code (not test files) must align with architecture boundaries and layering requirements as defined in @/docs/architecture/overview.md and @/docs/conventions/codebase-structure.md
Applied to files:
eslint.config.mjs
📚 Learning: 2026-01-07T08:54:48.071Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/workflow/code-review.md:0-0
Timestamp: 2026-01-07T08:54:48.071Z
Learning: Applies to docs/workflow/**/*.{ts,tsx,js,jsx,!(**/*.test.ts,**/*.test.tsx,**/*.test.js,**/*.spec.ts,**/*.spec.tsx,**/*.spec.js)} : All production code must comply with anti-patterns guidelines defined in @/docs/conventions/anti-patterns.md. Violations are hard failures unless documented exceptions exist.
Applied to files:
eslint.config.mjs
📚 Learning: 2026-01-08T22:20:13.250Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: For custom architectural conventions not covered by standard decorators, implement custom enforcement through ESLint rules or CI checks
Applied to files:
eslint.config.mjs
📚 Learning: 2026-01-08T07:05:01.766Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-conventions/CLAUDE.md:0-0
Timestamp: 2026-01-08T07:05:01.766Z
Learning: Configure ESLint to enforce component decorators on classes using the `require-component-decorator` rule from `living-architecture/riviere-extract-conventions/eslint-plugin`
Applied to files:
eslint.config.mjs
📚 Learning: 2026-01-08T22:20:13.250Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*.{ts,tsx} : Apply decorators from `living-architecture/riviere-extract-conventions` to mark all classes as architectural components
Applied to files:
eslint.config.mjspackages/riviere-extract-ts/src/extractor.tspackages/riviere-extract-config/src/types.tspackages/riviere-cli/src/output.ts
📚 Learning: 2026-01-08T07:05:01.766Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-conventions/CLAUDE.md:0-0
Timestamp: 2026-01-08T07:05:01.766Z
Learning: Applies to packages/riviere-extract-conventions/**/*.ts : Use `Custom(type)` decorator to annotate components with custom types not covered by standard decorators
Applied to files:
packages/riviere-extract-ts/src/extractor.tspackages/riviere-extract-config/src/types.ts
📚 Learning: 2026-01-06T23:01:34.751Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: The `find` field in extraction config describes user intent (what components to extract), not the implementation strategy. For example, `find: "methods"` means "I want methods as architectural components", not "find classes then extract methods"
Applied to files:
packages/riviere-extract-ts/src/extractor.ts
📚 Learning: 2026-01-06T08:11:15.403Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 53
File: packages/riviere-extract-config/vitest.config.mts:20-20
Timestamp: 2026-01-06T08:11:15.403Z
Learning: In packages/riviere-extract-config/vitest.config.mts, the explicit tuple type assertion for the reporter configuration (`as ['text', ['lcov', { projectRoot: string }]]`) is necessary because vitest's CoverageReporter type requires the exact tuple shape; neither inference nor 'as const' produces a compatible type.
Applied to files:
packages/riviere-extract-ts/src/extractor.spec.ts
📚 Learning: 2026-01-11T11:17:09.319Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.319Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Assert specific values, not types. Use `expect(result).toEqual(['First.', ' Second.'])` not `expect(result).toBeDefined()`. Specific assertions catch specific bugs.
Applied to files:
packages/riviere-extract-ts/src/extractor.spec.ts
📚 Learning: 2026-01-06T23:01:34.751Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Extraction config must support exactly eight predicate types that can be composed with and/or logic to filter architectural components
Applied to files:
packages/riviere-extract-config/src/types.ts
📚 Learning: 2026-01-06T23:01:34.751Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: The `where` field in extraction config describes filter predicates that qualify components. Predicates must directly match the extraction target (e.g., `hasDecorator` for decorated items, `inClassWith` for methods within qualifying classes)
Applied to files:
packages/riviere-extract-config/src/types.ts
📚 Learning: 2026-01-08T07:05:01.766Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-conventions/CLAUDE.md:0-0
Timestamp: 2026-01-08T07:05:01.766Z
Learning: Applies to packages/riviere-extract-conventions/**/*.ts : Use `DomainOp`, `APIEndpoint`, or `EventHandler` method-level decorators to mark individual methods as components
Applied to files:
packages/riviere-cli/src/output.ts
📚 Learning: 2026-01-08T07:05:01.766Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-conventions/CLAUDE.md:0-0
Timestamp: 2026-01-08T07:05:01.766Z
Learning: Applies to packages/riviere-extract-conventions/**/*.ts : Use `Ignore` decorator to exclude classes or methods from architectural extraction analysis
Applied to files:
packages/riviere-cli/src/output.ts
🧬 Code graph analysis (7)
packages/riviere-extract-ts/src/resolve-config.ts (2)
packages/riviere-extract-ts/src/index.ts (2)
ConfigLoader(6-6)resolveConfig(6-6)packages/riviere-extract-config/src/types.ts (5)
Module(84-93)ExtractionConfig(99-102)ResolvedExtractionConfig(108-111)ModuleConfig(68-78)ComponentRule(61-61)
packages/riviere-extract-config/src/validation.spec.ts (2)
packages/riviere-extract-config/src/validation.ts (1)
isValidExtractionConfig(16-18)packages/riviere-extract-config/src/validation-fixtures.ts (2)
createMinimalConfig(42-44)createResolvedConfig(46-48)
packages/riviere-extract-ts/src/test-fixtures.ts (2)
packages/riviere-extract-config/src/validation-fixtures.ts (2)
createMinimalModule(29-40)createResolvedConfig(46-48)packages/riviere-extract-config/src/types.ts (2)
Module(84-93)ResolvedExtractionConfig(108-111)
packages/riviere-extract-config/src/validation-extends.spec.ts (2)
packages/riviere-extract-config/src/index.ts (1)
validateExtractionConfig(4-4)packages/riviere-extract-config/src/validation-fixtures.ts (1)
createMinimalModule(29-40)
packages/riviere-extract-ts/src/extractor.ts (2)
packages/riviere-extract-ts/src/index.ts (2)
extractComponents(2-2)DraftComponent(2-2)packages/riviere-extract-config/src/types.ts (1)
ResolvedExtractionConfig(108-111)
packages/riviere-extract-ts/src/extractor.spec.ts (3)
packages/riviere-extract-ts/src/test-fixtures.ts (1)
createResolvedConfig(18-20)packages/riviere-extract-config/src/validation-fixtures.ts (1)
createResolvedConfig(46-48)packages/riviere-extract-config/src/types.ts (1)
ResolvedExtractionConfig(108-111)
packages/riviere-cli/src/commands/extract/extract.ts (4)
packages/riviere-cli/src/commands/extract/config-loader.ts (1)
createConfigLoader(89-98)packages/riviere-extract-ts/src/resolve-config.ts (1)
resolveConfig(18-26)packages/riviere-extract-ts/src/index.ts (2)
resolveConfig(6-6)extractComponents(2-2)packages/riviere-extract-ts/src/extractor.ts (1)
extractComponents(61-67)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: main
- GitHub Check: browser-tests (firefox)
- GitHub Check: browser-tests (webkit)
- GitHub Check: Cloudflare Pages
Replace string-based error detection with instanceof check using new PackageConfigNotFoundError class. Enhance isExtendedConfig type guard to validate modules array structure. Add source parameter to parseConfigContent for better error context. Co-Authored-By: Claude Opus 4.5 <[email protected]>
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Fix all issues with AI agents
In @packages/riviere-cli/src/commands/extract/config-loader.spec.ts:
- Around line 20-74: Add a regression test to assert that Windows absolute paths
are treated as file paths (not packages) by isPackageReference: in
packages/riviere-cli/src/commands/extract/config-loader.spec.ts add a test that
calls isPackageReference('C:\\\\project\\\\base.json') and expects false (and/or
that createConfigLoader('/project') resolves that path as a file when passed a
Windows absolute path). If isPackageReference currently uses a string-prefix
check, change it to use Node's path.isAbsolute(...) to detect absolute file
paths (ensuring Windows drive-letter paths return false from
isPackageReference).
In @packages/riviere-cli/src/commands/extract/config-loader.ts:
- Around line 31-51: The error-reporting in parseConfigContent can itself throw
when creating the preview with JSON.stringify; wrap the stringify in a safe
try/catch (or use a non-throwing fallback like util.inspect or a replacer that
converts BigInt to string) so that isExtendedConfig failures always produce the
intended Error; modify parseConfigContent to build preview via a safeSerialize
helper (try JSON.stringify(parsed, null, 2) inside try/catch and on error fall
back to String(parsed) or util.inspect(parsed, {depth:1})) and use that preview
in the thrown Error.
- Around line 77-99: isPackageReference() misdetects Windows absolute paths and
resolvePackagePath() uses bare require which fails in ESM; update
isPackageReference to treat any absolute path as non-package by using
path.isAbsolute(source) (keep the existing dot-prefix check), and change
resolvePackagePath to use createRequire(import.meta.url) from the 'module'
package (import createRequire) to obtain a local require function before calling
require.resolve(`${packageName}/package.json`), leaving the existing
dirname/resolve/existsSync logic and error handling intact.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
packages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-cli/src/commands/extract/config-loader.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Follow eslint configuration rules defined in
eslint.config.mjsfor all linting
Files:
packages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-cli/src/commands/extract/config-loader.ts
**/*.{ts,tsx,js,jsx,css,scss,html}
📄 CodeRabbit inference engine (CLAUDE.md)
All UI and UX design must conform to global brand guidelines in
/docs/brand/(logo, colors, typography, icons)
Files:
packages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-cli/src/commands/extract/config-loader.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,js,jsx}: Do not log sensitive data (passwords, tokens, PII) in any code
Validate and sanitize all external input
Files:
packages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-cli/src/commands/extract/config-loader.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use cross-project imports with package names (e.g.,
import { X } from '@living-architecture/[pkg-name]') rather than relative paths
Files:
packages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-cli/src/commands/extract/config-loader.ts
🧠 Learnings (38)
📓 Common learnings
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Use glob pattern matching for module-based organization of extraction rules
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Applies to packages/riviere-extract-config/**/*.ts : Extraction config schema is the source of truth for valid structures. TypeScript types must mirror the schema definition to maintain consistency
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.{json,ts} : Define extraction configuration using the JSON Schema from `living-architecture/riviere-extract-config` DSL
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Reject invalid extraction configs at load time, not during extraction phase
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use `living-architecture/riviere-extract-ts` TypeScript extractor with ts-morph for AST parsing when implementing TypeScript extraction for architecture schema components
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement integration tests for end-to-end extraction from TypeScript code to JSON output
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Implement extraction logic as pure functions with no side effects
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-conventions/CLAUDE.md:0-0
Timestamp: 2026-01-08T07:05:01.766Z
Learning: Import and use the default extraction config from `living-architecture/riviere-extract-conventions/default-config` in extraction tooling to detect all 6 component types
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Compose detection rules via and/or logic for predicates
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: All extraction rules should come from validated ExtractionConfig provided by riviere-extract-config
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement integration tests for end-to-end extraction from TypeScript code to JSON output
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Use ts-morph's in-memory file system (`useInMemoryFileSystem: true`) for fast isolated tests
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Reject invalid extraction configs at load time, not during extraction phase
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement unit tests for each predicate type in isolation with positive and negative cases
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-06T23:01:34.751Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Applies to packages/riviere-extract-config/**/*.ts : Extraction config schema is the source of truth for valid structures. TypeScript types must mirror the schema definition to maintain consistency
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Use glob pattern matching for module-based organization of extraction rules
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*-fixtures.ts : Create `<module>-fixtures.ts` fixture files alongside `<module>.spec.ts` to reduce duplication when multiple tests share similar setup data or differ only in specific values being tested.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.ts
📚 Learning: 2026-01-08T12:57:19.167Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 67
File: packages/riviere-extract-ts/tsconfig.spec.json:5-22
Timestamp: 2026-01-08T12:57:19.167Z
Learning: In tsconfig.spec.json files, use expanded types array ["vitest/globals", "vitest/importMeta", "vite/client", "node", "vitest"] for complete test type coverage. Include patterns should cover .test and .spec files, config files (vitest.config.ts/mts, vite.config.ts/mts), multiple extensions (.ts, .tsx, .js, .jsx), and .d.ts files to ensure proper TypeScript coverage across the testing environment.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/vitest.config.mts : Enforce 100% code coverage using Vitest with v8 coverage and thresholds configured in vitest.config.mts
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Implement extraction logic as pure functions with no side effects
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T19:36:17.306Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/codebase-structure.md:0-0
Timestamp: 2026-01-08T19:36:17.306Z
Learning: Applies to docs/conventions/packages/*/vitest.config.ts : Each package must include a vitest.config.ts file with 100% coverage thresholds for test configuration.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.ts
📚 Learning: 2026-01-10T10:14:57.499Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-10T10:14:57.499Z
Learning: Applies to **/vitest.config.ts : When creating new projects with tests, add vitest.config.ts with 100% coverage as the default
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.ts
📚 Learning: 2026-01-08T19:36:17.306Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/codebase-structure.md:0-0
Timestamp: 2026-01-08T19:36:17.306Z
Learning: Applies to docs/conventions/apps/*/vitest.config.ts : Each app must include a vitest.config.ts file with 100% coverage thresholds for test configuration.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.ts
📚 Learning: 2026-01-11T11:04:34.655Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/anti-patterns.md:0-0
Timestamp: 2026-01-11T11:04:34.655Z
Learning: When hitting max-lines limits, split files into focused modules (e.g., `foo.spec.ts` and `foo.edge-cases.spec.ts`), extract duplicated code into shared modules, or use parameterized tests with `it.each` or `describe.each` instead of removing tests or compressing code.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T06:46:00.609Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 66
File: packages/riviere-extract-conventions/src/eslint/require-component-decorator.spec.ts:19-21
Timestamp: 2026-01-08T06:46:00.609Z
Learning: In test files using typescript-eslint/rule-tester's RuleTester.run(), ensure there is an explicit it() block with at least one expect() assertion (e.g., expect(rule).toBeDefined()) to satisfy sonarjs/no-empty-test-file and sonarjs/assertions-in-tests lint rules, which don’t recognize RuleTester's internal test blocks. Apply this pattern to all spec.ts test files to maintain consistency and pass lint checks.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.ts
📚 Learning: 2026-01-10T08:54:09.466Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 96
File: apps/docs/.vitepress/theme/eclairLinkHandler.spec.ts:229-249
Timestamp: 2026-01-10T08:54:09.466Z
Learning: In jsdom test environments, window.location.assign cannot be spied on due to TypeError: Cannot redefine property. Use Object.defineProperty to mock the entire window.location object, replacing it with a controlled mock, and restore the original in afterEach. Ensure to clean up the mock after each test to avoid side effects.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.ts
📚 Learning: 2026-01-09T20:08:30.350Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 88
File: packages/riviere-cli/src/commands/extract/extract.spec.ts:33-38
Timestamp: 2026-01-09T20:08:30.350Z
Learning: In test files, keep type guard implementations like isExtractionOutput(value: unknown): value is ExtractionOutput focused on narrowing types for TypeScript. Do not perform comprehensive runtime shape validation in type guards; rely on explicit test assertions (e.g., expect(result).toMatchObject(...)) for shape checks. This keeps type guards simple and rely on assertion-based tests for thorough validation.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.ts
📚 Learning: 2026-01-09T20:08:44.180Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 88
File: packages/riviere-cli/src/commands/extract/extract.ts:109-114
Timestamp: 2026-01-09T20:08:44.180Z
Learning: In packages/riviere-cli/src/commands/extract/**/*.{ts,tsx}, CLI extraction commands should only catch and format expected validation errors as structured JSON. Do not wrap or convert system-level exceptions (e.g., disk I/O failures, OOM, AST parse errors) into JSON errors; instead, fail loudly with stack traces to aid debugging. Follow fail-fast principles: validate inputs explicitly, and surface unexpected failures clearly.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T22:20:13.250Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.{json,ts} : Define extraction configuration using the JSON Schema from `living-architecture/riviere-extract-config` DSL
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T07:05:01.766Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-conventions/CLAUDE.md:0-0
Timestamp: 2026-01-08T07:05:01.766Z
Learning: Import and use the default extraction config from `living-architecture/riviere-extract-conventions/default-config` in extraction tooling to detect all 6 component types
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T22:20:13.250Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use the Rivière Builder Node.js library to programmatically construct the schema graph when implementing custom extraction code
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T22:20:13.250Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use `living-architecture/riviere-extract-ts` TypeScript extractor with ts-morph for AST parsing when implementing TypeScript extraction for architecture schema components
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-09T20:08:30.350Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 88
File: packages/riviere-cli/src/commands/extract/extract.spec.ts:33-38
Timestamp: 2026-01-09T20:08:30.350Z
Learning: In test files (*.spec.ts, *.test.ts), type guards like `isExtractionOutput(value: unknown): value is ExtractionOutput` should focus on narrowing types for TypeScript rather than comprehensive validation. Actual shape validation is handled through explicit test assertions (e.g., `expect(result).toMatchObject(...)`). This keeps type guards simple while maintaining thorough validation through assertion-based testing.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T23:16:02.639Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/software-design.md:0-0
Timestamp: 2026-01-08T23:16:02.639Z
Learning: Applies to docs/conventions/**/*.{ts,tsx} : Parse, don't validate. Use Zod schemas at system boundaries to parse external data once. Don't scatter `isX(unknown): x is T` type guards throughout the codebase.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T23:16:02.639Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/software-design.md:0-0
Timestamp: 2026-01-08T23:16:02.639Z
Learning: Applies to docs/conventions/**/*.{ts,tsx,js,jsx} : Fail-Fast Error Handling: Validate and throw clear errors instead of using fallback chains. Error format: `Expected [X]. Got [Y]. Context: [debugging info]`
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-07T08:54:48.071Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/workflow/code-review.md:0-0
Timestamp: 2026-01-07T08:54:48.071Z
Learning: Applies to docs/workflow/**/*.{ts,tsx,js,jsx} : Avoid dangerous fallback values that hide bugs. Do not use `??` or `||` operators without clear reason for providing defaults. If a value is required, make it required rather than guessing at defaults. Exceptions: optional parameters with documented defaults, configuration with explicit optional semantics, and test data with placeholder values.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T23:16:02.639Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/software-design.md:0-0
Timestamp: 2026-01-08T23:16:02.639Z
Learning: Applies to docs/conventions/**/*.{ts,tsx,js,jsx} : Fail-fast over silent fallbacks. Never use fallback chains (`value ?? backup ?? 'unknown'`). If data should exist, validate and throw a clear error.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-06T08:11:15.403Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 53
File: packages/riviere-extract-config/vitest.config.mts:20-20
Timestamp: 2026-01-06T08:11:15.403Z
Learning: In packages/riviere-extract-config/vitest.config.mts, the explicit tuple type assertion for the reporter configuration (`as ['text', ['lcov', { projectRoot: string }]]`) is necessary because vitest's CoverageReporter type requires the exact tuple shape; neither inference nor 'as const' produces a compatible type.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-06T23:01:34.751Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: All validation of extraction config must occur at config load time, not during extraction. Invalid configs should fail fast with clear error messages that include paths and descriptive information
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-11T11:04:34.655Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/anti-patterns.md:0-0
Timestamp: 2026-01-11T11:04:34.655Z
Learning: Applies to docs/conventions/**/*.{ts,tsx,js,jsx} : Never parse error message strings to determine error types or extract information using `.message.includes()`, `.message.startsWith()`, or regex patterns on `error.message`. Use typed custom error classes instead.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-11T11:04:34.655Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/anti-patterns.md:0-0
Timestamp: 2026-01-11T11:04:34.655Z
Learning: Applies to docs/conventions/**/*.{ts,tsx,js,jsx} : When parsing strings in exception messages is 100% unavoidable (e.g., due to third-party library limitations), document the exception with justification, reference tracking issue, and note that upstream fix was requested.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-07T08:54:48.071Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/workflow/code-review.md:0-0
Timestamp: 2026-01-07T08:54:48.071Z
Learning: Applies to docs/workflow/**/*.{ts,tsx,js,jsx} : Review usage of `/* v8 ignore next -- preserve */` coverage skip directives. This is only acceptable for unreachable code needed to satisfy the compiler. Most cases should be solved by extracting code or writing tests to mock behavior.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T23:16:02.639Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/software-design.md:0-0
Timestamp: 2026-01-08T23:16:02.639Z
Learning: Applies to docs/conventions/**/*.{ts,tsx} : Use Zod for runtime validation. In TypeScript, use Zod schemas for parsing external data, API responses, and user input. Type inference from schemas keeps types and validation in sync.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T19:36:17.306Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/codebase-structure.md:0-0
Timestamp: 2026-01-08T19:36:17.306Z
Learning: Applies to docs/conventions/**/*.{ts,tsx} : Use living-architecture/[pkg-name] for imports from other workspace projects, not relative paths like ../../packages/[pkg-name].
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-10T10:14:57.499Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-10T10:14:57.499Z
Learning: Applies to **/*.{ts,tsx} : Use cross-project imports with package names (e.g., `import { X } from 'living-architecture/[pkg-name]'`) rather than relative paths
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T19:36:17.306Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/codebase-structure.md:0-0
Timestamp: 2026-01-08T19:36:17.306Z
Learning: Applies to docs/conventions/packages/*/package.json : When importing from another project, add explicit workspace dependencies to package.json using the format "living-architecture/[pkg-name]": "workspace:*" and run pnpm install.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: All extraction rules should come from validated ExtractionConfig provided by riviere-extract-config
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
🧬 Code graph analysis (2)
packages/riviere-cli/src/commands/extract/config-loader.spec.ts (1)
packages/riviere-cli/src/commands/extract/config-loader.ts (1)
createConfigLoader(112-121)
packages/riviere-cli/src/commands/extract/config-loader.ts (3)
packages/riviere-extract-config/src/types.ts (1)
Module(84-93)packages/riviere-extract-ts/src/resolve-config.ts (1)
ConfigLoader(10-10)packages/riviere-extract-ts/src/index.ts (1)
ConfigLoader(6-6)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: browser-tests (firefox)
- GitHub Check: browser-tests (webkit)
- GitHub Check: browser-tests (chromium)
- GitHub Check: main
- GitHub Check: Cloudflare Pages
🔇 Additional comments (4)
packages/riviere-cli/src/commands/extract/config-loader.ts (1)
112-121: Clean, minimal loader API; nice fit withresolveConfig’sConfigLoaderhook.The
createConfigLoader(configDir) => (source) => Moduleshape is easy to wire into config resolution, and the separation (resolvePackagePath/loadConfigFile/extractModuleFromConfig) keeps responsibilities clear.packages/riviere-cli/src/commands/extract/config-loader.spec.ts (3)
11-19: Mock lifecycle looks good.Resetting mocks before each test and restoring after each keeps suites isolated.
76-175: Extraction behavior tests are solid (modules[0] vs top-level defaults).Covers “prefer module entry” and “fill missing rules with
{ notUsed: true }” well.
177-215: Package resolution tests may be environment-coupled; consider mocking module resolution.These tests assume
require.resolve('@living-architecture/riviere-extract-conventions/package.json')works in the test runtime and that the package layout containssrc/default-extraction.config.json. If CI/package manager layout changes, this suite could become flaky; mocking the resolver boundary (or injecting it) would make this deterministic.
Adds review feedback check for .message.includes() and similar patterns. Hard fail - no decisions based on error message content. Explicitly calls out that `error instanceof Error && error.message.includes()` is still string-based detection and not allowed. Co-Authored-By: Claude Opus 4.5 <[email protected]>
Add ESLint rule banning `new Error()` to enforce use of custom error classes with semantic names throughout the codebase. Changes: - Add no-restricted-syntax rule for NewExpression[callee.name="Error"] - Create custom error classes in each package (errors.ts files) - Replace all `throw new Error()` with specific error types - Add MockError for test mocking scenarios - Add comprehensive tests for all new error classes Co-Authored-By: Claude Opus 4.5 <[email protected]>
Export custom error classes so consumers can catch them: - ExtractionConfigValidationError from riviere-extract-config - RiviereSchemaValidationError, InvalidComponentIdError from riviere-schema - Make TestAssertionError internal (not exported) Co-Authored-By: Claude Opus 4.5 <[email protected]>
There was a problem hiding this comment.
Actionable comments posted: 19
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
packages/riviere-schema/src/component-id.ts (1)
81-88:ComponentId.parsemust reject empty segments and validate all four parts are non-empty.Currently,
parse('a:b:c:')succeeds because the check only validatesparts.length !== 4andname !== undefined, but an empty string is not undefined. This violates the documented formatdomain:module:type:namewhere each segment must be present.Additionally,
InvalidComponentIdErroris not exported from the package entrypoint (src/index.ts), forcing downstream code to use a deep import to catch the error. Export it alongsideComponentIdso consumers can properly handle validation failures via@living-architecture/riviere-schema.Proposed fix
static parse(id: string): ComponentId { - const parts = id.split(':') - const name = parts[3] - if (parts.length !== 4 || name === undefined) { - throw new InvalidComponentIdError(id) + const trimmed = id.trim() + const parts = trimmed.split(':') + if (parts.length !== 4 || parts.some((p) => p.length === 0)) { + throw new InvalidComponentIdError(id) + } + const name = parts[3]! + return new ComponentId(name, trimmed) } - return new ComponentId(name, id) }In
src/index.ts:export { - ComponentId, type ComponentIdParts + ComponentId, InvalidComponentIdError, type ComponentIdParts } from './component-id'apps/eclair/src/features/comparison/ComparisonPage.detailedChanges.spec.tsx (1)
20-39: Extract duplicated test helper to shared fixture file.The
stubFileReaderWithMultipleContentsfunction is duplicated in bothComparisonPage.spec.tsx(lines 64-83) and this file. Consider extracting it to a shared test fixture file such ascomparison-test-fixtures.tsto eliminate duplication.Based on learnings, create fixture files alongside spec files to reduce duplication when multiple tests share similar setup data.
packages/riviere-cli/src/commands/builder/add-component.ts (1)
105-125: Don’t useMissingRequiredOptionErrorfor invalid--api-type.Line 110-112 throws “missing required option” even when
--api-typeis present but invalid; that’s misleading for users and makes error handling harder downstream. Consider a dedicatedInvalidApiTypeError(or reuse an existing “invalid value” error) and keepMissingRequiredOptionErrorstrictly for absence.
🤖 Fix all issues with AI agents
In @apps/eclair/src/errors.spec.ts:
- Around line 1-151: Add edge-case tests to errors.spec.ts that instantiate each
error class (EclairError, GraphError, RenderingError, LayoutError, ContextError,
CSSModuleError, DOMError, SchemaError) with empty string, whitespace-only
string, a very long string (e.g., 1000+ chars), Unicode (emoji/RTL/combining
chars), and special characters (quotes/backslashes), and assert the .message and
.name behave as expected; for ContextError and CSSModuleError include tests
where hook/provider/class/module names contain special/unicode characters and
verify the constructed message matches the precise formatted string.
In @apps/eclair/src/lib/riviereTestFixtures.ts:
- Around line 26-31: Duplicate class TestAssertionError is declared locally;
instead import the existing TestAssertionError from the shared test-assertions
module and remove the local class declaration. Update the top-of-file imports to
import TestAssertionError and delete the local class TestAssertionError {
constructor(...) { ... } } so all code uses the single canonical
TestAssertionError type.
In @apps/eclair/src/test-assertions.ts:
- Around line 1-6: The TestAssertionError class is duplicated across multiple
test modules; extract it into a shared test utilities package (e.g., export
class TestAssertionError from a new @living-architecture/test-utils) and replace
the local definitions with imports from that package. Create and publish (or add
as a workspace package) the shared module exporting TestAssertionError, update
each test consumer to import { TestAssertionError } instead of redefining it,
and add the new package as a devDependency/workspace dependency in consuming
package.json files and their test build configs.
In @apps/eclair/src/test/setup.ts:
- Line 6: TestAssertionError is duplicated across multiple test modules; remove
the duplicates and consolidate into a single shared test utility that exports
the TestAssertionError class, then update all places that currently define their
own TestAssertionError to import the shared export instead; ensure the shared
module exports the class (named TestAssertionError), preserves its
constructor/signature and any custom properties, update imports in test fixtures
and specs to reference the new shared export, and run tests to verify no type or
import mismatches remain.
In @packages/riviere-builder/src/builder-near-matches.spec.ts:
- Around line 6-11: TestAssertionError is duplicated across multiple test files;
extract it into a single shared test utility and import it instead of
redefining; create a test-utils.ts (or a shared test-utils package) that exports
class TestAssertionError and update local declarations (e.g., in
builder-near-matches.spec.ts) to import { TestAssertionError } from that module,
then remove the duplicate class definitions from the other test files and
replace them with imports.
In @packages/riviere-cli/src/cli.ts:
- Around line 28-42: Update the JSDoc for parsePackageJson to accurately
document the thrown error: replace the generic "@throws Error" with "@throws
{InvalidPackageJsonError}" and add a short description like "when package.json
is invalid or missing version" so callers see that parsePackageJson throws
InvalidPackageJsonError; reference the parsePackageJson function and the
InvalidPackageJsonError type in the docblock.
- Around line 34-42: The parsePackageJson function narrows pkg with a type-guard
but still accesses pkg.version from an unknown; after the initial guard (typeof
pkg !== 'object' || pkg === null || !('version' in pkg')) cast pkg to a concrete
shape like Record<string, unknown> (or an intermediate type) before checking
typeof pkg.version and returning it, so the access is explicit and robust
against future TS narrowing changes; update references inside parsePackageJson
accordingly (pkg, pkg.version, and the InvalidPackageJsonError checks).
In @packages/riviere-cli/src/command-test-fixtures.ts:
- Around line 18-23: TestAssertionError is duplicated across multiple files;
extract it into a single shared test utility module (e.g., export class
TestAssertionError in a new package or shared file) and replace the inline class
definitions with imports; update each location referencing the class
(TestAssertionError in command-test-fixtures.ts, test-assertions.ts,
default-config-fixtures.ts, riviere-graph-fixtures.ts) to import the shared
TestAssertionError and remove the local definition so all code uses the single
exported implementation.
In @packages/riviere-cli/src/commands/builder/add-component.spec.ts:
- Line 14: The test is using the test fixture MockError instead of the real
Error class, which makes the instanceof Error branch of getErrorMessage
untested; update the spec to instantiate and throw a real Error (use new
Error(...)) where MockError is used (references: getErrorMessage, MockError in
add-component.spec.ts) and replace the other occurrence mentioned (line ~355)
similarly so the test validates the production instanceof Error behavior.
In @packages/riviere-cli/src/commands/builder/finalize.spec.ts:
- Around line 57-69: The assertion helpers assertFinalizeSuccess and
assertFinalizeError throw generic TestAssertionError messages; include a short
serialized preview of the received value in those error messages to make
failures actionable. Update assertFinalizeSuccess(value: unknown) and
assertFinalizeError(value: unknown) to, on failure, call TestAssertionError with
a message like "Expected FinalizeSuccessOutput — received: <preview>" (use
JSON.stringify with a try/catch and fallback to String(value) and truncate the
preview if too long). Ensure only the message changes—keep the same type guard
checks and return value behavior.
- Around line 50-55: The test file duplicates the TestAssertionError class;
remove the local class definition in finalize.spec.ts and import the shared
TestAssertionError exported from command-test-fixtures (use the exported symbol
name TestAssertionError), updating the file's imports accordingly so all tests
use the single shared TestAssertionError helper.
In @packages/riviere-cli/src/commands/builder/init-options.spec.ts:
- Around line 29-34: Remove the duplicated local TestAssertionError class and
import the shared one instead: delete the local class definition named
TestAssertionError and add TestAssertionError to the existing import list from
command-test-fixtures in this file so the shared definition is used (update the
existing import statement to include TestAssertionError).
In @packages/riviere-cli/src/commands/extract/config-loader.ts:
- Around line 92-111: The code uses require.resolve directly in
resolvePackagePath (and the other similar site at lines ~122-129), which is
unsafe in ESM and can resolve from the CLI instead of the user project; replace
direct require.resolve with a require created via createRequire() anchored to
the config file/directory: import { createRequire } from 'module', call
createRequire(pathToConfigOrDir) to get a local require, then use that
localRequire.resolve(`${packageName}/package.json`) to find the package.json and
continue as before (keep the same PackageConfigNotFoundError /
PackageResolveError handling); apply the same change to the other occurrence
referenced in the review.
- Around line 51-90: isTopLevelRulesConfig currently treats arrays and arbitrary
objects as valid; tighten it to only accept plain non-array objects by adding an
Array.isArray check, and in parseConfigContent, instead of synthesizing the
"extended" Module directly, run the parsed value through parseExtractionConfig
(and resolveConfig if needed) to validate rule shapes and construct a Module
from the validated config (use parseExtractionConfig/resolveConfig to produce a
module shape or throw ConfigSchemaValidationError), referencing
isTopLevelRulesConfig, parseConfigContent, parseExtractionConfig, resolveConfig,
TopLevelRulesConfig and Module to locate where to apply the checks and
validation.
In @packages/riviere-cli/src/errors.ts:
- Around line 111-116: The InternalSchemaValidationError currently has no debug
context; update the constructor of class InternalSchemaValidationError to accept
an optional context parameter (e.g., configSource: string or details: unknown),
include that context in the error message passed to super (or append it to a new
readonly property like this.context), and set this.name as before; ensure any
code that throws new InternalSchemaValidationError is updated or can pass
undefined so existing behavior remains compatible.
In @packages/riviere-extract-conventions/src/default-config-fixtures.ts:
- Around line 13-18: The TestAssertionError class is duplicated across multiple
modules; remove the local definitions and centralize it by creating or using a
single shared export (e.g., export class TestAssertionError) in a common
test-utilities module, then update each file that currently defines
TestAssertionError to import { TestAssertionError } from that shared module
(replace the local constructor/this.name assignment with the import). Ensure the
shared module exports the same class shape (constructor(message: string) {
super(message); this.name = 'TestAssertionError' }) and update any package
build/test configs so the new test-utilities package is available as a dev/test
dependency.
In @packages/riviere-extract-ts/src/resolve-config.ts:
- Around line 12-13: Document the ConfigLoader contract by expanding the
ConfigLoader type comment to state which errors it may throw (e.g.,
PackageResolveError, ConfigFileNotFoundError), require that it returns a fully
resolved Module including all component rules, and enumerate the validation
responsibilities (schema validation, required fields present, and component rule
resolution). Reference the ConfigLoader type and the Module return type
explicitly and mention that callers expect these specific errors for error
handling and that the loader must perform validation and normalization before
returning the Module.
In @packages/riviere-query/src/riviere-graph-fixtures.ts:
- Around line 12-17: TestAssertionError is duplicated across multiple packages;
extract the class into a shared test utilities module (e.g., add/export
TestAssertionError from @living-architecture/test-utils or a new shared tests
package), remove the local definitions (e.g., the TestAssertionError class in
riviere-graph-fixtures), and update all call sites to import {
TestAssertionError } from the shared module (replace local declarations in
apps/eclair/src/test-assertions.ts,
packages/riviere-cli/src/command-test-fixtures.ts,
packages/riviere-extract-conventions/src/default-config-fixtures.ts, and
packages/riviere-query/src/riviere-graph-fixtures.ts with the centralized
import).
In @packages/riviere-schema/src/component-id.ts:
- Around line 11-19: The InvalidComponentIdError class needs to fix its
prototype and capture the stack so instanceof checks and stack traces work
across targets: inside the constructor of InvalidComponentIdError (and after
calling super) call Object.setPrototypeOf(this,
InvalidComponentIdError.prototype) and, if available, use
Error.captureStackTrace(this, InvalidComponentIdError) to populate the stack;
keep the existing message and name assignment.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In @packages/riviere-query/src/riviere-graph-fixtures.ts:
- Around line 12-17: The TestAssertionError class is duplicated; extract the
class into a shared test utilities module (e.g., export TestAssertionError from
a new or existing package such as @living-architecture/test-utils), remove the
local class declarations (including the one named TestAssertionError in this
file), export it from the shared package, and update all consumers to import {
TestAssertionError } from that shared package instead of redeclaring the class
so all references (TestAssertionError) use the centralized implementation.
In @packages/riviere-schema/src/index.ts:
- Around line 3-6: Add documentation for RiviereSchemaValidationError to
README.md describing that parseRiviereGraph throws this specific error when
schema validation fails, what fields/details it contains, and recommended
consumer handling (catch by class, inspect validation payload). Add a unit test
in schema.spec.ts that imports RiviereSchemaValidationError and calls
parseRiviereGraph with an invalid graph, then asserts the thrown error is an
instance of RiviereSchemaValidationError (e.g., using instanceof or
framework-specific matchers) and optionally checks its validation payload rather
than only matching the error message.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (3)
packages/riviere-extract-config/src/index.tspackages/riviere-query/src/riviere-graph-fixtures.tspackages/riviere-schema/src/index.ts
🧰 Additional context used
📓 Path-based instructions (5)
packages/riviere-extract-config/**/*.ts
📄 CodeRabbit inference engine (packages/riviere-extract-config/CLAUDE.md)
Extraction config schema is the source of truth for valid structures. TypeScript types must mirror the schema definition to maintain consistency
Files:
packages/riviere-extract-config/src/index.ts
**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Follow eslint configuration rules defined in
eslint.config.mjsfor all linting
Files:
packages/riviere-extract-config/src/index.tspackages/riviere-schema/src/index.tspackages/riviere-query/src/riviere-graph-fixtures.ts
**/*.{ts,tsx,js,jsx,css,scss,html}
📄 CodeRabbit inference engine (CLAUDE.md)
All UI and UX design must conform to global brand guidelines in
/docs/brand/(logo, colors, typography, icons)
Files:
packages/riviere-extract-config/src/index.tspackages/riviere-schema/src/index.tspackages/riviere-query/src/riviere-graph-fixtures.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,js,jsx}: Do not log sensitive data (passwords, tokens, PII) in any code
Validate and sanitize all external input
Files:
packages/riviere-extract-config/src/index.tspackages/riviere-schema/src/index.tspackages/riviere-query/src/riviere-graph-fixtures.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use cross-project imports with package names (e.g.,
import { X } from '@living-architecture/[pkg-name]') rather than relative paths
Files:
packages/riviere-extract-config/src/index.tspackages/riviere-schema/src/index.tspackages/riviere-query/src/riviere-graph-fixtures.ts
🧠 Learnings (32)
📓 Common learnings
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Use glob pattern matching for module-based organization of extraction rules
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.{json,ts} : Define extraction configuration using the JSON Schema from `living-architecture/riviere-extract-config` DSL
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Applies to packages/riviere-extract-config/**/*.ts : Extraction config schema is the source of truth for valid structures. TypeScript types must mirror the schema definition to maintain consistency
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use `living-architecture/riviere-extract-ts` TypeScript extractor with ts-morph for AST parsing when implementing TypeScript extraction for architecture schema components
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 129
File: packages/riviere-cli/src/commands/extract/config-loader.ts:31-39
Timestamp: 2026-01-11T14:38:35.637Z
Learning: In packages/riviere-cli/src/commands/extract/config-loader.ts, the isExtendedConfig type guard intentionally performs minimal validation (checks for non-null object and validates modules is an array if present) because comprehensive validation is handled downstream by the schema validator. The type guard's purpose is basic type narrowing to support both module-array and top-level-rules formats, not comprehensive validation. This follows the layered validation pattern where type guards are minimal and schema validation occurs at system boundaries.
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Reject invalid extraction configs at load time, not during extraction phase
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement integration tests for end-to-end extraction from TypeScript code to JSON output
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Implement extraction logic as pure functions with no side effects
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-conventions/CLAUDE.md:0-0
Timestamp: 2026-01-08T07:05:01.766Z
Learning: Import and use the default extraction config from `living-architecture/riviere-extract-conventions/default-config` in extraction tooling to detect all 6 component types
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use the Rivière Builder Node.js library to programmatically construct the schema graph when implementing custom extraction code
📚 Learning: 2026-01-06T23:01:34.751Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Applies to packages/riviere-extract-config/**/*.ts : Extraction config schema is the source of truth for valid structures. TypeScript types must mirror the schema definition to maintain consistency
Applied to files:
packages/riviere-extract-config/src/index.tspackages/riviere-schema/src/index.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Reject invalid extraction configs at load time, not during extraction phase
Applied to files:
packages/riviere-extract-config/src/index.tspackages/riviere-query/src/riviere-graph-fixtures.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Implement extraction logic as pure functions with no side effects
Applied to files:
packages/riviere-extract-config/src/index.tspackages/riviere-query/src/riviere-graph-fixtures.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Use glob pattern matching for module-based organization of extraction rules
Applied to files:
packages/riviere-extract-config/src/index.ts
📚 Learning: 2026-01-11T14:38:35.637Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 129
File: packages/riviere-cli/src/commands/extract/config-loader.ts:31-39
Timestamp: 2026-01-11T14:38:35.637Z
Learning: In packages/riviere-cli/src/commands/extract/config-loader.ts, the isExtendedConfig type guard intentionally performs minimal validation (checks for non-null object and validates modules is an array if present) because comprehensive validation is handled downstream by the schema validator. The type guard's purpose is basic type narrowing to support both module-array and top-level-rules formats, not comprehensive validation. This follows the layered validation pattern where type guards are minimal and schema validation occurs at system boundaries.
Applied to files:
packages/riviere-extract-config/src/index.ts
📚 Learning: 2026-01-08T22:20:13.250Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.{json,ts} : Define extraction configuration using the JSON Schema from `living-architecture/riviere-extract-config` DSL
Applied to files:
packages/riviere-extract-config/src/index.tspackages/riviere-schema/src/index.ts
📚 Learning: 2026-01-08T07:05:01.766Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-conventions/CLAUDE.md:0-0
Timestamp: 2026-01-08T07:05:01.766Z
Learning: Applies to packages/riviere-extract-conventions/**/*.ts : Use `Ignore` decorator to exclude classes or methods from architectural extraction analysis
Applied to files:
packages/riviere-extract-config/src/index.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement integration tests for end-to-end extraction from TypeScript code to JSON output
Applied to files:
packages/riviere-extract-config/src/index.tspackages/riviere-query/src/riviere-graph-fixtures.ts
📚 Learning: 2026-01-08T07:05:01.766Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-conventions/CLAUDE.md:0-0
Timestamp: 2026-01-08T07:05:01.766Z
Learning: Import and use the default extraction config from `living-architecture/riviere-extract-conventions/default-config` in extraction tooling to detect all 6 component types
Applied to files:
packages/riviere-extract-config/src/index.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Use ts-morph for TypeScript AST parsing instead of other parsers
Applied to files:
packages/riviere-extract-config/src/index.tspackages/riviere-query/src/riviere-graph-fixtures.ts
📚 Learning: 2026-01-06T23:01:34.751Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Extraction config schemas must define all six required component types per module: api, useCase, domainOp, event, eventHandler, and ui. Unused component types must be explicitly marked with `notUsed: true` rather than omitted
Applied to files:
packages/riviere-extract-config/src/index.ts
📚 Learning: 2026-01-06T23:01:34.751Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: All validation of extraction config must occur at config load time, not during extraction. Invalid configs should fail fast with clear error messages that include paths and descriptive information
Applied to files:
packages/riviere-extract-config/src/index.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: All extraction rules should come from validated ExtractionConfig provided by riviere-extract-config
Applied to files:
packages/riviere-extract-config/src/index.ts
📚 Learning: 2026-01-08T07:05:01.766Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-conventions/CLAUDE.md:0-0
Timestamp: 2026-01-08T07:05:01.766Z
Learning: Applies to packages/riviere-extract-conventions/**/*.ts : Use `Custom(type)` decorator to annotate components with custom types not covered by standard decorators
Applied to files:
packages/riviere-schema/src/index.ts
📚 Learning: 2026-01-02T11:58:30.913Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-schema/CLAUDE.md:0-0
Timestamp: 2026-01-02T11:58:30.913Z
Learning: Do not include riviere-schema in breaking change commits (`!` or `BREAKING CHANGE`) - this automatically bumps the major version
Applied to files:
packages/riviere-schema/src/index.ts
📚 Learning: 2026-01-08T07:05:01.766Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-conventions/CLAUDE.md:0-0
Timestamp: 2026-01-08T07:05:01.766Z
Learning: Applies to packages/riviere-extract-conventions/**/*.ts : Use `DomainOp`, `APIEndpoint`, or `EventHandler` method-level decorators to mark individual methods as components
Applied to files:
packages/riviere-schema/src/index.ts
📚 Learning: 2026-01-08T22:20:13.250Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use the Rivière Builder Node.js library to programmatically construct the schema graph when implementing custom extraction code
Applied to files:
packages/riviere-schema/src/index.ts
📚 Learning: 2026-01-08T22:20:13.250Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use `living-architecture/riviere-extract-ts` TypeScript extractor with ts-morph for AST parsing when implementing TypeScript extraction for architecture schema components
Applied to files:
packages/riviere-schema/src/index.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement unit tests for each predicate type in isolation with positive and negative cases
Applied to files:
packages/riviere-query/src/riviere-graph-fixtures.ts
📚 Learning: 2026-01-06T08:11:15.403Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 53
File: packages/riviere-extract-config/vitest.config.mts:20-20
Timestamp: 2026-01-06T08:11:15.403Z
Learning: In packages/riviere-extract-config/vitest.config.mts, the explicit tuple type assertion for the reporter configuration (`as ['text', ['lcov', { projectRoot: string }]]`) is necessary because vitest's CoverageReporter type requires the exact tuple shape; neither inference nor 'as const' produces a compatible type.
Applied to files:
packages/riviere-query/src/riviere-graph-fixtures.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Use ts-morph's in-memory file system (`useInMemoryFileSystem: true`) for fast isolated tests
Applied to files:
packages/riviere-query/src/riviere-graph-fixtures.ts
📚 Learning: 2026-01-11T11:17:09.319Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.319Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Assertions must match test titles. If the test claims to verify 'different IDs', assert on the actual ID values—not just count or existence.
Applied to files:
packages/riviere-query/src/riviere-graph-fixtures.ts
📚 Learning: 2026-01-09T20:08:44.180Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 88
File: packages/riviere-cli/src/commands/extract/extract.ts:109-114
Timestamp: 2026-01-09T20:08:44.180Z
Learning: Applies to packages/riviere-cli/src/commands/extract/**/*.{ts,tsx} : CLI extraction commands should only catch and format expected validation errors as structured JSON. System-level exceptions (disk I/O failures, OOM, AST parse errors) should fail loudly with stack traces for debugging rather than being wrapped in try-catch and converted to JSON errors. This follows the fail-fast principle: validate inputs explicitly, then let unexpected failures surface clearly.
Applied to files:
packages/riviere-query/src/riviere-graph-fixtures.ts
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Avoid implementation coupling in tests. Test behavior, not implementation details. Instead of asserting on mock call arguments with exact SQL, assert on the observable result (e.g., expect(result.user.name).toBe('Alice')).
Applied to files:
packages/riviere-query/src/riviere-graph-fixtures.ts
📚 Learning: 2026-01-08T19:36:17.306Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/codebase-structure.md:0-0
Timestamp: 2026-01-08T19:36:17.306Z
Learning: Applies to docs/conventions/apps/*/src/**/*.test.ts : Test fixtures used across multiple test files may be grouped in shared locations (e.g., test-fixtures.ts), but otherwise test files should be co-located with the code they test.
Applied to files:
packages/riviere-query/src/riviere-graph-fixtures.ts
📚 Learning: 2026-01-11T11:04:34.655Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/anti-patterns.md:0-0
Timestamp: 2026-01-11T11:04:34.655Z
Learning: When hitting max-lines limits, split files into focused modules (e.g., `foo.spec.ts` and `foo.edge-cases.spec.ts`), extract duplicated code into shared modules, or use parameterized tests with `it.each` or `describe.each` instead of removing tests or compressing code.
Applied to files:
packages/riviere-query/src/riviere-graph-fixtures.ts
📚 Learning: 2026-01-11T11:17:09.319Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.319Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Use Arrange-Act-Assert structure in tests: (1) Set up test data, (2) Execute the behavior, (3) Verify the outcome.
Applied to files:
packages/riviere-query/src/riviere-graph-fixtures.ts
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*-fixtures.ts : Create `<module>-fixtures.ts` fixture files alongside `<module>.spec.ts` to reduce duplication when multiple tests share similar setup data or differ only in specific values being tested.
Applied to files:
packages/riviere-query/src/riviere-graph-fixtures.ts
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test violated domain constraints: uniqueness violations (duplicate IDs, emails), missing required relationships (orphaned records), ordering violations (events out of sequence), range breaches (age -1, quantity 1000000), state inconsistencies (shipped but not paid), format mismatches (expected JSON, got XML), and temporal ordering (end before start).
Applied to files:
packages/riviere-query/src/riviere-graph-fixtures.ts
📚 Learning: 2026-01-11T11:17:09.319Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.319Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Assert specific values, not types. Use `expect(result).toEqual(['First.', ' Second.'])` not `expect(result).toBeDefined()`. Specific assertions catch specific bugs.
Applied to files:
packages/riviere-query/src/riviere-graph-fixtures.ts
📚 Learning: 2026-01-08T23:16:02.639Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/software-design.md:0-0
Timestamp: 2026-01-08T23:16:02.639Z
Learning: Applies to docs/conventions/**/*.{ts,tsx,js,jsx} : Fail-Fast Error Handling: Validate and throw clear errors instead of using fallback chains. Error format: `Expected [X]. Got [Y]. Context: [debugging info]`
Applied to files:
packages/riviere-query/src/riviere-graph-fixtures.ts
🧬 Code graph analysis (1)
packages/riviere-query/src/riviere-graph-fixtures.ts (3)
apps/eclair/src/test-assertions.ts (1)
TestAssertionError(1-6)packages/riviere-cli/src/command-test-fixtures.ts (1)
TestAssertionError(18-23)packages/riviere-extract-conventions/src/default-config-fixtures.ts (1)
TestAssertionError(13-18)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: main
- GitHub Check: Cloudflare Pages
🔇 Additional comments (4)
packages/riviere-extract-config/src/index.ts (2)
2-11: Export hygiene: ensuretype-only exports stay type-only.Nice to see
type ValidationError/type ValidationResultexported withtype(avoids runtime export bloat). Just ensureExtractionConfigValidationErroris a runtime value export from./validation(and not accidentally marked type-only), otherwise this will compile but fail at runtime for consumers.
1-11: Removal of fixture exports is safe; no downstream usages detected.The removal of
createMinimalConfigandcreateMinimalModulere-exports does not cause breaking changes—these symbols are unused throughout the codebase. Test fixtures appear to be in the dedicatedvalidation-fixtures.tsfile. AddingExtractionConfigValidationErrorto the public API is correct and aligns with the validation-first pattern: it allows downstream code to catch validation failures at load time with clear error information.packages/riviere-query/src/riviere-graph-fixtures.ts (1)
152-152: LGTM!Using TestAssertionError provides a distinct error type for test assertion failures, making it easier to distinguish from generic errors and improving error handling specificity.
packages/riviere-schema/src/index.ts (1)
9-9: Export is correct and well-implemented.
InvalidComponentIdErroris properly documented and its throwing behavior is validated by tests. The error message follows the fail-fast convention with context (the invalid ID and expected format). However, the test suite validates implicit error throwing but lacks an explicit example showing consumers how to import and catch this error—consider adding a test case that demonstrates the catch pattern if this error is intended for external consumers.
- Use createRequire() anchored to config directory for ESM-safe package resolution - Fix isTopLevelRulesConfig() to reject arrays - Add test coverage for useRequiredGraph error path - Export useRequiredGraph for testability Co-Authored-By: Claude Opus 4.5 <[email protected]>
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/eclair/src/App.tsx (1)
19-29: Good specialization + clearer failure mode for “graph missing”, but consider relocating the hook
ExportinguseRequiredGraph()and throwingGraphErrorwhengraph === nullis a nice upgrade in consistency and debuggability. However, exporting it fromApp.tsxcouples a reusable hook to an app-entry module—consider moving it toapps/eclair/src/contexts/GraphContext.tsx(or ahooks/module) and re-exporting from there to keep layering clean.
🤖 Fix all issues with AI agents
In @packages/riviere-cli/src/commands/extract/config-loader.ts:
- Around line 58-93: parseConfigContent currently calls resolveConfig(config)
without a ConfigLoader, causing nested "extends" to fail; update
parseConfigContent to accept a loader parameter (e.g., configLoader:
ConfigLoader) and pass it into resolveConfig as resolveConfig(config,
configLoader). Update any callers of parseConfigContent to provide the same
loader (or thread the loader through from where parseConfigContent is invoked),
ensuring parseExtractionConfig and the subsequent code paths remain unchanged
except for the added loader argument so nested/extended modules can be resolved
correctly.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (3)
apps/eclair/src/App.spec.tsxapps/eclair/src/App.tsxpackages/riviere-cli/src/commands/extract/config-loader.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Follow eslint configuration rules defined in
eslint.config.mjsfor all linting
Files:
apps/eclair/src/App.tsxpackages/riviere-cli/src/commands/extract/config-loader.tsapps/eclair/src/App.spec.tsx
**/*.{ts,tsx,js,jsx,css,scss,html}
📄 CodeRabbit inference engine (CLAUDE.md)
All UI and UX design must conform to global brand guidelines in
/docs/brand/(logo, colors, typography, icons)
Files:
apps/eclair/src/App.tsxpackages/riviere-cli/src/commands/extract/config-loader.tsapps/eclair/src/App.spec.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,js,jsx}: Do not log sensitive data (passwords, tokens, PII) in any code
Validate and sanitize all external input
Files:
apps/eclair/src/App.tsxpackages/riviere-cli/src/commands/extract/config-loader.tsapps/eclair/src/App.spec.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use cross-project imports with package names (e.g.,
import { X } from '@living-architecture/[pkg-name]') rather than relative paths
Files:
apps/eclair/src/App.tsxpackages/riviere-cli/src/commands/extract/config-loader.tsapps/eclair/src/App.spec.tsx
🧠 Learnings (39)
📓 Common learnings
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Use glob pattern matching for module-based organization of extraction rules
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.{json,ts} : Define extraction configuration using the JSON Schema from `living-architecture/riviere-extract-config` DSL
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 129
File: packages/riviere-cli/src/commands/extract/config-loader.ts:31-39
Timestamp: 2026-01-11T14:38:35.637Z
Learning: In packages/riviere-cli/src/commands/extract/config-loader.ts, the isExtendedConfig type guard intentionally performs minimal validation (checks for non-null object and validates modules is an array if present) because comprehensive validation is handled downstream by the schema validator. The type guard's purpose is basic type narrowing to support both module-array and top-level-rules formats, not comprehensive validation. This follows the layered validation pattern where type guards are minimal and schema validation occurs at system boundaries.
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use `living-architecture/riviere-extract-ts` TypeScript extractor with ts-morph for AST parsing when implementing TypeScript extraction for architecture schema components
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Applies to packages/riviere-extract-config/**/*.ts : Extraction config schema is the source of truth for valid structures. TypeScript types must mirror the schema definition to maintain consistency
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Reject invalid extraction configs at load time, not during extraction phase
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement integration tests for end-to-end extraction from TypeScript code to JSON output
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Implement extraction logic as pure functions with no side effects
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-conventions/CLAUDE.md:0-0
Timestamp: 2026-01-08T07:05:01.766Z
Learning: Import and use the default extraction config from `living-architecture/riviere-extract-conventions/default-config` in extraction tooling to detect all 6 component types
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use the Rivière Builder Node.js library to programmatically construct the schema graph when implementing custom extraction code
📚 Learning: 2026-01-06T23:01:34.751Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Applies to packages/riviere-extract-config/**/*.ts : Extraction config schema is the source of truth for valid structures. TypeScript types must mirror the schema definition to maintain consistency
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Reject invalid extraction configs at load time, not during extraction phase
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T22:20:13.250Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.{json,ts} : Define extraction configuration using the JSON Schema from `living-architecture/riviere-extract-config` DSL
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-11T14:38:35.637Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 129
File: packages/riviere-cli/src/commands/extract/config-loader.ts:31-39
Timestamp: 2026-01-11T14:38:35.637Z
Learning: In packages/riviere-cli/src/commands/extract/config-loader.ts, the isExtendedConfig type guard intentionally performs minimal validation (checks for non-null object and validates modules is an array if present) because comprehensive validation is handled downstream by the schema validator. The type guard's purpose is basic type narrowing to support both module-array and top-level-rules formats, not comprehensive validation. This follows the layered validation pattern where type guards are minimal and schema validation occurs at system boundaries.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Use glob pattern matching for module-based organization of extraction rules
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T07:05:01.766Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-conventions/CLAUDE.md:0-0
Timestamp: 2026-01-08T07:05:01.766Z
Learning: Import and use the default extraction config from `living-architecture/riviere-extract-conventions/default-config` in extraction tooling to detect all 6 component types
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T22:20:13.250Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use the Rivière Builder Node.js library to programmatically construct the schema graph when implementing custom extraction code
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Implement extraction logic as pure functions with no side effects
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T22:20:13.250Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use `living-architecture/riviere-extract-ts` TypeScript extractor with ts-morph for AST parsing when implementing TypeScript extraction for architecture schema components
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement integration tests for end-to-end extraction from TypeScript code to JSON output
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-09T20:08:30.350Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 88
File: packages/riviere-cli/src/commands/extract/extract.spec.ts:33-38
Timestamp: 2026-01-09T20:08:30.350Z
Learning: In test files (*.spec.ts, *.test.ts), type guards like `isExtractionOutput(value: unknown): value is ExtractionOutput` should focus on narrowing types for TypeScript rather than comprehensive validation. Actual shape validation is handled through explicit test assertions (e.g., `expect(result).toMatchObject(...)`). This keeps type guards simple while maintaining thorough validation through assertion-based testing.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T23:16:02.639Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/software-design.md:0-0
Timestamp: 2026-01-08T23:16:02.639Z
Learning: Applies to docs/conventions/**/*.{ts,tsx} : Parse, don't validate. Use Zod schemas at system boundaries to parse external data once. Don't scatter `isX(unknown): x is T` type guards throughout the codebase.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-09T20:08:44.180Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 88
File: packages/riviere-cli/src/commands/extract/extract.ts:109-114
Timestamp: 2026-01-09T20:08:44.180Z
Learning: In packages/riviere-cli/src/commands/extract/**/*.{ts,tsx}, CLI extraction commands should only catch and format expected validation errors as structured JSON. Do not wrap or convert system-level exceptions (e.g., disk I/O failures, OOM, AST parse errors) into JSON errors; instead, fail loudly with stack traces to aid debugging. Follow fail-fast principles: validate inputs explicitly, and surface unexpected failures clearly.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T23:16:02.639Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/software-design.md:0-0
Timestamp: 2026-01-08T23:16:02.639Z
Learning: Applies to docs/conventions/**/*.{ts,tsx,js,jsx} : Fail-Fast Error Handling: Validate and throw clear errors instead of using fallback chains. Error format: `Expected [X]. Got [Y]. Context: [debugging info]`
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-07T08:54:48.071Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/workflow/code-review.md:0-0
Timestamp: 2026-01-07T08:54:48.071Z
Learning: Applies to docs/workflow/**/*.{ts,tsx,js,jsx} : Avoid dangerous fallback values that hide bugs. Do not use `??` or `||` operators without clear reason for providing defaults. If a value is required, make it required rather than guessing at defaults. Exceptions: optional parameters with documented defaults, configuration with explicit optional semantics, and test data with placeholder values.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T23:16:02.639Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/software-design.md:0-0
Timestamp: 2026-01-08T23:16:02.639Z
Learning: Applies to docs/conventions/**/*.{ts,tsx,js,jsx} : Fail-fast over silent fallbacks. Never use fallback chains (`value ?? backup ?? 'unknown'`). If data should exist, validate and throw a clear error.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-06T08:11:15.403Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 53
File: packages/riviere-extract-config/vitest.config.mts:20-20
Timestamp: 2026-01-06T08:11:15.403Z
Learning: In packages/riviere-extract-config/vitest.config.mts, the explicit tuple type assertion for the reporter configuration (`as ['text', ['lcov', { projectRoot: string }]]`) is necessary because vitest's CoverageReporter type requires the exact tuple shape; neither inference nor 'as const' produces a compatible type.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-11T11:04:34.655Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/anti-patterns.md:0-0
Timestamp: 2026-01-11T11:04:34.655Z
Learning: Applies to docs/conventions/**/*.{ts,tsx,js,jsx} : Never parse error message strings to determine error types or extract information using `.message.includes()`, `.message.startsWith()`, or regex patterns on `error.message`. Use typed custom error classes instead.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-11T11:04:34.655Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/anti-patterns.md:0-0
Timestamp: 2026-01-11T11:04:34.655Z
Learning: Applies to docs/conventions/**/*.{ts,tsx,js,jsx} : When parsing strings in exception messages is 100% unavoidable (e.g., due to third-party library limitations), document the exception with justification, reference tracking issue, and note that upstream fix was requested.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-06T23:01:34.751Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: All validation of extraction config must occur at config load time, not during extraction. Invalid configs should fail fast with clear error messages that include paths and descriptive information
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T23:16:02.639Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/software-design.md:0-0
Timestamp: 2026-01-08T23:16:02.639Z
Learning: Applies to docs/conventions/**/*.{ts,tsx} : Use Zod for runtime validation. In TypeScript, use Zod schemas for parsing external data, API responses, and user input. Type inference from schemas keeps types and validation in sync.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test violated domain constraints: uniqueness violations (duplicate IDs, emails), missing required relationships (orphaned records), ordering violations (events out of sequence), range breaches (age -1, quantity 1000000), state inconsistencies (shipped but not paid), format mismatches (expected JSON, got XML), and temporal ordering (end before start).
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T19:36:17.306Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/codebase-structure.md:0-0
Timestamp: 2026-01-08T19:36:17.306Z
Learning: Applies to docs/conventions/**/*.{ts,tsx} : Use living-architecture/[pkg-name] for imports from other workspace projects, not relative paths like ../../packages/[pkg-name].
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-10T10:14:57.499Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-10T10:14:57.499Z
Learning: Applies to **/*.{ts,tsx} : Use cross-project imports with package names (e.g., `import { X } from 'living-architecture/[pkg-name]'`) rather than relative paths
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement unit tests for each predicate type in isolation with positive and negative cases
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.tsapps/eclair/src/App.spec.tsx
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: All extraction rules should come from validated ExtractionConfig provided by riviere-extract-config
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-07T08:54:48.071Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/workflow/code-review.md:0-0
Timestamp: 2026-01-07T08:54:48.071Z
Learning: Applies to docs/workflow/**/*.{ts,tsx,js,jsx} : Review usage of `/* v8 ignore next -- preserve */` coverage skip directives. This is only acceptable for unreachable code needed to satisfy the compiler. Most cases should be solved by extracting code or writing tests to mock behavior.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-06T23:01:34.751Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Extraction config schemas must define all six required component types per module: api, useCase, domainOp, event, eventHandler, and ui. Unused component types must be explicitly marked with `notUsed: true` rather than omitted
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-07T08:54:48.071Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/workflow/code-review.md:0-0
Timestamp: 2026-01-07T08:54:48.071Z
Learning: Applies to docs/workflow/**/*.{ts,tsx,js,jsx} : Check lint rules (eslint.config.mjs) before providing feedback to ensure suggestions don't contradict lint rules. Never suggest using banned keywords like 'as' or 'let'.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-10T10:14:57.499Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-10T10:14:57.499Z
Learning: Do not modify root configuration files (eslint.config.mjs, tsconfig.base.json, nx.json, vite.config, vitest.config.mts); provide suggested changes and ask the user before modifying
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Use ts-morph's in-memory file system (`useInMemoryFileSystem: true`) for fast isolated tests
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.tsapps/eclair/src/App.spec.tsx
📚 Learning: 2026-01-08T19:36:17.306Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/codebase-structure.md:0-0
Timestamp: 2026-01-08T19:36:17.306Z
Learning: Applies to docs/conventions/apps/*/package.json : When importing from another project, add explicit workspace dependencies to package.json using the format "living-architecture/[pkg-name]": "workspace:*" and run pnpm install.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T19:36:17.306Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/codebase-structure.md:0-0
Timestamp: 2026-01-08T19:36:17.306Z
Learning: Applies to docs/conventions/packages/*/package.json : When importing from another project, add explicit workspace dependencies to package.json using the format "living-architecture/[pkg-name]": "workspace:*" and run pnpm install.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.ts
📚 Learning: 2026-01-08T19:36:17.306Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/codebase-structure.md:0-0
Timestamp: 2026-01-08T19:36:17.306Z
Learning: Applies to docs/conventions/apps/*/vitest.config.ts : Each app must include a vitest.config.ts file with 100% coverage thresholds for test configuration.
Applied to files:
apps/eclair/src/App.spec.tsx
📚 Learning: 2026-01-08T06:46:05.503Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 66
File: packages/riviere-extract-conventions/src/eslint/require-component-decorator.spec.ts:19-21
Timestamp: 2026-01-08T06:46:05.503Z
Learning: In test files using typescript-eslint/rule-tester's RuleTester.run(), include an explicit it() block with an expect() assertion (e.g., expect(rule).toBeDefined()) to satisfy sonarjs/no-empty-test-file and sonarjs/assertions-in-tests lint rules, which don't recognize RuleTester's internal test blocks.
Applied to files:
apps/eclair/src/App.spec.tsx
📚 Learning: 2026-01-11T11:17:09.319Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.319Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Use Arrange-Act-Assert structure in tests: (1) Set up test data, (2) Execute the behavior, (3) Verify the outcome.
Applied to files:
apps/eclair/src/App.spec.tsx
📚 Learning: 2026-01-08T12:57:19.167Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 67
File: packages/riviere-extract-ts/tsconfig.spec.json:5-22
Timestamp: 2026-01-08T12:57:19.167Z
Learning: In tsconfig.spec.json files, use expanded types array ["vitest/globals", "vitest/importMeta", "vite/client", "node", "vitest"] for complete test type coverage. Include patterns should cover .test and .spec files, config files (vitest.config.ts/mts, vite.config.ts/mts), multiple extensions (.ts, .tsx, .js, .jsx), and .d.ts files to ensure proper TypeScript coverage across the testing environment.
Applied to files:
apps/eclair/src/App.spec.tsx
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Avoid implementation coupling in tests. Test behavior, not implementation details. Instead of asserting on mock call arguments with exact SQL, assert on the observable result (e.g., expect(result.user.name).toBe('Alice')).
Applied to files:
apps/eclair/src/App.spec.tsx
🧬 Code graph analysis (2)
apps/eclair/src/App.tsx (2)
apps/eclair/src/contexts/GraphContext.tsx (1)
useGraph(131-137)apps/eclair/src/errors.ts (1)
GraphError(14-19)
apps/eclair/src/App.spec.tsx (3)
apps/eclair/src/App.tsx (1)
useRequiredGraph(21-29)apps/eclair/src/contexts/GraphContext.tsx (1)
GraphProvider(70-129)apps/eclair/src/errors.ts (1)
GraphError(14-19)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: main
- GitHub Check: browser-tests (firefox)
- GitHub Check: browser-tests (webkit)
- GitHub Check: Cloudflare Pages
🔇 Additional comments (6)
apps/eclair/src/App.tsx (1)
1-7: Import formatting-only change
No functional impact here.apps/eclair/src/App.spec.tsx (2)
10-16: Import additions look fine
No concerns with importinguseRequiredGraphandGraphErrorfor behavioral testing.
179-209: Tests are correctly structured and don't require console.error handling adjustments.The tests assert on both error type and message as expected. The Vitest configuration does not enforce
console.erroras a test failure, and no such handling is configured in the test setup. These tests appropriately validate behavior (error type and message) rather than implementation details, following the repo's testing conventions.Likely an incorrect or invalid review comment.
packages/riviere-cli/src/commands/extract/config-loader.ts (3)
1-30: LGTM! Clean imports and type definitions.The imports follow workspace conventions using
@living-architecture/package names, and theTopLevelRulesConfiginterface appropriately models the simplified config format with optional component rules.
32-56: LGTM! Typed errors and focused type guards.The custom
PackageConfigNotFoundErrorfollows the pattern of using typed error classes. The type guards (hasModulesArrayandisTopLevelRulesConfig) perform minimal validation for type narrowing, with comprehensive validation handled downstream by schema validators per established patterns.
95-134: LGTM! Robust package resolution and clean factory pattern.The implementation is well-structured:
isPackageReferenceprovides a clear heuristic for distinguishing package names from file pathsresolvePackagePathcorrectly usescreateRequireanchored to the config directory for ESM-safe resolution- Error handling properly distinguishes between "package not found" and "package found but missing config"
- The factory function is clean and focused
The use of
resolve(configDir, 'package.json')as the anchor point forcreateRequire(line 100) is clever—it doesn't require the file to exist, just uses the directory as the resolution starting point.
Add tests to verify ContextError is thrown with correct type and message when context hooks are used outside their providers: - ExportContext: useExport outside ExportProvider - GraphContext: useGraph outside GraphProvider Addresses SonarCloud coverage for error throw statements. Co-Authored-By: Claude Opus 4.5 <[email protected]>
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/eclair/src/contexts/GraphContext.spec.tsx (1)
163-181: Combine redundant tests into a single assertion.Both tests verify the same error condition (useGraph outside provider) with identical setup. The first checks the error type, the second checks the message. They can be combined into a single test that verifies both properties, eliminating duplicate console mocking and render calls.
♻️ Combine into a single test
- it('throws ContextError when useGraph called outside provider', () => { - const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {}) - - expect(() => { - render(<TestConsumer />) - }).toThrow(ContextError) - - consoleError.mockRestore() - }) - - it('throws with descriptive message when useGraph called outside provider', () => { + it('throws ContextError with descriptive message when useGraph called outside provider', () => { const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {}) - expect(() => { + let thrownError: Error | undefined + try { render(<TestConsumer />) - }).toThrow('useGraph must be used within a GraphProvider') + } catch (error) { + thrownError = error as Error + } + + expect(thrownError).toBeInstanceOf(ContextError) + expect(thrownError?.message).toBe('useGraph must be used within a GraphProvider') consoleError.mockRestore() })
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
apps/eclair/src/contexts/ExportContext.spec.tsxapps/eclair/src/contexts/GraphContext.spec.tsx
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Follow eslint configuration rules defined in
eslint.config.mjsfor all linting
Files:
apps/eclair/src/contexts/ExportContext.spec.tsxapps/eclair/src/contexts/GraphContext.spec.tsx
**/*.{ts,tsx,js,jsx,css,scss,html}
📄 CodeRabbit inference engine (CLAUDE.md)
All UI and UX design must conform to global brand guidelines in
/docs/brand/(logo, colors, typography, icons)
Files:
apps/eclair/src/contexts/ExportContext.spec.tsxapps/eclair/src/contexts/GraphContext.spec.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,js,jsx}: Do not log sensitive data (passwords, tokens, PII) in any code
Validate and sanitize all external input
Files:
apps/eclair/src/contexts/ExportContext.spec.tsxapps/eclair/src/contexts/GraphContext.spec.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use cross-project imports with package names (e.g.,
import { X } from '@living-architecture/[pkg-name]') rather than relative paths
Files:
apps/eclair/src/contexts/ExportContext.spec.tsxapps/eclair/src/contexts/GraphContext.spec.tsx
🧠 Learnings (8)
📓 Common learnings
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Use glob pattern matching for module-based organization of extraction rules
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.{json,ts} : Define extraction configuration using the JSON Schema from `living-architecture/riviere-extract-config` DSL
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use `living-architecture/riviere-extract-ts` TypeScript extractor with ts-morph for AST parsing when implementing TypeScript extraction for architecture schema components
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Applies to packages/riviere-extract-config/**/*.ts : Extraction config schema is the source of truth for valid structures. TypeScript types must mirror the schema definition to maintain consistency
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement integration tests for end-to-end extraction from TypeScript code to JSON output
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 129
File: packages/riviere-cli/src/commands/extract/config-loader.ts:31-39
Timestamp: 2026-01-11T14:38:35.637Z
Learning: In packages/riviere-cli/src/commands/extract/config-loader.ts, the isExtendedConfig type guard intentionally performs minimal validation (checks for non-null object and validates modules is an array if present) because comprehensive validation is handled downstream by the schema validator. The type guard's purpose is basic type narrowing to support both module-array and top-level-rules formats, not comprehensive validation. This follows the layered validation pattern where type guards are minimal and schema validation occurs at system boundaries.
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Reject invalid extraction configs at load time, not during extraction phase
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-conventions/CLAUDE.md:0-0
Timestamp: 2026-01-08T07:05:01.766Z
Learning: Import and use the default extraction config from `living-architecture/riviere-extract-conventions/default-config` in extraction tooling to detect all 6 component types
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Implement extraction logic as pure functions with no side effects
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use the Rivière Builder Node.js library to programmatically construct the schema graph when implementing custom extraction code
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: All validation of extraction config must occur at config load time, not during extraction. Invalid configs should fail fast with clear error messages that include paths and descriptive information
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Extraction config schemas must define all six required component types per module: api, useCase, domainOp, event, eventHandler, and ui. Unused component types must be explicitly marked with `notUsed: true` rather than omitted
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 88
File: packages/riviere-cli/src/commands/extract/extract.ts:109-114
Timestamp: 2026-01-09T20:08:44.180Z
Learning: Applies to packages/riviere-cli/src/commands/extract/**/*.{ts,tsx} : CLI extraction commands should only catch and format expected validation errors as structured JSON. System-level exceptions (disk I/O failures, OOM, AST parse errors) should fail loudly with stack traces for debugging rather than being wrapped in try-catch and converted to JSON errors. This follows the fail-fast principle: validate inputs explicitly, then let unexpected failures surface clearly.
📚 Learning: 2026-01-08T23:16:02.639Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/software-design.md:0-0
Timestamp: 2026-01-08T23:16:02.639Z
Learning: Applies to docs/conventions/**/*.{ts,tsx,js,jsx} : Fail-Fast Error Handling: Validate and throw clear errors instead of using fallback chains. Error format: `Expected [X]. Got [Y]. Context: [debugging info]`
Applied to files:
apps/eclair/src/contexts/ExportContext.spec.tsxapps/eclair/src/contexts/GraphContext.spec.tsx
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test violated domain constraints: uniqueness violations (duplicate IDs, emails), missing required relationships (orphaned records), ordering violations (events out of sequence), range breaches (age -1, quantity 1000000), state inconsistencies (shipped but not paid), format mismatches (expected JSON, got XML), and temporal ordering (end before start).
Applied to files:
apps/eclair/src/contexts/ExportContext.spec.tsx
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test domain-specific edge cases: email (valid formats, plus signs, subdomains), URLs (protocols, ports, special characters, relative paths), phone numbers (international formats, extensions), addresses (Unicode, multi-line, missing components), currency (rounding, different currencies, zero amounts), percentages (0%, 100%, over 100%).
Applied to files:
apps/eclair/src/contexts/ExportContext.spec.tsx
📚 Learning: 2026-01-08T06:46:05.503Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 66
File: packages/riviere-extract-conventions/src/eslint/require-component-decorator.spec.ts:19-21
Timestamp: 2026-01-08T06:46:05.503Z
Learning: In test files using typescript-eslint/rule-tester's RuleTester.run(), include an explicit it() block with an expect() assertion (e.g., expect(rule).toBeDefined()) to satisfy sonarjs/no-empty-test-file and sonarjs/assertions-in-tests lint rules, which don't recognize RuleTester's internal test blocks.
Applied to files:
apps/eclair/src/contexts/ExportContext.spec.tsx
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement integration tests for end-to-end extraction from TypeScript code to JSON output
Applied to files:
apps/eclair/src/contexts/GraphContext.spec.tsx
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Use ts-morph's in-memory file system (`useInMemoryFileSystem: true`) for fast isolated tests
Applied to files:
apps/eclair/src/contexts/GraphContext.spec.tsx
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement unit tests for each predicate type in isolation with positive and negative cases
Applied to files:
apps/eclair/src/contexts/GraphContext.spec.tsx
🧬 Code graph analysis (2)
apps/eclair/src/contexts/ExportContext.spec.tsx (1)
apps/eclair/src/errors.ts (1)
ContextError(44-49)
apps/eclair/src/contexts/GraphContext.spec.tsx (1)
apps/eclair/src/errors.ts (1)
ContextError(44-49)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: browser-tests (webkit)
- GitHub Check: browser-tests (firefox)
- GitHub Check: main
- GitHub Check: Cloudflare Pages
🔇 Additional comments (3)
apps/eclair/src/contexts/GraphContext.spec.tsx (1)
19-19: LGTM!The ContextError import is correctly added and necessary for the updated test assertions.
apps/eclair/src/contexts/ExportContext.spec.tsx (2)
10-10: LGTM: Correct import of new error type.The import correctly uses the
@alias and brings in theContextErrorclass needed for the new test assertions.
128-138: Consider consolidating error validation tests.Both tests validate the same error condition (using
useExportoutside the provider) but check different aspects—one validates the error type, the other validates the message. While the current approach is clear and valid, consolidating them would reduce redundancy and improve test organization.♻️ Proposed consolidation
- it('throws ContextError when useExport is used outside ExportProvider', () => { - expect(() => { - render(<TestConsumer />) - }).toThrow(ContextError) - }) - - it('throws with descriptive message when used outside provider', () => { - expect(() => { - render(<TestConsumer />) - }).toThrow('useExport must be used within a ExportProvider') - }) + it('throws ContextError with descriptive message when used outside provider', () => { + const renderOutsideProvider = () => render(<TestConsumer />) + + expect(renderOutsideProvider).toThrow(ContextError) + expect(renderOutsideProvider).toThrow('useExport must be used within a ExportProvider') + })⛔ Skipped due to learnings
Learnt from: CR Repo: NTCoding/living-architecture PR: 0 File: docs/conventions/testing.md:0-0 Timestamp: 2026-01-11T11:17:09.319Z Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : One concept per test. Each test verifies one behavior. If you need 'and' in your test name, split it into multiple tests.Learnt from: CR Repo: NTCoding/living-architecture PR: 0 File: docs/workflow/code-review.md:0-0 Timestamp: 2026-01-07T08:54:48.071Z Learning: Applies to docs/workflow/**/*.{ts,tsx,js,jsx} : Review usage of `/* v8 ignore next -- preserve */` coverage skip directives. This is only acceptable for unreachable code needed to satisfy the compiler. Most cases should be solved by extracting code or writing tests to mock behavior.Learnt from: NTCoding Repo: NTCoding/living-architecture PR: 66 File: packages/riviere-extract-conventions/src/eslint/require-component-decorator.spec.ts:19-21 Timestamp: 2026-01-08T06:46:05.503Z Learning: In test files using typescript-eslint/rule-tester's RuleTester.run(), include an explicit it() block with an expect() assertion (e.g., expect(rule).toBeDefined()) to satisfy sonarjs/no-empty-test-file and sonarjs/assertions-in-tests lint rules, which don't recognize RuleTester's internal test blocks.Learnt from: CR Repo: NTCoding/living-architecture PR: 0 File: docs/conventions/software-design.md:0-0 Timestamp: 2026-01-08T23:16:02.639Z Learning: Applies to docs/conventions/**/*.{ts,tsx,js,jsx} : Fail-Fast Error Handling: Validate and throw clear errors instead of using fallback chains. Error format: `Expected [X]. Got [Y]. Context: [debugging info]`
Update tests to verify error classes are thrown with correct types, not just matching messages. This ensures custom error class constructors are covered: - ConfigFileNotFoundError, InvalidConfigFormatError, ConfigSchemaValidationError, PackageResolveError (riviere-cli) - InvalidComponentIdError (riviere-schema) - RiviereSchemaValidationError (riviere-schema) - ExtractionConfigValidationError (riviere-extract-config) Addresses SonarCloud coverage for error class definitions. Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Add SchemaError tests for invalid date format validation - Add LayoutError tests for DomainConnectionDiff missing domains - Add LayoutError class assertions in GraphRenderingSetup tests - Add v8 ignore comments for unreachable defensive code in: - compareGraphs.ts (Map.get after Map.set) - SchemaModal.tsx (CSS module and button disabled guards) - GraphRenderingSetup.ts (D3 callback error guards) Co-Authored-By: Claude Opus 4.5 <[email protected]>
There was a problem hiding this comment.
Actionable comments posted: 8
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
packages/riviere-schema/src/component-id.spec.ts (1)
49-70: Consider reducing redundancy in error assertions.The tests correctly verify both error type and message, but each test invokes
ComponentId.parse()twice. Consider capturing the error once to improve efficiency:♻️ Optional refactor to reduce redundant function calls
it('throws InvalidComponentIdError on invalid format with too few segments', () => { - expect(() => ComponentId.parse('orders:checkout')).toThrow(InvalidComponentIdError) - expect(() => ComponentId.parse('orders:checkout')).toThrow( - "Invalid component ID format: 'orders:checkout'. Expected 'domain:module:type:name'", - ) + let error: Error | undefined + try { + ComponentId.parse('orders:checkout') + } catch (e) { + error = e as Error + } + expect(error).toBeInstanceOf(InvalidComponentIdError) + expect(error?.message).toBe( + "Invalid component ID format: 'orders:checkout'. Expected 'domain:module:type:name'" + ) })Apply the same pattern to the other two test cases.
Additionally, consider adding tests for edge cases like empty segments (
"orders::domainop:place-order"), whitespace-only segments, and special characters to strengthen validation coverage.apps/eclair/src/components/SchemaModal/SchemaModal.tsx (2)
16-48: Module-level initialization with throws prevents graceful error handling.The
jsonViewStylesobject is initialized at module level (lines 25-48) by callinggetStyle, which can throwCSSModuleError. If a CSS class is missing at runtime, the error will be thrown during module load—before React error boundaries can catch it—potentially making the entire module unloadable and breaking the app.While the v8 ignore comment indicates this is defensive and should only happen during development, runtime safeguards are valuable. Consider one of these alternatives:
- Lazy initialization: Move
jsonViewStylesinto a function called during render- Safe fallback: Return a default/empty class name instead of throwing
- Remove the check: If CSS modules are guaranteed to be validated at build time
♻️ Alternative: Lazy initialization
-const jsonViewStyles = { - container: getStyle('jsonContainer'), - basicChildStyle: getStyle('jsonBasicChild'), - label: getStyle('jsonLabel'), - clickableLabel: getStyle('jsonClickableLabel'), - nullValue: getStyle('jsonNull'), - undefinedValue: getStyle('jsonUndefined'), - numberValue: getStyle('jsonNumber'), - stringValue: getStyle('jsonString'), - booleanValue: getStyle('jsonBoolean'), - otherValue: getStyle('jsonOther'), - punctuation: getStyle('jsonPunctuation'), - expandIcon: getStyle('jsonExpandIcon'), - collapseIcon: getStyle('jsonCollapseIcon'), - collapsedContent: getStyle('jsonCollapsedContent'), - childFieldsContainer: getStyle('jsonChildFields'), - quotesForFieldNames: true, - noQuotesForStringValues: false, - stringifyStringValues: false, - ariaLables: { - collapseJson: 'Collapse JSON node', - expandJson: 'Expand JSON node', - }, -} +function getJsonViewStyles() { + return { + container: getStyle('jsonContainer'), + basicChildStyle: getStyle('jsonBasicChild'), + label: getStyle('jsonLabel'), + clickableLabel: getStyle('jsonClickableLabel'), + nullValue: getStyle('jsonNull'), + undefinedValue: getStyle('jsonUndefined'), + numberValue: getStyle('jsonNumber'), + stringValue: getStyle('jsonString'), + booleanValue: getStyle('jsonBoolean'), + otherValue: getStyle('jsonOther'), + punctuation: getStyle('jsonPunctuation'), + expandIcon: getStyle('jsonExpandIcon'), + collapseIcon: getStyle('jsonCollapseIcon'), + collapsedContent: getStyle('jsonCollapsedContent'), + childFieldsContainer: getStyle('jsonChildFields'), + quotesForFieldNames: true, + noQuotesForStringValues: false, + stringifyStringValues: false, + ariaLables: { + collapseJson: 'Collapse JSON node', + expandJson: 'Expand JSON node', + }, + } +}Then update line 231:
-<JsonView data={graph} shouldExpandNode={shouldExpandNode} style={jsonViewStyles} /> +<JsonView data={graph} shouldExpandNode={shouldExpandNode} style={getJsonViewStyles()} />
114-126: Consider more robust date validation.
formatGeneratedDateonly checks that a non-empty string exists before the 'T' separator, but doesn't validate the actual date format. Invalid dates like"INVALID-DATET10:30:00Z"would pass this check.Since this is for display and the data comes from generated schemas (which should produce valid ISO strings), the current validation may be sufficient. However, for more robust error detection, consider parsing the date:
♻️ More robust validation
function formatGeneratedDate(isoDateString: string | undefined): string { if (isoDateString === undefined) { return 'Unknown' } const parts = isoDateString.split('T') const datePart = parts[0] if (datePart === undefined || datePart === '') { throw new SchemaError( `Invalid ISO date string: "${isoDateString}". Expected format like "2024-01-15T10:30:00Z".`, ) } + // Validate the date part is actually a valid date + const dateObj = new Date(datePart) + if (Number.isNaN(dateObj.getTime())) { + throw new SchemaError( + `Invalid ISO date string: "${isoDateString}". Date part "${datePart}" is not a valid date.`, + ) + } return datePart }
🤖 Fix all issues with AI agents
In @apps/eclair/src/components/SchemaModal/SchemaModal.spec.tsx:
- Around line 105-119: The generated date validation tests only cover one
empty-date case; add explicit edge-case tests inside the describe('generated
date validation') block using createTestGraph() and renderSchemaModalWithGraph()
to assert correct behavior for: a) missing 'T' separator (e.g., '2024-01-15') —
expect the component to render the date string, b) multiple 'T' separators
(e.g., '2024-01-15TT10:30:00Z') — expect a SchemaError or the existing 'Invalid
ISO date string' error, c) empty string ('') — expect a SchemaError, and d)
time-only strings like 'T' or '10:30:00Z' — expect a SchemaError; ensure each
test uses the same patterns as existing tests (expect(() =>
renderSchemaModalWithGraph(graph)).toThrow(... ) or screen.getByText(...)) and
references formatGeneratedDate behavior indirectly by exercising the component.
In @apps/eclair/src/features/comparison/DomainConnectionDiff.spec.tsx:
- Around line 400-421: Rename and clarify the existing test in
DomainConnectionDiff.spec.tsx to state it checks for a missing domain (not
“position”), update the expectation to assert the LayoutError (or its
descriptive message) when a connection references a missing target domain using
createMinimalDiff and render(<DomainConnectionDiff diff={diff} />); then add a
symmetric test named like "throws LayoutError when connection references missing
source domain" that constructs a diff with a missing source (e.g., source:
'nonexistent-source', target: 'payments') and asserts that rendering
DomainConnectionDiff throws LayoutError.
- Around line 378-422: Remove the redundant test that only asserts the error
type and consolidate into a single test that both verifies the thrown error is a
LayoutError and that its message is "Edge references missing position";
specifically, delete the first it(...) that asserts only toThrow(LayoutError)
and update the remaining test for the missing position case to capture the
render call (e.g., const fn = () => render(<DomainConnectionDiff diff={diff}
/>)) and then assert expect(fn).toThrow(LayoutError) and
expect(fn).toThrow('Edge references missing position'), keeping identifiers like
DomainConnectionDiff, createMinimalDiff and LayoutError to locate the test.
In @packages/riviere-cli/src/commands/extract/config-loader.spec.ts:
- Around line 26-111: Add edge-case tests to the createConfigLoader test suite
to cover malformed JSON, path traversal, special characters in paths, and file
read errors: write tests that (1) mock existsSync to true and readFileSync to
return malformed JSON and assert it throws InvalidConfigFormatError; (2) call
createConfigLoader('./') with inputs like '../../../etc/passwd' and
Windows-style backslashes and assert the loader either throws
ConfigFileNotFoundError or a security-related error (ensuring the resolved path
does not escape the project root); (3) pass paths containing Unicode, spaces,
and special characters and assert correct resolution or safe rejection; and (4)
mock readFileSync to throw (e.g., EACCES) and assert the loader surfaces an
error (expect a thrown error), referencing createConfigLoader,
InvalidConfigFormatError, and ConfigFileNotFoundError to locate the relevant
code paths.
- Around line 224-242: The test currently only asserts result.api; update the
test that calls createConfigLoader('/project') and
loader('@living-architecture/riviere-extract-conventions') to also assert that
the returned Module includes all six component keys with defaults of notUsed:
true for those not specified. Specifically, after the existing
expect(result.api) assertion, add assertions that result.{componentName} (for
the other five component types plus any top-level types expected by the Module
shape) exist and equal an object with notUsed: true, referencing the same result
variable and the createConfigLoader/loader call to locate the code to modify.
In @packages/riviere-schema/src/schema.spec.ts:
- Around line 141-142: Capture the thrown error from a single call to
parseRiviereGraph(input) and assert both its type and message on that captured
error instead of calling parseRiviereGraph twice; e.g., invoke
parseRiviereGraph(input) inside a try/catch (or use Jest’s function-capturing
pattern to get the error), store the error, then assert it is an instance of
RiviereSchemaValidationError and that its message matches /Invalid
RiviereGraph/.
- Around line 104-105: The test currently calls parseRiviereGraph(input) twice;
capture the thrown error once and assert both its type and message on that
single error object: call parseRiviereGraph(input) inside a try/catch (or use
Jest's toThrowError to get the thrown error) and then assert error is instance
of RiviereSchemaValidationError and that error.message matches /Invalid
RiviereGraph/ (referencing parseRiviereGraph and RiviereSchemaValidationError).
- Around line 122-123: The test currently uses a permissive regex
(/version|Invalid RiviereGraph/i) so it passes if either term appears; update
the second assertion in the spec that calls parseRiviereGraph to assert the
error mentions "version" specifically (e.g., expect(() =>
parseRiviereGraph(input)).toThrow(/version/i)) or, if you want both terms
present, use a stricter regex that requires both substrings in any order (e.g.,
match "version" and "Invalid RiviereGraph" together) while still expecting
RiviereSchemaValidationError from parseRiviereGraph.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (10)
apps/eclair/src/components/SchemaModal/SchemaModal.spec.tsxapps/eclair/src/components/SchemaModal/SchemaModal.tsxapps/eclair/src/features/comparison/DomainConnectionDiff.spec.tsxapps/eclair/src/features/comparison/compareGraphs.tsapps/eclair/src/features/full-graph/components/ForceGraph/GraphRenderingSetup.spec.tsapps/eclair/src/features/full-graph/components/ForceGraph/GraphRenderingSetup.tspackages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-extract-config/src/validation.spec.tspackages/riviere-schema/src/component-id.spec.tspackages/riviere-schema/src/schema.spec.ts
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Follow eslint configuration rules defined in
eslint.config.mjsfor all linting
Files:
apps/eclair/src/components/SchemaModal/SchemaModal.tsxapps/eclair/src/components/SchemaModal/SchemaModal.spec.tsxpackages/riviere-extract-config/src/validation.spec.tsapps/eclair/src/features/comparison/compareGraphs.tsapps/eclair/src/features/full-graph/components/ForceGraph/GraphRenderingSetup.tspackages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-schema/src/component-id.spec.tspackages/riviere-schema/src/schema.spec.tsapps/eclair/src/features/full-graph/components/ForceGraph/GraphRenderingSetup.spec.tsapps/eclair/src/features/comparison/DomainConnectionDiff.spec.tsx
**/*.{ts,tsx,js,jsx,css,scss,html}
📄 CodeRabbit inference engine (CLAUDE.md)
All UI and UX design must conform to global brand guidelines in
/docs/brand/(logo, colors, typography, icons)
Files:
apps/eclair/src/components/SchemaModal/SchemaModal.tsxapps/eclair/src/components/SchemaModal/SchemaModal.spec.tsxpackages/riviere-extract-config/src/validation.spec.tsapps/eclair/src/features/comparison/compareGraphs.tsapps/eclair/src/features/full-graph/components/ForceGraph/GraphRenderingSetup.tspackages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-schema/src/component-id.spec.tspackages/riviere-schema/src/schema.spec.tsapps/eclair/src/features/full-graph/components/ForceGraph/GraphRenderingSetup.spec.tsapps/eclair/src/features/comparison/DomainConnectionDiff.spec.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,js,jsx}: Do not log sensitive data (passwords, tokens, PII) in any code
Validate and sanitize all external input
Files:
apps/eclair/src/components/SchemaModal/SchemaModal.tsxapps/eclair/src/components/SchemaModal/SchemaModal.spec.tsxpackages/riviere-extract-config/src/validation.spec.tsapps/eclair/src/features/comparison/compareGraphs.tsapps/eclair/src/features/full-graph/components/ForceGraph/GraphRenderingSetup.tspackages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-schema/src/component-id.spec.tspackages/riviere-schema/src/schema.spec.tsapps/eclair/src/features/full-graph/components/ForceGraph/GraphRenderingSetup.spec.tsapps/eclair/src/features/comparison/DomainConnectionDiff.spec.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use cross-project imports with package names (e.g.,
import { X } from '@living-architecture/[pkg-name]') rather than relative paths
Files:
apps/eclair/src/components/SchemaModal/SchemaModal.tsxapps/eclair/src/components/SchemaModal/SchemaModal.spec.tsxpackages/riviere-extract-config/src/validation.spec.tsapps/eclair/src/features/comparison/compareGraphs.tsapps/eclair/src/features/full-graph/components/ForceGraph/GraphRenderingSetup.tspackages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-schema/src/component-id.spec.tspackages/riviere-schema/src/schema.spec.tsapps/eclair/src/features/full-graph/components/ForceGraph/GraphRenderingSetup.spec.tsapps/eclair/src/features/comparison/DomainConnectionDiff.spec.tsx
packages/riviere-extract-config/**/*.ts
📄 CodeRabbit inference engine (packages/riviere-extract-config/CLAUDE.md)
Extraction config schema is the source of truth for valid structures. TypeScript types must mirror the schema definition to maintain consistency
Files:
packages/riviere-extract-config/src/validation.spec.ts
🧠 Learnings (42)
📓 Common learnings
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Use glob pattern matching for module-based organization of extraction rules
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.{json,ts} : Define extraction configuration using the JSON Schema from `living-architecture/riviere-extract-config` DSL
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 129
File: packages/riviere-cli/src/commands/extract/config-loader.ts:31-39
Timestamp: 2026-01-11T14:38:35.637Z
Learning: In packages/riviere-cli/src/commands/extract/config-loader.ts, the isExtendedConfig type guard intentionally performs minimal validation (checks for non-null object and validates modules is an array if present) because comprehensive validation is handled downstream by the schema validator. The type guard's purpose is basic type narrowing to support both module-array and top-level-rules formats, not comprehensive validation. This follows the layered validation pattern where type guards are minimal and schema validation occurs at system boundaries.
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use `living-architecture/riviere-extract-ts` TypeScript extractor with ts-morph for AST parsing when implementing TypeScript extraction for architecture schema components
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Applies to packages/riviere-extract-config/**/*.ts : Extraction config schema is the source of truth for valid structures. TypeScript types must mirror the schema definition to maintain consistency
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement integration tests for end-to-end extraction from TypeScript code to JSON output
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Reject invalid extraction configs at load time, not during extraction phase
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Implement extraction logic as pure functions with no side effects
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-conventions/CLAUDE.md:0-0
Timestamp: 2026-01-08T07:05:01.766Z
Learning: Import and use the default extraction config from `living-architecture/riviere-extract-conventions/default-config` in extraction tooling to detect all 6 component types
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Compose detection rules via and/or logic for predicates
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: All validation of extraction config must occur at config load time, not during extraction. Invalid configs should fail fast with clear error messages that include paths and descriptive information
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Extraction config schemas must define all six required component types per module: api, useCase, domainOp, event, eventHandler, and ui. Unused component types must be explicitly marked with `notUsed: true` rather than omitted
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: All extraction rules should come from validated ExtractionConfig provided by riviere-extract-config
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test edge cases for dates and times: leap years (Feb 29), daylight saving transitions, timezone boundaries, midnight (00:00:00), end of day (23:59:59), year boundaries, invalid dates (Feb 30, Month 13), Unix epoch edge cases, and far future/past dates.
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.spec.tsxapps/eclair/src/features/comparison/DomainConnectionDiff.spec.tsx
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test violated domain constraints: uniqueness violations (duplicate IDs, emails), missing required relationships (orphaned records), ordering violations (events out of sequence), range breaches (age -1, quantity 1000000), state inconsistencies (shipped but not paid), format mismatches (expected JSON, got XML), and temporal ordering (end before start).
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.spec.tsxpackages/riviere-schema/src/component-id.spec.tsapps/eclair/src/features/comparison/DomainConnectionDiff.spec.tsx
📚 Learning: 2026-01-08T22:20:13.250Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use the Rivière Builder Node.js library to programmatically construct the schema graph when implementing custom extraction code
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.spec.tsxapps/eclair/src/features/comparison/compareGraphs.tspackages/riviere-schema/src/schema.spec.ts
📚 Learning: 2026-01-06T23:01:34.751Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Applies to packages/riviere-extract-config/**/*.ts : Extraction config schema is the source of truth for valid structures. TypeScript types must mirror the schema definition to maintain consistency
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.spec.tsxpackages/riviere-extract-config/src/validation.spec.tspackages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-schema/src/component-id.spec.tspackages/riviere-schema/src/schema.spec.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement unit tests for each predicate type in isolation with positive and negative cases
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.spec.tsxpackages/riviere-extract-config/src/validation.spec.tspackages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-schema/src/component-id.spec.tspackages/riviere-schema/src/schema.spec.tsapps/eclair/src/features/comparison/DomainConnectionDiff.spec.tsx
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement integration tests for end-to-end extraction from TypeScript code to JSON output
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.spec.tsxpackages/riviere-extract-config/src/validation.spec.tspackages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-schema/src/component-id.spec.tspackages/riviere-schema/src/schema.spec.tsapps/eclair/src/features/comparison/DomainConnectionDiff.spec.tsx
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Use ts-morph's in-memory file system (`useInMemoryFileSystem: true`) for fast isolated tests
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.spec.tsxpackages/riviere-cli/src/commands/extract/config-loader.spec.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Reject invalid extraction configs at load time, not during extraction phase
Applied to files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-schema/src/component-id.spec.tspackages/riviere-schema/src/schema.spec.ts
📚 Learning: 2026-01-11T14:38:35.637Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 129
File: packages/riviere-cli/src/commands/extract/config-loader.ts:31-39
Timestamp: 2026-01-11T14:38:35.637Z
Learning: In packages/riviere-cli/src/commands/extract/config-loader.ts, the isExtendedConfig type guard intentionally performs minimal validation (checks for non-null object and validates modules is an array if present) because comprehensive validation is handled downstream by the schema validator. The type guard's purpose is basic type narrowing to support both module-array and top-level-rules formats, not comprehensive validation. This follows the layered validation pattern where type guards are minimal and schema validation occurs at system boundaries.
Applied to files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-schema/src/schema.spec.ts
📚 Learning: 2026-01-09T20:08:44.180Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 88
File: packages/riviere-cli/src/commands/extract/extract.ts:109-114
Timestamp: 2026-01-09T20:08:44.180Z
Learning: Applies to packages/riviere-cli/src/commands/extract/**/*.{ts,tsx} : CLI extraction commands should only catch and format expected validation errors as structured JSON. System-level exceptions (disk I/O failures, OOM, AST parse errors) should fail loudly with stack traces for debugging rather than being wrapped in try-catch and converted to JSON errors. This follows the fail-fast principle: validate inputs explicitly, then let unexpected failures surface clearly.
Applied to files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-schema/src/component-id.spec.tspackages/riviere-schema/src/schema.spec.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: All extraction rules should come from validated ExtractionConfig provided by riviere-extract-config
Applied to files:
packages/riviere-extract-config/src/validation.spec.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Implement extraction logic as pure functions with no side effects
Applied to files:
packages/riviere-extract-config/src/validation.spec.ts
📚 Learning: 2026-01-08T22:20:13.250Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.{json,ts} : Define extraction configuration using the JSON Schema from `living-architecture/riviere-extract-config` DSL
Applied to files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-cli/src/commands/extract/config-loader.spec.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Use glob pattern matching for module-based organization of extraction rules
Applied to files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-cli/src/commands/extract/config-loader.spec.ts
📚 Learning: 2026-01-06T23:01:34.751Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: All validation of extraction config must occur at config load time, not during extraction. Invalid configs should fail fast with clear error messages that include paths and descriptive information
Applied to files:
packages/riviere-extract-config/src/validation.spec.ts
📚 Learning: 2026-01-06T23:01:34.751Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Extraction config schemas must define all six required component types per module: api, useCase, domainOp, event, eventHandler, and ui. Unused component types must be explicitly marked with `notUsed: true` rather than omitted
Applied to files:
packages/riviere-extract-config/src/validation.spec.ts
📚 Learning: 2026-01-08T07:05:01.766Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-conventions/CLAUDE.md:0-0
Timestamp: 2026-01-08T07:05:01.766Z
Learning: Import and use the default extraction config from `living-architecture/riviere-extract-conventions/default-config` in extraction tooling to detect all 6 component types
Applied to files:
packages/riviere-extract-config/src/validation.spec.ts
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*-fixtures.ts : Create `<module>-fixtures.ts` fixture files alongside `<module>.spec.ts` to reduce duplication when multiple tests share similar setup data or differ only in specific values being tested.
Applied to files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-cli/src/commands/extract/config-loader.spec.ts
📚 Learning: 2026-01-09T20:08:30.350Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 88
File: packages/riviere-cli/src/commands/extract/extract.spec.ts:33-38
Timestamp: 2026-01-09T20:08:30.350Z
Learning: In test files, keep type guard implementations like isExtractionOutput(value: unknown): value is ExtractionOutput focused on narrowing types for TypeScript. Do not perform comprehensive runtime shape validation in type guards; rely on explicit test assertions (e.g., expect(result).toMatchObject(...)) for shape checks. This keeps type guards simple and rely on assertion-based tests for thorough validation.
Applied to files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-schema/src/component-id.spec.tspackages/riviere-schema/src/schema.spec.tsapps/eclair/src/features/full-graph/components/ForceGraph/GraphRenderingSetup.spec.ts
📚 Learning: 2026-01-08T06:46:00.609Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 66
File: packages/riviere-extract-conventions/src/eslint/require-component-decorator.spec.ts:19-21
Timestamp: 2026-01-08T06:46:00.609Z
Learning: In test files using typescript-eslint/rule-tester's RuleTester.run(), ensure there is an explicit it() block with at least one expect() assertion (e.g., expect(rule).toBeDefined()) to satisfy sonarjs/no-empty-test-file and sonarjs/assertions-in-tests lint rules, which don’t recognize RuleTester's internal test blocks. Apply this pattern to all spec.ts test files to maintain consistency and pass lint checks.
Applied to files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-schema/src/component-id.spec.tspackages/riviere-schema/src/schema.spec.tsapps/eclair/src/features/full-graph/components/ForceGraph/GraphRenderingSetup.spec.ts
📚 Learning: 2026-01-10T08:54:09.466Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 96
File: apps/docs/.vitepress/theme/eclairLinkHandler.spec.ts:229-249
Timestamp: 2026-01-10T08:54:09.466Z
Learning: In jsdom test environments, window.location.assign cannot be spied on due to TypeError: Cannot redefine property. Use Object.defineProperty to mock the entire window.location object, replacing it with a controlled mock, and restore the original in afterEach. Ensure to clean up the mock after each test to avoid side effects.
Applied to files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-schema/src/component-id.spec.tspackages/riviere-schema/src/schema.spec.tsapps/eclair/src/features/full-graph/components/ForceGraph/GraphRenderingSetup.spec.ts
📚 Learning: 2026-01-08T12:57:19.167Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 67
File: packages/riviere-extract-ts/tsconfig.spec.json:5-22
Timestamp: 2026-01-08T12:57:19.167Z
Learning: In tsconfig.spec.json files, use expanded types array ["vitest/globals", "vitest/importMeta", "vite/client", "node", "vitest"] for complete test type coverage. Include patterns should cover .test and .spec files, config files (vitest.config.ts/mts, vite.config.ts/mts), multiple extensions (.ts, .tsx, .js, .jsx), and .d.ts files to ensure proper TypeScript coverage across the testing environment.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.tsapps/eclair/src/features/comparison/DomainConnectionDiff.spec.tsx
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/vitest.config.mts : Enforce 100% code coverage using Vitest with v8 coverage and thresholds configured in vitest.config.mts
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.ts
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test domain-specific edge cases: email (valid formats, plus signs, subdomains), URLs (protocols, ports, special characters, relative paths), phone numbers (international formats, extensions), addresses (Unicode, multi-line, missing components), currency (rounding, different currencies, zero amounts), percentages (0%, 100%, over 100%).
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.tspackages/riviere-schema/src/component-id.spec.tsapps/eclair/src/features/comparison/DomainConnectionDiff.spec.tsx
📚 Learning: 2026-01-11T11:17:09.319Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.319Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test edge cases for string inputs: empty string, whitespace-only strings, very long strings (10K+ characters), Unicode (emojis, RTL text, combining characters), special characters (quotes, backslashes, null bytes), SQL/HTML/script injection patterns, and leading/trailing whitespace.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.tsapps/eclair/src/features/comparison/DomainConnectionDiff.spec.tsx
📚 Learning: 2026-01-08T19:36:17.306Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/codebase-structure.md:0-0
Timestamp: 2026-01-08T19:36:17.306Z
Learning: Applies to docs/conventions/packages/*/vitest.config.ts : Each package must include a vitest.config.ts file with 100% coverage thresholds for test configuration.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.ts
📚 Learning: 2026-01-10T10:14:57.499Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-10T10:14:57.499Z
Learning: Applies to **/vitest.config.ts : When creating new projects with tests, add vitest.config.ts with 100% coverage as the default
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.ts
📚 Learning: 2026-01-09T20:08:44.180Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 88
File: packages/riviere-cli/src/commands/extract/extract.ts:109-114
Timestamp: 2026-01-09T20:08:44.180Z
Learning: In packages/riviere-cli/src/commands/extract/**/*.{ts,tsx}, CLI extraction commands should only catch and format expected validation errors as structured JSON. Do not wrap or convert system-level exceptions (e.g., disk I/O failures, OOM, AST parse errors) into JSON errors; instead, fail loudly with stack traces to aid debugging. Follow fail-fast principles: validate inputs explicitly, and surface unexpected failures clearly.
Applied to files:
packages/riviere-cli/src/commands/extract/config-loader.spec.ts
📚 Learning: 2026-01-08T07:05:01.766Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-conventions/CLAUDE.md:0-0
Timestamp: 2026-01-08T07:05:01.766Z
Learning: Applies to packages/riviere-extract-conventions/**/*.ts : Use `Custom(type)` decorator to annotate components with custom types not covered by standard decorators
Applied to files:
packages/riviere-schema/src/component-id.spec.tspackages/riviere-schema/src/schema.spec.ts
📚 Learning: 2026-01-08T07:05:01.766Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-conventions/CLAUDE.md:0-0
Timestamp: 2026-01-08T07:05:01.766Z
Learning: Applies to packages/riviere-extract-conventions/**/*.ts : Use `UseCase`, `Event`, or `UI` class-level decorators to mark the class itself as a component
Applied to files:
packages/riviere-schema/src/component-id.spec.ts
📚 Learning: 2026-01-11T11:17:09.319Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.319Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test edge cases for number inputs: zero, negative numbers, very large/small numbers (near MAX/MIN_SAFE_INTEGER), decimal precision (0.1 + 0.2), NaN, Infinity/-Infinity, and boundary values (off-by-one at limits).
Applied to files:
packages/riviere-schema/src/component-id.spec.tsapps/eclair/src/features/comparison/DomainConnectionDiff.spec.tsx
📚 Learning: 2026-01-11T11:17:09.319Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.319Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Assertions must match test titles. If the test claims to verify 'different IDs', assert on the actual ID values—not just count or existence.
Applied to files:
packages/riviere-schema/src/component-id.spec.tsapps/eclair/src/features/comparison/DomainConnectionDiff.spec.tsx
📚 Learning: 2026-01-02T11:58:30.913Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-schema/CLAUDE.md:0-0
Timestamp: 2026-01-02T11:58:30.913Z
Learning: Do not include riviere-schema in breaking change commits (`!` or `BREAKING CHANGE`) - this automatically bumps the major version
Applied to files:
packages/riviere-schema/src/schema.spec.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Use ts-morph for TypeScript AST parsing instead of other parsers
Applied to files:
packages/riviere-schema/src/schema.spec.ts
📚 Learning: 2026-01-08T23:16:02.639Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/software-design.md:0-0
Timestamp: 2026-01-08T23:16:02.639Z
Learning: Applies to docs/conventions/**/*.{ts,tsx,js,jsx} : Fail-Fast Error Handling: Validate and throw clear errors instead of using fallback chains. Error format: `Expected [X]. Got [Y]. Context: [debugging info]`
Applied to files:
packages/riviere-schema/src/schema.spec.tsapps/eclair/src/features/full-graph/components/ForceGraph/GraphRenderingSetup.spec.tsapps/eclair/src/features/comparison/DomainConnectionDiff.spec.tsx
📚 Learning: 2026-01-11T11:17:09.319Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.319Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test edge cases for collections (arrays, objects, maps): empty collections, single element, duplicates, nested structures, circular references, very large collections (performance), sparse arrays, and mixed types.
Applied to files:
apps/eclair/src/features/comparison/DomainConnectionDiff.spec.tsx
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test null and undefined inputs: null input, undefined input, missing optional properties, and explicit undefined vs missing key.
Applied to files:
apps/eclair/src/features/comparison/DomainConnectionDiff.spec.tsx
📚 Learning: 2026-01-08T06:46:05.503Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 66
File: packages/riviere-extract-conventions/src/eslint/require-component-decorator.spec.ts:19-21
Timestamp: 2026-01-08T06:46:05.503Z
Learning: In test files using typescript-eslint/rule-tester's RuleTester.run(), include an explicit it() block with an expect() assertion (e.g., expect(rule).toBeDefined()) to satisfy sonarjs/no-empty-test-file and sonarjs/assertions-in-tests lint rules, which don't recognize RuleTester's internal test blocks.
Applied to files:
apps/eclair/src/features/comparison/DomainConnectionDiff.spec.tsx
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Avoid implementation coupling in tests. Test behavior, not implementation details. Instead of asserting on mock call arguments with exact SQL, assert on the observable result (e.g., expect(result.user.name).toBe('Alice')).
Applied to files:
apps/eclair/src/features/comparison/DomainConnectionDiff.spec.tsx
📚 Learning: 2026-01-11T11:17:09.319Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.319Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Use Arrange-Act-Assert structure in tests: (1) Set up test data, (2) Execute the behavior, (3) Verify the outcome.
Applied to files:
apps/eclair/src/features/comparison/DomainConnectionDiff.spec.tsx
📚 Learning: 2026-01-11T11:17:09.319Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.319Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Assert specific values, not types. Use `expect(result).toEqual(['First.', ' Second.'])` not `expect(result).toBeDefined()`. Specific assertions catch specific bugs.
Applied to files:
apps/eclair/src/features/comparison/DomainConnectionDiff.spec.tsx
🧬 Code graph analysis (6)
apps/eclair/src/components/SchemaModal/SchemaModal.tsx (1)
apps/eclair/src/errors.ts (2)
CSSModuleError(54-59)SchemaError(74-79)
apps/eclair/src/components/SchemaModal/SchemaModal.spec.tsx (2)
apps/eclair/src/components/SchemaModal/SchemaModal.tsx (1)
SchemaModal(57-237)apps/eclair/src/errors.ts (1)
SchemaError(74-79)
apps/eclair/src/features/comparison/compareGraphs.ts (1)
apps/eclair/src/errors.ts (1)
GraphError(14-19)
apps/eclair/src/features/full-graph/components/ForceGraph/GraphRenderingSetup.ts (1)
apps/eclair/src/errors.ts (2)
LayoutError(34-39)RenderingError(24-29)
packages/riviere-cli/src/commands/extract/config-loader.spec.ts (2)
packages/riviere-cli/src/commands/extract/config-loader.ts (1)
createConfigLoader(126-134)packages/riviere-cli/src/errors.ts (4)
ConfigFileNotFoundError(99-109)InvalidConfigFormatError(71-84)ConfigSchemaValidationError(64-69)PackageResolveError(86-97)
apps/eclair/src/features/full-graph/components/ForceGraph/GraphRenderingSetup.spec.ts (2)
apps/eclair/src/features/full-graph/components/ForceGraph/GraphRenderingSetup.ts (1)
extractCoordinates(35-44)apps/eclair/src/errors.ts (1)
LayoutError(34-39)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Cloudflare Pages
- GitHub Check: browser-tests (webkit)
- GitHub Check: browser-tests (firefox)
- GitHub Check: main
🔇 Additional comments (20)
apps/eclair/src/features/comparison/compareGraphs.ts (3)
4-4: LGTM! Domain-specific error import added.The import of
GraphErrorenhances error specificity for graph operations and aligns with the new error hierarchy introduced in this PR.
207-217: LGTM! Defensive check with appropriate coverage annotation.The defensive undefined check at lines 213-215 correctly handles TypeScript's type system constraints while documenting that this code path should be unreachable in practice. The v8 coverage directive appropriately excludes this defensive code from coverage metrics.
214-214: LGTM! Error type upgraded to domain-specific GraphError.Replacing generic
ErrorwithGraphErrorimproves error specificity and enables more precise error handling for graph operations.apps/eclair/src/features/full-graph/components/ForceGraph/GraphRenderingSetup.spec.ts (1)
12-12: LGTM! Error type assertions correctly updated.The test updates properly reflect the implementation's use of
LayoutErrorfor coordinate validation failures. The assertions now check for the specific error type rather than generic errors, which improves type safety and error handling clarity.Optional: Consider validating error messages
For more thorough testing, you could also validate the error message content:
-expect(() => extractCoordinates(nodes, 'x')).toThrow(LayoutError) +expect(() => extractCoordinates(nodes, 'x')).toThrow( + new LayoutError('Node 1 missing layout x coordinate') +)This ensures both the error type and message remain correct, though the current type-only validation is acceptable.
Also applies to: 102-102, 121-121, 124-124, 143-143
apps/eclair/src/features/full-graph/components/ForceGraph/GraphRenderingSetup.ts (4)
14-16: LGTM! Specialized error types imported.The introduction of
LayoutErrorandRenderingErrorimproves error handling by distinguishing coordinate/layout issues from node lookup failures, making debugging easier.
35-43: LGTM! Error handling improved with specific type.Using
LayoutErrorinstead of a genericErrorfor missing coordinates is appropriate and aligns with the domain-specific error class strategy.
183-190: LGTM! Defensive check with appropriate error type.The
RenderingErrorcorrectly categorizes node lookup failures. The v8 ignore comment appropriately marks this as defensive code since links should only reference valid node IDs.
302-368: LGTM! Comprehensive defensive error handling.The multiple defensive checks properly distinguish between:
RenderingError: Node lookup failures in the position map (lines 316, 322)LayoutError: Missing coordinates after layout computation (lines 328, 334, 364)Error messages include helpful debugging context (available nodes, JSON dumps). The v8 ignore comments correctly mark these as defensive paths that shouldn't execute in normal D3 simulation flow.
Note on v8 ignore comment format: The
@preservedirective in the v8 ignore comments (e.g., line 314) is non-standard. Standard format is/* v8 ignore next N */. While the current format likely works, consider removing@preserveif coverage reporting encounters issues:-/* v8 ignore next 3 -- @preserve defensive: D3 callback, position map built from same nodes */ +/* v8 ignore next 3 -- defensive: D3 callback, position map built from same nodes */packages/riviere-schema/src/component-id.spec.ts (1)
1-3: LGTM! Import correctly extended for error-type assertions.The addition of
InvalidComponentIdErrorto the imports is necessary and correct for the type-specific error assertions added below.packages/riviere-schema/src/schema.spec.ts (1)
10-12: LGTM: Imports correctly include the new error type.The imports properly include
RiviereSchemaValidationErrorfor testing the specific error class thrown byparseRiviereGraph.packages/riviere-extract-config/src/validation.spec.ts (3)
7-7: LGTM!The import of
ExtractionConfigValidationErrorimproves type safety and enables more specific test assertions for validation failures.
345-346: LGTM!Excellent improvement. Asserting the specific
ExtractionConfigValidationErrortype instead of a genericErrormakes the test more precise and ensures the correct error type is thrown on validation failures.
25-27: Test is valid—validator schema accepts both unresolved and resolved config shapes.The validator schema accepts
ResolvedExtractionConfigbecauseModuleis a superset ofModuleConfig(required fields in resolved configs satisfy optional-field requirements in unresolved configs). This test confirms the schema's permissiveness. Consider a more descriptive test name: "returns true when config has all modules fully resolved" or similar.apps/eclair/src/features/comparison/DomainConnectionDiff.spec.tsx (2)
2-2: LGTM: Import formattingThe import formatting changes are purely cosmetic and maintain consistency.
Also applies to: 5-5
10-10: LGTM: Error type importThe LayoutError import is necessary for the new error-handling tests and uses the correct import pattern.
packages/riviere-cli/src/commands/extract/config-loader.spec.ts (1)
58-61: Consider consolidating error assertions to avoid redundant loader calls.Multiple tests call the loader twice—once to check the error type and again to verify the message. While harmless, this is inefficient.
♻️ Example refactor to reduce redundancy
-expect(() => loader('./missing.json')).toThrow(ConfigFileNotFoundError) -expect(() => loader('./missing.json')).toThrow( - "Cannot resolve extends reference './missing.json'", -) +expect(() => loader('./missing.json')) + .toThrow(ConfigFileNotFoundError) + .toThrow("Cannot resolve extends reference './missing.json'")Or use a try-catch to capture the error once:
try { loader('./missing.json') expect.fail('Expected error to be thrown') } catch (error) { expect(error).toBeInstanceOf(ConfigFileNotFoundError) expect(error).toHaveProperty('source', './missing.json') expect(error).toHaveProperty('message', expect.stringContaining("Cannot resolve extends reference './missing.json'")) }Also applies to: 70-71, 80-81, 90-91, 108-109
⛔ Skipped due to learnings
Learnt from: CR Repo: NTCoding/living-architecture PR: 0 File: packages/riviere-extract-ts/CLAUDE.md:0-0 Timestamp: 2026-01-08T17:19:17.148Z Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement integration tests for end-to-end extraction from TypeScript code to JSON outputLearnt from: NTCoding Repo: NTCoding/living-architecture PR: 88 File: packages/riviere-cli/src/commands/extract/extract.ts:109-114 Timestamp: 2026-01-09T20:08:44.180Z Learning: Applies to packages/riviere-cli/src/commands/extract/**/*.{ts,tsx} : CLI extraction commands should only catch and format expected validation errors as structured JSON. System-level exceptions (disk I/O failures, OOM, AST parse errors) should fail loudly with stack traces for debugging rather than being wrapped in try-catch and converted to JSON errors. This follows the fail-fast principle: validate inputs explicitly, then let unexpected failures surface clearly.Learnt from: CR Repo: NTCoding/living-architecture PR: 0 File: packages/riviere-extract-ts/CLAUDE.md:0-0 Timestamp: 2026-01-08T17:19:17.148Z Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement unit tests for each predicate type in isolation with positive and negative casesLearnt from: NTCoding Repo: NTCoding/living-architecture PR: 129 File: packages/riviere-cli/src/commands/extract/config-loader.ts:31-39 Timestamp: 2026-01-11T14:38:35.637Z Learning: In packages/riviere-cli/src/commands/extract/config-loader.ts, the isExtendedConfig type guard intentionally performs minimal validation (checks for non-null object and validates modules is an array if present) because comprehensive validation is handled downstream by the schema validator. The type guard's purpose is basic type narrowing to support both module-array and top-level-rules formats, not comprehensive validation. This follows the layered validation pattern where type guards are minimal and schema validation occurs at system boundaries.Learnt from: CR Repo: NTCoding/living-architecture PR: 0 File: docs/workflow/code-review.md:0-0 Timestamp: 2026-01-07T08:54:48.071Z Learning: Applies to docs/workflow/**/*.{ts,tsx,js,jsx} : Review usage of `/* v8 ignore next -- preserve */` coverage skip directives. This is only acceptable for unreachable code needed to satisfy the compiler. Most cases should be solved by extracting code or writing tests to mock behavior.Learnt from: CR Repo: NTCoding/living-architecture PR: 0 File: packages/riviere-extract-ts/CLAUDE.md:0-0 Timestamp: 2026-01-08T17:19:17.148Z Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Reject invalid extraction configs at load time, not during extraction phaseLearnt from: NTCoding Repo: NTCoding/living-architecture PR: 67 File: packages/riviere-extract-ts/tsconfig.spec.json:5-22 Timestamp: 2026-01-08T12:57:19.167Z Learning: In tsconfig.spec.json files, use expanded types array ["vitest/globals", "vitest/importMeta", "vite/client", "node", "vitest"] for complete test type coverage. Include patterns should cover .test and .spec files, config files (vitest.config.ts/mts, vite.config.ts/mts), multiple extensions (.ts, .tsx, .js, .jsx), and .d.ts files to ensure proper TypeScript coverage across the testing environment.Learnt from: CR Repo: NTCoding/living-architecture PR: 0 File: docs/conventions/anti-patterns.md:0-0 Timestamp: 2026-01-11T11:04:34.655Z Learning: When hitting max-lines limits, split files into focused modules (e.g., `foo.spec.ts` and `foo.edge-cases.spec.ts`), extract duplicated code into shared modules, or use parameterized tests with `it.each` or `describe.each` instead of removing tests or compressing code.Learnt from: CR Repo: NTCoding/living-architecture PR: 0 File: docs/conventions/testing.md:0-0 Timestamp: 2026-01-11T11:17:09.320Z Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test domain-specific edge cases: email (valid formats, plus signs, subdomains), URLs (protocols, ports, special characters, relative paths), phone numbers (international formats, extensions), addresses (Unicode, multi-line, missing components), currency (rounding, different currencies, zero amounts), percentages (0%, 100%, over 100%).Learnt from: CR Repo: NTCoding/living-architecture PR: 0 File: packages/riviere-extract-ts/CLAUDE.md:0-0 Timestamp: 2026-01-08T17:19:17.148Z Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Use ts-morph's in-memory file system (`useInMemoryFileSystem: true`) for fast isolated testsLearnt from: CR Repo: NTCoding/living-architecture PR: 0 File: docs/conventions/software-design.md:0-0 Timestamp: 2026-01-08T23:16:02.639Z Learning: Applies to docs/conventions/**/*.{ts,tsx,js,jsx} : Fail-Fast Error Handling: Validate and throw clear errors instead of using fallback chains. Error format: `Expected [X]. Got [Y]. Context: [debugging info]`apps/eclair/src/components/SchemaModal/SchemaModal.tsx (2)
12-14: LGTM! Error imports are correct.The new error class imports follow the project's error hierarchy pattern.
94-108: LGTM! Defensive check with clear error message.The
SchemaErrorprovides a descriptive message for the defensive case wheregraphNameis undefined. While the button is disabled in the UI (line 168), this guard prevents issues from programmatic calls or race conditions.apps/eclair/src/components/SchemaModal/SchemaModal.spec.tsx (2)
16-16: LGTM! Error import is correct.
27-31: LGTM! Test helper is appropriate for its use case.The helper function is well-suited for testing error throws, where the render result isn't needed. The hardcoded values (graphName, isOpen, onClose) are reasonable defaults for these specific tests.
- Remove unjustified v8 ignore comments from SchemaModal.tsx - Extract validateDownloadGraphName function for testability - Export getStyle function for testability - Add SchemaModal.cssModule.spec.ts to test CSSModuleError path - Add validateDownloadGraphName tests for SchemaError path - Add anti-pattern rule for lazy coverage ignore comments Coverage ignore comments must be fully justified - "hard to test" or "button is disabled" are not valid excuses. Co-Authored-By: Claude Opus 4.5 <[email protected]>
When SonarCloud quality gate fails, the script now shows a direct link to the coverage breakdown page, making it easier to identify which files need additional test coverage. Co-Authored-By: Claude Opus 4.5 <[email protected]>
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/eclair/src/components/SchemaModal/SchemaModal.tsx (1)
116-128: Improved error handling, but consider more defensive date parsing.The change to use
SchemaErrorwith a descriptive message is a good improvement. However, the date parsing could be more defensive:
- The
split('T')operation is not guaranteed to return a non-empty array.- While you check
datePart === undefined, using optional chaining would be more idiomatic:const datePart = parts[0]?.trim().- Consider checking for valid date format more thoroughly (e.g., using regex or Date validation) if this function processes untrusted input.
Given that
graph.metadata.generatedshould be validated earlier in the pipeline, the current implementation may be acceptable, but defensive parsing is recommended.♻️ More defensive date parsing
function formatGeneratedDate(isoDateString: string | undefined): string { if (isoDateString === undefined) { return 'Unknown' } const parts = isoDateString.split('T') - const datePart = parts[0] - if (datePart === undefined || datePart === '') { + const datePart = parts[0]?.trim() + if (!datePart) { throw new SchemaError( `Invalid ISO date string: "${isoDateString}". Expected format like "2024-01-15T10:30:00Z".`, ) } return datePart }
🤖 Fix all issues with AI agents
In @apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts:
- Around line 13-21: Add a positive test that mocks the full CSS module so
importing './SchemaModal' succeeds and exports are usable, and consolidate the
two failing tests into one that asserts the thrown error is an instance of
CSSModuleError and that its message contains the missing class name;
specifically, create/reset module state between tests (use vi.resetModules or a
separate test file), add a success case that provides all required class keys
when importing './SchemaModal', and replace the two existing negative tests with
a single assertion that import('./SchemaModal') rejects with CSSModuleError and
that the error message includes 'jsonBasicChild' (or make the expected class
name configurable if order is nondeterministic).
In @apps/eclair/src/components/SchemaModal/SchemaModal.spec.tsx:
- Around line 107-121: Tests duplicate validation of graph.metadata.generated;
consolidate the two cases into one test that asserts both the thrown type
(SchemaError) and the error message ('Invalid ISO date string') when rendering
via renderSchemaModalWithGraph, and replace the two single-case tests with a
table-driven test that iterates invalid inputs (""; "2024-01-15";
"2024-T01-15T10:30:00Z"; "T"; " T10:30:00Z"; " 2024-01-15 T10:30:00Z") by
assigning each to graph.metadata.generated and expecting
renderSchemaModalWithGraph(graph) to throw SchemaError with the message; also
add a positive case where graph.metadata.generated = "2024-01-15T10:30:00Z" and
assert renderSchemaModalWithGraph(graph) does not throw and yields/contains the
formatted date part "2024-01-15".
In @apps/eclair/src/components/SchemaModal/SchemaModal.tsx:
- Around line 16-22: The getStyle function is currently exported but appears to
be an internal helper; remove the export modifier from getStyle in SchemaModal
(change "export function getStyle" to "function getStyle") and update any
internal references to it within the module; if any external files import
getStyle, instead export a stable public API or update those callers to use the
public component API; leave the CSSModuleError and 'SchemaModal.module.css'
usage intact so the function still throws when a style is missing.
In @scripts/get-pr-feedback.sh:
- Line 157: The SONAR_PROJECT_KEY extraction uses grep without limiting matches,
so duplicate sonar.projectKey entries would be concatenated; update the command
that sets SONAR_PROJECT_KEY to pass the grep -m1 flag to stop after the first
match (keep the rest of the pipeline: cut -d'=' -f2 | tr -d '[:space:]') so only
the first project key is used.
- Line 165: The printed SonarCloud URL uses SONAR_PROJECT_KEY directly which can
break with special characters; encode SONAR_PROJECT_KEY before insertion and use
the encoded variable in the printf that builds the URL (replace the direct
$SONAR_PROJECT_KEY in the printf with the encoded variable). A simple approach
is to compute ENCODED_SONAR_PROJECT_KEY via jq's @uri filter (e.g., pass
SONAR_PROJECT_KEY into jq to produce a URI-encoded string) and then reference
ENCODED_SONAR_PROJECT_KEY and PR_NUMBER in the existing printf call.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (5)
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.tsapps/eclair/src/components/SchemaModal/SchemaModal.spec.tsxapps/eclair/src/components/SchemaModal/SchemaModal.tsxdocs/conventions/anti-patterns.mdscripts/get-pr-feedback.sh
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Follow eslint configuration rules defined in
eslint.config.mjsfor all linting
Files:
apps/eclair/src/components/SchemaModal/SchemaModal.spec.tsxapps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.tsapps/eclair/src/components/SchemaModal/SchemaModal.tsx
**/*.{ts,tsx,js,jsx,css,scss,html}
📄 CodeRabbit inference engine (CLAUDE.md)
All UI and UX design must conform to global brand guidelines in
/docs/brand/(logo, colors, typography, icons)
Files:
apps/eclair/src/components/SchemaModal/SchemaModal.spec.tsxapps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.tsapps/eclair/src/components/SchemaModal/SchemaModal.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,js,jsx}: Do not log sensitive data (passwords, tokens, PII) in any code
Validate and sanitize all external input
Files:
apps/eclair/src/components/SchemaModal/SchemaModal.spec.tsxapps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.tsapps/eclair/src/components/SchemaModal/SchemaModal.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use cross-project imports with package names (e.g.,
import { X } from '@living-architecture/[pkg-name]') rather than relative paths
Files:
apps/eclair/src/components/SchemaModal/SchemaModal.spec.tsxapps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.tsapps/eclair/src/components/SchemaModal/SchemaModal.tsx
🧠 Learnings (31)
📓 Common learnings
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use `living-architecture/riviere-extract-ts` TypeScript extractor with ts-morph for AST parsing when implementing TypeScript extraction for architecture schema components
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.{json,ts} : Define extraction configuration using the JSON Schema from `living-architecture/riviere-extract-config` DSL
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Use glob pattern matching for module-based organization of extraction rules
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 129
File: packages/riviere-cli/src/commands/extract/config-loader.ts:31-39
Timestamp: 2026-01-11T14:38:35.637Z
Learning: In packages/riviere-cli/src/commands/extract/config-loader.ts, the isExtendedConfig type guard intentionally performs minimal validation (checks for non-null object and validates modules is an array if present) because comprehensive validation is handled downstream by the schema validator. The type guard's purpose is basic type narrowing to support both module-array and top-level-rules formats, not comprehensive validation. This follows the layered validation pattern where type guards are minimal and schema validation occurs at system boundaries.
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Applies to packages/riviere-extract-config/**/*.ts : Extraction config schema is the source of truth for valid structures. TypeScript types must mirror the schema definition to maintain consistency
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-conventions/CLAUDE.md:0-0
Timestamp: 2026-01-08T07:05:01.766Z
Learning: Import and use the default extraction config from `living-architecture/riviere-extract-conventions/default-config` in extraction tooling to detect all 6 component types
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement integration tests for end-to-end extraction from TypeScript code to JSON output
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use the Rivière Builder Node.js library to programmatically construct the schema graph when implementing custom extraction code
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Reject invalid extraction configs at load time, not during extraction phase
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Implement extraction logic as pure functions with no side effects
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Extraction config schemas must define all six required component types per module: api, useCase, domainOp, event, eventHandler, and ui. Unused component types must be explicitly marked with `notUsed: true` rather than omitted
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: All validation of extraction config must occur at config load time, not during extraction. Invalid configs should fail fast with clear error messages that include paths and descriptive information
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: All extraction rules should come from validated ExtractionConfig provided by riviere-extract-config
📚 Learning: 2026-01-06T18:02:51.422Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 58
File: scripts/get-pr-feedback.sh:45-55
Timestamp: 2026-01-06T18:02:51.422Z
Learning: In shell scripts that call GraphQL APIs (e.g., scripts/get-pr-feedback.sh and similar), prefer using sed-based interpolation for GraphQL variables instead of gh api graphql's -f/-F flags. Rationale: sed-based interpolation is typically simpler and more robust in Bash contexts, avoids JSON encoding pitfalls, and keeps the script portable. Implement by building the GraphQL query as a string and substituting variables with sed or parameter expansion, ensuring proper escaping. If you must use -f/-F, provide clear justification in a comment.
Applied to files:
scripts/get-pr-feedback.sh
📚 Learning: 2026-01-06T18:13:47.289Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 58
File: scripts/reply-to-thread.sh:1-12
Timestamp: 2026-01-06T18:13:47.289Z
Learning: In shell scripts across the repository (e.g., scripts/reply-to-thread.sh), keep the code simple by not adding explicit preflight tool-availability checks for external commands (like gh or jq) when those tools would fail on first use anyway. Such checks add boilerplate without changing behavior. If you must guard against missing tools, prefer a minimal, early startup check or rely on the script failing naturally at the point of use.
Applied to files:
scripts/get-pr-feedback.sh
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test edge cases for dates and times: leap years (Feb 29), daylight saving transitions, timezone boundaries, midnight (00:00:00), end of day (23:59:59), year boundaries, invalid dates (Feb 30, Month 13), Unix epoch edge cases, and far future/past dates.
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.spec.tsx
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test domain-specific edge cases: email (valid formats, plus signs, subdomains), URLs (protocols, ports, special characters, relative paths), phone numbers (international formats, extensions), addresses (Unicode, multi-line, missing components), currency (rounding, different currencies, zero amounts), percentages (0%, 100%, over 100%).
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.spec.tsxapps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.tsdocs/conventions/anti-patterns.md
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test violated domain constraints: uniqueness violations (duplicate IDs, emails), missing required relationships (orphaned records), ordering violations (events out of sequence), range breaches (age -1, quantity 1000000), state inconsistencies (shipped but not paid), format mismatches (expected JSON, got XML), and temporal ordering (end before start).
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.spec.tsxapps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.tsdocs/conventions/anti-patterns.md
📚 Learning: 2026-01-11T11:17:09.319Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.319Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test edge cases for string inputs: empty string, whitespace-only strings, very long strings (10K+ characters), Unicode (emojis, RTL text, combining characters), special characters (quotes, backslashes, null bytes), SQL/HTML/script injection patterns, and leading/trailing whitespace.
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.spec.tsx
📚 Learning: 2026-01-11T11:17:09.319Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.319Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test edge cases for number inputs: zero, negative numbers, very large/small numbers (near MAX/MIN_SAFE_INTEGER), decimal precision (0.1 + 0.2), NaN, Infinity/-Infinity, and boundary values (off-by-one at limits).
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.spec.tsx
📚 Learning: 2026-01-11T11:17:09.319Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.319Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test edge cases for collections (arrays, objects, maps): empty collections, single element, duplicates, nested structures, circular references, very large collections (performance), sparse arrays, and mixed types.
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.spec.tsxdocs/conventions/anti-patterns.md
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement unit tests for each predicate type in isolation with positive and negative cases
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.spec.tsxapps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts
📚 Learning: 2026-01-07T08:54:48.071Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/workflow/code-review.md:0-0
Timestamp: 2026-01-07T08:54:48.071Z
Learning: Applies to docs/workflow/**/*.{ts,tsx,js,jsx} : Review usage of `/* v8 ignore next -- preserve */` coverage skip directives. This is only acceptable for unreachable code needed to satisfy the compiler. Most cases should be solved by extracting code or writing tests to mock behavior.
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.spec.tsxdocs/conventions/anti-patterns.md
📚 Learning: 2026-01-11T11:04:34.655Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/anti-patterns.md:0-0
Timestamp: 2026-01-11T11:04:34.655Z
Learning: Applies to docs/conventions/**/*.{ts,tsx,js,jsx} : Do not pass empty strings into parameters of type string. Empty strings indicate missing values and should trigger errors, use optional types, or reconsider the design. Avoid test cases that verify empty string as a valid expected scenario for string parameters.
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.spec.tsx
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test null and undefined inputs: null input, undefined input, missing optional properties, and explicit undefined vs missing key.
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.spec.tsxapps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts
📚 Learning: 2026-01-08T22:20:13.250Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use the Rivière Builder Node.js library to programmatically construct the schema graph when implementing custom extraction code
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.spec.tsx
📚 Learning: 2026-01-08T12:57:19.167Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 67
File: packages/riviere-extract-ts/tsconfig.spec.json:5-22
Timestamp: 2026-01-08T12:57:19.167Z
Learning: In tsconfig.spec.json files, use expanded types array ["vitest/globals", "vitest/importMeta", "vite/client", "node", "vitest"] for complete test type coverage. Include patterns should cover .test and .spec files, config files (vitest.config.ts/mts, vite.config.ts/mts), multiple extensions (.ts, .tsx, .js, .jsx), and .d.ts files to ensure proper TypeScript coverage across the testing environment.
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*-fixtures.ts : Create `<module>-fixtures.ts` fixture files alongside `<module>.spec.ts` to reduce duplication when multiple tests share similar setup data or differ only in specific values being tested.
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.tsdocs/conventions/anti-patterns.md
📚 Learning: 2026-01-11T11:17:09.319Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.319Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Assertions must match test titles. If the test claims to verify 'different IDs', assert on the actual ID values—not just count or existence.
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Avoid implementation coupling in tests. Test behavior, not implementation details. Instead of asserting on mock call arguments with exact SQL, assert on the observable result (e.g., expect(result.user.name).toBe('Alice')).
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts
📚 Learning: 2026-01-08T19:36:17.306Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/codebase-structure.md:0-0
Timestamp: 2026-01-08T19:36:17.306Z
Learning: Applies to docs/conventions/apps/*/vitest.config.ts : Each app must include a vitest.config.ts file with 100% coverage thresholds for test configuration.
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts
📚 Learning: 2026-01-08T06:46:00.609Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 66
File: packages/riviere-extract-conventions/src/eslint/require-component-decorator.spec.ts:19-21
Timestamp: 2026-01-08T06:46:00.609Z
Learning: In test files using typescript-eslint/rule-tester's RuleTester.run(), ensure there is an explicit it() block with at least one expect() assertion (e.g., expect(rule).toBeDefined()) to satisfy sonarjs/no-empty-test-file and sonarjs/assertions-in-tests lint rules, which don’t recognize RuleTester's internal test blocks. Apply this pattern to all spec.ts test files to maintain consistency and pass lint checks.
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts
📚 Learning: 2026-01-08T23:16:02.639Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/software-design.md:0-0
Timestamp: 2026-01-08T23:16:02.639Z
Learning: Applies to docs/conventions/**/*.{ts,tsx,js,jsx} : Fail-Fast Error Handling: Validate and throw clear errors instead of using fallback chains. Error format: `Expected [X]. Got [Y]. Context: [debugging info]`
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts
📚 Learning: 2026-01-10T08:54:09.466Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 96
File: apps/docs/.vitepress/theme/eclairLinkHandler.spec.ts:229-249
Timestamp: 2026-01-10T08:54:09.466Z
Learning: In jsdom test environments, window.location.assign cannot be spied on due to TypeError: Cannot redefine property. Use Object.defineProperty to mock the entire window.location object, replacing it with a controlled mock, and restore the original in afterEach. Ensure to clean up the mock after each test to avoid side effects.
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts
📚 Learning: 2026-01-09T20:08:30.350Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 88
File: packages/riviere-cli/src/commands/extract/extract.spec.ts:33-38
Timestamp: 2026-01-09T20:08:30.350Z
Learning: In test files, keep type guard implementations like isExtractionOutput(value: unknown): value is ExtractionOutput focused on narrowing types for TypeScript. Do not perform comprehensive runtime shape validation in type guards; rely on explicit test assertions (e.g., expect(result).toMatchObject(...)) for shape checks. This keeps type guards simple and rely on assertion-based tests for thorough validation.
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts
📚 Learning: 2026-01-10T10:14:57.499Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-10T10:14:57.499Z
Learning: Avoid anti-patterns documented in `docs/conventions/anti-patterns.md`
Applied to files:
docs/conventions/anti-patterns.md
📚 Learning: 2026-01-08T19:36:17.306Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/codebase-structure.md:0-0
Timestamp: 2026-01-08T19:36:17.306Z
Learning: Applies to docs/conventions/apps/*/src/**/*.test.ts : Test fixtures used across multiple test files may be grouped in shared locations (e.g., test-fixtures.ts), but otherwise test files should be co-located with the code they test.
Applied to files:
docs/conventions/anti-patterns.md
📚 Learning: 2026-01-07T08:54:48.071Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/workflow/code-review.md:0-0
Timestamp: 2026-01-07T08:54:48.071Z
Learning: Applies to docs/workflow/**/*.{ts,tsx,js,jsx,!(**/*.test.ts,**/*.test.tsx,**/*.test.js,**/*.spec.ts,**/*.spec.tsx,**/*.spec.js)} : All production code must comply with anti-patterns guidelines defined in @/docs/conventions/anti-patterns.md. Violations are hard failures unless documented exceptions exist.
Applied to files:
docs/conventions/anti-patterns.md
📚 Learning: 2026-01-07T08:54:48.071Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/workflow/code-review.md:0-0
Timestamp: 2026-01-07T08:54:48.071Z
Learning: Applies to docs/workflow/**/*.{test.ts,test.tsx,test.js,test.jsx,spec.ts,spec.tsx,spec.js,spec.jsx} : All test files must comply with testing standards defined in @/docs/conventions/testing.md. Test files must not contain any code comments - comments are banned and a hard failure.
Applied to files:
docs/conventions/anti-patterns.md
📚 Learning: 2026-01-11T11:04:34.655Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/anti-patterns.md:0-0
Timestamp: 2026-01-11T11:04:34.655Z
Learning: When hitting max-lines limits, split files into focused modules (e.g., `foo.spec.ts` and `foo.edge-cases.spec.ts`), extract duplicated code into shared modules, or use parameterized tests with `it.each` or `describe.each` instead of removing tests or compressing code.
Applied to files:
docs/conventions/anti-patterns.md
📚 Learning: 2026-01-08T23:16:02.639Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/software-design.md:0-0
Timestamp: 2026-01-08T23:16:02.639Z
Learning: Applies to docs/conventions/**/*.{ts,tsx,js,jsx} : Fail-fast over silent fallbacks. Never use fallback chains (`value ?? backup ?? 'unknown'`). If data should exist, validate and throw a clear error.
Applied to files:
docs/conventions/anti-patterns.md
📚 Learning: 2026-01-08T19:36:17.306Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/codebase-structure.md:0-0
Timestamp: 2026-01-08T19:36:17.306Z
Learning: Applies to docs/conventions/packages/*/vitest.config.ts : Each package must include a vitest.config.ts file with 100% coverage thresholds for test configuration.
Applied to files:
docs/conventions/anti-patterns.md
📚 Learning: 2026-01-08T23:16:02.639Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/software-design.md:0-0
Timestamp: 2026-01-08T23:16:02.639Z
Learning: Applies to docs/conventions/**/*.{ts,tsx,js,jsx} : No code comments. Comments are a failure to express intent in code. If you need a comment to explain what code does, the code isn't clear enough—refactor it.
Applied to files:
docs/conventions/anti-patterns.md
🧬 Code graph analysis (2)
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts (1)
apps/eclair/src/errors.ts (1)
CSSModuleError(54-59)
apps/eclair/src/components/SchemaModal/SchemaModal.tsx (1)
apps/eclair/src/errors.ts (2)
CSSModuleError(54-59)SchemaError(74-79)
🪛 LanguageTool
docs/conventions/anti-patterns.md
[style] ~177-~177: To elevate your writing, try using a synonym here.
Context: ...fy it's truly unreachable** - Not just "hard to test" or "unlikely to happen" ### ❌...
(HARD_TO)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: main
- GitHub Check: browser-tests (webkit)
- GitHub Check: browser-tests (firefox)
- GitHub Check: Cloudflare Pages
🔇 Additional comments (6)
docs/conventions/anti-patterns.md (1)
134-220: Excellent documentation additions—clear, actionable, and well-aligned with team practices.Both new anti-pattern sections follow the established pattern and provide concrete guidance:
- "Sharing test fixtures" clearly distinguishes raw test data from reusable test utilities (line 165)
- "Lazy Coverage Ignore Comments" provides practical examples of invalid vs. justified ignore comments, a full table of test-instead scenarios, and valid-use cases
The guidance is consistent with the project's learnings on testing standards and code-quality expectations.
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts (1)
1-11: LGTM!The mock setup correctly simulates missing CSS classes by only providing
jsonContainer. This will trigger validation errors when the component tries to access other required classes likejsonBasicChild.apps/eclair/src/components/SchemaModal/SchemaModal.tsx (3)
24-30: LGTM! Good defensive programming.The assertion function correctly narrows the type and provides a clear error message. The error message appropriately indicates this is a programmer error ("Button should be disabled"), which aligns with the UI logic that disables the download button when
graphNameis undefined (line 170).This defensive check is valuable for catching logic errors during development and refactoring.
32-55: LGTM! Module-level validation aligns with fail-fast principles.The
jsonViewStylesinitialization validates all required CSS classes at module import time. This fail-fast approach ensures CSS module issues are caught immediately when the module loads, rather than later during rendering.This design aligns with the fail-fast error handling guidelines and makes CSS configuration errors visible early in the development cycle.
101-110: LGTM! Good refactoring to extract validation.Extracting the
graphNamevalidation into a dedicated assertion function improves code clarity and testability. The download logic remains unchanged and correct.apps/eclair/src/components/SchemaModal/SchemaModal.spec.tsx (1)
8-10: LGTM! Helper function reduces duplication.The new imports and
renderSchemaModalWithGraphhelper function simplify test setup for the generated date validation tests. The helper appropriately encapsulates common rendering logic.Also applies to: 18-18, 29-33
SonarCloud couldn't resolve coverage paths because they were relative to the package directory instead of the repo root. Adding projectRoot to the lcov reporter config fixes the path resolution. Co-Authored-By: Claude Opus 4.5 <[email protected]>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @apps/eclair/vitest.config.mts:
- Line 1: The file currently imports both a default "path" from 'node:path' and
a named "resolve" from 'path', causing redundancy; pick one style and
consolidate imports—either remove the named "resolve" import and call
path.resolve wherever resolve is used, or remove the default "path" import and
keep the named "resolve" import (replacing any path.resolve uses with resolve);
update the import line accordingly and adjust all usages of resolve/path in the
file to match the chosen import style.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
apps/eclair/vitest.config.mts
🧰 Additional context used
🧠 Learnings (11)
📓 Common learnings
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use `living-architecture/riviere-extract-ts` TypeScript extractor with ts-morph for AST parsing when implementing TypeScript extraction for architecture schema components
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.{json,ts} : Define extraction configuration using the JSON Schema from `living-architecture/riviere-extract-config` DSL
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Use glob pattern matching for module-based organization of extraction rules
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Applies to packages/riviere-extract-config/**/*.ts : Extraction config schema is the source of truth for valid structures. TypeScript types must mirror the schema definition to maintain consistency
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 129
File: packages/riviere-cli/src/commands/extract/config-loader.ts:31-39
Timestamp: 2026-01-11T14:38:35.637Z
Learning: In packages/riviere-cli/src/commands/extract/config-loader.ts, the isExtendedConfig type guard intentionally performs minimal validation (checks for non-null object and validates modules is an array if present) because comprehensive validation is handled downstream by the schema validator. The type guard's purpose is basic type narrowing to support both module-array and top-level-rules formats, not comprehensive validation. This follows the layered validation pattern where type guards are minimal and schema validation occurs at system boundaries.
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-conventions/CLAUDE.md:0-0
Timestamp: 2026-01-08T07:05:01.766Z
Learning: Import and use the default extraction config from `living-architecture/riviere-extract-conventions/default-config` in extraction tooling to detect all 6 component types
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use the Rivière Builder Node.js library to programmatically construct the schema graph when implementing custom extraction code
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Reject invalid extraction configs at load time, not during extraction phase
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Implement extraction logic as pure functions with no side effects
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement integration tests for end-to-end extraction from TypeScript code to JSON output
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Extraction config schemas must define all six required component types per module: api, useCase, domainOp, event, eventHandler, and ui. Unused component types must be explicitly marked with `notUsed: true` rather than omitted
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: All validation of extraction config must occur at config load time, not during extraction. Invalid configs should fail fast with clear error messages that include paths and descriptive information
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 88
File: packages/riviere-cli/src/commands/extract/extract.ts:109-114
Timestamp: 2026-01-09T20:08:44.180Z
Learning: Applies to packages/riviere-cli/src/commands/extract/**/*.{ts,tsx} : CLI extraction commands should only catch and format expected validation errors as structured JSON. System-level exceptions (disk I/O failures, OOM, AST parse errors) should fail loudly with stack traces for debugging rather than being wrapped in try-catch and converted to JSON errors. This follows the fail-fast principle: validate inputs explicitly, then let unexpected failures surface clearly.
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: All extraction rules should come from validated ExtractionConfig provided by riviere-extract-config
📚 Learning: 2026-01-06T08:11:15.403Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 53
File: packages/riviere-extract-config/vitest.config.mts:20-20
Timestamp: 2026-01-06T08:11:15.403Z
Learning: In packages/riviere-extract-config/vitest.config.mts, the explicit tuple type assertion for the reporter configuration (`as ['text', ['lcov', { projectRoot: string }]]`) is necessary because vitest's CoverageReporter type requires the exact tuple shape; neither inference nor 'as const' produces a compatible type.
Applied to files:
apps/eclair/vitest.config.mts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/vitest.config.mts : Enforce 100% code coverage using Vitest with v8 coverage and thresholds configured in vitest.config.mts
Applied to files:
apps/eclair/vitest.config.mts
📚 Learning: 2026-01-10T10:14:57.499Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-10T10:14:57.499Z
Learning: Applies to **/vitest.config.ts : When creating new projects with tests, add vitest.config.ts with 100% coverage as the default
Applied to files:
apps/eclair/vitest.config.mts
📚 Learning: 2026-01-08T12:57:19.167Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 67
File: packages/riviere-extract-ts/tsconfig.spec.json:5-22
Timestamp: 2026-01-08T12:57:19.167Z
Learning: In tsconfig.spec.json files, use expanded types array ["vitest/globals", "vitest/importMeta", "vite/client", "node", "vitest"] for complete test type coverage. Include patterns should cover .test and .spec files, config files (vitest.config.ts/mts, vite.config.ts/mts), multiple extensions (.ts, .tsx, .js, .jsx), and .d.ts files to ensure proper TypeScript coverage across the testing environment.
Applied to files:
apps/eclair/vitest.config.mts
📚 Learning: 2026-01-08T19:36:17.306Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/codebase-structure.md:0-0
Timestamp: 2026-01-08T19:36:17.306Z
Learning: Applies to docs/conventions/packages/*/vitest.config.ts : Each package must include a vitest.config.ts file with 100% coverage thresholds for test configuration.
Applied to files:
apps/eclair/vitest.config.mts
📚 Learning: 2026-01-08T19:36:17.306Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/codebase-structure.md:0-0
Timestamp: 2026-01-08T19:36:17.306Z
Learning: Applies to docs/conventions/apps/*/vitest.config.ts : Each app must include a vitest.config.ts file with 100% coverage thresholds for test configuration.
Applied to files:
apps/eclair/vitest.config.mts
📚 Learning: 2026-01-10T10:14:57.499Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-10T10:14:57.499Z
Learning: Do not modify root configuration files (eslint.config.mjs, tsconfig.base.json, nx.json, vite.config, vitest.config.mts); provide suggested changes and ask the user before modifying
Applied to files:
apps/eclair/vitest.config.mts
📚 Learning: 2026-01-07T08:54:48.071Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/workflow/code-review.md:0-0
Timestamp: 2026-01-07T08:54:48.071Z
Learning: Applies to docs/workflow/**/*.{ts,tsx,js,jsx} : Review usage of `/* v8 ignore next -- preserve */` coverage skip directives. This is only acceptable for unreachable code needed to satisfy the compiler. Most cases should be solved by extracting code or writing tests to mock behavior.
Applied to files:
apps/eclair/vitest.config.mts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement integration tests for end-to-end extraction from TypeScript code to JSON output
Applied to files:
apps/eclair/vitest.config.mts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Use ts-morph's in-memory file system (`useInMemoryFileSystem: true`) for fast isolated tests
Applied to files:
apps/eclair/vitest.config.mts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: browser-tests (firefox)
- GitHub Check: browser-tests (webkit)
- GitHub Check: main
- GitHub Check: browser-tests (chromium)
- GitHub Check: Cloudflare Pages
🔇 Additional comments (1)
apps/eclair/vitest.config.mts (1)
25-25: LGTM! Type annotation is correct.The explicit tuple type assertion for the reporter configuration is necessary for vitest's type system and correctly specifies the nested LCOV reporter with projectRoot option.
Based on learnings, this explicit tuple type assertion is required because vitest's CoverageReporter type requires the exact tuple shape.
Same fix as eclair - SonarCloud needs paths relative to repo root. Co-Authored-By: Claude Opus 4.5 <[email protected]>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @packages/riviere-cli/vitest.config.mts:
- Around line 1-5: The config uses __dirname to build repoRoot (symbol repoRoot)
in an ESM .mts file, which may be undefined under ESM; replace the __dirname
dependency by computing the module directory from import.meta.url (via file URL
-> path dirname) or otherwise ensure your bundler/vitest loader provides
__dirname, update repoRoot to use that value, and run the vitest config loader
locally to verify coverage paths are stable and imports still resolve.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
packages/riviere-cli/vitest.config.mts
🧰 Additional context used
🧠 Learnings (12)
📓 Common learnings
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use `living-architecture/riviere-extract-ts` TypeScript extractor with ts-morph for AST parsing when implementing TypeScript extraction for architecture schema components
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.{json,ts} : Define extraction configuration using the JSON Schema from `living-architecture/riviere-extract-config` DSL
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Use glob pattern matching for module-based organization of extraction rules
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 129
File: packages/riviere-cli/src/commands/extract/config-loader.ts:31-39
Timestamp: 2026-01-11T14:38:35.637Z
Learning: In packages/riviere-cli/src/commands/extract/config-loader.ts, the isExtendedConfig type guard intentionally performs minimal validation (checks for non-null object and validates modules is an array if present) because comprehensive validation is handled downstream by the schema validator. The type guard's purpose is basic type narrowing to support both module-array and top-level-rules formats, not comprehensive validation. This follows the layered validation pattern where type guards are minimal and schema validation occurs at system boundaries.
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Applies to packages/riviere-extract-config/**/*.ts : Extraction config schema is the source of truth for valid structures. TypeScript types must mirror the schema definition to maintain consistency
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-conventions/CLAUDE.md:0-0
Timestamp: 2026-01-08T07:05:01.766Z
Learning: Import and use the default extraction config from `living-architecture/riviere-extract-conventions/default-config` in extraction tooling to detect all 6 component types
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Reject invalid extraction configs at load time, not during extraction phase
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use the Rivière Builder Node.js library to programmatically construct the schema graph when implementing custom extraction code
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Implement extraction logic as pure functions with no side effects
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement integration tests for end-to-end extraction from TypeScript code to JSON output
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Extraction config schemas must define all six required component types per module: api, useCase, domainOp, event, eventHandler, and ui. Unused component types must be explicitly marked with `notUsed: true` rather than omitted
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 88
File: packages/riviere-cli/src/commands/extract/extract.ts:109-114
Timestamp: 2026-01-09T20:08:44.180Z
Learning: Applies to packages/riviere-cli/src/commands/extract/**/*.{ts,tsx} : CLI extraction commands should only catch and format expected validation errors as structured JSON. System-level exceptions (disk I/O failures, OOM, AST parse errors) should fail loudly with stack traces for debugging rather than being wrapped in try-catch and converted to JSON errors. This follows the fail-fast principle: validate inputs explicitly, then let unexpected failures surface clearly.
📚 Learning: 2026-01-06T08:11:15.403Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 53
File: packages/riviere-extract-config/vitest.config.mts:20-20
Timestamp: 2026-01-06T08:11:15.403Z
Learning: In packages/riviere-extract-config/vitest.config.mts, the explicit tuple type assertion for the reporter configuration (`as ['text', ['lcov', { projectRoot: string }]]`) is necessary because vitest's CoverageReporter type requires the exact tuple shape; neither inference nor 'as const' produces a compatible type.
Applied to files:
packages/riviere-cli/vitest.config.mts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/vitest.config.mts : Enforce 100% code coverage using Vitest with v8 coverage and thresholds configured in vitest.config.mts
Applied to files:
packages/riviere-cli/vitest.config.mts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Use ts-morph's in-memory file system (`useInMemoryFileSystem: true`) for fast isolated tests
Applied to files:
packages/riviere-cli/vitest.config.mts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement integration tests for end-to-end extraction from TypeScript code to JSON output
Applied to files:
packages/riviere-cli/vitest.config.mts
📚 Learning: 2026-01-08T19:36:17.306Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/codebase-structure.md:0-0
Timestamp: 2026-01-08T19:36:17.306Z
Learning: Applies to docs/conventions/packages/*/vitest.config.ts : Each package must include a vitest.config.ts file with 100% coverage thresholds for test configuration.
Applied to files:
packages/riviere-cli/vitest.config.mts
📚 Learning: 2026-01-08T12:57:19.167Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 67
File: packages/riviere-extract-ts/tsconfig.spec.json:5-22
Timestamp: 2026-01-08T12:57:19.167Z
Learning: In tsconfig.spec.json files, use expanded types array ["vitest/globals", "vitest/importMeta", "vite/client", "node", "vitest"] for complete test type coverage. Include patterns should cover .test and .spec files, config files (vitest.config.ts/mts, vite.config.ts/mts), multiple extensions (.ts, .tsx, .js, .jsx), and .d.ts files to ensure proper TypeScript coverage across the testing environment.
Applied to files:
packages/riviere-cli/vitest.config.mts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Use ts-morph for TypeScript AST parsing instead of other parsers
Applied to files:
packages/riviere-cli/vitest.config.mts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Use glob pattern matching for module-based organization of extraction rules
Applied to files:
packages/riviere-cli/vitest.config.mts
📚 Learning: 2026-01-10T10:14:57.499Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-10T10:14:57.499Z
Learning: Applies to **/vitest.config.ts : When creating new projects with tests, add vitest.config.ts with 100% coverage as the default
Applied to files:
packages/riviere-cli/vitest.config.mts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement unit tests for each predicate type in isolation with positive and negative cases
Applied to files:
packages/riviere-cli/vitest.config.mts
📚 Learning: 2026-01-08T19:36:17.306Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/codebase-structure.md:0-0
Timestamp: 2026-01-08T19:36:17.306Z
Learning: Applies to docs/conventions/apps/*/vitest.config.ts : Each app must include a vitest.config.ts file with 100% coverage thresholds for test configuration.
Applied to files:
packages/riviere-cli/vitest.config.mts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: browser-tests (webkit)
- GitHub Check: browser-tests (firefox)
- GitHub Check: main
- GitHub Check: Cloudflare Pages
🔇 Additional comments (1)
packages/riviere-cli/vitest.config.mts (1)
20-20: No changes needed. The type assertion is appropriate and necessary for vitest's CoverageReporter type constraints. TheprojectRootoption is supported by vitest's v8 coverage provider's lcov reporter in version 4.0.8. This configuration matches the vitest documentation and is consistent with other packages in the codebase.
Test both error type and message in a single test - they represent one error condition. Co-Authored-By: Claude Opus 4.5 <[email protected]>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @docs/conventions/testing.md:
- Around line 317-325: The example calls loadConfig('nonexistent.json') twice;
change it to call the function once, capture the thrown error (e.g., via
try/catch into a variable), then assert both the error type (instanceof
ConfigurationError) and message on that captured error so the test invokes
loadConfig only once and checks both conditions.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
docs/conventions/testing.md
🧰 Additional context used
🧠 Learnings (18)
📓 Common learnings
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use `living-architecture/riviere-extract-ts` TypeScript extractor with ts-morph for AST parsing when implementing TypeScript extraction for architecture schema components
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.{json,ts} : Define extraction configuration using the JSON Schema from `living-architecture/riviere-extract-config` DSL
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Use glob pattern matching for module-based organization of extraction rules
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 129
File: packages/riviere-cli/src/commands/extract/config-loader.ts:31-39
Timestamp: 2026-01-11T14:38:35.637Z
Learning: In packages/riviere-cli/src/commands/extract/config-loader.ts, the isExtendedConfig type guard intentionally performs minimal validation (checks for non-null object and validates modules is an array if present) because comprehensive validation is handled downstream by the schema validator. The type guard's purpose is basic type narrowing to support both module-array and top-level-rules formats, not comprehensive validation. This follows the layered validation pattern where type guards are minimal and schema validation occurs at system boundaries.
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Applies to packages/riviere-extract-config/**/*.ts : Extraction config schema is the source of truth for valid structures. TypeScript types must mirror the schema definition to maintain consistency
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-conventions/CLAUDE.md:0-0
Timestamp: 2026-01-08T07:05:01.766Z
Learning: Import and use the default extraction config from `living-architecture/riviere-extract-conventions/default-config` in extraction tooling to detect all 6 component types
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Reject invalid extraction configs at load time, not during extraction phase
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use the Rivière Builder Node.js library to programmatically construct the schema graph when implementing custom extraction code
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Extraction config schemas must define all six required component types per module: api, useCase, domainOp, event, eventHandler, and ui. Unused component types must be explicitly marked with `notUsed: true` rather than omitted
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 88
File: packages/riviere-cli/src/commands/extract/extract.ts:109-114
Timestamp: 2026-01-09T20:08:44.180Z
Learning: Applies to packages/riviere-cli/src/commands/extract/**/*.{ts,tsx} : CLI extraction commands should only catch and format expected validation errors as structured JSON. System-level exceptions (disk I/O failures, OOM, AST parse errors) should fail loudly with stack traces for debugging rather than being wrapped in try-catch and converted to JSON errors. This follows the fail-fast principle: validate inputs explicitly, then let unexpected failures surface clearly.
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test domain-specific edge cases: email (valid formats, plus signs, subdomains), URLs (protocols, ports, special characters, relative paths), phone numbers (international formats, extensions), addresses (Unicode, multi-line, missing components), currency (rounding, different currencies, zero amounts), percentages (0%, 100%, over 100%).
Applied to files:
docs/conventions/testing.md
📚 Learning: 2026-01-11T11:17:09.319Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.319Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Assertions must match test titles. If the test claims to verify 'different IDs', assert on the actual ID values—not just count or existence.
Applied to files:
docs/conventions/testing.md
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test violated domain constraints: uniqueness violations (duplicate IDs, emails), missing required relationships (orphaned records), ordering violations (events out of sequence), range breaches (age -1, quantity 1000000), state inconsistencies (shipped but not paid), format mismatches (expected JSON, got XML), and temporal ordering (end before start).
Applied to files:
docs/conventions/testing.md
📚 Learning: 2026-01-11T11:04:34.655Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/anti-patterns.md:0-0
Timestamp: 2026-01-11T11:04:34.655Z
Learning: Applies to docs/conventions/**/*.{ts,tsx,js,jsx} : Never parse error message strings to determine error types or extract information using `.message.includes()`, `.message.startsWith()`, or regex patterns on `error.message`. Use typed custom error classes instead.
Applied to files:
docs/conventions/testing.md
📚 Learning: 2026-01-08T23:16:02.639Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/software-design.md:0-0
Timestamp: 2026-01-08T23:16:02.639Z
Learning: Applies to docs/conventions/**/*.{ts,tsx,js,jsx} : Fail-Fast Error Handling: Validate and throw clear errors instead of using fallback chains. Error format: `Expected [X]. Got [Y]. Context: [debugging info]`
Applied to files:
docs/conventions/testing.md
📚 Learning: 2026-01-11T11:17:09.319Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.319Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test edge cases for collections (arrays, objects, maps): empty collections, single element, duplicates, nested structures, circular references, very large collections (performance), sparse arrays, and mixed types.
Applied to files:
docs/conventions/testing.md
📚 Learning: 2026-01-11T11:04:34.655Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/anti-patterns.md:0-0
Timestamp: 2026-01-11T11:04:34.655Z
Learning: Applies to docs/conventions/**/*.{ts,tsx,js,jsx} : When parsing strings in exception messages is 100% unavoidable (e.g., due to third-party library limitations), document the exception with justification, reference tracking issue, and note that upstream fix was requested.
Applied to files:
docs/conventions/testing.md
📚 Learning: 2026-01-11T11:17:09.319Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.319Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test edge cases for number inputs: zero, negative numbers, very large/small numbers (near MAX/MIN_SAFE_INTEGER), decimal precision (0.1 + 0.2), NaN, Infinity/-Infinity, and boundary values (off-by-one at limits).
Applied to files:
docs/conventions/testing.md
📚 Learning: 2026-01-11T11:17:09.319Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.319Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : One concept per test. Each test verifies one behavior. If you need 'and' in your test name, split it into multiple tests.
Applied to files:
docs/conventions/testing.md
📚 Learning: 2026-01-10T10:14:57.499Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-10T10:14:57.499Z
Learning: Follow `docs/conventions/testing.md` for all testing practices
Applied to files:
docs/conventions/testing.md
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : When testing cleanup functions and resource management (timers, event listeners, subscriptions), verify the cleanup mechanism was called using spies. Always restore spies in the same test or in `afterEach` to prevent leaks between tests.
Applied to files:
docs/conventions/testing.md
📚 Learning: 2026-01-08T06:46:05.503Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 66
File: packages/riviere-extract-conventions/src/eslint/require-component-decorator.spec.ts:19-21
Timestamp: 2026-01-08T06:46:05.503Z
Learning: In test files using typescript-eslint/rule-tester's RuleTester.run(), include an explicit it() block with an expect() assertion (e.g., expect(rule).toBeDefined()) to satisfy sonarjs/no-empty-test-file and sonarjs/assertions-in-tests lint rules, which don't recognize RuleTester's internal test blocks.
Applied to files:
docs/conventions/testing.md
📚 Learning: 2026-01-11T11:17:09.319Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.319Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Assert specific values, not types. Use `expect(result).toEqual(['First.', ' Second.'])` not `expect(result).toBeDefined()`. Specific assertions catch specific bugs.
Applied to files:
docs/conventions/testing.md
📚 Learning: 2026-01-11T11:17:09.319Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.319Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Test names describe outcomes, not actions. Use the pattern: '[outcome] when [condition]' (e.g., 'returns empty array when input is null', not 'test null input'). The test name IS the specification.
Applied to files:
docs/conventions/testing.md
📚 Learning: 2026-01-11T11:17:09.319Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.319Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Use Arrange-Act-Assert structure in tests: (1) Set up test data, (2) Execute the behavior, (3) Verify the outcome.
Applied to files:
docs/conventions/testing.md
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Avoid implementation coupling in tests. Test behavior, not implementation details. Instead of asserting on mock call arguments with exact SQL, assert on the observable result (e.g., expect(result.user.name).toBe('Alice')).
Applied to files:
docs/conventions/testing.md
📚 Learning: 2026-01-11T11:04:34.655Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/anti-patterns.md:0-0
Timestamp: 2026-01-11T11:04:34.655Z
Learning: When hitting max-lines limits, split files into focused modules (e.g., `foo.spec.ts` and `foo.edge-cases.spec.ts`), extract duplicated code into shared modules, or use parameterized tests with `it.each` or `describe.each` instead of removing tests or compressing code.
Applied to files:
docs/conventions/testing.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: browser-tests (firefox)
- GitHub Check: main
- GitHub Check: browser-tests (webkit)
- GitHub Check: browser-tests (chromium)
- GitHub Check: Cloudflare Pages
WebKit caches modules differently, causing separate import() calls in successive tests to have different behavior. Combined the type and message assertions into a single test on the same promise. Co-Authored-By: Claude Opus 4.5 <[email protected]>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts:
- Around line 13-19: Refactor the failing-path test so you only await
import('./SchemaModal') once by wrapping it in try/catch, capture the caught
error, then assert it is an instance of CSSModuleError and that error.message
contains 'jsonBasicChild'; additionally add a separate happy-path test named
like "imports successfully when required CSS classes are present" that ensures
import('./SchemaModal') resolves when the CSS module includes the required class
(mock or provide a fixture including 'jsonBasicChild') and assert the module
loads without throwing.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Follow eslint configuration rules defined in
eslint.config.mjsfor all linting
Files:
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts
**/*.{ts,tsx,js,jsx,css,scss,html}
📄 CodeRabbit inference engine (CLAUDE.md)
All UI and UX design must conform to global brand guidelines in
/docs/brand/(logo, colors, typography, icons)
Files:
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,js,jsx}: Do not log sensitive data (passwords, tokens, PII) in any code
Validate and sanitize all external input
Files:
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use cross-project imports with package names (e.g.,
import { X } from '@living-architecture/[pkg-name]') rather than relative paths
Files:
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts
🧠 Learnings (15)
📓 Common learnings
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use `living-architecture/riviere-extract-ts` TypeScript extractor with ts-morph for AST parsing when implementing TypeScript extraction for architecture schema components
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.{json,ts} : Define extraction configuration using the JSON Schema from `living-architecture/riviere-extract-config` DSL
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 129
File: packages/riviere-cli/src/commands/extract/config-loader.ts:31-39
Timestamp: 2026-01-11T14:38:35.637Z
Learning: In packages/riviere-cli/src/commands/extract/config-loader.ts, the isExtendedConfig type guard intentionally performs minimal validation (checks for non-null object and validates modules is an array if present) because comprehensive validation is handled downstream by the schema validator. The type guard's purpose is basic type narrowing to support both module-array and top-level-rules formats, not comprehensive validation. This follows the layered validation pattern where type guards are minimal and schema validation occurs at system boundaries.
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Use glob pattern matching for module-based organization of extraction rules
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Applies to packages/riviere-extract-config/**/*.ts : Extraction config schema is the source of truth for valid structures. TypeScript types must mirror the schema definition to maintain consistency
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-conventions/CLAUDE.md:0-0
Timestamp: 2026-01-08T07:05:01.766Z
Learning: Import and use the default extraction config from `living-architecture/riviere-extract-conventions/default-config` in extraction tooling to detect all 6 component types
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Reject invalid extraction configs at load time, not during extraction phase
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use the Rivière Builder Node.js library to programmatically construct the schema graph when implementing custom extraction code
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement integration tests for end-to-end extraction from TypeScript code to JSON output
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Extraction config schemas must define all six required component types per module: api, useCase, domainOp, event, eventHandler, and ui. Unused component types must be explicitly marked with `notUsed: true` rather than omitted
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: All validation of extraction config must occur at config load time, not during extraction. Invalid configs should fail fast with clear error messages that include paths and descriptive information
📚 Learning: 2026-01-08T12:57:19.167Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 67
File: packages/riviere-extract-ts/tsconfig.spec.json:5-22
Timestamp: 2026-01-08T12:57:19.167Z
Learning: In tsconfig.spec.json files, use expanded types array ["vitest/globals", "vitest/importMeta", "vite/client", "node", "vitest"] for complete test type coverage. Include patterns should cover .test and .spec files, config files (vitest.config.ts/mts, vite.config.ts/mts), multiple extensions (.ts, .tsx, .js, .jsx), and .d.ts files to ensure proper TypeScript coverage across the testing environment.
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*-fixtures.ts : Create `<module>-fixtures.ts` fixture files alongside `<module>.spec.ts` to reduce duplication when multiple tests share similar setup data or differ only in specific values being tested.
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts
📚 Learning: 2026-01-11T11:17:09.319Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.319Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Assertions must match test titles. If the test claims to verify 'different IDs', assert on the actual ID values—not just count or existence.
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement unit tests for each predicate type in isolation with positive and negative cases
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test violated domain constraints: uniqueness violations (duplicate IDs, emails), missing required relationships (orphaned records), ordering violations (events out of sequence), range breaches (age -1, quantity 1000000), state inconsistencies (shipped but not paid), format mismatches (expected JSON, got XML), and temporal ordering (end before start).
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts
📚 Learning: 2026-01-11T11:17:09.319Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.319Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test edge cases for collections (arrays, objects, maps): empty collections, single element, duplicates, nested structures, circular references, very large collections (performance), sparse arrays, and mixed types.
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts
📚 Learning: 2026-01-08T06:46:00.609Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 66
File: packages/riviere-extract-conventions/src/eslint/require-component-decorator.spec.ts:19-21
Timestamp: 2026-01-08T06:46:00.609Z
Learning: In test files using typescript-eslint/rule-tester's RuleTester.run(), ensure there is an explicit it() block with at least one expect() assertion (e.g., expect(rule).toBeDefined()) to satisfy sonarjs/no-empty-test-file and sonarjs/assertions-in-tests lint rules, which don’t recognize RuleTester's internal test blocks. Apply this pattern to all spec.ts test files to maintain consistency and pass lint checks.
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test null and undefined inputs: null input, undefined input, missing optional properties, and explicit undefined vs missing key.
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts
📚 Learning: 2026-01-11T11:17:09.320Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.320Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test domain-specific edge cases: email (valid formats, plus signs, subdomains), URLs (protocols, ports, special characters, relative paths), phone numbers (international formats, extensions), addresses (Unicode, multi-line, missing components), currency (rounding, different currencies, zero amounts), percentages (0%, 100%, over 100%).
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts
📚 Learning: 2026-01-11T11:17:09.319Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.319Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : One concept per test. Each test verifies one behavior. If you need 'and' in your test name, split it into multiple tests.
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts
📚 Learning: 2026-01-11T11:17:09.319Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T11:17:09.319Z
Learning: Applies to docs/conventions/**/*.{spec,test}.{js,ts,jsx,tsx} : Systematically test edge cases for string inputs: empty string, whitespace-only strings, very long strings (10K+ characters), Unicode (emojis, RTL text, combining characters), special characters (quotes, backslashes, null bytes), SQL/HTML/script injection patterns, and leading/trailing whitespace.
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts
📚 Learning: 2026-01-11T11:04:34.655Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/anti-patterns.md:0-0
Timestamp: 2026-01-11T11:04:34.655Z
Learning: When hitting max-lines limits, split files into focused modules (e.g., `foo.spec.ts` and `foo.edge-cases.spec.ts`), extract duplicated code into shared modules, or use parameterized tests with `it.each` or `describe.each` instead of removing tests or compressing code.
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts
📚 Learning: 2026-01-10T08:54:09.466Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 96
File: apps/docs/.vitepress/theme/eclairLinkHandler.spec.ts:229-249
Timestamp: 2026-01-10T08:54:09.466Z
Learning: In jsdom test environments, window.location.assign cannot be spied on due to TypeError: Cannot redefine property. Use Object.defineProperty to mock the entire window.location object, replacing it with a controlled mock, and restore the original in afterEach. Ensure to clean up the mock after each test to avoid side effects.
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts
📚 Learning: 2026-01-09T20:08:30.350Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 88
File: packages/riviere-cli/src/commands/extract/extract.spec.ts:33-38
Timestamp: 2026-01-09T20:08:30.350Z
Learning: In test files, keep type guard implementations like isExtractionOutput(value: unknown): value is ExtractionOutput focused on narrowing types for TypeScript. Do not perform comprehensive runtime shape validation in type guards; rely on explicit test assertions (e.g., expect(result).toMatchObject(...)) for shape checks. This keeps type guards simple and rely on assertion-based tests for thorough validation.
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts
🧬 Code graph analysis (1)
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts (1)
apps/eclair/src/errors.ts (1)
CSSModuleError(54-59)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: browser-tests (firefox)
- GitHub Check: browser-tests (webkit)
- GitHub Check: main
- GitHub Check: Cloudflare Pages
🔇 Additional comments (2)
apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts (2)
1-4: LGTM!Imports are standard and correctly structured for a Vitest test file.
6-11: LGTM!Mock setup correctly simulates missing CSS classes to test error handling. The comment clearly documents the intent.
The function is only used internally within SchemaModal.tsx. Co-Authored-By: Claude Opus 4.5 <[email protected]>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @apps/eclair/src/components/SchemaModal/SchemaModal.tsx:
- Around line 24-30: The error message in validateDownloadGraphName ties
validation logic to UI ("Button should be disabled..."); update the thrown
SchemaError in validateDownloadGraphName to be UI-agnostic and purely about the
missing input (e.g., "graphName is required to download" or similar), leaving
any UI hints to the UI layer; ensure you only change the message string in
validateDownloadGraphName while keeping the TypeScript assertion signature and
SchemaError usage intact.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
apps/eclair/src/components/SchemaModal/SchemaModal.tsx
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Follow eslint configuration rules defined in
eslint.config.mjsfor all linting
Files:
apps/eclair/src/components/SchemaModal/SchemaModal.tsx
**/*.{ts,tsx,js,jsx,css,scss,html}
📄 CodeRabbit inference engine (CLAUDE.md)
All UI and UX design must conform to global brand guidelines in
/docs/brand/(logo, colors, typography, icons)
Files:
apps/eclair/src/components/SchemaModal/SchemaModal.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,js,jsx}: Do not log sensitive data (passwords, tokens, PII) in any code
Validate and sanitize all external input
Files:
apps/eclair/src/components/SchemaModal/SchemaModal.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use cross-project imports with package names (e.g.,
import { X } from '@living-architecture/[pkg-name]') rather than relative paths
Files:
apps/eclair/src/components/SchemaModal/SchemaModal.tsx
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use `living-architecture/riviere-extract-ts` TypeScript extractor with ts-morph for AST parsing when implementing TypeScript extraction for architecture schema components
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.{json,ts} : Define extraction configuration using the JSON Schema from `living-architecture/riviere-extract-config` DSL
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 129
File: packages/riviere-cli/src/commands/extract/config-loader.ts:31-39
Timestamp: 2026-01-11T14:38:35.637Z
Learning: In packages/riviere-cli/src/commands/extract/config-loader.ts, the isExtendedConfig type guard intentionally performs minimal validation (checks for non-null object and validates modules is an array if present) because comprehensive validation is handled downstream by the schema validator. The type guard's purpose is basic type narrowing to support both module-array and top-level-rules formats, not comprehensive validation. This follows the layered validation pattern where type guards are minimal and schema validation occurs at system boundaries.
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Use glob pattern matching for module-based organization of extraction rules
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Applies to packages/riviere-extract-config/**/*.ts : Extraction config schema is the source of truth for valid structures. TypeScript types must mirror the schema definition to maintain consistency
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-conventions/CLAUDE.md:0-0
Timestamp: 2026-01-08T07:05:01.766Z
Learning: Import and use the default extraction config from `living-architecture/riviere-extract-conventions/default-config` in extraction tooling to detect all 6 component types
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Reject invalid extraction configs at load time, not during extraction phase
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use the Rivière Builder Node.js library to programmatically construct the schema graph when implementing custom extraction code
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement integration tests for end-to-end extraction from TypeScript code to JSON output
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Implement extraction logic as pure functions with no side effects
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Extraction config schemas must define all six required component types per module: api, useCase, domainOp, event, eventHandler, and ui. Unused component types must be explicitly marked with `notUsed: true` rather than omitted
📚 Learning: 2026-01-11T18:47:09.232Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 129
File: apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts:13-19
Timestamp: 2026-01-11T18:47:09.232Z
Learning: Encourage using const for declarations by default in TypeScript/JavaScript files and only use let when a variable must be reassigned. Do not rely on var. This improves immutability and clarity. If a variable needs mutation (e.g., counters in loops, reassigned values), use let, but prefer const whenever possible and refactor reassigned logic to avoid mutations where feasible.
Applied to files:
apps/eclair/src/components/SchemaModal/SchemaModal.tsx
🧬 Code graph analysis (1)
apps/eclair/src/components/SchemaModal/SchemaModal.tsx (1)
apps/eclair/src/errors.ts (2)
CSSModuleError(54-59)SchemaError(74-79)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: browser-tests (webkit)
- GitHub Check: main
- GitHub Check: browser-tests (firefox)
- GitHub Check: Cloudflare Pages
🔇 Additional comments (3)
apps/eclair/src/components/SchemaModal/SchemaModal.tsx (3)
12-22: Improved error typing with domain-specific error classes.The introduction of
CSSModuleErrorprovides better error context than a genericErrorand aligns with the PR's goal of centralizing domain-specific error handling.
101-110: Good refactoring for testability.Extracting the validation into a named function improves testability and makes the download logic clearer. The TypeScript assertion ensures
graphNameis astringat line 107.
116-128: Consistent error handling with SchemaError.Replacing the generic
ErrorwithSchemaErrormaintains consistency with the domain-specific error handling pattern introduced across the codebase. The validation logic correctly handles bothundefinedinput and invalid ISO date formats.
| export function validateDownloadGraphName(graphName: string | undefined): asserts graphName is string { | ||
| if (graphName === undefined) { | ||
| throw new SchemaError( | ||
| 'Cannot download: graphName is required. Button should be disabled when graphName is undefined.', | ||
| ) | ||
| } | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Consider making the error message UI-agnostic.
The validation function correctly uses a TypeScript assertion signature and provides good defensive programming. However, the error message mentions "Button should be disabled when graphName is undefined," which couples the validation logic to the current UI implementation.
♻️ Consider this alternative
export function validateDownloadGraphName(graphName: string | undefined): asserts graphName is string {
if (graphName === undefined) {
throw new SchemaError(
- 'Cannot download: graphName is required. Button should be disabled when graphName is undefined.',
+ 'Cannot download: graphName is required.',
)
}
}This makes the error message independent of UI implementation details while still conveying the validation requirement.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export function validateDownloadGraphName(graphName: string | undefined): asserts graphName is string { | |
| if (graphName === undefined) { | |
| throw new SchemaError( | |
| 'Cannot download: graphName is required. Button should be disabled when graphName is undefined.', | |
| ) | |
| } | |
| } | |
| export function validateDownloadGraphName(graphName: string | undefined): asserts graphName is string { | |
| if (graphName === undefined) { | |
| throw new SchemaError( | |
| 'Cannot download: graphName is required.', | |
| ) | |
| } | |
| } |
🤖 Prompt for AI Agents
In @apps/eclair/src/components/SchemaModal/SchemaModal.tsx around lines 24 - 30,
The error message in validateDownloadGraphName ties validation logic to UI
("Button should be disabled..."); update the thrown SchemaError in
validateDownloadGraphName to be UI-agnostic and purely about the missing input
(e.g., "graphName is required to download" or similar), leaving any UI hints to
the UI layer; ensure you only change the message string in
validateDownloadGraphName while keeping the TypeScript assertion signature and
SchemaError usage intact.
|



User description
Closes #128
Summary
extendsproperty to extraction config schemaresolveConfigfunction in riviere-extract-tscreateConfigLoaderin riviere-cli for concrete resolutionTest plan
Closes #128
🤖 Generated with Claude Code
PR Type
Enhancement
Description
Add
extendssupport to extraction config schema for rule inheritanceImplement
resolveConfigfunction to merge inherited and local rulesCreate
createConfigLoaderfor npm package and file path resolutionUpdate extractor to use resolved configs with complete rule definitions
Diagram Walkthrough
File Walkthrough
8 files
Split Module into ModuleConfig and resolved Module typesAdd extends property with conditional rule validationExport createResolvedConfig fixture functionImplement config resolution with extends inheritanceExport resolveConfig and ConfigLoader typeUpdate to use ResolvedExtractionConfig typeImplement config loader for npm and file resolutionIntegrate config resolution into extract command6 files
Add comprehensive tests for extends validationAdd createResolvedConfig fixture helper functionAdd test for createResolvedConfig validationAdd tests for config resolution and rule mergingUpdate tests to use ResolvedExtractionConfigAdd comprehensive tests for config loaderSummary by CodeRabbit
New Features
Documentation
Tests
Bug Fixes / UX
✏️ Tip: You can customize this high-level summary in your review settings.