Skip to content

fix(core): validate schema validation modes - #1223

Merged
phernandez merged 3 commits into
mainfrom
fix/1222-validation-mode
Aug 10, 2026
Merged

fix(core): validate schema validation modes#1223
phernandez merged 3 commits into
mainfrom
fix/1222-validation-mode

Conversation

@phernandez

@phernandez phernandez commented Aug 10, 2026

Copy link
Copy Markdown
Member

Why

Schema validation accepted arbitrary settings.validation values and treated every value except strict as warning-only. That made the natural error spelling fail open: notes missing required fields still reported passed: true.

The public schema contract documents two modes, warn and strict. The parser also has to enforce that contract after Markdown frontmatter loading, where YAML 1.1 tokens such as bare off may already have become non-string values. Invalid schema configuration must also remain actionable at the API boundary instead of surfacing as a generic server error.

Closes #1222.

What Changed

  • Model validation mode as the documented closed warn | strict vocabulary.
  • Parse modes at schema boundaries for both schema notes and inline schemas.
  • Accept error as a compatibility alias normalized to canonical strict.
  • Reject off, its YAML-loaded False representation, and every other unknown value.
  • Handle warn and strict exhaustively when recording validation findings.
  • Translate invalid schema definitions into HTTP 400 responses for single validation, batch validation, and schema diff.
  • Align checked-in schema references and shared skills with the public documentation.
  • Add unit coverage for the complete accepted/rejected mode matrix.
  • Add integration coverage that loads a real Markdown fixture and exercises the PyYAML boundary.
  • Add API regression coverage for malformed inline and file-backed schema modes.

Implementation Details

parse_validation_mode() narrows the untrusted YAML value once, so SchemaDefinition.validation_mode is always a typed ValidationMode. The validator consumes that closed type with an exhaustive match and assert_never, preventing a future mode from silently degrading to warnings.

The compatibility alias preserves the spelling already used by the cloud acceptance flow while keeping strict as the documented canonical enforcing mode. The integration fixture deliberately uses bare validation: off: PyYAML loads it as False, and schema parsing now rejects it with the accepted vocabulary instead of bypassing the boundary behavior in hand-built test dictionaries.

The schema router catches parser ValueError only around schema resolution and returns HTTP 400 with the actionable parser message. Other failures retain their existing error behavior.

Testing

Automated

  • uv run pytest tests/picoschema/test_parser.py tests/picoschema/test_resolver.py tests/picoschema/test_validator.py test-int/test_picoschema/test_parser_integration.py test-int/test_picoschema/test_validator_integration.py -q: 138 passed
  • uv run pytest tests/api/v2/test_schema_router.py tests/mcp/test_client_schema.py tests/mcp/test_tool_schema.py -q: 56 passed
  • just fast-check: passed
  • just package-check: passed
  • just doctor: passed
  • git diff --check: passed

Manual

  • Verified the pushed branch matches local head 91e16b77409e52aefff138f2dcbf6ce3c283dfb7.
  • Verified checked-in Markdown documentation has no remaining supported-off guidance; the only bare off is the intentional invalid integration fixture.
  • Verified malformed modes return HTTP 400 for identifier validation, note-type batch validation, and schema diff.

Risks / Follow-ups

  • Unknown modes, including previously tolerated off, now fail at schema parse time instead of degrading to warnings. This is intentional alignment with the public warn | strict contract but may expose previously unnoticed invalid schemas.
  • The cloud development MCP acceptance schemas phase was not run locally because it requires a deployed build carrying this core change. Rerun that phase after deployment.

Signed-off-by: phernandez <paul@basicmachines.co>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d4efea0a40

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/basic_memory/picoschema/parser.py Outdated
Signed-off-by: phernandez <paul@basicmachines.co>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c2a823a9fa

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/basic_memory/picoschema/parser.py
Signed-off-by: phernandez <paul@basicmachines.co>
@phernandez
phernandez merged commit 072ad5f into main Aug 10, 2026
33 checks passed
@phernandez
phernandez deleted the fix/1222-validation-mode branch August 10, 2026 15:21
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.

Schema validation mode is stringly-typed: unknown modes (including 'error') silently degrade to warn

1 participant