Skip to content

chore: add allow_inf_nan=False to all remaining ConfigDict declarations#943

Merged
Aureliolo merged 2 commits intomainfrom
chore/allow-inf-nan
Mar 31, 2026
Merged

chore: add allow_inf_nan=False to all remaining ConfigDict declarations#943
Aureliolo merged 2 commits intomainfrom
chore/allow-inf-nan

Conversation

@Aureliolo
Copy link
Copy Markdown
Owner

Summary

  • Add allow_inf_nan=False to all 260 remaining ConfigDict declarations across 92 files in src/synthorg/
  • All 421 ConfigDict declarations in the codebase now consistently reject NaN/Inf in numeric fields at validation time
  • Defensive application to models without numeric fields guards against future float field additions

Details

PR #911 established the allow_inf_nan=False convention and applied it to Task and AcceptanceCriterion. This PR completes the rollout to all remaining models across: api/, budget/, communication/, config/, core/, engine/, hr/, memory/ (already done), observability/, persistence/, providers/, security/, settings/, templates/, and tools/.

Four patterns were updated:

  • ConfigDict(frozen=True) (240 declarations)
  • ConfigDict(frozen=True, extra="forbid") (18 declarations)
  • ConfigDict(frozen=True, arbitrary_types_allowed=True) (1 declaration)
  • ConfigDict(frozen=True, populate_by_name=True) (1 declaration)

Test plan

  • uv run ruff check src/ tests/ -- all checks passed
  • uv run ruff format src/ tests/ -- all files already formatted
  • uv run mypy src/ tests/ -- no issues in 1,250 files
  • uv run python -m pytest tests/ -n auto -- 11,259 passed, 9 skipped
  • Pre-commit and pre-push hooks passed

Closes #913

🤖 Generated with Claude Code

Closes #913

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 31, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2efae26f-44d8-4366-b5b9-85e663dfa593

📥 Commits

Reviewing files that changed from the base of the PR and between c946e26 and 11fcc2d.

📒 Files selected for processing (1)
  • docs/architecture/tech-stack.md
📜 Recent review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Test (Python 3.14)
🧰 Additional context used
📓 Path-based instructions (2)
!(src/synthorg/observability/setup.py|src/synthorg/observability/sinks.py)

📄 CodeRabbit inference engine (CLAUDE.md)

Never use import logging, logging.getLogger(), or print() in application code. Exception: observability/setup.py and observability/sinks.py may use stdlib logging and print(..., file=sys.stderr) for bootstrap/handler-cleanup code

Files:

  • docs/architecture/tech-stack.md
docs/**/*.md

📄 CodeRabbit inference engine (CLAUDE.md)

Use Markdown for documentation in docs/ directory, built with Zensical. Config: mkdocs.yml. Do not edit .github/CHANGELOG.md (auto-generated) or release config files manually

Files:

  • docs/architecture/tech-stack.md
🧠 Learnings (12)
📓 Common learnings
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T08:35:07.813Z
Learning: Applies to src/**/*.py : Use Pydantic v2 with `allow_inf_nan=False` in all `ConfigDict` declarations to reject `NaN`/`Inf` in numeric fields at validation time
📚 Learning: 2026-03-31T08:35:07.813Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T08:35:07.813Z
Learning: Applies to src/**/*.py : Use Pydantic v2 with `allow_inf_nan=False` in all `ConfigDict` declarations to reject `NaN`/`Inf` in numeric fields at validation time

Applied to files:

  • docs/architecture/tech-stack.md
📚 Learning: 2026-03-17T22:08:13.456Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T22:08:13.456Z
Learning: Applies to src/synthorg/**/*.py : Use Pydantic v2 conventions: `BaseModel`, `model_validator`, `computed_field`, `ConfigDict`. For derived values use `computed_field` instead of storing + validating redundant fields. Use `NotBlankStr` (from `core.types`) for all identifier/name fields — including optional (`NotBlankStr | None`) and tuple (`tuple[NotBlankStr, ...]`) variants — instead of manual whitespace validators.

Applied to files:

  • docs/architecture/tech-stack.md
📚 Learning: 2026-03-20T21:44:04.528Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-20T21:44:04.528Z
Learning: Applies to src/synthorg/**/*.py : Use frozen Pydantic models for config/identity; use separate mutable-via-copy models (via `model_copy(update=...)`) for runtime state that evolves

Applied to files:

  • docs/architecture/tech-stack.md
📚 Learning: 2026-03-15T19:14:27.144Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T19:14:27.144Z
Learning: Applies to src/synthorg/**/*.py : Use frozen Pydantic models for config/identity; use separate mutable-via-copy models (using model_copy(update=...)) for runtime state that evolves. Never mix static config fields with mutable runtime fields in one model.

Applied to files:

  • docs/architecture/tech-stack.md
📚 Learning: 2026-03-15T18:38:44.202Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:38:44.202Z
Learning: Applies to src/synthorg/**/*.py : Use frozen Pydantic models for config/identity; separate mutable-via-copy models (using `model_copy(update=...)`) for runtime state

Applied to files:

  • docs/architecture/tech-stack.md
📚 Learning: 2026-03-20T08:28:32.845Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-20T08:28:32.845Z
Learning: Applies to **/*.py : Config vs runtime state: use frozen Pydantic models for config/identity; separate mutable-via-copy models (using `model_copy(update=...)`) for runtime state. Never mix static config fields with mutable runtime fields in one model.

Applied to files:

  • docs/architecture/tech-stack.md
📚 Learning: 2026-03-31T08:35:07.813Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-31T08:35:07.813Z
Learning: Applies to src/**/*.py : Use frozen Pydantic models for config/identity and separate mutable-via-copy models (using `model_copy(update=...)`) for runtime state that evolves. Never mix static config fields with mutable runtime fields in one model

Applied to files:

  • docs/architecture/tech-stack.md
📚 Learning: 2026-03-15T18:38:44.202Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T18:38:44.202Z
Learning: Applies to **/*.py : Config vs runtime state: frozen Pydantic models for config/identity; separate mutable-via-copy models (using model_copy(update=...)) for runtime state that evolves. Never mix static config fields with mutable runtime fields in one model.

Applied to files:

  • docs/architecture/tech-stack.md
📚 Learning: 2026-03-17T22:08:13.456Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-17T22:08:13.456Z
Learning: Applies to src/synthorg/**/*.py : Prefer `asyncio.TaskGroup` for fan-out/fan-in parallel operations in new code (e.g. multiple tool invocations, parallel agent calls). Prefer structured concurrency over bare `create_task`. Existing code is being migrated incrementally.

Applied to files:

  • docs/architecture/tech-stack.md
📚 Learning: 2026-03-15T19:14:27.144Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T19:14:27.144Z
Learning: Applies to src/synthorg/**/*.py : Use Pydantic v2 with adopted conventions: use computed_field for derived values instead of storing + validating redundant fields; use NotBlankStr from core.types for all identifier/name fields (including optional and tuple variants) instead of manual whitespace validators.

Applied to files:

  • docs/architecture/tech-stack.md
📚 Learning: 2026-03-15T19:14:27.144Z
Learnt from: CR
Repo: Aureliolo/synthorg PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-15T19:14:27.144Z
Learning: Applies to src/synthorg/**/*.py : Use Pydantic v2 BaseModel, model_validator, computed_field, ConfigDict.

Applied to files:

  • docs/architecture/tech-stack.md
🔇 Additional comments (1)
docs/architecture/tech-stack.md (1)

110-110: Good convention addition; aligns docs with enforced model validation.

This line clearly documents the allow_inf_nan=False standard and matches the implemented rollout across ConfigDict declarations.

Based on learnings: "Use Pydantic v2 with allow_inf_nan=False in all ConfigDict declarations to reject NaN/Inf in numeric fields at validation time".


Walkthrough

This PR adds allow_inf_nan=False to numerous Pydantic ConfigDict declarations across the repository. Many models previously using ConfigDict(frozen=True) (or with other flags like extra="forbid" / populate_by_name=True) now include allow_inf_nan=False, making Pydantic validation reject Infinity/-Infinity/NaN values during model parsing/assignment. No fields, validators, control flow, or public signatures were changed.

Suggested labels

autorelease: tagged

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed Title accurately describes the main change: adding allow_inf_nan=False to all remaining ConfigDict declarations across the codebase.
Description check ✅ Passed Description is comprehensive and directly related to the changeset, explaining the summary, details, patterns updated, test plan, and context for why the change was made.
Linked Issues check ✅ Passed The PR fully addresses issue #913 by adding allow_inf_nan=False to 260 remaining ConfigDict declarations across 92 files, completing rollout to all modules as specified in the linked issue.
Out of Scope Changes check ✅ Passed All changes are in scope: adding allow_inf_nan=False to ConfigDict declarations and documenting the convention in tech-stack.md. No unrelated modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@Aureliolo Aureliolo temporarily deployed to cloudflare-preview March 31, 2026 09:16 — with GitHub Actions Inactive
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 31, 2026

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Snapshot Warnings

⚠️: No snapshots were found for the head SHA 11fcc2d.
Ensure that dependencies are being submitted on PR branches. Re-running this action after a short time may resolve the issue. See the documentation for more information and troubleshooting advice.

Scanned Files

None

Copy link
Copy Markdown
Contributor

@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 implements a global update to Pydantic model configurations by adding allow_inf_nan=False to the ConfigDict of numerous BaseModel subclasses. This change enhances data validation by explicitly prohibiting the use of infinity and NaN values across various modules, including API, core engine, security, and communication subsystems. I have no feedback to provide.

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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/synthorg/engine/decomposition/llm.py`:
- Line 64: The ConfigDict instantiation uses an invalid parameter allow_inf_nan;
remove allow_inf_nan from model_config = ConfigDict(frozen=True) and instead
enforce no-inf/nan at field-level by updating the temperature field (in the
relevant Pydantic model/class) to use Field(allow_inf_nan=False) or change its
type to FiniteFloat; make sure to keep ConfigDict(frozen=True) and adjust the
temperature field definition accordingly.
🪄 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

Review profile: ASSERTIVE

Plan: Pro

Run ID: c85eaf4d-1518-4f87-b108-ed57511de3bc

📥 Commits

Reviewing files that changed from the base of the PR and between 6a5088c and c946e26.

📒 Files selected for processing (92)
  • src/synthorg/api/auth/config.py
  • src/synthorg/api/auth/controller.py
  • src/synthorg/api/auth/models.py
  • src/synthorg/api/auth/ticket_store.py
  • src/synthorg/api/config.py
  • src/synthorg/api/controllers/approvals.py
  • src/synthorg/api/controllers/autonomy.py
  • src/synthorg/api/controllers/budget.py
  • src/synthorg/api/controllers/health.py
  • src/synthorg/api/controllers/meetings.py
  • src/synthorg/api/controllers/setup_models.py
  • src/synthorg/api/controllers/users.py
  • src/synthorg/api/dto_discovery.py
  • src/synthorg/api/ws_models.py
  • src/synthorg/budget/config.py
  • src/synthorg/budget/coordination_config.py
  • src/synthorg/budget/coordination_metrics.py
  • src/synthorg/budget/hierarchy.py
  • src/synthorg/budget/spending_summary.py
  • src/synthorg/communication/channel.py
  • src/synthorg/communication/config.py
  • src/synthorg/communication/conflict_resolution/config.py
  • src/synthorg/communication/conflict_resolution/models.py
  • src/synthorg/communication/delegation/authority.py
  • src/synthorg/communication/dispatcher.py
  • src/synthorg/communication/handler.py
  • src/synthorg/communication/loop_prevention/models.py
  • src/synthorg/communication/meeting/config.py
  • src/synthorg/communication/meeting/models.py
  • src/synthorg/communication/message.py
  • src/synthorg/communication/subscription.py
  • src/synthorg/config/schema.py
  • src/synthorg/core/agent.py
  • src/synthorg/core/approval.py
  • src/synthorg/core/artifact.py
  • src/synthorg/core/company.py
  • src/synthorg/core/project.py
  • src/synthorg/core/role.py
  • src/synthorg/engine/agent_state.py
  • src/synthorg/engine/approval_gate_models.py
  • src/synthorg/engine/checkpoint/models.py
  • src/synthorg/engine/classification/models.py
  • src/synthorg/engine/compaction/models.py
  • src/synthorg/engine/context.py
  • src/synthorg/engine/context_budget.py
  • src/synthorg/engine/coordination/config.py
  • src/synthorg/engine/coordination/dispatchers.py
  • src/synthorg/engine/coordination/models.py
  • src/synthorg/engine/coordination/section_config.py
  • src/synthorg/engine/decomposition/llm.py
  • src/synthorg/engine/decomposition/models.py
  • src/synthorg/engine/hybrid_models.py
  • src/synthorg/engine/loop_protocol.py
  • src/synthorg/engine/loop_selector.py
  • src/synthorg/engine/parallel_models.py
  • src/synthorg/engine/plan_models.py
  • src/synthorg/engine/prompt.py
  • src/synthorg/engine/recovery.py
  • src/synthorg/engine/routing/models.py
  • src/synthorg/engine/run_result.py
  • src/synthorg/engine/stagnation/models.py
  • src/synthorg/engine/task_engine_models.py
  • src/synthorg/engine/task_execution.py
  • src/synthorg/engine/workspace/config.py
  • src/synthorg/engine/workspace/models.py
  • src/synthorg/hr/promotion/config.py
  • src/synthorg/hr/promotion/models.py
  • src/synthorg/observability/config.py
  • src/synthorg/persistence/config.py
  • src/synthorg/providers/models.py
  • src/synthorg/providers/probing.py
  • src/synthorg/providers/routing/models.py
  • src/synthorg/security/autonomy/models.py
  • src/synthorg/security/config.py
  • src/synthorg/security/models.py
  • src/synthorg/security/timeout/config.py
  • src/synthorg/security/timeout/models.py
  • src/synthorg/security/timeout/parked_context.py
  • src/synthorg/security/trust/config.py
  • src/synthorg/security/trust/models.py
  • src/synthorg/settings/models.py
  • src/synthorg/templates/model_matcher.py
  • src/synthorg/templates/model_requirements.py
  • src/synthorg/templates/schema.py
  • src/synthorg/tools/base.py
  • src/synthorg/tools/git_url_validator.py
  • src/synthorg/tools/mcp/config.py
  • src/synthorg/tools/mcp/models.py
  • src/synthorg/tools/sandbox/config.py
  • src/synthorg/tools/sandbox/docker_config.py
  • src/synthorg/tools/sandbox/result.py
  • src/synthorg/tools/sandbox/sandboxing_config.py

"""

model_config = ConfigDict(frozen=True)
model_config = ConfigDict(frozen=True, allow_inf_nan=False)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

Does Pydantic v2.12.5 support allow_inf_nan as a ConfigDict parameter? What is the correct way to reject NaN and Inf values in Pydantic v2?

💡 Result:

No, Pydantic v2.12.5 does not support allow_inf_nan as a ConfigDict (model_config) parameter. The official documentation lists allow_inf_nan as a field-level parameter for numeric fields (float, Decimal) via Field, confloat, etc., and as a metadata class AllowInfNan. ConfigDict supports ser_json_inf_nan for serialization behavior, but not allow_inf_nan for validation. The correct way to reject NaN and Inf values in Pydantic v2 is to use field constraints: 1. For plain float fields, use Field(allow_inf_nan=False) or confloat(allow_inf_nan=False): from pydantic import BaseModel, Field, confloat class Model(BaseModel): value: float = Field(allow_inf_nan=False) # or: value: confloat(allow_inf_nan=False) 2. Use built-in types like FiniteFloat which rejects NaN/Inf: from pydantic import BaseModel, FiniteFloat class Model(BaseModel): value: FiniteFloat This raises ValidationError for NaN, Inf, -Inf. Confirmed across Pydantic v2 docs (including latest for v2.12.5), GitHub issues (#7296), and API references. Floats allow NaN/Inf by default unless explicitly rejected at field level.

Citations:


Use field-level allow_inf_nan=False constraint instead of ConfigDict parameter.

allow_inf_nan is not a valid ConfigDict parameter in Pydantic v2.12.5—it is a field-level constraint only. Remove it from ConfigDict and apply directly to the temperature field using Field(allow_inf_nan=False), or use the FiniteFloat type instead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/synthorg/engine/decomposition/llm.py` at line 64, The ConfigDict
instantiation uses an invalid parameter allow_inf_nan; remove allow_inf_nan from
model_config = ConfigDict(frozen=True) and instead enforce no-inf/nan at
field-level by updating the temperature field (in the relevant Pydantic
model/class) to use Field(allow_inf_nan=False) or change its type to
FiniteFloat; make sure to keep ConfigDict(frozen=True) and adjust the
temperature field definition accordingly.

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 31, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.15%. Comparing base (6a5088c) to head (11fcc2d).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #943      +/-   ##
==========================================
- Coverage   92.15%   92.15%   -0.01%     
==========================================
  Files         600      600              
  Lines       32052    32052              
  Branches     3115     3115              
==========================================
- Hits        29537    29536       -1     
  Misses       1985     1985              
- Partials      530      531       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Aureliolo Aureliolo temporarily deployed to cloudflare-preview March 31, 2026 09:36 — with GitHub Actions Inactive
@Aureliolo Aureliolo merged commit cd7bbca into main Mar 31, 2026
34 checks passed
@Aureliolo Aureliolo deleted the chore/allow-inf-nan branch March 31, 2026 09:59
@Aureliolo Aureliolo temporarily deployed to cloudflare-preview March 31, 2026 09:59 — with GitHub Actions Inactive
Aureliolo added a commit that referenced this pull request Mar 31, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.5.3](v0.5.2...v0.5.3)
(2026-03-31)


### Features

* implement artifact and project persistence
([#947](#947))
([6dea87a](6dea87a))


### Maintenance

* add allow_inf_nan=False to all remaining ConfigDict declarations
([#943](#943))
([cd7bbca](cd7bbca))
* audit full web dashboard for hardcoded design token violations
([#944](#944))
([a1322cd](a1322cd))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
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.

chore: add allow_inf_nan=False to all remaining ConfigDict declarations

1 participant