Skip to content

refactor: WP-3 API conventions + query performance + project-wide extra=forbid#1953

Merged
Aureliolo merged 9 commits into
mainfrom
refactor/wp3-api-conventions-query-perf
May 17, 2026
Merged

refactor: WP-3 API conventions + query performance + project-wide extra=forbid#1953
Aureliolo merged 9 commits into
mainfrom
refactor/wp3-api-conventions-query-perf

Conversation

@Aureliolo
Copy link
Copy Markdown
Owner

Summary

WP-3 (#1918): API boundary discipline + query performance + the project-wide extra="forbid" rollout with its new enforcement gate.

  • Input validation: typed PathId path params across the 5 memory admin handlers (redundant NotBlankStr(...) runtime wraps dropped — they were no-ops).
  • Rate limits: per-op guards on POST /training/{agent}/plan and PUT .../overrides.
  • Pydantic conventions: project-wide extra="forbid" (~266 frozen models) + new check_frozen_model_extra_forbid.py gate; default_volume_caps lambda → named factory.
  • Centralised error mapping: controller InternalServerException/NotFoundException and inline 404s → DomainError subclasses; ~15 new ErrorCode entries; regenerated TS error-code constants.
  • Query performance: MessageRepository.get_by_id + indexed meeting lookup replace O(N) scans; real two-step SQL pagination for subworkflow.search; sargable agent_state.get_active; composite/partial indices (snapshot, oplog, approvals, heartbeat) in both backends via one consolidated revision per backend.
  • Pagination: cursor/limit on 9 repo protocol methods.
  • Resilience: exponential backoff in telemetry deployment-ID retry; hard async ceiling on the preflight directory walk; Cache-Control on streaming ETag passthrough.

Pre-PR review coverage

Reviewed by 24 agents (full roster + 5 audit mini-pass) before first push. 47 findings triaged: 41 fixed (36 code/test changes + the gate-surfaced RefreshRotation fix), 3 dropped as verified false positives (would have violated MANDATORY rules / project structure — convention_gate_map registration, Code-conventions (MANDATORY) promotion, RS-sourced count hand-edit), 8 resolved by analysis as already-covered (existing layered tests / existing indices / intentional design), 1 invalid conflict (PEP 758 except A, B: is correct per CLAUDE.md — not "fixed").

Key behavioural test additions: training-endpoint burst-rejection (429), telemetry retry-exhaustion path, workflows 404 error_code assertions; mock_of[...] specs replace bare mocks; design-doc model examples updated; OpenCode↔Claude tool-parity gap (check_no_git_no_verify.sh) closed.

Test plan

  • ruff check / ruff format: clean
  • mypy --strict (full): clean, 3851 files
  • Full unit suite: 28899 passed / 18 skipped
  • Dual-backend conformance (SQLite + Postgres) for the changed repos + new consolidated migration revision: schema-drift + single-migration + schema-drift-revisions all green
  • All convention gates (frozen-extra-forbid, no-review-origin, no-migration-framing, convention-inventory meta-gate, etc.): green at pre-push

Closes #1918

Aureliolo added 6 commits May 17, 2026 14:39
Pre-reviewed by 24 agents; 44 findings addressed across pagination, error-contract, logging, docstrings, tests, tool-parity, and design docs.
…#1918)

Pre-push affected-pytest surfaced one test still asserting the old QueryError on the vanished-after-activation path; updated to the contracted CheckpointNotFoundError introduced by the #45 fix.
Rebase onto main pulled in a frozen model lacking extra=forbid; the project-wide gate self-test (a #1918 acceptance criterion) flagged it. Bundled per the gate-surfaced-preexisting-fix rule.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 17, 2026

Dependency Review

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

Scanned Files

None

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request implements a comprehensive set of improvements focusing on API boundary discipline, query performance, and system resilience. It standardizes Pydantic model configurations project-wide, optimizes database access patterns through improved indexing and pagination, and enhances error handling and rate limiting for critical endpoints.

Highlights

  • Pydantic extra='forbid' Rollout: Enforced project-wide 'extra="forbid"' on all frozen Pydantic models to prevent silent absorption of unknown fields, replacing the previous API-only gate with a new 'check_frozen_model_extra_forbid.py' script.
  • Query Performance & Pagination: Optimized multiple repository methods with cursor-based pagination and added composite/partial indices to backends, significantly improving performance for high-load read paths.
  • API Resilience & Error Mapping: Centralized error mapping by introducing new 'DomainError' subclasses and 'ErrorCode' entries, and added per-operation rate limits to training endpoints to improve system stability.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 17, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

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

Review profile: ASSERTIVE

Plan: Pro

Run ID: 53f06cc3-ec48-4a38-8022-6cf4067e2d9c

📥 Commits

Reviewing files that changed from the base of the PR and between 637f7e5 and 9907f0a.

📒 Files selected for processing (1)
  • web/src/stores/subworkflows.ts
📜 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). (8)
  • GitHub Check: Test E2E
  • GitHub Check: Dashboard Test
  • GitHub Check: Test Integration
  • GitHub Check: Test Unit
  • GitHub Check: Lighthouse Site
  • GitHub Check: Lighthouse Dashboard
  • GitHub Check: Build Web Assets (melange)
  • GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (5)
web/src/**/*.{js,jsx,ts,tsx,mts}

📄 CodeRabbit inference engine (web/CLAUDE.md)

web/src/**/*.{js,jsx,ts,tsx,mts}: Always use createLogger from @/lib/logger; never bare console.warn/console.error/console.debug in application code. Variable name must always be log. Only logger.ts itself may use bare console methods. Use log.debug() (DEV-only, stripped in production), log.warn(), log.error().
Pass dynamic/untrusted values as separate args to logger calls (not interpolated into the message string) so they go through sanitizeArg
Attacker-controlled fields inside structured objects must be wrapped in sanitizeForLog() before embedding in log calls
Error-code constants (MANDATORY): import ErrorCode and ErrorCategory from @/api/types/errors (re-exported from the generated web/src/api/types/error-codes.gen.ts). Discriminate on ErrorCode.<NAME>, never on raw integer literals.
Use @eslint-react/web-api-no-leaked-fetch to detect fetch() in effects without AbortController cleanup

Files:

  • web/src/stores/subworkflows.ts
web/src/stores/**/*.ts

📄 CodeRabbit inference engine (web/CLAUDE.md)

web/src/stores/**/*.ts: List reads (fetch*) must set error: string | null on the store instead of toasting
Test teardown (MANDATORY): any new store that schedules timers or attaches event listeners must expose an equivalent cleanup hook and register it in the global afterEach. The global afterEach in web/src/test-setup.tsx already calls useToastStore.getState().dismissAll(), cancelPendingPersist(), and useThemeStore.getState().teardown().

Files:

  • web/src/stores/subworkflows.ts
web/src/{api/endpoints,stores}/**/*.ts

📄 CodeRabbit inference engine (web/CLAUDE.md)

Cursor pagination (MANDATORY): list endpoints must use opaque cursor-based paging via PaginationMeta. Stores must keep nextCursor + hasMore in state (not offset arithmetic) and early-return when !hasMore || !nextCursor. Display counts must come from data.length.

Files:

  • web/src/stores/subworkflows.ts
web/src/**/*.{ts,tsx,mts}

📄 CodeRabbit inference engine (web/CLAUDE.md)

web/src/**/*.{ts,tsx,mts}: Use @typescript-eslint/no-floating-promises to forbid unawaited promises so async work cannot survive the test that scheduled it and trip the active-handle gate
Use @typescript-eslint/no-misused-promises (with checksVoidReturn: { attributes: false }) to forbid passing async functions where the callsite ignores the returned promise. React 19 async event handlers stay allowed via the attributes: false exemption.

Files:

  • web/src/stores/subworkflows.ts
web/**/*.{tsx,ts,jsx,js}

📄 CodeRabbit inference engine (CLAUDE.md)

Web Dashboard uses React 19; see web/CLAUDE.md for details

Files:

  • web/src/stores/subworkflows.ts
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: Aureliolo/synthorg

Timestamp: 2026-05-17T14:19:21.235Z
Learning: After every squash merge → run `/post-merge-cleanup`
Learnt from: CR
Repo: Aureliolo/synthorg

Timestamp: 2026-05-17T14:19:21.235Z
Learning: CLI is Docker-only (init/start/stop/status); features go in dashboard + REST API
Learnt from: CR
Repo: Aureliolo/synthorg

Timestamp: 2026-05-17T14:19:21.235Z
Learning: GitHub queries: use `gh issue list` via Bash, NOT MCP `list_issues`
🔇 Additional comments (1)
web/src/stores/subworkflows.ts (1)

11-11: LGTM!

Also applies to: 67-84


Walkthrough

This PR enforces project-wide Pydantic frozen models to set extra="forbid" (new gate + pre-commit hook and tests), adds scripts/check_frozen_model_extra_forbid.py, extends ErrorCode and DomainError classes, converts several controllers to raise domain errors and use PathId types, implements paginated repository APIs plus collect_all/collect_all_mapping helpers and drains in services/controllers, adds indexed single-row message/meeting lookups, introduces DB index migrations, refactors memory preflight to depth/time-bounded walks with outer timeouts, updates cache-control/ETag and telemetry backoff, and adjusts many tests and generated web types.

@Aureliolo Aureliolo temporarily deployed to cloudflare-preview May 17, 2026 13:08 — with GitHub Actions Inactive
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 17, 2026

Merging this PR will not alter performance

✅ 54 untouched benchmarks


Comparing refactor/wp3-api-conventions-query-perf (9907f0a) with main (f3252cd)

Open in CodSpeed

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 project-wide enforcement of the extra="forbid" constraint for all frozen Pydantic models, replacing the previous API-only gate. It introduces a new static analysis script, updates numerous models across the codebase, and refines error handling with specialized domain exceptions and error codes. Furthermore, the PR optimizes repository performance by implementing pagination for multiple high-traffic read paths, accompanied by new database indices and utility functions for result reassembly. Review feedback highlights an opportunity to improve the consistency of PostgreSQL search queries using explicit escape clauses and suggests implementing cursor-based pagination at the API boundary for subworkflow searches to prevent excessive memory usage.

# ``limit * versions_per_subworkflow``.
await cur.execute(
"SELECT subworkflow_id FROM subworkflows"
" WHERE name ILIKE %s OR description ILIKE %s"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The ILIKE query uses wildcards (%) in the pattern constructed on line 418, but it does not explicitly specify an ESCAPE clause. While PostgreSQL defaults to \ as the escape character, it is safer and more consistent with the SQLite implementation (line 498) to explicitly provide ESCAPE '\\' to ensure that literal backslashes, percent signs, or underscores in the search query are handled correctly regardless of server configuration.

Suggested change
" WHERE name ILIKE %s OR description ILIKE %s"
" WHERE name ILIKE %s ESCAPE '\\' OR description ILIKE %s ESCAPE '\\'"

Comment on lines +230 to +234
lambda limit, offset: registry.search(
NotBlankStr(q),
limit=limit,
offset=offset,
),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

This endpoint drains all matching subworkflows from the repository into memory before returning them in a single response. While the repository now supports pagination to bound database-side scan costs, a very large result set could still lead to high memory usage in the API process and large network payloads. Consider implementing cursor-based pagination at the API boundary for this search endpoint, similar to list_parents (line 332).

Copy link
Copy Markdown
Contributor

@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: 7

Caution

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

⚠️ Outside diff range comments (1)
src/synthorg/persistence/sqlite/subworkflow_repo.py (1)

632-700: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Pagination default can bypass referential-integrity checks.

find_parents now returns only one page by default, but delete_if_unreferenced still calls it once (Line 592). That can miss references beyond DEFAULT_PAGE_SIZE, allowing deletion of still-referenced versions.

🔧 Suggested fix
@@
-                parents = await self.find_parents(subworkflow_id, version)
+                # Must check the full parent set for referential integrity.
+                parents = await self._find_parents_unpaged(subworkflow_id, version)
                 if parents:
                     await self._db.rollback()
                     return False, parents
@@
-    async def find_parents(
+    async def find_parents(
         self,
         subworkflow_id: NotBlankStr,
         version: NotBlankStr | None = None,
         *,
         limit: int = DEFAULT_PAGE_SIZE,
         offset: int = 0,
     ) -> tuple[ParentReference, ...]:
+        references = await self._find_parents_unpaged(subworkflow_id, version)
+        return tuple(references[offset : offset + limit])
+
+    async def _find_parents_unpaged(
+        self,
+        subworkflow_id: NotBlankStr,
+        version: NotBlankStr | None = None,
+    ) -> tuple[ParentReference, ...]:
         ...
-        references.sort(...)
-        return tuple(references[offset : offset + limit])
+        references.sort(...)
+        return tuple(references)
🤖 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 `@src/synthorg/persistence/sqlite/subworkflow_repo.py` around lines 632 - 700,
find_parents currently returns a single default-sized page which lets
delete_if_unreferenced miss later references; update the delete_if_unreferenced
call site to fully drain all pages by iterating or using the existing helper
collect_all when calling find_parents. Specifically, change the code that calls
find_parents (method delete_if_unreferenced) to call
synthorg.persistence._shared.collect_all(self.find_parents(...)) or implement a
loop that repeatedly calls find_parents with increasing offset until no more
results, so every ParentReference is examined before deleting a version.
🤖 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/synthorg/core/company.py`:
- Line 153: The ReportingLine model's model_config is missing extra="forbid"
(currently ConfigDict(frozen=True, allow_inf_nan=False)), so update
ReportingLine.model_config to ConfigDict(frozen=True, allow_inf_nan=False,
extra="forbid") to prevent unknown fields being accepted in this frozen nested
model; locate the ReportingLine class and its model_config assignment and add
the extra="forbid" flag to match project-wide pydantic v2 guidelines.

In `@src/synthorg/hr/training/config.py`:
- Around line 33-37: Replace the inline numeric caps in the dict returned by the
Config mapping (the entries for ContentType.PROCEDURAL, ContentType.SEMANTIC,
ContentType.TOOL_PATTERNS) with named constants sourced from settings
definitions or module-level annotated constants; add/consume constants like
PROCEDURAL_CAP, SEMANTIC_CAP, TOOL_PATTERNS_CAP (typed, e.g., int) in the
settings/definitions module (or at top of src/synthorg/hr/training/config.py if
settings import is preferred) and then reference those symbols in the return
dict instead of the hardcoded numbers so no plain numeric literals remain in the
mapping.

In `@src/synthorg/memory/service.py`:
- Around line 106-113: Remove migration/history framing from the inline
docstring that describes the CHECKPOINT_ROLLBACK_UNAVAILABLE handling: rewrite
the docstring to explain only the current intent and why the handler emits a 422
with the specific CHECKPOINT_ROLLBACK_UNAVAILABLE code (i.e., checkpoint exists
but required stored backup config is missing), avoid any references to prior
behavior, migrations, reviewer citations or comparative migration context; apply
the same cleanup to other nearby comments/docstrings that reference
migration/history framing related to EXCEPTION_HANDLERS or checkpoint rollback
logic so all in-code comments describe only the current reason/intent.

In `@src/synthorg/persistence/postgres/circuit_breaker_repo.py`:
- Around line 176-189: The load_all method currently forwards pagination args to
list_items without validation; call validate_pagination_args(limit=limit,
offset=offset) at the start of load_all (or alternatively add the same call
inside list_items) to enforce non-negative/allowed bounds and raise the existing
validation error immediately; ensure the import/reference to
validate_pagination_args is present and keep the subsequent return await
self.list_items(limit=limit, offset=offset) unchanged so callers get the same
behavior after validation.

In `@tests/unit/api/fakes_workflow.py`:
- Around line 365-375: The test helper truncates inputs by calling
self.list_summaries() with its default page cap, so change it to fetch all
summaries before filtering: call self.list_summaries with an explicit parameter
to retrieve the full set (or implement a loop to page through until no more
results) and assign that to summaries, then apply the existing filtering (q,
matched, sorting, and slicing by offset/limit) unchanged; reference the
list_summaries call, the summaries variable, and the matched/q/offset/limit
logic when making the change.

In `@tests/unit/engine/workflow/test_subworkflow_registry.py`:
- Around line 155-168: The search function (search) currently calls
list_summaries() with its default capped limit (DEFAULT_PAGE_SIZE), which
truncates candidates before filtering and pagination; fix by fetching the full
untruncated set of summaries before filtering — e.g., call list_summaries with
no limit or a sufficiently large limit (or use a dedicated list_all_summaries
helper) so that matched = sorted((s for s in summaries if q in s.name.lower() or
q in s.description.lower()), ...) operates over all summaries, then apply
offset/limit slicing to matched.

In `@tests/unit/persistence/_shared/test_pagination.py`:
- Around line 33-40: The test test_exact_multiple_stops_on_empty_page currently
only asserts the returned rows and doesn't verify that collect_all performs the
terminating empty fetch; modify the test to track calls to the inner fetch
(e.g., add a counter or list like calls = [] and append the (limit, offset) on
each invocation inside fetch) and assert after collect_all that the expected
sequence of fetch calls occurred including the final empty-page call (for
page_size=100 expect offsets 0,100,200 with the last fetch returning empty).
Ensure references to the inner fetch function and collect_all remain the same so
the test fails if the empty fetch is skipped.

---

Outside diff comments:
In `@src/synthorg/persistence/sqlite/subworkflow_repo.py`:
- Around line 632-700: find_parents currently returns a single default-sized
page which lets delete_if_unreferenced miss later references; update the
delete_if_unreferenced call site to fully drain all pages by iterating or using
the existing helper collect_all when calling find_parents. Specifically, change
the code that calls find_parents (method delete_if_unreferenced) to call
synthorg.persistence._shared.collect_all(self.find_parents(...)) or implement a
loop that repeatedly calls find_parents with increasing offset until no more
results, so every ParentReference is examined before deleting a version.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: e4dbfe39-4435-4cf2-a970-a35c7cad9c64

📥 Commits

Reviewing files that changed from the base of the PR and between f3252cd and e0a5b2a.

📒 Files selected for processing (202)
  • .opencode/plugins/synthorg-hooks.ts
  • .pre-commit-config.yaml
  • CLAUDE.md
  • docs/design/agents.md
  • docs/design/memory.md
  • docs/reference/audit-category-gate-coverage.md
  • docs/reference/convention-gates.md
  • docs/reference/conventions.md
  • docs/reference/errors.md
  • scripts/check_dto_forbid_extra.py
  • scripts/check_frozen_model_extra_forbid.py
  • src/synthorg/api/auth/service.py
  • src/synthorg/api/auth/ticket_store.py
  • src/synthorg/api/config.py
  • src/synthorg/api/controllers/_webhooks_wiring.py
  • src/synthorg/api/controllers/agent_identity_versions.py
  • src/synthorg/api/controllers/memory.py
  • src/synthorg/api/controllers/meta.py
  • src/synthorg/api/controllers/settings.py
  • src/synthorg/api/controllers/subworkflows.py
  • src/synthorg/api/controllers/training.py
  • src/synthorg/api/controllers/workflows.py
  • src/synthorg/api/cursor_config.py
  • src/synthorg/api/etag.py
  • src/synthorg/api/pagination.py
  • src/synthorg/api/rate_limits/policies.py
  • src/synthorg/api/rate_limits/protocol.py
  • src/synthorg/api/ws_models.py
  • src/synthorg/backup/errors.py
  • src/synthorg/budget/baseline_store.py
  • src/synthorg/budget/call_analytics_config.py
  • src/synthorg/budget/call_analytics_models.py
  • src/synthorg/budget/call_classifier.py
  • src/synthorg/budget/category_analytics.py
  • src/synthorg/budget/config.py
  • src/synthorg/budget/coordination_config.py
  • src/synthorg/budget/coordination_metrics.py
  • src/synthorg/budget/coordination_store.py
  • src/synthorg/budget/cost_record.py
  • src/synthorg/budget/cost_tiers.py
  • src/synthorg/budget/hierarchy.py
  • src/synthorg/budget/optimizer_models.py
  • src/synthorg/budget/project_cost_aggregate.py
  • src/synthorg/budget/quota.py
  • src/synthorg/budget/quota_poller_config.py
  • src/synthorg/budget/report_config.py
  • src/synthorg/budget/report_templates.py
  • src/synthorg/budget/reports.py
  • src/synthorg/budget/risk_check.py
  • src/synthorg/budget/risk_config.py
  • src/synthorg/budget/risk_record.py
  • src/synthorg/budget/spending_summary.py
  • src/synthorg/budget/trends.py
  • src/synthorg/communication/handler.py
  • src/synthorg/communication/loop_prevention/circuit_breaker.py
  • src/synthorg/communication/meetings/service.py
  • src/synthorg/communication/message.py
  • src/synthorg/communication/messages/service.py
  • src/synthorg/coordination/ceremony_policy/service.py
  • src/synthorg/core/agent.py
  • src/synthorg/core/approval.py
  • src/synthorg/core/artifact.py
  • src/synthorg/core/auth/config.py
  • src/synthorg/core/auth/models.py
  • src/synthorg/core/auth/refresh_record.py
  • src/synthorg/core/auth/session.py
  • src/synthorg/core/company.py
  • src/synthorg/core/domain_errors.py
  • src/synthorg/core/error_taxonomy.py
  • src/synthorg/core/evidence.py
  • src/synthorg/core/project.py
  • src/synthorg/core/resilience_config.py
  • src/synthorg/core/role.py
  • src/synthorg/core/structured_artifact.py
  • src/synthorg/core/task.py
  • src/synthorg/core/tool_disclosure.py
  • src/synthorg/engine/decisions.py
  • src/synthorg/engine/strategy/context.py
  • src/synthorg/engine/trajectory/models.py
  • src/synthorg/engine/workflow/subworkflow_registry.py
  • src/synthorg/engine/workflow/subworkflow_service.py
  • src/synthorg/hr/training/config.py
  • src/synthorg/integrations/config.py
  • src/synthorg/integrations/connections/models.py
  • src/synthorg/integrations/mcp_catalog/installations.py
  • src/synthorg/integrations/mcp_catalog/service.py
  • src/synthorg/integrations/webhooks/models.py
  • src/synthorg/memory/service.py
  • src/synthorg/meta/analytics/models.py
  • src/synthorg/meta/chief_of_staff/config.py
  • src/synthorg/meta/chief_of_staff/models.py
  • src/synthorg/meta/config.py
  • src/synthorg/meta/evolution/outcome_models.py
  • src/synthorg/meta/mcp/handlers/common.py
  • src/synthorg/meta/mcp/registry.py
  • src/synthorg/meta/models.py
  • src/synthorg/meta/reports/models.py
  • src/synthorg/meta/rollout/ab_models.py
  • src/synthorg/meta/rollout/group_aggregator.py
  • src/synthorg/meta/rollout/regression/statistical.py
  • src/synthorg/meta/rollout/regression/welch.py
  • src/synthorg/meta/rules/custom.py
  • src/synthorg/meta/signal_models.py
  • src/synthorg/meta/telemetry/config.py
  • src/synthorg/meta/telemetry/models.py
  • src/synthorg/notifications/config.py
  • src/synthorg/notifications/models.py
  • src/synthorg/observability/audit_chain/chain.py
  • src/synthorg/observability/config.py
  • src/synthorg/observability/events/memory.py
  • src/synthorg/observability/events/persistence.py
  • src/synthorg/ontology/config.py
  • src/synthorg/ontology/models.py
  • src/synthorg/ontology/service.py
  • src/synthorg/persistence/_shared/__init__.py
  • src/synthorg/persistence/_shared/pagination.py
  • src/synthorg/persistence/agent_state_protocol.py
  • src/synthorg/persistence/checkpoint_protocol.py
  • src/synthorg/persistence/circuit_breaker_protocol.py
  • src/synthorg/persistence/config.py
  • src/synthorg/persistence/idempotency_protocol.py
  • src/synthorg/persistence/memory_protocol.py
  • src/synthorg/persistence/message_protocol.py
  • src/synthorg/persistence/ontology_protocol.py
  • src/synthorg/persistence/parked_context_protocol.py
  • src/synthorg/persistence/postgres/agent_state_repo.py
  • src/synthorg/persistence/postgres/circuit_breaker_repo.py
  • src/synthorg/persistence/postgres/heartbeat_repo.py
  • src/synthorg/persistence/postgres/ontology_entity_repo.py
  • src/synthorg/persistence/postgres/org_fact_repo.py
  • src/synthorg/persistence/postgres/parked_context_repo.py
  • src/synthorg/persistence/postgres/repositories.py
  • src/synthorg/persistence/postgres/revisions/20260517000001_wp3_query_indices.sql
  • src/synthorg/persistence/postgres/schema.sql
  • src/synthorg/persistence/postgres/subworkflow_repo.py
  • src/synthorg/persistence/settings_protocol.py
  • src/synthorg/persistence/sqlite/agent_state_repo.py
  • src/synthorg/persistence/sqlite/circuit_breaker_repo.py
  • src/synthorg/persistence/sqlite/heartbeat_repo.py
  • src/synthorg/persistence/sqlite/ontology_entity_repo.py
  • src/synthorg/persistence/sqlite/org_fact_repo.py
  • src/synthorg/persistence/sqlite/parked_context_repo.py
  • src/synthorg/persistence/sqlite/repositories.py
  • src/synthorg/persistence/sqlite/revisions/20260517000001_wp3_query_indices.sql
  • src/synthorg/persistence/sqlite/schema.sql
  • src/synthorg/persistence/sqlite/subworkflow_repo.py
  • src/synthorg/persistence/subworkflow_protocol.py
  • src/synthorg/providers/cost_recording.py
  • src/synthorg/providers/management/capability_dtos.py
  • src/synthorg/settings/bootstrap_resolver.py
  • src/synthorg/settings/definitions/memory.py
  • src/synthorg/settings/errors.py
  • src/synthorg/settings/models.py
  • src/synthorg/telemetry/collector.py
  • src/synthorg/telemetry/protocol.py
  • src/synthorg/templates/preset_service.py
  • src/synthorg/tools/analytics/config.py
  • src/synthorg/tools/base.py
  • src/synthorg/tools/communication/config.py
  • src/synthorg/tools/database/config.py
  • src/synthorg/tools/design/config.py
  • src/synthorg/tools/design/image_generator.py
  • src/synthorg/tools/disclosure_config.py
  • src/synthorg/tools/git_url_validator.py
  • src/synthorg/tools/html_parse_guard.py
  • src/synthorg/tools/integrity_check.py
  • src/synthorg/tools/invocation_record.py
  • src/synthorg/tools/mcp/config.py
  • src/synthorg/tools/mcp/models.py
  • src/synthorg/tools/network_validator.py
  • src/synthorg/tools/sandbox/config.py
  • src/synthorg/tools/sandbox/docker_config.py
  • src/synthorg/tools/sandbox/lifecycle/config.py
  • src/synthorg/tools/sandbox/policy.py
  • src/synthorg/tools/sandbox/sandboxing_config.py
  • src/synthorg/tools/sub_constraint_enforcer.py
  • src/synthorg/tools/terminal/config.py
  • src/synthorg/tools/web/config.py
  • src/synthorg/versioning/models.py
  • src/synthorg/workers/claim.py
  • src/synthorg/workers/config.py
  • tests/conformance/persistence/test_core_repositories.py
  • tests/integration/engine/test_multi_agent_delegation.py
  • tests/unit/api/controllers/test_agent_identity_versions.py
  • tests/unit/api/controllers/test_memory_admin.py
  • tests/unit/api/controllers/test_workflows.py
  • tests/unit/api/fakes_workflow.py
  • tests/unit/api/rate_limits/test_controller_coverage.py
  • tests/unit/api/rate_limits/test_guard.py
  • tests/unit/api/test_dto_forbid_extra.py
  • tests/unit/api/test_etag.py
  • tests/unit/api/test_exception_handlers.py
  • tests/unit/communication/meetings/test_service.py
  • tests/unit/communication/messages/test_service.py
  • tests/unit/engine/workflow/test_subworkflow_registry.py
  • tests/unit/memory/test_service.py
  • tests/unit/persistence/_shared/test_pagination.py
  • tests/unit/persistence/test_protocol.py
  • tests/unit/scripts/test_check_frozen_model_extra_forbid.py
  • tests/unit/telemetry/test_collector.py
  • web/src/api/types/error-codes.gen.ts
  • web/src/api/types/openapi.gen.ts
💤 Files with no reviewable changes (2)
  • scripts/check_dto_forbid_extra.py
  • tests/unit/api/test_dto_forbid_extra.py

Comment thread src/synthorg/core/company.py
Comment thread src/synthorg/hr/training/config.py
Comment thread src/synthorg/memory/service.py
Comment thread src/synthorg/persistence/postgres/circuit_breaker_repo.py
Comment thread tests/unit/api/fakes_workflow.py Outdated
Comment thread tests/unit/engine/workflow/test_subworkflow_registry.py
Comment thread tests/unit/persistence/_shared/test_pagination.py
@codecov
Copy link
Copy Markdown

codecov Bot commented May 17, 2026

Codecov Report

❌ Patch coverage is 91.60000% with 42 lines in your changes missing coverage. Please review.
✅ Project coverage is 84.92%. Comparing base (f3252cd) to head (9907f0a).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/synthorg/api/controllers/memory.py 70.37% 14 Missing and 2 partials ⚠️
src/synthorg/persistence/postgres/repositories.py 73.33% 4 Missing ⚠️
src/synthorg/persistence/sqlite/repositories.py 71.42% 4 Missing ⚠️
src/synthorg/api/controllers/subworkflows.py 50.00% 3 Missing ⚠️
src/synthorg/memory/service.py 75.00% 3 Missing ⚠️
src/synthorg/api/controllers/meta.py 50.00% 2 Missing ⚠️
src/synthorg/api/controllers/settings.py 0.00% 2 Missing ⚠️
src/synthorg/persistence/_shared/pagination.py 84.61% 1 Missing and 1 partial ⚠️
...ynthorg/api/controllers/agent_identity_versions.py 66.66% 1 Missing ⚠️
src/synthorg/api/controllers/training.py 50.00% 1 Missing ⚠️
... and 4 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1953      +/-   ##
==========================================
+ Coverage   84.89%   84.92%   +0.02%     
==========================================
  Files        1858     1858              
  Lines      109992   110151     +159     
  Branches     9412     9420       +8     
==========================================
+ Hits        93380    93543     +163     
+ Misses      14308    14306       -2     
+ Partials     2304     2302       -2     

☔ 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.

Aureliolo added 2 commits May 17, 2026 15:45
CI: regenerate data/runtime_stats.yaml (tests display drift 31,000+ vs 30,000+).

CodeRabbit: core/company.py ReportingLine gains extra=forbid (WP-3 scope); hr/training/config.py caps become module-level Final[int] constants; memory/service.py docstrings and comments stripped of migration/history framing; postgres/circuit_breaker_repo.py list_items calls validate_pagination_args (sqlite parity); sqlite/subworkflow_repo.py adds _find_parents_unpaged so delete_if_unreferenced sees the full parent set (parity with postgres _find_parents_with_conn; fixes truncated parent set returned to the API); tests fakes_workflow.py and test_subworkflow_registry.py search() no longer pre-truncate; test_pagination.py asserts the terminating empty-page fetch sequence.

Gemini: postgres/subworkflow_repo.py ILIKE gets an explicit ESCAPE clause (sqlite parity); /subworkflows/search is now cursor-paginated (PaginatedResponse), openapi.gen.ts regenerated and the web endpoint/store/mocks/test updated.
…rbid

extra=forbid (added this round for the WP-3 gate) makes computed keys subordinate_key/supervisor_key non-round-trippable as constructor inputs; exclude them on model_validate, matching the project-wide forbid contract.
Round 1's cursor-pagination cascade left a TS7022 in stores/subworkflows.ts: the search/list ternary defeated return-type inference for the loop-local page. Annotate page as PaginatedResult<SubworkflowSummary> and import the type from @/api/client. Fixes Dashboard Type Check + Dashboard Build; the melange and Lighthouse failures were downstream of the build break. Verified locally: web type-check, vite build, and the subworkflows store test all green.
coderabbitai[bot]
coderabbitai Bot previously approved these changes May 17, 2026
@Aureliolo Aureliolo merged commit 504d579 into main May 17, 2026
82 checks passed
@Aureliolo Aureliolo deleted the refactor/wp3-api-conventions-query-perf branch May 17, 2026 14:29
@Aureliolo Aureliolo temporarily deployed to cloudflare-preview May 17, 2026 14:29 — with GitHub Actions Inactive
Aureliolo pushed a commit that referenced this pull request May 17, 2026
<!-- HIGHLIGHTS_START -->
## Highlights

> _AI-generated summary (model: `openai/gpt-4.1-mini` via GitHub
Models). Commit-based changelog below._

### What you'll notice
- Frontend WP-6 update with UX polish improves user interface and
workflow.
- Dashboard and training endpoint improvements enhance observability and
dispatch behavior.
- Web storybook now supports change detection for more responsive UI
interactions.
- Git hooks now isolated per worktree for cleaner repository management.
- Providers automatically detect native streaming support in Litellm
models.

### What's new
- Added a new pipeline to convert Pydantic DTOs to TypeScript for better
front-end compatibility.

### Under the hood
- Refactored settings to three precedence categories, removing YAML tier
for simpler configuration.
- Completed RootConfig mirror coverage for enhanced configuration
consistency.
- Adopted API conventions with better query performance and forbidden
extra fields for stricter validation.
- Improved persistence, layer discipline, and restart safety in core
work packages.
- CI updated with split test jobs and tightened coverage gates for
better test quality.
- Switched to direct Trivy binary for security scans, removing previous
Trivy action dependency.
- Enhanced memory management with per-call processing options and better
observability during speech-to-text encoding.
- Various dependency updates for Python, infrastructure, and lock files
maintain security and stability.
- Removed TypeScript DTO type-tightening overlays to simplify type
management.
- Codebase audit tightened skill sets to prevent false positivity in
class detection by 2026.

<!-- HIGHLIGHTS_END -->

:robot: I have created a release *beep* *boop*
---


##
[0.8.5](v0.8.4...v0.8.5)
(2026-05-17)


### Features

* **codegen:** pydantic-to-typescript DTO pipeline + parity gate (closes
[#1889](#1889))
([#1909](#1909))
([0265ef5](0265ef5))
* **storybook:** enable changeDetection + trim web/CLAUDE.md
([#1939](#1939))
([3b1f4c0](3b1f4c0))
* **web,setup:** WP-6 frontend + UX polish
([#1941](#1941))
([d9ca76d](d9ca76d))


### Bug Fixes

* correct invalid git for-each-ref syntax in post-merge-cleanup skill
([#1946](#1946))
([69a1649](69a1649))
* dashboard polish, training endpoint dispatch, and observability
cleanup ([#1911](#1911))
([b61e9e8](b61e9e8))
* per-worktree git-hook isolation + hookify gate migration + MSW drift
fix ([#1949](#1949))
([e3f8495](e3f8495))
* **providers:** read supports_native_streaming from litellm model info
([#1942](#1942))
([60364ca](60364ca))
* security and audit coverage (closes
[#1883](#1883))
([#1904](#1904))
([d8ebf55](d8ebf55))


### Performance

* **ci:** mypy --num-workers=4 + enable ruff TID255
([#1944](#1944))
([484c1d3](484c1d3))


### Refactoring

* **ci:** drop aquasecurity/trivy-action, use direct trivy binary
([#1940](#1940))
([df1f946](df1f946))
* **memory:** per-call processing_kwargs + observability for ST encode
([#1943](#1943))
([3aa9d20](3aa9d20))
* Phase 7 follow-up — complete RootConfig mirror coverage (closes
[#1907](#1907))
([#1914](#1914))
([605500b](605500b))
* **settings:** collapse precedence to three categories; drop YAML tier
(closes [#1890](#1890))
([#1910](#1910))
([efd54c9](efd54c9))
* WP-3 API conventions + query performance + project-wide extra=forbid
([#1953](#1953))
([504d579](504d579)),
closes [#1918](#1918)
* WP-4 settings + cross-cutting (clock seam, contextvars, dispatch,
plugin surfaces)
([#1954](#1954))
([7207d92](7207d92))
* **wp1:** persistence + layer discipline + restart safety
([#1945](#1945))
([57586fb](57586fb))


### Documentation

* **wp5:** public-facing truth refresh
([#1924](#1924))
([afb5cc5](afb5cc5))


### CI/CD

* split test job by marker with airtight aggregate coverage gate
([#1948](#1948))
([0b818d5](0b818d5)),
closes [#1938](#1938)
[#1937](#1937)


### Maintenance

* **codebase-audit:** tighten skill to prevent 2026-05-15 FP classes
([#1923](#1923))
([9317ed1](9317ed1))
* Lock file maintenance
([#1913](#1913))
([c08a355](c08a355))
* Lock file maintenance
([#1950](#1950))
([8940ab1](8940ab1))
* remove TS DTO type-tightening overlays
([#1915](#1915))
([d296214](d296214)),
closes [#1906](#1906)
* Update Infrastructure dependencies
([#1928](#1928))
([d19fae5](d19fae5))
* Update Python dependencies
([#1929](#1929))
([75cc2c8](75cc2c8))
* **wp7:** hygiene, stubs, test/CI/tooling, doc gaps, boundary patterns
doc ([#1926](#1926))
([c29eb32](c29eb32))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Co-authored-by: synthorg-repo-bot[bot] <279117679+synthorg-repo-bot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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.

WP-3: API Conventions + Query Performance

1 participant