feat: brownfield codebase intake (merger/acquisition entry mode)#2042
Conversation
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Repository UI (base), Organization UI (inherited) Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (80)
WalkthroughAdds a complete brownfield codebase intake feature: core structure-map domain; git-backend seed workflow; ecosystem scanners and aggregator; import service with source resolver; persistence protocol and repos (Postgres/SQLite + migrations); agent tool and factory; API startup wiring, AppState, controller with rate limiting; pipeline entry adapter and boot hook; observability events; web enum/UI updates; and extensive unit, integration, and e2e tests. Documentation updates include a new design page and catalog references. |
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
Summary of ChangesHello, 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 'brownfield' codebase intake system, enabling the platform to ingest, analyze, and index external repositories. By automating the mapping of project structures and integrating this data into the existing knowledge substrate, the system allows agents to effectively navigate and work within acquired codebases. The changes include secure source resolution, deterministic scanners, and new agent tools, all supported by robust persistence and pipeline integration. Highlights
Using Gemini Code AssistThe 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
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 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
|
There was a problem hiding this comment.
Code Review
This pull request implements the 'Brownfield Codebase Intake' feature, enabling the studio to import existing repositories into a persistent project workspace. The implementation includes a deterministic structure map model to track modules, entry points, and dependencies, an automated agent-driven analysis pass, and integration with the knowledge substrate for hybrid retrieval. The changes cover the API controller, engine pipeline, persistence layer (Postgres/SQLite), and new agent tools for querying the structure map. I have reviewed the feedback provided; all comments are actionable and address potential robustness issues in the scanner logic, so no comments were filtered out.
| packages = sorted( | ||
| { | ||
| path.rsplit("/__init__.py", 1)[0] | ||
| for path in rel_paths | ||
| if path.endswith("__init__.py") | ||
| } | ||
| ) |
There was a problem hiding this comment.
The rsplit logic for discovering Python packages fails when an __init__.py file exists at the repository root. In such cases, path.rsplit("/__init__.py", 1)[0] evaluates to "__init__.py" instead of the expected root directory ("."). This results in an incorrect module path in the structure map. Using removesuffix with a conditional check for the root level is more robust.
| packages = sorted( | |
| { | |
| path.rsplit("/__init__.py", 1)[0] | |
| for path in rel_paths | |
| if path.endswith("__init__.py") | |
| } | |
| ) | |
| packages = sorted( | |
| { | |
| path.removesuffix("/__init__.py") if "/" in path else "." | |
| for path in rel_paths | |
| if path.endswith("__init__.py") | |
| } | |
| ) |
| def _test_framework( | ||
| self, workspace_path: Path, pyproject: dict[str, Any] | ||
| ) -> str | None: | ||
| if "pytest" in str(pyproject.get("tool", {})): |
There was a problem hiding this comment.
Using str(pyproject.get("tool", {})) for framework detection is fragile and prone to false positives. It will match the string "pytest" anywhere in the tool table's values (e.g., in a plugin list for another tool like mypy). It is safer to check for the presence of the "pytest" key directly in the tool dictionary.
| if "pytest" in str(pyproject.get("tool", {})): | |
| if "pytest" in pyproject.get("tool", {}): |
| def _test_framework(self, manifest: dict[str, Any]) -> str | None: | ||
| dev = manifest.get("devDependencies", {}) | ||
| names = set(dev) if isinstance(dev, dict) else set() | ||
| for framework in _KNOWN_FRAMEWORKS: | ||
| if framework in names: | ||
| return framework | ||
| return None |
There was a problem hiding this comment.
The test framework detection only inspects devDependencies. While common, some projects may list test frameworks (like jest or vitest) in the main dependencies block. Checking both collections ensures better detection coverage.
def _test_framework(self, manifest: dict[str, Any]) -> str | None:
deps = manifest.get("dependencies", {})
dev = manifest.get("devDependencies", {})
names = set()
if isinstance(deps, dict):
names.update(deps)
if isinstance(dev, dict):
names.update(dev)
for framework in _KNOWN_FRAMEWORKS:
if framework in names:
return framework
return NoneThere was a problem hiding this comment.
Actionable comments posted: 7
🤖 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 `@docs/design/brownfield-intake.md`:
- Around line 16-30: Replace the unlabeled fenced pipeline block for the POST
/brownfield/import flow with a mermaid flowchart; specifically convert the plain
block describing POST /brownfield/import -> BrownfieldEntryAdapter.submit ->
BrownfieldImportService.import_codebase (and its steps 1..6 including
ProjectWorkspaceService.get_or_provision, BrownfieldSourceResolver.resolve,
GitBackend.seed, scan_codebase, KnowledgeService.ingest) and the subsequent
WorkItem -> agent CODEBASE_ANALYSIS -> 202 Accepted flow into a mermaid
flowchart (flowchart TD) so the diagram renders and removes the fenced-language
warning.
In `@src/synthorg/engine/brownfield/source_resolver.py`:
- Around line 95-104: The current check in source_resolver.py rejects any URL
with a username (urlsplit(source_ref).username), which incorrectly blocks valid
SSH refs like ssh://git@host/...; update the condition so it only raises
BrownfieldSourceUnavailableError when a username is embedded for non-SSH schemes
(e.g., check urlsplit(source_ref).username is not None AND the scheme is not an
SSH-type like "ssh" or "git+ssh"), leaving SSH usernames allowed; modify the
conditional around the raise in the block that references source_ref, urlsplit,
and BrownfieldSourceUnavailableError accordingly.
In `@src/synthorg/engine/workspace/git_backend/_git_ops.py`:
- Around line 274-293: The guard only checks tracked files via git(...,
"ls-files") so untracked files can bypass seeding; update the check to also
detect untracked content (for example by calling git(..., "ls-files",
"--others", "--exclude-standard") or git(..., "status", "--porcelain") and
inspect its output) and treat any non-empty result the same way as tracked files
(log GIT_BACKEND_SEED_FAILED with reason "workspace_not_empty" and raise
GitBackendSeedError with the existing message), keeping the same
project_id/event parameters used in the existing git and logger calls.
In `@src/synthorg/tools/structure_map/query_structure_map.py`:
- Around line 66-79: The ValueError/TypeError catch currently spans both
parse_typed(...) and self._repository.get(...), misclassifying
repository/data-layer errors as client argument errors; narrow the scope by
isolating argument parsing into its own try/except that catches
ValueError/TypeError from parse_typed("mcp.tool", arguments,
QueryStructureMapArgs) and returns the ToolExecutionResult with
safe_error_description, then call structure_map = await
self._repository.get(self._project_id) in a separate block so repository-raised
ValueError/TypeError propagate to their appropriate handlers (refer to
parse_typed, QueryStructureMapArgs, self._repository.get, ToolExecutionResult,
safe_error_description).
In `@tests/unit/core/test_enums.py`:
- Around line 65-66: The test increased TaskType membership to seven but
test_task_type_values still asserts only six values; update
test_task_type_values to include an assertion for the new TaskType member
(reference TaskType enum and the test_task_type_values function) by adding the
missing enum member’s expected string value so the test verifies all seven
members match their expected values; ensure the new expected string corresponds
to the actual enum constant name/value.
In `@tests/unit/engine/workspace/git_backend/test_external_remote_backend.py`:
- Line 379: The test fixture uses a real vendor hostname in the fetch_url value
(NotBlankStr("https://github.com/acme/legacy.git")); update the test to use a
vendor-neutral placeholder per guidelines (e.g.,
"https://example-provider/legacy.git" or "https://example-repo/legacy.git") so
tests remain policy-compliant—locate the NotBlankStr(...) assignment for
fetch_url in test_external_remote_backend.py and replace the domain portion with
the recommended placeholder.
In `@tests/unit/engine/workspace/git_backend/test_seed.py`:
- Around line 35-43: The _git helper uses asyncio.create_subprocess_exec and
needs a Windows subprocess-capable loop policy; on Windows detect platform
(e.g., sys.platform.startswith("win")) and temporarily set
asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy()) before
calling create_subprocess_exec (and restore the previous policy afterward) so
subprocess-based unit tests run reliably under Windows; perform this change
inside the async _git function to ensure the correct policy is active for
subprocess creation.
🪄 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: 7926f0da-796b-4aae-8c07-effcc92f6fc0
📒 Files selected for processing (74)
docs/DESIGN_SPEC.mddocs/design/brownfield-intake.mddocs/design/living-documentation.mddocs/design/persistence.mdscripts/_ghost_wiring_manifest.txtsrc/synthorg/api/app.pysrc/synthorg/api/controllers/__init__.pysrc/synthorg/api/controllers/brownfield.pysrc/synthorg/api/rate_limits/policies.pysrc/synthorg/api/state.pysrc/synthorg/core/codebase_structure_map.pysrc/synthorg/core/enums.pysrc/synthorg/engine/brownfield/__init__.pysrc/synthorg/engine/brownfield/errors.pysrc/synthorg/engine/brownfield/models.pysrc/synthorg/engine/brownfield/scanner/__init__.pysrc/synthorg/engine/brownfield/scanner/_common.pysrc/synthorg/engine/brownfield/scanner/aggregator.pysrc/synthorg/engine/brownfield/scanner/factory.pysrc/synthorg/engine/brownfield/scanner/generic_scanner.pysrc/synthorg/engine/brownfield/scanner/go_scanner.pysrc/synthorg/engine/brownfield/scanner/node_scanner.pysrc/synthorg/engine/brownfield/scanner/protocol.pysrc/synthorg/engine/brownfield/scanner/python_scanner.pysrc/synthorg/engine/brownfield/scanner/rust_scanner.pysrc/synthorg/engine/brownfield/service.pysrc/synthorg/engine/brownfield/source_resolver.pysrc/synthorg/engine/errors.pysrc/synthorg/engine/pipeline/entry/boot.pysrc/synthorg/engine/pipeline/entry/brownfield_adapter.pysrc/synthorg/engine/pipeline/entry/factory.pysrc/synthorg/engine/pipeline/models.pysrc/synthorg/engine/workspace/git_backend/__init__.pysrc/synthorg/engine/workspace/git_backend/_git_ops.pysrc/synthorg/engine/workspace/git_backend/embedded.pysrc/synthorg/engine/workspace/git_backend/external_remote.pysrc/synthorg/engine/workspace/git_backend/local_path.pysrc/synthorg/engine/workspace/git_backend/protocol.pysrc/synthorg/observability/events/brownfield.pysrc/synthorg/observability/events/persistence.pysrc/synthorg/observability/events/workspace.pysrc/synthorg/persistence/codebase_structure_map_protocol.pysrc/synthorg/persistence/postgres/backend.pysrc/synthorg/persistence/postgres/codebase_structure_map_repo.pysrc/synthorg/persistence/postgres/revisions/20260522000002_codebase_structure_map.sqlsrc/synthorg/persistence/postgres/schema.sqlsrc/synthorg/persistence/protocol.pysrc/synthorg/persistence/sqlite/_backend_accessors.pysrc/synthorg/persistence/sqlite/backend.pysrc/synthorg/persistence/sqlite/codebase_structure_map_repo.pysrc/synthorg/persistence/sqlite/revisions/20260522000002_codebase_structure_map.sqlsrc/synthorg/persistence/sqlite/schema.sqlsrc/synthorg/tools/structure_map/__init__.pysrc/synthorg/tools/structure_map/_args.pysrc/synthorg/tools/structure_map/query_structure_map.pysrc/synthorg/tools/structure_map/tool_factory.pytests/conformance/persistence/test_codebase_structure_map_repository.pytests/e2e/test_brownfield_intake_e2e.pytests/unit/api/fakes.pytests/unit/api/fakes_backend.pytests/unit/core/test_enums.pytests/unit/engine/brownfield/__init__.pytests/unit/engine/brownfield/test_scanner.pytests/unit/engine/brownfield/test_service.pytests/unit/engine/brownfield/test_source_resolver.pytests/unit/engine/pipeline/entry/test_brownfield_adapter.pytests/unit/engine/workspace/git_backend/test_external_remote_backend.pytests/unit/engine/workspace/git_backend/test_seed.pytests/unit/observability/test_events.pytests/unit/persistence/test_protocol.pytests/unit/tools/structure_map/__init__.pytests/unit/tools/structure_map/test_query_structure_map.pyweb/src/api/types/enum-values.gen.tsweb/src/api/types/openapi.gen.ts
📜 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). (11)
- GitHub Check: Deploy Preview
- GitHub Check: Build Backend
- GitHub Check: Dashboard Test
- GitHub Check: Test Integration
- GitHub Check: Test Unit
- GitHub Check: Test E2E
- GitHub Check: Test Conformance (SQLite)
- GitHub Check: CodSpeed Web benchmarks
- GitHub Check: CodSpeed Python benchmarks
- GitHub Check: Lighthouse Site
- GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (10)
**/*.{py,ts,tsx,jsx,md}
📄 CodeRabbit inference engine (CLAUDE.md)
No region/currency/locale privileged; use metric units; British English per docs/reference/regional-defaults.md
Files:
docs/DESIGN_SPEC.mdtests/unit/engine/brownfield/__init__.pydocs/design/living-documentation.mddocs/design/persistence.mdtests/unit/core/test_enums.pysrc/synthorg/engine/workspace/git_backend/_git_ops.pysrc/synthorg/tools/structure_map/__init__.pysrc/synthorg/engine/brownfield/scanner/_common.pysrc/synthorg/tools/structure_map/tool_factory.pydocs/design/brownfield-intake.mdsrc/synthorg/engine/brownfield/__init__.pytests/unit/api/fakes.pyweb/src/api/types/openapi.gen.tssrc/synthorg/engine/brownfield/scanner/factory.pysrc/synthorg/persistence/protocol.pysrc/synthorg/api/rate_limits/policies.pysrc/synthorg/observability/events/brownfield.pysrc/synthorg/engine/brownfield/scanner/__init__.pysrc/synthorg/tools/structure_map/_args.pysrc/synthorg/engine/brownfield/models.pysrc/synthorg/engine/workspace/git_backend/__init__.pysrc/synthorg/api/controllers/__init__.pytests/unit/api/fakes_backend.pysrc/synthorg/persistence/codebase_structure_map_protocol.pytests/unit/observability/test_events.pysrc/synthorg/engine/workspace/git_backend/external_remote.pyweb/src/api/types/enum-values.gen.tssrc/synthorg/engine/brownfield/scanner/protocol.pysrc/synthorg/engine/pipeline/models.pytests/unit/engine/pipeline/entry/test_brownfield_adapter.pytests/unit/engine/brownfield/test_source_resolver.pysrc/synthorg/persistence/sqlite/_backend_accessors.pysrc/synthorg/persistence/postgres/backend.pysrc/synthorg/engine/brownfield/scanner/generic_scanner.pysrc/synthorg/engine/workspace/git_backend/protocol.pytests/unit/persistence/test_protocol.pysrc/synthorg/observability/events/workspace.pysrc/synthorg/core/enums.pysrc/synthorg/tools/structure_map/query_structure_map.pysrc/synthorg/engine/workspace/git_backend/embedded.pysrc/synthorg/core/codebase_structure_map.pysrc/synthorg/engine/errors.pysrc/synthorg/api/controllers/brownfield.pysrc/synthorg/persistence/sqlite/backend.pytests/unit/engine/brownfield/test_scanner.pytests/unit/engine/brownfield/test_service.pysrc/synthorg/api/app.pysrc/synthorg/observability/events/persistence.pysrc/synthorg/engine/pipeline/entry/factory.pytests/unit/engine/workspace/git_backend/test_seed.pytests/e2e/test_brownfield_intake_e2e.pysrc/synthorg/engine/pipeline/entry/brownfield_adapter.pytests/unit/engine/workspace/git_backend/test_external_remote_backend.pysrc/synthorg/engine/brownfield/scanner/aggregator.pysrc/synthorg/engine/brownfield/source_resolver.pysrc/synthorg/engine/brownfield/service.pysrc/synthorg/engine/workspace/git_backend/local_path.pysrc/synthorg/engine/brownfield/scanner/node_scanner.pysrc/synthorg/persistence/sqlite/codebase_structure_map_repo.pytests/conformance/persistence/test_codebase_structure_map_repository.pysrc/synthorg/engine/pipeline/entry/boot.pysrc/synthorg/engine/brownfield/scanner/go_scanner.pysrc/synthorg/engine/brownfield/scanner/rust_scanner.pysrc/synthorg/engine/brownfield/errors.pysrc/synthorg/persistence/postgres/codebase_structure_map_repo.pysrc/synthorg/engine/brownfield/scanner/python_scanner.pytests/unit/tools/structure_map/test_query_structure_map.pytests/unit/tools/structure_map/__init__.pysrc/synthorg/api/state.py
**/*.md
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.md: Numerics in README + public docs sourced fromdata/runtime_stats.yamlvia<!--RS:NAME-->markers per data/README.md
Used2for architecture / nested containers;mermaidfor flowcharts / sequence / pipelines; Markdown tables for tabular data; D2 theme 200 (Dark Mauve); D2 CLI pinned to v0.7.1 in CI
Files:
docs/DESIGN_SPEC.mddocs/design/living-documentation.mddocs/design/persistence.mddocs/design/brownfield-intake.md
tests/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
tests/**/*.py: Timeout/slow failures = source-code regression; never edittests/baselines/unit_timing.jsonor anyscripts/*_baseline.{txt,json}/scripts/_*_baseline.py; both families PreToolUse-blocked; per-invocation bypass requires explicit approval (ALLOW_BASELINE_GROWTH=1 git commit)
Test markers:@pytest.mark.{unit,integration,e2e,slow}; async auto; timeout 30s global; coverage 80% min
xdist-n 8 --dist=loadfileauto-applied via pyprojectaddopts; Windows unit tests useWindowsSelectorEventLoopPolicy; subprocess tests override back
Test doubles:FakeClockfor Clock seam,mock_of[T](**overrides)for typed-boundary substitutions,SimpleNamespacefor attribute-bags; bareMagicMockat typed boundary blocked byscripts/check_mock_spec.py
Hypothesis: 10 deterministic CI examples; failures are real bugs (fix + add@example(...)); never skip/xfail flaky tests; fix fundamentally
Files:
tests/unit/engine/brownfield/__init__.pytests/unit/core/test_enums.pytests/unit/api/fakes.pytests/unit/api/fakes_backend.pytests/unit/observability/test_events.pytests/unit/engine/pipeline/entry/test_brownfield_adapter.pytests/unit/engine/brownfield/test_source_resolver.pytests/unit/persistence/test_protocol.pytests/unit/engine/brownfield/test_scanner.pytests/unit/engine/brownfield/test_service.pytests/unit/engine/workspace/git_backend/test_seed.pytests/e2e/test_brownfield_intake_e2e.pytests/unit/engine/workspace/git_backend/test_external_remote_backend.pytests/conformance/persistence/test_codebase_structure_map_repository.pytests/unit/tools/structure_map/test_query_structure_map.pytests/unit/tools/structure_map/__init__.py
⚙️ CodeRabbit configuration file
Test files do not require Google-style docstrings on classes or functions -- ruff D rules are only enforced on src/. A bare
@settings() decorator with no arguments on Hypothesis property tests is a no-op and should not be suggested -- the HYPOTHESIS_PROFILE env var controls example counts via registered profiles, which@given() honors automatically.
Files:
tests/unit/engine/brownfield/__init__.pytests/unit/core/test_enums.pytests/unit/api/fakes.pytests/unit/api/fakes_backend.pytests/unit/observability/test_events.pytests/unit/engine/pipeline/entry/test_brownfield_adapter.pytests/unit/engine/brownfield/test_source_resolver.pytests/unit/persistence/test_protocol.pytests/unit/engine/brownfield/test_scanner.pytests/unit/engine/brownfield/test_service.pytests/unit/engine/workspace/git_backend/test_seed.pytests/e2e/test_brownfield_intake_e2e.pytests/unit/engine/workspace/git_backend/test_external_remote_backend.pytests/conformance/persistence/test_codebase_structure_map_repository.pytests/unit/tools/structure_map/test_query_structure_map.pytests/unit/tools/structure_map/__init__.py
src/synthorg/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
src/synthorg/**/*.py: Onlysrc/synthorg/persistence/may import sqlite/psycopg or emit raw SQL; new repository protocols inherit from generic categories inpersistence/_generics.py; bespoke methods permitted only under ADR-0001 D7
Configuration Precedence: DB > env > code default viaSettingsService/ConfigResolver(Cat-1) or env > code default (Cat-2,read_only_post_init); Cat-3 bootstrap secrets pure env; YAML is ingestion format only, not precedence tier; noos.environ.getoutside startup
No hardcoded numeric values; numerics live insettings/definitions/; allowlist only 0/1/-1, HTTP codes, hex masks, powers-of-2, and module-level annotated named constants (NAME: int|float|Final); enforced byscripts/check_no_magic_numbers.py
Comments document WHY only; no reviewer citations, issue back-refs, or migration framing; enforced bycheck_no_review_origin_in_code.py+check_no_migration_framing.py
Nofrom __future__ import annotations(Python 3.14 has PEP 649); use PEP 758 except:except A, B:no parens unless binding
Type hints on public functions; mypy strict; Google-style docstrings; line length 88; functions <50 lines; files <800 lines
Errors follow<Domain><Condition>Errorpattern fromDomainError; never inheritException/RuntimeErrordirectly; enforced bycheck_domain_error_hierarchy.py
Pydantic v2 frozen +extra="forbid"on every frozen model project-wide; gatecheck_frozen_model_extra_forbid.py;@computed_fieldauto-exempt; per-line# lint-allow: frozen-extra-forbid -- <reason>forextra="allow"/"ignore"boundaries; use@computed_fieldfor derived; useNotBlankStrfor identifiers
Args models at every system boundary;parse_typed()for every external dict ingestion; enforced bycheck_boundary_typed.py
Immutability: usemodel_copy(update=...)orcopy.deepcopy(); deepcopy at system boundaries
Async: useasyncio.TaskGroupfor fan-out/fan-in; helpers catchException(re-raiseMemoryError/`RecursionError...
Files:
src/synthorg/engine/workspace/git_backend/_git_ops.pysrc/synthorg/tools/structure_map/__init__.pysrc/synthorg/engine/brownfield/scanner/_common.pysrc/synthorg/tools/structure_map/tool_factory.pysrc/synthorg/engine/brownfield/__init__.pysrc/synthorg/engine/brownfield/scanner/factory.pysrc/synthorg/persistence/protocol.pysrc/synthorg/api/rate_limits/policies.pysrc/synthorg/observability/events/brownfield.pysrc/synthorg/engine/brownfield/scanner/__init__.pysrc/synthorg/tools/structure_map/_args.pysrc/synthorg/engine/brownfield/models.pysrc/synthorg/engine/workspace/git_backend/__init__.pysrc/synthorg/api/controllers/__init__.pysrc/synthorg/persistence/codebase_structure_map_protocol.pysrc/synthorg/engine/workspace/git_backend/external_remote.pysrc/synthorg/engine/brownfield/scanner/protocol.pysrc/synthorg/engine/pipeline/models.pysrc/synthorg/persistence/sqlite/_backend_accessors.pysrc/synthorg/persistence/postgres/backend.pysrc/synthorg/engine/brownfield/scanner/generic_scanner.pysrc/synthorg/engine/workspace/git_backend/protocol.pysrc/synthorg/observability/events/workspace.pysrc/synthorg/core/enums.pysrc/synthorg/tools/structure_map/query_structure_map.pysrc/synthorg/engine/workspace/git_backend/embedded.pysrc/synthorg/core/codebase_structure_map.pysrc/synthorg/engine/errors.pysrc/synthorg/api/controllers/brownfield.pysrc/synthorg/persistence/sqlite/backend.pysrc/synthorg/api/app.pysrc/synthorg/observability/events/persistence.pysrc/synthorg/engine/pipeline/entry/factory.pysrc/synthorg/engine/pipeline/entry/brownfield_adapter.pysrc/synthorg/engine/brownfield/scanner/aggregator.pysrc/synthorg/engine/brownfield/source_resolver.pysrc/synthorg/engine/brownfield/service.pysrc/synthorg/engine/workspace/git_backend/local_path.pysrc/synthorg/engine/brownfield/scanner/node_scanner.pysrc/synthorg/persistence/sqlite/codebase_structure_map_repo.pysrc/synthorg/engine/pipeline/entry/boot.pysrc/synthorg/engine/brownfield/scanner/go_scanner.pysrc/synthorg/engine/brownfield/scanner/rust_scanner.pysrc/synthorg/engine/brownfield/errors.pysrc/synthorg/persistence/postgres/codebase_structure_map_repo.pysrc/synthorg/engine/brownfield/scanner/python_scanner.pysrc/synthorg/api/state.py
src/**/*.py
⚙️ CodeRabbit configuration file
This project uses Python 3.14+ with PEP 758 except syntax: "except A, B:" (comma-separated, no parentheses) is correct and mandatory -- do NOT flag it as a typo or suggest parenthesized form. The "except builtins.MemoryError, RecursionError: raise" pattern is intentional project convention for system-error propagation. When evaluating the 50-line function limit, count only the function body excluding the signature lines, decorators, and docstring. Functions 1-5 lines over due to docstrings or multi-line signatures should not be flagged. Do not suggest extracting single-use helper functions called exactly once -- this reduces readability without improving maintainability.
Files:
src/synthorg/engine/workspace/git_backend/_git_ops.pysrc/synthorg/tools/structure_map/__init__.pysrc/synthorg/engine/brownfield/scanner/_common.pysrc/synthorg/tools/structure_map/tool_factory.pysrc/synthorg/engine/brownfield/__init__.pysrc/synthorg/engine/brownfield/scanner/factory.pysrc/synthorg/persistence/protocol.pysrc/synthorg/api/rate_limits/policies.pysrc/synthorg/observability/events/brownfield.pysrc/synthorg/engine/brownfield/scanner/__init__.pysrc/synthorg/tools/structure_map/_args.pysrc/synthorg/engine/brownfield/models.pysrc/synthorg/engine/workspace/git_backend/__init__.pysrc/synthorg/api/controllers/__init__.pysrc/synthorg/persistence/codebase_structure_map_protocol.pysrc/synthorg/engine/workspace/git_backend/external_remote.pysrc/synthorg/engine/brownfield/scanner/protocol.pysrc/synthorg/engine/pipeline/models.pysrc/synthorg/persistence/sqlite/_backend_accessors.pysrc/synthorg/persistence/postgres/backend.pysrc/synthorg/engine/brownfield/scanner/generic_scanner.pysrc/synthorg/engine/workspace/git_backend/protocol.pysrc/synthorg/observability/events/workspace.pysrc/synthorg/core/enums.pysrc/synthorg/tools/structure_map/query_structure_map.pysrc/synthorg/engine/workspace/git_backend/embedded.pysrc/synthorg/core/codebase_structure_map.pysrc/synthorg/engine/errors.pysrc/synthorg/api/controllers/brownfield.pysrc/synthorg/persistence/sqlite/backend.pysrc/synthorg/api/app.pysrc/synthorg/observability/events/persistence.pysrc/synthorg/engine/pipeline/entry/factory.pysrc/synthorg/engine/pipeline/entry/brownfield_adapter.pysrc/synthorg/engine/brownfield/scanner/aggregator.pysrc/synthorg/engine/brownfield/source_resolver.pysrc/synthorg/engine/brownfield/service.pysrc/synthorg/engine/workspace/git_backend/local_path.pysrc/synthorg/engine/brownfield/scanner/node_scanner.pysrc/synthorg/persistence/sqlite/codebase_structure_map_repo.pysrc/synthorg/engine/pipeline/entry/boot.pysrc/synthorg/engine/brownfield/scanner/go_scanner.pysrc/synthorg/engine/brownfield/scanner/rust_scanner.pysrc/synthorg/engine/brownfield/errors.pysrc/synthorg/persistence/postgres/codebase_structure_map_repo.pysrc/synthorg/engine/brownfield/scanner/python_scanner.pysrc/synthorg/api/state.py
web/src/**/*.{js,jsx,ts,tsx,mts}
📄 CodeRabbit inference engine (web/CLAUDE.md)
web/src/**/*.{js,jsx,ts,tsx,mts}: Always usecreateLoggerfrom@/lib/logger; never bareconsole.warn/console.error/console.debugin application code. Variable name must always belog. Onlylogger.tsitself may use bare console methods. Uselog.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 throughsanitizeArg
Attacker-controlled fields inside structured objects must be wrapped insanitizeForLog()before embedding in log calls
Error-code constants (MANDATORY): importErrorCodeandErrorCategoryfrom@/api/types/errors(re-exported from the generatedweb/src/api/types/error-codes.gen.ts). Discriminate onErrorCode.<NAME>, never on raw integer literals.
Use@eslint-react/web-api-no-leaked-fetchto detectfetch()in effects withoutAbortControllercleanup
Files:
web/src/api/types/openapi.gen.tsweb/src/api/types/enum-values.gen.ts
web/src/api/types/**/*.gen.ts
📄 CodeRabbit inference engine (web/CLAUDE.md)
Generated DTO types (MANDATORY): NEVER hand-edit
web/src/api/types/*.gen.ts. Regenerate withuv run python scripts/generate_dto_types_ts.py. Import DTOs via the barrel (import type { AgentConfig } from '@/api/types').
Files:
web/src/api/types/openapi.gen.tsweb/src/api/types/enum-values.gen.ts
web/src/**/*.{ts,tsx,mts}
📄 CodeRabbit inference engine (web/CLAUDE.md)
web/src/**/*.{ts,tsx,mts}: Use@typescript-eslint/no-floating-promisesto 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(withchecksVoidReturn: { attributes: false }) to forbid passing async functions where the callsite ignores the returned promise. React 19asyncevent handlers stay allowed via theattributes: falseexemption.
Files:
web/src/api/types/openapi.gen.tsweb/src/api/types/enum-values.gen.ts
src/synthorg/persistence/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
src/synthorg/persistence/**/*.py: Repository CRUD:save(entity),get(id),delete(id) -> bool,list_items(...),query(...)returning tuples
Datetime in persistence: useparse_iso_utc/format_iso_utcfrompersistence._shared(reject naive); usenormalize_utcfor already-typed
Files:
src/synthorg/persistence/protocol.pysrc/synthorg/persistence/codebase_structure_map_protocol.pysrc/synthorg/persistence/sqlite/_backend_accessors.pysrc/synthorg/persistence/postgres/backend.pysrc/synthorg/persistence/sqlite/backend.pysrc/synthorg/persistence/sqlite/codebase_structure_map_repo.pysrc/synthorg/persistence/postgres/codebase_structure_map_repo.py
tests/conformance/persistence/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
Dual-backend conformance:
tests/conformance/persistence/consumesbackendfixture (SQLite + Postgres); enforced bycheck_dual_backend_test_parity.py
Files:
tests/conformance/persistence/test_codebase_structure_map_repository.py
🧠 Learnings (7)
📚 Learning: 2026-05-16T18:36:31.446Z
Learnt from: Aureliolo
Repo: Aureliolo/synthorg PR: 1944
File: docs/reference/conventions.md:787-789
Timestamp: 2026-05-16T18:36:31.446Z
Learning: In Aureliolo/synthorg, do not require adding `<!--RS:...-->` “Doc Numeric Claims (MANDATORY)” numeric macros for Python version numbers mentioned in documentation prose (e.g., “Python 3.14”, “Python 3.15”). The `scripts/check_doc_numeric_macros.py` gate only applies to `README.md`, `docs/index.md`, `docs/roadmap/index.md`, `docs/architecture/decisions.md`, and `docs/reference/convention-gates.md`, and it only flags digits adjacent to specific stat nouns (tests/providers/agents/stars/releases), not language version mentions like “Python 3.14”.
Applied to files:
docs/DESIGN_SPEC.mddocs/design/living-documentation.mddocs/design/persistence.mddocs/design/brownfield-intake.md
📚 Learning: 2026-05-16T18:36:35.250Z
Learnt from: Aureliolo
Repo: Aureliolo/synthorg PR: 1944
File: docs/getting_started.md:109-109
Timestamp: 2026-05-16T18:36:35.250Z
Learning: When reviewing Markdown in the synthorg repo, account for the CI gate `check_doc_numeric_macros.py`: it skips fenced code blocks entirely, and it only flags digits that are adjacent to these stat nouns: `tests`, `providers`, `agents`, `stars`, `releases`. Therefore, numeric examples such as CLI flag values (e.g., `--num-workers=4` in fenced bash blocks) and prose version numbers (e.g., `3.14`/`3.15`) are not expected to trigger this check; prioritize changes only when digits appear next to one of the listed nouns (e.g., “5 tests”, “10 stars”, etc.).
Applied to files:
docs/DESIGN_SPEC.mddocs/design/living-documentation.mddocs/design/persistence.mddocs/design/brownfield-intake.md
📚 Learning: 2026-05-16T18:36:35.250Z
Learnt from: Aureliolo
Repo: Aureliolo/synthorg PR: 1944
File: docs/getting_started.md:109-109
Timestamp: 2026-05-16T18:36:35.250Z
Learning: When reviewing markdown files for the "Doc Numeric Claims (MANDATORY)" RS-marker rule, only require/flag missing RS markers in the files that are actually in-scope for the rule. The scope is enforced via an identical _SCOPED_FILES allowlist in scripts/check_doc_numeric_macros.py and scripts/inject_runtime_stats.py, and currently includes: README.md; docs/index.md; docs/roadmap/index.md; docs/architecture/decisions.md; docs/reference/convention-gates.md. For any other markdown files (e.g., docs/getting_started.md, docs/guides/*), missing RS markers for numeric claims are no-ops and should NOT be flagged.
Applied to files:
docs/DESIGN_SPEC.mddocs/design/living-documentation.mddocs/design/persistence.mddocs/design/brownfield-intake.md
📚 Learning: 2026-05-16T18:36:35.250Z
Learnt from: Aureliolo
Repo: Aureliolo/synthorg PR: 1944
File: docs/getting_started.md:109-109
Timestamp: 2026-05-16T18:36:35.250Z
Learning: When reviewing Markdown in the synthorg repo against the `check_doc_numeric_macros.py` gate, account for its documented behavior: it skips fenced code blocks entirely, and it only flags digits that are adjacent to specific stat nouns (`tests`, `providers`, `agents`, `stars`, `releases`). As a result, CLI-style numbers (e.g., `--num-workers=4`) inside fenced bash code blocks should never be treated as violations of this gate; only non-fenced text needs checking, and only around those specific nouns.
Applied to files:
docs/DESIGN_SPEC.mddocs/design/living-documentation.mddocs/design/persistence.mddocs/design/brownfield-intake.md
📚 Learning: 2026-05-05T09:04:46.195Z
Learnt from: Aureliolo
Repo: Aureliolo/synthorg PR: 1760
File: scripts/_dual_backend_parity_lib.py:215-216
Timestamp: 2026-05-05T09:04:46.195Z
Learning: This repository targets Python 3.14+ and follows PEP 758. Therefore, reviewer tooling should NOT treat unparenthesized multi-exception `except` clauses written without an `as` clause (e.g., `except MemoryError, RecursionError:`) as syntax errors. Only flag `except`-clause problems when they are genuinely invalid for Python 3.14+.
Applied to files:
tests/unit/engine/brownfield/__init__.pytests/unit/core/test_enums.pysrc/synthorg/engine/workspace/git_backend/_git_ops.pysrc/synthorg/tools/structure_map/__init__.pysrc/synthorg/engine/brownfield/scanner/_common.pysrc/synthorg/tools/structure_map/tool_factory.pysrc/synthorg/engine/brownfield/__init__.pytests/unit/api/fakes.pysrc/synthorg/engine/brownfield/scanner/factory.pysrc/synthorg/persistence/protocol.pysrc/synthorg/api/rate_limits/policies.pysrc/synthorg/observability/events/brownfield.pysrc/synthorg/engine/brownfield/scanner/__init__.pysrc/synthorg/tools/structure_map/_args.pysrc/synthorg/engine/brownfield/models.pysrc/synthorg/engine/workspace/git_backend/__init__.pysrc/synthorg/api/controllers/__init__.pytests/unit/api/fakes_backend.pysrc/synthorg/persistence/codebase_structure_map_protocol.pytests/unit/observability/test_events.pysrc/synthorg/engine/workspace/git_backend/external_remote.pysrc/synthorg/engine/brownfield/scanner/protocol.pysrc/synthorg/engine/pipeline/models.pytests/unit/engine/pipeline/entry/test_brownfield_adapter.pytests/unit/engine/brownfield/test_source_resolver.pysrc/synthorg/persistence/sqlite/_backend_accessors.pysrc/synthorg/persistence/postgres/backend.pysrc/synthorg/engine/brownfield/scanner/generic_scanner.pysrc/synthorg/engine/workspace/git_backend/protocol.pytests/unit/persistence/test_protocol.pysrc/synthorg/observability/events/workspace.pysrc/synthorg/core/enums.pysrc/synthorg/tools/structure_map/query_structure_map.pysrc/synthorg/engine/workspace/git_backend/embedded.pysrc/synthorg/core/codebase_structure_map.pysrc/synthorg/engine/errors.pysrc/synthorg/api/controllers/brownfield.pysrc/synthorg/persistence/sqlite/backend.pytests/unit/engine/brownfield/test_scanner.pytests/unit/engine/brownfield/test_service.pysrc/synthorg/api/app.pysrc/synthorg/observability/events/persistence.pysrc/synthorg/engine/pipeline/entry/factory.pytests/unit/engine/workspace/git_backend/test_seed.pytests/e2e/test_brownfield_intake_e2e.pysrc/synthorg/engine/pipeline/entry/brownfield_adapter.pytests/unit/engine/workspace/git_backend/test_external_remote_backend.pysrc/synthorg/engine/brownfield/scanner/aggregator.pysrc/synthorg/engine/brownfield/source_resolver.pysrc/synthorg/engine/brownfield/service.pysrc/synthorg/engine/workspace/git_backend/local_path.pysrc/synthorg/engine/brownfield/scanner/node_scanner.pysrc/synthorg/persistence/sqlite/codebase_structure_map_repo.pytests/conformance/persistence/test_codebase_structure_map_repository.pysrc/synthorg/engine/pipeline/entry/boot.pysrc/synthorg/engine/brownfield/scanner/go_scanner.pysrc/synthorg/engine/brownfield/scanner/rust_scanner.pysrc/synthorg/engine/brownfield/errors.pysrc/synthorg/persistence/postgres/codebase_structure_map_repo.pysrc/synthorg/engine/brownfield/scanner/python_scanner.pytests/unit/tools/structure_map/test_query_structure_map.pytests/unit/tools/structure_map/__init__.pysrc/synthorg/api/state.py
📚 Learning: 2026-05-21T22:55:20.496Z
Learnt from: Aureliolo
Repo: Aureliolo/synthorg PR: 2035
File: src/synthorg/meta/toolsmith/models.py:114-114
Timestamp: 2026-05-21T22:55:20.496Z
Learning: In this repo’s “magic number” review standard, the existing gate in `scripts/check_no_magic_numbers.py` intentionally does NOT flag numeric literals used as raw call-site arguments. So, do not flag numeric literals passed as keyword arguments to Pydantic `Field()` (e.g., `Field(ge=0, le=100)` / `Field(ge=1, le=50)`)—this is an established idiom. Only treat numeric literals as “magic numbers” when they occur in the locations the gate checks (module-level assignments and function/method parameter defaults).
Applied to files:
tests/unit/engine/brownfield/__init__.pytests/unit/core/test_enums.pysrc/synthorg/engine/workspace/git_backend/_git_ops.pysrc/synthorg/tools/structure_map/__init__.pysrc/synthorg/engine/brownfield/scanner/_common.pysrc/synthorg/tools/structure_map/tool_factory.pysrc/synthorg/engine/brownfield/__init__.pytests/unit/api/fakes.pysrc/synthorg/engine/brownfield/scanner/factory.pysrc/synthorg/persistence/protocol.pysrc/synthorg/api/rate_limits/policies.pysrc/synthorg/observability/events/brownfield.pysrc/synthorg/engine/brownfield/scanner/__init__.pysrc/synthorg/tools/structure_map/_args.pysrc/synthorg/engine/brownfield/models.pysrc/synthorg/engine/workspace/git_backend/__init__.pysrc/synthorg/api/controllers/__init__.pytests/unit/api/fakes_backend.pysrc/synthorg/persistence/codebase_structure_map_protocol.pytests/unit/observability/test_events.pysrc/synthorg/engine/workspace/git_backend/external_remote.pysrc/synthorg/engine/brownfield/scanner/protocol.pysrc/synthorg/engine/pipeline/models.pytests/unit/engine/pipeline/entry/test_brownfield_adapter.pytests/unit/engine/brownfield/test_source_resolver.pysrc/synthorg/persistence/sqlite/_backend_accessors.pysrc/synthorg/persistence/postgres/backend.pysrc/synthorg/engine/brownfield/scanner/generic_scanner.pysrc/synthorg/engine/workspace/git_backend/protocol.pytests/unit/persistence/test_protocol.pysrc/synthorg/observability/events/workspace.pysrc/synthorg/core/enums.pysrc/synthorg/tools/structure_map/query_structure_map.pysrc/synthorg/engine/workspace/git_backend/embedded.pysrc/synthorg/core/codebase_structure_map.pysrc/synthorg/engine/errors.pysrc/synthorg/api/controllers/brownfield.pysrc/synthorg/persistence/sqlite/backend.pytests/unit/engine/brownfield/test_scanner.pytests/unit/engine/brownfield/test_service.pysrc/synthorg/api/app.pysrc/synthorg/observability/events/persistence.pysrc/synthorg/engine/pipeline/entry/factory.pytests/unit/engine/workspace/git_backend/test_seed.pytests/e2e/test_brownfield_intake_e2e.pysrc/synthorg/engine/pipeline/entry/brownfield_adapter.pytests/unit/engine/workspace/git_backend/test_external_remote_backend.pysrc/synthorg/engine/brownfield/scanner/aggregator.pysrc/synthorg/engine/brownfield/source_resolver.pysrc/synthorg/engine/brownfield/service.pysrc/synthorg/engine/workspace/git_backend/local_path.pysrc/synthorg/engine/brownfield/scanner/node_scanner.pysrc/synthorg/persistence/sqlite/codebase_structure_map_repo.pytests/conformance/persistence/test_codebase_structure_map_repository.pysrc/synthorg/engine/pipeline/entry/boot.pysrc/synthorg/engine/brownfield/scanner/go_scanner.pysrc/synthorg/engine/brownfield/scanner/rust_scanner.pysrc/synthorg/engine/brownfield/errors.pysrc/synthorg/persistence/postgres/codebase_structure_map_repo.pysrc/synthorg/engine/brownfield/scanner/python_scanner.pytests/unit/tools/structure_map/test_query_structure_map.pytests/unit/tools/structure_map/__init__.pysrc/synthorg/api/state.py
📚 Learning: 2026-05-21T22:55:09.289Z
Learnt from: Aureliolo
Repo: Aureliolo/synthorg PR: 2035
File: src/synthorg/meta/toolsmith/config.py:29-30
Timestamp: 2026-05-21T22:55:09.289Z
Learning: For this repo’s Pydantic configuration idiom, do not treat numeric literals passed directly as arguments to `pydantic.Field(...)` as “magic numbers” during review. This includes call-site usages like `Field(default=0.2, ge=0.0, le=1.0)` (e.g., in config models such as `ToolAuthoringConfig`, `ToolValidationConfig`, `ToolsmithConfig`). Do not request extracting those `Field(...)` numeric arguments into named constants, since the repo’s `scripts/check_no_magic_numbers.py` intentionally excludes call-site `Field(...)` numerics and relies on `Field(...)` as the canonical way to express these constraints/defaults.
Applied to files:
src/synthorg/engine/workspace/git_backend/_git_ops.pysrc/synthorg/tools/structure_map/__init__.pysrc/synthorg/engine/brownfield/scanner/_common.pysrc/synthorg/tools/structure_map/tool_factory.pysrc/synthorg/engine/brownfield/__init__.pysrc/synthorg/engine/brownfield/scanner/factory.pysrc/synthorg/persistence/protocol.pysrc/synthorg/api/rate_limits/policies.pysrc/synthorg/observability/events/brownfield.pysrc/synthorg/engine/brownfield/scanner/__init__.pysrc/synthorg/tools/structure_map/_args.pysrc/synthorg/engine/brownfield/models.pysrc/synthorg/engine/workspace/git_backend/__init__.pysrc/synthorg/api/controllers/__init__.pysrc/synthorg/persistence/codebase_structure_map_protocol.pysrc/synthorg/engine/workspace/git_backend/external_remote.pysrc/synthorg/engine/brownfield/scanner/protocol.pysrc/synthorg/engine/pipeline/models.pysrc/synthorg/persistence/sqlite/_backend_accessors.pysrc/synthorg/persistence/postgres/backend.pysrc/synthorg/engine/brownfield/scanner/generic_scanner.pysrc/synthorg/engine/workspace/git_backend/protocol.pysrc/synthorg/observability/events/workspace.pysrc/synthorg/core/enums.pysrc/synthorg/tools/structure_map/query_structure_map.pysrc/synthorg/engine/workspace/git_backend/embedded.pysrc/synthorg/core/codebase_structure_map.pysrc/synthorg/engine/errors.pysrc/synthorg/api/controllers/brownfield.pysrc/synthorg/persistence/sqlite/backend.pysrc/synthorg/api/app.pysrc/synthorg/observability/events/persistence.pysrc/synthorg/engine/pipeline/entry/factory.pysrc/synthorg/engine/pipeline/entry/brownfield_adapter.pysrc/synthorg/engine/brownfield/scanner/aggregator.pysrc/synthorg/engine/brownfield/source_resolver.pysrc/synthorg/engine/brownfield/service.pysrc/synthorg/engine/workspace/git_backend/local_path.pysrc/synthorg/engine/brownfield/scanner/node_scanner.pysrc/synthorg/persistence/sqlite/codebase_structure_map_repo.pysrc/synthorg/engine/pipeline/entry/boot.pysrc/synthorg/engine/brownfield/scanner/go_scanner.pysrc/synthorg/engine/brownfield/scanner/rust_scanner.pysrc/synthorg/engine/brownfield/errors.pysrc/synthorg/persistence/postgres/codebase_structure_map_repo.pysrc/synthorg/engine/brownfield/scanner/python_scanner.pysrc/synthorg/api/state.py
🪛 markdownlint-cli2 (0.22.1)
docs/design/brownfield-intake.md
[warning] 16-16: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🔇 Additional comments (71)
docs/DESIGN_SPEC.md (1)
32-32: LGTM!tests/unit/engine/brownfield/__init__.py (1)
1-1: LGTM!docs/design/living-documentation.md (1)
66-69: LGTM!docs/design/persistence.md (1)
79-79: LGTM!src/synthorg/tools/structure_map/__init__.py (1)
1-5: LGTM!src/synthorg/engine/brownfield/scanner/_common.py (1)
1-88: LGTM!src/synthorg/tools/structure_map/tool_factory.py (1)
22-63: LGTM!src/synthorg/persistence/postgres/revisions/20260522000002_codebase_structure_map.sql (1)
11-28: LGTM!src/synthorg/persistence/sqlite/revisions/20260522000002_codebase_structure_map.sql (1)
11-28: LGTM!src/synthorg/engine/brownfield/__init__.py (1)
1-9: LGTM!src/synthorg/persistence/sqlite/schema.sql (1)
473-491: LGTM!tests/unit/api/fakes.py (1)
633-662: LGTM!web/src/api/types/openapi.gen.ts (2)
7838-7844: LGTM!
12271-12271: LGTM!src/synthorg/engine/brownfield/scanner/factory.py (1)
1-72: LGTM!src/synthorg/persistence/protocol.py (1)
54-56: LGTM!Also applies to: 431-434
src/synthorg/api/rate_limits/policies.py (1)
86-87: LGTM!src/synthorg/persistence/postgres/schema.sql (1)
487-506: LGTM!src/synthorg/observability/events/brownfield.py (1)
1-38: LGTM!src/synthorg/engine/brownfield/scanner/__init__.py (1)
1-28: LGTM!src/synthorg/tools/structure_map/_args.py (1)
1-34: LGTM!src/synthorg/engine/brownfield/models.py (1)
1-66: LGTM!src/synthorg/engine/workspace/git_backend/__init__.py (1)
26-28: LGTM!Also applies to: 42-44
src/synthorg/api/controllers/__init__.py (1)
17-17: LGTM!Also applies to: 188-188, 225-225
tests/unit/api/fakes_backend.py (1)
33-33: LGTM!Also applies to: 606-606, 729-731
src/synthorg/persistence/codebase_structure_map_protocol.py (1)
1-87: LGTM!tests/unit/observability/test_events.py (1)
354-355: LGTM!src/synthorg/engine/workspace/git_backend/external_remote.py (1)
45-45: LGTM!Also applies to: 55-57, 69-70, 333-372
web/src/api/types/enum-values.gen.ts (1)
278-278: LGTM!Also applies to: 750-750
src/synthorg/engine/brownfield/scanner/protocol.py (1)
1-54: LGTM!src/synthorg/engine/pipeline/models.py (1)
40-40: LGTM!tests/unit/engine/pipeline/entry/test_brownfield_adapter.py (1)
1-99: LGTM!tests/unit/engine/brownfield/test_source_resolver.py (1)
1-121: LGTM!src/synthorg/persistence/sqlite/_backend_accessors.py (1)
49-51: LGTM!Also applies to: 158-158, 328-333
src/synthorg/persistence/postgres/backend.py (1)
59-61: LGTM!Also applies to: 217-219, 316-316, 384-384, 451-451, 718-723
src/synthorg/engine/brownfield/scanner/generic_scanner.py (1)
1-65: LGTM!src/synthorg/engine/workspace/git_backend/protocol.py (1)
10-10: LGTM!Also applies to: 14-14, 20-29, 31-56, 68-77, 123-145
tests/unit/persistence/test_protocol.py (1)
1139-1143: LGTM!src/synthorg/observability/events/workspace.py (1)
52-54: LGTM!src/synthorg/core/enums.py (1)
152-155: LGTM!Also applies to: 161-161, 342-342
src/synthorg/tools/structure_map/query_structure_map.py (1)
89-99: LGTM!Also applies to: 101-147
src/synthorg/engine/workspace/git_backend/embedded.py (1)
24-25: LGTM!Also applies to: 32-34, 43-45, 182-240
src/synthorg/core/codebase_structure_map.py (1)
1-181: LGTM!src/synthorg/engine/errors.py (1)
230-241: LGTM!src/synthorg/api/controllers/brownfield.py (1)
1-152: LGTM!src/synthorg/persistence/sqlite/backend.py (1)
58-60: LGTM!Also applies to: 222-224, 298-298, 462-465
tests/unit/engine/brownfield/test_scanner.py (1)
1-233: LGTM!tests/unit/engine/brownfield/test_service.py (1)
1-124: LGTM!scripts/_ghost_wiring_manifest.txt (1)
84-91: LGTM!src/synthorg/api/app.py (1)
1453-1477: LGTM!src/synthorg/observability/events/persistence.py (1)
328-349: LGTM!src/synthorg/engine/pipeline/entry/factory.py (1)
23-24: LGTM!Also applies to: 31-31, 124-150
tests/e2e/test_brownfield_intake_e2e.py (1)
1-369: LGTM!src/synthorg/engine/pipeline/entry/brownfield_adapter.py (1)
1-105: LGTM!tests/unit/engine/workspace/git_backend/test_external_remote_backend.py (1)
26-29: LGTM!Also applies to: 362-378, 380-388
src/synthorg/engine/brownfield/scanner/aggregator.py (1)
1-86: LGTM!src/synthorg/engine/brownfield/source_resolver.py (1)
1-94: LGTM!Also applies to: 105-162
src/synthorg/engine/brownfield/service.py (1)
1-223: LGTM!src/synthorg/engine/workspace/git_backend/local_path.py (1)
27-28: LGTM!Also applies to: 34-35, 43-44, 225-264
src/synthorg/engine/brownfield/scanner/node_scanner.py (1)
1-142: LGTM!src/synthorg/persistence/sqlite/codebase_structure_map_repo.py (1)
1-234: LGTM!tests/conformance/persistence/test_codebase_structure_map_repository.py (1)
1-158: LGTM!src/synthorg/engine/pipeline/entry/boot.py (1)
30-33: LGTM!Also applies to: 37-37, 304-376
src/synthorg/engine/brownfield/scanner/go_scanner.py (1)
1-114: LGTM!src/synthorg/engine/brownfield/scanner/rust_scanner.py (1)
1-134: LGTM!src/synthorg/engine/brownfield/errors.py (1)
1-60: LGTM!src/synthorg/persistence/postgres/codebase_structure_map_repo.py (1)
1-212: LGTM!src/synthorg/engine/brownfield/scanner/python_scanner.py (1)
1-179: LGTM!tests/unit/tools/structure_map/test_query_structure_map.py (1)
1-115: LGTM!tests/unit/tools/structure_map/__init__.py (1)
1-1: LGTM!src/synthorg/api/state.py (1)
181-181: LGTM!Also applies to: 227-228, 336-336, 388-388, 450-451, 531-531, 1163-1174, 1905-1983
| async def _git(cwd: Path, *args: str) -> str: | ||
| proc = await asyncio.create_subprocess_exec( | ||
| "git", | ||
| *args, | ||
| cwd=str(cwd), | ||
| env=_clean_env(), | ||
| stdout=asyncio.subprocess.PIPE, | ||
| stderr=asyncio.subprocess.PIPE, | ||
| ) |
There was a problem hiding this comment.
Add an event-loop policy override for subprocess-based unit tests.
This test uses asyncio.create_subprocess_exec but does not provide the required policy override for Windows unit runs, so it can fail under the selector policy.
Suggested patch
import asyncio
import os
+import warnings
from pathlib import Path
+from typing import Any
import pytest
from tests._shared import FakeClock
@@
pytestmark = pytest.mark.unit
+@pytest.fixture(scope="session")
+def event_loop_policy() -> Any:
+ """Enable subprocess support for this subprocess-heavy test module."""
+ with warnings.catch_warnings():
+ warnings.simplefilter("ignore", DeprecationWarning)
+ return asyncio.DefaultEventLoopPolicy() # type: ignore[attr-defined,unused-ignore]
+
+
def _clean_env() -> dict[str, str]:🤖 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 `@tests/unit/engine/workspace/git_backend/test_seed.py` around lines 35 - 43,
The _git helper uses asyncio.create_subprocess_exec and needs a Windows
subprocess-capable loop policy; on Windows detect platform (e.g.,
sys.platform.startswith("win")) and temporarily set
asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy()) before
calling create_subprocess_exec (and restore the previous policy afterward) so
subprocess-based unit tests run reliably under Windows; perform this change
inside the async _git function to ensure the correct policy is active for
subprocess creation.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #2042 +/- ##
========================================
Coverage 85.04% 85.05%
========================================
Files 2208 2233 +25
Lines 128126 129048 +922
Branches 10613 10670 +57
========================================
+ Hits 108962 109757 +795
- Misses 16488 16590 +102
- Partials 2676 2701 +25 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
08da029 to
4b9748c
Compare
There was a problem hiding this comment.
Actionable comments posted: 12
♻️ Duplicate comments (1)
tests/unit/engine/workspace/git_backend/test_seed.py (1)
35-43:⚠️ Potential issue | 🟠 Major | ⚡ Quick winRestore a subprocess-capable event-loop policy for this module.
These tests spawn real git subprocesses via
asyncio.create_subprocess_exec(), but this repo’s Windows unit runs use the selector policy by default. Without a local override, the module can fail on Windows before any seed assertions execute.Suggested patch
import asyncio import os +import sys from pathlib import Path +from typing import Any import pytest from tests._shared import FakeClock @@ pytestmark = pytest.mark.unit +@pytest.fixture(scope="module") +def event_loop_policy() -> Any: + if sys.platform.startswith("win"): + return asyncio.WindowsProactorEventLoopPolicy() + return asyncio.DefaultEventLoopPolicy() + + def _clean_env() -> dict[str, str]:#!/bin/bash set -euo pipefail file="tests/unit/engine/workspace/git_backend/test_seed.py" echo "== subprocess usage in ${file} ==" rg -n "create_subprocess_exec|event_loop_policy|Windows(Proactor|Selector)EventLoopPolicy|DefaultEventLoopPolicy" "$file" echo echo "== existing event-loop policy overrides under tests/ ==" rg -n "def event_loop_policy|Windows(Proactor|Selector)EventLoopPolicy|DefaultEventLoopPolicy" testsAs per coding guidelines, "Windows unit tests use
WindowsSelectorEventLoopPolicy; subprocess tests override back".🤖 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 `@tests/unit/engine/workspace/git_backend/test_seed.py` around lines 35 - 43, Test module spawns real subprocesses via create_subprocess_exec in _git, but on Windows the default selector policy breaks subprocesses; fix by setting a subprocess-capable event loop policy at module import for Windows (e.g. call asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy()) when running on Windows, with a safe fallback/no-op on other platforms) so create_subprocess_exec in the _git coroutine works reliably; place this policy override near the top of tests/unit/engine/workspace/git_backend/test_seed.py before any async subprocess usage and ensure it only applies when the WindowsProactorEventLoopPolicy attribute exists.
🤖 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/api/app.py`:
- Around line 1547-1562: The _wire_brownfield_intake hook currently awaits
wire_real_brownfield_entry(app_state) and will let any exception abort startup;
wrap that await in a try/except so failures are treated as best-effort: catch
Exception around the call to wire_real_brownfield_entry, log the exception
(including context and stacktrace) and do not re-raise, but only set
_brownfield_intake_installed = True on success; keep the guard using
_brownfield_intake_installed and ensure app startup continues even if
wire_real_brownfield_entry fails.
In `@src/synthorg/api/controllers/brownfield.py`:
- Around line 119-126: The import endpoint currently only applies per-minute
rate limiting but needs an inflight concurrency cap to prevent too many
simultaneous heavy imports; add a concurrency guard to the `@post`("/import")
guards list (next to require_write_access and per_op_rate_limit_from_policy)
such as per_op_concurrency_limit_from_policy("brownfield.import", key="user") or
another guard that acquires/releases a per-user semaphore before scheduling the
background work, returning 429 when the limit is reached; implement the guard
function (or reuse existing policy helpers) so it atomically
increments/decrements the in-flight count around the background task start and
integrates with the same "brownfield.import" policy key.
In `@src/synthorg/engine/brownfield/scanner/go_scanner.py`:
- Around line 29-31: The regex _REQUIRE_RE in go_scanner.py currently matches
bare words (so it picks up "retract v1.2.3") and misses some module paths;
update _REQUIRE_RE to require a module path containing at least one slash and
allow dots, hyphens and pluses in path segments (e.g. change the first capture
to require something like "<segment>/<rest>" rather than any word), e.g. make
the left capture require a '/' so lines like "require github.com/pkg/errors
v0.9.1" match and "retract v1.2.3" does not; keep the existing version capture
(v[\w.\-+]+) and apply this change to the _REQUIRE_RE definition in
go_scanner.py.
In `@src/synthorg/engine/brownfield/scanner/python_scanner.py`:
- Around line 102-103: pyproject may contain a non-table "project" key so the
chained calls like scripts = pyproject.get("project", {}).get("scripts", {}) can
raise AttributeError; update python_scanner.py to first retrieve project =
pyproject.get("project") and check isinstance(project, dict) before calling
project.get(...) (falling back to {} if not a dict), and apply the same pattern
to the other occurrence around lines 148-151 that also does chained access on
pyproject.get("project") so all accesses (scripts, dependencies, etc.) safely
degrade when "project" is not a table.
In `@src/synthorg/engine/brownfield/service.py`:
- Around line 136-137: Persisting the structure_map before calling _index causes
permanent unindexed projects when _index fails and later retries return early
due to the "unchanged" branch; change the order so that await
self._index(submission, repo_root) runs before await
self._repo.save(structure_map) (or only save after a successful index), and
ensure the unchanged-check/early-return logic around the unchanged branch still
allows re-index attempts when _index previously failed; update references to
_index, _repo.save, structure_map, submission and repo_root accordingly.
- Around line 53-63: The regex _URL_USERINFO only matches simple schemes and can
miss valid schemes like "git+ssh://" so update the pattern used by _URL_USERINFO
and the _redact_source_ref function to use the full RFC3986 scheme syntax
(scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )) when capturing the leading
scheme token, then substitute the userinfo portion as before; locate the
_URL_USERINFO definition and replace its pattern with one that matches any valid
URI scheme (so _redact_source_ref continues to call _URL_USERINFO.sub(... ) and
redact embedded "user:pass@" segments for all schemes).
In `@src/synthorg/engine/brownfield/source_resolver.py`:
- Around line 141-146: The URL netloc construction in the code that builds
authenticated HTTPS URLs (uses urlsplit -> split, hostname, token, quote,
netloc, split.port, urlunsplit) fails for IPv6 literal hosts because
split.hostname is unbracketed; detect IPv6 hosts and wrap the host in square
brackets before composing netloc. Update the logic that sets netloc to wrap
split.hostname in "[]" when the hostname contains ":" or is an IPv6 address (you
can use the ipaddress module or a simple ":" check and ensure it's not already
bracketed), then continue to append :port and the user:token@ prefix as before
so urlunsplit receives a valid netloc.
In `@src/synthorg/engine/workspace/git_backend/embedded.py`:
- Around line 209-228: In seed(), the git calls that currently raise
GitBackendPushError and emit GIT_BACKEND_PUSH_FAILED should instead use
seed-specific types/events; change the two git(...) invocations that push
REMOTE_NAME and rev-parse default_branch (they pass pid and self._cmd_timeout)
to use fail_exc=GitBackendSeedError and event=GIT_BACKEND_SEED_FAILED so
failures are typed/logged as seed failures (keep other args like project_id=pid
and cmd_timeout=self._cmd_timeout unchanged).
In
`@src/synthorg/persistence/sqlite/revisions/20260522000003_codebase_structure_map.sql`:
- Around line 16-20: The migration currently creates TEXT columns modules,
entry_points, test_suites, build_files and dependencies without validating JSON
shape; update the migration to add CHECK constraints on each column using
json_valid(column) AND json_type(column) = 'array' so only valid JSON arrays can
be written, and also mirror the exact same CHECK constraints for these columns
in the canonical schema file to keep drift checks green.
In `@tests/unit/engine/brownfield/test_source_resolver.py`:
- Around line 30-35: The test test_file_url_resolves currently only asserts
source_kind; add an assertion that the resolver also normalizes
"file://{tmp_path}" into the canonical local path by checking result.fetch_url
(from BrownfieldSourceResolver().resolve) equals the expected path string (e.g.,
str(tmp_path) or tmp_path.as_posix()) so the file:// URL is converted to the
same local-path contract used by the directory-path case.
In `@tests/unit/engine/pipeline/entry/test_brownfield_adapter.py`:
- Around line 83-86: The test currently calls adapter.submit(_submission()) and
only checks import_service.import_codebase.assert_awaited_once(), which misses
verifying the actual payload; instead assign the submission to a variable (e.g.,
submission = _submission()), call result = await adapter.submit(submission), and
replace the count-only check with
import_service.import_codebase.assert_awaited_once_with(submission) (or assert
the captured["item"] equals submission) to ensure the exact submission passed is
asserted.
---
Duplicate comments:
In `@tests/unit/engine/workspace/git_backend/test_seed.py`:
- Around line 35-43: Test module spawns real subprocesses via
create_subprocess_exec in _git, but on Windows the default selector policy
breaks subprocesses; fix by setting a subprocess-capable event loop policy at
module import for Windows (e.g. call
asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy()) when
running on Windows, with a safe fallback/no-op on other platforms) so
create_subprocess_exec in the _git coroutine works reliably; place this policy
override near the top of tests/unit/engine/workspace/git_backend/test_seed.py
before any async subprocess usage and ensure it only applies when the
WindowsProactorEventLoopPolicy attribute exists.
🪄 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: 5257f65e-a56f-40de-91a8-0815e8c3f9ba
📒 Files selected for processing (79)
docs/DESIGN_SPEC.mddocs/design/brownfield-intake.mddocs/design/living-documentation.mddocs/design/persistence.mdscripts/_ghost_wiring_manifest.txtsrc/synthorg/api/app.pysrc/synthorg/api/controllers/__init__.pysrc/synthorg/api/controllers/brownfield.pysrc/synthorg/api/rate_limits/policies.pysrc/synthorg/api/state.pysrc/synthorg/core/codebase_structure_map.pysrc/synthorg/core/enums.pysrc/synthorg/engine/brownfield/__init__.pysrc/synthorg/engine/brownfield/errors.pysrc/synthorg/engine/brownfield/models.pysrc/synthorg/engine/brownfield/scanner/__init__.pysrc/synthorg/engine/brownfield/scanner/_common.pysrc/synthorg/engine/brownfield/scanner/aggregator.pysrc/synthorg/engine/brownfield/scanner/factory.pysrc/synthorg/engine/brownfield/scanner/generic_scanner.pysrc/synthorg/engine/brownfield/scanner/go_scanner.pysrc/synthorg/engine/brownfield/scanner/node_scanner.pysrc/synthorg/engine/brownfield/scanner/protocol.pysrc/synthorg/engine/brownfield/scanner/python_scanner.pysrc/synthorg/engine/brownfield/scanner/rust_scanner.pysrc/synthorg/engine/brownfield/service.pysrc/synthorg/engine/brownfield/source_resolver.pysrc/synthorg/engine/errors.pysrc/synthorg/engine/pipeline/entry/boot.pysrc/synthorg/engine/pipeline/entry/brownfield_adapter.pysrc/synthorg/engine/pipeline/entry/factory.pysrc/synthorg/engine/pipeline/models.pysrc/synthorg/engine/workspace/git_backend/__init__.pysrc/synthorg/engine/workspace/git_backend/_git_ops.pysrc/synthorg/engine/workspace/git_backend/embedded.pysrc/synthorg/engine/workspace/git_backend/external_remote.pysrc/synthorg/engine/workspace/git_backend/local_path.pysrc/synthorg/engine/workspace/git_backend/protocol.pysrc/synthorg/observability/events/brownfield.pysrc/synthorg/observability/events/persistence.pysrc/synthorg/observability/events/workspace.pysrc/synthorg/persistence/codebase_structure_map_protocol.pysrc/synthorg/persistence/postgres/backend.pysrc/synthorg/persistence/postgres/codebase_structure_map_repo.pysrc/synthorg/persistence/postgres/revisions/20260522000003_codebase_structure_map.sqlsrc/synthorg/persistence/postgres/schema.sqlsrc/synthorg/persistence/protocol.pysrc/synthorg/persistence/sqlite/_backend_accessors.pysrc/synthorg/persistence/sqlite/backend.pysrc/synthorg/persistence/sqlite/codebase_structure_map_repo.pysrc/synthorg/persistence/sqlite/revisions/20260522000003_codebase_structure_map.sqlsrc/synthorg/persistence/sqlite/schema.sqlsrc/synthorg/tools/structure_map/__init__.pysrc/synthorg/tools/structure_map/_args.pysrc/synthorg/tools/structure_map/query_structure_map.pysrc/synthorg/tools/structure_map/tool_factory.pytests/conformance/persistence/test_codebase_structure_map_repository.pytests/e2e/test_brownfield_intake_e2e.pytests/unit/api/fakes.pytests/unit/api/fakes_backend.pytests/unit/core/test_enums.pytests/unit/engine/brownfield/__init__.pytests/unit/engine/brownfield/test_scanner.pytests/unit/engine/brownfield/test_service.pytests/unit/engine/brownfield/test_source_resolver.pytests/unit/engine/pipeline/entry/test_brownfield_adapter.pytests/unit/engine/workspace/git_backend/test_external_remote_backend.pytests/unit/engine/workspace/git_backend/test_seed.pytests/unit/observability/test_events.pytests/unit/persistence/test_protocol.pytests/unit/tools/structure_map/__init__.pytests/unit/tools/structure_map/test_query_structure_map.pyweb/src/__tests__/utils/tasks.property.test.tsweb/src/api/types/enum-values.gen.tsweb/src/api/types/openapi.gen.tsweb/src/pages/agents/TaskHistoryBar.tsxweb/src/pages/project-docs/DocList.tsxweb/src/pages/tasks/TaskFilterBar.tsxweb/src/utils/tasks.ts
📜 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). (14)
- GitHub Check: Deploy Preview
- GitHub Check: Build Backend
- GitHub Check: Build Web Assets (melange)
- GitHub Check: CodSpeed Python benchmarks
- GitHub Check: CodSpeed Web benchmarks
- GitHub Check: Lighthouse Dashboard
- GitHub Check: Lighthouse Site
- GitHub Check: Dashboard Test
- GitHub Check: Test E2E
- GitHub Check: Test Unit
- GitHub Check: Test Conformance (SQLite)
- GitHub Check: Test Integration
- GitHub Check: Analyze (python)
- GitHub Check: Analyze (javascript-typescript)
🧰 Additional context used
📓 Path-based instructions (13)
**/*.{py,ts,tsx,jsx,md}
📄 CodeRabbit inference engine (CLAUDE.md)
No region/currency/locale privileged; use metric units; British English per docs/reference/regional-defaults.md
Files:
tests/unit/engine/brownfield/__init__.pyweb/src/pages/agents/TaskHistoryBar.tsxtests/unit/tools/structure_map/__init__.pyweb/src/utils/tasks.tssrc/synthorg/tools/structure_map/__init__.pysrc/synthorg/api/controllers/__init__.pydocs/design/persistence.mdsrc/synthorg/engine/brownfield/models.pysrc/synthorg/observability/events/workspace.pysrc/synthorg/engine/brownfield/__init__.pyweb/src/__tests__/utils/tasks.property.test.tsweb/src/pages/tasks/TaskFilterBar.tsxsrc/synthorg/api/rate_limits/policies.pyweb/src/pages/project-docs/DocList.tsxweb/src/api/types/openapi.gen.tsdocs/DESIGN_SPEC.mdsrc/synthorg/observability/events/brownfield.pysrc/synthorg/engine/pipeline/models.pysrc/synthorg/engine/brownfield/scanner/protocol.pysrc/synthorg/persistence/sqlite/_backend_accessors.pydocs/design/living-documentation.mdweb/src/api/types/enum-values.gen.tssrc/synthorg/engine/brownfield/scanner/__init__.pytests/unit/observability/test_events.pytests/unit/engine/pipeline/entry/test_brownfield_adapter.pysrc/synthorg/engine/brownfield/scanner/node_scanner.pysrc/synthorg/api/app.pysrc/synthorg/engine/errors.pytests/unit/api/fakes_backend.pysrc/synthorg/engine/brownfield/scanner/go_scanner.pysrc/synthorg/engine/brownfield/scanner/aggregator.pytests/unit/api/fakes.pysrc/synthorg/engine/brownfield/scanner/generic_scanner.pysrc/synthorg/observability/events/persistence.pysrc/synthorg/persistence/codebase_structure_map_protocol.pysrc/synthorg/tools/structure_map/_args.pytests/unit/tools/structure_map/test_query_structure_map.pysrc/synthorg/engine/workspace/git_backend/protocol.pysrc/synthorg/engine/pipeline/entry/factory.pysrc/synthorg/core/enums.pysrc/synthorg/engine/brownfield/scanner/factory.pysrc/synthorg/tools/structure_map/tool_factory.pysrc/synthorg/engine/pipeline/entry/boot.pysrc/synthorg/engine/brownfield/scanner/_common.pytests/unit/core/test_enums.pysrc/synthorg/core/codebase_structure_map.pydocs/design/brownfield-intake.mdsrc/synthorg/persistence/postgres/backend.pytests/unit/engine/brownfield/test_source_resolver.pytests/unit/engine/brownfield/test_scanner.pytests/unit/engine/workspace/git_backend/test_seed.pysrc/synthorg/persistence/protocol.pysrc/synthorg/engine/brownfield/service.pysrc/synthorg/engine/workspace/git_backend/__init__.pysrc/synthorg/tools/structure_map/query_structure_map.pysrc/synthorg/engine/workspace/git_backend/local_path.pysrc/synthorg/persistence/sqlite/backend.pysrc/synthorg/engine/workspace/git_backend/external_remote.pysrc/synthorg/api/state.pytests/e2e/test_brownfield_intake_e2e.pysrc/synthorg/engine/brownfield/scanner/rust_scanner.pytests/unit/persistence/test_protocol.pysrc/synthorg/engine/brownfield/scanner/python_scanner.pysrc/synthorg/persistence/postgres/codebase_structure_map_repo.pysrc/synthorg/engine/pipeline/entry/brownfield_adapter.pysrc/synthorg/engine/workspace/git_backend/embedded.pysrc/synthorg/engine/brownfield/errors.pysrc/synthorg/engine/workspace/git_backend/_git_ops.pysrc/synthorg/persistence/sqlite/codebase_structure_map_repo.pysrc/synthorg/engine/brownfield/source_resolver.pytests/conformance/persistence/test_codebase_structure_map_repository.pysrc/synthorg/api/controllers/brownfield.pytests/unit/engine/workspace/git_backend/test_external_remote_backend.pytests/unit/engine/brownfield/test_service.py
tests/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
tests/**/*.py: Timeout/slow failures = source-code regression; never edittests/baselines/unit_timing.jsonor anyscripts/*_baseline.{txt,json}/scripts/_*_baseline.py; both families PreToolUse-blocked; per-invocation bypass requires explicit approval (ALLOW_BASELINE_GROWTH=1 git commit)
Test markers:@pytest.mark.{unit,integration,e2e,slow}; async auto; timeout 30s global; coverage 80% min
xdist-n 8 --dist=loadfileauto-applied via pyprojectaddopts; Windows unit tests useWindowsSelectorEventLoopPolicy; subprocess tests override back
Test doubles:FakeClockfor Clock seam,mock_of[T](**overrides)for typed-boundary substitutions,SimpleNamespacefor attribute-bags; bareMagicMockat typed boundary blocked byscripts/check_mock_spec.py
Hypothesis: 10 deterministic CI examples; failures are real bugs (fix + add@example(...)); never skip/xfail flaky tests; fix fundamentally
Files:
tests/unit/engine/brownfield/__init__.pytests/unit/tools/structure_map/__init__.pytests/unit/observability/test_events.pytests/unit/engine/pipeline/entry/test_brownfield_adapter.pytests/unit/api/fakes_backend.pytests/unit/api/fakes.pytests/unit/tools/structure_map/test_query_structure_map.pytests/unit/core/test_enums.pytests/unit/engine/brownfield/test_source_resolver.pytests/unit/engine/brownfield/test_scanner.pytests/unit/engine/workspace/git_backend/test_seed.pytests/e2e/test_brownfield_intake_e2e.pytests/unit/persistence/test_protocol.pytests/conformance/persistence/test_codebase_structure_map_repository.pytests/unit/engine/workspace/git_backend/test_external_remote_backend.pytests/unit/engine/brownfield/test_service.py
⚙️ CodeRabbit configuration file
Test files do not require Google-style docstrings on classes or functions -- ruff D rules are only enforced on src/. A bare
@settings() decorator with no arguments on Hypothesis property tests is a no-op and should not be suggested -- the HYPOTHESIS_PROFILE env var controls example counts via registered profiles, which@given() honors automatically.
Files:
tests/unit/engine/brownfield/__init__.pytests/unit/tools/structure_map/__init__.pytests/unit/observability/test_events.pytests/unit/engine/pipeline/entry/test_brownfield_adapter.pytests/unit/api/fakes_backend.pytests/unit/api/fakes.pytests/unit/tools/structure_map/test_query_structure_map.pytests/unit/core/test_enums.pytests/unit/engine/brownfield/test_source_resolver.pytests/unit/engine/brownfield/test_scanner.pytests/unit/engine/workspace/git_backend/test_seed.pytests/e2e/test_brownfield_intake_e2e.pytests/unit/persistence/test_protocol.pytests/conformance/persistence/test_codebase_structure_map_repository.pytests/unit/engine/workspace/git_backend/test_external_remote_backend.pytests/unit/engine/brownfield/test_service.py
web/src/**/*.{js,jsx,ts,tsx,mts}
📄 CodeRabbit inference engine (web/CLAUDE.md)
web/src/**/*.{js,jsx,ts,tsx,mts}: Always usecreateLoggerfrom@/lib/logger; never bareconsole.warn/console.error/console.debugin application code. Variable name must always belog. Onlylogger.tsitself may use bare console methods. Uselog.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 throughsanitizeArg
Attacker-controlled fields inside structured objects must be wrapped insanitizeForLog()before embedding in log calls
Error-code constants (MANDATORY): importErrorCodeandErrorCategoryfrom@/api/types/errors(re-exported from the generatedweb/src/api/types/error-codes.gen.ts). Discriminate onErrorCode.<NAME>, never on raw integer literals.
Use@eslint-react/web-api-no-leaked-fetchto detectfetch()in effects withoutAbortControllercleanup
Files:
web/src/pages/agents/TaskHistoryBar.tsxweb/src/utils/tasks.tsweb/src/__tests__/utils/tasks.property.test.tsweb/src/pages/tasks/TaskFilterBar.tsxweb/src/pages/project-docs/DocList.tsxweb/src/api/types/openapi.gen.tsweb/src/api/types/enum-values.gen.ts
web/src/**/*.{jsx,tsx}
📄 CodeRabbit inference engine (web/CLAUDE.md)
web/src/**/*.{jsx,tsx}: Use@eslint-react/no-leaked-conditional-renderingto catch the{count && <Foo />}bug where0renders verbatim. ForReactNode | undefinedprops use{value != null && value !== false && <jsx>}; for compound truthiness useBoolean(...).
Use@eslint-react/globalsto restrictwindow/document/localStorage/ etc. inside render. Hoist offenders into auseCallbackevent handler, auseEffect, or auseSyncExternalStore-backed hook.Reuse
web/src/components/ui/design tokens in Web Dashboard Design System; detail inweb/CLAUDE.md
Files:
web/src/pages/agents/TaskHistoryBar.tsxweb/src/pages/tasks/TaskFilterBar.tsxweb/src/pages/project-docs/DocList.tsx
web/src/**/*.{ts,tsx,mts}
📄 CodeRabbit inference engine (web/CLAUDE.md)
web/src/**/*.{ts,tsx,mts}: Use@typescript-eslint/no-floating-promisesto 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(withchecksVoidReturn: { attributes: false }) to forbid passing async functions where the callsite ignores the returned promise. React 19asyncevent handlers stay allowed via theattributes: falseexemption.
Files:
web/src/pages/agents/TaskHistoryBar.tsxweb/src/utils/tasks.tsweb/src/__tests__/utils/tasks.property.test.tsweb/src/pages/tasks/TaskFilterBar.tsxweb/src/pages/project-docs/DocList.tsxweb/src/api/types/openapi.gen.tsweb/src/api/types/enum-values.gen.ts
web/src/{components,utils}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (web/CLAUDE.md)
NEVER write
getXIcon(value): LucideIconfactories called inside JSX bodies. Export a<XIcon value={...} />wrapper that does the lookup viacreateElementinside the wrapper body. Wrapper components live in their own file, not alongside utility exports.
Files:
web/src/utils/tasks.ts
src/synthorg/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
src/synthorg/**/*.py: Onlysrc/synthorg/persistence/may import sqlite/psycopg or emit raw SQL; new repository protocols inherit from generic categories inpersistence/_generics.py; bespoke methods permitted only under ADR-0001 D7
Configuration Precedence: DB > env > code default viaSettingsService/ConfigResolver(Cat-1) or env > code default (Cat-2,read_only_post_init); Cat-3 bootstrap secrets pure env; YAML is ingestion format only, not precedence tier; noos.environ.getoutside startup
No hardcoded numeric values; numerics live insettings/definitions/; allowlist only 0/1/-1, HTTP codes, hex masks, powers-of-2, and module-level annotated named constants (NAME: int|float|Final); enforced byscripts/check_no_magic_numbers.py
Comments document WHY only; no reviewer citations, issue back-refs, or migration framing; enforced bycheck_no_review_origin_in_code.py+check_no_migration_framing.py
Nofrom __future__ import annotations(Python 3.14 has PEP 649); use PEP 758 except:except A, B:no parens unless binding
Type hints on public functions; mypy strict; Google-style docstrings; line length 88; functions <50 lines; files <800 lines
Errors follow<Domain><Condition>Errorpattern fromDomainError; never inheritException/RuntimeErrordirectly; enforced bycheck_domain_error_hierarchy.py
Pydantic v2 frozen +extra="forbid"on every frozen model project-wide; gatecheck_frozen_model_extra_forbid.py;@computed_fieldauto-exempt; per-line# lint-allow: frozen-extra-forbid -- <reason>forextra="allow"/"ignore"boundaries; use@computed_fieldfor derived; useNotBlankStrfor identifiers
Args models at every system boundary;parse_typed()for every external dict ingestion; enforced bycheck_boundary_typed.py
Immutability: usemodel_copy(update=...)orcopy.deepcopy(); deepcopy at system boundaries
Async: useasyncio.TaskGroupfor fan-out/fan-in; helpers catchException(re-raiseMemoryError/`RecursionError...
Files:
src/synthorg/tools/structure_map/__init__.pysrc/synthorg/api/controllers/__init__.pysrc/synthorg/engine/brownfield/models.pysrc/synthorg/observability/events/workspace.pysrc/synthorg/engine/brownfield/__init__.pysrc/synthorg/api/rate_limits/policies.pysrc/synthorg/observability/events/brownfield.pysrc/synthorg/engine/pipeline/models.pysrc/synthorg/engine/brownfield/scanner/protocol.pysrc/synthorg/persistence/sqlite/_backend_accessors.pysrc/synthorg/engine/brownfield/scanner/__init__.pysrc/synthorg/engine/brownfield/scanner/node_scanner.pysrc/synthorg/api/app.pysrc/synthorg/engine/errors.pysrc/synthorg/engine/brownfield/scanner/go_scanner.pysrc/synthorg/engine/brownfield/scanner/aggregator.pysrc/synthorg/engine/brownfield/scanner/generic_scanner.pysrc/synthorg/observability/events/persistence.pysrc/synthorg/persistence/codebase_structure_map_protocol.pysrc/synthorg/tools/structure_map/_args.pysrc/synthorg/engine/workspace/git_backend/protocol.pysrc/synthorg/engine/pipeline/entry/factory.pysrc/synthorg/core/enums.pysrc/synthorg/engine/brownfield/scanner/factory.pysrc/synthorg/tools/structure_map/tool_factory.pysrc/synthorg/engine/pipeline/entry/boot.pysrc/synthorg/engine/brownfield/scanner/_common.pysrc/synthorg/core/codebase_structure_map.pysrc/synthorg/persistence/postgres/backend.pysrc/synthorg/persistence/protocol.pysrc/synthorg/engine/brownfield/service.pysrc/synthorg/engine/workspace/git_backend/__init__.pysrc/synthorg/tools/structure_map/query_structure_map.pysrc/synthorg/engine/workspace/git_backend/local_path.pysrc/synthorg/persistence/sqlite/backend.pysrc/synthorg/engine/workspace/git_backend/external_remote.pysrc/synthorg/api/state.pysrc/synthorg/engine/brownfield/scanner/rust_scanner.pysrc/synthorg/engine/brownfield/scanner/python_scanner.pysrc/synthorg/persistence/postgres/codebase_structure_map_repo.pysrc/synthorg/engine/pipeline/entry/brownfield_adapter.pysrc/synthorg/engine/workspace/git_backend/embedded.pysrc/synthorg/engine/brownfield/errors.pysrc/synthorg/engine/workspace/git_backend/_git_ops.pysrc/synthorg/persistence/sqlite/codebase_structure_map_repo.pysrc/synthorg/engine/brownfield/source_resolver.pysrc/synthorg/api/controllers/brownfield.py
src/**/*.py
⚙️ CodeRabbit configuration file
This project uses Python 3.14+ with PEP 758 except syntax: "except A, B:" (comma-separated, no parentheses) is correct and mandatory -- do NOT flag it as a typo or suggest parenthesized form. The "except builtins.MemoryError, RecursionError: raise" pattern is intentional project convention for system-error propagation. When evaluating the 50-line function limit, count only the function body excluding the signature lines, decorators, and docstring. Functions 1-5 lines over due to docstrings or multi-line signatures should not be flagged. Do not suggest extracting single-use helper functions called exactly once -- this reduces readability without improving maintainability.
Files:
src/synthorg/tools/structure_map/__init__.pysrc/synthorg/api/controllers/__init__.pysrc/synthorg/engine/brownfield/models.pysrc/synthorg/observability/events/workspace.pysrc/synthorg/engine/brownfield/__init__.pysrc/synthorg/api/rate_limits/policies.pysrc/synthorg/observability/events/brownfield.pysrc/synthorg/engine/pipeline/models.pysrc/synthorg/engine/brownfield/scanner/protocol.pysrc/synthorg/persistence/sqlite/_backend_accessors.pysrc/synthorg/engine/brownfield/scanner/__init__.pysrc/synthorg/engine/brownfield/scanner/node_scanner.pysrc/synthorg/api/app.pysrc/synthorg/engine/errors.pysrc/synthorg/engine/brownfield/scanner/go_scanner.pysrc/synthorg/engine/brownfield/scanner/aggregator.pysrc/synthorg/engine/brownfield/scanner/generic_scanner.pysrc/synthorg/observability/events/persistence.pysrc/synthorg/persistence/codebase_structure_map_protocol.pysrc/synthorg/tools/structure_map/_args.pysrc/synthorg/engine/workspace/git_backend/protocol.pysrc/synthorg/engine/pipeline/entry/factory.pysrc/synthorg/core/enums.pysrc/synthorg/engine/brownfield/scanner/factory.pysrc/synthorg/tools/structure_map/tool_factory.pysrc/synthorg/engine/pipeline/entry/boot.pysrc/synthorg/engine/brownfield/scanner/_common.pysrc/synthorg/core/codebase_structure_map.pysrc/synthorg/persistence/postgres/backend.pysrc/synthorg/persistence/protocol.pysrc/synthorg/engine/brownfield/service.pysrc/synthorg/engine/workspace/git_backend/__init__.pysrc/synthorg/tools/structure_map/query_structure_map.pysrc/synthorg/engine/workspace/git_backend/local_path.pysrc/synthorg/persistence/sqlite/backend.pysrc/synthorg/engine/workspace/git_backend/external_remote.pysrc/synthorg/api/state.pysrc/synthorg/engine/brownfield/scanner/rust_scanner.pysrc/synthorg/engine/brownfield/scanner/python_scanner.pysrc/synthorg/persistence/postgres/codebase_structure_map_repo.pysrc/synthorg/engine/pipeline/entry/brownfield_adapter.pysrc/synthorg/engine/workspace/git_backend/embedded.pysrc/synthorg/engine/brownfield/errors.pysrc/synthorg/engine/workspace/git_backend/_git_ops.pysrc/synthorg/persistence/sqlite/codebase_structure_map_repo.pysrc/synthorg/engine/brownfield/source_resolver.pysrc/synthorg/api/controllers/brownfield.py
**/*.md
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.md: Numerics in README + public docs sourced fromdata/runtime_stats.yamlvia<!--RS:NAME-->markers per data/README.md
Used2for architecture / nested containers;mermaidfor flowcharts / sequence / pipelines; Markdown tables for tabular data; D2 theme 200 (Dark Mauve); D2 CLI pinned to v0.7.1 in CI
Files:
docs/design/persistence.mddocs/DESIGN_SPEC.mddocs/design/living-documentation.mddocs/design/brownfield-intake.md
web/src/{stores,**/*.test.{ts,tsx}}
📄 CodeRabbit inference engine (web/CLAUDE.md)
Active-handle gate (MANDATORY): every unit test runs under
web/test-infra/active-handle-tracker.ts, which fails any test that leaks an event-loop-holding resource. A new store that schedules timers / attaches listeners MUST expose a teardown hook and register it in the globalafterEach; otherwise the gate fails the first test that triggers the schedule.
Files:
web/src/__tests__/utils/tasks.property.test.ts
web/src/api/types/**/*.gen.ts
📄 CodeRabbit inference engine (web/CLAUDE.md)
Generated DTO types (MANDATORY): NEVER hand-edit
web/src/api/types/*.gen.ts. Regenerate withuv run python scripts/generate_dto_types_ts.py. Import DTOs via the barrel (import type { AgentConfig } from '@/api/types').
Files:
web/src/api/types/openapi.gen.tsweb/src/api/types/enum-values.gen.ts
src/synthorg/persistence/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
src/synthorg/persistence/**/*.py: Repository CRUD:save(entity),get(id),delete(id) -> bool,list_items(...),query(...)returning tuples
Datetime in persistence: useparse_iso_utc/format_iso_utcfrompersistence._shared(reject naive); usenormalize_utcfor already-typed
Files:
src/synthorg/persistence/sqlite/_backend_accessors.pysrc/synthorg/persistence/codebase_structure_map_protocol.pysrc/synthorg/persistence/postgres/backend.pysrc/synthorg/persistence/protocol.pysrc/synthorg/persistence/sqlite/backend.pysrc/synthorg/persistence/postgres/codebase_structure_map_repo.pysrc/synthorg/persistence/sqlite/codebase_structure_map_repo.py
tests/conformance/persistence/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
Dual-backend conformance:
tests/conformance/persistence/consumesbackendfixture (SQLite + Postgres); enforced bycheck_dual_backend_test_parity.py
Files:
tests/conformance/persistence/test_codebase_structure_map_repository.py
🧠 Learnings (7)
📚 Learning: 2026-05-05T09:04:46.195Z
Learnt from: Aureliolo
Repo: Aureliolo/synthorg PR: 1760
File: scripts/_dual_backend_parity_lib.py:215-216
Timestamp: 2026-05-05T09:04:46.195Z
Learning: This repository targets Python 3.14+ and follows PEP 758. Therefore, reviewer tooling should NOT treat unparenthesized multi-exception `except` clauses written without an `as` clause (e.g., `except MemoryError, RecursionError:`) as syntax errors. Only flag `except`-clause problems when they are genuinely invalid for Python 3.14+.
Applied to files:
tests/unit/engine/brownfield/__init__.pytests/unit/tools/structure_map/__init__.pysrc/synthorg/tools/structure_map/__init__.pysrc/synthorg/api/controllers/__init__.pysrc/synthorg/engine/brownfield/models.pysrc/synthorg/observability/events/workspace.pysrc/synthorg/engine/brownfield/__init__.pysrc/synthorg/api/rate_limits/policies.pysrc/synthorg/observability/events/brownfield.pysrc/synthorg/engine/pipeline/models.pysrc/synthorg/engine/brownfield/scanner/protocol.pysrc/synthorg/persistence/sqlite/_backend_accessors.pysrc/synthorg/engine/brownfield/scanner/__init__.pytests/unit/observability/test_events.pytests/unit/engine/pipeline/entry/test_brownfield_adapter.pysrc/synthorg/engine/brownfield/scanner/node_scanner.pysrc/synthorg/api/app.pysrc/synthorg/engine/errors.pytests/unit/api/fakes_backend.pysrc/synthorg/engine/brownfield/scanner/go_scanner.pysrc/synthorg/engine/brownfield/scanner/aggregator.pytests/unit/api/fakes.pysrc/synthorg/engine/brownfield/scanner/generic_scanner.pysrc/synthorg/observability/events/persistence.pysrc/synthorg/persistence/codebase_structure_map_protocol.pysrc/synthorg/tools/structure_map/_args.pytests/unit/tools/structure_map/test_query_structure_map.pysrc/synthorg/engine/workspace/git_backend/protocol.pysrc/synthorg/engine/pipeline/entry/factory.pysrc/synthorg/core/enums.pysrc/synthorg/engine/brownfield/scanner/factory.pysrc/synthorg/tools/structure_map/tool_factory.pysrc/synthorg/engine/pipeline/entry/boot.pysrc/synthorg/engine/brownfield/scanner/_common.pytests/unit/core/test_enums.pysrc/synthorg/core/codebase_structure_map.pysrc/synthorg/persistence/postgres/backend.pytests/unit/engine/brownfield/test_source_resolver.pytests/unit/engine/brownfield/test_scanner.pytests/unit/engine/workspace/git_backend/test_seed.pysrc/synthorg/persistence/protocol.pysrc/synthorg/engine/brownfield/service.pysrc/synthorg/engine/workspace/git_backend/__init__.pysrc/synthorg/tools/structure_map/query_structure_map.pysrc/synthorg/engine/workspace/git_backend/local_path.pysrc/synthorg/persistence/sqlite/backend.pysrc/synthorg/engine/workspace/git_backend/external_remote.pysrc/synthorg/api/state.pytests/e2e/test_brownfield_intake_e2e.pysrc/synthorg/engine/brownfield/scanner/rust_scanner.pytests/unit/persistence/test_protocol.pysrc/synthorg/engine/brownfield/scanner/python_scanner.pysrc/synthorg/persistence/postgres/codebase_structure_map_repo.pysrc/synthorg/engine/pipeline/entry/brownfield_adapter.pysrc/synthorg/engine/workspace/git_backend/embedded.pysrc/synthorg/engine/brownfield/errors.pysrc/synthorg/engine/workspace/git_backend/_git_ops.pysrc/synthorg/persistence/sqlite/codebase_structure_map_repo.pysrc/synthorg/engine/brownfield/source_resolver.pytests/conformance/persistence/test_codebase_structure_map_repository.pysrc/synthorg/api/controllers/brownfield.pytests/unit/engine/workspace/git_backend/test_external_remote_backend.pytests/unit/engine/brownfield/test_service.py
📚 Learning: 2026-05-21T22:55:20.496Z
Learnt from: Aureliolo
Repo: Aureliolo/synthorg PR: 2035
File: src/synthorg/meta/toolsmith/models.py:114-114
Timestamp: 2026-05-21T22:55:20.496Z
Learning: In this repo’s “magic number” review standard, the existing gate in `scripts/check_no_magic_numbers.py` intentionally does NOT flag numeric literals used as raw call-site arguments. So, do not flag numeric literals passed as keyword arguments to Pydantic `Field()` (e.g., `Field(ge=0, le=100)` / `Field(ge=1, le=50)`)—this is an established idiom. Only treat numeric literals as “magic numbers” when they occur in the locations the gate checks (module-level assignments and function/method parameter defaults).
Applied to files:
tests/unit/engine/brownfield/__init__.pytests/unit/tools/structure_map/__init__.pysrc/synthorg/tools/structure_map/__init__.pysrc/synthorg/api/controllers/__init__.pysrc/synthorg/engine/brownfield/models.pysrc/synthorg/observability/events/workspace.pysrc/synthorg/engine/brownfield/__init__.pysrc/synthorg/api/rate_limits/policies.pysrc/synthorg/observability/events/brownfield.pysrc/synthorg/engine/pipeline/models.pysrc/synthorg/engine/brownfield/scanner/protocol.pysrc/synthorg/persistence/sqlite/_backend_accessors.pysrc/synthorg/engine/brownfield/scanner/__init__.pytests/unit/observability/test_events.pytests/unit/engine/pipeline/entry/test_brownfield_adapter.pysrc/synthorg/engine/brownfield/scanner/node_scanner.pysrc/synthorg/api/app.pysrc/synthorg/engine/errors.pytests/unit/api/fakes_backend.pysrc/synthorg/engine/brownfield/scanner/go_scanner.pysrc/synthorg/engine/brownfield/scanner/aggregator.pytests/unit/api/fakes.pysrc/synthorg/engine/brownfield/scanner/generic_scanner.pysrc/synthorg/observability/events/persistence.pysrc/synthorg/persistence/codebase_structure_map_protocol.pysrc/synthorg/tools/structure_map/_args.pytests/unit/tools/structure_map/test_query_structure_map.pysrc/synthorg/engine/workspace/git_backend/protocol.pysrc/synthorg/engine/pipeline/entry/factory.pysrc/synthorg/core/enums.pysrc/synthorg/engine/brownfield/scanner/factory.pysrc/synthorg/tools/structure_map/tool_factory.pysrc/synthorg/engine/pipeline/entry/boot.pysrc/synthorg/engine/brownfield/scanner/_common.pytests/unit/core/test_enums.pysrc/synthorg/core/codebase_structure_map.pysrc/synthorg/persistence/postgres/backend.pytests/unit/engine/brownfield/test_source_resolver.pytests/unit/engine/brownfield/test_scanner.pytests/unit/engine/workspace/git_backend/test_seed.pysrc/synthorg/persistence/protocol.pysrc/synthorg/engine/brownfield/service.pysrc/synthorg/engine/workspace/git_backend/__init__.pysrc/synthorg/tools/structure_map/query_structure_map.pysrc/synthorg/engine/workspace/git_backend/local_path.pysrc/synthorg/persistence/sqlite/backend.pysrc/synthorg/engine/workspace/git_backend/external_remote.pysrc/synthorg/api/state.pytests/e2e/test_brownfield_intake_e2e.pysrc/synthorg/engine/brownfield/scanner/rust_scanner.pytests/unit/persistence/test_protocol.pysrc/synthorg/engine/brownfield/scanner/python_scanner.pysrc/synthorg/persistence/postgres/codebase_structure_map_repo.pysrc/synthorg/engine/pipeline/entry/brownfield_adapter.pysrc/synthorg/engine/workspace/git_backend/embedded.pysrc/synthorg/engine/brownfield/errors.pysrc/synthorg/engine/workspace/git_backend/_git_ops.pysrc/synthorg/persistence/sqlite/codebase_structure_map_repo.pysrc/synthorg/engine/brownfield/source_resolver.pytests/conformance/persistence/test_codebase_structure_map_repository.pysrc/synthorg/api/controllers/brownfield.pytests/unit/engine/workspace/git_backend/test_external_remote_backend.pytests/unit/engine/brownfield/test_service.py
📚 Learning: 2026-05-21T22:55:09.289Z
Learnt from: Aureliolo
Repo: Aureliolo/synthorg PR: 2035
File: src/synthorg/meta/toolsmith/config.py:29-30
Timestamp: 2026-05-21T22:55:09.289Z
Learning: For this repo’s Pydantic configuration idiom, do not treat numeric literals passed directly as arguments to `pydantic.Field(...)` as “magic numbers” during review. This includes call-site usages like `Field(default=0.2, ge=0.0, le=1.0)` (e.g., in config models such as `ToolAuthoringConfig`, `ToolValidationConfig`, `ToolsmithConfig`). Do not request extracting those `Field(...)` numeric arguments into named constants, since the repo’s `scripts/check_no_magic_numbers.py` intentionally excludes call-site `Field(...)` numerics and relies on `Field(...)` as the canonical way to express these constraints/defaults.
Applied to files:
src/synthorg/tools/structure_map/__init__.pysrc/synthorg/api/controllers/__init__.pysrc/synthorg/engine/brownfield/models.pysrc/synthorg/observability/events/workspace.pysrc/synthorg/engine/brownfield/__init__.pysrc/synthorg/api/rate_limits/policies.pysrc/synthorg/observability/events/brownfield.pysrc/synthorg/engine/pipeline/models.pysrc/synthorg/engine/brownfield/scanner/protocol.pysrc/synthorg/persistence/sqlite/_backend_accessors.pysrc/synthorg/engine/brownfield/scanner/__init__.pysrc/synthorg/engine/brownfield/scanner/node_scanner.pysrc/synthorg/api/app.pysrc/synthorg/engine/errors.pysrc/synthorg/engine/brownfield/scanner/go_scanner.pysrc/synthorg/engine/brownfield/scanner/aggregator.pysrc/synthorg/engine/brownfield/scanner/generic_scanner.pysrc/synthorg/observability/events/persistence.pysrc/synthorg/persistence/codebase_structure_map_protocol.pysrc/synthorg/tools/structure_map/_args.pysrc/synthorg/engine/workspace/git_backend/protocol.pysrc/synthorg/engine/pipeline/entry/factory.pysrc/synthorg/core/enums.pysrc/synthorg/engine/brownfield/scanner/factory.pysrc/synthorg/tools/structure_map/tool_factory.pysrc/synthorg/engine/pipeline/entry/boot.pysrc/synthorg/engine/brownfield/scanner/_common.pysrc/synthorg/core/codebase_structure_map.pysrc/synthorg/persistence/postgres/backend.pysrc/synthorg/persistence/protocol.pysrc/synthorg/engine/brownfield/service.pysrc/synthorg/engine/workspace/git_backend/__init__.pysrc/synthorg/tools/structure_map/query_structure_map.pysrc/synthorg/engine/workspace/git_backend/local_path.pysrc/synthorg/persistence/sqlite/backend.pysrc/synthorg/engine/workspace/git_backend/external_remote.pysrc/synthorg/api/state.pysrc/synthorg/engine/brownfield/scanner/rust_scanner.pysrc/synthorg/engine/brownfield/scanner/python_scanner.pysrc/synthorg/persistence/postgres/codebase_structure_map_repo.pysrc/synthorg/engine/pipeline/entry/brownfield_adapter.pysrc/synthorg/engine/workspace/git_backend/embedded.pysrc/synthorg/engine/brownfield/errors.pysrc/synthorg/engine/workspace/git_backend/_git_ops.pysrc/synthorg/persistence/sqlite/codebase_structure_map_repo.pysrc/synthorg/engine/brownfield/source_resolver.pysrc/synthorg/api/controllers/brownfield.py
📚 Learning: 2026-05-16T18:36:31.446Z
Learnt from: Aureliolo
Repo: Aureliolo/synthorg PR: 1944
File: docs/reference/conventions.md:787-789
Timestamp: 2026-05-16T18:36:31.446Z
Learning: In Aureliolo/synthorg, do not require adding `<!--RS:...-->` “Doc Numeric Claims (MANDATORY)” numeric macros for Python version numbers mentioned in documentation prose (e.g., “Python 3.14”, “Python 3.15”). The `scripts/check_doc_numeric_macros.py` gate only applies to `README.md`, `docs/index.md`, `docs/roadmap/index.md`, `docs/architecture/decisions.md`, and `docs/reference/convention-gates.md`, and it only flags digits adjacent to specific stat nouns (tests/providers/agents/stars/releases), not language version mentions like “Python 3.14”.
Applied to files:
docs/design/persistence.mddocs/DESIGN_SPEC.mddocs/design/living-documentation.mddocs/design/brownfield-intake.md
📚 Learning: 2026-05-16T18:36:35.250Z
Learnt from: Aureliolo
Repo: Aureliolo/synthorg PR: 1944
File: docs/getting_started.md:109-109
Timestamp: 2026-05-16T18:36:35.250Z
Learning: When reviewing Markdown in the synthorg repo, account for the CI gate `check_doc_numeric_macros.py`: it skips fenced code blocks entirely, and it only flags digits that are adjacent to these stat nouns: `tests`, `providers`, `agents`, `stars`, `releases`. Therefore, numeric examples such as CLI flag values (e.g., `--num-workers=4` in fenced bash blocks) and prose version numbers (e.g., `3.14`/`3.15`) are not expected to trigger this check; prioritize changes only when digits appear next to one of the listed nouns (e.g., “5 tests”, “10 stars”, etc.).
Applied to files:
docs/design/persistence.mddocs/DESIGN_SPEC.mddocs/design/living-documentation.mddocs/design/brownfield-intake.md
📚 Learning: 2026-05-16T18:36:35.250Z
Learnt from: Aureliolo
Repo: Aureliolo/synthorg PR: 1944
File: docs/getting_started.md:109-109
Timestamp: 2026-05-16T18:36:35.250Z
Learning: When reviewing markdown files for the "Doc Numeric Claims (MANDATORY)" RS-marker rule, only require/flag missing RS markers in the files that are actually in-scope for the rule. The scope is enforced via an identical _SCOPED_FILES allowlist in scripts/check_doc_numeric_macros.py and scripts/inject_runtime_stats.py, and currently includes: README.md; docs/index.md; docs/roadmap/index.md; docs/architecture/decisions.md; docs/reference/convention-gates.md. For any other markdown files (e.g., docs/getting_started.md, docs/guides/*), missing RS markers for numeric claims are no-ops and should NOT be flagged.
Applied to files:
docs/design/persistence.mddocs/DESIGN_SPEC.mddocs/design/living-documentation.mddocs/design/brownfield-intake.md
📚 Learning: 2026-05-16T18:36:35.250Z
Learnt from: Aureliolo
Repo: Aureliolo/synthorg PR: 1944
File: docs/getting_started.md:109-109
Timestamp: 2026-05-16T18:36:35.250Z
Learning: When reviewing Markdown in the synthorg repo against the `check_doc_numeric_macros.py` gate, account for its documented behavior: it skips fenced code blocks entirely, and it only flags digits that are adjacent to specific stat nouns (`tests`, `providers`, `agents`, `stars`, `releases`). As a result, CLI-style numbers (e.g., `--num-workers=4`) inside fenced bash code blocks should never be treated as violations of this gate; only non-fenced text needs checking, and only around those specific nouns.
Applied to files:
docs/design/persistence.mddocs/DESIGN_SPEC.mddocs/design/living-documentation.mddocs/design/brownfield-intake.md
🔇 Additional comments (71)
docs/DESIGN_SPEC.md (1)
32-32: LGTM!docs/design/brownfield-intake.md (1)
1-135: LGTM!docs/design/living-documentation.md (1)
66-68: LGTM!docs/design/persistence.md (1)
79-79: LGTM!src/synthorg/core/codebase_structure_map.py (1)
1-180: LGTM!src/synthorg/core/enums.py (1)
152-155: LGTM!Also applies to: 161-161, 203-247, 388-388, 759-759
web/src/api/types/enum-values.gen.ts (1)
278-278: LGTM!Also applies to: 651-651, 751-751
web/src/api/types/openapi.gen.ts (4)
7835-7847: LGTM!
8047-8053: LGTM!
11679-11685: LGTM!
12268-12274: LGTM!web/src/pages/agents/TaskHistoryBar.tsx (1)
19-19: LGTM!web/src/pages/project-docs/DocList.tsx (1)
2-2: LGTM!Also applies to: 8-8, 11-11
web/src/pages/tasks/TaskFilterBar.tsx (1)
5-5: LGTM!Also applies to: 14-14
web/src/utils/tasks.ts (1)
82-82: LGTM!web/src/__tests__/utils/tasks.property.test.ts (1)
3-3: LGTM!Also applies to: 19-19
tests/e2e/test_brownfield_intake_e2e.py (1)
1-369: LGTM!tests/unit/core/test_enums.py (1)
65-66: LGTM!Also applies to: 121-122, 130-130, 182-182
src/synthorg/persistence/postgres/schema.sql (2)
493-497: Duplicate: enforce JSONB array shape checks here as well.Same root issue already raised on the migration file; keep schema/revision parity by adding the same
jsonb_typeof(...) = 'array'constraints in this table definition too.
487-492: LGTM!Also applies to: 498-505, 1728-1747
src/synthorg/persistence/protocol.py (1)
54-56: LGTM!Also applies to: 124-126, 434-437, 459-462
src/synthorg/persistence/codebase_structure_map_protocol.py (1)
1-87: LGTM!src/synthorg/persistence/postgres/backend.py (1)
59-61: LGTM!Also applies to: 148-150, 220-222, 268-269, 320-325, 389-392, 457-460, 725-730, 749-753
src/synthorg/persistence/postgres/codebase_structure_map_repo.py (1)
1-212: LGTM!src/synthorg/persistence/postgres/revisions/20260522000003_codebase_structure_map.sql (1)
1-15: LGTM!Also applies to: 21-28
src/synthorg/persistence/sqlite/_backend_accessors.py (1)
49-51: LGTM!Also applies to: 100-100, 159-159, 164-164, 330-335, 361-364
src/synthorg/persistence/sqlite/backend.py (1)
58-60: LGTM!Also applies to: 147-149, 225-227, 232-232, 302-302, 307-307, 467-470, 487-490
tests/unit/tools/structure_map/test_query_structure_map.py (1)
1-115: LGTM!tests/conformance/persistence/test_codebase_structure_map_repository.py (1)
1-158: LGTM!tests/unit/persistence/test_protocol.py (1)
52-52: LGTM!Also applies to: 74-74, 1141-1145, 1175-1179, 1507-1512
tests/unit/api/fakes.py (1)
633-662: LGTM!tests/unit/api/fakes_backend.py (1)
33-33: LGTM!Also applies to: 60-60, 607-607, 612-612, 731-734, 751-754
src/synthorg/observability/events/brownfield.py (1)
1-37: LGTM!src/synthorg/observability/events/persistence.py (1)
328-349: LGTM!Also applies to: 842-868
src/synthorg/observability/events/workspace.py (1)
52-54: LGTM!src/synthorg/engine/errors.py (1)
230-240: LGTM!src/synthorg/engine/workspace/git_backend/protocol.py (1)
10-10: LGTM!Also applies to: 14-14, 20-55, 68-77, 123-145
src/synthorg/engine/workspace/git_backend/__init__.py (1)
26-29: LGTM!Also applies to: 42-44
src/synthorg/engine/workspace/git_backend/_git_ops.py (1)
13-27: LGTM!Also applies to: 254-355
src/synthorg/engine/workspace/git_backend/embedded.py (1)
24-45: LGTM!Also applies to: 182-203, 229-239
src/synthorg/engine/workspace/git_backend/external_remote.py (1)
45-56: LGTM!Also applies to: 69-70, 333-371
src/synthorg/engine/workspace/git_backend/local_path.py (1)
27-35: LGTM!Also applies to: 43-44, 225-264
tests/unit/engine/workspace/git_backend/test_external_remote_backend.py (1)
26-29: LGTM!Also applies to: 50-50, 59-59, 69-69, 123-126, 137-137, 213-213, 235-235, 257-257, 278-279, 308-308, 331-331, 351-351, 362-391
tests/unit/engine/workspace/git_backend/test_seed.py (1)
1-32: LGTM!Also applies to: 49-159
tests/unit/observability/test_events.py (1)
266-266: LGTM!Also applies to: 355-356
src/synthorg/engine/brownfield/source_resolver.py (1)
1-140: LGTM!Also applies to: 147-167
src/synthorg/engine/brownfield/__init__.py (1)
1-9: LGTM!src/synthorg/engine/brownfield/errors.py (1)
15-60: LGTM!src/synthorg/engine/brownfield/models.py (1)
10-65: LGTM!src/synthorg/engine/pipeline/entry/boot.py (1)
30-33: LGTM!Also applies to: 37-38, 306-375
src/synthorg/engine/pipeline/entry/brownfield_adapter.py (1)
41-105: LGTM!src/synthorg/engine/pipeline/entry/factory.py (1)
23-24: LGTM!Also applies to: 31-32, 124-150
scripts/_ghost_wiring_manifest.txt (1)
84-103: LGTM!src/synthorg/engine/pipeline/models.py (1)
40-40: LGTM!src/synthorg/api/app.py (1)
1453-1544: LGTM!Also applies to: 1564-1570
src/synthorg/api/controllers/__init__.py (1)
17-17: LGTM!Also applies to: 188-188, 225-225
src/synthorg/api/controllers/brownfield.py (1)
1-117: LGTM!Also applies to: 127-152
src/synthorg/api/rate_limits/policies.py (1)
86-87: LGTM!src/synthorg/api/state.py (1)
181-184: LGTM!Also applies to: 229-230, 325-326, 340-340, 392-392, 454-455, 535-537, 1169-1210, 1941-2020
tests/unit/engine/brownfield/test_scanner.py (1)
1-233: LGTM!tests/unit/engine/brownfield/test_service.py (1)
1-124: LGTM!tests/unit/engine/brownfield/__init__.py (1)
1-1: LGTM!src/synthorg/engine/brownfield/scanner/__init__.py (1)
1-27: LGTM!src/synthorg/engine/brownfield/scanner/_common.py (1)
1-88: LGTM!src/synthorg/engine/brownfield/scanner/aggregator.py (1)
1-85: LGTM!src/synthorg/engine/brownfield/scanner/factory.py (1)
1-71: LGTM!src/synthorg/engine/brownfield/scanner/generic_scanner.py (1)
1-64: LGTM!src/synthorg/engine/brownfield/scanner/node_scanner.py (1)
1-143: LGTM!src/synthorg/engine/brownfield/scanner/python_scanner.py (1)
1-101: LGTM!Also applies to: 104-147, 152-180
src/synthorg/engine/brownfield/scanner/rust_scanner.py (1)
1-134: LGTM!src/synthorg/engine/brownfield/scanner/protocol.py (1)
18-53: LGTM!
There was a problem hiding this comment.
♻️ Duplicate comments (1)
src/synthorg/engine/brownfield/scanner/go_scanner.py (1)
30-34:⚠️ Potential issue | 🟠 Major | ⚡ Quick winHandle single-line
requiredirectives ingo.modparsing.The regex now avoids
retractfalse positives, but it still skips valid lines likerequire github.com/pkg/errors v0.9.1, so dependency extraction is incomplete.♻️ Proposed fix
_REQUIRE_RE: Final[re.Pattern[str]] = re.compile( - r"^\s*([\w.\-+]+/[\w.\-+/]+)\s+(v[\w.\-+]+)", + r"^\s*(?:require\s+)?([\w.\-+]+/[\w.\-+/]+)\s+(v[\w.\-+]+)", re.MULTILINE, )🤖 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/engine/brownfield/scanner/go_scanner.py` around lines 30 - 34, The regex in go_scanner.py that matches module path/version pairs currently expects the line to start with the module path and thus misses single-line directives like "require github.com/pkg/errors v0.9.1"; update the pattern (the r"^\s*([\w.\-+]+/[\w.\-+/]+)\s+(v[\w.\-+]+)" literal) to allow an optional "require" token before the module (e.g. use a non-capturing optional prefix like (?:require\s+)?), keeping the existing slash requirement so "retract v1.2.3" remains excluded; adjust the same regex usage locations in go_scanner.py where it is compiled or referenced.
🤖 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.
Duplicate comments:
In `@src/synthorg/engine/brownfield/scanner/go_scanner.py`:
- Around line 30-34: The regex in go_scanner.py that matches module path/version
pairs currently expects the line to start with the module path and thus misses
single-line directives like "require github.com/pkg/errors v0.9.1"; update the
pattern (the r"^\s*([\w.\-+]+/[\w.\-+/]+)\s+(v[\w.\-+]+)" literal) to allow an
optional "require" token before the module (e.g. use a non-capturing optional
prefix like (?:require\s+)?), keeping the existing slash requirement so "retract
v1.2.3" remains excluded; adjust the same regex usage locations in go_scanner.py
where it is compiled or referenced.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro
Run ID: a256a069-5d50-44c5-b311-426cff4703c7
📒 Files selected for processing (15)
src/synthorg/api/app.pysrc/synthorg/api/controllers/brownfield.pysrc/synthorg/api/rate_limits/policies.pysrc/synthorg/engine/brownfield/scanner/go_scanner.pysrc/synthorg/engine/brownfield/scanner/python_scanner.pysrc/synthorg/engine/brownfield/service.pysrc/synthorg/engine/brownfield/source_resolver.pysrc/synthorg/engine/workspace/git_backend/embedded.pysrc/synthorg/persistence/postgres/revisions/20260522000003_codebase_structure_map.sqlsrc/synthorg/persistence/postgres/schema.sqlsrc/synthorg/persistence/sqlite/revisions/20260522000003_codebase_structure_map.sqlsrc/synthorg/persistence/sqlite/schema.sqlsrc/synthorg/settings/definitions/api.pytests/unit/engine/brownfield/test_source_resolver.pytests/unit/engine/pipeline/entry/test_brownfield_adapter.py
📜 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). (15)
- GitHub Check: Build Backend
- GitHub Check: Build Web Assets (melange)
- GitHub Check: Test Integration
- GitHub Check: Test Conformance (SQLite)
- GitHub Check: Test E2E
- GitHub Check: Test Unit
- GitHub Check: Dashboard Test
- GitHub Check: Lighthouse Site
- GitHub Check: Lighthouse Dashboard
- GitHub Check: CodSpeed Python benchmarks
- GitHub Check: CodSpeed Web benchmarks
- GitHub Check: Build Preview
- GitHub Check: Analyze (go)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{py,ts,tsx,jsx,md}
📄 CodeRabbit inference engine (CLAUDE.md)
No region/currency/locale privileged; use metric units; British English per docs/reference/regional-defaults.md
Files:
src/synthorg/settings/definitions/api.pysrc/synthorg/engine/workspace/git_backend/embedded.pytests/unit/engine/pipeline/entry/test_brownfield_adapter.pysrc/synthorg/api/app.pysrc/synthorg/api/rate_limits/policies.pysrc/synthorg/api/controllers/brownfield.pytests/unit/engine/brownfield/test_source_resolver.pysrc/synthorg/engine/brownfield/scanner/go_scanner.pysrc/synthorg/engine/brownfield/source_resolver.pysrc/synthorg/engine/brownfield/scanner/python_scanner.pysrc/synthorg/engine/brownfield/service.py
src/synthorg/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
src/synthorg/**/*.py: Onlysrc/synthorg/persistence/may import sqlite/psycopg or emit raw SQL; new repository protocols inherit from generic categories inpersistence/_generics.py; bespoke methods permitted only under ADR-0001 D7
Configuration Precedence: DB > env > code default viaSettingsService/ConfigResolver(Cat-1) or env > code default (Cat-2,read_only_post_init); Cat-3 bootstrap secrets pure env; YAML is ingestion format only, not precedence tier; noos.environ.getoutside startup
No hardcoded numeric values; numerics live insettings/definitions/; allowlist only 0/1/-1, HTTP codes, hex masks, powers-of-2, and module-level annotated named constants (NAME: int|float|Final); enforced byscripts/check_no_magic_numbers.py
Comments document WHY only; no reviewer citations, issue back-refs, or migration framing; enforced bycheck_no_review_origin_in_code.py+check_no_migration_framing.py
Nofrom __future__ import annotations(Python 3.14 has PEP 649); use PEP 758 except:except A, B:no parens unless binding
Type hints on public functions; mypy strict; Google-style docstrings; line length 88; functions <50 lines; files <800 lines
Errors follow<Domain><Condition>Errorpattern fromDomainError; never inheritException/RuntimeErrordirectly; enforced bycheck_domain_error_hierarchy.py
Pydantic v2 frozen +extra="forbid"on every frozen model project-wide; gatecheck_frozen_model_extra_forbid.py;@computed_fieldauto-exempt; per-line# lint-allow: frozen-extra-forbid -- <reason>forextra="allow"/"ignore"boundaries; use@computed_fieldfor derived; useNotBlankStrfor identifiers
Args models at every system boundary;parse_typed()for every external dict ingestion; enforced bycheck_boundary_typed.py
Immutability: usemodel_copy(update=...)orcopy.deepcopy(); deepcopy at system boundaries
Async: useasyncio.TaskGroupfor fan-out/fan-in; helpers catchException(re-raiseMemoryError/`RecursionError...
Files:
src/synthorg/settings/definitions/api.pysrc/synthorg/engine/workspace/git_backend/embedded.pysrc/synthorg/api/app.pysrc/synthorg/api/rate_limits/policies.pysrc/synthorg/api/controllers/brownfield.pysrc/synthorg/engine/brownfield/scanner/go_scanner.pysrc/synthorg/engine/brownfield/source_resolver.pysrc/synthorg/engine/brownfield/scanner/python_scanner.pysrc/synthorg/engine/brownfield/service.py
src/**/*.py
⚙️ CodeRabbit configuration file
This project uses Python 3.14+ with PEP 758 except syntax: "except A, B:" (comma-separated, no parentheses) is correct and mandatory -- do NOT flag it as a typo or suggest parenthesized form. The "except builtins.MemoryError, RecursionError: raise" pattern is intentional project convention for system-error propagation. When evaluating the 50-line function limit, count only the function body excluding the signature lines, decorators, and docstring. Functions 1-5 lines over due to docstrings or multi-line signatures should not be flagged. Do not suggest extracting single-use helper functions called exactly once -- this reduces readability without improving maintainability.
Files:
src/synthorg/settings/definitions/api.pysrc/synthorg/engine/workspace/git_backend/embedded.pysrc/synthorg/api/app.pysrc/synthorg/api/rate_limits/policies.pysrc/synthorg/api/controllers/brownfield.pysrc/synthorg/engine/brownfield/scanner/go_scanner.pysrc/synthorg/engine/brownfield/source_resolver.pysrc/synthorg/engine/brownfield/scanner/python_scanner.pysrc/synthorg/engine/brownfield/service.py
tests/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
tests/**/*.py: Timeout/slow failures = source-code regression; never edittests/baselines/unit_timing.jsonor anyscripts/*_baseline.{txt,json}/scripts/_*_baseline.py; both families PreToolUse-blocked; per-invocation bypass requires explicit approval (ALLOW_BASELINE_GROWTH=1 git commit)
Test markers:@pytest.mark.{unit,integration,e2e,slow}; async auto; timeout 30s global; coverage 80% min
xdist-n 8 --dist=loadfileauto-applied via pyprojectaddopts; Windows unit tests useWindowsSelectorEventLoopPolicy; subprocess tests override back
Test doubles:FakeClockfor Clock seam,mock_of[T](**overrides)for typed-boundary substitutions,SimpleNamespacefor attribute-bags; bareMagicMockat typed boundary blocked byscripts/check_mock_spec.py
Hypothesis: 10 deterministic CI examples; failures are real bugs (fix + add@example(...)); never skip/xfail flaky tests; fix fundamentally
Files:
tests/unit/engine/pipeline/entry/test_brownfield_adapter.pytests/unit/engine/brownfield/test_source_resolver.py
⚙️ CodeRabbit configuration file
Test files do not require Google-style docstrings on classes or functions -- ruff D rules are only enforced on src/. A bare
@settings() decorator with no arguments on Hypothesis property tests is a no-op and should not be suggested -- the HYPOTHESIS_PROFILE env var controls example counts via registered profiles, which@given() honors automatically.
Files:
tests/unit/engine/pipeline/entry/test_brownfield_adapter.pytests/unit/engine/brownfield/test_source_resolver.py
🧠 Learnings (5)
📚 Learning: 2026-05-05T09:04:46.195Z
Learnt from: Aureliolo
Repo: Aureliolo/synthorg PR: 1760
File: scripts/_dual_backend_parity_lib.py:215-216
Timestamp: 2026-05-05T09:04:46.195Z
Learning: This repository targets Python 3.14+ and follows PEP 758. Therefore, reviewer tooling should NOT treat unparenthesized multi-exception `except` clauses written without an `as` clause (e.g., `except MemoryError, RecursionError:`) as syntax errors. Only flag `except`-clause problems when they are genuinely invalid for Python 3.14+.
Applied to files:
src/synthorg/settings/definitions/api.pysrc/synthorg/engine/workspace/git_backend/embedded.pytests/unit/engine/pipeline/entry/test_brownfield_adapter.pysrc/synthorg/api/app.pysrc/synthorg/api/rate_limits/policies.pysrc/synthorg/api/controllers/brownfield.pytests/unit/engine/brownfield/test_source_resolver.pysrc/synthorg/engine/brownfield/scanner/go_scanner.pysrc/synthorg/engine/brownfield/source_resolver.pysrc/synthorg/engine/brownfield/scanner/python_scanner.pysrc/synthorg/engine/brownfield/service.py
📚 Learning: 2026-05-21T22:55:20.496Z
Learnt from: Aureliolo
Repo: Aureliolo/synthorg PR: 2035
File: src/synthorg/meta/toolsmith/models.py:114-114
Timestamp: 2026-05-21T22:55:20.496Z
Learning: In this repo’s “magic number” review standard, the existing gate in `scripts/check_no_magic_numbers.py` intentionally does NOT flag numeric literals used as raw call-site arguments. So, do not flag numeric literals passed as keyword arguments to Pydantic `Field()` (e.g., `Field(ge=0, le=100)` / `Field(ge=1, le=50)`)—this is an established idiom. Only treat numeric literals as “magic numbers” when they occur in the locations the gate checks (module-level assignments and function/method parameter defaults).
Applied to files:
src/synthorg/settings/definitions/api.pysrc/synthorg/engine/workspace/git_backend/embedded.pytests/unit/engine/pipeline/entry/test_brownfield_adapter.pysrc/synthorg/api/app.pysrc/synthorg/api/rate_limits/policies.pysrc/synthorg/api/controllers/brownfield.pytests/unit/engine/brownfield/test_source_resolver.pysrc/synthorg/engine/brownfield/scanner/go_scanner.pysrc/synthorg/engine/brownfield/source_resolver.pysrc/synthorg/engine/brownfield/scanner/python_scanner.pysrc/synthorg/engine/brownfield/service.py
📚 Learning: 2026-05-17T11:45:11.839Z
Learnt from: Aureliolo
Repo: Aureliolo/synthorg PR: 1952
File: src/synthorg/settings/definitions/api.py:594-638
Timestamp: 2026-05-17T11:45:11.839Z
Learning: In SynthOrg (Aureliolo/synthorg) pre-alpha, apply the strict no-backward-compat policy: any setting-key rename must be fully completed in the same change/PR with all repo callers updated, and you should not keep legacy aliases or compatibility fallbacks. When reviewing, do not flag a setting-key rename as a breaking upgrade hazard if the rename is repo-wide and fully implemented within the same PR.
Applied to files:
src/synthorg/settings/definitions/api.py
📚 Learning: 2026-05-17T11:45:11.839Z
Learnt from: Aureliolo
Repo: Aureliolo/synthorg PR: 1952
File: src/synthorg/settings/definitions/api.py:594-638
Timestamp: 2026-05-17T11:45:11.839Z
Learning: In this repository, SynthOrg is pre-alpha and uses a strict no-backward-compat policy for setting-key renames. When reviewing code under src/synthorg/settings, do NOT flag a setting-key rename as an “upgrade-safety” issue if the rename is complete/atomic in the same PR: all callers/usages of the old key are updated simultaneously, and the PR does not keep any legacy aliases, compatibility fallbacks, or migration/rollback paths for the old key.
Applied to files:
src/synthorg/settings/definitions/api.py
📚 Learning: 2026-05-21T22:55:09.289Z
Learnt from: Aureliolo
Repo: Aureliolo/synthorg PR: 2035
File: src/synthorg/meta/toolsmith/config.py:29-30
Timestamp: 2026-05-21T22:55:09.289Z
Learning: For this repo’s Pydantic configuration idiom, do not treat numeric literals passed directly as arguments to `pydantic.Field(...)` as “magic numbers” during review. This includes call-site usages like `Field(default=0.2, ge=0.0, le=1.0)` (e.g., in config models such as `ToolAuthoringConfig`, `ToolValidationConfig`, `ToolsmithConfig`). Do not request extracting those `Field(...)` numeric arguments into named constants, since the repo’s `scripts/check_no_magic_numbers.py` intentionally excludes call-site `Field(...)` numerics and relies on `Field(...)` as the canonical way to express these constraints/defaults.
Applied to files:
src/synthorg/settings/definitions/api.pysrc/synthorg/engine/workspace/git_backend/embedded.pysrc/synthorg/api/app.pysrc/synthorg/api/rate_limits/policies.pysrc/synthorg/api/controllers/brownfield.pysrc/synthorg/engine/brownfield/scanner/go_scanner.pysrc/synthorg/engine/brownfield/source_resolver.pysrc/synthorg/engine/brownfield/scanner/python_scanner.pysrc/synthorg/engine/brownfield/service.py
🔇 Additional comments (14)
src/synthorg/settings/definitions/api.py (1)
4-5: LGTM!Also applies to: 62-66
src/synthorg/persistence/postgres/revisions/20260522000003_codebase_structure_map.sql (1)
16-25: LGTM!src/synthorg/persistence/sqlite/schema.sql (1)
479-488: LGTM!src/synthorg/persistence/sqlite/revisions/20260522000003_codebase_structure_map.sql (1)
16-25: LGTM!src/synthorg/persistence/postgres/schema.sql (1)
493-502: LGTM!src/synthorg/engine/workspace/git_backend/embedded.py (1)
19-20: LGTM!Also applies to: 45-46, 218-220, 227-229
tests/unit/engine/pipeline/entry/test_brownfield_adapter.py (1)
83-84: LGTM!Also applies to: 86-86
src/synthorg/api/app.py (1)
1561-1573: LGTM!src/synthorg/api/rate_limits/policies.py (1)
36-37: LGTM!Also applies to: 254-255
src/synthorg/api/controllers/brownfield.py (1)
21-24: LGTM!Also applies to: 128-128
tests/unit/engine/brownfield/test_source_resolver.py (1)
35-38: LGTM!src/synthorg/engine/brownfield/source_resolver.py (1)
143-147: LGTM!src/synthorg/engine/brownfield/scanner/python_scanner.py (1)
102-105: LGTM!Also applies to: 151-153
src/synthorg/engine/brownfield/service.py (1)
53-57: LGTM!Also applies to: 140-146, 174-177
CI: - Add analysis/codebase_analysis enum keys to frontend Records + filters (Dashboard Type Check/Build, melange, Lighthouse) - Bump starlette 1.0.0 to 1.0.1 for PYSEC-2026-161 (Python Security Audit) CodeRabbit: - brownfield-intake.md flow block converted to a mermaid flowchart - source_resolver: allow ssh:// usernames, still block passwords and http(s) usernames - _git_ops seed guard: detect untracked files too (ls-files plus ls-files --others) - query_structure_map: narrow arg-validation except scope away from repository errors - test_enums: assert TaskType.ANALYSIS value - external_remote tests: vendor-neutral hosts Gemini: - python_scanner: root __init__.py maps to a dot - python_scanner: pytest detection via tool table key, not str() - node_scanner: test-framework checks dependencies and devDependencies Skipped CR7 (stale): the git-backend dir conftest already provides the subprocess event_loop_policy that test_seed inherits.
frontend-reviewer (3 MAJOR): - TaskFilterBar.tsx: source TASK_TYPES from generated TASK_TYPE_VALUES - DocList.tsx: source DOC_TYPES from generated DOC_TYPE_VALUES - tasks.property.test.ts: source ALL_TASK_TYPES from generated TASK_TYPE_VALUES Kills the hand-maintained enum-literal drift hazard at the source. docs-consistency (1 MAJOR): - brownfield-intake.md: clarify credential rejection policy (password in any scheme + http(s) username rejected; bare ssh git@host username allowed) docs-consistency / conventions (1 MAJOR): - test_external_remote_backend.py: finish vendor-neutralisation (_catalog_github to _catalog_forge, "github-main" to "forge-main"); ConnectionType.GITHUB enum stays as legitimate forge-type domain conventions-enforcer (1 MEDIUM): - _git_ops.py: extract _assert_workspace_empty helper; keeps import_source_into_worktree under the 50-line guideline (round 1 had pushed it to 84)
app.py: wrap _wire_brownfield_intake in try/except (best-effort + idempotent like _wire_research_engine) controllers/brownfield.py: add per-user inflight concurrency cap to /import rate_limits/policies.py + settings/definitions/api.py: BROWNFIELD_IMPORT_INFLIGHT_MAX (single-slot per user) scanner/go_scanner.py: tighten _REQUIRE_RE to require a slash in the module path (skip "retract v1.2.3") scanner/python_scanner.py: guard against non-table "project" key in pyproject (isinstance dict check) brownfield/service.py: index before save in both _fresh_import and _reimport so a failed index does not strand an unindexed map brownfield/service.py: _URL_USERINFO regex now uses RFC 3986 scheme syntax so git+ssh:// etc. redact correctly brownfield/source_resolver.py: IPv6 hostname wrapped in brackets before composing netloc git_backend/embedded.py: seed-phase push + rev-parse now raise GitBackendSeedError / GIT_BACKEND_SEED_FAILED (not push types) persistence migrations + schema.sql: JSON array CHECK constraints on modules / entry_points / test_suites / build_files / dependencies (both backends) test_source_resolver.py: assert resolved fetch_url for file:// case test_brownfield_adapter.py: assert_awaited_once_with(submission) for stronger payload check Skipped CR-duplicate (test_seed.py event_loop_policy): the dir conftest at tests/unit/engine/workspace/git_backend/conftest.py already provides session-scoped event_loop_policy returning DefaultEventLoopPolicy (Proactor on Windows), which test_seed inherits.
go_scanner _REQUIRE_RE: prepend optional (?:require\s+)? so the regex matches single-line directives like "require github.com/pkg/errors v0.9.1" AND the indented lines inside a require ( ... ) block; still rejects "retract v1.2.3" (no slash).
8054aab to
56eee1b
Compare
<!-- HIGHLIGHTS_START --> ## Highlights > _AI-generated summary (model: `openai/gpt-4.1-mini` via GitHub Models). Commit-based changelog below._ ### What you'll notice - New brownfield codebase intake mode supports merger and acquisition scenarios. - Added deep CEO interview feature to improve project charter creation. - Introduced mission control and flight recorder operator cockpit for better operational oversight. - Research mode added for enhanced exploratory work. - Runtime services now log safety-spine state at boot for clearer diagnostics. ### What's new - Research mode feature enables deeper data exploration. - CEO interview integration helps shape project charters. - Mission control and flight recorder cockpit introduced for operational tracking. ### Under the hood - Improved codebase modularity with module-size gates and lint tightening. - Added __init__.py to 21 test directories for better test discovery. - Promoted six transitive dependencies to direct dependencies for clarity. - Split codespell ignore list into vocabulary and source renames. - Decomposed oversized web utilities, hooks, and libraries for maintainability. - Enhanced CI with Lychee link checker integration and retry logic for cosign signing. - Sharded unit and integration tests and added Postgres service container in CI. - Updated infrastructure and web dependencies; maintained lock files. <!-- HIGHLIGHTS_END --> :robot: I have created a release *beep* *boop* --- ## [0.8.8](v0.8.7...v0.8.8) (2026-05-24) ### Features * brownfield codebase intake (merger/acquisition entry mode) ([#2042](#2042)) ([e287621](e287621)), closes [#1975](#1975) * deep CEO interview to project charter ([#2045](#2045)) ([904f2fb](904f2fb)) * mission control + flight recorder operator cockpit ([#2044](#2044)) ([1c2660b](1c2660b)) * research mode ([#2041](#2041)) ([f81a5ac](f81a5ac)), closes [#1989](#1989) * surface safety-spine state in runtime-services boot log (closes [#2096](#2096)) ([#2097](#2097)) ([f187b31](f187b31)) ### Refactoring * add __init__.py to 21 leaf test directories (INP001) ([#2081](#2081)) ([2592118](2592118)), closes [#2064](#2064) * codebase modularity (1/4) - module-size gates + lint tightening + tools ([#2078](#2078)) ([556fbd9](556fbd9)), closes [#2047](#2047) [#2040](#2040) * promote 6 transitive deps to direct deps ([#2083](#2083)) ([adedc6a](adedc6a)) * split codespell ignore-words-list into vocab + source renames ([#2085](#2085)) ([917d98a](917d98a)), closes [#2074](#2074) * **web:** PR A foundation, decompose oversized utils/hooks/lib ([#2092](#2092)) ([#2098](#2098)) ([aedbba5](aedbba5)) ### CI/CD * exclude slsa.dev from lychee (transient timeout on canonical badge) ([#2090](#2090)) ([346c51d](346c51d)) * fix paths-filter shallow-clone race and scorecard allowlist ([#2089](#2089)) ([7cd7ce8](7cd7ce8)) * refresh .test_durations.{unit,integration} ([#2087](#2087)) ([ddf2d86](ddf2d86)) * retry cosign sign on transient GHCR/Rekor failures ([#2100](#2100)) ([da9422a](da9422a)) * shard test-unit + test-integration, sysmon coverage, Postgres service container ([#2080](#2080)) ([0768787](0768787)) * wire Lychee link-checker (workflow + installer + pre-push hook) ([#2084](#2084)) ([1c0694a](1c0694a)) ### Maintenance * Lock file maintenance ([#2086](#2086)) ([a78810a](a78810a)) * Update Infrastructure dependencies ([#2055](#2055)) ([041ad8b](041ad8b)) * Update Web dependencies ([#2054](#2054)) ([4d57b9a](4d57b9a)) --- 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>
Summary
Adds the "merger/acquisition" entry mode (EPIC #1973): point the studio at an existing repo, and it imports, maps, analyses, and indexes the codebase, then awaits human direction and builds on the ingested base.
GitBackendprotocol with a one-shotseed(...)(clone-remote / ingest-local) across all three backends; shared fetch-HEAD + reset import helper (no named remote, so credential URLs never persist).BrownfieldSourceResolverdoes SSRF validation (reuses the clone-URL validator) + forge-token injection from the connection catalog; rejects credentials embedded in the source ref.CodebaseStructureMap, persisted 1:1 per project (IdKeyedRepository, SQLite TEXT-JSON / Postgres JSONB, dual-backend conformance, one yoyo revision per backend).BrownfieldImportService(per-project lock; provision → seed → scan → persist →KnowledgeService.ingest(REPO)) and a thinBrownfieldEntryAdapterthat drives anANALYSISwork item through the pipeline spine so the agent analysis pass authors aCODEBASE_ANALYSISliving document.query_structure_map(SEC-1wrap_untrusted) for structured navigation of the imported codebase.POST /brownfield/importcontroller,wire_real_brownfield_entryboot hook (gated/best-effort), AppState seams, ghost-wiring manifest entries, rate-limit policy, regenerated*.gen.ts.BrownfieldWorkspaceNotEmptyError).docs/design/brownfield-intake.md(+ DESIGN_SPEC index), DocType + persistence-protocol table updates.Test plan
seedacross backends, source resolver (SSRF, token injection, embedded-cred rejection), service orchestration (fresh/idempotent/reject), query tool, adapter + factory.tests/conformance/persistence/test_codebase_structure_map_repository.py(SQLite + Postgres).tests/e2e/test_brownfield_intake_e2e.py— real-git import → structure map + analysis pass → indexed → follow-up TASK_BOARD directive through the spine.Review coverage
Pre-reviewed by 8 core agents (code-reviewer, python-reviewer, conventions-enforcer, security-reviewer, persistence-reviewer, issue-resolution-verifier, docs-consistency, comment-quality-rot). issue-resolution-verifier: all acceptance criteria RESOLVED. 6 valid findings addressed; 9 false positives documented in
_audit/pre-pr-review/triage.md.Closes #1975