Skip to content

fix(registry): validate frontmatter thinkingLevel against the closed enum (#90) - #98

Merged
rz1989s merged 2 commits into
mainfrom
fix/90-frontmatter-thinking-guard
Sep 2, 2026
Merged

rz1989s merged 2 commits into
mainfrom
fix/90-frontmatter-thinking-guard

Conversation

@rz1989s

@rz1989s rz1989s commented Sep 2, 2026

Copy link
Copy Markdown
Member

Closes #90.

Problem

parseAgentFile parsed agent frontmatter thinkingLevel with a bare cast — an invalid value (thinkingLevel: "ultra", or a non-string) reached createAgentSession unvalidated and silently no-op'd, while the identical typo in fleet settings.json warns (#78 guard). Inconsistent validation for the same value class.

Design choice (the issue's micro-decision)

The issue offered "warnings-out param vs registry-load-time surface". Both miss the parser's own precedent: backend is the same closed-enum value class and already throws FrontmatterError — no warnings channel needed. discovery.ts already catches FrontmatterError → actionable warning + skip that file, siblings still load. So:

Changes

  • src/registry/frontmatter.ts: THINKING_LEVELS + isThinkingLevel() move here (canonical home, next to the type — avoids a settings→registry inverted dependency); parseAgentFile validates before returning.
  • src/settings/fleet-settings.ts: imports the guard from frontmatter, re-exports isThinkingLevel/THINKING_LEVELS for back-compat (zero external consumers in-repo today, but the package ships raw ts).
  • README: one paragraph documenting the frontmatter validation behavior.
  • Tests: +6 (invalid string throws w/ actionable message; non-string throws; absent → undefined; null → undefined; all 7 levels parse; discovery integration — bad file skipped + warned, sibling loads). 819/819 (was 813).

Verification

  • pnpm typecheck ✅ standalone
  • pnpm test:run ✅ 819/819 standalone
  • TDD: RED confirmed first (3 new tests failed against the bare cast with "Missing expected exception")

…enum (#90)

The bare cast let an invalid thinkingLevel (e.g. 'ultra', or a non-string)
reach createAgentSession unvalidated and silently no-op — inconsistent with
both the backend field (throws FrontmatterError) and the fleet-settings guard
(#78 warns).

- isThinkingLevel + THINKING_LEVELS move to registry/frontmatter.ts (canonical
  home, next to the type); fleet-settings re-exports for back-compat
- parseAgentFile: invalid value -> FrontmatterError naming file, bad value,
  valid levels (discovery catches -> warning + skip, siblings still load);
  YAML-empty null counts as absent
- 6 new tests (throws x2, back-compat x3, discovery integration x1); 819/819
…e message pin (#90)

NIT 1: quoted padded values (' low') now trim before validating — genuinely
the same contract as backend, as the comment claims.
NIT 2: array value test pins the rendered message shape (["low"]). 821/821.
@rz1989s
rz1989s merged commit ef1f2a4 into main Sep 2, 2026
1 check passed
@rz1989s
rz1989s deleted the fix/90-frontmatter-thinking-guard branch September 2, 2026 02:30
@rz1989s rz1989s mentioned this pull request Sep 2, 2026
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.

Agent frontmatter thinkingLevel parsed with bare cast — invalid values silently no-op (inconsistent with fleet-settings guard)

1 participant