mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-08-01 19:18:35 -04:00
docs: classify architecture inventory and refresh guidance
This commit is contained in:
+1
-1
@@ -31,4 +31,4 @@ Compact, code-grounded discovery maps of cross-cutting systems in the checked-in
|
|||||||
4. When no owning specification exists, retain the verified finding here and record missing documentation ownership as a follow-up; otherwise retain unresolved context here and correct stale wording.
|
4. When no owning specification exists, retain the verified finding here and record missing documentation ownership as a follow-up; otherwise retain unresolved context here and correct stale wording.
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> This package intentionally contains no generator, validator, maturity scale, feature database, or parallel work tracker. The [architecture runtime inventory](../specs/architecture-runtime-inventory.md) remains useful structural context, but is an explicitly draft snapshot.
|
> This package intentionally contains no generator, validator, maturity scale, feature database, or parallel work tracker. The [architecture runtime inventory](./architecture-runtime-inventory.md) preserves dated structural metrics, investigation context, and historical planning as an explicitly non-canonical snapshot.
|
||||||
|
|||||||
@@ -0,0 +1,331 @@
|
|||||||
|
# Architecture runtime inventory
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
> This document is a dated structural snapshot, not a canonical runtime specification.
|
||||||
|
> Counts, paths, and implementation details may drift as the repository changes.
|
||||||
|
> Verify implementation-sensitive claims against the current code and tests.
|
||||||
|
|
||||||
|
- **Branch:** `discovery`
|
||||||
|
- **Commit:** `c762efe1c97a`
|
||||||
|
- **Generated:** `2026-07-28T05:38:14+01:00`
|
||||||
|
- **Historical context:** readability and refactor planning in [#4071](https://github.com/odysseus-dev/odysseus/issues/4071) and [#4082](https://github.com/odysseus-dev/odysseus/issues/4082)
|
||||||
|
|
||||||
|
## Disposition
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> Reviewed for documentation classification. Stable runtime structure and
|
||||||
|
> subsystem ownership have been transferred to the proposed canonical
|
||||||
|
> destination, [`docs/ARCHITECTURE.md`](../docs/ARCHITECTURE.md), for
|
||||||
|
> maintainer review.
|
||||||
|
>
|
||||||
|
> This document retains dated metrics, rankings, investigation context,
|
||||||
|
> refactor-sensitive observations, and historical planning. Those contents are
|
||||||
|
> non-canonical and belong under `discovery/`.
|
||||||
|
|
||||||
|
| Content | Authority and destination |
|
||||||
|
|---|---|
|
||||||
|
| Stable runtime structure | Proposed canonical destination: `docs/ARCHITECTURE.md` |
|
||||||
|
| Stable subsystem boundaries | Proposed canonical destination: `docs/ARCHITECTURE.md` |
|
||||||
|
| Frontend module organization | `static/js/MODULE_SUMMARY.md` |
|
||||||
|
| Counts, line totals, and rankings | This non-canonical inventory |
|
||||||
|
| Investigation context and open questions | `discovery/` |
|
||||||
|
| Refactor options and prioritization | Issues, Plane, or non-canonical discovery material |
|
||||||
|
|
||||||
|
The transfer preserves the stable facts without promoting generated metrics or
|
||||||
|
historical prioritization into canonical documentation.
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
This inventory provides a reviewable map of the current repository structure,
|
||||||
|
large runtime modules, major subsystem boundaries, and refactor-sensitive areas.
|
||||||
|
|
||||||
|
It does not:
|
||||||
|
|
||||||
|
- define accepted subsystem behaviour;
|
||||||
|
- certify runtime correctness;
|
||||||
|
- prescribe a committed refactor sequence;
|
||||||
|
- replace focused specifications, tests, or source review.
|
||||||
|
|
||||||
|
For cross-cutting implementation evidence, see the [discovery maps](./README.md).
|
||||||
|
|
||||||
|
## Top-level runtime structure
|
||||||
|
|
||||||
|
| Area | Role |
|
||||||
|
|---|---|
|
||||||
|
| `app.py` | FastAPI application composition and entry point |
|
||||||
|
| `launcher.py` | Application launch support |
|
||||||
|
| `setup.py` | Native setup workflow |
|
||||||
|
| `core/` | Authentication, middleware, persistence, sessions, and platform primitives |
|
||||||
|
| `routes/` | HTTP and API route handlers |
|
||||||
|
| `src/` | Application services, orchestration, tools, providers, and runtime helpers |
|
||||||
|
| `services/` | Domain-oriented service packages |
|
||||||
|
| `mcp_servers/` | Built-in MCP server implementations |
|
||||||
|
| `scripts/` | CLI tools, diagnostics, maintenance, and migration helpers |
|
||||||
|
| `static/` | No-build browser frontend and bundled assets |
|
||||||
|
| `tests/` | Automated test suite and supporting test infrastructure |
|
||||||
|
|
||||||
|
## Directory snapshot
|
||||||
|
|
||||||
|
| Directory | Tracked files | Tracked Python files | Direct subdirectories |
|
||||||
|
|---|---:|---:|---|
|
||||||
|
| `src/` | 143 | 143 | `agent_tools/`, `model_capability_readers/`, `search/`, `tools/` |
|
||||||
|
| `routes/` | 73 | 73 | `admin_wipe/`, `cleanup/`, `compare/`, `contacts/`, `gallery/`, `history/`, `memory/`, `note/`, `research/` |
|
||||||
|
| `core/` | 11 | 11 | None |
|
||||||
|
| `services/` | 42 | 40 | `docs/`, `faces/`, `hwfit/`, `memory/`, `research/`, `search/`, `shell/`, `stt/`, `tts/`, `youtube/` |
|
||||||
|
| `mcp_servers/` | 5 | 5 | None |
|
||||||
|
| `scripts/` | 44 | 17 | `_completion/`, `_lib/`, `demo_email/` |
|
||||||
|
| `static/js/` | 154 | 0 | `calendar/`, `color/`, `compare/`, `editor/`, `emailLibrary/`, `markdown/`, `model/`, `research/`, `util/` |
|
||||||
|
| `tests/` | 768 | 758 | `cli/`, `helpers/`, `streaming/`, `tools/` |
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> Counts in this table use `git ls-files`, so generated caches, virtual
|
||||||
|
> environments, and other untracked local files are excluded.
|
||||||
|
|
||||||
|
## Largest backend modules
|
||||||
|
|
||||||
|
Large files are review signals, not proof that a module should be split.
|
||||||
|
Coupling, ownership, import compatibility, tests, and runtime authority matter more
|
||||||
|
than line count alone.
|
||||||
|
|
||||||
|
| Rank | File | Lines | Classes | Top-level functions | Review signal |
|
||||||
|
|---:|---|---:|---:|---:|---|
|
||||||
|
| 1 | `routes/email_routes.py` | 6032 | 1 | 58 | High |
|
||||||
|
| 2 | `src/agent_loop.py` | 5248 | 0 | 63 | High |
|
||||||
|
| 3 | `routes/cookbook_routes.py` | 4545 | 0 | 16 | High |
|
||||||
|
| 4 | `mcp_servers/email_server.py` | 2920 | 0 | 77 | High |
|
||||||
|
| 5 | `src/llm_core.py` | 2895 | 3 | 85 | High |
|
||||||
|
| 6 | `src/builtin_actions.py` | 2845 | 2 | 27 | High |
|
||||||
|
| 7 | `routes/model_routes.py` | 2743 | 0 | 65 | High |
|
||||||
|
| 8 | `src/task_scheduler.py` | 2627 | 1 | 8 | Medium |
|
||||||
|
| 9 | `core/database.py` | 2562 | 28 | 67 | High |
|
||||||
|
| 10 | `routes/gallery/gallery_routes.py` | 2325 | 0 | 16 | Medium |
|
||||||
|
| 11 | `routes/chat_routes.py` | 2063 | 0 | 18 | Medium |
|
||||||
|
| 12 | `routes/shell_routes.py` | 1971 | 1 | 21 | Medium |
|
||||||
|
| 13 | `src/visual_report.py` | 1933 | 0 | 11 | Medium |
|
||||||
|
| 14 | `routes/email_helpers.py` | 1888 | 3 | 48 | Medium |
|
||||||
|
| 15 | `routes/document_routes.py` | 1810 | 0 | 5 | Medium |
|
||||||
|
| 16 | `src/tools/cookbook.py` | 1705 | 0 | 34 | Medium |
|
||||||
|
| 17 | `routes/calendar_routes.py` | 1667 | 2 | 19 | Medium |
|
||||||
|
| 18 | `routes/skills_routes.py` | 1662 | 3 | 19 | Medium |
|
||||||
|
| 19 | `src/tool_schemas.py` | 1595 | 0 | 3 | Medium |
|
||||||
|
| 20 | `routes/email_pollers.py` | 1551 | 0 | 23 | Medium |
|
||||||
|
|
||||||
|
The largest current backend concentrations include:
|
||||||
|
|
||||||
|
- email routing and helper logic;
|
||||||
|
- agent-loop orchestration;
|
||||||
|
- Cookbook lifecycle and serving logic;
|
||||||
|
- provider and model routing;
|
||||||
|
- task scheduling;
|
||||||
|
- shared database models and persistence helpers.
|
||||||
|
|
||||||
|
These areas require focused ownership and compatibility analysis before structural
|
||||||
|
changes are attempted.
|
||||||
|
|
||||||
|
## Largest frontend modules
|
||||||
|
|
||||||
|
| Rank | File | Lines |
|
||||||
|
|---:|---|---:|
|
||||||
|
| 1 | `static/style.css` | 41132 |
|
||||||
|
| 2 | `static/js/document.js` | 11200 |
|
||||||
|
| 3 | `static/js/emailLibrary.js` | 8505 |
|
||||||
|
| 4 | `static/js/slashCommands.js` | 6520 |
|
||||||
|
| 5 | `static/js/chat.js` | 6001 |
|
||||||
|
| 6 | `static/js/settings.js` | 5819 |
|
||||||
|
| 7 | `static/js/notes.js` | 5365 |
|
||||||
|
| 8 | `static/app.js` | 4681 |
|
||||||
|
| 9 | `static/js/cookbookRunning.js` | 4433 |
|
||||||
|
| 10 | `static/js/galleryEditor.js` | 4386 |
|
||||||
|
| 11 | `static/js/cookbookServe.js` | 4305 |
|
||||||
|
| 12 | `static/js/calendar.js` | 3722 |
|
||||||
|
| 13 | `static/js/cookbook.js` | 3677 |
|
||||||
|
| 14 | `static/js/sessions.js` | 3665 |
|
||||||
|
| 15 | `static/js/documentLibrary.js` | 3422 |
|
||||||
|
| 16 | `static/js/tasks.js` | 3187 |
|
||||||
|
| 17 | `static/js/admin.js` | 3144 |
|
||||||
|
| 18 | `static/js/gallery.js` | 2958 |
|
||||||
|
| 19 | `static/js/cookbook-hwfit.js` | 2826 |
|
||||||
|
| 20 | `static/js/chatRenderer.js` | 2808 |
|
||||||
|
|
||||||
|
The browser frontend remains a no-build ES-module application. Its current source
|
||||||
|
tree is authoritative; the maintained structural summary is available in
|
||||||
|
[`static/js/MODULE_SUMMARY.md`](../static/js/MODULE_SUMMARY.md).
|
||||||
|
|
||||||
|
CSS modularization remains tracked separately in
|
||||||
|
[#2617](https://github.com/odysseus-dev/odysseus/issues/2617).
|
||||||
|
|
||||||
|
## Major subsystem boundaries
|
||||||
|
|
||||||
|
| Subsystem | Primary implementation locations |
|
||||||
|
|---|---|
|
||||||
|
| Application startup | `app.py`, `src/app_initializer.py`, `core/` |
|
||||||
|
| Authentication and sessions | `core/auth.py`, `core/middleware.py`, `core/session_manager.py`, `routes/auth_routes.py` |
|
||||||
|
| Chat and streaming | `routes/chat_routes.py`, `routes/chat_helpers.py`, `src/chat_handler.py`, `src/chat_processor.py`, `src/llm_core.py` |
|
||||||
|
| Agents and tools | `src/agent_loop.py`, `src/tool_execution.py`, `src/agent_tools/`, `src/tools/`, `src/tool_policy.py`, `src/tool_security.py` |
|
||||||
|
| Models and providers | `routes/model_routes.py`, `src/model_discovery.py`, `src/model_capabilities.py`, `src/endpoint_resolver.py`, `src/llm_core.py` |
|
||||||
|
| Cookbook and hardware fit | `routes/cookbook_routes.py`, `routes/cookbook_helpers.py`, `src/cookbook_serve_lifecycle.py`, `services/hwfit/` |
|
||||||
|
| Search and research | `routes/search_routes.py`, `services/search/`, `routes/research/`, `services/research/`, `src/deep_research.py` |
|
||||||
|
| Documents and retrieval | `routes/document_routes.py`, `src/document_processor.py`, `src/personal_docs.py`, `src/rag_manager.py`, `src/pdf_runtime.py` |
|
||||||
|
| Memory and skills | `routes/memory/`, `services/memory/`, `routes/skills_routes.py` |
|
||||||
|
| Email | `routes/email_routes.py`, `routes/email_helpers.py`, `routes/email_pollers.py`, `mcp_servers/email_server.py` |
|
||||||
|
| Calendar, contacts, notes, and tasks | `routes/calendar_routes.py`, `routes/contacts/`, `routes/note/`, `routes/task_routes.py`, `src/task_scheduler.py` |
|
||||||
|
| Media and speech | `routes/gallery/`, `routes/stt_routes.py`, `routes/tts_routes.py`, `services/stt/`, `services/tts/` |
|
||||||
|
| Persistence and operations | `core/database.py`, `src/runtime_paths.py`, `src/bg_jobs.py`, `routes/backup_routes.py`, `routes/cleanup/` |
|
||||||
|
|
||||||
|
For a broader evidence map, see
|
||||||
|
[`system-map.md`](./system-map.md).
|
||||||
|
|
||||||
|
## Refactor-sensitive areas
|
||||||
|
|
||||||
|
### Shared persistence
|
||||||
|
|
||||||
|
`core/database.py` is a central dependency containing models and shared persistence
|
||||||
|
helpers. Changes can affect routes, services, background work, tests, migrations,
|
||||||
|
and import compatibility.
|
||||||
|
|
||||||
|
A split should not begin from file size alone. It requires:
|
||||||
|
|
||||||
|
- an importer inventory;
|
||||||
|
- model and helper ownership decisions;
|
||||||
|
- migration compatibility checks;
|
||||||
|
- stable re-export or migration strategy;
|
||||||
|
- focused and full-suite validation.
|
||||||
|
|
||||||
|
### Agent orchestration
|
||||||
|
|
||||||
|
`src/agent_loop.py` coordinates model interaction, tool selection, policy decisions,
|
||||||
|
multi-round execution, and background behaviour. Extraction work must preserve tool
|
||||||
|
event semantics, policy enforcement, cancellation, and test patch points.
|
||||||
|
|
||||||
|
Historical agent-loop modularization discussion is tracked in
|
||||||
|
[#3266](https://github.com/odysseus-dev/odysseus/issues/3266).
|
||||||
|
|
||||||
|
### Tool implementation boundaries
|
||||||
|
|
||||||
|
Tool implementation is no longer represented by one proposed future package alone.
|
||||||
|
Current responsibilities are distributed across:
|
||||||
|
|
||||||
|
- `src/tool_execution.py`;
|
||||||
|
- `src/tool_schemas.py`;
|
||||||
|
- `src/tool_index.py`;
|
||||||
|
- `src/tool_policy.py`;
|
||||||
|
- `src/tool_security.py`;
|
||||||
|
- `src/agent_tools/`;
|
||||||
|
- `src/tools/`;
|
||||||
|
- remaining compatibility surfaces such as `src/tool_implementations.py`.
|
||||||
|
|
||||||
|
Historical tool modularization work is tracked in
|
||||||
|
[#3629](https://github.com/odysseus-dev/odysseus/issues/3629).
|
||||||
|
|
||||||
|
### Route ownership
|
||||||
|
|
||||||
|
`routes/` now contains both flat modules and domain packages. Existing package
|
||||||
|
boundaries should be extended only through focused changes. Broad mechanical route
|
||||||
|
movement would affect registration, imports, tests, monkeypatch targets, and
|
||||||
|
compatibility paths.
|
||||||
|
|
||||||
|
### Frontend concentration
|
||||||
|
|
||||||
|
The no-build frontend contains several large JavaScript modules and one central CSS
|
||||||
|
file. Refactors should preserve module load order, global compatibility exports,
|
||||||
|
DOM contracts, deep-link handling, and browser behaviour.
|
||||||
|
|
||||||
|
## Non-implemented architecture options
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> The paths below are historical or possible design directions. They do not describe
|
||||||
|
> the current repository and are not approved implementation plans.
|
||||||
|
|
||||||
|
Earlier planning discussed:
|
||||||
|
|
||||||
|
- renaming `app.py` to `main.py`;
|
||||||
|
- moving agent orchestration into a new `src/agent/` package;
|
||||||
|
- introducing broad `src/domain/`, `src/infra/`, `src/api/`, or `src/pkg/` layers;
|
||||||
|
- moving all routes into domain subpackages;
|
||||||
|
- splitting database models into a new infrastructure hierarchy.
|
||||||
|
|
||||||
|
These options should be reconsidered against the current tree rather than copied
|
||||||
|
forward as assumed targets.
|
||||||
|
|
||||||
|
## Refactor guardrails
|
||||||
|
|
||||||
|
- Keep structural changes behaviour-preserving.
|
||||||
|
- Change one ownership boundary at a time.
|
||||||
|
- Do not mix file movement with unrelated feature work.
|
||||||
|
- Preserve existing import and monkeypatch paths where compatibility is required.
|
||||||
|
- Identify focused tests before modifying high-authority modules.
|
||||||
|
- Validate startup, imports, and affected runtime paths.
|
||||||
|
- Avoid repository-wide package reorganizations without maintainer agreement.
|
||||||
|
- Treat generated metrics as snapshots, not architectural decisions.
|
||||||
|
|
||||||
|
## Reproduce the snapshot
|
||||||
|
|
||||||
|
Run these commands from the repository root.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Tracked directory totals
|
||||||
|
for dir in src routes core services mcp_servers scripts static/js tests; do
|
||||||
|
files="$(git ls-files "$dir" | wc -l)"
|
||||||
|
python_files="$(git ls-files "$dir" '*.py' | wc -l)"
|
||||||
|
|
||||||
|
printf '%-14s tracked=%-5s python=%-5s\n' \
|
||||||
|
"$dir" \
|
||||||
|
"$files" \
|
||||||
|
"$python_files"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Largest tracked backend files
|
||||||
|
git ls-files \
|
||||||
|
'app.py' \
|
||||||
|
'launcher.py' \
|
||||||
|
'setup.py' \
|
||||||
|
'core/*.py' \
|
||||||
|
'core/**/*.py' \
|
||||||
|
'routes/*.py' \
|
||||||
|
'routes/**/*.py' \
|
||||||
|
'services/*.py' \
|
||||||
|
'services/**/*.py' \
|
||||||
|
'src/*.py' \
|
||||||
|
'src/**/*.py' \
|
||||||
|
'mcp_servers/*.py' \
|
||||||
|
'scripts/*.py' \
|
||||||
|
'scripts/**/*.py' |
|
||||||
|
xargs wc -l |
|
||||||
|
sort -nr |
|
||||||
|
head -31
|
||||||
|
|
||||||
|
# Largest tracked frontend source files
|
||||||
|
git ls-files \
|
||||||
|
'static/*.js' \
|
||||||
|
'static/*.css' \
|
||||||
|
'static/*.html' \
|
||||||
|
'static/**/*.js' \
|
||||||
|
'static/**/*.css' \
|
||||||
|
'static/**/*.html' |
|
||||||
|
grep -vE '\.min\.js$' |
|
||||||
|
xargs wc -l |
|
||||||
|
sort -nr |
|
||||||
|
head -31
|
||||||
|
```
|
||||||
|
|
||||||
|
## Validation for architecture changes
|
||||||
|
|
||||||
|
Use the smallest relevant checks first, then expand according to risk:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 -m compileall -q app.py core routes services src
|
||||||
|
venv/bin/python -m pytest tests/<focused-test-file>.py -q
|
||||||
|
venv/bin/python -m pytest -q
|
||||||
|
```
|
||||||
|
|
||||||
|
Startup, browser, Docker, and integration checks may also be required depending on
|
||||||
|
the affected boundary.
|
||||||
|
|
||||||
|
## Related documentation
|
||||||
|
|
||||||
|
- [Documentation style](../docs/STYLE.md)
|
||||||
|
- [Discovery maps](../discovery/README.md)
|
||||||
|
- [Current system map](../discovery/system-map.md)
|
||||||
|
- [Safety boundaries](../discovery/safety-boundaries.md)
|
||||||
|
- [Frontend module summary](../static/js/MODULE_SUMMARY.md)
|
||||||
|
- [Testing standard](../tests/TESTING_STANDARD.md)
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
# Architecture
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> This document is the proposed canonical destination for stable high-level
|
||||||
|
> architecture facts. It remains subject to maintainer review. Source code,
|
||||||
|
> tests, and configuration remain authoritative for implementation-sensitive
|
||||||
|
> behaviour.
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
This document identifies the stable runtime boundaries and primary ownership
|
||||||
|
locations used to navigate and extend Odysseus.
|
||||||
|
|
||||||
|
It intentionally excludes generated metrics, file-size rankings, refactor
|
||||||
|
priorities, unresolved investigation findings, and proposed package layouts.
|
||||||
|
|
||||||
|
## Runtime structure
|
||||||
|
|
||||||
|
| Area | Responsibility |
|
||||||
|
|---|---|
|
||||||
|
| `app.py` | FastAPI application composition and primary application entry point |
|
||||||
|
| `launcher.py` | Application launch support |
|
||||||
|
| `setup.py` | Native setup workflow |
|
||||||
|
| `core/` | Authentication, middleware, persistence, sessions, and platform primitives |
|
||||||
|
| `routes/` | HTTP and API route handlers |
|
||||||
|
| `src/` | Application orchestration, tools, providers, and runtime helpers |
|
||||||
|
| `services/` | Domain-oriented service implementations |
|
||||||
|
| `mcp_servers/` | Built-in MCP server implementations |
|
||||||
|
| `scripts/` | CLI tools, diagnostics, maintenance, and migration helpers |
|
||||||
|
| `static/` | No-build browser frontend and bundled assets |
|
||||||
|
| `tests/` | Automated tests and supporting test infrastructure |
|
||||||
|
|
||||||
|
## Subsystem boundaries
|
||||||
|
|
||||||
|
| Subsystem | Primary implementation locations |
|
||||||
|
|---|---|
|
||||||
|
| Application startup | `app.py`, `src/app_initializer.py`, `core/` |
|
||||||
|
| Authentication and sessions | `core/auth.py`, `core/middleware.py`, `core/session_manager.py`, `routes/auth_routes.py` |
|
||||||
|
| Chat and streaming | `routes/chat_routes.py`, `routes/chat_helpers.py`, `src/chat_handler.py`, `src/chat_processor.py`, `src/llm_core.py` |
|
||||||
|
| Agents and tools | `src/agent_loop.py`, `src/tool_execution.py`, `src/agent_tools/`, `src/tools/`, `src/tool_policy.py`, `src/tool_security.py` |
|
||||||
|
| Models and providers | `routes/model_routes.py`, `src/model_discovery.py`, `src/model_capabilities.py`, `src/endpoint_resolver.py`, `src/llm_core.py` |
|
||||||
|
| Cookbook and hardware fit | `routes/cookbook_routes.py`, `routes/cookbook_helpers.py`, `src/cookbook_serve_lifecycle.py`, `services/hwfit/` |
|
||||||
|
| Search and research | `routes/search_routes.py`, `services/search/`, `routes/research/`, `services/research/`, `src/deep_research.py` |
|
||||||
|
| Documents and retrieval | `routes/document_routes.py`, `src/document_processor.py`, `src/personal_docs.py`, `src/rag_manager.py`, `src/pdf_runtime.py` |
|
||||||
|
| Memory and skills | `routes/memory/`, `services/memory/`, `routes/skills_routes.py` |
|
||||||
|
| Email | `routes/email_routes.py`, `routes/email_helpers.py`, `routes/email_pollers.py`, `mcp_servers/email_server.py` |
|
||||||
|
| Calendar, contacts, notes, and tasks | `routes/calendar_routes.py`, `routes/contacts/`, `routes/note/`, `routes/task_routes.py`, `src/task_scheduler.py` |
|
||||||
|
| Media and speech | `routes/gallery/`, `routes/stt_routes.py`, `routes/tts_routes.py`, `services/stt/`, `services/tts/` |
|
||||||
|
| Persistence and operations | `core/database.py`, `src/runtime_paths.py`, `src/bg_jobs.py`, `routes/backup_routes.py`, `routes/cleanup/` |
|
||||||
|
|
||||||
|
## Architectural constraints
|
||||||
|
|
||||||
|
- Preserve established import and compatibility paths unless a focused change
|
||||||
|
explicitly migrates them.
|
||||||
|
- Keep HTTP concerns in route modules and reusable domain behaviour in runtime
|
||||||
|
or service modules.
|
||||||
|
- Treat shared persistence, agent orchestration, tool execution, and application
|
||||||
|
startup as high-authority boundaries.
|
||||||
|
- Change one ownership boundary at a time.
|
||||||
|
- Do not mix structural movement with unrelated feature behaviour.
|
||||||
|
- Validate affected imports, startup paths, compatibility surfaces, and tests.
|
||||||
|
|
||||||
|
## Frontend
|
||||||
|
|
||||||
|
The browser frontend is a no-build ES-module application under `static/`.
|
||||||
|
|
||||||
|
Its maintained module-level structure is documented in
|
||||||
|
[`static/js/MODULE_SUMMARY.md`](../static/js/MODULE_SUMMARY.md).
|
||||||
|
|
||||||
|
## Investigation and snapshots
|
||||||
|
|
||||||
|
Non-canonical investigation material is maintained under [`discovery/`](../discovery/).
|
||||||
|
|
||||||
|
The following documents may contain dated observations, metrics, unresolved
|
||||||
|
questions, or historical planning and must not be treated as specifications:
|
||||||
|
|
||||||
|
- [`discovery/system-map.md`](../discovery/system-map.md)
|
||||||
|
- [`discovery/architecture-runtime-inventory.md`](../discovery/architecture-runtime-inventory.md)
|
||||||
|
|
||||||
|
## Documentation authority
|
||||||
|
|
||||||
|
- Code, tests, and configuration define implemented behaviour.
|
||||||
|
- Mature specifications define accepted subsystem behaviour where they exist.
|
||||||
|
- Following maintainer acceptance, this document will define the high-level
|
||||||
|
architecture map.
|
||||||
|
- Discovery documents preserve evidence and uncertainty but remain
|
||||||
|
non-canonical.
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
# Documentation style
|
||||||
|
|
||||||
|
This guide defines the shared structure and writing conventions for Odysseus documentation.
|
||||||
|
|
||||||
|
## Principles
|
||||||
|
|
||||||
|
- Write for a clear audience and purpose.
|
||||||
|
- State whether a document is canonical, informational, a snapshot, or planning material.
|
||||||
|
- Prefer current behaviour over historical explanation.
|
||||||
|
- Link to source files, tests, issues, or other documentation when useful.
|
||||||
|
- Separate verified behaviour from assumptions, open questions, and future work.
|
||||||
|
- Keep headings descriptive and consistent.
|
||||||
|
- Use Markdown callouts where status or risk must be visible.
|
||||||
|
- Do not use emojis.
|
||||||
|
|
||||||
|
## Document status
|
||||||
|
|
||||||
|
Use a status callout near the top when the document is not normal canonical guidance.
|
||||||
|
|
||||||
|
### Canonical documentation
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
> This document describes accepted current behaviour. Verify implementation-sensitive details against the current code and tests.
|
||||||
|
|
||||||
|
### Discovery material
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> This is non-canonical discovery material. It records code-grounded observations and open questions.
|
||||||
|
|
||||||
|
### Snapshot or inventory
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
> This document is a dated snapshot. Counts, paths, and implementation details may drift as the codebase changes.
|
||||||
|
|
||||||
|
### Planning material
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> This document records planning context. It does not define current runtime behaviour or guarantee future implementation.
|
||||||
|
|
||||||
|
## Recommended structure
|
||||||
|
|
||||||
|
Use the following sections where relevant:
|
||||||
|
|
||||||
|
1. Title
|
||||||
|
2. Purpose or status callout
|
||||||
|
3. Scope
|
||||||
|
4. Current behaviour or guidance
|
||||||
|
5. Safety, limitations, or known gaps
|
||||||
|
6. Validation or evidence
|
||||||
|
7. Related documentation
|
||||||
|
|
||||||
|
Not every document needs every section.
|
||||||
|
|
||||||
|
## Writing style
|
||||||
|
|
||||||
|
- Use concise sentences.
|
||||||
|
- Prefer direct language.
|
||||||
|
- Avoid jokes, filler, and informal warnings.
|
||||||
|
- Avoid repeating the same guidance across several files.
|
||||||
|
- Link to the owning document instead of duplicating large sections.
|
||||||
|
- Use lists for procedures, requirements, and comparisons.
|
||||||
|
- Use tables only when they improve scanning.
|
||||||
|
- Use fenced code blocks with an appropriate language identifier.
|
||||||
|
- Use relative repository links for internal files.
|
||||||
|
|
||||||
|
## Authority
|
||||||
|
|
||||||
|
The current code, tests, and configuration are the source of truth for implemented behaviour.
|
||||||
|
|
||||||
|
Canonical documentation describes accepted behaviour and supported workflows.
|
||||||
|
|
||||||
|
Discovery, inventory, and planning documents must identify themselves explicitly and must not silently become behavioural specifications.
|
||||||
@@ -181,8 +181,8 @@ Dirty, blocked, conflicting, and unknown merge states are shown as risk/caution
|
|||||||
## Validation
|
## Validation
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python3 -m py_compile scripts/pr_blocker_audit.py tests/test_pr_blocker_audit.py
|
venv/bin/python -m py_compile scripts/pr_blocker_audit.py tests/test_pr_blocker_audit.py
|
||||||
python3 -m pytest tests/test_pr_blocker_audit.py -q
|
venv/bin/python -m pytest tests/test_pr_blocker_audit.py -q
|
||||||
python3 scripts/pr_blocker_audit.py --help
|
python3 scripts/pr_blocker_audit.py --help
|
||||||
git diff --check
|
git diff --check
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -1,412 +1,31 @@
|
|||||||
# Architecture Runtime Inventory
|
# Architecture runtime inventory disposition
|
||||||
|
|
||||||
> **Purpose**: Phase 0 planning baseline for codebase readability improvements (#4071).
|
> [!NOTE]
|
||||||
> **Parent issue**: [#4082](https://github.com/odysseus-dev/odysseus/issues/4082)
|
> The dated architecture runtime inventory has been classified and transferred
|
||||||
> **Last updated**: dev@b58af42 | 2026-06-16
|
> to [`discovery/architecture-runtime-inventory.md`](../discovery/architecture-runtime-inventory.md)
|
||||||
> **Status**: Draft — to be reviewed before follow-up slices open.
|
> after verification of its stable facts.
|
||||||
> **Snapshot basis**: Importer / file / import-line counts are refreshed to `dev@b58af42` (2026-06-16) and are recomputable via the commands in §3.4. **Line counts** in §2.1 / §2.2 are a snapshot from an earlier baseline and drift as `dev` moves — recompute any of them with `wc -l <file>`. This inventory tracks structure and risk, not live metrics.
|
>
|
||||||
|
> Stable runtime structure and subsystem boundaries were transferred to the
|
||||||
This document maps the current runtime module structure, identifies high-risk boundaries, and recommends safe first refactor slices. It does **not** move files, change imports, or alter runtime behavior.
|
> proposed canonical destination,
|
||||||
|
> [`docs/ARCHITECTURE.md`](../docs/ARCHITECTURE.md), for maintainer review.
|
||||||
---
|
|
||||||
|
## Classification
|
||||||
## 1. Current Structure Overview
|
|
||||||
|
| Content | Disposition |
|
||||||
### 1.1 Top-Level Layout
|
|---|---|
|
||||||
|
| Stable runtime structure | Proposed canonical architecture document |
|
||||||
```
|
| Stable subsystem boundaries | Proposed canonical architecture document |
|
||||||
odysseus/
|
| Frontend module organization | `static/js/MODULE_SUMMARY.md` |
|
||||||
├── app.py # FastAPI app entrypoint (1,145 lines)
|
| Counts, rankings, and generated metrics | Non-canonical discovery inventory |
|
||||||
├── conf/ # Configuration (config.py, settings.py, settings_scrub.py)
|
| Investigation context and unresolved questions | Non-canonical discovery material |
|
||||||
├── src/ # 95 flat .py files + 2 subdirectories
|
| Refactor options and prioritization | Issues, Plane, or discovery material |
|
||||||
│ ├── agent_tools/ # Tool helpers: document, filesystem, subprocess, web
|
|
||||||
│ └── search/ # Search subsystem
|
No dated metrics, prioritization, or investigation findings remain in this
|
||||||
├── routes/ # 54 flat .py files — HTTP route handlers
|
specification path.
|
||||||
├── core/ # 10 files — database models, auth, middleware, session
|
|
||||||
├── mcp_servers/ # 5 files — MCP server implementations
|
## Review status
|
||||||
├── scripts/ # CLI tools and one-shot scripts
|
|
||||||
├── static/ # Frontend HTML/CSS/JS
|
- Findings and scope have been validated.
|
||||||
├── tests/ # 583 test files (~54,800 lines)
|
- Transfer verification has completed.
|
||||||
└── services/ # (exists as needed)
|
- The final canonical status of `docs/ARCHITECTURE.md` requires maintainer review.
|
||||||
```
|
- No implementation behaviour, test taxonomy, or runtime files were changed.
|
||||||
|
|
||||||
### 1.2 Directory Flatness Metric
|
|
||||||
|
|
||||||
| Directory | Flat `.py` Files | Subdirectories | Concern |
|
|
||||||
|-----------|-----------------|----------------|---------|
|
|
||||||
| `src/` | **95** | 2 (`agent_tools/`, `search/`) | No domain grouping; 95 files in one directory |
|
|
||||||
| `routes/` | **54** | 0 | All route handlers in one flat directory |
|
|
||||||
| `core/` | 10 | 0 | Manageable, but `database.py` is oversized |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. Largest Runtime Modules
|
|
||||||
|
|
||||||
### 2.1 Python Backend
|
|
||||||
|
|
||||||
| Rank | File | Lines | Classes | Functions | Risk |
|
|
||||||
|------|------|-------|---------|-----------|------|
|
|
||||||
| 1 | `src/tool_implementations.py` | **4,032** | 0 | ~48 | **HIGH** |
|
|
||||||
| 2 | `routes/email_routes.py` | **3,245** | — | — | **MEDIUM** |
|
|
||||||
| 3 | `routes/cookbook_routes.py` | **2,969** | — | — | **MEDIUM** |
|
|
||||||
| 4 | `src/agent_loop.py` | **2,961** | 0 | ~24 | **HIGH** |
|
|
||||||
| 5 | `src/task_scheduler.py` | **2,330** | — | 5 | MEDIUM |
|
|
||||||
| 6 | `routes/model_routes.py` | **2,266** | — | — | MEDIUM |
|
|
||||||
| 7 | `core/database.py` | **2,265** | 28 | ~59 helpers | **HIGH** |
|
|
||||||
| 8 | `src/builtin_actions.py` | **2,262** | 2 | ~24 | MEDIUM |
|
|
||||||
| 9 | `src/llm_core.py` | **2,164** | — | — | MEDIUM |
|
|
||||||
| 10 | `mcp_servers/email_server.py` | 2,197 | — | — | LOW (separate process) |
|
|
||||||
| 11 | `src/visual_report.py` | 1,918 | — | — | LOW |
|
|
||||||
| 12 | `routes/gallery_routes.py` | 1,896 | — | — | LOW |
|
|
||||||
| 13 | `src/ai_interaction.py` | 1,846 | — | — | MEDIUM |
|
|
||||||
| 14 | `routes/document_routes.py` | 1,717 | — | — | LOW |
|
|
||||||
| 15 | `routes/skills_routes.py` | 1,648 | — | — | LOW |
|
|
||||||
|
|
||||||
**Heuristic**: Files > 2,000 lines with 20+ public symbols and many importers are the highest-risk splits. Files 1,000–2,000 lines are medium-risk if tightly coupled.
|
|
||||||
|
|
||||||
### 2.2 Frontend
|
|
||||||
|
|
||||||
| File | Lines | Concern |
|
|
||||||
|------|-------|---------|
|
|
||||||
| `static/style.css` | **36,653** | Entire app CSS in one file (tracked separately in #2617) |
|
|
||||||
| `static/js/document.js` | **9,776** | Single JS file for document functionality |
|
|
||||||
| `static/js/slashCommands.js` | 6,498 | |
|
|
||||||
| `static/js/settings.js` | 5,266 | |
|
|
||||||
| `static/js/emailLibrary.js` | 5,217 | |
|
|
||||||
| `static/js/notes.js` | 5,124 | |
|
|
||||||
| `static/js/chat.js` | 4,985 | |
|
|
||||||
| `static/app.js` | 4,090 | |
|
|
||||||
|
|
||||||
**Note**: Frontend modularization is tracked separately in #2617 (CSS) and is not the focus of this Phase 0 inventory. Frontend is listed here for completeness but follow-up slices should target Python backend boundaries first.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. Import Dependency Graph
|
|
||||||
|
|
||||||
### 3.1 Who Depends on `core/database.py`
|
|
||||||
|
|
||||||
**102 files** import from `core.database` — this is the most depended-upon module:
|
|
||||||
|
|
||||||
- All route handlers (`routes/*.py`)
|
|
||||||
- Most `src/*.py` files
|
|
||||||
- `core/session_manager.py`, `core/auth.py`
|
|
||||||
- Multiple test files
|
|
||||||
|
|
||||||
**Implication**: Any split of `core/database.py` is the highest-risk refactor. It should be tackled **last**, never first.
|
|
||||||
|
|
||||||
### 3.2 Who Depends on `src/tool_implementations.py`
|
|
||||||
|
|
||||||
**17 files** import from `src.tool_implementations`:
|
|
||||||
- `src/agent_loop.py`, `src/builtin_actions.py`, `src/tool_index.py`
|
|
||||||
- `src/task_scheduler.py`, `src/tool_policy.py`
|
|
||||||
- Various tests
|
|
||||||
|
|
||||||
### 3.3 Who Depends on `src/agent_loop.py`
|
|
||||||
|
|
||||||
**22 files** import from `src.agent_loop`:
|
|
||||||
|
|
||||||
- `src/tool_policy.py`, `src/teacher_escalation.py`, `src/bg_monitor.py`
|
|
||||||
- `src/task_scheduler.py`
|
|
||||||
- Multiple test files
|
|
||||||
|
|
||||||
### 3.4 Cross-Layer Import Violations
|
|
||||||
|
|
||||||
**`src/` importing from `routes/`** (backwards dependency — domain logic depending on HTTP layer):
|
|
||||||
|
|
||||||
```
|
|
||||||
src/tool_implementations.py ──→ routes/calendar_routes.py
|
|
||||||
src/tool_implementations.py ──→ routes/cookbook_helpers.py
|
|
||||||
src/tool_implementations.py ──→ routes/email_helpers.py
|
|
||||||
src/tool_implementations.py ──→ routes/email_pollers.py
|
|
||||||
src/tool_implementations.py ──→ routes/email_routes.py
|
|
||||||
src/tool_implementations.py ──→ routes/model_routes.py
|
|
||||||
src/tool_implementations.py ──→ routes/note_routes.py
|
|
||||||
src/tool_implementations.py ──→ routes/prefs_routes.py
|
|
||||||
```
|
|
||||||
|
|
||||||
> These are **runtime imports** (inside function bodies, not at module top), which mitigates circular import risk but indicates fuzzy layer boundaries. Function-level inline imports from the HTTP layer into business logic are a code smell.
|
|
||||||
|
|
||||||
**Import counts (top-level)**:
|
|
||||||
| Direction | Count | Notes |
|
|
||||||
|-----------|-------|-------|
|
|
||||||
| `routes/` → `src/` | **374** | Expected: HTTP handlers call domain logic |
|
|
||||||
| `routes/` → `core/` | **126** | Expected: handlers access DB models |
|
|
||||||
| `src/` → `routes/` | **31** | **Unexpected**: domain logic reaching into HTTP layer (direct grep of import lines referencing `routes/`) |
|
|
||||||
| `src/` → `core/` | **106** | Acceptable but could be reduced with a data-access layer |
|
|
||||||
|
|
||||||
> **How the metrics in this document are computed** — recompute against current `dev` before treating any count as authoritative (the tree drifts; these numbers are a snapshot, not a live value):
|
|
||||||
> - `src/` flat `.py` files: `find src -maxdepth 1 -name '*.py' | wc -l`
|
|
||||||
> - `tests/` test files: `find tests -name 'test_*.py' | wc -l`
|
|
||||||
> - `core.database` importers: `grep -rlE '(from|import) +core\.database' --include='*.py' . | grep -v core/database.py | wc -l`
|
|
||||||
> - `src.agent_loop` importers: `grep -rlE '(from|import) +src\.agent_loop' --include='*.py' . | grep -v src/agent_loop.py | wc -l`
|
|
||||||
> - Cross-layer import lines: `grep -rhE '(from|import) +<pkg>' --include='*.py' <dir>/ | wc -l` (e.g. `(from|import) +routes` over `src/`)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. Route Ownership Map
|
|
||||||
|
|
||||||
Routes can be grouped into logical feature domains. Current flat structure obscures these boundaries:
|
|
||||||
|
|
||||||
| Domain | Route Files | Total Lines | Review Complexity |
|
|
||||||
|--------|-------------|-------------|-------------------|
|
|
||||||
| **Email** | `email_routes.py`, `email_helpers.py`, `email_pollers.py` | 5,936 | HIGH — most complex domain |
|
|
||||||
| **Chat / Agent** | `chat_routes.py`, `chat_helpers.py`, `shell_routes.py`, `codex_routes.py`, `skills_routes.py` | 6,365 | HIGH — core interaction surface |
|
|
||||||
| **Cookbook** | `cookbook_routes.py`, `cookbook_helpers.py`, `cookbook_output.py` | 4,110 | MEDIUM |
|
|
||||||
| **Model / LLM** | `model_routes.py`, `assistant_routes.py`, `copilot_routes.py` | 2,764 | MEDIUM |
|
|
||||||
| **Calendar / Contacts** | `calendar_routes.py`, `contacts_routes.py` | 2,336 | MEDIUM |
|
|
||||||
| **Documents** | `document_routes.py`, `document_helpers.py` | 1,954 | LOW |
|
|
||||||
| **Auth** | `auth_routes.py`, `api_token_routes.py`, `device_flow.py` | 1,171 | LOW |
|
|
||||||
| **Tasks** | `task_routes.py` (standalone) | 1,157 | LOW |
|
|
||||||
| **Session** | `session_routes.py` (standalone) | 1,287 | LOW |
|
|
||||||
| **Gallery** | `gallery_routes.py`, `gallery_helpers.py` | 1,896 | LOW |
|
|
||||||
| **Memory** | `memory_routes.py` | — | LOW |
|
|
||||||
| **Research** | `research_routes.py` | — | LOW |
|
|
||||||
| **MCP** | `mcp_routes.py` | — | LOW |
|
|
||||||
| **Notes** | `note_routes.py` | — | LOW |
|
|
||||||
| **Other** | `prefs_routes.py`, `upload_routes.py`, `vault_routes.py`, `webhook_routes.py`, `workspace_routes.py`, `search_routes.py`, `history_routes.py`, `hwfit_routes.py`, `preset_routes.py`, `signature_routes.py`, `backup_routes.py`, `cleanup_routes.py`, `diagnostics_routes.py`, `embedding_routes.py`, `emoji_routes.py`, `font_routes.py`, `stt_routes.py`, `tts_routes.py`, `compare_routes.py`, `personal_routes.py`, `editor_draft_routes.py`, `admin_wipe_routes.py`, `chatgpt_subscription_routes.py` | 2,000+ | LOW individual, HIGH cumulative |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5. Tool Registry & Implementation Boundaries
|
|
||||||
|
|
||||||
### 5.1 Current Tool Architecture
|
|
||||||
|
|
||||||
| Component | File | Lines | Role |
|
|
||||||
|-----------|------|-------|------|
|
|
||||||
| Tool schemas | `src/tool_schemas.py` | 1,392 | JSON Schema tool definitions (Duck-TypedDict) |
|
|
||||||
| Tool index | `src/tool_index.py` | 542 | RAG-based tool retrieval from ChromaDB |
|
|
||||||
| Tool implementations | `src/tool_implementations.py` | 4,032 | 33 `do_*` functions — all tool execution logic |
|
|
||||||
| Tool security | `src/tool_security.py` | — | Owner-scoped tool blocking |
|
|
||||||
| Tool policy | `src/tool_policy.py` | — | Guide-only directive, plan-mode disabled tools |
|
|
||||||
| Tool utils | `src/tool_utils.py` | — | Shared tool helpers |
|
|
||||||
|
|
||||||
### 5.2 Tool Implementation Categories
|
|
||||||
|
|
||||||
The 33 `do_*` functions in `tool_implementations.py` fall into natural domain groups — the basis for slice 1's split in §6.2:
|
|
||||||
|
|
||||||
| Category | `do_*` functions | Count |
|
|
||||||
|----------|------------------|-------|
|
|
||||||
| **System / config** | `do_manage_skills`, `do_manage_tasks`, `do_manage_endpoints`, `do_manage_mcp`, `do_manage_webhooks`, `do_manage_tokens`, `do_manage_settings`, `do_api_call`, `do_app_api` | 9 |
|
|
||||||
| **Cookbook / model serving** | `do_download_model`, `do_serve_model`, `do_list_served_models`, `do_stop_served_model`, `do_tail_serve_output`, `do_list_downloads`, `do_cancel_download`, `do_search_hf_models`, `do_adopt_served_model`, `do_list_cookbook_servers`, `do_list_serve_presets`, `do_serve_preset`, `do_list_cached_models` | 13 |
|
|
||||||
| **Notes** | `do_manage_notes` | 1 |
|
|
||||||
| **Calendar** | `do_manage_calendar` | 1 |
|
|
||||||
| **Search** | `do_search_chats` | 1 |
|
|
||||||
| **Research** | `do_manage_research`, `do_trigger_research` | 2 |
|
|
||||||
| **Contacts** | `do_resolve_contact`, `do_manage_contact` | 2 |
|
|
||||||
| **Vault** | `do_vault_search`, `do_vault_get`, `do_vault_unlock` | 3 |
|
|
||||||
| **Image** | `do_edit_image` | 1 |
|
|
||||||
| | **Total** | **33** |
|
|
||||||
|
|
||||||
> Low-level tools (filesystem, subprocess, web fetch, document parsing) live in `src/agent_tools/`, **not** in `tool_implementations.py` — out of scope for this split.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 6. Risk Assessment & Candidate Slice Ranking
|
|
||||||
|
|
||||||
> **Candidate proposals, not a committed plan.** The rankings, package shapes (e.g. `src/pkg/`, `src/domain/`, `src/infra/`, `src/api/`), split ordering, and route-grouping strategy below are **options for maintainer discussion**. Per #4082/#4071, slice ownership and order are settled by maintainers before any follow-up PR. §1–§3 above are the factual current-state inventory.
|
|
||||||
|
|
||||||
### 6.1 Risk Scale
|
|
||||||
|
|
||||||
| Level | Criteria |
|
|
||||||
|-------|----------|
|
|
||||||
| **LOW** | File has ≤3 importers AND ≤500 lines, OR is a pure refactor with clear boundaries |
|
|
||||||
| **MEDIUM** | File has 4–15 importers OR 500–1,500 lines |
|
|
||||||
| **HIGH** | File has 16+ importers OR >2,000 lines, OR has cross-layer import violations |
|
|
||||||
|
|
||||||
### 6.2 Ranked Split Candidates
|
|
||||||
|
|
||||||
| Priority | Target | Risk | Rationale |
|
|
||||||
|----------|--------|------|-----------|
|
|
||||||
| **1** | `src/tool_implementations.py` → `src/tools/*.py` | **MEDIUM** | 4,032 lines → ~10 files by tool category. Already has natural boundaries. 17 importers, tracked in #3629. Use `__init__.py` shim to keep existing imports working. |
|
|
||||||
| **2** | `routes/` → domain subdirectories (one domain per PR) | **MEDIUM** | 54 flat files. Done **one domain at a time** (e.g. a standalone PR for the email domain, then chat, …), not a broad reorganization — route modules carry helper imports, registration assumptions, and test import paths. |
|
|
||||||
| **3** | `src/agent_loop.py` → `src/agent/loop.py` + submodules | **MEDIUM-HIGH** | 2,961 lines, 24 functions. Can extract prompt building, classification, verification, and runaway detection. Tracked in #3266. |
|
|
||||||
| **4** | `src/` → `src/pkg/`, `src/domain/`, `src/infra/`, `src/api/` | **MEDIUM** | Structural reorganization. Split flat `src/` into layered packages. Must come after routes and tools are stable. |
|
|
||||||
| **5** | `routes/email_*.py` consolidation | **LOW** | Already grouped by filename prefix. Low-risk cleanup within the email domain. |
|
|
||||||
| **6** | `core/database.py` → `src/infra/database/models/*.py` | **HIGH** | 28 classes, 102 importers. Highest-risk split. Must be **last** in any sequence. Requires careful import shim strategy. |
|
|
||||||
| **7** | Frontend CSS modularization | **MEDIUM** | 36,653 lines. Tracked in #2617. Separate timeline from backend work. |
|
|
||||||
| **8** | Frontend JS modularization | **MEDIUM** | 9,776 lines in `document.js`. Introduce ES modules at minimum. |
|
|
||||||
|
|
||||||
### 6.3 Candidate First 3 Behavior-Preserving Slices
|
|
||||||
|
|
||||||
**Slice 1: Split `tool_implementations.py`** (Lowest-risk high-impact)
|
|
||||||
|
|
||||||
- Create `src/tools/` package with one file per tool category
|
|
||||||
- Add `src/tools/__init__.py` re-exporting all symbols with current names
|
|
||||||
- Update 17 importers to use new paths (can be deferred via shim)
|
|
||||||
- Validation: `python -m pytest tests/ -x -q` + manual smoke test of tool execution
|
|
||||||
- Reference: #3629
|
|
||||||
|
|
||||||
**Slice 2: Group `routes/` by domain** (one domain per PR, not a broad sweep)
|
|
||||||
|
|
||||||
Route modules carry helper imports, router registration assumptions, and test import paths, so this must be done **one domain at a time** rather than as a single reorganization PR. Example sequence (each its own PR):
|
|
||||||
|
|
||||||
- PR 2a: move the **email** domain (`email_routes.py`, `email_helpers.py`, `email_pollers.py`) → `routes/email/` + shim
|
|
||||||
- PR 2b: move the **chat/agent** domain → `routes/chat/` + shim
|
|
||||||
- PR 2c: move the **cookbook** domain → `routes/cookbook/` + shim
|
|
||||||
- …and so on per domain from §4
|
|
||||||
|
|
||||||
Each PR: add `__init__.py` re-exporting old names, update `app.py` router imports, validation `python app.py` starts clean. **No behavior change** — pure file reorganization.
|
|
||||||
|
|
||||||
**Slice 3: Extract `agent_loop.py` submodules** (Improve reviewability)
|
|
||||||
|
|
||||||
- Move prompt assembly → `src/agent/prompt.py`
|
|
||||||
- Move request classification → `src/agent/classifier.py`
|
|
||||||
- Move sub-agent verification → `src/agent/verifier.py`
|
|
||||||
- Move runaway detection → `src/agent/runaway.py`
|
|
||||||
- Move context management → `src/agent/context.py`
|
|
||||||
- Keep `src/agent/loop.py` as the main orchestration module
|
|
||||||
- Validation: `python -m pytest tests/test_agent_loop.py tests/test_loop_breaker_runaway.py -v`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 7. Safety Guardrails for Follow-Up Work
|
|
||||||
|
|
||||||
Per maintainer guidance in #4082 and #4071:
|
|
||||||
|
|
||||||
- [ ] **One domain/slice per PR** — never mix multiple reorganizations
|
|
||||||
- [ ] **No behavior changes** mixed with file moves — pure reorganization only
|
|
||||||
- [ ] **Keep compatibility shims** — `__init__.py` re-exports for all existing import paths
|
|
||||||
- [ ] **Add or identify focused tests** before risky splits
|
|
||||||
- [ ] **Do not start with `core/database.py`** or broad route movement unless this inventory shows a safe boundary
|
|
||||||
- [ ] **Prefer small, reviewable slices** over large restructures
|
|
||||||
- [ ] **No packaging/runtime/tooling migration** mixed into file moves
|
|
||||||
- [ ] **No frontend framework migration** inside this stabilization lane
|
|
||||||
- [ ] **Validate with `python -m compileall`** — every PR must pass CI checks
|
|
||||||
- [ ] **Validate with `pytest`** — run the full test suite before opening each PR
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 8. Validation Commands
|
|
||||||
|
|
||||||
Each follow-up PR should be verifiable with these commands before submission:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Syntax check — must pass with zero errors
|
|
||||||
python -m compileall src/ routes/ core/ conf/
|
|
||||||
|
|
||||||
# Full test suite — must match baseline pass rate
|
|
||||||
python -m pytest tests/ -x -q
|
|
||||||
|
|
||||||
# Import shim verification — existing import paths must still work
|
|
||||||
python -c "from src.tool_implementations import do_search_chats; print('OK')"
|
|
||||||
|
|
||||||
# App startup smoke test (if backend touched)
|
|
||||||
timeout 5 python app.py 2>&1 | head -5 || true
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 9. Open Questions
|
|
||||||
|
|
||||||
1. Is `#2538` (specs ground truth) the canonical behavior map baseline, and should this inventory be kept in sync with those specs once merged?
|
|
||||||
2. Should route grouping follow the domain map proposed here, or is there a different taxonomy preferred by maintainers?
|
|
||||||
3. For the `tool_implementations.py` split (#3629), is the tool categorization in §5.2 acceptable, or should it follow a different grouping?
|
|
||||||
4. Should compatibility shims (`__init__.py`) be temporary (removed in a follow-up wave) or permanent?
|
|
||||||
5. Should an ADR (Architecture Decision Record) document be started to track decisions made during this process?
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 10. Future Direction (NOT current state)
|
|
||||||
|
|
||||||
The following are **future refactor targets** (candidate directions **pending maintainer agreement**, not committed), recorded here so this inventory does not imply they exist today. None of them are present in the current `dev` tree:
|
|
||||||
|
|
||||||
- `main.py` — proposed rename of the `app.py` entrypoint. Today the app boots via `app.py`.
|
|
||||||
- `src/agent/` — proposed package to hold `agent_loop.py` submodules (prompt/classifier/verifier/runaway/context). Today `agent_loop.py` is a single flat file in `src/`.
|
|
||||||
- `src/infra/`, `src/domain/`, `src/pkg/`, `src/api/` — proposed layered reorganization of the flat `src/` directory (slice 4 in §6).
|
|
||||||
|
|
||||||
These become real only when the corresponding slices land.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Appendix A: File Listing
|
|
||||||
|
|
||||||
### `src/` (95 files — 61 shown; run `ls src/*.py` for the full list)
|
|
||||||
|
|
||||||
```
|
|
||||||
agent_loop.py tool_implementations.py tool_schemas.py
|
|
||||||
tool_index.py tool_security.py tool_policy.py
|
|
||||||
tool_utils.py builtin_actions.py task_scheduler.py
|
|
||||||
llm_core.py model_context.py model_discovery.py
|
|
||||||
session_search.py context_budget.py context_compactor.py
|
|
||||||
ai_interaction.py action_intents.py agent_runs.py
|
|
||||||
app_helpers.py app_initializer.py config.py
|
|
||||||
database.py memory.py memory_provider.py
|
|
||||||
secret_storage.py prompt_security.py url_security.py
|
|
||||||
url_safety.py rate_limiter.py cleanup_service.py
|
|
||||||
readiness.py service_health.py exceptions.py
|
|
||||||
request_models.py assistant_log.py bg_monitor.py
|
|
||||||
builtin_mcp.py chat_helpers.py chroma_client.py
|
|
||||||
document_processor.py embedding_lanes.py deep_research.py
|
|
||||||
research_handler.py research_utils.py personal_docs.py
|
|
||||||
rag_manager.py rag_singleton.py topic_analyzer.py
|
|
||||||
visual_report.py youtube_handler.py pdf_forms.py
|
|
||||||
pdf_form_doc.py pdf_runtime.py caldav_writeback.py
|
|
||||||
email_thread_parser.py text_helpers.py user_time.py
|
|
||||||
teacher_escalation.py cookbook_serve_lifecycle.py
|
|
||||||
chatgpt_subscription.py mcp_manager.py
|
|
||||||
```
|
|
||||||
|
|
||||||
### `routes/` (54 files)
|
|
||||||
|
|
||||||
```
|
|
||||||
__init__.py _validators.py
|
|
||||||
auth_routes.py api_token_routes.py device_flow.py
|
|
||||||
chat_routes.py chat_helpers.py shell_routes.py
|
|
||||||
codex_routes.py skills_routes.py
|
|
||||||
email_routes.py email_helpers.py email_pollers.py
|
|
||||||
cookbook_routes.py cookbook_helpers.py cookbook_output.py
|
|
||||||
model_routes.py assistant_routes.py copilot_routes.py
|
|
||||||
calendar_routes.py contacts_routes.py
|
|
||||||
document_routes.py document_helpers.py
|
|
||||||
gallery_routes.py gallery_helpers.py
|
|
||||||
task_routes.py session_routes.py
|
|
||||||
note_routes.py memory_routes.py research_routes.py
|
|
||||||
mcp_routes.py search_routes.py history_routes.py
|
|
||||||
webhook_routes.py workspace_routes.py upload_routes.py
|
|
||||||
vault_routes.py prefs_routes.py preset_routes.py
|
|
||||||
signature_routes.py personal_routes.py hwfit_routes.py
|
|
||||||
backup_routes.py cleanup_routes.py diagnostics_routes.py
|
|
||||||
embedding_routes.py emoji_routes.py font_routes.py
|
|
||||||
stt_routes.py tts_routes.py compare_routes.py
|
|
||||||
editor_draft_routes.py chatgpt_subscription_routes.py admin_wipe_routes.py
|
|
||||||
```
|
|
||||||
|
|
||||||
### `core/` (10 files)
|
|
||||||
|
|
||||||
```
|
|
||||||
__init__.py constants.py database.py models.py
|
|
||||||
auth.py middleware.py session_manager.py exceptions.py
|
|
||||||
atomic_io.py platform_compat.py
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Appendix B: Key Import Relationships
|
|
||||||
|
|
||||||
```
|
|
||||||
core/database.py ←── 102 importers (routes/*, src/*, core/*, tests/*)
|
|
||||||
↑
|
|
||||||
├── routes/auth_routes.py
|
|
||||||
├── routes/email_routes.py
|
|
||||||
├── src/builtin_actions.py
|
|
||||||
├── src/task_scheduler.py
|
|
||||||
├── src/tool_implementations.py (inline)
|
|
||||||
└── ...97 more
|
|
||||||
|
|
||||||
src/tool_implementations.py ←── 17 importers
|
|
||||||
↑
|
|
||||||
├── src/agent_loop.py
|
|
||||||
├── src/builtin_actions.py
|
|
||||||
├── src/tool_index.py
|
|
||||||
├── src/task_scheduler.py
|
|
||||||
├── src/tool_policy.py
|
|
||||||
└── ...12 more (mostly tests)
|
|
||||||
|
|
||||||
src/agent_loop.py ←── 22 importers
|
|
||||||
↑
|
|
||||||
├── src/tool_policy.py
|
|
||||||
├── src/teacher_escalation.py
|
|
||||||
├── src/bg_monitor.py
|
|
||||||
├── src/task_scheduler.py
|
|
||||||
└── 18 more (incl. tests)
|
|
||||||
```
|
|
||||||
|
|||||||
+125
-175
@@ -1,202 +1,152 @@
|
|||||||
# Test Layout Inventory
|
# Test layout inventory
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> This document is a completed implementation snapshot for the first low-risk
|
||||||
|
> test-directory reorganization. It does not propose additional file moves and
|
||||||
|
> is not the canonical definition of the current test taxonomy.
|
||||||
|
|
||||||
|
- **Original inventory:** #3712
|
||||||
|
- **Parent tracker:** #2523
|
||||||
|
- **Implemented by:** #3842
|
||||||
|
- **Status:** completed historical snapshot
|
||||||
|
|
||||||
## Purpose
|
## Purpose
|
||||||
|
|
||||||
Inventory for the first low-risk split of the flat `tests/` directory
|
This document preserves the reasoning, scope, and validation contract for the
|
||||||
(issue #3712, parent #2523). This document only records *what* should move
|
first mechanical reorganization of the formerly flat `tests/` directory.
|
||||||
first and *why*; it moves nothing. The actual move is a separate, mechanical
|
|
||||||
PR that relocates the listed files verbatim and changes no test content.
|
|
||||||
|
|
||||||
The target layout and category definitions come from
|
The original change moved 28 tests classified as `area_cli` into `tests/cli/`
|
||||||
[`TESTING_STANDARD.md`](./TESTING_STANDARD.md); the collection-time markers
|
without changing their assertions, helpers, taxonomy, or runtime behaviour.
|
||||||
come from [`_taxonomy.py`](./_taxonomy.py), which classifies by **filename
|
|
||||||
tokens only** (paths are ignored, except the `tests/helpers/` rule). A file
|
|
||||||
keeps its `area_*`/`sub_*` markers when moved into a subdirectory, and
|
|
||||||
`conftest.py` discovers marker names recursively (`rglob`), so a move does not
|
|
||||||
disturb marker registration or focused selection.
|
|
||||||
|
|
||||||
## Current low-risk candidate groups
|
Current testing guidance and classification rules are maintained in:
|
||||||
|
|
||||||
Groups whose tests need no route/app setup and no real DB/session setup:
|
- [`README.md`](./README.md)
|
||||||
|
- [`TESTING_STANDARD.md`](./TESTING_STANDARD.md)
|
||||||
|
- [`_taxonomy.py`](./_taxonomy.py)
|
||||||
|
|
||||||
1. **CLI / script tests** (`area_cli`, 28 files) - load `scripts/` entry
|
The current repository and test suite remain authoritative when this snapshot
|
||||||
points via `tests.helpers.cli_loader.load_script`; DB access is stubbed
|
and the implementation differ.
|
||||||
with `tests.helpers.db_stubs` (`SessionLocal` is a plain stub attribute).
|
|
||||||
No `TestClient`, no FastAPI app import, no SQLite files.
|
|
||||||
2. **Helper self-tests** (`area_helpers`) - e.g. `test_helpers_import_state.py`,
|
|
||||||
`test_db_stubs_helper.py`. Safe but tiny (two files), and they test the
|
|
||||||
shared helpers from the #3685 audit (merged) that the rest of the suite
|
|
||||||
depends on; little payoff as a first slice.
|
|
||||||
3. **Pure unit / parsing tests** (`area_unit`) - `*_nonstring.py`,
|
|
||||||
`*_nondict.py`, parsing tests. Large and heterogeneous; some touch
|
|
||||||
provider/session modules, so the boundary is less crisp.
|
|
||||||
4. **Static checks** - e.g. `test_readme_ascii_fenced.py`,
|
|
||||||
`test_docs_no_orphan_images.py`. Safe but tiny and `uncategorized` in the
|
|
||||||
taxonomy, so a move buys little and matches no existing marker.
|
|
||||||
|
|
||||||
Not candidates for the first move (per #3712 guidance): security/owner-scope
|
## Why CLI tests were selected
|
||||||
tests, route/API tests, DB/session-heavy tests, auth/session concurrency
|
|
||||||
tests, and the taxonomy/runner infrastructure tests that changed recently
|
|
||||||
(#3491, #3556, #3659, #3711).
|
|
||||||
|
|
||||||
## Recommended first move
|
The CLI and script tests were selected as the first low-risk group because they
|
||||||
|
formed a narrow, mechanically identifiable boundary:
|
||||||
|
|
||||||
**CLI / script tests → `tests/cli/`**
|
- script entry points were loaded through shared CLI helpers;
|
||||||
|
- database access used controlled stubs rather than persistent sessions;
|
||||||
|
- the tests did not require FastAPI application or route setup;
|
||||||
|
- the tests did not require a real database;
|
||||||
|
- taxonomy classification could be derived consistently from filenames;
|
||||||
|
- absolute helper imports remained valid after relocation.
|
||||||
|
|
||||||
Why this group over the alternatives:
|
This reduced the risk relative to route, security, session, provider, and
|
||||||
|
heterogeneous unit-test groups.
|
||||||
|
|
||||||
- Lowest coupling: every file imports only the script under test (via
|
## Completed implementation
|
||||||
`cli_loader`) plus `tests.helpers` stubs - no app, no routes, no real DB.
|
|
||||||
- Crisp, machine-checkable boundary: the set is exactly the files classified
|
|
||||||
`area_cli` by `_taxonomy.py`, so before/after selection counts can be
|
|
||||||
compared mechanically.
|
|
||||||
- Already the planned target dir for this category in `TESTING_STANDARD.md`
|
|
||||||
(`tests/cli/`).
|
|
||||||
- Absolute imports (`from tests.helpers...`) and unique basenames mean no
|
|
||||||
import-order or module-name collisions after the move.
|
|
||||||
- Lower risk than helper self-tests (tiny group, little payoff), unit tests
|
|
||||||
(fuzzy boundary), or anything security/route/session-shaped.
|
|
||||||
|
|
||||||
## Files included in the first move
|
Repository history records the implementation as:
|
||||||
|
|
||||||
The 28 files classified `area_cli` (verified against `_taxonomy.py`):
|
- `83af3ca test: move area_cli tests into cli directory (#3842)`
|
||||||
|
|
||||||
Note: this inventory was refreshed against current `dev` after `tests/test_research_cli_status.py` was added to the `area_cli` set.
|
The following 28 files were included in that completed move:
|
||||||
|
|
||||||
- `tests/test_calendar_cli_name.py`
|
- `tests/cli/test_calendar_cli_name.py`
|
||||||
- `tests/test_contacts_cli_rows.py`
|
- `tests/cli/test_contacts_cli_rows.py`
|
||||||
- `tests/test_cookbook_cli_state.py`
|
- `tests/cli/test_cookbook_cli_state.py`
|
||||||
- `tests/test_docs_cli_content_length.py`
|
- `tests/cli/test_docs_cli_content_length.py`
|
||||||
- `tests/test_gallery_cli_album_count.py`
|
- `tests/cli/test_gallery_cli_album_count.py`
|
||||||
- `tests/test_gallery_cli_preview.py`
|
- `tests/cli/test_gallery_cli_preview.py`
|
||||||
- `tests/test_logs_cli_resolve_nonstring.py`
|
- `tests/cli/test_logs_cli_resolve_nonstring.py`
|
||||||
- `tests/test_mail_cli_read_empty_fetch.py`
|
- `tests/cli/test_mail_cli_read_empty_fetch.py`
|
||||||
- `tests/test_mail_cli_recipients.py`
|
- `tests/cli/test_mail_cli_recipients.py`
|
||||||
- `tests/test_mcp_cli_env_serialize.py`
|
- `tests/cli/test_mcp_cli_env_serialize.py`
|
||||||
- `tests/test_mcp_cli_json.py`
|
- `tests/cli/test_mcp_cli_json.py`
|
||||||
- `tests/test_memory_cli_rows.py`
|
- `tests/cli/test_memory_cli_rows.py`
|
||||||
- `tests/test_notes_cli_items.py`
|
- `tests/cli/test_notes_cli_items.py`
|
||||||
- `tests/test_personal_cli_rows.py`
|
- `tests/cli/test_personal_cli_rows.py`
|
||||||
- `tests/test_preset_cli_invalid_entries.py`
|
- `tests/cli/test_preset_cli_invalid_entries.py`
|
||||||
- `tests/test_preset_cli_set_corrupt_entry.py`
|
- `tests/cli/test_preset_cli_set_corrupt_entry.py`
|
||||||
- `tests/test_preset_cli_store.py`
|
- `tests/cli/test_preset_cli_store.py`
|
||||||
- `tests/test_research_cli_preview.py`
|
- `tests/cli/test_research_cli_preview.py`
|
||||||
- `tests/test_research_cli_status_filter.py`
|
- `tests/cli/test_research_cli_status.py`
|
||||||
- `tests/test_research_cli_status.py`
|
- `tests/cli/test_research_cli_status_filter.py`
|
||||||
- `tests/test_research_cli_store.py`
|
- `tests/cli/test_research_cli_store.py`
|
||||||
- `tests/test_sessions_cli.py`
|
- `tests/cli/test_sessions_cli.py`
|
||||||
- `tests/test_signature_cli_export.py`
|
- `tests/cli/test_signature_cli_export.py`
|
||||||
- `tests/test_skills_cli_preview.py`
|
- `tests/cli/test_skills_cli_preview.py`
|
||||||
- `tests/test_skills_cli_rows.py`
|
- `tests/cli/test_skills_cli_rows.py`
|
||||||
- `tests/test_tasks_cli_preview.py`
|
- `tests/cli/test_tasks_cli_preview.py`
|
||||||
- `tests/test_theme_cli_store.py`
|
- `tests/cli/test_theme_cli_store.py`
|
||||||
- `tests/test_webhook_cli_mask.py`
|
- `tests/cli/test_webhook_cli_mask.py`
|
||||||
|
|
||||||
## Files intentionally excluded
|
## Original exclusions
|
||||||
|
|
||||||
- `tests/test_backup_cli_security.py` - classifies as `area_security`
|
The original inventory deliberately excluded:
|
||||||
(security outranks cli in the taxonomy); moving it into `tests/cli/` would
|
|
||||||
make the directory disagree with its marker. It belongs with the security
|
|
||||||
group in a later phase.
|
|
||||||
- `tests/test_run_focus.py`, `tests/test_taxonomy.py` - taxonomy/runner
|
|
||||||
infrastructure tests, recently changed (#3556, #3659); they also pin
|
|
||||||
flat-layout paths (e.g. `tests/test_auth_config_lock_concurrency.py` in
|
|
||||||
`test_run_focus.py`), so they stay put.
|
|
||||||
- Script-like but `uncategorized` files - `test_pr_blocker_audit.py`,
|
|
||||||
`test_update_database_script.py`, `test_windows_update_script.py`,
|
|
||||||
`test_setup_admin_user.py`, `test_amd_gpu_check_args.py`, `test_hwfit_*.py`.
|
|
||||||
They exercise `scripts/` too, but moving them would make `tests/cli/`
|
|
||||||
diverge from the `area_cli` marker set. Reclassify or move them in a later,
|
|
||||||
separate slice.
|
|
||||||
- Everything else (security, routes, services, unit, js, helpers) - out of
|
|
||||||
scope for the first move by design.
|
|
||||||
|
|
||||||
## How this was verified
|
- `tests/test_backup_cli_security.py`, because its security classification
|
||||||
|
outranked the CLI token in its filename;
|
||||||
|
- taxonomy and focused-runner infrastructure, including
|
||||||
|
`tests/test_taxonomy.py` and `tests/test_run_focus.py`;
|
||||||
|
- script-oriented tests not classified as `area_cli`;
|
||||||
|
- route, service, security, session, JavaScript, helper, and broad unit-test
|
||||||
|
groups.
|
||||||
|
|
||||||
Read-only checks, run from the repo root on this branch. Note the real API is
|
These exclusions kept the implementation mechanical and prevented it from
|
||||||
`classify_test_path` (there is no `classify_test_file`).
|
mixing taxonomy changes, assertion changes, helper extraction, or unrelated
|
||||||
|
test-suite restructuring.
|
||||||
|
|
||||||
|
## Current repository observation
|
||||||
|
|
||||||
|
The current taxonomy classifies 30 files as `area_cli`:
|
||||||
|
|
||||||
|
| Location | Files |
|
||||||
|
|---|---:|
|
||||||
|
| `tests/cli/` | 28 |
|
||||||
|
| Flat `tests/` directory | 2 |
|
||||||
|
|
||||||
|
The two currently classified CLI tests outside `tests/cli/` are:
|
||||||
|
|
||||||
|
- `tests/test_calendar_cli_overlap.py`
|
||||||
|
- `tests/test_memory_cli_add_nondict.py`
|
||||||
|
|
||||||
|
These files were not part of the original 28-file implementation.
|
||||||
|
|
||||||
|
Their presence is recorded solely to keep this snapshot accurate. This
|
||||||
|
documentation update does not recommend moving them, changing their taxonomy,
|
||||||
|
or opening implementation work. Any future test-layout change requires separate
|
||||||
|
maintainer agreement, scope, and validation.
|
||||||
|
|
||||||
|
## Validation contract preserved by the original move
|
||||||
|
|
||||||
|
The completed implementation was designed to preserve:
|
||||||
|
|
||||||
|
- identical `area_cli` selection before and after relocation;
|
||||||
|
- successful direct execution of the relocated tests;
|
||||||
|
- successful whole-suite collection;
|
||||||
|
- unchanged taxonomy and focused-runner behaviour;
|
||||||
|
- no stale references to the former flat paths;
|
||||||
|
- no production-code changes.
|
||||||
|
|
||||||
|
Relevant current verification commands include:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Compute the area_cli set and confirm test_backup_cli_security.py is
|
venv/bin/python tests/run_focus.py --dry-run --area cli
|
||||||
# area_security. Expected: 28 files, then "security".
|
venv/bin/python -m pytest -m area_cli -q
|
||||||
./venv/bin/python - <<'PY'
|
venv/bin/python -m pytest tests/cli/ -q
|
||||||
from pathlib import Path
|
venv/bin/python -m pytest tests/test_taxonomy.py tests/test_run_focus.py -q
|
||||||
from tests._taxonomy import classify_test_path
|
venv/bin/python -m pytest --collect-only -q
|
||||||
|
|
||||||
cli = [p for p in sorted(Path("tests").glob("test_*.py"))
|
|
||||||
if classify_test_path(p).area == "cli"]
|
|
||||||
print(len(cli))
|
|
||||||
for p in cli:
|
|
||||||
print(p)
|
|
||||||
print(classify_test_path("tests/test_backup_cli_security.py").area)
|
|
||||||
PY
|
|
||||||
|
|
||||||
# Coupling check across the CLI files. Expected: the only hits are
|
|
||||||
# "SessionLocal" as stub attribute names passed to tests.helpers.db_stubs;
|
|
||||||
# no TestClient, FastAPI, create_app, sqlite, or dependency_overrides.
|
|
||||||
rg -n "TestClient|FastAPI|create_app|SessionLocal|sqlite|dependency_overrides" \
|
|
||||||
tests/test_*cli*.py tests/test_sessions_cli.py
|
|
||||||
|
|
||||||
# Hard-coded flat paths to the exact CLI files outside tests/. Expected: no matches.
|
|
||||||
./venv/bin/python - <<'PY2' > /tmp/area_cli_paths.txt
|
|
||||||
from pathlib import Path
|
|
||||||
from tests._taxonomy import classify_test_path
|
|
||||||
|
|
||||||
for path in sorted(Path("tests").glob("test_*.py")):
|
|
||||||
if classify_test_path(path).area == "cli":
|
|
||||||
print(path)
|
|
||||||
PY2
|
|
||||||
|
|
||||||
rg -n -F -f /tmp/area_cli_paths.txt .github scripts docs \
|
|
||||||
tests/README.md tests/TESTING_STANDARD.md pyproject.toml 2>/dev/null || true
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Also checked by reading the code: `tests/conftest.py` registers sub-markers
|
These commands describe validation coverage. This snapshot does not claim that
|
||||||
from a recursive `rglob` scan, and `tests/_taxonomy.py` classifies by filename
|
they were executed as part of the present documentation update.
|
||||||
tokens only (plus the `tests/helpers/` directory rule), so the markers of the
|
|
||||||
28 files do not change when they move into `tests/cli/`.
|
|
||||||
|
|
||||||
## Validation for the future move PR
|
|
||||||
|
|
||||||
Run with the project venv (`./venv/bin/python`); system `python3` may miss
|
|
||||||
pinned deps. Before the move, record the baseline; after, compare:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Selection must match the 28 files before and after the move.
|
|
||||||
./venv/bin/python tests/run_focus.py --dry-run --area cli
|
|
||||||
./venv/bin/python -m pytest -m area_cli -q
|
|
||||||
|
|
||||||
# Moved files pass when targeted directly.
|
|
||||||
./venv/bin/python -m pytest tests/cli/ -q
|
|
||||||
|
|
||||||
# Whole-suite collection still succeeds (catches import/path breakage).
|
|
||||||
./venv/bin/python -m pytest --collect-only -q
|
|
||||||
|
|
||||||
# Taxonomy/runner infrastructure is unaffected.
|
|
||||||
./venv/bin/python -m pytest tests/test_taxonomy.py tests/test_run_focus.py -q
|
|
||||||
|
|
||||||
# No stale flat-path references to the moved files. Expected: no matches
|
|
||||||
# outside tests/cli/ itself.
|
|
||||||
./venv/bin/python - <<'PY2' > /tmp/area_cli_paths.txt
|
|
||||||
from pathlib import Path
|
|
||||||
from tests._taxonomy import classify_test_path
|
|
||||||
|
|
||||||
for path in sorted(Path("tests").glob("test_*.py")):
|
|
||||||
if classify_test_path(path).area == "cli":
|
|
||||||
print(path)
|
|
||||||
PY2
|
|
||||||
|
|
||||||
rg -n -F -f /tmp/area_cli_paths.txt .github scripts docs \
|
|
||||||
tests/README.md tests/TESTING_STANDARD.md pyproject.toml 2>/dev/null || true
|
|
||||||
```
|
|
||||||
|
|
||||||
Pass criteria: identical test counts for `-m area_cli` before/after, zero
|
|
||||||
collection errors, and no changes outside the moved files.
|
|
||||||
|
|
||||||
## Non-goals
|
## Non-goals
|
||||||
|
|
||||||
- No file moves, renames, or deletions in this PR.
|
This document does not:
|
||||||
- No changes to `conftest.py`, `_taxonomy.py`, `run_focus.py`, helpers,
|
|
||||||
markers, CI workflows, or production code.
|
- propose moving or renaming tests;
|
||||||
- No recommendation to split the whole suite at once; later groups get their
|
- redefine taxonomy classifications;
|
||||||
own inventory-then-move slices.
|
- change test behaviour or assertions;
|
||||||
|
- prescribe the next test-suite refactor;
|
||||||
|
- replace the testing standard;
|
||||||
|
- create implementation work from the two current residual files.
|
||||||
|
|||||||
+177
-148
@@ -1,5 +1,9 @@
|
|||||||
# Oversized Test File Split Plan
|
# Oversized Test File Split Plan
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> This is generated planning material based on the current test tree.
|
||||||
|
> It does not define runtime behaviour or approve any test-file split.
|
||||||
|
|
||||||
## Purpose
|
## Purpose
|
||||||
|
|
||||||
This document plans future oversized test-file splits using current repo data.
|
This document plans future oversized test-file splits using current repo data.
|
||||||
@@ -26,8 +30,8 @@ Future split PRs must still inspect each file manually before editing.
|
|||||||
|
|
||||||
## Current summary
|
## Current summary
|
||||||
|
|
||||||
- test files scanned: 583
|
- test files scanned: 746
|
||||||
- collected pytest items counted: 3586
|
- collected pytest items counted: 4764
|
||||||
- large-file threshold: 300 lines
|
- large-file threshold: 300 lines
|
||||||
- large-collected threshold: 20 collected items
|
- large-collected threshold: 20 collected items
|
||||||
|
|
||||||
@@ -35,123 +39,123 @@ Area distribution:
|
|||||||
|
|
||||||
| Value | Files |
|
| Value | Files |
|
||||||
|---|---:|
|
|---|---:|
|
||||||
| cli | 28 |
|
| cli | 30 |
|
||||||
| helpers | 1 |
|
| helpers | 1 |
|
||||||
| js | 39 |
|
| js | 49 |
|
||||||
| routes | 23 |
|
| routes | 35 |
|
||||||
| security | 77 |
|
| security | 88 |
|
||||||
| services | 144 |
|
| services | 197 |
|
||||||
| uncategorized | 234 |
|
| uncategorized | 306 |
|
||||||
| unit | 37 |
|
| unit | 40 |
|
||||||
|
|
||||||
Sub-area distribution:
|
Sub-area distribution:
|
||||||
|
|
||||||
| Value | Files |
|
| Value | Files |
|
||||||
|---|---:|
|
|---|---:|
|
||||||
| api | 6 |
|
| api | 8 |
|
||||||
| atomic | 3 |
|
| atomic | 3 |
|
||||||
| auth | 9 |
|
| auth | 11 |
|
||||||
| calendar | 10 |
|
| calendar | 12 |
|
||||||
| cli | 28 |
|
| cli | 30 |
|
||||||
| confinement | 7 |
|
| confinement | 8 |
|
||||||
| cookbook | 13 |
|
| cookbook | 20 |
|
||||||
| document | 11 |
|
| document | 13 |
|
||||||
| email | 12 |
|
| email | 23 |
|
||||||
| embedding | 3 |
|
| embedding | 6 |
|
||||||
| gallery | 5 |
|
| gallery | 6 |
|
||||||
| history | 3 |
|
| history | 3 |
|
||||||
| js | 39 |
|
| js | 49 |
|
||||||
| llm | 16 |
|
| llm | 21 |
|
||||||
| mcp | 8 |
|
| mcp | 12 |
|
||||||
| memory | 15 |
|
| memory | 17 |
|
||||||
| nondict | 7 |
|
| nondict | 7 |
|
||||||
| nonstring | 22 |
|
| nonstring | 23 |
|
||||||
| owner | 14 |
|
| owner | 15 |
|
||||||
| owner_scope | 23 |
|
| owner_scope | 27 |
|
||||||
| parse | 4 |
|
| parse | 5 |
|
||||||
| provider | 6 |
|
| provider | 16 |
|
||||||
| research | 16 |
|
| research | 17 |
|
||||||
| route | 6 |
|
| route | 6 |
|
||||||
| routes | 9 |
|
| routes | 19 |
|
||||||
| scheduler | 3 |
|
| scheduler | 4 |
|
||||||
| scope | 5 |
|
| scope | 5 |
|
||||||
| security | 9 |
|
| security | 9 |
|
||||||
| session | 16 |
|
| session | 18 |
|
||||||
| ssrf | 3 |
|
| ssrf | 6 |
|
||||||
| webhook | 3 |
|
| webhook | 4 |
|
||||||
| xss | 5 |
|
| xss | 5 |
|
||||||
|
|
||||||
Values below 2 files: 244 values covering 244 files.
|
Values below 2 files: 318 values covering 318 files.
|
||||||
|
|
||||||
## Top files by collected pytest items
|
## Top files by collected pytest items
|
||||||
|
|
||||||
| File | Lines | Collected tests | Test defs | Test classes | Area | Sub-area | Signals |
|
| File | Lines | Collected tests | Test defs | Test classes | Area | Sub-area | Signals |
|
||||||
|---|---:|---:|---:|---:|---|---|---|
|
|---|---:|---:|---:|---:|---|---|---|
|
||||||
| `tests/test_model_routes.py` | 1778 | 139 | 116 | 10 | routes | routes | route/api, db/session, import-state, async/threading |
|
| `tests/test_model_routes.py` | 2099 | 163 | 134 | 10 | routes | routes | route/api, db/session, import-state, async/threading |
|
||||||
| `tests/test_security_regressions.py` | 1224 | 92 | 68 | 0 | security | security | route/api, db/session, import-state, security, filesystem, async/threading, ui/static |
|
| `tests/test_security_regressions.py` | 1515 | 98 | 74 | 0 | security | security | route/api, db/session, import-state, security, filesystem, async/threading, ui/static |
|
||||||
| `tests/test_provider_classification.py` | 188 | 67 | 21 | 4 | services | provider | - |
|
| `tests/test_cookbook_helpers.py` | 958 | 69 | 69 | 0 | services | cookbook | route/api, filesystem, subprocess/script, async/threading, ui/static |
|
||||||
| `tests/test_cookbook_helpers.py` | 912 | 65 | 65 | 0 | services | cookbook | route/api, filesystem, subprocess/script, async/threading, ui/static |
|
| `tests/test_shell_routes.py` | 538 | 69 | 53 | 9 | routes | routes | route/api, import-state, filesystem |
|
||||||
| `tests/test_shell_routes.py` | 481 | 63 | 48 | 8 | routes | routes | route/api, import-state, filesystem |
|
| `tests/test_endpoint_probing.py` | 497 | 61 | 36 | 7 | uncategorized | endpoint_probing | route/api, db/session, import-state |
|
||||||
| `tests/test_pr_blocker_audit.py` | 964 | 58 | 58 | 0 | uncategorized | pr_blocker_audit | import-state, security, filesystem |
|
| `tests/test_pr_blocker_audit.py` | 964 | 58 | 58 | 0 | uncategorized | pr_blocker_audit | import-state, security, filesystem |
|
||||||
| `tests/test_provider_endpoints.py` | 241 | 58 | 18 | 1 | services | provider | subprocess/script |
|
| `tests/test_research_routes_path_confinement.py` | 565 | 58 | 26 | 0 | security | confinement | route/api, security, filesystem, async/threading |
|
||||||
| `tests/test_agent_loop.py` | 469 | 52 | 52 | 5 | uncategorized | agent_loop | db/session, import-state |
|
| `tests/test_run_focus.py` | 492 | 55 | 52 | 0 | uncategorized | run_focus | security, filesystem, subprocess/script, ui/static |
|
||||||
| `tests/test_service_health.py` | 472 | 47 | 42 | 0 | uncategorized | service_health | async/threading |
|
| `tests/test_agent_loop.py` | 500 | 54 | 54 | 5 | uncategorized | agent_loop | db/session, import-state |
|
||||||
| `tests/test_run_focus.py` | 399 | 47 | 44 | 0 | uncategorized | run_focus | security, filesystem, subprocess/script, ui/static |
|
| `tests/test_manage_mcp_command_allowlist.py` | 168 | 45 | 10 | 0 | services | mcp | db/session, subprocess/script, async/threading, ui/static |
|
||||||
| `tests/test_llm_core_temperature.py` | 196 | 41 | 17 | 0 | services | llm | - |
|
| `tests/test_provider_classification.py` | 115 | 42 | 9 | 2 | services | provider | - |
|
||||||
| `tests/test_endpoint_probing.py` | 411 | 34 | 30 | 6 | uncategorized | endpoint_probing | route/api, db/session, import-state |
|
| `tests/test_review_regressions.py` | 1429 | 41 | 41 | 0 | uncategorized | review_regressions | route/api, db/session, import-state, filesystem, async/threading |
|
||||||
|
| `tests/test_chat_helpers.py` | 582 | 37 | 24 | 0 | uncategorized | chat_helpers | route/api, filesystem, async/threading |
|
||||||
|
| `tests/test_model_context.py` | 314 | 36 | 34 | 4 | uncategorized | model_context | db/session, import-state |
|
||||||
|
| `tests/test_email_oauth.py` | 798 | 34 | 29 | 0 | services | email | route/api, db/session, security, async/threading |
|
||||||
| `tests/test_llm_core_anthropic_temp_omit.py` | 94 | 32 | 6 | 0 | services | llm | db/session |
|
| `tests/test_llm_core_anthropic_temp_omit.py` | 94 | 32 | 6 | 0 | services | llm | db/session |
|
||||||
| `tests/test_chat_helpers.py` | 264 | 31 | 18 | 0 | uncategorized | chat_helpers | route/api |
|
| `tests/test_redos_verdict_continuation.py` | 80 | 30 | 5 | 0 | uncategorized | redos_verdict_continuation | route/api |
|
||||||
| `tests/test_provider_detection.py` | 148 | 31 | 31 | 5 | services | provider | - |
|
|
||||||
| `tests/test_model_context.py` | 251 | 30 | 30 | 4 | uncategorized | model_context | db/session, import-state |
|
|
||||||
| `tests/test_endpoint_resolver.py` | 148 | 30 | 30 | 6 | uncategorized | endpoint_resolver | - |
|
|
||||||
| `tests/test_embedding_lanes.py` | 1104 | 29 | 29 | 0 | services | embedding | filesystem |
|
|
||||||
| `tests/test_upload_limits_centralized.py` | 110 | 29 | 5 | 0 | uncategorized | upload_limits_centralized | import-state, filesystem |
|
| `tests/test_upload_limits_centralized.py` | 110 | 29 | 5 | 0 | uncategorized | upload_limits_centralized | import-state, filesystem |
|
||||||
| `tests/test_email_oauth.py` | 580 | 28 | 25 | 0 | services | email | route/api, db/session, security, async/threading |
|
| `tests/test_cookbook_docker_access.py` | 339 | 28 | 13 | 0 | services | cookbook | route/api, filesystem, async/threading |
|
||||||
| `tests/test_review_regressions.py` | 930 | 26 | 26 | 0 | uncategorized | review_regressions | route/api, db/session, import-state, filesystem, async/threading |
|
| `tests/test_rename_user_owner_sync.py` | 740 | 27 | 27 | 0 | security | owner | route/api, db/session, import-state, filesystem, async/threading |
|
||||||
| `tests/test_rename_user_owner_sync.py` | 686 | 26 | 26 | 0 | security | owner | route/api, db/session, import-state, filesystem, async/threading |
|
| `tests/test_taxonomy.py` | 151 | 27 | 17 | 0 | uncategorized | taxonomy | security, ui/static |
|
||||||
|
| `tests/test_endpoint_resolver_urls.py` | 95 | 27 | 23 | 3 | uncategorized | endpoint_resolver_urls | - |
|
||||||
| `tests/test_helpers_import_state.py` | 426 | 26 | 26 | 0 | helpers | helpers | route/api, db/session, import-state |
|
| `tests/test_helpers_import_state.py` | 426 | 26 | 26 | 0 | helpers | helpers | route/api, db/session, import-state |
|
||||||
| `tests/test_taxonomy.py` | 145 | 26 | 16 | 0 | uncategorized | taxonomy | security, ui/static |
|
| `tests/test_workspace_confine.py` | 527 | 25 | 25 | 0 | uncategorized | workspace_confine | route/api, filesystem, subprocess/script, async/threading |
|
||||||
| `tests/test_tool_path_confinement.py` | 282 | 24 | 24 | 0 | security | confinement | import-state, filesystem, async/threading |
|
| `tests/test_chat_route_tool_policy.py` | 344 | 25 | 23 | 0 | routes | route | filesystem, ui/static |
|
||||||
| `tests/test_copilot.py` | 170 | 23 | 16 | 0 | uncategorized | copilot | - |
|
| `tests/test_tool_path_confinement.py` | 303 | 25 | 25 | 0 | security | confinement | import-state, filesystem, async/threading |
|
||||||
| `tests/test_research_utils.py` | 97 | 23 | 23 | 2 | services | research | - |
|
| `tests/test_copilot.py` | 182 | 25 | 18 | 0 | uncategorized | copilot | - |
|
||||||
| `tests/test_api_chat_security.py` | 401 | 22 | 8 | 0 | security | security | route/api, db/session, import-state, filesystem, async/threading |
|
| `tests/test_llm_core_temperature_reasoning.py` | 133 | 25 | 9 | 0 | services | llm | - |
|
||||||
| `tests/test_tool_support_heuristic.py` | 166 | 22 | 22 | 3 | uncategorized | tool_support_heuristic | - |
|
| `tests/test_provider_endpoints_url_building.py` | 86 | 25 | 3 | 0 | services | provider | - |
|
||||||
| `tests/test_platform_compat.py` | 318 | 21 | 21 | 0 | uncategorized | platform_compat | import-state, filesystem, subprocess/script |
|
| `tests/test_bg_job_tools.py` | 174 | 23 | 16 | 0 | uncategorized | bg_job_tools | filesystem, async/threading |
|
||||||
|
|
||||||
## Top files by physical line count
|
## Top files by physical line count
|
||||||
|
|
||||||
| File | Lines | Collected tests | Test defs | Test classes | Area | Sub-area | Signals |
|
| File | Lines | Collected tests | Test defs | Test classes | Area | Sub-area | Signals |
|
||||||
|---|---:|---:|---:|---:|---|---|---|
|
|---|---:|---:|---:|---:|---|---|---|
|
||||||
| `tests/test_model_routes.py` | 1778 | 139 | 116 | 10 | routes | routes | route/api, db/session, import-state, async/threading |
|
| `tests/test_model_routes.py` | 2099 | 163 | 134 | 10 | routes | routes | route/api, db/session, import-state, async/threading |
|
||||||
| `tests/test_security_regressions.py` | 1224 | 92 | 68 | 0 | security | security | route/api, db/session, import-state, security, filesystem, async/threading, ui/static |
|
| `tests/test_security_regressions.py` | 1515 | 98 | 74 | 0 | security | security | route/api, db/session, import-state, security, filesystem, async/threading, ui/static |
|
||||||
| `tests/test_embedding_lanes.py` | 1104 | 29 | 29 | 0 | services | embedding | filesystem |
|
| `tests/test_review_regressions.py` | 1429 | 41 | 41 | 0 | uncategorized | review_regressions | route/api, db/session, import-state, filesystem, async/threading |
|
||||||
| `tests/test_pr_blocker_audit.py` | 964 | 58 | 58 | 0 | uncategorized | pr_blocker_audit | import-state, security, filesystem |
|
| `tests/test_pr_blocker_audit.py` | 964 | 58 | 58 | 0 | uncategorized | pr_blocker_audit | import-state, security, filesystem |
|
||||||
| `tests/test_review_regressions.py` | 930 | 26 | 26 | 0 | uncategorized | review_regressions | route/api, db/session, import-state, filesystem, async/threading |
|
| `tests/test_cookbook_helpers.py` | 958 | 69 | 69 | 0 | services | cookbook | route/api, filesystem, subprocess/script, async/threading, ui/static |
|
||||||
| `tests/test_cookbook_helpers.py` | 912 | 65 | 65 | 0 | services | cookbook | route/api, filesystem, subprocess/script, async/threading, ui/static |
|
| `tests/test_upload_handler_cleanup.py` | 831 | 13 | 13 | 0 | uncategorized | upload_handler_cleanup | route/api, db/session, filesystem, async/threading |
|
||||||
| `tests/test_rename_user_owner_sync.py` | 686 | 26 | 26 | 0 | security | owner | route/api, db/session, import-state, filesystem, async/threading |
|
| `tests/test_email_oauth.py` | 798 | 34 | 29 | 0 | services | email | route/api, db/session, security, async/threading |
|
||||||
| `tests/test_email_oauth.py` | 580 | 28 | 25 | 0 | services | email | route/api, db/session, security, async/threading |
|
| `tests/test_rename_user_owner_sync.py` | 740 | 27 | 27 | 0 | security | owner | route/api, db/session, import-state, filesystem, async/threading |
|
||||||
|
| `tests/test_email_owner_scope.py` | 656 | 13 | 13 | 0 | security | owner_scope | route/api, db/session, filesystem, async/threading |
|
||||||
|
| `tests/test_model_capability_readers.py` | 646 | 20 | 20 | 0 | uncategorized | model_capability_readers | - |
|
||||||
|
| `tests/test_chat_helpers.py` | 582 | 37 | 24 | 0 | uncategorized | chat_helpers | route/api, filesystem, async/threading |
|
||||||
| `tests/test_api_token_routes.py` | 578 | 17 | 17 | 0 | routes | api_routes | route/api, db/session, import-state, async/threading |
|
| `tests/test_api_token_routes.py` | 578 | 17 | 17 | 0 | routes | api_routes | route/api, db/session, import-state, async/threading |
|
||||||
| `tests/test_shell_routes.py` | 481 | 63 | 48 | 8 | routes | routes | route/api, import-state, filesystem |
|
| `tests/test_research_routes_path_confinement.py` | 565 | 58 | 26 | 0 | security | confinement | route/api, security, filesystem, async/threading |
|
||||||
| `tests/test_email_owner_scope.py` | 474 | 9 | 9 | 0 | security | owner_scope | route/api, db/session, filesystem, async/threading |
|
| `tests/test_shell_routes.py` | 538 | 69 | 53 | 9 | routes | routes | route/api, import-state, filesystem |
|
||||||
| `tests/test_service_health.py` | 472 | 47 | 42 | 0 | uncategorized | service_health | async/threading |
|
| `tests/test_workspace_confine.py` | 527 | 25 | 25 | 0 | uncategorized | workspace_confine | route/api, filesystem, subprocess/script, async/threading |
|
||||||
| `tests/test_agent_loop.py` | 469 | 52 | 52 | 5 | uncategorized | agent_loop | db/session, import-state |
|
| `tests/test_agent_loop.py` | 500 | 54 | 54 | 5 | uncategorized | agent_loop | db/session, import-state |
|
||||||
|
| `tests/test_endpoint_probing.py` | 497 | 61 | 36 | 7 | uncategorized | endpoint_probing | route/api, db/session, import-state |
|
||||||
|
| `tests/test_run_focus.py` | 492 | 55 | 52 | 0 | uncategorized | run_focus | security, filesystem, subprocess/script, ui/static |
|
||||||
|
| `tests/test_tool_policy.py` | 475 | 18 | 18 | 0 | uncategorized | tool_policy | import-state, async/threading |
|
||||||
| `tests/test_kv_cache_invalidation_2927.py` | 463 | 8 | 8 | 0 | uncategorized | kv_cache_invalidation_2927 | route/api, db/session, import-state, async/threading |
|
| `tests/test_kv_cache_invalidation_2927.py` | 463 | 8 | 8 | 0 | uncategorized | kv_cache_invalidation_2927 | route/api, db/session, import-state, async/threading |
|
||||||
|
| `tests/test_email_test_connection_oauth.py` | 436 | 9 | 7 | 0 | services | email | route/api, db/session, async/threading |
|
||||||
| `tests/test_helpers_import_state.py` | 426 | 26 | 26 | 0 | helpers | helpers | route/api, db/session, import-state |
|
| `tests/test_helpers_import_state.py` | 426 | 26 | 26 | 0 | helpers | helpers | route/api, db/session, import-state |
|
||||||
| `tests/test_endpoint_owner_scope_followup.py` | 414 | 11 | 11 | 0 | security | owner_scope | route/api, db/session, filesystem |
|
| `tests/test_endpoint_owner_scope_followup.py` | 414 | 11 | 11 | 0 | security | owner_scope | route/api, db/session, filesystem |
|
||||||
| `tests/test_endpoint_probing.py` | 411 | 34 | 30 | 6 | uncategorized | endpoint_probing | route/api, db/session, import-state |
|
| `tests/test_api_chat_security.py` | 404 | 22 | 8 | 0 | security | security | route/api, db/session, import-state, filesystem, async/threading |
|
||||||
| `tests/test_imap_leak_fixes.py` | 404 | 15 | 15 | 0 | uncategorized | imap_leak_fixes | route/api, db/session, security, filesystem |
|
| `tests/test_imap_leak_fixes.py` | 404 | 15 | 15 | 0 | uncategorized | imap_leak_fixes | route/api, db/session, security, filesystem |
|
||||||
| `tests/test_companion_readonly.py` | 402 | 17 | 17 | 0 | uncategorized | companion_readonly | db/session, import-state |
|
| `tests/test_companion_readonly.py` | 402 | 17 | 17 | 0 | uncategorized | companion_readonly | db/session, import-state |
|
||||||
| `tests/test_api_chat_security.py` | 401 | 22 | 8 | 0 | security | security | route/api, db/session, import-state, filesystem, async/threading |
|
|
||||||
| `tests/test_upload_handler_atomicity.py` | 401 | 9 | 9 | 0 | uncategorized | upload_handler_atomicity | filesystem, async/threading |
|
| `tests/test_upload_handler_atomicity.py` | 401 | 9 | 9 | 0 | uncategorized | upload_handler_atomicity | filesystem, async/threading |
|
||||||
| `tests/test_run_focus.py` | 399 | 47 | 44 | 0 | uncategorized | run_focus | security, filesystem, subprocess/script, ui/static |
|
| `tests/test_auth_regressions.py` | 370 | 15 | 15 | 0 | security | auth | route/api, db/session, import-state, async/threading |
|
||||||
| `tests/test_auth_regressions.py` | 375 | 15 | 15 | 0 | security | auth | route/api, db/session, import-state, async/threading |
|
| `tests/test_calendar_recurrence.py` | 356 | 20 | 20 | 0 | services | calendar | - |
|
||||||
| `tests/test_calendar_owner_scope.py` | 345 | 7 | 7 | 0 | security | owner_scope | route/api, db/session, import-state, filesystem, async/threading, ui/static |
|
| `tests/test_task_cookbook_admin_gate.py` | 350 | 10 | 10 | 0 | services | cookbook | route/api, db/session, import-state, filesystem, async/threading |
|
||||||
| `tests/test_null_owner_gates.py` | 342 | 20 | 20 | 0 | security | owner | route/api, db/session, import-state |
|
|
||||||
| `tests/test_agent_migration_manifest.py` | 340 | 15 | 15 | 0 | uncategorized | agent_migration_manifest | import-state, filesystem |
|
|
||||||
| `tests/test_calendar_recurrence.py` | 338 | 19 | 19 | 0 | services | calendar | - |
|
|
||||||
| `tests/test_tool_policy.py` | 330 | 13 | 13 | 0 | uncategorized | tool_policy | import-state, async/threading |
|
|
||||||
| `tests/test_workspace_confine.py` | 328 | 18 | 18 | 0 | uncategorized | workspace_confine | route/api, filesystem, subprocess/script, async/threading |
|
|
||||||
| `tests/test_diffusion_server_security.py` | 325 | 14 | 14 | 0 | security | security | route/api, import-state, security, filesystem, async/threading, ui/static |
|
|
||||||
|
|
||||||
## Split planning candidates
|
## Split planning candidates
|
||||||
|
|
||||||
@@ -165,53 +169,69 @@ These are planning candidates only. A later split PR still needs a focused manua
|
|||||||
|
|
||||||
| File | Why included | Setup/risk signals | Suggested handling |
|
| File | Why included | Setup/risk signals | Suggested handling |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| `tests/test_model_routes.py` | 1778 lines, 139 collected tests | route/api, db/session, import-state, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_model_routes.py` | 2099 lines, 163 collected tests | route/api, db/session, import-state, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_security_regressions.py` | 1224 lines, 92 collected tests | route/api, db/session, import-state, security, filesystem, async/threading, ui/static | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_security_regressions.py` | 1515 lines, 98 collected tests | route/api, db/session, import-state, security, filesystem, async/threading, ui/static | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_provider_classification.py` | 67 collected tests | No obvious setup signals from static scan. | Good first manual-review candidate if test themes are cohesive. |
|
| `tests/test_cookbook_helpers.py` | 958 lines, 69 collected tests | route/api, filesystem, subprocess/script, async/threading, ui/static | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_cookbook_helpers.py` | 912 lines, 65 collected tests | route/api, filesystem, subprocess/script, async/threading, ui/static | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_shell_routes.py` | 538 lines, 69 collected tests | route/api, import-state, filesystem | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_shell_routes.py` | 481 lines, 63 collected tests | route/api, import-state, filesystem | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_endpoint_probing.py` | 497 lines, 61 collected tests | route/api, db/session, import-state | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_pr_blocker_audit.py` | 964 lines, 58 collected tests | import-state, security, filesystem | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_pr_blocker_audit.py` | 964 lines, 58 collected tests | import-state, security, filesystem | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_provider_endpoints.py` | 58 collected tests | subprocess/script | Good first manual-review candidate if test themes are cohesive. |
|
| `tests/test_research_routes_path_confinement.py` | 565 lines, 58 collected tests | route/api, security, filesystem, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_agent_loop.py` | 469 lines, 52 collected tests | db/session, import-state | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_run_focus.py` | 492 lines, 55 collected tests | security, filesystem, subprocess/script, ui/static | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_service_health.py` | 472 lines, 47 collected tests | async/threading | Good first manual-review candidate if test themes are cohesive. |
|
| `tests/test_agent_loop.py` | 500 lines, 54 collected tests | db/session, import-state | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_run_focus.py` | 399 lines, 47 collected tests | security, filesystem, subprocess/script, ui/static | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_manage_mcp_command_allowlist.py` | 45 collected tests | db/session, subprocess/script, async/threading, ui/static | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_llm_core_temperature.py` | 41 collected tests | No obvious setup signals from static scan. | Good first manual-review candidate if test themes are cohesive. |
|
| `tests/test_provider_classification.py` | 42 collected tests | No obvious setup signals from static scan. | Good first manual-review candidate if test themes are cohesive. |
|
||||||
| `tests/test_endpoint_probing.py` | 411 lines, 34 collected tests | route/api, db/session, import-state | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_review_regressions.py` | 1429 lines, 41 collected tests | route/api, db/session, import-state, filesystem, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
|
| `tests/test_chat_helpers.py` | 582 lines, 37 collected tests | route/api, filesystem, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
|
| `tests/test_model_context.py` | 314 lines, 36 collected tests | db/session, import-state | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
|
| `tests/test_email_oauth.py` | 798 lines, 34 collected tests | route/api, db/session, security, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_llm_core_anthropic_temp_omit.py` | 32 collected tests | db/session | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_llm_core_anthropic_temp_omit.py` | 32 collected tests | db/session | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_chat_helpers.py` | 31 collected tests | route/api | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_redos_verdict_continuation.py` | 30 collected tests | route/api | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_provider_detection.py` | 31 collected tests | No obvious setup signals from static scan. | Good first manual-review candidate if test themes are cohesive. |
|
|
||||||
| `tests/test_model_context.py` | 30 collected tests | db/session, import-state | Defer mechanical split until setup/risk boundaries are mapped. |
|
|
||||||
| `tests/test_endpoint_resolver.py` | 30 collected tests | No obvious setup signals from static scan. | Good first manual-review candidate if test themes are cohesive. |
|
|
||||||
| `tests/test_embedding_lanes.py` | 1104 lines, 29 collected tests | filesystem | Good first manual-review candidate if test themes are cohesive. |
|
|
||||||
| `tests/test_upload_limits_centralized.py` | 29 collected tests | import-state, filesystem | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_upload_limits_centralized.py` | 29 collected tests | import-state, filesystem | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_email_oauth.py` | 580 lines, 28 collected tests | route/api, db/session, security, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_cookbook_docker_access.py` | 339 lines, 28 collected tests | route/api, filesystem, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_review_regressions.py` | 930 lines, 26 collected tests | route/api, db/session, import-state, filesystem, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_rename_user_owner_sync.py` | 740 lines, 27 collected tests | route/api, db/session, import-state, filesystem, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_rename_user_owner_sync.py` | 686 lines, 26 collected tests | route/api, db/session, import-state, filesystem, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_taxonomy.py` | 27 collected tests | security, ui/static | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
|
| `tests/test_endpoint_resolver_urls.py` | 27 collected tests | No obvious setup signals from static scan. | Good first manual-review candidate if test themes are cohesive. |
|
||||||
| `tests/test_helpers_import_state.py` | 426 lines, 26 collected tests | route/api, db/session, import-state | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_helpers_import_state.py` | 426 lines, 26 collected tests | route/api, db/session, import-state | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_taxonomy.py` | 26 collected tests | security, ui/static | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_workspace_confine.py` | 527 lines, 25 collected tests | route/api, filesystem, subprocess/script, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_tool_path_confinement.py` | 24 collected tests | import-state, filesystem, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_chat_route_tool_policy.py` | 344 lines, 25 collected tests | filesystem, ui/static | Good first manual-review candidate if test themes are cohesive. |
|
||||||
| `tests/test_copilot.py` | 23 collected tests | No obvious setup signals from static scan. | Good first manual-review candidate if test themes are cohesive. |
|
| `tests/test_tool_path_confinement.py` | 303 lines, 25 collected tests | import-state, filesystem, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
|
| `tests/test_copilot.py` | 25 collected tests | No obvious setup signals from static scan. | Good first manual-review candidate if test themes are cohesive. |
|
||||||
|
| `tests/test_llm_core_temperature_reasoning.py` | 25 collected tests | No obvious setup signals from static scan. | Good first manual-review candidate if test themes are cohesive. |
|
||||||
|
| `tests/test_provider_endpoints_url_building.py` | 25 collected tests | No obvious setup signals from static scan. | Good first manual-review candidate if test themes are cohesive. |
|
||||||
|
| `tests/test_bg_job_tools.py` | 23 collected tests | filesystem, async/threading | Good first manual-review candidate if test themes are cohesive. |
|
||||||
| `tests/test_research_utils.py` | 23 collected tests | No obvious setup signals from static scan. | Good first manual-review candidate if test themes are cohesive. |
|
| `tests/test_research_utils.py` | 23 collected tests | No obvious setup signals from static scan. | Good first manual-review candidate if test themes are cohesive. |
|
||||||
| `tests/test_api_chat_security.py` | 401 lines, 22 collected tests | route/api, db/session, import-state, filesystem, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_api_chat_security.py` | 404 lines, 22 collected tests | route/api, db/session, import-state, filesystem, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_tool_support_heuristic.py` | 22 collected tests | No obvious setup signals from static scan. | Good first manual-review candidate if test themes are cohesive. |
|
| `tests/test_tool_support_heuristic.py` | 22 collected tests | No obvious setup signals from static scan. | Good first manual-review candidate if test themes are cohesive. |
|
||||||
| `tests/test_platform_compat.py` | 318 lines, 21 collected tests | import-state, filesystem, subprocess/script | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_platform_compat.py` | 322 lines, 21 collected tests | import-state, filesystem, subprocess/script | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_context_compactor.py` | 21 collected tests | db/session, import-state, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_context_compactor.py` | 21 collected tests | db/session, import-state, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_prompt_security.py` | 21 collected tests | No obvious setup signals from static scan. | Good first manual-review candidate if test themes are cohesive. |
|
| `tests/test_prompt_security.py` | 21 collected tests | No obvious setup signals from static scan. | Good first manual-review candidate if test themes are cohesive. |
|
||||||
| `tests/test_null_owner_gates.py` | 342 lines, 20 collected tests | route/api, db/session, import-state | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_fenced_inline_args.py` | 21 collected tests | db/session, import-state | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
|
| `tests/test_cache_affinity_local_only.py` | 21 collected tests | No obvious setup signals from static scan. | Good first manual-review candidate if test themes are cohesive. |
|
||||||
|
| `tests/test_model_capability_readers.py` | 646 lines, 20 collected tests | No obvious setup signals from static scan. | Good first manual-review candidate if test themes are cohesive. |
|
||||||
|
| `tests/test_calendar_recurrence.py` | 356 lines, 20 collected tests | No obvious setup signals from static scan. | Good first manual-review candidate if test themes are cohesive. |
|
||||||
|
| `tests/test_null_owner_gates.py` | 332 lines, 20 collected tests | route/api, db/session, import-state | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
|
| `tests/test_gallery_endpoint_hardening.py` | 326 lines, 20 collected tests | route/api, security, filesystem, ui/static | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
|
| `tests/test_redos_llm_parsers.py` | 20 collected tests | No obvious setup signals from static scan. | Good first manual-review candidate if test themes are cohesive. |
|
||||||
|
| `tests/test_code_nav_tools.py` | 20 collected tests | db/session, filesystem, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_youtube_handler_consolidation.py` | 20 collected tests | route/api, import-state | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_youtube_handler_consolidation.py` | 20 collected tests | route/api, import-state | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_calendar_recurrence.py` | 338 lines | No obvious setup signals from static scan. | Plan split boundaries before editing. |
|
| `tests/test_tool_policy.py` | 475 lines | import-state, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_workspace_confine.py` | 328 lines | route/api, filesystem, subprocess/script, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_fenced_example_not_executed_for_native_models.py` | 345 lines | async/threading | Plan split boundaries before editing. |
|
||||||
| `tests/test_api_token_routes.py` | 578 lines | route/api, db/session, import-state, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_api_token_routes.py` | 578 lines | route/api, db/session, import-state, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_companion_readonly.py` | 402 lines | db/session, import-state | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_companion_readonly.py` | 402 lines | db/session, import-state | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_set_admin.py` | 317 lines | route/api, import-state, filesystem, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_set_admin.py` | 317 lines | route/api, import-state, filesystem, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
|
| `tests/test_llm_core_ollama.py` | 324 lines | async/threading | Plan split boundaries before editing. |
|
||||||
| `tests/test_imap_leak_fixes.py` | 404 lines | route/api, db/session, security, filesystem | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_imap_leak_fixes.py` | 404 lines | route/api, db/session, security, filesystem | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_auth_regressions.py` | 375 lines | route/api, db/session, import-state, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_auth_regressions.py` | 370 lines | route/api, db/session, import-state, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_agent_migration_manifest.py` | 340 lines | import-state, filesystem | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_agent_migration_manifest.py` | 340 lines | import-state, filesystem | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
|
| `tests/test_mcp_email_decode_header_spaces.py` | 327 lines | route/api, db/session, filesystem, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_diffusion_server_security.py` | 325 lines | route/api, import-state, security, filesystem, async/threading, ui/static | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_diffusion_server_security.py` | 325 lines | route/api, import-state, security, filesystem, async/threading, ui/static | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_tool_policy.py` | 330 lines | import-state, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_upload_handler_cleanup.py` | 831 lines | route/api, db/session, filesystem, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
|
| `tests/test_email_owner_scope.py` | 656 lines | route/api, db/session, filesystem, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
|
| `tests/test_upload_routes_owner_scope.py` | 344 lines | route/api, filesystem, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_endpoint_owner_scope_followup.py` | 414 lines | route/api, db/session, filesystem | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_endpoint_owner_scope_followup.py` | 414 lines | route/api, db/session, filesystem | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_upload_routes_owner_scope.py` | 315 lines | route/api, filesystem, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_composer_arrow_up_recall_js.py` | 308 lines | filesystem, subprocess/script, ui/static | Plan split boundaries before editing. |
|
||||||
| `tests/test_email_owner_scope.py` | 474 lines | route/api, db/session, filesystem, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_task_cookbook_admin_gate.py` | 350 lines | route/api, db/session, import-state, filesystem, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
|
| `tests/test_email_test_connection_oauth.py` | 436 lines | route/api, db/session, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_upload_handler_atomicity.py` | 401 lines | filesystem, async/threading | Plan split boundaries before editing. |
|
| `tests/test_upload_handler_atomicity.py` | 401 lines | filesystem, async/threading | Plan split boundaries before editing. |
|
||||||
| `tests/test_kv_cache_invalidation_2927.py` | 463 lines | route/api, db/session, import-state, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_kv_cache_invalidation_2927.py` | 463 lines | route/api, db/session, import-state, async/threading | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
| `tests/test_calendar_owner_scope.py` | 345 lines | route/api, db/session, import-state, filesystem, async/threading, ui/static | Defer mechanical split until setup/risk boundaries are mapped. |
|
| `tests/test_calendar_owner_scope.py` | 345 lines | route/api, db/session, import-state, filesystem, async/threading, ui/static | Defer mechanical split until setup/risk boundaries are mapped. |
|
||||||
@@ -226,28 +246,35 @@ Before using any of these files as a split target, first decide whether the taxo
|
|||||||
|
|
||||||
| File | Lines | Collected tests | Sub-area | Signals | Suggested follow-up |
|
| File | Lines | Collected tests | Sub-area | Signals | Suggested follow-up |
|
||||||
|---|---:|---:|---|---|---|
|
|---|---:|---:|---|---|---|
|
||||||
|
| `tests/test_endpoint_probing.py` | 497 | 61 | endpoint_probing | route/api, db/session, import-state | Review taxonomy and setup/risk boundaries before any split. |
|
||||||
| `tests/test_pr_blocker_audit.py` | 964 | 58 | pr_blocker_audit | import-state, security, filesystem | Review taxonomy and setup/risk boundaries before any split. |
|
| `tests/test_pr_blocker_audit.py` | 964 | 58 | pr_blocker_audit | import-state, security, filesystem | Review taxonomy and setup/risk boundaries before any split. |
|
||||||
| `tests/test_agent_loop.py` | 469 | 52 | agent_loop | db/session, import-state | Review taxonomy and setup/risk boundaries before any split. |
|
| `tests/test_run_focus.py` | 492 | 55 | run_focus | security, filesystem, subprocess/script, ui/static | Review taxonomy and setup/risk boundaries before any split. |
|
||||||
| `tests/test_service_health.py` | 472 | 47 | service_health | async/threading | Review taxonomy mapping before using as a split target. |
|
| `tests/test_agent_loop.py` | 500 | 54 | agent_loop | db/session, import-state | Review taxonomy and setup/risk boundaries before any split. |
|
||||||
| `tests/test_run_focus.py` | 399 | 47 | run_focus | security, filesystem, subprocess/script, ui/static | Review taxonomy and setup/risk boundaries before any split. |
|
| `tests/test_review_regressions.py` | 1429 | 41 | review_regressions | route/api, db/session, import-state, filesystem, async/threading | Review taxonomy and setup/risk boundaries before any split. |
|
||||||
| `tests/test_endpoint_probing.py` | 411 | 34 | endpoint_probing | route/api, db/session, import-state | Review taxonomy and setup/risk boundaries before any split. |
|
| `tests/test_chat_helpers.py` | 582 | 37 | chat_helpers | route/api, filesystem, async/threading | Review taxonomy and setup/risk boundaries before any split. |
|
||||||
| `tests/test_chat_helpers.py` | 264 | 31 | chat_helpers | route/api | Review taxonomy and setup/risk boundaries before any split. |
|
| `tests/test_model_context.py` | 314 | 36 | model_context | db/session, import-state | Review taxonomy and setup/risk boundaries before any split. |
|
||||||
| `tests/test_model_context.py` | 251 | 30 | model_context | db/session, import-state | Review taxonomy and setup/risk boundaries before any split. |
|
| `tests/test_redos_verdict_continuation.py` | 80 | 30 | redos_verdict_continuation | route/api | Review taxonomy and setup/risk boundaries before any split. |
|
||||||
| `tests/test_endpoint_resolver.py` | 148 | 30 | endpoint_resolver | - | Review taxonomy mapping before using as a split target. |
|
|
||||||
| `tests/test_upload_limits_centralized.py` | 110 | 29 | upload_limits_centralized | import-state, filesystem | Review taxonomy and setup/risk boundaries before any split. |
|
| `tests/test_upload_limits_centralized.py` | 110 | 29 | upload_limits_centralized | import-state, filesystem | Review taxonomy and setup/risk boundaries before any split. |
|
||||||
| `tests/test_review_regressions.py` | 930 | 26 | review_regressions | route/api, db/session, import-state, filesystem, async/threading | Review taxonomy and setup/risk boundaries before any split. |
|
| `tests/test_taxonomy.py` | 151 | 27 | taxonomy | security, ui/static | Review taxonomy and setup/risk boundaries before any split. |
|
||||||
| `tests/test_taxonomy.py` | 145 | 26 | taxonomy | security, ui/static | Review taxonomy and setup/risk boundaries before any split. |
|
| `tests/test_endpoint_resolver_urls.py` | 95 | 27 | endpoint_resolver_urls | - | Review taxonomy mapping before using as a split target. |
|
||||||
| `tests/test_copilot.py` | 170 | 23 | copilot | - | Review taxonomy mapping before using as a split target. |
|
| `tests/test_workspace_confine.py` | 527 | 25 | workspace_confine | route/api, filesystem, subprocess/script, async/threading | Review taxonomy and setup/risk boundaries before any split. |
|
||||||
|
| `tests/test_copilot.py` | 182 | 25 | copilot | - | Review taxonomy mapping before using as a split target. |
|
||||||
|
| `tests/test_bg_job_tools.py` | 174 | 23 | bg_job_tools | filesystem, async/threading | Review taxonomy mapping before using as a split target. |
|
||||||
| `tests/test_tool_support_heuristic.py` | 166 | 22 | tool_support_heuristic | - | Review taxonomy mapping before using as a split target. |
|
| `tests/test_tool_support_heuristic.py` | 166 | 22 | tool_support_heuristic | - | Review taxonomy mapping before using as a split target. |
|
||||||
| `tests/test_platform_compat.py` | 318 | 21 | platform_compat | import-state, filesystem, subprocess/script | Review taxonomy and setup/risk boundaries before any split. |
|
| `tests/test_platform_compat.py` | 322 | 21 | platform_compat | import-state, filesystem, subprocess/script | Review taxonomy and setup/risk boundaries before any split. |
|
||||||
| `tests/test_context_compactor.py` | 233 | 21 | context_compactor | db/session, import-state, async/threading | Review taxonomy and setup/risk boundaries before any split. |
|
| `tests/test_context_compactor.py` | 233 | 21 | context_compactor | db/session, import-state, async/threading | Review taxonomy and setup/risk boundaries before any split. |
|
||||||
|
| `tests/test_fenced_inline_args.py` | 186 | 21 | fenced_inline_args | db/session, import-state | Review taxonomy and setup/risk boundaries before any split. |
|
||||||
|
| `tests/test_cache_affinity_local_only.py` | 104 | 21 | cache_affinity_local_only | - | Review taxonomy mapping before using as a split target. |
|
||||||
|
| `tests/test_model_capability_readers.py` | 646 | 20 | model_capability_readers | - | Review taxonomy mapping before using as a split target. |
|
||||||
|
| `tests/test_code_nav_tools.py` | 198 | 20 | code_nav_tools | db/session, filesystem, async/threading | Review taxonomy and setup/risk boundaries before any split. |
|
||||||
| `tests/test_youtube_handler_consolidation.py` | 104 | 20 | youtube_handler_consolidation | route/api, import-state | Review taxonomy and setup/risk boundaries before any split. |
|
| `tests/test_youtube_handler_consolidation.py` | 104 | 20 | youtube_handler_consolidation | route/api, import-state | Review taxonomy and setup/risk boundaries before any split. |
|
||||||
| `tests/test_workspace_confine.py` | 328 | 18 | workspace_confine | route/api, filesystem, subprocess/script, async/threading | Review taxonomy and setup/risk boundaries before any split. |
|
| `tests/test_tool_policy.py` | 475 | 18 | tool_policy | import-state, async/threading | Review taxonomy and setup/risk boundaries before any split. |
|
||||||
|
| `tests/test_fenced_example_not_executed_for_native_models.py` | 345 | 18 | fenced_example_not_executed_for_native_models | async/threading | Review taxonomy mapping before using as a split target. |
|
||||||
| `tests/test_companion_readonly.py` | 402 | 17 | companion_readonly | db/session, import-state | Review taxonomy and setup/risk boundaries before any split. |
|
| `tests/test_companion_readonly.py` | 402 | 17 | companion_readonly | db/session, import-state | Review taxonomy and setup/risk boundaries before any split. |
|
||||||
| `tests/test_set_admin.py` | 317 | 17 | set_admin | route/api, import-state, filesystem, async/threading | Review taxonomy and setup/risk boundaries before any split. |
|
| `tests/test_set_admin.py` | 317 | 17 | set_admin | route/api, import-state, filesystem, async/threading | Review taxonomy and setup/risk boundaries before any split. |
|
||||||
| `tests/test_imap_leak_fixes.py` | 404 | 15 | imap_leak_fixes | route/api, db/session, security, filesystem | Review taxonomy and setup/risk boundaries before any split. |
|
| `tests/test_imap_leak_fixes.py` | 404 | 15 | imap_leak_fixes | route/api, db/session, security, filesystem | Review taxonomy and setup/risk boundaries before any split. |
|
||||||
| `tests/test_agent_migration_manifest.py` | 340 | 15 | agent_migration_manifest | import-state, filesystem | Review taxonomy and setup/risk boundaries before any split. |
|
| `tests/test_agent_migration_manifest.py` | 340 | 15 | agent_migration_manifest | import-state, filesystem | Review taxonomy and setup/risk boundaries before any split. |
|
||||||
| `tests/test_tool_policy.py` | 330 | 13 | tool_policy | import-state, async/threading | Review taxonomy and setup/risk boundaries before any split. |
|
| `tests/test_upload_handler_cleanup.py` | 831 | 13 | upload_handler_cleanup | route/api, db/session, filesystem, async/threading | Review taxonomy and setup/risk boundaries before any split. |
|
||||||
| `tests/test_upload_handler_atomicity.py` | 401 | 9 | upload_handler_atomicity | filesystem, async/threading | Review taxonomy mapping before using as a split target. |
|
| `tests/test_upload_handler_atomicity.py` | 401 | 9 | upload_handler_atomicity | filesystem, async/threading | Review taxonomy mapping before using as a split target. |
|
||||||
| `tests/test_kv_cache_invalidation_2927.py` | 463 | 8 | kv_cache_invalidation_2927 | route/api, db/session, import-state, async/threading | Review taxonomy and setup/risk boundaries before any split. |
|
| `tests/test_kv_cache_invalidation_2927.py` | 463 | 8 | kv_cache_invalidation_2927 | route/api, db/session, import-state, async/threading | Review taxonomy and setup/risk boundaries before any split. |
|
||||||
|
|
||||||
@@ -259,14 +286,16 @@ Files still in the `uncategorized` taxonomy area are listed separately below so
|
|||||||
|
|
||||||
| File | Lines | Collected tests | Area | Sub-area | Signals | Why this is a candidate |
|
| File | Lines | Collected tests | Area | Sub-area | Signals | Why this is a candidate |
|
||||||
|---|---:|---:|---|---|---|---|
|
|---|---:|---:|---|---|---|---|
|
||||||
| `tests/test_provider_classification.py` | 188 | 67 | services | provider | - | 67 collected tests |
|
| `tests/test_provider_classification.py` | 115 | 42 | services | provider | - | 42 collected tests |
|
||||||
| `tests/test_provider_endpoints.py` | 241 | 58 | services | provider | subprocess/script | 58 collected tests |
|
| `tests/test_chat_route_tool_policy.py` | 344 | 25 | routes | route | filesystem, ui/static | 344 lines, 25 collected tests |
|
||||||
| `tests/test_llm_core_temperature.py` | 196 | 41 | services | llm | - | 41 collected tests |
|
| `tests/test_llm_core_temperature_reasoning.py` | 133 | 25 | services | llm | - | 25 collected tests |
|
||||||
| `tests/test_provider_detection.py` | 148 | 31 | services | provider | - | 31 collected tests |
|
| `tests/test_provider_endpoints_url_building.py` | 86 | 25 | services | provider | - | 25 collected tests |
|
||||||
| `tests/test_embedding_lanes.py` | 1104 | 29 | services | embedding | filesystem | 1104 lines, 29 collected tests |
|
|
||||||
| `tests/test_research_utils.py` | 97 | 23 | services | research | - | 23 collected tests |
|
| `tests/test_research_utils.py` | 97 | 23 | services | research | - | 23 collected tests |
|
||||||
| `tests/test_prompt_security.py` | 203 | 21 | security | security | - | 21 collected tests |
|
| `tests/test_prompt_security.py` | 203 | 21 | security | security | - | 21 collected tests |
|
||||||
| `tests/test_calendar_recurrence.py` | 338 | 19 | services | calendar | - | 338 lines |
|
| `tests/test_calendar_recurrence.py` | 356 | 20 | services | calendar | - | 356 lines, 20 collected tests |
|
||||||
|
| `tests/test_redos_llm_parsers.py` | 201 | 20 | services | llm | - | 20 collected tests |
|
||||||
|
| `tests/test_llm_core_ollama.py` | 324 | 16 | services | llm | async/threading | 324 lines |
|
||||||
|
| `tests/test_composer_arrow_up_recall_js.py` | 308 | 11 | js | js | filesystem, subprocess/script, ui/static | 308 lines |
|
||||||
|
|
||||||
## High-risk candidates to defer first
|
## High-risk candidates to defer first
|
||||||
|
|
||||||
@@ -274,21 +303,21 @@ These files may still be split later, but not as the first implementation slice
|
|||||||
|
|
||||||
| File | Lines | Collected tests | High-risk signals |
|
| File | Lines | Collected tests | High-risk signals |
|
||||||
|---|---:|---:|---|
|
|---|---:|---:|---|
|
||||||
| `tests/test_model_routes.py` | 1778 | 139 | db/session, import-state, route/api |
|
| `tests/test_model_routes.py` | 2099 | 163 | db/session, import-state, route/api |
|
||||||
| `tests/test_security_regressions.py` | 1224 | 92 | db/session, import-state, route/api, security |
|
| `tests/test_security_regressions.py` | 1515 | 98 | db/session, import-state, route/api, security |
|
||||||
| `tests/test_cookbook_helpers.py` | 912 | 65 | route/api |
|
| `tests/test_cookbook_helpers.py` | 958 | 69 | route/api |
|
||||||
| `tests/test_shell_routes.py` | 481 | 63 | import-state, route/api |
|
| `tests/test_shell_routes.py` | 538 | 69 | import-state, route/api |
|
||||||
|
| `tests/test_endpoint_probing.py` | 497 | 61 | db/session, import-state, route/api |
|
||||||
| `tests/test_pr_blocker_audit.py` | 964 | 58 | import-state, security |
|
| `tests/test_pr_blocker_audit.py` | 964 | 58 | import-state, security |
|
||||||
| `tests/test_agent_loop.py` | 469 | 52 | db/session, import-state |
|
| `tests/test_research_routes_path_confinement.py` | 565 | 58 | route/api, security |
|
||||||
| `tests/test_run_focus.py` | 399 | 47 | security |
|
| `tests/test_run_focus.py` | 492 | 55 | security |
|
||||||
| `tests/test_endpoint_probing.py` | 411 | 34 | db/session, import-state, route/api |
|
| `tests/test_agent_loop.py` | 500 | 54 | db/session, import-state |
|
||||||
|
| `tests/test_manage_mcp_command_allowlist.py` | 168 | 45 | db/session |
|
||||||
|
| `tests/test_review_regressions.py` | 1429 | 41 | db/session, import-state, route/api |
|
||||||
|
| `tests/test_chat_helpers.py` | 582 | 37 | route/api |
|
||||||
|
| `tests/test_model_context.py` | 314 | 36 | db/session, import-state |
|
||||||
|
| `tests/test_email_oauth.py` | 798 | 34 | db/session, route/api, security |
|
||||||
| `tests/test_llm_core_anthropic_temp_omit.py` | 94 | 32 | db/session |
|
| `tests/test_llm_core_anthropic_temp_omit.py` | 94 | 32 | db/session |
|
||||||
| `tests/test_chat_helpers.py` | 264 | 31 | route/api |
|
|
||||||
| `tests/test_model_context.py` | 251 | 30 | db/session, import-state |
|
|
||||||
| `tests/test_upload_limits_centralized.py` | 110 | 29 | import-state |
|
|
||||||
| `tests/test_email_oauth.py` | 580 | 28 | db/session, route/api, security |
|
|
||||||
| `tests/test_review_regressions.py` | 930 | 26 | db/session, import-state, route/api |
|
|
||||||
| `tests/test_rename_user_owner_sync.py` | 686 | 26 | db/session, import-state, route/api |
|
|
||||||
|
|
||||||
## Rules for future split PRs
|
## Rules for future split PRs
|
||||||
|
|
||||||
@@ -313,7 +342,7 @@ Do not start a split PR from this planning issue alone if the file's boundaries
|
|||||||
This document was generated with:
|
This document was generated with:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
.venv/bin/python tests/tools/build_oversized_test_split_plan.py
|
venv/bin/python tests/tools/build_oversized_test_split_plan.py
|
||||||
```
|
```
|
||||||
|
|
||||||
## Freshness check
|
## Freshness check
|
||||||
@@ -321,6 +350,6 @@ This document was generated with:
|
|||||||
After editing the builder or rebasing the branch, regenerate the plan and confirm no unexpected plan drift:
|
After editing the builder or rebasing the branch, regenerate the plan and confirm no unexpected plan drift:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
.venv/bin/python tests/tools/build_oversized_test_split_plan.py
|
venv/bin/python tests/tools/build_oversized_test_split_plan.py
|
||||||
git diff --exit-code -- tests/OVERSIZED_TEST_SPLIT_PLAN.md
|
git diff --exit-code -- tests/OVERSIZED_TEST_SPLIT_PLAN.md
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -441,6 +441,10 @@ def write_report(metrics: list[FileMetric], node_count_total: int) -> None:
|
|||||||
lines = [
|
lines = [
|
||||||
"# Oversized Test File Split Plan",
|
"# Oversized Test File Split Plan",
|
||||||
"",
|
"",
|
||||||
|
"> [!NOTE]",
|
||||||
|
"> This is generated planning material based on the current test tree.",
|
||||||
|
"> It does not define runtime behaviour or approve any test-file split.",
|
||||||
|
"",
|
||||||
"## Purpose",
|
"## Purpose",
|
||||||
"",
|
"",
|
||||||
"This document plans future oversized test-file splits using current repo data.",
|
"This document plans future oversized test-file splits using current repo data.",
|
||||||
@@ -508,7 +512,7 @@ def write_report(metrics: list[FileMetric], node_count_total: int) -> None:
|
|||||||
"This document was generated with:",
|
"This document was generated with:",
|
||||||
"",
|
"",
|
||||||
"```bash",
|
"```bash",
|
||||||
".venv/bin/python tests/tools/build_oversized_test_split_plan.py",
|
"venv/bin/python tests/tools/build_oversized_test_split_plan.py",
|
||||||
"```",
|
"```",
|
||||||
"",
|
"",
|
||||||
"## Freshness check",
|
"## Freshness check",
|
||||||
@@ -516,7 +520,7 @@ def write_report(metrics: list[FileMetric], node_count_total: int) -> None:
|
|||||||
"After editing the builder or rebasing the branch, regenerate the plan and confirm no unexpected plan drift:",
|
"After editing the builder or rebasing the branch, regenerate the plan and confirm no unexpected plan drift:",
|
||||||
"",
|
"",
|
||||||
"```bash",
|
"```bash",
|
||||||
".venv/bin/python tests/tools/build_oversized_test_split_plan.py",
|
"venv/bin/python tests/tools/build_oversized_test_split_plan.py",
|
||||||
"git diff --exit-code -- tests/OVERSIZED_TEST_SPLIT_PLAN.md",
|
"git diff --exit-code -- tests/OVERSIZED_TEST_SPLIT_PLAN.md",
|
||||||
"```",
|
"```",
|
||||||
"",
|
"",
|
||||||
|
|||||||
Reference in New Issue
Block a user