Skip to content

docs(agents): make boundary-only type validation an invariant#289

Merged
gbrlcustodio merged 3 commits into
devfrom
docs/type-validation-invariant
Jun 10, 2026
Merged

docs(agents): make boundary-only type validation an invariant#289
gbrlcustodio merged 3 commits into
devfrom
docs/type-validation-invariant

Conversation

@gbrlcustodio

Copy link
Copy Markdown
Collaborator

Summary

Adds a coding-style invariant to AGENTS.md: type validation belongs at trust boundaries, not inside internal functions.

Why

A PR review (#280) flagged a missing isinstance guard inside a pure SDK planner (normalize_label_color). On inspection the guard was redundant: the MCP tool signature (color: str, FastMCP/pydantic-backed) already coerces and rejects the scalar at the boundary, so the planner behind it can trust its annotation. Hand-guarding every internal function reinvents dynamic typing and, once accepted, becomes the expectation everywhere.

The invariant draws the line explicitly:

  • Internal code trusts its annotations; a type checker is the enforcement mechanism, not runtime guards.
  • Runtime checks are warranted only where untyped or external data crosses into typed code: MCP tool signatures, and the nested un-schema'd values of dict-typed args (which is why validate_report_cards_filter's checks are legitimate and normalize_label_color's would not be).

Testing

Docs-only change. No code paths affected.

gbrlcustodio and others added 2 commits June 3, 2026 16:39
release: v0.2.0-beta.3
Codify that static typing is the contract for internal code and runtime
isinstance guards belong only at trust boundaries (MCP tool signatures,
nested values of dict-typed args), not inside internal functions.

Prevents per-function defensive type checks from becoming the norm; the
enforcement mechanism for internal type contracts is a type checker, not
hand-written guards.
@gbrlcustodio gbrlcustodio self-assigned this Jun 8, 2026
@gbrlcustodio gbrlcustodio added the documentation Improvements or additions to documentation label Jun 8, 2026
@adriannoes adriannoes self-requested a review June 9, 2026 03:28

@adriannoes adriannoes left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Clear, well-motivated docs change.

The invariant matches how the codebase already behaves: scalar args are coerced at the MCP shell (color: str via FastMCP/pydantic), SDK planners like normalize_label_color trust the annotation, and nested JSON under dict-typed args is where runtime shape checks (validate_report_cards_filter) legitimately live. CI is green; nothing blocking merge.

Static review only (docs-only diff).

Also noted

** CLI as a boundary peer:** The MCP example lands well. Since the same SDK planners are called from CLI (color: str on Typer options in pipefy_cli), a short parallel note that CLI signatures are the same kind of trust boundary would keep MCP/CLI parity reviews aligned — optional polish, not a merge blocker.

@gbrlcustodio

Copy link
Copy Markdown
Collaborator Author

Added in 5aeb430: a parallel bullet noting the CLI command signature (Typer options like color: str in pipefy_cli) is the same trust boundary as the MCP signature, with the same SDK planners running behind it. Keeps the MCP/CLI parity framing aligned. Thanks for the catch.

@gbrlcustodio gbrlcustodio changed the base branch from main to dev June 10, 2026 15:10
@gbrlcustodio gbrlcustodio merged commit 7c75ada into dev Jun 10, 2026
2 checks passed
@gbrlcustodio gbrlcustodio deleted the docs/type-validation-invariant branch June 10, 2026 15:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants