Repository navigation
Conversation
…ced state machine Implement workflow-definition module using @ntcoding/agentic-workflow-builder. 10-state machine (IMPLEMENTING through COMPLETE + BLOCKED) with transition guards, operation gates, bash command filtering, and event sourcing via fold. 185 tests, 100% coverage across all domain files. Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Move test fixtures to domain/fixtures/ (SoC-010: co-locate by change) - Move output-messages to infra/ (SoC-001: CLI output formatting) - Move workflow-adapter to infra/ (SoC-001: adapter pattern) - Configure vitest coverage output to test-output/ (eslint-ignored) Co-Authored-By: Claude Opus 4.6 <[email protected]>
…rage config Add 10 state instruction markdown files referenced by agentInstructions fields in state definitions. Each file provides TODO checklists and constraints for the agent when operating in that workflow state. Also fix vitest coverage output to test-output/ (eslint-ignored path). Co-Authored-By: Claude Opus 4.6 <[email protected]>
…re and CLI entrypoint Event store: SQLite persistence with better-sqlite3 for event sourcing. CLI entrypoint: 15 command handlers + hook routing (SessionStart, PreToolUse). Infra layer: composition root, environment config, git adapter, hook I/O parsing. 253 tests at 100% coverage across all metrics. Co-Authored-By: Claude Opus 4.6 <[email protected]>
… and API - Remove resolveStringField (AP-004 violation) — fail fast for missing Bash command - Move workflow-error.ts to domain/ (not infra) - Move environment.ts, stdin.ts, git.ts, hook-io.ts to infra/cli/ - Move composition-root.ts to shell/ - Move sqlite-event-store to infra/persistence/ - Move test fixtures to entrypoint/fixtures/ - Delete invalid infra/domain/ directory Co-Authored-By: Claude Opus 4.6 <[email protected]>
Remove duplicate SQLite event store — now imported from @ntcoding/agentic-workflow-builder/event-store. Removes direct better-sqlite3 dependency from this project. Co-Authored-By: Claude Opus 4.6 <[email protected]>
pnpm v10 onlyBuiltDependencies does not reliably trigger better-sqlite3's native compilation during install. Explicit rebuild ensures bindings exist for dev-workflow-v2 tests. Co-Authored-By: Claude Opus 4.6 <[email protected]>
pnpm v10 onlyBuiltDependencies does not reliably trigger better-sqlite3's native compilation during install. Explicit rebuild ensures bindings exist for dev-workflow-v2 tests. Co-Authored-By: Claude Opus 4.6 <[email protected]>
pnpm v10 onlyBuiltDependencies does not reliably trigger better-sqlite3's native compilation during install. Explicit rebuild ensures bindings exist for dev-workflow-v2 tests. Co-Authored-By: Claude Opus 4.6 <[email protected]>
Strip manufactured transition hints and state-dependent content from output-messages. Replace with a pure op-name formatter (hyphen-to-space + capitalize). Move from infra/ to domain/ since it's domain logic. Co-Authored-By: Claude Opus 4.6 <[email protected]>
…a root .claude/commands Add root .claude/commands/implement-feature.md that Claude Code discovers natively. Move agents to .claude/agents/ under the plugin dir and register via additionalDirectories. Remove v1 dev-workflow hooks from settings. Co-Authored-By: Claude Opus 4.6 <[email protected]>
Create marketplace at tools/.claude-plugin/ referencing the plugin at tools/dev-workflow-v2/. Add plugin.json, workflow command, and move agents/commands back to plugin root for proper discovery. Remove root .claude/commands/implement-feature.md in favor of plugin-namespaced /dev-workflow-v2:implement-feature. Co-Authored-By: Claude Opus 4.6 <[email protected]>
…ts to .claude-plugin/ $CLAUDE_PLUGIN_ROOT resolves to the .claude-plugin/ directory, not the plugin root. Use $CLAUDE_PLUGIN_ROOT/.. to reach the actual plugin root where src/ lives. Co-Authored-By: Claude Opus 4.6 <[email protected]>
Move marketplace.json to plugin root (.claude-plugin/), matching the reference pattern where source "./" means the plugin IS the marketplace. Add SessionStart/PreToolUse hooks for env var injection (CLAUDE_SESSION_ID, CLAUDE_PLUGIN_ROOT). Simplify workflow.md command to match reference repo. Bump plugin version to 0.0.4. After this commit, register with: /plugin marketplace add ./tools/dev-workflow-v2 /plugin install dev-workflow-v2@dev-workflow-v2-marketplace Co-Authored-By: Claude Opus 4.6 <[email protected]>
Add a top-level "riviere hello" command that outputs "hello". Co-Authored-By: Claude Opus 4.6 <[email protected]>
📝 WalkthroughWalkthroughA new dev-workflow-v2 Claude plugin is introduced with an event-sourced workflow state machine enforcing structured task lifecycle (IMPLEMENTING → VERIFYING → REVIEWING → SUBMITTING_PR → AWAITING_CI → CHECKING_FEEDBACK → ADDRESSING_FEEDBACK → REFLECTING → COMPLETE). Configuration updates enable the plugin; CLI infrastructure provides hook handlers and command dispatchers; domain model defines state definitions with guards, predicates, and event sourcing; comprehensive tests validate workflows and state transitions. Changes
Sequence Diagram(s)sequenceDiagram
participant Claude as Claude Code Hook
participant CLI as Workflow CLI
participant Engine as Workflow Engine
participant Store as Event Store (SQLite)
participant Guard as State Guard
Claude->>CLI: PreToolUse hook (tool_name, command)
CLI->>CLI: Parse hook input (session_id, tool_name, command)
CLI->>Engine: checkBashAllowed(toolName, command)
Engine->>Guard: Evaluate bash safety predicate
Guard->>Guard: Check global forbidden patterns<br/>(git push, gh pr, etc.)
alt Command Allowed
Guard-->>Engine: pass()
Engine-->>CLI: { pass: true }
CLI-->>Claude: Allow (exit 0)
else Command Blocked
Guard-->>Engine: fail(reason)
Engine->>Store: Append bash-checked event
Engine-->>CLI: { pass: false }
CLI->>CLI: Format deny decision
CLI-->>Claude: Block (exit 2) + reason
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 OpenGrep (1.16.2).claude/settings.json┌──────────────┐ �[32m✔�[39m �[1mOpengrep OSS�[0m �[1m Loading rules from local config...�[0m knip.json┌──────────────┐ �[32m✔�[39m �[1mOpengrep OSS�[0m �[1m Loading rules from local config...�[0m package.json┌──────────────┐ �[32m✔�[39m �[1mOpengrep OSS�[0m �[1m Loading rules from local config...�[0m
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. Comment |
|
There was a problem hiding this comment.
Actionable comments posted: 34
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/ci.yml:
- Around line 45-52: The CI step "Build better-sqlite3 native bindings" uses
`npx --yes prebuild-install` and `npx --yes node-gyp rebuild`, which fetches
unpinned tooling at runtime; change the step to invoke the local binaries
shipped with the better-sqlite3 package instead of npx and ensure node-gyp is
pinned: replace the commands that run inside the BS3_DIR block to call
"$BS3_DIR/node_modules/.bin/prebuild-install" (and
"$BS3_DIR/node_modules/.bin/node-gyp rebuild" if you keep the fallback), and if
you need node-gyp add it to devDependencies so its version is locked in
pnpm-lock.yaml (or remove the node-gyp fallback entirely if you only want to run
the locked prebuild-install).
In `@package.json`:
- Around line 91-94: Remove "better-sqlite3" from the root package.json
ignoredBuiltDependencies array so the workspace-level allowlist in
pnpm-workspace.yaml can control native builds; specifically edit the
ignoredBuiltDependencies block (remove the "better-sqlite3" entry), commit the
change, then re-run CI to confirm the manual native rebuild step in
.github/workflows/ci.yml (lines that perform a rebuild) is no longer required.
In `@tools/dev-workflow-v2/commands/implement-feature.md`:
- Around line 31-38: Add a new step documenting the ADDRESSING_FEEDBACK state
between CHECKING_FEEDBACK and REFLECTING: describe that when CHECKING_FEEDBACK
finds review comments you enter ADDRESSING_FEEDBACK, list the actions to take
(implement requested changes, run tests/`pnpm verify`, push commits and update
the PR), record the iteration and results, and specify transitions (loop back to
AWAITING_CI to wait for CI on new commits or proceed to REFLECTING once
reviewers are satisfied); reference the state name ADDRESSING_FEEDBACK and the
preceding/following states CHECKING_FEEDBACK, AWAITING_CI, and REFLECTING so the
flow is unambiguous.
In `@tools/dev-workflow-v2/commands/workflow.md`:
- Around line 3-5: Remove the redundant self-assignment of CLAUDE_PLUGIN_ROOT in
the command invocation: the env var CLAUDE_PLUGIN_ROOT is already expected to be
set, so invoke npx tsx with the existing
"${CLAUDE_PLUGIN_ROOT}/src/entrypoint/workflow-cli.ts" and $ARGUMENTS without
prefixing CLAUDE_PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT}"; update the example
invocation in the documentation to simply call npx tsx
"${CLAUDE_PLUGIN_ROOT}/src/entrypoint/workflow-cli.ts" $ARGUMENTS.
In `@tools/dev-workflow-v2/package.json`:
- Line 2: Update the package.json "name" property to use the
`@living-architecture` scope (e.g., change "name": "dev-workflow-v2" to the scoped
name "@living-architecture/dev-workflow-v2") so the package follows the monorepo
naming guidelines; locate and update the "name" field in the package.json file
to the new scoped value.
In `@tools/dev-workflow-v2/README.md`:
- Line 42: Update the diagram label and/or visualization to reflect that the
BLOCKED transition returns to the previously active state (not always
IMPLEMENTING); reference blocked.ts and the BLOCKED state logic and change the
label text from "returns to pre-blocked state" to something explicit like
"returns to previous state (e.g., IMPLEMENTING)" or add a note/annotation tied
to the BLOCKED arrow, or redraw the arrow to indicate it returns to the prior
state rather than only pointing to IMPLEMENTING.
In `@tools/dev-workflow-v2/src/domain/workflow-error.ts`:
- Around line 1-6: The WorkflowError constructor should capture the stack like
other errors in the codebase: after calling super(message) and setting this.name
= 'WorkflowError', invoke Error.captureStackTrace?.(this, this.constructor) to
ensure the stack trace is properly captured; use this.constructor (not the
literal class name) to match the existing pattern used across other error
classes.
In `@tools/dev-workflow-v2/src/entrypoint/fixtures/workflow-cli-test-fixtures.ts`:
- Around line 128-130: The silent return after resolving steps hides missing
fixture states; instead, detect when stateSteps[targetState] is undefined and
fail fast by throwing an explicit error (or using an assertion) that includes
the targetState value and a clear message; update the block around
runWorkflow([...], deps) / stateSteps and targetState to validate steps !==
undefined and throw (or assert) so typos or unimplemented states surface
immediately.
In `@tools/dev-workflow-v2/src/entrypoint/workflow-cli.spec.ts`:
- Around line 164-176: The tests for argument validation are running commands
from the initial CLI state so the handlers can early-reject before argument
parsing; update the failing cases (the tests titled 'record-feedback-exists' and
'record-reflection') to mirror the working pattern used in the 'record-pr' tests
by calling setup() followed by runWorkflow(['init'], deps) before invoking
runWorkflow(['record-feedback-exists', ...], deps) and
runWorkflow(['record-reflection', ...], deps) respectively (use the same
runWorkflow/init sequence as in the 'record-pr' tests to ensure the
argument-validation logic in the handlers is actually exercised).
In `@tools/dev-workflow-v2/src/infra/cli/command-handlers.ts`:
- Around line 142-153: handleRecordReviewFailed currently allows an empty
reviewers array; add validation at the start of handleRecordReviewFailed to
ensure reviewers.length > 0 and return an appropriate failure OperationResult if
none provided. Specifically, check the reviewers variable after const reviewers
= args.slice(1) and short-circuit (e.g., return a failure OperationResult or
throw a controlled error consistent with other handlers) instead of calling
engine.transaction; keep the existing call to engine.transaction(..., (w) =>
w.recordReviewFailed(reviewers)) unchanged when validation passes.
In `@tools/dev-workflow-v2/src/infra/cli/environment.spec.ts`:
- Around line 24-61: Update the negative-path tests for getSessionId,
getPluginRoot, and getEnvFilePath to also assert that empty-string ('') and
whitespace-only values (e.g., ' ') are treated as missing: set
process.env['CLAUDE_SESSION_ID'] (and likewise CLAUDE_PLUGIN_ROOT,
CLAUDE_ENV_FILE) to '' and to ' ' in separate assertions and expect each to
throw WorkflowError with the same message 'Missing required env var: <VAR_NAME>'
— keep the existing delete-case assertions, and add the two extra cases per
accessor to ensure the accessors reject effectively-missing inputs.
In `@tools/dev-workflow-v2/src/infra/cli/environment.ts`:
- Around line 4-25: The three functions getSessionId, getPluginRoot, and
getEnvFilePath currently only check for undefined but allow empty or
whitespace-only env values; update each to read the env var, trim it, and if the
trimmed value is falsy (empty string) throw the same WorkflowError ('Missing
required env var: <NAME>') so blank/whitespace values are rejected at the
boundary; ensure you return the trimmed non-empty string from each function.
In `@tools/dev-workflow-v2/src/infra/cli/hook-io.spec.ts`:
- Around line 19-75: Add tests to cover empty string and whitespace-only values
for required string fields so the parsers reject them: extend parseCommonInput
specs to pass payloads where session_id, transcript_path, cwd, and
hook_event_name are '' and ' ' and assert they throw WorkflowError with
message 'Invalid hook input for HookCommonInput'; similarly extend
parsePreToolUseInput specs to include cases where tool_name and tool_use_id (and
the common required fields) are '' and ' ' and assert they throw WorkflowError
with message 'Invalid hook input for PreToolUseInput'; keep the same
JSON-malformed assertions but add these negative cases to ensure the parsers
validate non-empty, non-whitespace strings.
In `@tools/dev-workflow-v2/src/infra/cli/hook-io.ts`:
- Around line 4-16: HOOK_COMMON_INPUT and PRE_TOOL_USE_INPUT currently allow
empty or whitespace-only strings (e.g., session_id, cwd, hook_event_name,
tool_name, tool_use_id); tighten the schemas by requiring non-empty,
non-whitespace values—replace z.string() for those fields with a
trimmed-and-minimum-length check (e.g., use z.string().trim().min(1) or an
equivalent refine) so blank or whitespace-only inputs are rejected at the hook
boundary while leaving permission_mode and tool_input behavior unchanged.
In `@tools/dev-workflow-v2/src/shell/composition-root.ts`:
- Around line 33-37: The current WorkflowDeps object sets checkPrChecks: () =>
true which unconditionally marks PR checks as passing; replace this with a real
check or a fail-closed stub so CI cannot be bypassed. Update the workflowDeps
entry (or the buildRealDeps factory that creates it) to call the actual check
function (e.g., an existing getPrChecksStatus / verifyPrChecks method) or
implement a placeholder that returns false or throws when it cannot determine CI
status; ensure the symbol names workflowDeps and checkPrChecks are used so the
runtime uses the real verifier instead of the always-true lambda.
In `@tools/dev-workflow-v2/src/workflow-definition/domain/fold.ts`:
- Around line 26-84: The applyEvent reducer currently swallows unknown
WorkflowEvent types by falling through to the final "return state"; update
applyEvent so all intentional no-op event types are handled explicitly (add case
branches that return state for known no-op events) and replace the implicit
fallback with a hard failure: after the switch throw a descriptive error
(including the event.type and any id) for unknown/unhandled events so reducer
drift is caught; keep the existing special-case call to applyTransitioned(event)
at the top and ensure the thrown error references applyEvent and WorkflowEvent
to aid locating the problem.
- Around line 4-12: EMPTY_STATE is duplicated from the adapter's INITIAL_STATE
which risks drift; change EMPTY_STATE to derive from the shared INITIAL_STATE
used by WORKFLOW_ADAPTER.initialState() (import INITIAL_STATE) instead of
repeating the literal, and ensure you clone it (e.g., shallow spread or deep
copy) so applyEvents() and rehydrated workflows share the same
initial-source-of-truth without exposing the original to mutation.
In `@tools/dev-workflow-v2/src/workflow-definition/domain/registry.ts`:
- Around line 16-21: GLOBAL_FORBIDDEN's bashPatterns only match literal bare
tokens and miss prefixed paths or args (e.g., "./git push" or "bash -lc \"git
push ...\""); update GLOBAL_FORBIDDEN.bashPatterns to match command invocations
more robustly by anchoring on word boundaries and allowing optional path
prefixes and intervening args, e.g. patterns that detect (optional ./ or / or
path components) before the command name and use \b after the subcommand (e.g.,
match (?:^|\s|&&|;|[|<>])(?:\.\/|\/|[\w\-/]+\/)?git\s+push\b and similarly for
gh\s+pr\b to catch "gh pr create" etc.), and ensure flags/arguments after the
subcommand don't prevent a match; modify the bashPatterns array in
GLOBAL_FORBIDDEN accordingly.
In
`@tools/dev-workflow-v2/src/workflow-definition/domain/states/addressing-feedback.ts`:
- Around line 14-18: transitionGuard currently blocks all transitions when
ctx.state.feedbackAddressed is false; change it so BLOCKED transitions are
exempted. Update the transitionGuard (the function that calls fail(...) /
pass()) to first check the transition/event type (e.g., ctx.event?.type or
ctx.transition name) and immediately return pass() when the transition is
'BLOCKED', otherwise keep the existing check against ctx.state.feedbackAddressed
and return fail('Feedback not addressed. Run record-feedback-addressed first.')
or pass() accordingly.
In `@tools/dev-workflow-v2/src/workflow-definition/domain/states/awaiting-ci.ts`:
- Around line 12-17: The transitionGuard currently allows moving to
'IMPLEMENTING' when ctx.state.ciPassed is unset; change the guard in
transitionGuard so transitions to 'IMPLEMENTING' are only permitted when
ctx.state.ciPassed === false (i.e., CI explicitly recorded as failed).
Concretely, update the condition that checks ctx.to === 'IMPLEMENTING' to reject
when ctx.state.ciPassed is not strictly false (ctx.state.ciPassed !== false) and
return a clear fail message instructing to run the record-ci-failed action; keep
the existing CHECKING_FEEDBACK check using ctx.state.ciPassed for the pass case.
In
`@tools/dev-workflow-v2/src/workflow-definition/domain/states/checking-feedback.ts`:
- Around line 12-17: The transitionGuard currently only blocks
ADDRESSING_FEEDBACK when ctx.state.feedbackClean === true, allowing a transition
from CHECKING_FEEDBACK to ADDRESSING_FEEDBACK when feedbackClean is unset;
update transitionGuard to require an explicit recorded flag (e.g.,
ctx.state.feedbackRecorded or test for feedbackClean !== undefined) before
permitting ADDRESSING_FEEDBACK: if the recorded flag is missing, return
fail('Feedback not recorded. Run record-feedback-first.') and only allow
ADDRESSING_FEEDBACK when feedbackRecorded === true (or when feedbackClean is
explicitly false), keeping the existing checks for REFLECTING and using the same
fail/pass helpers.
In
`@tools/dev-workflow-v2/src/workflow-definition/domain/workflow-feedback-reflecting.spec.ts`:
- Around line 185-191: The test title "rejects all transitions" is misleading
because the spec only tests COMPLETE -> IMPLEMENTING; either rename the it()
description to something like "rejects transition from COMPLETE to IMPLEMENTING"
or expand the when(...) calls to attempt transitions to every other target state
(e.g., call wf.transitionTo for each possible state after invoking
spec.given(...eventsToComplete()) and assert result.pass is false for each).
Locate the failing test around the describe('COMPLETE state') block that uses
spec.given(...eventsToComplete()) and wf.transitionTo('IMPLEMENTING') and update
the test name or add additional transition attempts accordingly.
- Around line 80-88: The test only asserts preBlockedState but must also confirm
the workflow's actual current state changed; update the spec that calls
spec.given(...eventsToCheckingFeedback()).when((wf) =>
wf.transitionTo('BLOCKED')) (and the similar specs at the other ranges) to
include an assertion that state.currentStateMachineState (from the destructured
{ result, state }) is 'BLOCKED' (e.g.,
expect(state.currentStateMachineState).toBe('BLOCKED')) so the test verifies the
transition, not just the recorded previous state.
- Around line 60-68: The test currently only asserts state.feedbackClean flipped
to false; update the spec that calls recordFeedbackExists(3) (and uses
eventsToCheckingFeedback()) to also assert the actual feedback-exists signal and
the stored count: after when(wf => wf.recordFeedbackExists(3)) add assertions
that the field which records existence (e.g., state.feedbackExists or the
appropriate property on state) is true and that the stored count property (e.g.,
state.feedbackCount or the property that holds the value) equals 3, keeping the
existing feedbackClean assertion.
In `@tools/dev-workflow-v2/src/workflow-definition/domain/workflow-predicates.ts`:
- Around line 20-33: The policy gates currently use substring checks on the raw
command (command.includes(flag) and allowed.some(cmd => command.includes(cmd))),
which leads to false positives/negatives; instead parse the command into argv
tokens (respecting quotes/escapes) and perform exact/positional checks: for
DANGEROUS_FLAGS check against parsedArgs for exact matches or canonical prefixed
forms (e.g., "--flag" or "-f" and "--flag=value"), and for
CURRENT_DEF.allowForbidden?.bash exemptions compare tokens or full parsed
command patterns (not substrings) or run regexes against joined tokens; update
the logic in the block referencing DANGEROUS_FLAGS,
GLOBAL_FORBIDDEN.bashPatterns, getStateDefinition, and
currentDef.allowForbidden?.bash to use a shell-arguments parser (or tokenizer)
and token-based matching rather than raw substring matching.
In
`@tools/dev-workflow-v2/src/workflow-definition/domain/workflow-reviewing-submitting.spec.ts`:
- Around line 214-229: Add a test that covers the "pending CI" case for the
AWAITING_CI -> IMPLEMENTING transition: use spec.given(...eventsToAwaitingCi())
without calling ciPassed() or ciFailed(), then .when(wf =>
wf.transitionTo('IMPLEMENTING')) and assert that result.pass is false and
state.currentStateMachineState remains AWAITING_CI; this ensures
transitionTo('IMPLEMENTING'), eventsToAwaitingCi(), and the spec setup are
exercised for the unset/ongoing CI case.
In `@tools/dev-workflow-v2/src/workflow-definition/domain/workflow-types.spec.ts`:
- Around line 8-10: Replace the array forEach in the test with a for...of loop
so returned values from expect aren't discarded: locate the test "it('accepts
all valid state names')" that iterates STATE_NAMES and change the iteration over
STATE_NAMES to a for (const s of STATE_NAMES) {
expect(STATE_NAME_SCHEMA.parse(s)).toStrictEqual(s) } pattern, keeping the same
assertion using STATE_NAME_SCHEMA and s.
In `@tools/dev-workflow-v2/src/workflow-definition/domain/workflow.ts`:
- Around line 249-251: The verifyIdentity method is a stub that always returns
pass() and ignores the _transcriptPath parameter; add a clear TODO comment above
the verifyIdentity function (referencing verifyIdentity, PreconditionResult,
pass(), and _transcriptPath) stating the intended work (implement identity
verification using the transcript path, validate speaker/metadata, return
appropriate PreconditionResult) and note the parameter is currently unused so it
should be wired into the implementation when addressed.
- Around line 270-284: transitionTo currently calls the
WORKFLOW_REGISTRY[targetState].onEntry and mutates this.state before appending
the 'transitioned' event, which means onEntry changes are not event-sourced and
will be lost on replay; fix by either (A) emitting explicit events for the
onEntry mutations instead of applying them inline (use this.append to push new
events representing the state changes immediately after or as part of the
transition), or (B) move the onEntry application into the fold logic so
applyTransitioned (in fold.ts) invokes WORKFLOW_REGISTRY[to].onEntry (or an
equivalent helper) when handling a 'transitioned' event so those mutations are
recreated during applyEvents/replay; update transitionTo, the append sequence,
and applyTransitioned accordingly to ensure onEntry effects are captured in the
event stream.
In `@tools/dev-workflow-v2/states/awaiting-ci.md`:
- Around line 9-12: The example for the failing CI path is missing the required
failure summary argument for the record-ci-failed command; update the second
checklist item to call `/dev-workflow-v2:workflow record-ci-failed "CI failed:
<brief-reason>"` (or similar) so the CLI receives the required output/reason,
while keeping the subsequent transition instruction to
`/dev-workflow-v2:workflow transition IMPLEMENTING` unchanged; leave the
record-ci-passed and transition CHECKING_FEEDBACK examples as-is.
In `@tools/dev-workflow-v2/states/reviewing.md`:
- Around line 12-15: Add an explicit "reviewer-error" branch before aggregating
verdicts: when waiting for agents to complete, detect crash/invalid JSON
responses and immediately call a new workflow step (e.g.,
`/dev-workflow-v2:workflow record-review-error <failed-agent-names...>` or a
retry/halt action) instead of proceeding to PASS/FAIL aggregation; update the
logic that currently emits `/dev-workflow-v2:workflow record-task-check-passed`,
`/dev-workflow-v2:workflow record-review-passed`, and `/dev-workflow-v2:workflow
record-review-failed` to first validate each agent's JSON and short-circuit to
the reviewer-error branch on parse/runner failures so the workflow halts or
retries rather than recording a partial review.
In `@tools/dev-workflow-v2/states/verifying.md`:
- Around line 8-11: The verifying state steps are out of order: when
verification fails you should immediately invoke /dev-workflow-v2:workflow
record-verify-failed and then /dev-workflow-v2:workflow transition IMPLEMENTING;
after fixing and committing, run /dev-workflow-v2:workflow transition VERIFYING
and re-run verification, and only when it passes call /dev-workflow-v2:workflow
record-verify-passed and /dev-workflow-v2:workflow transition REVIEWING. Ensure
the sequence uses record-verify-failed before transitioning to IMPLEMENTING, and
uses transition VERIFYING after commits to re-run verification.
In `@tools/dev-workflow-v2/tsconfig.json`:
- Around line 1-19: The root tsconfig.json currently contains test-only settings
(types: "vitest/globals" and test includes) so split into the three-file
pattern: keep generic build/compiler options in tsconfig.json, create
tsconfig.lib.json extending ./tsconfig.json for library build specifics
(outDir/rootDir/strict/etc.) and create tsconfig.spec.json extending
./tsconfig.json for tests; move the "types": ["vitest/globals"] entry and any
test-specific "include" globs (e.g., tests/**/*.ts or **/*.spec.ts) into
tsconfig.spec.json and remove vitest from the root "types" array so only
tsconfig.spec.json references vitest/globals, and ensure tsconfig.lib.json and
tsconfig.spec.json are referenced by package-level tooling as needed.
In `@tools/dev-workflow-v2/vitest.config.mts`:
- Around line 3-22: Add the missing root setting to the Vitest config: update
the object passed to defineConfig (the top-level export containing test,
coverage, etc.) to include root: __dirname so Vitest resolves paths consistently
under ESM; locate the exported default object (defineConfig({ ... })) and add
the root: __dirname property alongside test to match other vitest.config.mts
files in the repo.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 097a235f-3463-4046-8283-f0051f459d01
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (80)
.claude/settings.json.github/workflows/ci.ymleslint.config.mjsknip.jsonpackage.jsonpackages/riviere-cli/src/features/hello/entrypoint/hello.spec.tspackages/riviere-cli/src/features/hello/entrypoint/hello.tspackages/riviere-cli/src/shell/cli.tspnpm-workspace.yamltools/dev-workflow-v2/.claude-plugin/marketplace.jsontools/dev-workflow-v2/.claude-plugin/plugin.jsontools/dev-workflow-v2/.gitignoretools/dev-workflow-v2/CLAUDE.mdtools/dev-workflow-v2/README.mdtools/dev-workflow-v2/agents/architecture-review.mdtools/dev-workflow-v2/agents/bug-scanner.mdtools/dev-workflow-v2/agents/code-review.mdtools/dev-workflow-v2/agents/task-check.mdtools/dev-workflow-v2/commands/implement-feature.mdtools/dev-workflow-v2/commands/workflow.mdtools/dev-workflow-v2/hooks/hooks.jsontools/dev-workflow-v2/package.jsontools/dev-workflow-v2/src/domain/workflow-error.spec.tstools/dev-workflow-v2/src/domain/workflow-error.tstools/dev-workflow-v2/src/entrypoint/fixtures/workflow-cli-test-fixtures.tstools/dev-workflow-v2/src/entrypoint/workflow-cli-hooks.spec.tstools/dev-workflow-v2/src/entrypoint/workflow-cli.spec.tstools/dev-workflow-v2/src/entrypoint/workflow-cli.tstools/dev-workflow-v2/src/infra/cli/command-handlers.tstools/dev-workflow-v2/src/infra/cli/environment.spec.tstools/dev-workflow-v2/src/infra/cli/environment.tstools/dev-workflow-v2/src/infra/cli/git.tstools/dev-workflow-v2/src/infra/cli/hook-handlers.tstools/dev-workflow-v2/src/infra/cli/hook-io.spec.tstools/dev-workflow-v2/src/infra/cli/hook-io.tstools/dev-workflow-v2/src/infra/cli/operation-result.spec.tstools/dev-workflow-v2/src/infra/cli/operation-result.tstools/dev-workflow-v2/src/infra/cli/stdin.tstools/dev-workflow-v2/src/shell/composition-root.tstools/dev-workflow-v2/src/workflow-definition/domain/fixtures/workflow-test-fixtures.tstools/dev-workflow-v2/src/workflow-definition/domain/fold.spec.tstools/dev-workflow-v2/src/workflow-definition/domain/fold.tstools/dev-workflow-v2/src/workflow-definition/domain/output-messages.spec.tstools/dev-workflow-v2/src/workflow-definition/domain/output-messages.tstools/dev-workflow-v2/src/workflow-definition/domain/registry.tstools/dev-workflow-v2/src/workflow-definition/domain/states/addressing-feedback.tstools/dev-workflow-v2/src/workflow-definition/domain/states/awaiting-ci.tstools/dev-workflow-v2/src/workflow-definition/domain/states/blocked.tstools/dev-workflow-v2/src/workflow-definition/domain/states/checking-feedback.tstools/dev-workflow-v2/src/workflow-definition/domain/states/complete.tstools/dev-workflow-v2/src/workflow-definition/domain/states/implementing.tstools/dev-workflow-v2/src/workflow-definition/domain/states/reflecting.tstools/dev-workflow-v2/src/workflow-definition/domain/states/reviewing.tstools/dev-workflow-v2/src/workflow-definition/domain/states/submitting-pr.tstools/dev-workflow-v2/src/workflow-definition/domain/states/verifying.tstools/dev-workflow-v2/src/workflow-definition/domain/workflow-events.spec.tstools/dev-workflow-v2/src/workflow-definition/domain/workflow-events.tstools/dev-workflow-v2/src/workflow-definition/domain/workflow-feedback-reflecting.spec.tstools/dev-workflow-v2/src/workflow-definition/domain/workflow-hook-checks.spec.tstools/dev-workflow-v2/src/workflow-definition/domain/workflow-implementing-verifying.spec.tstools/dev-workflow-v2/src/workflow-definition/domain/workflow-predicates.tstools/dev-workflow-v2/src/workflow-definition/domain/workflow-reviewing-submitting.spec.tstools/dev-workflow-v2/src/workflow-definition/domain/workflow-types.spec.tstools/dev-workflow-v2/src/workflow-definition/domain/workflow-types.tstools/dev-workflow-v2/src/workflow-definition/domain/workflow.tstools/dev-workflow-v2/src/workflow-definition/index.tstools/dev-workflow-v2/src/workflow-definition/infra/workflow-adapter.spec.tstools/dev-workflow-v2/src/workflow-definition/infra/workflow-adapter.tstools/dev-workflow-v2/states/addressing-feedback.mdtools/dev-workflow-v2/states/awaiting-ci.mdtools/dev-workflow-v2/states/blocked.mdtools/dev-workflow-v2/states/checking-feedback.mdtools/dev-workflow-v2/states/complete.mdtools/dev-workflow-v2/states/implementing.mdtools/dev-workflow-v2/states/reflecting.mdtools/dev-workflow-v2/states/reviewing.mdtools/dev-workflow-v2/states/submitting-pr.mdtools/dev-workflow-v2/states/verifying.mdtools/dev-workflow-v2/tsconfig.jsontools/dev-workflow-v2/vitest.config.mts
| # pnpm v10 does not run better-sqlite3's install script despite onlyBuiltDependencies. | ||
| # Manually trigger prebuild-install to download prebuilt native bindings. | ||
| - name: Build better-sqlite3 native bindings | ||
| run: | | ||
| BS3_DIR=$(find node_modules/.pnpm -path "*/better-sqlite3@*/node_modules/better-sqlite3/package.json" -exec dirname {} \; | head -1) | ||
| if [ -n "$BS3_DIR" ]; then | ||
| cd "$BS3_DIR" && npx --yes prebuild-install || npx --yes node-gyp rebuild --release | ||
| fi |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Find and check the workflow file content
cat -n .github/workflows/ci.yml | sed -n '40,60p'Repository: NTCoding/living-architecture
Length of output: 1228
🏁 Script executed:
# Check root package.json for better-sqlite3 and related dependencies
cat -n package.json | head -50Repository: NTCoding/living-architecture
Length of output: 2824
🏁 Script executed:
# Look for package-lock.json or pnpm-lock.yaml to understand lockfile
ls -la | grep -E "lock|manifest"Repository: NTCoding/living-architecture
Length of output: 138
🏁 Script executed:
# Check if better-sqlite3 has prebuild-install or node-gyp as dependencies
rg "better-sqlite3" pnpm-lock.yaml -A 20 | head -60Repository: NTCoding/living-architecture
Length of output: 2983
🏁 Script executed:
# Check what dependencies better-sqlite3 declares
rg "name: better-sqlite3" pnpm-lock.yaml -A 30 | head -80Repository: NTCoding/living-architecture
Length of output: 54
🏁 Script executed:
# Search for prebuild-install and node-gyp in the lockfile
rg "prebuild-install|node-gyp" pnpm-lock.yaml | head -20Repository: NTCoding/living-architecture
Length of output: 153
🏁 Script executed:
# Look at better-sqlite3's actual dependencies in the lockfile
rg "[email protected]:" pnpm-lock.yaml -A 50 | head -100Repository: NTCoding/living-architecture
Length of output: 3459
🏁 Script executed:
# Check if prebuild-install is a dependency of better-sqlite3
rg "[email protected]:" pnpm-lock.yaml -B 5 -A 20 | head -60Repository: NTCoding/living-architecture
Length of output: 1811
🏁 Script executed:
# Search for node-gyp in lockfile and its version
rg "node-gyp" pnpm-lock.yaml | head -20Repository: NTCoding/living-architecture
Length of output: 54
🏁 Script executed:
# Check if node-gyp is available in the lockfile as a dependency anywhere
rg "node-gyp" pnpm-lock.yaml -B 3 -A 3Repository: NTCoding/living-architecture
Length of output: 54
🏁 Script executed:
# List all dependencies of better-sqlite3 to confirm what's available
rg "[email protected]:" pnpm-lock.yaml -A 3Repository: NTCoding/living-architecture
Length of output: 378
🏁 Script executed:
# Check the actual node_modules structure after install - what binaries would be available
# Let's examine what would be in BS3_DIR's node_modules
rg "prebuild-install|node-gyp" . --type=json -l 2>/dev/null | head -5Repository: NTCoding/living-architecture
Length of output: 54
🏁 Script executed:
# Search for node-gyp more broadly - it might be spelled differently or be part of a larger dependency
rg "node.gyp|node_gyp" pnpm-lock.yaml | head -20Repository: NTCoding/living-architecture
Length of output: 54
🏁 Script executed:
# Check better-sqlite3's package.json to see what it lists as dependencies/devDependencies
find . -path "*/node_modules/better-sqlite3/package.json" -o -path "*/better-sqlite3/package.json" 2>/dev/null | grep -v node_modules | head -3Repository: NTCoding/living-architecture
Length of output: 54
🏁 Script executed:
# Let's check the actual better-sqlite3 source in the repo if it exists
fd -t f "package.json" | xargs rg -l "better-sqlite3" | head -5Repository: NTCoding/living-architecture
Length of output: 119
🏁 Script executed:
# Check root package.json for node-gyp
rg "node-gyp" package.jsonRepository: NTCoding/living-architecture
Length of output: 54
🏁 Script executed:
# Check what dev dependencies are listed in package.json - search around lines 25-100
sed -n '25,100p' package.json | cat -nRepository: NTCoding/living-architecture
Length of output: 2554
🏁 Script executed:
# Check full devDependencies section to see if node-gyp is there
rg '"devDependencies"' package.json -A 80 | head -100Repository: NTCoding/living-architecture
Length of output: 2050
Avoid downloading unpinned build tooling in CI.
Line 51 uses npx --yes prebuild-install and npx --yes node-gyp rebuild, which bypass your pnpm-lock.yaml. While [email protected] is locked as a dependency of better-sqlite3, using npx --yes ignores the local copy and can download an unpinned version from npm at runtime. More critically, node-gyp is not in your lockfile at all, so this fallback will always fetch unpinned from npm, making the build non-reproducible. Use the local prebuild-install binary directly from better-sqlite3's node_modules, or add node-gyp as a dev dependency to lock its version.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/ci.yml around lines 45 - 52, The CI step "Build
better-sqlite3 native bindings" uses `npx --yes prebuild-install` and `npx --yes
node-gyp rebuild`, which fetches unpinned tooling at runtime; change the step to
invoke the local binaries shipped with the better-sqlite3 package instead of npx
and ensure node-gyp is pinned: replace the commands that run inside the BS3_DIR
block to call "$BS3_DIR/node_modules/.bin/prebuild-install" (and
"$BS3_DIR/node_modules/.bin/node-gyp rebuild" if you keep the fallback), and if
you need node-gyp add it to devDependencies so its version is locked in
pnpm-lock.yaml (or remove the node-gyp fallback entirely if you only want to run
the locked prebuild-install).
| "ignoredBuiltDependencies": [ | ||
| "@ntcoding/agentic-workflow-builder", | ||
| "better-sqlite3" | ||
| ] |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, find the key files mentioned
git ls-files | grep -E "(package\.json|pnpm-workspace\.yaml|\.github/workflows/ci\.yml)" | head -20Repository: NTCoding/living-architecture
Length of output: 525
🏁 Script executed:
# Check the package.json content around the flagged lines
fd package.json --type f | head -5Repository: NTCoding/living-architecture
Length of output: 204
🏁 Script executed:
# Get the full package.json to understand context around ignoredBuiltDependencies
fd package.json --type f -x cat -n {} \; | head -200Repository: NTCoding/living-architecture
Length of output: 7480
🏁 Script executed:
# Check for pnpm-workspace.yaml
fd "pnpm-workspace.yaml" --type fRepository: NTCoding/living-architecture
Length of output: 91
🏁 Script executed:
# Read the pnpm-workspace.yaml file
cat -n pnpm-workspace.yamlRepository: NTCoding/living-architecture
Length of output: 249
🏁 Script executed:
# Check the CI workflow for the mentioned better-sqlite3 workaround
cat -n .github/workflows/ci.yml | head -150Repository: NTCoding/living-architecture
Length of output: 5674
Remove better-sqlite3 from ignoredBuiltDependencies—it conflicts with the workspace-level onlyBuiltDependencies allowlist.
The workspace-level pnpm-workspace.yaml explicitly allows better-sqlite3 to be built, but the root package.json blocklist overrides this by ignoring it. This conflict is why CI requires a manual native binding rebuild step (lines 45–52 of .github/workflows/ci.yml). Remove better-sqlite3 from the ignored list to let the workspace allowlist control whether the native binding is built.
Suggested fix
"ignoredBuiltDependencies": [
- "@ntcoding/agentic-workflow-builder",
- "better-sqlite3"
+ "@ntcoding/agentic-workflow-builder"
]🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@package.json` around lines 91 - 94, Remove "better-sqlite3" from the root
package.json ignoredBuiltDependencies array so the workspace-level allowlist in
pnpm-workspace.yaml can control native builds; specifically edit the
ignoredBuiltDependencies block (remove the "better-sqlite3" entry), commit the
change, then re-run CI to confirm the manual native rebuild step in
.github/workflows/ci.yml (lines that perform a rebuild) is no longer required.
| 1. **IMPLEMENTING** — Read requirements, plan, implement, test, commit | ||
| 2. **VERIFYING** — Run `pnpm verify`, record result | ||
| 3. **REVIEWING** — Spawn review agents, record result | ||
| 4. **SUBMITTING_PR** — Push branch, create PR, record PR number | ||
| 5. **AWAITING_CI** — Wait for CI, record result | ||
| 6. **CHECKING_FEEDBACK** — Check PR for review comments | ||
| 7. **REFLECTING** — Write a reflection on the work | ||
| 8. **COMPLETE** — Done |
There was a problem hiding this comment.
Document the ADDRESSING_FEEDBACK state in this flow.
The sequence jumps from CHECKING_FEEDBACK to REFLECTING, but the workflow definition includes ADDRESSING_FEEDBACK when review comments exist. As written, this guide suggests the flow is done immediately after checking feedback even when there are comments to address.
Suggested doc fix
6. **CHECKING_FEEDBACK** — Check PR for review comments
-7. **REFLECTING** — Write a reflection on the work
-8. **COMPLETE** — Done
+7. **ADDRESSING_FEEDBACK** — Address review feedback when comments exist
+8. **REFLECTING** — Write a reflection on the work
+9. **COMPLETE** — Done📝 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.
| 1. **IMPLEMENTING** — Read requirements, plan, implement, test, commit | |
| 2. **VERIFYING** — Run `pnpm verify`, record result | |
| 3. **REVIEWING** — Spawn review agents, record result | |
| 4. **SUBMITTING_PR** — Push branch, create PR, record PR number | |
| 5. **AWAITING_CI** — Wait for CI, record result | |
| 6. **CHECKING_FEEDBACK** — Check PR for review comments | |
| 7. **REFLECTING** — Write a reflection on the work | |
| 8. **COMPLETE** — Done | |
| 1. **IMPLEMENTING** — Read requirements, plan, implement, test, commit | |
| 2. **VERIFYING** — Run `pnpm verify`, record result | |
| 3. **REVIEWING** — Spawn review agents, record result | |
| 4. **SUBMITTING_PR** — Push branch, create PR, record PR number | |
| 5. **AWAITING_CI** — Wait for CI, record result | |
| 6. **CHECKING_FEEDBACK** — Check PR for review comments | |
| 7. **ADDRESSING_FEEDBACK** — Address review feedback when comments exist | |
| 8. **REFLECTING** — Write a reflection on the work | |
| 9. **COMPLETE** — Done |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@tools/dev-workflow-v2/commands/implement-feature.md` around lines 31 - 38,
Add a new step documenting the ADDRESSING_FEEDBACK state between
CHECKING_FEEDBACK and REFLECTING: describe that when CHECKING_FEEDBACK finds
review comments you enter ADDRESSING_FEEDBACK, list the actions to take
(implement requested changes, run tests/`pnpm verify`, push commits and update
the PR), record the iteration and results, and specify transitions (loop back to
AWAITING_CI to wait for CI on new commits or proceed to REFLECTING once
reviewers are satisfied); reference the state name ADDRESSING_FEEDBACK and the
preceding/following states CHECKING_FEEDBACK, AWAITING_CI, and REFLECTING so the
flow is unambiguous.
| ```bash | ||
| CLAUDE_PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT}" npx tsx "${CLAUDE_PLUGIN_ROOT}/src/entrypoint/workflow-cli.ts" $ARGUMENTS | ||
| ``` |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Redundant environment variable assignment.
The CLAUDE_PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT}" assignment is self-referential and redundant. If the variable is already set in the environment, it doesn't need to be re-exported with the same value.
♻️ Proposed simplification
```bash
-CLAUDE_PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT}" npx tsx "${CLAUDE_PLUGIN_ROOT}/src/entrypoint/workflow-cli.ts" $ARGUMENTS
+npx tsx "${CLAUDE_PLUGIN_ROOT}/src/entrypoint/workflow-cli.ts" $ARGUMENTS
</details>
<!-- suggestion_start -->
<details>
<summary>📝 Committable suggestion</summary>
> ‼️ **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.
```suggestion
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@tools/dev-workflow-v2/commands/workflow.md` around lines 3 - 5, Remove the
redundant self-assignment of CLAUDE_PLUGIN_ROOT in the command invocation: the
env var CLAUDE_PLUGIN_ROOT is already expected to be set, so invoke npx tsx with
the existing "${CLAUDE_PLUGIN_ROOT}/src/entrypoint/workflow-cli.ts" and
$ARGUMENTS without prefixing CLAUDE_PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT}"; update
the example invocation in the documentation to simply call npx tsx
"${CLAUDE_PLUGIN_ROOT}/src/entrypoint/workflow-cli.ts" $ARGUMENTS.
| @@ -0,0 +1,21 @@ | |||
| { | |||
| "name": "dev-workflow-v2", | |||
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Package name should use @living-architecture scope.
The coding guidelines specify using @living-architecture scoped package names for new projects in this monorepo.
♻️ Proposed fix
- "name": "dev-workflow-v2",
+ "name": "@living-architecture/dev-workflow-v2",As per coding guidelines: "Update package.json with correct @living-architecture scoped name when creating new projects"
📝 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.
| "name": "dev-workflow-v2", | |
| "name": "@living-architecture/dev-workflow-v2", |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@tools/dev-workflow-v2/package.json` at line 2, Update the package.json "name"
property to use the `@living-architecture` scope (e.g., change "name":
"dev-workflow-v2" to the scoped name "@living-architecture/dev-workflow-v2") so
the package follows the monorepo naming guidelines; locate and update the "name"
field in the package.json file to the new scoped value.
| - [ ] If CI passes: `/dev-workflow-v2:workflow record-ci-passed` | ||
| - [ ] If CI fails: `/dev-workflow-v2:workflow record-ci-failed` | ||
| - [ ] If passed — transition to CHECKING_FEEDBACK: `/dev-workflow-v2:workflow transition CHECKING_FEEDBACK` | ||
| - [ ] If failed — transition back to IMPLEMENTING to fix: `/dev-workflow-v2:workflow transition IMPLEMENTING` |
There was a problem hiding this comment.
Include the required failure summary in the record-ci-failed example.
The CLI contract here requires an output/reason argument for record-ci-failed. As written, this step will error before the user can follow the transition instruction.
Suggested doc fix
-- [ ] If CI fails: `/dev-workflow-v2:workflow record-ci-failed`
+- [ ] If CI fails: `/dev-workflow-v2:workflow record-ci-failed <FAILURE_SUMMARY>`📝 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.
| - [ ] If CI passes: `/dev-workflow-v2:workflow record-ci-passed` | |
| - [ ] If CI fails: `/dev-workflow-v2:workflow record-ci-failed` | |
| - [ ] If passed — transition to CHECKING_FEEDBACK: `/dev-workflow-v2:workflow transition CHECKING_FEEDBACK` | |
| - [ ] If failed — transition back to IMPLEMENTING to fix: `/dev-workflow-v2:workflow transition IMPLEMENTING` | |
| - [ ] If CI passes: `/dev-workflow-v2:workflow record-ci-passed` | |
| - [ ] If CI fails: `/dev-workflow-v2:workflow record-ci-failed <FAILURE_SUMMARY>` | |
| - [ ] If passed — transition to CHECKING_FEEDBACK: `/dev-workflow-v2:workflow transition CHECKING_FEEDBACK` | |
| - [ ] If failed — transition back to IMPLEMENTING to fix: `/dev-workflow-v2:workflow transition IMPLEMENTING` |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@tools/dev-workflow-v2/states/awaiting-ci.md` around lines 9 - 12, The example
for the failing CI path is missing the required failure summary argument for the
record-ci-failed command; update the second checklist item to call
`/dev-workflow-v2:workflow record-ci-failed "CI failed: <brief-reason>"` (or
similar) so the CLI receives the required output/reason, while keeping the
subsequent transition instruction to `/dev-workflow-v2:workflow transition
IMPLEMENTING` unchanged; leave the record-ci-passed and transition
CHECKING_FEEDBACK examples as-is.
| - [ ] Wait for all agents to complete and parse each agent's JSON verdict | ||
| - [ ] If task-check returned PASS: `/dev-workflow-v2:workflow record-task-check-passed` | ||
| - [ ] If **all** agents returned PASS: `/dev-workflow-v2:workflow record-review-passed` | ||
| - [ ] If **any** agent returned FAIL: `/dev-workflow-v2:workflow record-review-failed <failed-agent-names...>` |
There was a problem hiding this comment.
Add an explicit reviewer-error branch before verdict aggregation.
These steps only describe PASS/FAIL JSON verdicts. If an agent crashes or returns invalid JSON, the workflow has no instruction to halt, retry, or block, which can leave you recording a partial review result. Based on learnings, reviewer execution should halt immediately if any reviewer fails rather than continue with partial results.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@tools/dev-workflow-v2/states/reviewing.md` around lines 12 - 15, Add an
explicit "reviewer-error" branch before aggregating verdicts: when waiting for
agents to complete, detect crash/invalid JSON responses and immediately call a
new workflow step (e.g., `/dev-workflow-v2:workflow record-review-error
<failed-agent-names...>` or a retry/halt action) instead of proceeding to
PASS/FAIL aggregation; update the logic that currently emits
`/dev-workflow-v2:workflow record-task-check-passed`, `/dev-workflow-v2:workflow
record-review-passed`, and `/dev-workflow-v2:workflow record-review-failed` to
first validate each agent's JSON and short-circuit to the reviewer-error branch
on parse/runner failures so the workflow halts or retries rather than recording
a partial review.
| - [ ] If verify passes: `/dev-workflow-v2:workflow record-verify-passed` | ||
| - [ ] If verify fails: fix the errors, commit, then `/dev-workflow-v2:workflow record-verify-failed` | ||
| - [ ] If passed — transition to REVIEWING: `/dev-workflow-v2:workflow transition REVIEWING` | ||
| - [ ] If failed — transition back to IMPLEMENTING: `/dev-workflow-v2:workflow transition IMPLEMENTING` |
There was a problem hiding this comment.
Workflow instruction is logically inconsistent.
Line 9 states: "If verify fails: fix the errors, commit, then /dev-workflow-v2:workflow record-verify-failed"
This is backwards. If you fix the errors and commit, you should re-run verify (expecting it to pass), not record a failure. The correct workflow should be:
- If verify fails → record-verify-failed
- Transition to IMPLEMENTING
- Fix errors and commit
- Transition back to VERIFYING
- Re-run verify
📝 Proposed fix
- [ ] Run `pnpm verify` to execute lint, build, typecheck, test, and knip across the monorepo
- [ ] If verify passes: `/dev-workflow-v2:workflow record-verify-passed`
-- [ ] If verify fails: fix the errors, commit, then `/dev-workflow-v2:workflow record-verify-failed`
+- [ ] If verify fails: `/dev-workflow-v2:workflow record-verify-failed`
- [ ] If passed — transition to REVIEWING: `/dev-workflow-v2:workflow transition REVIEWING`
- [ ] If failed — transition back to IMPLEMENTING: `/dev-workflow-v2:workflow transition IMPLEMENTING`📝 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.
| - [ ] If verify passes: `/dev-workflow-v2:workflow record-verify-passed` | |
| - [ ] If verify fails: fix the errors, commit, then `/dev-workflow-v2:workflow record-verify-failed` | |
| - [ ] If passed — transition to REVIEWING: `/dev-workflow-v2:workflow transition REVIEWING` | |
| - [ ] If failed — transition back to IMPLEMENTING: `/dev-workflow-v2:workflow transition IMPLEMENTING` | |
| - [ ] If verify passes: `/dev-workflow-v2:workflow record-verify-passed` | |
| - [ ] If verify fails: `/dev-workflow-v2:workflow record-verify-failed` | |
| - [ ] If passed — transition to REVIEWING: `/dev-workflow-v2:workflow transition REVIEWING` | |
| - [ ] If failed — transition back to IMPLEMENTING: `/dev-workflow-v2:workflow transition IMPLEMENTING` |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@tools/dev-workflow-v2/states/verifying.md` around lines 8 - 11, The verifying
state steps are out of order: when verification fails you should immediately
invoke /dev-workflow-v2:workflow record-verify-failed and then
/dev-workflow-v2:workflow transition IMPLEMENTING; after fixing and committing,
run /dev-workflow-v2:workflow transition VERIFYING and re-run verification, and
only when it passes call /dev-workflow-v2:workflow record-verify-passed and
/dev-workflow-v2:workflow transition REVIEWING. Ensure the sequence uses
record-verify-failed before transitioning to IMPLEMENTING, and uses transition
VERIFYING after commits to re-run verification.
| { | ||
| "compilerOptions": { | ||
| "target": "ES2022", | ||
| "module": "ESNext", | ||
| "moduleResolution": "bundler", | ||
| "strict": true, | ||
| "noUncheckedIndexedAccess": true, | ||
| "exactOptionalPropertyTypes": true, | ||
| "verbatimModuleSyntax": true, | ||
| "outDir": "dist", | ||
| "rootDir": "src", | ||
| "esModuleInterop": true, | ||
| "skipLibCheck": true, | ||
| "resolveJsonModule": true, | ||
| "types": ["vitest/globals", "node"] | ||
| }, | ||
| "include": ["src/**/*"], | ||
| "exclude": ["node_modules", "dist"] | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if other tools packages follow the 3-file tsconfig pattern
fd -t f 'tsconfig*.json' tools/ --exec basename {} \; | sort | uniq -c | sort -rn | head -10Repository: NTCoding/living-architecture
Length of output: 93
🏁 Script executed:
# Check if test files exist in this project
find tools/dev-workflow-v2 -type f \( -name "*.test.ts" -o -name "*.spec.ts" -o -name "vitest.config.ts" \)Repository: NTCoding/living-architecture
Length of output: 1147
🏁 Script executed:
# Check tsconfig structure in other packages to see if 3-file pattern is used elsewhere
fd -t f 'tsconfig' packages/ -exec dirname {} \; | sort | uniq -c | sort -rn | head -20Repository: NTCoding/living-architecture
Length of output: 222
🏁 Script executed:
# List all tsconfig files with their full paths to understand the pattern
fd -t f 'tsconfig.*\.json$' --max-depth 3 | head -20Repository: NTCoding/living-architecture
Length of output: 837
🏁 Script executed:
# Check the CLAUDE.md file for the exact requirement
cat CLAUDE.md | grep -A 10 -B 5 "tsconfig"Repository: NTCoding/living-architecture
Length of output: 3033
Split tsconfig.json into 3-file structure (tsconfig.json, tsconfig.lib.json, tsconfig.spec.json).
This project has 15+ test files and must follow the established pattern. All packages in the repo use this 3-file structure to separate library and test concerns. Currently vitest/globals is in the root config when it belongs only in tsconfig.spec.json. Move it there along with test-specific includes and types.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@tools/dev-workflow-v2/tsconfig.json` around lines 1 - 19, The root
tsconfig.json currently contains test-only settings (types: "vitest/globals" and
test includes) so split into the three-file pattern: keep generic build/compiler
options in tsconfig.json, create tsconfig.lib.json extending ./tsconfig.json for
library build specifics (outDir/rootDir/strict/etc.) and create
tsconfig.spec.json extending ./tsconfig.json for tests; move the "types":
["vitest/globals"] entry and any test-specific "include" globs (e.g.,
tests/**/*.ts or **/*.spec.ts) into tsconfig.spec.json and remove vitest from
the root "types" array so only tsconfig.spec.json references vitest/globals, and
ensure tsconfig.lib.json and tsconfig.spec.json are referenced by package-level
tooling as needed.
| export default defineConfig({ | ||
| test: { | ||
| globals: true, | ||
| coverage: { | ||
| reportsDirectory: './test-output/vitest/coverage', | ||
| provider: 'v8', | ||
| include: ['src/**/*.ts'], | ||
| exclude: [ | ||
| 'src/**/*.spec.ts', | ||
| 'src/**/*-test-fixtures.ts', | ||
| ], | ||
| thresholds: { | ||
| lines: 100, | ||
| statements: 100, | ||
| functions: 100, | ||
| branches: 100, | ||
| }, | ||
| }, | ||
| }, | ||
| }) |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Consider adding root: __dirname for consistency.
Per repository conventions for Vitest ESM configs, other vitest.config.mts files in this repo use root: __dirname to ensure consistent path resolution. Vitest's ESM loader exposes __dirname, so no workaround is needed.
♻️ Suggested improvement
export default defineConfig({
test: {
+ root: __dirname,
globals: true,
coverage: {Based on learnings: "In Vitest config files written as ESM (e.g., vitest.config.mts), use root: __dirname directly."
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export default defineConfig({ | |
| test: { | |
| globals: true, | |
| coverage: { | |
| reportsDirectory: './test-output/vitest/coverage', | |
| provider: 'v8', | |
| include: ['src/**/*.ts'], | |
| exclude: [ | |
| 'src/**/*.spec.ts', | |
| 'src/**/*-test-fixtures.ts', | |
| ], | |
| thresholds: { | |
| lines: 100, | |
| statements: 100, | |
| functions: 100, | |
| branches: 100, | |
| }, | |
| }, | |
| }, | |
| }) | |
| export default defineConfig({ | |
| root: __dirname, | |
| test: { | |
| globals: true, | |
| coverage: { | |
| reportsDirectory: './test-output/vitest/coverage', | |
| provider: 'v8', | |
| include: ['src/**/*.ts'], | |
| exclude: [ | |
| 'src/**/*.spec.ts', | |
| 'src/**/*-test-fixtures.ts', | |
| ], | |
| thresholds: { | |
| lines: 100, | |
| statements: 100, | |
| functions: 100, | |
| branches: 100, | |
| }, | |
| }, | |
| }, | |
| }) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@tools/dev-workflow-v2/vitest.config.mts` around lines 3 - 22, Add the missing
root setting to the Vitest config: update the object passed to defineConfig (the
top-level export containing test, coverage, etc.) to include root: __dirname so
Vitest resolves paths consistently under ESM; locate the exported default object
(defineConfig({ ... })) and add the root: __dirname property alongside test to
match other vitest.config.mts files in the repo.



Summary
riviere hellocommand that outputs "hello"features/hello/with entrypoint and testsTest plan
pnpm verifypasses (lint, build, typecheck, test, knip)🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Tests