Skip to content

perf: drop zod from settings hot path (~38% faster) + unblock auto daily release#41

Merged
unbraind merged 2 commits into
mainfrom
perf/drop-zod-settings-hot-path
May 22, 2026
Merged

perf: drop zod from settings hot path (~38% faster) + unblock auto daily release#41
unbraind merged 2 commits into
mainfrom
perf/drop-zod-settings-hot-path

Conversation

@unbraind
Copy link
Copy Markdown
Owner

@unbraind unbraind commented May 22, 2026

Summary

A focused, high-confidence pass from a full manual audit (4 parallel sub-agents: code-quality, CI/CD, Sentry+telemetry, dogfood). Two shipped changes; the rest of the audit is documented as pm items for follow-up so this PR stays small and reviewable.

1. Performance — remove zod from the settings hot path

settings.ts is read by nearly every command (list/get/search/context/create/update). It imported zod eagerly and built schemas at module load. Profiling showed zod's import alone was ~85ms — the single largest CLI startup cost — and it was used in exactly one file.

Replaced with a dependency-free validator (src/core/store/settings-validator.ts) that mirrors the previous safeParse semantics exactly: type checks, required/optional fields, integer/positive constraints, literal unions, unknown-key stripping, and all-or-nothing failure. The read path also no longer validates twice (mergeSettings now takes the already-validated input).

before after
settings.ts import 157ms 14ms
pm --help 227ms 140ms
pm list 540ms 340ms (~38%)

One fewer runtime dependency (zod + transitive undici removed). New validator at 100% coverage.

2. Unblock the auto daily release

Diagnosed why the merged crash fixes (Sentry PM-CLI-R/S/T, PRs #39/#40) were stranded on 2026.5.18 for days even though they were on main: the daily auto-release silently no-ops with reason=changelog_unreleased_empty because those PRs never added CHANGELOG entries. Populated CHANGELOG.md [Unreleased] so the next scheduled auto-release ships them. No manual version bump (date-based automation handles versioning).

Audit findings filed as pm items (under pm-rnpb)

pm-e1va config-driven custom item types · pm-ot8r auto-release empty-changelog robustness · pm-kyd6 --blocked-bydeps edge · pm-1nht validate ok:false on warn-only + token-heavy ID dumps · pm-6blp plan materialize dependency cycle + flag UX · pm-uzmf calendar ergonomics · pm-why9 code dedup. Larger efforts kept as existing items: pm-7rlp (in-process test runner — 745 CLI spawns produce 0 coverage and ~2/3 of test CPU), pm-mbdu (large-file splits), pm-gt82 (esbuild bundle + item-store read index).

Test plan

  • node scripts/run-tests.mjs coverage1431 tests pass, 100% coverage (lines/branches/functions/statements)
  • pnpm typecheck (app + packages) ✅ · pnpm quality:static ✅ · pnpm quality:docs-skills ✅ · pnpm security:scan
  • Behavior parity for settings validation is locked in by the existing settings-store.spec.ts suite plus the new settings-validator.spec.ts (every combinator branch).

🤖 Generated with Claude Code

Summary by Sourcery

Replace zod-based settings validation with a lightweight internal validator and update release metadata to ship previously merged crash fixes.

New Features:

  • Introduce a dependency-free settings validator that mirrors the legacy schema semantics for settings.json.

Bug Fixes:

  • Document previously merged CLI crash fixes in the changelog so they are included in the next automated release.

Enhancements:

  • Streamline settings merging to consume already-validated settings data, avoiding duplicate validation work.

Build:

  • Remove the zod runtime dependency from the project.

Tests:

  • Add focused unit tests for the new settings validator and include it in coverage instrumentation.

Chores:

  • Record follow-up technical and product work as new internal agent items, chores, issues, and history entries.

Removes the eagerly-imported `zod` dependency from settings.ts, which is read
by nearly every command (list/get/search/context/create/update). zod (~85ms to
import) was the single largest CLI startup cost and was used in exactly one
file. It is replaced by a dependency-free validator
(src/core/store/settings-validator.ts) that mirrors the previous schema's
safeParse semantics exactly: type checks, required/optional fields,
integer/positive constraints, literal unions, unknown-key stripping, and
all-or-nothing failure. The read path no longer validates twice (mergeSettings
now takes the already-validated input).

Measured on the maintainer machine:
  settings module import  157ms -> 14ms
  pm --help               227ms -> 140ms
  pm list                 540ms -> 340ms  (~38% faster)
One fewer runtime dependency (zod + transitive undici removed).

The new validator is at 100% coverage (tests/unit/settings-validator.spec.ts)
and is added to the vitest coverage include list.

Also populates CHANGELOG [Unreleased]: the daily auto-release was silently
no-op'ing (run-release-pipeline reason=changelog_unreleased_empty) because the
merged crash fixes (Sentry PM-CLI-R/S/T, PRs #39/#40) never added changelog
entries, stranding them on 2026.5.18. Populating [Unreleased] lets the next
scheduled release ship them. No manual version bump (date-based auto-release).

Documents 7 new audit findings as pm items under pm-rnpb: pm-e1va
(config-driven custom types), pm-ot8r (auto-release empty-changelog
robustness), pm-kyd6 (--blocked-by deps edge), pm-1nht (validate ok:false on
warn), pm-6blp (plan materialize cycle + flag UX), pm-uzmf (calendar
ergonomics), pm-why9 (code dedup).

Gates: 1431 tests pass, 100% coverage, typecheck/static/docs-skills/secrets green.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented May 22, 2026

Reviewer's Guide

Replaces the zod-based settings schema with a custom, dependency-free validator on the settings hot path, adjusts settings reading to use the new ParsedSettings type without double-validation, updates tests and coverage to lock in parity, removes zod from runtime dependencies, and adds CHANGELOG entries plus internal agent PM items to unblock and document daily auto-release behavior.

Sequence diagram for the optimized settings read path

sequenceDiagram
  participant CLI as CLICommand
  participant Settings as settings_ts
  participant Validator as settings_validator

  CLI->>Settings: readSettingsWithMetadata(pmRoot)
  Settings->>Settings: readFile(settings.json)
  Settings->>Settings: JSON.parse(contents)
  Settings->>Validator: validateSettings(parsed)
  alt [validated.success]
    Validator-->>Settings: { success: true, data: ParsedSettings }
    Settings->>Settings: mergeSettings(ParsedSettings)
    Settings-->>CLI: SettingsReadResult(success)
  else [!validated.success]
    Validator-->>Settings: { success: false }
    Settings->>Settings: buildFallbackSettingsReadResult("settings_read_invalid_schema")
    Settings-->>CLI: SettingsReadResult(fallback)
  end
Loading

File-Level Changes

Change Details Files
Replaced zod schema-based settings validation with a custom dependency-free validator and integrated it into the settings read/merge path.
  • Implemented a settings-validator module that replicates the previous zod schema semantics (type checks, literal unions, integer/positive constraints, unknown-key stripping, all-or-nothing failure) and returns a ParsedSettings structure.
  • Changed readSettingsWithMetadata to validate settings.json via validateSettings, preserving existing fallback error codes on failure.
  • Updated mergeSettings to consume an already-validated ParsedSettings object, avoiding redundant schema validation on the read path.
  • Ensured vitest coverage treats the new validator as a covered file.
src/core/store/settings-validator.ts
src/core/store/settings.ts
vitest.config.ts
Added focused unit tests to prove parity of the new validator with the old zod behavior.
  • Created a minimal-valid-settings factory used across tests to mirror the required schema surface.
  • Added tests for required/optional fields, number constraints (int/positive/NaN), literal unions, array element validation, nested objects, and unknown-key stripping semantics.
  • Verified extension policy overrides and nested schema roles enforce the same failure behavior as the previous zod-based implementation.
tests/unit/settings-validator.spec.ts
Removed zod from runtime dependencies and updated lockfile to reflect the new dependency graph.
  • Dropped zod from package.json dependencies, leaving fast-json-patch as the remaining dependency in that block.
  • Updated pnpm-lock.yaml to remove zod and its transitive dependencies (e.g., undici) from the install graph.
package.json
pnpm-lock.yaml
Documented the fixes and performance changes in the changelog and wired up internal PM/agent artifacts to unblock the daily auto-release.
  • Populated the [Unreleased] section of CHANGELOG.md with the recent crash fixes and the performance improvement description, ensuring the auto daily release no longer no-ops on an empty unreleased section.
  • Added or updated internal .agents artifacts (features/issues/chores/history) that capture audit findings and follow-up work items for future changes.
CHANGELOG.md
.agents/pm/features/pm-gt82.toon
.agents/pm/features/pm-rnpb.toon
.agents/pm/history/pm-gt82.jsonl
.agents/pm/history/pm-rnpb.jsonl
.agents/pm/chores/pm-1nht.toon
.agents/pm/chores/pm-uzmf.toon
.agents/pm/chores/pm-why9.toon
.agents/pm/features/pm-e1va.toon
.agents/pm/history/pm-1nht.jsonl
.agents/pm/history/pm-6blp.jsonl
.agents/pm/history/pm-e1va.jsonl
.agents/pm/history/pm-kyd6.jsonl
.agents/pm/history/pm-ot8r.jsonl
.agents/pm/history/pm-uzmf.jsonl
.agents/pm/history/pm-why9.jsonl
.agents/pm/issues/pm-6blp.toon
.agents/pm/issues/pm-kyd6.toon
.agents/pm/issues/pm-ot8r.toon

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 22, 2026

Review Change Stack

Warning

Rate limit exceeded

@unbraind has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 19 minutes and 29 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 47121c9b-4b42-4609-aef9-a5a42ef09a9e

📥 Commits

Reviewing files that changed from the base of the PR and between 6946773 and 1f849cd.

📒 Files selected for processing (4)
  • .agents/pm/features/pm-gt82.toon
  • .agents/pm/history/pm-gt82.jsonl
  • src/core/store/settings-validator.ts
  • tests/unit/settings-validator.spec.ts
📝 Walkthrough

Walkthrough

This PR removes the zod dependency from the settings validation hot path by implementing a dependency-free validator, updates the settings pipeline to use it, adds comprehensive tests, and records multiple PM tracking items documenting work and planning items.

Changes

Settings Validator Implementation

Layer / File(s) Summary
Validator contract and core implementation
src/core/store/settings-validator.ts
ParsedSettings interface and SettingsValidationResult type define the validation contract. Core checker primitives (string, boolean, number with constraints, literal unions, arrays, optionals) are composed into nested schema validators for all settings sub-objects, with unknown-key stripping and omission of absent optionals.
Settings.ts integration and zod removal
src/core/store/settings.ts
Import validateSettings and ParsedSettings from the new validator module. Remove the large inline zod schema declarations. Update mergeSettings to accept pre-validated ParsedSettings and readSettingsWithMetadata to call validateSettings(parsed) instead of settingsSchema.safeParse.
Test suite for validator
tests/unit/settings-validator.spec.ts
Define minimalValidSettings() helper and assert validator behavior across success paths (unknown-key stripping, optional-field omission) and failure modes (non-object, missing required fields, type mismatches, NaN/positive constraints, literal unions, nested object shapes, and missing nested required fields).
Dependency removal and build configuration
package.json, vitest.config.ts
Remove zod from dependencies. Add src/core/store/settings-validator.ts to vitest coverage include list.
Changelog documentation
CHANGELOG.md
Document [Unreleased] crash fixes (status-filter normalization, search corpus array tolerance, command option guards, calendar date stability), changed behavior (zod hot-path removal, status auto-routing, semantic search fallback, token efficiency improvements), and additions (pm create positional form, close-via-update routing).

PM Planning and Tracking

Layer / File(s) Summary
PM chores, features, issues, and history entries
.agents/pm/chores/*, .agents/pm/features/*, .agents/pm/issues/*, .agents/pm/history/*
Add new chore records (pm-1nht validation semantics, pm-uzmf calendar event edge cases, pm-why9 refactor deduplication), new feature tracking (pm-e1va custom type schema registration, pm-gt82 startup progress update, pm-rnpb audit and learning entries), new issue records (pm-6blp plan materialize bugs, pm-kyd6 blocked-by graph mismatch, pm-ot8r silent release pipeline skip), and corresponding JSONL history entries documenting creation timestamps and progress notes.

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the two main changes: removing zod from the settings hot path (with measured performance gain) and unblocking the auto daily release.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, detailing the performance optimization, auto-release fix, test results, and filed follow-up items.
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.


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.

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • The literal unions and nested shape definitions in settings-validator.ts duplicate several existing domain concepts (e.g., status roles, governance presets); consider deriving these from shared enums/types or constants so the validator can't silently diverge from the rest of the codebase when settings evolve.
  • The generic Check/Outcome helpers in settings-validator.ts currently use unknown; you could make them generic (e.g. Check<T>, Outcome<T>) to get stronger type inference through the composed validators and reduce casting at the end of validateSettings.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The literal unions and nested shape definitions in `settings-validator.ts` duplicate several existing domain concepts (e.g., status roles, governance presets); consider deriving these from shared enums/types or constants so the validator can't silently diverge from the rest of the codebase when settings evolve.
- The generic `Check`/`Outcome` helpers in `settings-validator.ts` currently use `unknown`; you could make them generic (e.g. `Check<T>`, `Outcome<T>`) to get stronger type inference through the composed validators and reduce casting at the end of `validateSettings`.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 22, 2026

Note

Docstrings generation - SUCCESS
Generated docstrings for this pull request at #42

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request significantly improves CLI startup performance by removing the zod dependency from the settings hot path and replacing it with a custom, dependency-free validator. This change reduces settings import time from ~157ms to ~14ms, resulting in approximately 38% faster execution for all commands. The PR also includes several crash fixes related to undefined tokens and missing arrays in search/context commands, updates the CHANGELOG, and adds multiple new project management items (chores, features, and issues). Feedback was provided to enhance the number validator by ensuring input values are finite.

Comment thread src/core/store/settings-validator.ts Outdated
Comment on lines +107 to +120
function vNumber(options: { int?: boolean; positive?: boolean } = {}): Check {
return (input) => {
if (typeof input !== "number" || Number.isNaN(input)) {
return FAIL;
}
if (options.int && !Number.isInteger(input)) {
return FAIL;
}
if (options.positive && input <= 0) {
return FAIL;
}
return { ok: true, value: input };
};
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The vNumber validator currently allows Infinity and -Infinity when int is not set to true. While this mirrors the default behavior of zod, it might be safer to enforce finite numbers for settings fields like score_threshold or hybrid_semantic_weight to prevent unexpected application behavior. Consider using Number.isFinite(input) if strict finiteness is desired.

Suggested change
function vNumber(options: { int?: boolean; positive?: boolean } = {}): Check {
return (input) => {
if (typeof input !== "number" || Number.isNaN(input)) {
return FAIL;
}
if (options.int && !Number.isInteger(input)) {
return FAIL;
}
if (options.positive && input <= 0) {
return FAIL;
}
return { ok: true, value: input };
};
}
function vNumber(options: { int?: boolean; positive?: boolean } = {}): Check {
return (input) => {
if (typeof input !== "number" || !Number.isFinite(input)) {
return FAIL;
}
if (options.int && !Number.isInteger(input)) {
return FAIL;
}
if (options.positive && input <= 0) {
return FAIL;
}
return { ok: true, value: input };
};
}

coderabbitai Bot added a commit that referenced this pull request May 22, 2026
Docstrings generation was requested by @unbraind.

* #41 (comment)

The following files were modified:

* `src/core/store/settings-validator.ts`
* `src/core/store/settings.ts`
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (5)
.agents/pm/issues/pm-kyd6.toon (1)

1-13: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Coding guideline violation: .agents/pm files should not be edited directly.

This file is being added under .agents/pm/, but the coding guidelines explicitly state: "pm is the system of record. Do not edit .agents/pm files directly." These files should be generated through the pm system's workflow rather than committed directly in a PR.

As per coding guidelines: .agents/pm/**: pm is the system of record. Do not edit .agents/pm files directly.

🤖 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 @.agents/pm/issues/pm-kyd6.toon around lines 1 - 13, This change adds a
generated agent file under .agents/pm (id: pm-kyd6) which violates the guideline
"pm is the system of record. Do not edit .agents/pm files directly"; remove the
direct file edit and instead regenerate the issue through the pm system/workflow
that creates pm agent artifacts (or move any manual content to the canonical
source that pm uses), ensuring the pm workflow produces the pm-kyd6 issue entry
so repository changes do not directly modify .agents/pm files.
.agents/pm/issues/pm-ot8r.toon (1)

1-13: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Coding guideline violation: .agents/pm files should not be edited directly.

This file is being added under .agents/pm/, but the coding guidelines explicitly state: "pm is the system of record. Do not edit .agents/pm files directly." These files should be generated through the pm system's workflow rather than committed directly in a PR.

As per coding guidelines: .agents/pm/**: pm is the system of record. Do not edit .agents/pm files directly.

🤖 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 @.agents/pm/issues/pm-ot8r.toon around lines 1 - 13, This new .agents/pm
issue file (id: pm-ot8r, title: "Auto daily release silently skips releasable
commits...") violates the guideline that `.agents/pm/**` must not be edited
directly; remove the added file from the PR and instead create the issue through
the pm system workflow (or regenerate it via the pm tool) so the pm repository
remains the system-of-record; reference the same metadata (id pm-ot8r and title)
when recreating the issue via the proper pm interface and ensure any remediation
(warning behavior change or changelog auto-generation) is implemented in the
application code or via a properly authored pm issue rather than committing
under `.agents/pm/`.
.agents/pm/history/pm-uzmf.jsonl (1)

1-2: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Coding guideline violation: .agents/pm files should not be edited directly.

This file is being added under .agents/pm/, but the coding guidelines explicitly state: "pm is the system of record. Do not edit .agents/pm files directly." These files should be generated through the pm system's workflow rather than committed directly in a PR.

As per coding guidelines: .agents/pm/**: pm is the system of record. Do not edit .agents/pm files directly.

🤖 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 @.agents/pm/history/pm-uzmf.jsonl around lines 1 - 2, This new .agents/pm
JSON entry (metadata.id "pm-uzmf", metadata.title "Calendar agent ergonomics:
equal start/end rejected; schedule-less Event items invisible") was added
directly to .agents/pm which violates the rule that pm is the system of record;
remove or revert this direct change from the PR and instead create/update the
item through the pm system workflow (or the official CLI/API) so the file is
generated correctly; if you need to keep the content for reference, move it
outside .agents/pm (e.g., a draft in docs/ or tmp/) and then submit the
canonical change via the pm tooling.
.agents/pm/issues/pm-6blp.toon (1)

1-13: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Coding guideline violation: .agents/pm files should not be edited directly.

This file is being added under .agents/pm/, but the coding guidelines explicitly state: "pm is the system of record. Do not edit .agents/pm files directly." These files should be generated through the pm system's workflow rather than committed directly in a PR.

As per coding guidelines: .agents/pm/**: pm is the system of record. Do not edit .agents/pm files directly.

🤖 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 @.agents/pm/issues/pm-6blp.toon around lines 1 - 13, The new entry with id
"pm-6blp" (title "pm plan: materialize creates dependency cycle;
decision/discovery/validation flag mismatch; --steps all unsupported") was added
directly under .agents/pm which violates the rule that pm is the system of
record; remove this direct edit and instead create or update the issue through
the pm system/workflow that generates .agents/pm artifacts; revert the commit
adding id "pm-6blp" (or move the change out of the .agents/pm directory), and
reapply the intended changes by using the pm tool or API so the generated
.agents/pm file is produced by the proper pipeline rather than committing it
manually.
.agents/pm/history/pm-why9.jsonl (1)

1-2: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Coding guideline violation: .agents/pm files should not be edited directly.

This file is being added under .agents/pm/, but the coding guidelines explicitly state: "pm is the system of record. Do not edit .agents/pm files directly." These files should be generated through the pm system's workflow rather than committed directly in a PR.

As per coding guidelines: .agents/pm/**: pm is the system of record. Do not edit .agents/pm files directly.

🤖 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 @.agents/pm/history/pm-why9.jsonl around lines 1 - 2, This change adds a new
.agents/pm file (.agents/pm/history/pm-why9.jsonl) which violates the rule "pm
is the system of record; do not edit .agents/pm files directly"; please
remove/revert this file from the PR (or undo the metadata additions like
metadata/id "pm-why9" and metadata/title) and instead create the intended record
via the pm system workflow so the entry (title "Code dedup: extract shared CLI
parser blocks and consolidate item-record casts" and associated metadata) is
generated by the PM tooling rather than committed directly.
🤖 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/core/store/settings-validator.ts`:
- Around line 107-119: The vNumber validator currently only rejects NaN and uses
Number.isInteger which allows Infinity and unsafe integers; update vNumber to
first require Number.isFinite(input) (this will reject NaN and ±Infinity) and
when options.int is true require Number.isInteger(input) &&
Number.isSafeInteger(input) (to reject unsafe integers); keep the positive check
as input <= 0 but run it after the finite/int checks so only valid finite
numbers are evaluated; reference the vNumber function and its options.int and
options.positive parameters when making the changes.

---

Outside diff comments:
In @.agents/pm/history/pm-uzmf.jsonl:
- Around line 1-2: This new .agents/pm JSON entry (metadata.id "pm-uzmf",
metadata.title "Calendar agent ergonomics: equal start/end rejected;
schedule-less Event items invisible") was added directly to .agents/pm which
violates the rule that pm is the system of record; remove or revert this direct
change from the PR and instead create/update the item through the pm system
workflow (or the official CLI/API) so the file is generated correctly; if you
need to keep the content for reference, move it outside .agents/pm (e.g., a
draft in docs/ or tmp/) and then submit the canonical change via the pm tooling.

In @.agents/pm/history/pm-why9.jsonl:
- Around line 1-2: This change adds a new .agents/pm file
(.agents/pm/history/pm-why9.jsonl) which violates the rule "pm is the system of
record; do not edit .agents/pm files directly"; please remove/revert this file
from the PR (or undo the metadata additions like metadata/id "pm-why9" and
metadata/title) and instead create the intended record via the pm system
workflow so the entry (title "Code dedup: extract shared CLI parser blocks and
consolidate item-record casts" and associated metadata) is generated by the PM
tooling rather than committed directly.

In @.agents/pm/issues/pm-6blp.toon:
- Around line 1-13: The new entry with id "pm-6blp" (title "pm plan: materialize
creates dependency cycle; decision/discovery/validation flag mismatch; --steps
all unsupported") was added directly under .agents/pm which violates the rule
that pm is the system of record; remove this direct edit and instead create or
update the issue through the pm system/workflow that generates .agents/pm
artifacts; revert the commit adding id "pm-6blp" (or move the change out of the
.agents/pm directory), and reapply the intended changes by using the pm tool or
API so the generated .agents/pm file is produced by the proper pipeline rather
than committing it manually.

In @.agents/pm/issues/pm-kyd6.toon:
- Around line 1-13: This change adds a generated agent file under .agents/pm
(id: pm-kyd6) which violates the guideline "pm is the system of record. Do not
edit .agents/pm files directly"; remove the direct file edit and instead
regenerate the issue through the pm system/workflow that creates pm agent
artifacts (or move any manual content to the canonical source that pm uses),
ensuring the pm workflow produces the pm-kyd6 issue entry so repository changes
do not directly modify .agents/pm files.

In @.agents/pm/issues/pm-ot8r.toon:
- Around line 1-13: This new .agents/pm issue file (id: pm-ot8r, title: "Auto
daily release silently skips releasable commits...") violates the guideline that
`.agents/pm/**` must not be edited directly; remove the added file from the PR
and instead create the issue through the pm system workflow (or regenerate it
via the pm tool) so the pm repository remains the system-of-record; reference
the same metadata (id pm-ot8r and title) when recreating the issue via the
proper pm interface and ensure any remediation (warning behavior change or
changelog auto-generation) is implemented in the application code or via a
properly authored pm issue rather than committing under `.agents/pm/`.
🪄 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: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 15f08b77-f34c-4dd4-aec8-59de82b0d364

📥 Commits

Reviewing files that changed from the base of the PR and between 3ea6002 and 6946773.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (24)
  • .agents/pm/chores/pm-1nht.toon
  • .agents/pm/chores/pm-uzmf.toon
  • .agents/pm/chores/pm-why9.toon
  • .agents/pm/features/pm-e1va.toon
  • .agents/pm/features/pm-gt82.toon
  • .agents/pm/features/pm-rnpb.toon
  • .agents/pm/history/pm-1nht.jsonl
  • .agents/pm/history/pm-6blp.jsonl
  • .agents/pm/history/pm-e1va.jsonl
  • .agents/pm/history/pm-gt82.jsonl
  • .agents/pm/history/pm-kyd6.jsonl
  • .agents/pm/history/pm-ot8r.jsonl
  • .agents/pm/history/pm-rnpb.jsonl
  • .agents/pm/history/pm-uzmf.jsonl
  • .agents/pm/history/pm-why9.jsonl
  • .agents/pm/issues/pm-6blp.toon
  • .agents/pm/issues/pm-kyd6.toon
  • .agents/pm/issues/pm-ot8r.toon
  • CHANGELOG.md
  • package.json
  • src/core/store/settings-validator.ts
  • src/core/store/settings.ts
  • tests/unit/settings-validator.spec.ts
  • vitest.config.ts

Comment thread src/core/store/settings-validator.ts Outdated
@unbraind unbraind merged commit 2d73b2f into main May 22, 2026
11 checks passed
@unbraind unbraind deleted the perf/drop-zod-settings-hot-path branch May 22, 2026 16:36
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