Skip to content

feat: concept-explanation tools for queryable methodology knowledge#78

Merged
ablanrob merged 3 commits into
mainfrom
feat/concept-tools
May 13, 2026
Merged

feat: concept-explanation tools for queryable methodology knowledge#78
ablanrob merged 3 commits into
mainfrom
feat/concept-tools

Conversation

@ablanrob

Copy link
Copy Markdown
Owner

Summary

  • Adds a concept registry (src/methodology/) with 23 methodology concepts covering AEM phases, rituals (Sprint 0, phase gates, iterative loops), artifact types, and persona roles
  • Exposes three new MCP tools: list_concepts, explain_concept, explain_phase that return structured, queryable methodology definitions
  • Concepts are the single source of truth for methodology knowledge — assistants can query them directly instead of extracting definitions from persona guidance prose
  • Filtering by category and methodology is supported; AEM-specific checklist items are auto-included/excluded based on project config
  • Includes normalizeMethodology() to map config IDs (sap-aem) to concept values (aem)

Test plan

  • 57 new tests (41 registry + 16 tool tests) — all passing
  • Verify list_concepts({}) returns all expected concepts (AC1.1)
  • Verify explain_concept("sprint-0") returns Sprint 0 checklist matching DM persona guidance (AC1.2)
  • Verify explain_concept("nonexistent-id") returns clear error suggesting list_concepts (AC1.3)
  • Verify adding a new concept to the registry makes it available without tool changes (AC1.5)
  • Full test suite (967 tests) passes, typecheck clean

Add a concept registry and three MCP tools (list_concepts, explain_concept,
explain_phase) that expose Marvin's methodology definitions as structured,
queryable data. Concepts cover AEM phases, rituals (Sprint 0, phase gates,
iterative loops), artifact types, and persona roles.

The registry is the single source of truth for methodology knowledge,
replacing the need to extract definitions from persona guidance text.
Filtering by category and methodology is supported, and AEM-specific
checklist items are automatically included/excluded based on project config.
@coderabbitai

coderabbitai Bot commented May 12, 2026

Copy link
Copy Markdown

Review Change Stack
No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e131ba5d-099c-49cc-aba4-16bc123ac408

📥 Commits

Reviewing files that changed from the base of the PR and between 63e80dc and 2d98eb9.

📒 Files selected for processing (1)
  • src/methodology/types.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/methodology/types.ts

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added a comprehensive methodology concepts framework (phases, rituals, roles, artifact types) with guidance and metadata.
    • Assistant now exposes concept lookup, explain, and phase-lookup capabilities and includes methodology-aware concept tools.
  • Bug Fixes / Enhancements

    • Improved methodology normalization and matching (aliases supported); checklist content adapts to selected methodology.
  • Tests

    • Added tests covering the concept registry and assistant-facing concept tools.

Walkthrough

Adds a methodology concepts domain: core types, concept collections (phases, rituals, artifact types, roles), ALL_CONCEPTS, a ConceptRegistry with filtering and methodology-aware checklist behavior, three MCP tools (list_concepts, explain_concept, explain_phase), MCP server wiring, and tests for registry and tools.

Changes

Methodology Concepts System

Layer / File(s) Summary
Methodology Type System
src/methodology/types.ts
ConceptCategory, Methodology, ConceptDefinition, ConceptSummary, ChecklistItem, and ConceptFilter plus normalizeMethodology define contracts and normalization for methodologies.
Phase and Ritual Concepts
src/methodology/concepts/phases.ts, src/methodology/concepts/rituals.ts
Three AEM phases and three ritual concepts are defined with metadata, checklists (where present), and relationships.
Artifact Type and Role Concepts
src/methodology/concepts/artifact-types.ts, src/methodology/concepts/roles.ts
Multiple artifact-type concepts and role concepts with lifecycle descriptions, related artifacts/tools/personas, and supported methodologies.
Concept Index
src/methodology/concepts/index.ts
Exports ALL_CONCEPTS by concatenating concept collections and re-exports individual collections.
Concept Registry and Index
src/methodology/registry.ts
ConceptRegistry with constructor duplicate-ID checks, get, list(filter?), explain(id, methodology?) (filters AEM-only checklist items when methodology != "aem"), ids(), and a lazy getConceptRegistry().
MCP Tools
src/methodology/tools.ts
createConceptTools(config?) returns three read-only MCP tools: list_concepts, explain_concept, and explain_phase, each validating inputs and returning JSON-serialized structured payloads.
MCP Server Integration
src/agent/mcp-server.ts
Imports createConceptTools and appends createConceptTools(options?.config) to the MCP server tools array.
Concept Registry Tests
test/methodology/registry.test.ts
Tests registry initialization, duplicate-ID rejection, get/list/explain semantics, methodology-aware checklist inclusion, and data integrity checks (unique kebab-case IDs, non-empty sources, required concepts).
MCP Tools Tests
test/methodology/tools.test.ts
Tests tool registration and behavior for listing, explain_concept, and explain_phase, including error cases and methodology-dependent outputs.

Sequence Diagram

sequenceDiagram
  participant Client
  participant MCP_Tools as MCP Tools
  participant Registry as ConceptRegistry
  Client->>MCP_Tools: list_concepts(category?, methodology?)
  MCP_Tools->>Registry: list(filter)
  Registry-->>MCP_Tools: ConceptSummary[]
  MCP_Tools-->>Client: JSON response
  Client->>MCP_Tools: explain_concept(id, methodology?)
  MCP_Tools->>Registry: explain(id, methodology)
  Registry-->>MCP_Tools: ConceptDefinition (with conditional checklist)
  MCP_Tools-->>Client: JSON response
  Client->>MCP_Tools: explain_phase(name_or_id)
  MCP_Tools->>Registry: get(id) or list() + name match
  Registry-->>MCP_Tools: ConceptDefinition (validated as phase)
  MCP_Tools-->>Client: JSON response
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • ablanrob/marvin-cli#74: Modifies src/agent/mcp-server.ts MCP server tool registration, similar to this PR's wiring of concept tools into the server configuration.

Poem

🐰 I hopped through phases, rituals, and roles today,

I tumbled definitions into a tidy array,
The registry hums, the tools answer in JSON light,
Claude can ask and the concepts take flight,
A rabbit applauds—methodology tucked in tight.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The PR description covers the key changes (concept registry, MCP tools, filtering), test plan status, and objectives. However, it does not follow the provided template structure with explicit sections for Summary, Changes, Type of Change, Testing, and Checklist. Restructure the description to follow the repository template: add explicit 'Type of Change' checkbox confirmation, complete the 'Testing' checklist with all items checked, and ensure 'Checklist' items are explicitly marked as complete or pending.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: concept-explanation tools for queryable methodology knowledge' accurately summarizes the main change: adding MCP tools for querying methodology concepts.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/concept-tools

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@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: 5

🧹 Nitpick comments (2)
src/methodology/registry.ts (1)

36-51: ⚡ Quick win

Return a copy consistently for safety and predictability.

The explain() method returns the original internal concept reference on line 42 when no filtering is needed, but returns a shallow copy on line 50 when filtering is applied. This inconsistency could allow callers to accidentally mutate the registry's internal state in the unfiltered case.

🔒 Proposed fix to always return a shallow copy
   if (!concept.checklist || methodology === "aem") {
-    return concept;
+    return { ...concept };
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/methodology/registry.ts` around lines 36 - 51, The explain() method
currently returns the internal concept object (variable concept) when no
filtering is needed but returns a shallow copy when filtering occurs; always
return a shallow copy to avoid exposing internal state. Modify explain() so both
branches return a new object (e.g., { ...concept, checklist: concept.checklist }
or when filtered use filteredChecklist) instead of returning concept directly;
ensure the checklist property is preserved (possibly undefined) and that the
filteredChecklist is used when methodology !== "aem".
test/methodology/tools.test.ts (1)

41-41: ⚡ Quick win

Avoid hard-coding the phase count in this test.

expect(data.concepts.length).toBe(3) will break when new phase concepts are added, even if behavior is correct.

Suggested patch
-      expect(data.concepts.length).toBe(3);
+      expect(data.concepts.length).toBeGreaterThan(0);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/methodology/tools.test.ts` at line 41, The test currently hard-codes the
phase count with expect(data.concepts.length).toBe(3), which will break when new
phase concepts are added; update the assertion to derive the expected count
dynamically (for example by comparing data.concepts.length to the source of
truth such as the Phase enum/array or methodologyPhases list used by the
implementation) or assert presence of specific expected concept names instead of
an exact numeric literal; refer to data.concepts in the test and the Phase
enum/array (or methodologyPhases) in the production code to compute the expected
value and use that computed value in the expect() call.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/methodology/tools.ts`:
- Line 8: The code blindly casts config?.methodology to Methodology when setting
the methodology constant, which skips the config-ID mapping path; instead call
the existing normalization helper (e.g., normalizeMethodology or whichever
helper maps config IDs to Methodology) on config?.methodology and then fallback
to "generic-agile" if the normalized result is falsy. Replace the current
expression that uses (config?.methodology as Methodology) with a call like
normalizeMethodology(config?.methodology) ?? "generic-agile", keeping the
variable name methodology.
- Around line 110-120: The phase lookup and "available phases" message are
currently using registry.list({ category: "phase" }) which returns phases across
all methodologies; change both registry.list calls in explain_phase to scope to
the active methodology (e.g., pass the methodology identifier/filter used
elsewhere in code such as registry.list({ category: "phase", methodology }) or
registry.list({ category: "phase", methodologyId: methodology.id }) so the match
variable and available list only include phases for the current methodology;
ensure the name comparison (match = phases.find(...)) and the available string
(available = phases.map(...)) both use this filtered list.
- Line 7: The exported function createConceptTools currently returns
SdkMcpToolDefinition<any>[] which forces unsafe downstream casts; change the
exported signature to avoid any (e.g., use SdkMcpToolDefinition<unknown>[] or
make the function generic so each tool’s arg type is explicit) and then
narrow/validate args inside the tool handlers instead of casting (remove the
explicit `as ConceptCategory | undefined` and `as Methodology` casts in the tool
implementations and replace them with runtime checks or type guards). Apply the
same pattern to other tool factory functions (or introduce a small
wrapper/generic alias for SdkMcpToolDefinition<T>) so the codebase no longer
relies on `any` for tool args.

In `@test/methodology/registry.test.ts`:
- Around line 135-142: The test title is misleading: it says "includes AEM
addendum when no methodology specified" but the body (using ConceptRegistry,
registry.explain("sprint-0"), sprint0 and the aem-addendum check) asserts the
AEM section is excluded; update the it(...) description to reflect that behavior
(e.g., "excludes AEM addendum when no methodology specified (no filtering)") so
the test name matches the expectations and inline comment.

In `@test/methodology/tools.test.ts`:
- Around line 1-15: The test suite "Concept tools" (in
test/methodology/tools.test.ts) is missing per-test temp directory lifecycle;
add creation of a temp dir using fs.mkdtempSync in a beforeEach (or at top of
the describe) and remove it in afterEach (fs.rmSync with recursive and force) so
each test gets an isolated directory; update any helpers or tests that rely on a
temp path to use this per-test directory (refer to the describe("Concept tools")
block and helper functions extractHandler and parseResult to locate where to
wire the temp dir into test setup/teardown).

---

Nitpick comments:
In `@src/methodology/registry.ts`:
- Around line 36-51: The explain() method currently returns the internal concept
object (variable concept) when no filtering is needed but returns a shallow copy
when filtering occurs; always return a shallow copy to avoid exposing internal
state. Modify explain() so both branches return a new object (e.g., {
...concept, checklist: concept.checklist } or when filtered use
filteredChecklist) instead of returning concept directly; ensure the checklist
property is preserved (possibly undefined) and that the filteredChecklist is
used when methodology !== "aem".

In `@test/methodology/tools.test.ts`:
- Line 41: The test currently hard-codes the phase count with
expect(data.concepts.length).toBe(3), which will break when new phase concepts
are added; update the assertion to derive the expected count dynamically (for
example by comparing data.concepts.length to the source of truth such as the
Phase enum/array or methodologyPhases list used by the implementation) or assert
presence of specific expected concept names instead of an exact numeric literal;
refer to data.concepts in the test and the Phase enum/array (or
methodologyPhases) in the production code to compute the expected value and use
that computed value in the expect() call.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 298d4df8-41c5-4c47-8b42-8151de3a2217

📥 Commits

Reviewing files that changed from the base of the PR and between fc5fd69 and 5bd06f1.

📒 Files selected for processing (11)
  • src/agent/mcp-server.ts
  • src/methodology/concepts/artifact-types.ts
  • src/methodology/concepts/index.ts
  • src/methodology/concepts/phases.ts
  • src/methodology/concepts/rituals.ts
  • src/methodology/concepts/roles.ts
  • src/methodology/registry.ts
  • src/methodology/tools.ts
  • src/methodology/types.ts
  • test/methodology/registry.test.ts
  • test/methodology/tools.test.ts

Comment thread src/methodology/tools.ts
import type { Methodology, ConceptCategory } from "./types.js";
import { getConceptRegistry } from "./registry.js";

export function createConceptTools(config?: MarvinProjectConfig): SdkMcpToolDefinition<any>[] {

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 | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify `any` usage and downstream casts in changed methodology tool wiring.
rg -n --type=ts 'SdkMcpToolDefinition<any>|as ConceptCategory|as Methodology' src/methodology/tools.ts src/agent/mcp-server.ts

Repository: ablanrob/marvin-cli

Length of output: 614


🏁 Script executed:

# Check the full function implementation to understand the context
sed -n '1,50p' src/methodology/tools.ts

Repository: ablanrob/marvin-cli

Length of output: 2088


🏁 Script executed:

# Find the definition of SdkMcpToolDefinition
rg -n 'type SdkMcpToolDefinition|interface SdkMcpToolDefinition' --type=ts

Repository: ablanrob/marvin-cli

Length of output: 3317


🏁 Script executed:

# Check what args type is used in the function and look for Zod schemas
rg -n 'args\.|ZodSchema\|z\.object' src/methodology/tools.ts -A 2 -B 2

Repository: ablanrob/marvin-cli

Length of output: 1716


🏁 Script executed:

# Check if other tool functions in the codebase use <any> or have found a better pattern
rg -n 'export function.*Tool.*SdkMcpToolDefinition' src/ --type=ts -A 1 | head -40

Repository: ablanrob/marvin-cli

Length of output: 2504


🏁 Script executed:

# Look for any type parameter examples in tool definitions
rg -n 'SdkMcpToolDefinition<(?!any)' src/ --type=ts

Repository: ablanrob/marvin-cli

Length of output: 316


🏁 Script executed:

# Search with proper regex for any type parameter usage
rg -n 'SdkMcpToolDefinition<[^>]*>' src/ --type=ts | cut -d: -f3 | sort | uniq -c

Repository: ablanrob/marvin-cli

Length of output: 1442


🏁 Script executed:

# Check the tool() function return type to understand if it enforces <any>
rg -n 'const.*=.*tool\(' src/methodology/tools.ts -A 5 | head -25

Repository: ablanrob/marvin-cli

Length of output: 45


🏁 Script executed:

# Check if tool() function has generic parameters
rg -n 'function tool|const tool|export.*tool' node_modules/@anthropic-ai/claude-agent-sdk -A 3 2>/dev/null | head -20 || echo "SDK not in node_modules, checking imports"

Repository: ablanrob/marvin-cli

Length of output: 45


🏁 Script executed:

# Look at how the tool() results are being used to understand the pattern better
sed -n '7,70p' src/methodology/tools.ts

Repository: ablanrob/marvin-cli

Length of output: 2471


Remove any from the exported tool signature to preserve type safety.

SdkMcpToolDefinition<any>[] causes the downstream casts at lines 28–29. The any type on args forces explicit as ConceptCategory | undefined and as Methodology casts, violating the guideline: "Never use @ts-ignore or any unless absolutely unavoidable — prefer unknown with type narrowing."

Note: This pattern appears across all tool factory functions in the codebase. Consider a systematic approach (e.g., wrapper type, SDK upgrade, or documented exception) rather than addressing this file in isolation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/methodology/tools.ts` at line 7, The exported function createConceptTools
currently returns SdkMcpToolDefinition<any>[] which forces unsafe downstream
casts; change the exported signature to avoid any (e.g., use
SdkMcpToolDefinition<unknown>[] or make the function generic so each tool’s arg
type is explicit) and then narrow/validate args inside the tool handlers instead
of casting (remove the explicit `as ConceptCategory | undefined` and `as
Methodology` casts in the tool implementations and replace them with runtime
checks or type guards). Apply the same pattern to other tool factory functions
(or introduce a small wrapper/generic alias for SdkMcpToolDefinition<T>) so the
codebase no longer relies on `any` for tool args.

Comment thread src/methodology/tools.ts Outdated
Comment thread src/methodology/tools.ts Outdated
Comment thread test/methodology/registry.test.ts Outdated
Comment on lines +1 to +15
import { describe, it, expect } from "vitest";
import { createConceptTools } from "../../src/methodology/tools.js";
import type { MarvinProjectConfig } from "../../src/core/config.js";

function extractHandler(tools: any[], name: string): (args: any) => Promise<any> {
const t = tools.find((tool) => tool.name === name);
if (!t) throw new Error(`Tool "${name}" not found`);
return (t as any).handler;
}

function parseResult(result: any): any {
return JSON.parse(result.content[0].text);
}

describe("Concept tools", () => {

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 | ⚡ Quick win

Add per-test temp directory setup/cleanup for this suite.

Current tests skip the required temp-dir lifecycle (mkdtempSync + cleanup in afterEach).

As per coding guidelines, test/**/*.test.ts: "Each test should create a temp directory (fs.mkdtempSync) and clean up in afterEach."

Also applies to: 15-207

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/methodology/tools.test.ts` around lines 1 - 15, The test suite "Concept
tools" (in test/methodology/tools.test.ts) is missing per-test temp directory
lifecycle; add creation of a temp dir using fs.mkdtempSync in a beforeEach (or
at top of the describe) and remove it in afterEach (fs.rmSync with recursive and
force) so each test gets an isolated directory; update any helpers or tests that
rely on a temp path to use this per-test directory (refer to the
describe("Concept tools") block and helper functions extractHandler and
parseResult to locate where to wire the temp dir into test setup/teardown).

- Add normalizeMethodology() to map config IDs (sap-aem → aem) instead
  of raw-casting config.methodology to Methodology type
- Scope explain_phase phase lookups to active methodology so only
  relevant phases appear in suggestions
- Always return shallow copy from registry.explain() to avoid exposing
  internal state
- Fix misleading test title ("includes" → "excludes" AEM addendum)
- Derive expected phase count from source data instead of hard-coding

@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.

🧹 Nitpick comments (1)
src/methodology/types.ts (1)

47-50: ⚡ Quick win

Avoid silently downgrading invalid methodology IDs

Unknown non-empty values currently fall back to "generic-agile", which can mask config mistakes and return the wrong concept/checklist set. Keep fallback for missing values, but raise a typed config error for invalid IDs.

Suggested refactor
+import { ConfigError } from "../core/errors.js";
+
 export function normalizeMethodology(configValue?: string): Methodology {
-  if (!configValue) return "generic-agile";
-  return METHODOLOGY_ALIASES[configValue] ?? "generic-agile";
+  if (!configValue?.trim()) return "generic-agile";
+  const methodology = METHODOLOGY_ALIASES[configValue.trim().toLowerCase()];
+  if (!methodology) {
+    throw new ConfigError(`Unsupported methodology: ${configValue}`);
+  }
+  return methodology;
 }

As per coding guidelines "Use the project's error hierarchy in src/core/errors.ts (MarvinError, ProjectNotFoundError, ConfigError, ApiKeyMissingError). Throw typed errors, never plain strings."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/methodology/types.ts` around lines 47 - 50, The current
normalizeMethodology silently maps unknown non-empty IDs to "generic-agile";
instead, keep the existing fallback when configValue is missing but throw a
typed ConfigError for invalid non-empty IDs. Update the normalizeMethodology
function to: if configValue is falsy return "generic-agile"; else if
METHODOLOGY_ALIASES has the key return that value; otherwise throw a ConfigError
(from src/core/errors.ts) describing the invalid methodology id so callers get a
typed error rather than a silent downgrade. Ensure the function signature and
Methodology return type remain unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/methodology/types.ts`:
- Around line 47-50: The current normalizeMethodology silently maps unknown
non-empty IDs to "generic-agile"; instead, keep the existing fallback when
configValue is missing but throw a typed ConfigError for invalid non-empty IDs.
Update the normalizeMethodology function to: if configValue is falsy return
"generic-agile"; else if METHODOLOGY_ALIASES has the key return that value;
otherwise throw a ConfigError (from src/core/errors.ts) describing the invalid
methodology id so callers get a typed error rather than a silent downgrade.
Ensure the function signature and Methodology return type remain unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b0e765ee-8ca2-47e6-9ac1-703269a21514

📥 Commits

Reviewing files that changed from the base of the PR and between 5bd06f1 and 63e80dc.

📒 Files selected for processing (5)
  • src/methodology/registry.ts
  • src/methodology/tools.ts
  • src/methodology/types.ts
  • test/methodology/registry.test.ts
  • test/methodology/tools.test.ts
✅ Files skipped from review due to trivial changes (1)
  • test/methodology/tools.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • test/methodology/registry.test.ts
  • src/methodology/tools.ts
  • src/methodology/registry.ts

@ablanrob
ablanrob merged commit 481634c into main May 13, 2026
2 checks passed
@ablanrob
ablanrob deleted the feat/concept-tools branch May 13, 2026 07:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant