Skip to content

feat(extraction-config): add support for $ref file references - #156

Merged
NTCoding merged 4 commits into
mainfrom
issue-141-feat-support-ref-file-referenc
Jan 14, 2026
Merged

NTCoding merged 4 commits into
mainfrom
issue-141-feat-support-ref-file-referenc

Conversation

@NTCoding

@NTCoding NTCoding commented Jan 13, 2026 •

Copy link
Copy Markdown
Owner

User description

Closes #141

Adds support for $ref file references in extraction config, allowing users to split large configs into one file per domain.

Changes

  • New expandModuleRefs function to resolve $ref references
  • ModuleRefNotFoundError for clear error messages
  • Updated JSON schema to allow moduleRef in modules array
  • Added ModuleRef TypeScript type
  • Integration with extract command
  • Full test coverage

Example Usage

# extract.yaml
modules:
  - $ref: ./domains/orders.extraction.json
  - $ref: ./domains/inventory.extraction.json

Closes #141


PR Type

Enhancement


Description

  • Add support for $ref file references in extraction configs

  • Enable splitting large configs across multiple domain files

  • Implement expandModuleRefs function for reference resolution

  • Add ModuleRefNotFoundError for clear error messaging

  • Update JSON schema to support moduleRef in modules array

  • Integrate reference expansion into extract command workflow


Diagram Walkthrough

flowchart LR
  A["Extract Config<br/>with $ref"] -->|expandModuleRefs| B["Expanded Config<br/>with inline modules"]
  B -->|validateExtractionConfig| C["Validation"]
  C -->|resolveConfig| D["Resolved Config"]
  D -->|extractComponents| E["Extracted Components"]
Loading

File Walkthrough

Relevant files
Enhancement
3 files
expand-module-refs.ts
New function to expand $ref references                                     
+59/-0   
extract.ts
Integrate expandModuleRefs into extract workflow                 
+7/-4     
types.ts
Add ModuleRef interface type definition                                   
+6/-0     
Tests
4 files
expand-module-refs.spec.ts
Comprehensive tests for reference expansion                           
+141/-0 
extract.spec.ts
Add integration test for $ref expansion                                   
+62/-0   
errors.spec.ts
Add tests for ModuleRefNotFoundError                                         
+25/-0   
validation.spec.ts
Add validation tests for $ref modules                                       
+10/-0   
Error handling
1 files
errors.ts
Add ModuleRefNotFoundError exception class                             
+12/-0   
Configuration changes
2 files
extraction-config.schema.json
Update schema to allow moduleRef in modules                           
+17/-1   
block-dangerous-commands.sh
Block direct gh pr create command                                               
+12/-0   
Documentation
1 files
schema.md
Document moduleRef schema in generated docs                           
+13/-1   

Summary by CodeRabbit

  • New Features

    • Extraction configs can reference external module files; referenced modules are resolved automatically during extraction.
  • Bug Fixes / Errors

    • Clear, specific error reported when a referenced module file is missing or invalid.
  • Tests

    • Added tests covering $ref expansion, successful loads, and error paths for missing/invalid referenced modules.
  • Chores

    • CLI hook updated to enforce the preferred PR workflow and contributor docs updated with a PR submission script.

✏️ Tip: You can customize this high-level summary in your review settings.

NTCoding and others added 2 commits January 13, 2026 23:37
Enable users to split large extraction configs into multiple files by
supporting $ref references in the modules array. This allows organizing
configs by domain with one file per domain.

Key changes:
- New expandModuleRefs function to resolve $ref references
- ModuleRefNotFoundError for clear error messages when refs not found
- Updated JSON schema to allow moduleRef objects in modules array
- Added ModuleRef TypeScript type for type safety
- Integration with extract command for automatic expansion
- Full test coverage for reference resolution and error cases

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@coderabbitai

coderabbitai Bot commented Jan 13, 2026 •

Copy link
Copy Markdown

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Adds support for $ref file references in extraction configs: schema/types updates, a new expandModuleRefs utility and ModuleRefNotFoundError, integration of expansion into the extract command with tests, and a git-hook change blocking gh pr create.

Changes

Cohort / File(s) Summary
Hook Enforcement
.claude/hooks/block-dangerous-commands.sh
Adds a PreToolUse denial block preventing gh pr create, directing users to use the /complete-task workflow.
Errors
packages/riviere-cli/src/errors.ts, packages/riviere-cli/src/errors.spec.ts
New exported ModuleRefNotFoundError(ref, filePath) with ref and filePath properties and tests verifying message, name, and properties.
Module Ref Expansion
packages/riviere-cli/src/commands/extract/expand-module-refs.ts, packages/riviere-cli/src/commands/extract/expand-module-refs.spec.ts
New expandModuleRefs(config, configDir) that resolves $ref entries by reading/parsing referenced JSON/YAML files, replaces refs with parsed modules, and throws ModuleRefNotFoundError if missing; unit tests mock FS read/existence and error paths.
Extract Command Integration
packages/riviere-cli/src/commands/extract/extract.ts, packages/riviere-cli/src/commands/extract/extract.spec.ts
Integrates expansion step before validation, computes configDir earlier, uses expanded data for validation/resolution, and handles ModuleRefNotFoundError with formatted errors; tests for success and missing/invalid ref cases.
Schema & Types
packages/riviere-extract-config/extraction-config.schema.json, packages/riviere-extract-config/src/types.ts, packages/riviere-extract-config/src/validation.spec.ts
Adds $defs.moduleRef and updates modules.items to oneOf (module

Sequence Diagram(s)

sequenceDiagram
    participant CLI as Extract CLI
    participant Parser as Config Parser
    participant Expander as ModuleRef Expander
    participant FS as File System
    participant Validator as Schema Validator
    participant Processor as Config Processor

    CLI->>Parser: Load & parse config file
    Parser-->>CLI: Parse result (includes modules)
    CLI->>Expander: expandModuleRefs(parseResult.data, configDir)
    loop each module entry
        alt module has `$ref`
            Expander->>FS: Resolve path & check exists
            FS-->>Expander: exists / not found
            alt exists
                Expander->>FS: Read file
                FS-->>Expander: file content
                Expander->>Expander: Parse YAML/JSON -> ModuleConfig
                Expander-->>CLI: replace `$ref` with ModuleConfig
            else not found
                Expander-->>CLI: throw ModuleRefNotFoundError
            end
        else inline module
            Expander-->>CLI: leave as-is
        end
    end
    Expander-->>CLI: expanded config
    CLI->>Validator: Validate expanded config
    Validator-->>CLI: validation result
    CLI->>Processor: Process validated config
    Processor-->>CLI: extraction output
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰
I nibble at refs and hop through files,
Paths unfurl like tidy trails,
Modules found in scattered piles,
I stitch them back with tiny tails—🥕

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(extraction-config): add support for $ref file references' is fully related to the main change—the PR introduces support for $ref file references in extraction configs, which is precisely what the title conveys.
Linked Issues check ✅ Passed All coding requirements from issue #141 are met: expandModuleRefs resolves $ref references [#141], error handling via ModuleRefNotFoundError for missing files [#141], schema updated to support moduleRef entries [#141], ModuleRef type added [#141], both JSON and YAML support via existing parsing [#141], relative path resolution implemented [#141], and comprehensive test coverage for all scenarios [#141].
Out of Scope Changes check ✅ Passed All changes are in-scope; the PR adds $ref reference support and related infrastructure. The only tangential change is .claude/hooks/block-dangerous-commands.sh, which blocks gh pr create to enforce the /complete-task workflow for proper issue linking—a supporting change that aligns with the feature's purpose of managing complex configs via proper workflows.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@qodo-code-review

qodo-code-review Bot commented Jan 13, 2026 •

Copy link
Copy Markdown
Contributor

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
⚪
Arbitrary file read

Description: $ref values are resolved and read from disk without restricting them to the config
directory (e.g., an absolute $ref like /etc/passwd or a ../ traversal) which can lead to
unintended arbitrary local file reads when processing an untrusted config.
expand-module-refs.ts [36-52]

Referred Code
export function expandModuleRefs(config: unknown, configDir: string): unknown {
  if (!hasModulesArray(config)) {
    return config
  }

  const expandedModules = config.modules.map((module) => {
    if (!isModuleRef(module)) {
      return module
    }

    const filePath = resolve(configDir, module.$ref)
    if (!existsSync(filePath)) {
      throw new ModuleRefNotFoundError(module.$ref, filePath)
    }
    const content = readFileSync(filePath, 'utf-8')
    const parsed: unknown = parseYaml(content)
    return parsed
Ticket Compliance
🟡
🎫 #141
🟢 Support $ref file references inside the extraction config modules array so configs can be
split across files.
Resolve `$ref` paths relative to the main config file location.
Support both JSON and YAML in referenced module definition files.
Validate that referenced files conform to the expected module schema.
⚪ Produce a clear error when a referenced file cannot be found.
Codebase Duplication Compliance
⚪
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

🔴
Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Unhandled parse errors: The new $ref expansion reads and parses referenced files without guarding
readFileSync/parseYaml failures, so invalid YAML/JSON or I/O errors will bubble up as
uncaught exceptions without actionable context.

Referred Code
  const filePath = resolve(configDir, module.$ref)
  if (!existsSync(filePath)) {
    throw new ModuleRefNotFoundError(module.$ref, filePath)
  }
  const content = readFileSync(filePath, 'utf-8')
  const parsed: unknown = parseYaml(content)
  return parsed
})

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status:
Uncaught user-facing error: expandModuleRefs can throw (e.g., ModuleRefNotFoundError or YAML parse errors) and is not
caught/converted into a sanitized CLI error response, which can expose stack traces and
internal paths to end users.

Referred Code
const configDir = dirname(resolve(options.config))
const expandedData = expandModuleRefs(parseResult.data, configDir)

if (!isValidExtractionConfig(expandedData)) {
  const validationResult = validateExtractionConfig(expandedData)
  console.log(

Learn more about managing compliance generic rules or creating your own custom rules

⚪
Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status:
Path traversal risk: The $ref value is used with resolve(configDir, module.$ref) and then read from disk
without enforcing that the resolved path stays within configDir, so a config could
potentially reference unintended files via ../ depending on threat model and expected
trust boundary.

Referred Code
const filePath = resolve(configDir, module.$ref)
if (!existsSync(filePath)) {
  throw new ModuleRefNotFoundError(module.$ref, filePath)
}
const content = readFileSync(filePath, 'utf-8')

Learn more about managing compliance generic rules or creating your own custom rules

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jan 13, 2026 •

Copy link
Copy Markdown

Deploying living-architecture with  Cloudflare Pages  Cloudflare Pages

Latest commit: 4e2b261
Status: ✅  Deploy successful!
Preview URL: https://0303a304.living-architecture.pages.dev
Branch Preview URL: https://issue-141-feat-support-ref-f.living-architecture.pages.dev

View logs

@qodo-code-review

qodo-code-review Bot commented Jan 13, 2026 •

Copy link
Copy Markdown
Contributor

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Security
Guard against ref path traversal

Add a check to prevent path traversal vulnerabilities by ensuring the resolved
path from a $ref is within the configuration directory.

packages/riviere-cli/src/commands/extract/expand-module-refs.ts [46-49]

+import { resolve, sep } from 'node:path'
+...
 const filePath = resolve(configDir, module.$ref)
+if (!filePath.startsWith(configDir + sep)) {
+  throw new Error(
+    `Module reference '${module.$ref}' resolves outside config directory`
+  )
+}
 if (!existsSync(filePath)) {
   throw new ModuleRefNotFoundError(module.$ref, filePath)
 }

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 9

__

Why: This suggestion correctly identifies a critical path traversal security vulnerability and provides a robust solution using path.sep to ensure the check is cross-platform compatible.

High
High-level
Implement recursive expansion for $ref

Enhance the $ref expansion to be recursive, allowing referenced files to contain
further $refs. This would enable more complex and composable configurations, but
requires adding protection against circular dependencies.

Examples:

packages/riviere-cli/src/commands/extract/expand-module-refs.ts [36-59]
export function expandModuleRefs(config: unknown, configDir: string): unknown {
  if (!hasModulesArray(config)) {
    return config
  }

  const expandedModules = config.modules.map((module) => {
    if (!isModuleRef(module)) {
      return module
    }


 ... (clipped 14 lines)

Solution Walkthrough:

Before:

function expandModuleRefs(config, configDir) {
  if (!config.modules) {
    return config;
  }

  const expandedModules = config.modules.map(module => {
    if (isModuleRef(module)) {
      const filePath = resolve(configDir, module.$ref);
      const content = readFileSync(filePath);
      const parsed = parseYaml(content);
      // The parsed content is returned without checking for nested $refs
      return parsed;
    }
    return module;
  });

  return { ...config, modules: expandedModules };
}

After:

function expandModuleRefs(config, configDir, visited = new Set()) {
  if (!config.modules) {
    return config;
  }

  const expandedModules = [];
  for (const module of config.modules) {
    if (isModuleRef(module)) {
      const filePath = resolve(configDir, module.$ref);
      if (visited.has(filePath)) {
        throw new CircularReferenceError(filePath);
      }
      
      const subConfig = readAndParseFile(filePath);
      // Recursively expand the loaded configuration
      const expandedSubConfig = expandModuleRefs(subConfig, dirname(filePath), new Set(visited).add(filePath));
      
      // Add the expanded modules to the list
      expandedModules.push(...(expandedSubConfig.modules || [expandedSubConfig]));
    } else {
      expandedModules.push(module);
    }
  }
  return { ...config, modules: expandedModules };
}
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a significant limitation in the new feature's design; implementing recursive expansion with circular dependency checks would substantially increase the feature's power and flexibility.

Medium
General
Handle YAML parse errors

Add a try...catch block around the parseYaml call to handle syntax errors in
referenced files and provide a more descriptive error message.

packages/riviere-cli/src/commands/extract/expand-module-refs.ts [50-52]

 const content = readFileSync(filePath, 'utf-8')
-const parsed: unknown = parseYaml(content)
+let parsed: unknown
+try {
+  parsed = parseYaml(content)
+} catch (err: any) {
+  throw new Error(
+    `Failed to parse module reference '${module.$ref}': ${err.message}`
+  )
+}
 return parsed
  • Apply / Chat
Suggestion importance[1-10]: 7

__

Why: This suggestion correctly points out that an invalid YAML file would cause an unhandled exception and provides a good solution to catch the error and re-throw a more informative one, improving usability.

Medium
Fix incorrect modules type in docs

In the documentation file schema.md, correct the type of the modules property
from undefined[] to module[] or moduleRef[].

packages/riviere-extract-config/docs/generated/schema.md [21]

-| `modules` | `undefined[]` | **Yes** | Module definitions for component extraction |
+| `modules` | `module[] or moduleRef[]` | **Yes** | Module definitions for component extraction |
  • Apply / Chat
Suggestion importance[1-10]: 4

__

Why: The suggestion correctly identifies and fixes a documentation error introduced in this PR, where the type for modules was changed to undefined[] instead of reflecting the new moduleRef option.

Low
  • Update

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In @packages/riviere-cli/src/commands/extract/expand-module-refs.ts:
- Line 8: The local interface declaration "interface ModuleRef { $ref: string }"
in expand-module-refs.ts should be removed and replaced by importing ModuleRef
from the package export; update the top-level imports to add "ModuleRef" from
"@living-architecture/riviere-extract-config" and use that imported type
everywhere in this file (e.g., where ModuleRef is referenced) so the type is
sourced from the canonical config package rather than redefined locally.

In @packages/riviere-cli/src/commands/extract/extract.ts:
- Around line 118-119: The call to expandModuleRefs can throw
ModuleRefNotFoundError and must be handled like the other user-facing validation
errors: import ModuleRefNotFoundError, wrap the
expandModuleRefs(parseResult.data, configDir) call in a try/catch, catch errors
instanceof ModuleRefNotFoundError and emit the same structured JSON error output
and non-zero exit used elsewhere in this file (mirror the formatting/keys used
in the existing error handlers), then return/exit; rethrow unexpected errors.

In @packages/riviere-extract-config/src/types.ts:
- Around line 71-75: The ExtractionConfig type currently declares modules as
ModuleConfig[] but the schema allows each entry to be either ModuleConfig or
ModuleRef; update the ExtractionConfig interface (symbol ExtractionConfig) so
its modules property is typed as an array of (ModuleConfig | ModuleRef) instead
of ModuleConfig[] — ensure ModuleRef (interface ModuleRef {$ref: string}) and
ModuleConfig are imported/available and adjust the declaration line (previously
at the modules property) accordingly to match the schema.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c0ecc01 and 58aba38.

⛔ Files ignored due to path filters (1)
  • packages/riviere-extract-config/docs/generated/schema.md is excluded by !**/generated/**
📒 Files selected for processing (10)
  • .claude/hooks/block-dangerous-commands.sh
  • packages/riviere-cli/src/commands/extract/expand-module-refs.spec.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.ts
  • packages/riviere-cli/src/commands/extract/extract.spec.ts
  • packages/riviere-cli/src/commands/extract/extract.ts
  • packages/riviere-cli/src/errors.spec.ts
  • packages/riviere-cli/src/errors.ts
  • packages/riviere-extract-config/extraction-config.schema.json
  • packages/riviere-extract-config/src/types.ts
  • packages/riviere-extract-config/src/validation.spec.ts
🧰 Additional context used
📓 Path-based instructions (4)
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
  • packages/riviere-extract-config/src/types.ts
**/*.{js,mjs,ts,tsx,json}

📄 CodeRabbit inference engine (CLAUDE.md)

Always use nx commands for build, test, lint operations. Do not run npm/pnpm directly in project folders

Files:

  • packages/riviere-extract-config/src/validation.spec.ts
  • packages/riviere-extract-config/src/types.ts
  • packages/riviere-cli/src/errors.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.spec.ts
  • packages/riviere-cli/src/commands/extract/extract.ts
  • packages/riviere-cli/src/errors.spec.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.ts
  • packages/riviere-cli/src/commands/extract/extract.spec.ts
  • packages/riviere-extract-config/extraction-config.schema.json
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Use cross-project imports with package names (e.g., import { X } from '@living-architecture/[pkg-name]'), not relative paths
When adding dependencies between projects, add "@living-architecture/[pkg-name]": "workspace:*" to the consuming project's package.json
Follow docs/conventions/software-design.md when writing, editing, refactoring, or reviewing code
Look for and follow standard implementation patterns defined in docs/conventions/standard-patterns.md
Avoid anti-patterns documented in @docs/conventions/anti-patterns.md
Follow docs/conventions/testing.md when writing tests. 100% test coverage is mandatory and enforced

Files:

  • packages/riviere-extract-config/src/validation.spec.ts
  • packages/riviere-extract-config/src/types.ts
  • packages/riviere-cli/src/errors.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.spec.ts
  • packages/riviere-cli/src/commands/extract/extract.ts
  • packages/riviere-cli/src/errors.spec.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.ts
  • packages/riviere-cli/src/commands/extract/extract.spec.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js,jsx}: Never commit secrets, API keys, or credentials. Use environment variables for sensitive configuration
Do not log sensitive data (passwords, tokens, PII). Validate and sanitize all external input

Files:

  • packages/riviere-extract-config/src/validation.spec.ts
  • packages/riviere-extract-config/src/types.ts
  • packages/riviere-cli/src/errors.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.spec.ts
  • packages/riviere-cli/src/commands/extract/extract.ts
  • packages/riviere-cli/src/errors.spec.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.ts
  • packages/riviere-cli/src/commands/extract/extract.spec.ts
🧠 Learnings (39)
📓 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*.{json,ts} : Define extraction configuration using the JSON Schema from `living-architecture/riviere-extract-config` DSL
📚 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/validation.spec.ts
  • packages/riviere-extract-config/src/types.ts
  • packages/riviere-cli/src/commands/extract/extract.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.ts
  • packages/riviere-cli/src/commands/extract/extract.spec.ts
  • packages/riviere-extract-config/extraction-config.schema.json
📚 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/validation.spec.ts
  • packages/riviere-extract-config/src/types.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.spec.ts
  • packages/riviere-cli/src/commands/extract/extract.ts
  • packages/riviere-cli/src/errors.spec.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.ts
  • packages/riviere-cli/src/commands/extract/extract.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.ts
  • packages/riviere-extract-config/src/types.ts
  • packages/riviere-cli/src/commands/extract/extract.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.ts
  • packages/riviere-cli/src/commands/extract/extract.spec.ts
  • packages/riviere-extract-config/extraction-config.schema.json
📚 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-extract-config/src/validation.spec.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.spec.ts
  • packages/riviere-cli/src/errors.spec.ts
  • packages/riviere-cli/src/commands/extract/extract.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.ts
  • packages/riviere-extract-config/src/types.ts
  • packages/riviere-cli/src/commands/extract/extract.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.ts
  • packages/riviere-extract-config/extraction-config.schema.json
📚 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.ts
  • packages/riviere-extract-config/src/types.ts
  • packages/riviere-cli/src/errors.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.spec.ts
  • packages/riviere-cli/src/commands/extract/extract.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.ts
  • packages/riviere-cli/src/commands/extract/extract.spec.ts
  • packages/riviere-extract-config/extraction-config.schema.json
📚 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-extract-config/src/validation.spec.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.spec.ts
  • packages/riviere-cli/src/errors.spec.ts
  • packages/riviere-cli/src/commands/extract/extract.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
  • packages/riviere-extract-config/src/types.ts
  • packages/riviere-cli/src/commands/extract/extract.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.ts
  • packages/riviere-cli/src/commands/extract/extract.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.ts
  • packages/riviere-extract-config/src/types.ts
  • packages/riviere-cli/src/commands/extract/extract.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.ts
  • packages/riviere-cli/src/commands/extract/extract.spec.ts
  • packages/riviere-extract-config/extraction-config.schema.json
📚 Learning: 2026-01-13T11:37:59.334Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T11:37:59.334Z
Learning: Applies to vitest.config.ts : Add vitest.config.ts if tests are needed with 100% coverage as the default

Applied to files:

  • packages/riviere-extract-config/src/validation.spec.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.spec.ts
📚 Learning: 2026-01-11T22:42:36.650Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T22:42:36.650Z
Learning: Applies to docs/conventions/**/*.spec.{ts,tsx,js,jsx} : Systematically test edge cases for collections: empty collections, single element, duplicates, nested structures, circular references, large collections, sparse arrays, and mixed types.

Applied to files:

  • packages/riviere-extract-config/src/validation.spec.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.spec.ts
  • packages/riviere-cli/src/errors.spec.ts
  • packages/riviere-cli/src/commands/extract/extract.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
  • packages/riviere-extract-config/extraction-config.schema.json
📚 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.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.spec.ts
  • packages/riviere-cli/src/errors.spec.ts
  • packages/riviere-cli/src/commands/extract/extract.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.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.spec.ts
  • packages/riviere-cli/src/errors.spec.ts
  • packages/riviere-cli/src/commands/extract/extract.spec.ts
📚 Learning: 2026-01-11T22:42:36.650Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T22:42:36.650Z
Learning: Applies to docs/conventions/**/*-fixtures.ts : Create fixture files with pattern '<module>-fixtures.ts' alongside '<module>.spec.ts' to reduce test duplication. Use a buildArgs helper to define defaults and override specific values in tests.

Applied to files:

  • packages/riviere-extract-config/src/validation.spec.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.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.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.spec.ts
  • packages/riviere-cli/src/errors.spec.ts
  • packages/riviere-cli/src/commands/extract/extract.spec.ts
📚 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: In test files matching *.spec.ts or *.test.ts, avoid using try/catch blocks for testing error conditions. Prefer assertion library matchers like expect(...).toThrow() or expect(...).rejects.toThrow() to assert errors.

Applied to files:

  • packages/riviere-extract-config/src/validation.spec.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.spec.ts
  • packages/riviere-cli/src/errors.spec.ts
  • packages/riviere-cli/src/commands/extract/extract.spec.ts
📚 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:

  • packages/riviere-extract-config/src/validation.spec.ts
  • packages/riviere-extract-config/src/types.ts
  • packages/riviere-cli/src/errors.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.spec.ts
  • packages/riviere-cli/src/commands/extract/extract.ts
  • packages/riviere-cli/src/errors.spec.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.ts
  • packages/riviere-cli/src/commands/extract/extract.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-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-config/src/types.ts
  • packages/riviere-cli/src/commands/extract/extract.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.ts
  • packages/riviere-cli/src/commands/extract/extract.spec.ts
  • packages/riviere-extract-config/extraction-config.schema.json
📚 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/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: 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/types.ts
  • packages/riviere-cli/src/commands/extract/extract.ts
  • packages/riviere-extract-config/extraction-config.schema.json
📚 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/expand-module-refs.spec.ts
  • packages/riviere-cli/src/commands/extract/extract.spec.ts
📚 Learning: 2026-01-11T22:42:36.650Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T22:42:36.650Z
Learning: Applies to docs/conventions/**/*.spec.{ts,tsx,js,jsx} : Avoid implementation coupling in tests. Test behavior outcomes, not internal implementation details. For example, assert on result values rather than mock method call signatures.

Applied to files:

  • packages/riviere-cli/src/commands/extract/expand-module-refs.spec.ts
📚 Learning: 2026-01-11T22:42:36.650Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T22:42:36.650Z
Learning: Applies to docs/conventions/**/*.spec.{ts,tsx,js,jsx} : Systematically test null and undefined cases: null input, undefined input, missing optional properties, and explicit undefined vs missing key distinction.

Applied to files:

  • packages/riviere-cli/src/commands/extract/expand-module-refs.spec.ts
📚 Learning: 2026-01-11T22:42:12.408Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/anti-patterns.md:0-0
Timestamp: 2026-01-11T22:42:12.408Z
Learning: Applies to docs/conventions/**/packages/*/src/index.{ts,tsx} : Never export test fixtures from a package's public API for use by other packages. Each package should create its own local test fixtures to avoid fragile cross-package coupling.

Applied to files:

  • packages/riviere-cli/src/commands/extract/expand-module-refs.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:

  • packages/riviere-cli/src/commands/extract/expand-module-refs.spec.ts
  • packages/riviere-cli/src/commands/extract/extract.spec.ts
📚 Learning: 2026-01-11T22:42:36.650Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T22:42:36.650Z
Learning: Applies to docs/conventions/**/*.spec.{ts,tsx,js,jsx} : When testing errors, test both error type and message in a single test—they represent one error condition. For example: expect(() => loadConfig('nonexistent.json')).toThrow(ConfigurationError) and expect(() => loadConfig('nonexistent.json')).toThrow('Config file not found')

Applied to files:

  • packages/riviere-cli/src/commands/extract/expand-module-refs.spec.ts
  • packages/riviere-cli/src/errors.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/expand-module-refs.spec.ts
  • packages/riviere-cli/src/commands/extract/extract.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.ts
  • packages/riviere-cli/src/commands/extract/extract.spec.ts
📚 Learning: 2026-01-11T22:40:43.505Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 132
File: scripts/submit-pr.sh:76-82
Timestamp: 2026-01-11T22:40:43.505Z
Learning: Claude Code PreToolUse hooks (`.claude/hooks/block-dangerous-commands.sh`) intercept direct agent tool invocations but do not intercept commands that run inside scripts. When an agent executes a script like `./scripts/submit-pr.sh`, the hook checks the script execution command itself, not the individual commands (e.g., `git push`) that run within the script's subprocess.

Applied to files:

  • .claude/hooks/block-dangerous-commands.sh
📚 Learning: 2026-01-13T11:37:59.334Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T11:37:59.334Z
Learning: Always use scripts in `./scripts/` for git and GitHub operations (PRs, issues, tasks). Do not use `gh` or `git` commands directly unless no script exists

Applied to files:

  • .claude/hooks/block-dangerous-commands.sh
📚 Learning: 2026-01-06T18:13:55.588Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 58
File: scripts/reply-to-thread.sh:1-12
Timestamp: 2026-01-06T18:13:55.588Z
Learning: In shell scripts like reply-to-thread.sh, NTCoding prefers to keep code simple and not add explicit tool availability checks (e.g., for gh or jq) when the tools will fail immediately upon first use anyway, since such checks add code without changing behavior.

Applied to files:

  • .claude/hooks/block-dangerous-commands.sh
📚 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/**/*.sh : In shell scripts (.sh files), use `jq` for JSON construction instead of manual string escaping to properly handle backslashes, newlines, and tabs.

Applied to files:

  • .claude/hooks/block-dangerous-commands.sh
📚 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/extract.ts
  • packages/riviere-cli/src/commands/extract/expand-module-refs.ts
  • packages/riviere-cli/src/commands/extract/extract.spec.ts
  • packages/riviere-extract-config/extraction-config.schema.json
📚 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/extract.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/extract.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-cli/src/errors.spec.ts
📚 Learning: 2026-01-11T22:42:36.650Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T22:42:36.650Z
Learning: Applies to docs/conventions/**/*.spec.{ts,tsx,js,jsx} : Use Arrange-Act-Assert structure in tests: Set up test data, execute behavior, then verify outcomes.

Applied to files:

  • packages/riviere-cli/src/commands/extract/extract.spec.ts
🧬 Code graph analysis (3)
packages/riviere-extract-config/src/validation.spec.ts (3)
packages/riviere-extract-config/src/index.ts (1)
  • isValidExtractionConfig (3-3)
packages/riviere-extract-config/src/validation.ts (1)
  • isValidExtractionConfig (16-18)
packages/riviere-extract-config/src/validation-fixtures.ts (1)
  • createMinimalModule (29-40)
packages/riviere-cli/src/errors.spec.ts (1)
packages/riviere-cli/src/errors.ts (1)
  • ModuleRefNotFoundError (118-128)
packages/riviere-cli/src/commands/extract/expand-module-refs.ts (2)
packages/riviere-extract-config/src/types.ts (1)
  • ModuleRef (75-75)
packages/riviere-cli/src/errors.ts (1)
  • ModuleRefNotFoundError (118-128)
⏰ 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). (1)
  • GitHub Check: main
🔇 Additional comments (20)
.claude/hooks/block-dangerous-commands.sh (1)

29-39: Implementation is correct and follows existing patterns.

The regex pattern correctly matches gh pr create commands and the denial message provides a clear alternative. The structure mirrors the existing git push block appropriately.

One observation: this change appears unrelated to the PR's stated objective of adding $ref file reference support for extraction configs. Consider whether this workflow enforcement belongs in a separate PR to keep changes focused and easier to review/revert independently.

Based on learnings, this aligns with the repository guideline to use scripts in ./scripts/ for git and GitHub operations rather than direct commands.

packages/riviere-cli/src/errors.ts (1)

118-128: LGTM!

The ModuleRefNotFoundError class follows the established error patterns in this file. The implementation is clean with:

  • Clear, actionable error message
  • Readonly properties for immutability
  • Proper name assignment for error identification
packages/riviere-cli/src/commands/extract/expand-module-refs.spec.ts (5)

12-19: Good mock lifecycle management.

The beforeEach/afterEach setup correctly resets and restores mocks between tests, preventing test pollution.


21-43: Solid edge case coverage.

These tests verify that expandModuleRefs gracefully handles invalid or unexpected inputs by returning them unchanged, which is important for robustness.


129-140: LGTM!

The error test correctly verifies both the error type and message, following the testing convention to test both in a single test case.


1-8: Missing import for createMinimalModule fixture.

The test at line 27 uses createMinimalModule() but this function is not imported. Based on the coding guidelines about cross-project imports, you should either:

  1. Import from the package if it's a public export:
+import { createMinimalModule } from '@living-architecture/riviere-extract-config/validation-fixtures'
  1. Or define a local fixture inline (as done in lines 66-75).

Option 2 is preferred per learnings: "Never export test fixtures from a package's public API for use by other packages."

Proposed fix
 it('returns true when mixing $ref and inline modules', () => {
-    const config = {modules: [{ $ref: './domains/orders.extraction.json' }, createMinimalModule()],}
+    const inlineModule = {
+      name: 'test',
+      path: 'src/**',
+      api: { notUsed: true },
+      useCase: { notUsed: true },
+      domainOp: { notUsed: true },
+      event: { notUsed: true },
+      eventHandler: { notUsed: true },
+      ui: { notUsed: true },
+    }
+    const config = { modules: [{ $ref: './domains/orders.extraction.json' }, inlineModule] }
     expect(isValidExtractionConfig(config)).toBe(true)
   })

Note: This issue is in validation.spec.ts at line 27, not this file. Apologies for the confusion - I'll address the actual file review below.


85-126: YAML file expansion is already supported through the parseYaml function.

The implementation uses the YAML parser for both JSON and YAML files since JSON is valid YAML syntax. The current test for JSON file expansion (lines 85–126) implicitly covers YAML support. Adding an explicit YAML test would improve test clarity and documentation, but is not required for functional correctness.

⛔ Skipped due to learnings
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.
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/**/*.test.{ts,tsx} : Use ts-morph's in-memory file system (`useInMemoryFileSystem: true`) for fast isolated tests
packages/riviere-extract-config/extraction-config.schema.json (2)

18-23: LGTM! Schema correctly updated to support module references.

The oneOf construct properly allows modules array items to be either inline module definitions or external file references.


27-39: moduleRef definition is well-constrained.

The definition correctly enforces:

  • Required $ref property
  • No additional properties (strict shape)
  • Non-empty string for the file path

This aligns with the ModuleRef TypeScript interface.

packages/riviere-extract-config/src/validation.spec.ts (1)

21-29: Good test coverage for $ref validation.

The tests correctly verify that isValidExtractionConfig accepts both standalone $ref modules and mixed configurations. The test structure is consistent with existing patterns.

Consider adding negative test cases to the 'returns false when data is %s' parameterized test to verify schema rejects invalid $ref values:

  • { modules: [{ $ref: '' }] } (empty string)
  • { modules: [{ $ref: 123 }] } (non-string)
  • { modules: [{ $ref: './file.json', extra: 'prop' }] } (additional properties)
⛔ Skipped due to learnings
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.
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/**/*.test.{ts,tsx} : Implement unit tests for each predicate type in isolation with positive and negative cases
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T22:42:36.650Z
Learning: Applies to docs/conventions/**/*.spec.{ts,tsx,js,jsx} : Systematically test edge cases for collections: empty collections, single element, duplicates, nested structures, circular references, large collections, sparse arrays, and mixed 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: 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: 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/testing.md:0-0
Timestamp: 2026-01-11T22:42:36.650Z
Learning: Applies to docs/conventions/**/*.spec.{ts,tsx,js,jsx} : Systematically test null and undefined cases: null input, undefined input, missing optional properties, and explicit undefined vs missing key distinction.
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/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/testing.md:0-0
Timestamp: 2026-01-11T22:42:36.650Z
Learning: Applies to docs/conventions/**/*.spec.{ts,tsx,js,jsx} : When testing errors, test both error type and message in a single test—they represent one error condition. For example: expect(() => loadConfig('nonexistent.json')).toThrow(ConfigurationError) and expect(() => loadConfig('nonexistent.json')).toThrow('Config file not found')
packages/riviere-cli/src/commands/extract/expand-module-refs.ts (4)

1-6: LGTM!

Imports are appropriate—using node:fs and node:path for file operations, yaml for parsing, and the custom error class for missing references.


10-18: LGTM!

Type guard correctly narrows to ModuleRef with appropriate null/type checks before property access.


20-28: LGTM!

Type guard correctly identifies configs with a modules array property using minimal validation as expected per the layered validation pattern.


36-59: LGTM!

Implementation correctly:

  • Short-circuits for configs without modules array
  • Resolves file paths relative to configDir as required
  • Throws descriptive error for missing referenced files
  • Preserves non-ref modules unchanged
  • Returns a new object without mutating input
packages/riviere-cli/src/errors.spec.ts (2)

16-16: LGTM!

Import addition follows the existing pattern for error imports.


209-231: LGTM!

Test suite comprehensively covers the ModuleRefNotFoundError class with tests for message formatting, name property, and exposed ref/filePath properties. Structure matches established patterns in this file.

packages/riviere-cli/src/commands/extract/extract.ts (2)

26-26: LGTM!

Import follows cross-project import conventions using relative path within the same package.


121-136: LGTM!

Correctly wires the expanded config data through validation and resolution. The flow ensures $ref entries are resolved before schema validation, which aligns with the PR objective of validating referenced files against the existing schema.

packages/riviere-cli/src/commands/extract/extract.spec.ts (2)

137-140: LGTM!

Test suite setup follows the established pattern with createTestContext and setupCommandTest.


141-196: LGTM!

Comprehensive integration test that verifies the complete $ref expansion flow:

  • Sets up realistic file structure with source code and referenced module config
  • Uses $ref in main config pointing to external module definition
  • Validates that extraction succeeds and produces expected component output

This effectively proves that $ref references are expanded before schema validation (since raw $ref objects would fail validation).

Comment thread packages/riviere-cli/src/commands/extract/expand-module-refs.ts Outdated
Comment thread packages/riviere-cli/src/commands/extract/extract.ts Outdated
Comment thread packages/riviere-extract-config/src/types.ts
NTCoding and others added 2 commits January 14, 2026 00:31
Extracted module ref expansion error handling into separate tryExpandModuleRefs function.
Simplified type predicates for better readability.
Added test coverage for missing module file scenario.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@sonarqubecloud

Copy link
Copy Markdown

@NTCoding
NTCoding merged commit e8568f9 into main Jan 14, 2026
16 of 17 checks passed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @.claude/commands/complete-task.md:
- Around line 164-171: Update Step 5 to add explicit failure handling for the
./scripts/submit-pr.sh invocation: document the expected FAIL output block when
submit-pr.sh exits non‑zero (capture and paste raw output, show "SUBMIT PR
FAILED", include troubleshooting steps like verify branch pushed, network/auth
checks, and instruct whether to retry or run /complete-task), clarify PR
title/body guidance by telling agents to synthesize the title from changed files
and commit types (use conventional commit format via the diff and PR objectives)
and to generate the body from PR objectives plus a short summary of key changed
files and rationale, and reconcile the workflow diagram by making the "submit-pr
subagent → captures output" line consistent with the "Run directly" instruction
so both reference the same behavior for ./scripts/submit-pr.sh.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2366a5a and 4e2b261.

📒 Files selected for processing (1)
  • .claude/commands/complete-task.md
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 156
File: packages/riviere-extract-config/src/types.ts:71-75
Timestamp: 2026-01-14T00:09:27.486Z
Learning: In packages/riviere-extract-config/src/types.ts, the ExtractionConfig interface represents the post-expansion state where all $ref module references have been resolved to ModuleConfig entries. The extraction-config.schema.json allows both ModuleConfig and ModuleRef in the modules array because it validates raw input before expandModuleRefs runs, but after expansion, modules are always ModuleConfig[], so the TypeScript type correctly models this expanded state.
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/**/*.{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-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: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Use glob pattern matching for module-based organization of extraction rules
📚 Learning: 2026-01-09T18:10:15.724Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 85
File: .claude/commands/post-merge-completion.md:35-39
Timestamp: 2026-01-09T18:10:15.724Z
Learning: In .claude/commands/post-merge-completion.md, the review files in `reviews/<branch>/` (code-review.md, bug-scanner.md, task-check.md, doc-suggestions.md) are optional inputs to the reflection process. The post-merge-completion command should work gracefully even if these files are missing or if /complete-task wasn't run before merging.

Applied to files:

  • .claude/commands/complete-task.md
📚 Learning: 2026-01-11T22:40:43.505Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 132
File: scripts/submit-pr.sh:76-82
Timestamp: 2026-01-11T22:40:43.505Z
Learning: Claude Code PreToolUse hooks (`.claude/hooks/block-dangerous-commands.sh`) intercept direct agent tool invocations but do not intercept commands that run inside scripts. When an agent executes a script like `./scripts/submit-pr.sh`, the hook checks the script execution command itself, not the individual commands (e.g., `git push`) that run within the script's subprocess.

Applied to files:

  • .claude/commands/complete-task.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). (2)
  • GitHub Check: main
  • GitHub Check: Cloudflare Pages

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +164 to +171
Run directly (10-minute timeout):

- FAIL → return:
```text
SUBMIT PR FAILED
<raw-output>
[paste the COMPLETE raw output here - do not summarize]
</raw-output>
NEXT STEPS: Address the issues and re-run /complete-task
LOOP CONTROL: If this is your third successive attempt, ask the user for help.
```
```bash
./scripts/submit-pr.sh --title "<type>(scope): description" --body "<summary>"
```

Title: Use conventional commit format based on the changes.
Body: Brief summary of what changed and why.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, check if the file exists and examine its structure
find . -name "complete-task.md" -type f 2>/dev/null | head -5

Repository: NTCoding/living-architecture

Length of output: 107


🏁 Script executed:

# Check the repository structure to understand context
git ls-files | grep -E "(claude|script)" | head -20

Repository: NTCoding/living-architecture

Length of output: 1032


🏁 Script executed:

# Once we know the file exists, get total line count and examine the target area
if [[ -f .claude/commands/complete-task.md ]]; then
  wc -l .claude/commands/complete-task.md
fi

Repository: NTCoding/living-architecture

Length of output: 109


🏁 Script executed:

# Examine the target lines (164-171) and the workflow diagram area (around line 30)
cat -n .claude/commands/complete-task.md | sed -n '25,35p'

Repository: NTCoding/living-architecture

Length of output: 449


🏁 Script executed:

# Read the Step 5 section (lines 164-171)
cat -n .claude/commands/complete-task.md | sed -n '160,175p'

Repository: NTCoding/living-architecture

Length of output: 608


🏁 Script executed:

# Also check Step 1 to understand the error handling pattern referenced in the review
cat -n .claude/commands/complete-task.md | sed -n '1,100p' | grep -A 30 "Step 1"

Repository: NTCoding/living-architecture

Length of output: 54


🏁 Script executed:

# Check if submit-pr.sh exists and examine its interface
if [[ -f ./scripts/submit-pr.sh ]]; then
  echo "=== Script found ===" 
  head -30 ./scripts/submit-pr.sh
  echo -e "\n=== Error patterns ===" 
  grep -n "exit\|return\|ERROR\|FAIL" ./scripts/submit-pr.sh | head -20
else
  echo "submit-pr.sh not found at ./scripts/submit-pr.sh"
  find . -name "submit-pr.sh" 2>/dev/null
fi

Repository: NTCoding/living-architecture

Length of output: 973


🏁 Script executed:

# Look for Step 1 to understand the error handling pattern
cat -n .claude/commands/complete-task.md | sed -n '50,130p'

Repository: NTCoding/living-architecture

Length of output: 2907


🏁 Script executed:

# Get more of submit-pr.sh to understand its error handling better
cat -n ./scripts/submit-pr.sh | sed -n '1,60p'

Repository: NTCoding/living-architecture

Length of output: 1865


🏁 Script executed:

# Look at the full Step 5 section and beyond to see if error handling is documented elsewhere
cat -n .claude/commands/complete-task.md | sed -n '162,190p'

Repository: NTCoding/living-architecture

Length of output: 1243


Add error handling and clarify PR content guidance.

Step 5 has several issues:

  1. Missing failure handling (major): Unlike Step 1 (verify gate), there's no documented error path if submit-pr.sh fails. The script uses set -euo pipefail and exits on errors, but the documentation doesn't tell agents whether to retry, fix, or report when script execution fails due to network issues, authentication failures, or validation errors.

  2. Insufficient guidance on PR content (minor): The placeholders <type>(scope): description and <summary> lack clear sourcing instructions. The guidance "based on the changes" and "what changed and why" is ambiguous—should the agent synthesize from diffs, use the issue description, reference PR objectives, or generate a new summary?

  3. Workflow diagram inconsistency (minor): Line 30 states "submit-pr subagent → captures output", but line 164 instructs "Run directly". These conflict and should be aligned.

📝 Suggested improvements

Add a failure handling block similar to Step 1:

 Run directly (10-minute timeout):
 
 ```bash
 ./scripts/submit-pr.sh --title "<type>(scope): description" --body "<summary>"

+- FAIL → return:

  • SUBMIT PR FAILED
  • [paste the COMPLETE error output here - do not summarize]
  • NEXT STEPS: Verify branch is pushed, check network/auth, and retry /complete-task

Title: Use conventional commit format based on the changes.
-Body: Brief summary of what changed and why.
+Body: Synthesize a brief summary from the PR objectives and changed files, explaining what changed and why.


Update line 30 in the workflow diagram:

```diff
-    ├── submit-pr subagent → captures output
+    ├── submit-pr script → run directly with timeout
📝 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.

Suggested change
Run directly (10-minute timeout):
- FAIL → return:
```text
SUBMIT PR FAILED
<raw-output>
[paste the COMPLETE raw output here - do not summarize]
</raw-output>
NEXT STEPS: Address the issues and re-run /complete-task
LOOP CONTROL: If this is your third successive attempt, ask the user for help.
```
```bash
./scripts/submit-pr.sh --title "<type>(scope): description" --body "<summary>"
```
Title: Use conventional commit format based on the changes.
Body: Brief summary of what changed and why.
Run directly (10-minute timeout):
🤖 Prompt for AI Agents
In @.claude/commands/complete-task.md around lines 164 - 171, Update Step 5 to
add explicit failure handling for the ./scripts/submit-pr.sh invocation:
document the expected FAIL output block when submit-pr.sh exits non‑zero
(capture and paste raw output, show "SUBMIT PR FAILED", include troubleshooting
steps like verify branch pushed, network/auth checks, and instruct whether to
retry or run /complete-task), clarify PR title/body guidance by telling agents
to synthesize the title from changed files and commit types (use conventional
commit format via the diff and PR objectives) and to generate the body from PR
objectives plus a short summary of key changed files and rationale, and
reconcile the workflow diagram by making the "submit-pr subagent → captures
output" line consistent with the "Run directly" instruction so both reference
the same behavior for ./scripts/submit-pr.sh.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Support $ref file references in extraction config

1 participant