release: promote dev to master for v1.0.0-beta.46 - #2279
Conversation
…ollapse (PR 2240 remainder) (#2244) * tsk-2bkd56 [OPEN] Task PATCH route rejects the agent registry JWT, s * tsk-b6ugu5 [OPEN] Fold tsk-2bkd56: lead card-edit via project_tasks_ * docs: changelog + agent-coordination entries for project_tasks_update lead grant
…2252) Remove local app/TestClient fixtures and use the shared async client from conftest.py. Add missing endpoint coverage for GET settings, attachment upload, and attachment serve. Replace direct app.state assignments with monkeypatch.setattr on the transport app state. Streaming happy path for POST /chat requires a live opencode server and is skipped with a comment.
… at beta.45 promote (#2247) * tsk-737pd7 [OPEN] Reconcile doc-review (#1835) into dev: master-only * feat(spa): port the doc-review FilesApp UI + projects.docReviews client Completes the reconciliation: the backend port alone would have left the SPA half master-only and the next promote's tree diff dirty. FilesApp hunks are master's verbatim; the client block and types match the beta.45 promote branch (master's redundant docReview singular block deliberately omitted). SPA builds clean. * fix: project_doc_review joins the canonical consent-flow scope vocabulary + changelog line The scope-parity test rightly caught _ALLOWED_SCOPES diverging from VALID_SCOPES; the doc-gate rightly demanded the changelog entry.
* test: add endpoint tests for routes/catalog * test: restore real-backend catalog cases, keep the new validation/error paths The rewrite had replaced store-backed happy paths with MagicMock-backed ones - test_recent_respects_limit asserted len<=5 on a mocked empty list, proving nothing. Combined file: all 22 original real-backend tests restored verbatim + the 7 genuinely-new route-layer cases (422 validation, 500 mapping, found/not-found shapes) where mocking is the right tool. 29 pass locally.
…ering contract (#2256) * test(base_store): pin SCHEMA-before-_post_init index ordering contract * test: pin the red case to the actual failure mode (no such column: extra_col) A bare raises(Exception) would pass if init() failed for an unrelated reason; matching the message makes the pin assert the CLASS it documents.
Tests for _parse_size, read_btrfs_pool_size, read_bees_deduped_total, capacity_snapshot, and gpu_vram_snapshot covering happy paths, edge cases, and error conditions
Cover initial mount sync, empty fetch result, centreOpen refresh, visibility change sync and polling, polling interval lifecycle, and unmount cleanup.
…on (#2265) * fix(lists): harden reorder scoping and atomic position allocation reorder_entries now requires list_id, scopes UPDATE by list_id, and returns False (rolling back) when any supplied entry id does not belong to that list, preventing silent corruption of sibling lists in the same project. add_entry allocates position atomically inside the INSERT via COALESCE((SELECT MAX(position)+1 ...), 0) when position is None, eliminating the concurrent-duplicate-position race that occurred when MAX(position)+1 was read in a separate query. * test(lists): prove reorder rolls back a prior valid update on scope mismatch
…y) (#2266) * tsk-qdvfg4 [OPEN] Deploy route registers deployed agents into agent_ * fix(deploy): always mint a fresh registry identity per deployed agent Display names are not unique, so matching config.agents by display_name could hand a second same-named agent the first agent's canonical_id - one identity shared by two agents (JWT sub, memory namespace). Every deploy creates a new agent entry, so every deploy mints. Reserved-name rejections from the registry now return 400 instead of 500. * docs(changelog): deploy-time agent registry identity
…ignal) (#2268) * tsk-ge5bfa [OPEN] Decisions routes: run auth before body validation * test(decisions): fold auth-before-validation repros into the agent routes suite The repro and probe scratch files duplicated helpers that already exist in test_routes_decisions_agent.py. The local-token probe asserted nothing; pinned the real behavior instead (401 on both sides of the fix - admin drives decisions via the session path, never a bearer). * docs(changelog): decisions auth ordering fix
…ating (#2269) The test asserted 201 for every request, so it passed whether or not the rate limit existed. Add the missing assertion that a further admin post after hitting the cap returns 429, while user2's first post still returns 201. This pair is the actual per-user scoping claim.
…domain language (#2270) mesh_credentials.py docstring, mesh.py module docstring, and taosgo-mesh-join-foundation.md all referenced <label>.<handle>.taos.my. Per account-username-subdomain-model.md the subdomain namespace is now a separate claimable namespace decoupled from the username, so those references become <subdomain>.taos.my / claimed-subdomain language. No code changes.
) (#2271) Add docs/agent-manual/11-files-api.md covering multipart upload, listing, fetch, stats and watch, plus the one-write principle (upload once and the file is immediately fetchable, no second register step). Link it from the manual index, rebuild docs/taos-agent-manual.md, and add a CHANGELOG line. Raise the compiled-manual size guard (MAX_CHARS) from 16000 to 18000. The manual sat at 15986 chars on dev with essentially zero headroom, so any docs addition tripped test_compiled_size_under_limit -- this red on #2139. Suite is green: 4 passed in test_agent_manual_compiled.py and 28 passed across the agent-manual + project-files test set.
Docs-Reviewed: routine release version bump (pyproject/__init__/uv.lock to 1.0.0-beta.46 + CHANGELOG rollover); no CI, packaging, or contribution-rule change, so no contributor-skill/docs update is warranted.
Resolves the routes/__init__.py doc-review router registration to dev's canonical single CSRF-protected mount (master carried a stale double registration without CSRF from the beta.45 conflict residue).
📝 WalkthroughWalkthroughThe release updates agent authentication and authorization, deploy-time registry identities, Observatory visibility, project-list transactions, API documentation, package versions, and broad desktop and backend test coverage. ChangesAgent authorization and route behavior
Regression and integration coverage
Documentation and release metadata
Estimated code review effort: 5 (Critical) | ~120 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant DecisionsRoute
participant AuthDependency
participant Authorization
Client->>DecisionsRoute: Send bearer token and request body
DecisionsRoute->>AuthDependency: Authenticate before body parsing
AuthDependency->>Authorization: Pass canonical agent identity
Authorization-->>DecisionsRoute: Check project-scoped decisions_write
DecisionsRoute-->>Client: Return decision or validation response
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
👋 Thanks for the PR! This one targets See CONTRIBUTING.md for the branch model. |
PR Summary by QodoRelease promote dev → master for v1.0.0-beta.46
AI Description
Diagram
High-Level Assessment
Files changed (45)
|
Code Review by Qodo
1. Em dash in next_step_hint
|
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Files Reviewed (0 files)No code changes since previous review. Previous Review Summary (commit 66a437a)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit 66a437a)Status: 4 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
Files Reviewed (43 files)
Reviewed by step-3.7-flash · Input: 52.9K · Output: 3.9K · Cached: 188.9K |
…iver The gate reads github.event.pull_request.body from the event payload, so a workflow re-run replays the ORIGINAL body and never sees a waiver added by editing the PR afterwards. An empty commit raises a fresh synchronize event carrying the current body; the tree is unchanged, so the promote-tree-identity assertion (diff vs dev empty) still holds.
There was a problem hiding this comment.
Actionable comments posted: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
tinyagentos/routes/agents.py (1)
566-634: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winDo not register taosmd before a registry validation failure.
tm_agents.register_agent(unique_slug)runs beforear.register(...). AValueErrorfromar.register()returns 400 after taosmd has already registered the unique slug, with no rollback. Movear.register()beforetm_agents.register_agent()so reserved-name rejections abort before any taosmd side effect.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tinyagentos/routes/agents.py` around lines 566 - 634, The deployment flow currently calls tm_agents.register_agent before the agent registry validates the name, leaving taosmd state behind when ar.register raises ValueError. In the deployment handler, move the ar.register block and its error handling ahead of tm_agents.register_agent, preserving canonical_id assignment and the existing 400/500 responses, so registry validation completes before any taosmd side effect.
🧹 Nitpick comments (5)
tests/cluster/test_worker_capacity.py (1)
155-165: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRemove the duplicated unit-parsing test.
test_parse_size_handles_all_btrfs_unitsrepeats the exact cases already asserted bytest_parse_size_valid_gib,test_parse_size_valid_tib,test_parse_size_valid_mib,test_parse_size_valid_kib, andtest_parse_size_valid_b. Keep one form. A single@pytest.mark.parametrizetest covers all units and reports the failing unit by name.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/cluster/test_worker_capacity.py` around lines 155 - 165, Remove the redundant test_parse_size_handles_all_btrfs_units test and retain the existing parametrized coverage in test_parse_size_valid_gib, test_parse_size_valid_tib, test_parse_size_valid_mib, test_parse_size_valid_kib, and test_parse_size_valid_b, consolidating those cases into a single pytest.mark.parametrize test if needed.tests/test_base_store.py (2)
48-55: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winNarrow the swallowed exception in both
_post_initoverrides.
except Exception: passhides any failure of theALTER TABLE, including programming errors in the fixture itself. Catch only the duplicate-column case so a real failure surfaces.♻️ Proposed change
async def _post_init(self) -> None: - try: - await self._db.execute( - "ALTER TABLE items ADD COLUMN extra_col TEXT" - ) - await self._db.commit() - except Exception: - pass + try: + await self._db.execute( + "ALTER TABLE items ADD COLUMN extra_col TEXT" + ) + await self._db.commit() + except sqlite3.OperationalError as exc: + if "duplicate column" not in str(exc): + raiseAlso applies to: 67-74
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/test_base_store.py` around lines 48 - 55, The `_post_init` overrides currently swallow every database error; narrow their exception handling to ignore only the expected duplicate-column error from `ALTER TABLE items ADD COLUMN extra_col TEXT`. Update both `_post_init` implementations, while allowing all other exceptions to propagate.Source: Linters/SAST tools
210-219: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winAssert the concrete exception type for the bad-index regression.
pytest.raises(Exception, ...)accepts any exception. The failure mode under test is a SQLiteno such column: extra_colduringexecutescript. Assertsqlite3.OperationalErrorso an unrelated error does not make the test pass. Also make the pattern a raw string to satisfy Ruff RUF043.♻️ Proposed change
- with pytest.raises(Exception, match="extra_col|no such column"): + with pytest.raises(sqlite3.OperationalError, match=r"extra_col|no such column"): await store.init()🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/test_base_store.py` around lines 210 - 219, Update test_schema_index_on_post_init_column_fails_on_old_db to expect sqlite3.OperationalError instead of Exception, and make the match pattern a raw string while preserving the existing no-such-column assertion.Source: Linters/SAST tools
tests/test_permissions.py (1)
18-23: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd coverage for the tool and resource allowlist branches.
The tests set
allowed_tools=["read"]but never passtoolorresourcetocheck_permission. Thetool not in allowlistandresource pattern mismatchbranches intinyagentos/mcp/permissions.pystay untested. Add two cases:tool="read"allowed, andtool="write"denied with that reason.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/test_permissions.py` around lines 18 - 23, Extend test_granted_agent_has_access or add focused cases around check_permission to pass tool="read" and assert access is allowed, then pass tool="write" and assert access is denied with the expected denial reason. Keep the existing server, attachment, and allowed_tools=["read"] setup so both tool allowlist branches are covered.tests/test_routes_torrent.py (1)
10-13: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winExtract the store wiring into a fixture.
Lines 10-13, 20-23, and 47-50 repeat the same three-line setup and reach through two private attributes (
download_manager._torrent_settings_store) to obtain the store. A rename of either private attribute breaks three tests. Move the lookup and themonkeypatch.setattrinto one fixture and request it from the three tests that need the store.♻️ Proposed change
+@pytest.fixture +def settings_store(client, monkeypatch): + store = client._transport.app.state.download_manager._torrent_settings_store + monkeypatch.setattr( + client._transport.app.state, "torrent_settings_store", store, raising=False + ) + return store + + `@pytest.mark.asyncio` -async def test_get_torrent_settings_returns_200(client, monkeypatch): - store = client._transport.app.state.download_manager._torrent_settings_store - monkeypatch.setattr( - client._transport.app.state, "torrent_settings_store", store, raising=False - ) +async def test_get_torrent_settings_returns_200(client, settings_store): resp = await client.get("/api/torrent/settings") assert resp.status_code == 200🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/test_routes_torrent.py` around lines 10 - 13, Extract the repeated store lookup and monkeypatch wiring from the affected tests into a shared fixture, using the existing client and monkeypatch fixtures to obtain the store through the current private attributes and assign torrent_settings_store. Update the three tests that currently duplicate this setup to request the new fixture, removing their inline wiring while preserving the same store behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@desktop/src/hooks/use-server-notifications.test.ts`:
- Around line 212-227: Rename the test case around useServerNotifications to
accurately describe that fetchSpy runs once at mount and once more when
centreOpen starts true, while leaving its setup, comment, and assertion
unchanged.
In `@docs/agent-manual/11-files-api.md`:
- Around line 28-32: Add test coverage for the Files API routes covering nested
file retrieval through the path parameter and the SSE response from the watch
endpoint. Ensure the tests exercise the watch route before the catch-all file
path route, validate nested upload paths and directory listings, and assert the
expected SSE stream behavior.
In `@docs/design/taosgo-mesh-join-foundation.md`:
- Around line 122-126: Update the publish-contract description near the
Authorization payload to use subdomain consistently: replace the reference to
label with subdomain, or explicitly document label as a UI-only alias mapped to
subdomain.
In `@tests/test_restart_orchestrator.py`:
- Around line 403-417: Update test_writes_note_file in TestWriteControllerNote
to compare data["paused_at"] against the current epoch time using a small
tolerance rather than exact equality, preventing failures across a one-second
wall-clock boundary while retaining validation that the timestamp was captured
near the assertion.
In `@tests/test_routes_catalog.py`:
- Around line 183-192: Strengthen both not-found tests in
tests/test_routes_catalog.py at lines 183-192 and 205-212 by storing the GET
response, asserting its status_code is 404, and then asserting "detail" exists
in resp.json(); apply the same change to both session-context variants.
In `@tests/test_routes_skills.py`:
- Around line 15-18: The test helper _init_real_skills currently initializes
app.state.skills without ensuring it is closed. Add teardown handling for the
initialized SkillStore, using a fixture or local cleanup that calls
store.close() after each test exercising the helper, while preserving reuse of
already-initialized stores.
In `@tests/test_routes_taos_agent.py`:
- Around line 33-41: The _init_desktop_settings autouse fixture should stop
accessing the private client._transport and ds._db attributes. Use the test
suite’s public app fixture or patch the store’s app directly, then initialize
and close desktop_settings through that public access while preserving the
existing setup and teardown behavior.
In `@tests/test_routes_torrent.py`:
- Around line 46-62: Update test_put_torrent_settings_happy_path to use an
isolated TorrentSettingsStore backed by tmp_path instead of the shared
download-manager store. Patch the app state with this temporary store and
preserve the existing request and assertions, preventing the written
seed_enabled, upload_rate_limit_kbps, and max_active_seeds values from leaking
into other tests.
In `@tinyagentos/routes/projects.py`:
- Around line 813-823: Update the agent PATCH validation around the is_agent
field whitelist to compare the incoming labels’ claimable presence with the
task’s stored labels and return 403 when they differ, while allowing other label
edits. Add a regression test covering a non-lead agent editing its own task and
attempting to add or remove claimable, confirming both requests are rejected.
---
Outside diff comments:
In `@tinyagentos/routes/agents.py`:
- Around line 566-634: The deployment flow currently calls
tm_agents.register_agent before the agent registry validates the name, leaving
taosmd state behind when ar.register raises ValueError. In the deployment
handler, move the ar.register block and its error handling ahead of
tm_agents.register_agent, preserving canonical_id assignment and the existing
400/500 responses, so registry validation completes before any taosmd side
effect.
---
Nitpick comments:
In `@tests/cluster/test_worker_capacity.py`:
- Around line 155-165: Remove the redundant
test_parse_size_handles_all_btrfs_units test and retain the existing
parametrized coverage in test_parse_size_valid_gib, test_parse_size_valid_tib,
test_parse_size_valid_mib, test_parse_size_valid_kib, and
test_parse_size_valid_b, consolidating those cases into a single
pytest.mark.parametrize test if needed.
In `@tests/test_base_store.py`:
- Around line 48-55: The `_post_init` overrides currently swallow every database
error; narrow their exception handling to ignore only the expected
duplicate-column error from `ALTER TABLE items ADD COLUMN extra_col TEXT`.
Update both `_post_init` implementations, while allowing all other exceptions to
propagate.
- Around line 210-219: Update
test_schema_index_on_post_init_column_fails_on_old_db to expect
sqlite3.OperationalError instead of Exception, and make the match pattern a raw
string while preserving the existing no-such-column assertion.
In `@tests/test_permissions.py`:
- Around line 18-23: Extend test_granted_agent_has_access or add focused cases
around check_permission to pass tool="read" and assert access is allowed, then
pass tool="write" and assert access is denied with the expected denial reason.
Keep the existing server, attachment, and allowed_tools=["read"] setup so both
tool allowlist branches are covered.
In `@tests/test_routes_torrent.py`:
- Around line 10-13: Extract the repeated store lookup and monkeypatch wiring
from the affected tests into a shared fixture, using the existing client and
monkeypatch fixtures to obtain the store through the current private attributes
and assign torrent_settings_store. Update the three tests that currently
duplicate this setup to request the new fixture, removing their inline wiring
while preserving the same store behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 19abe35a-0c5e-43ee-b4af-f22dcdd97610
⛔ Files ignored due to path filters (2)
desktop/package-lock.jsonis excluded by!**/package-lock.json,!**/package-lock.jsonuv.lockis excluded by!**/*.lock,!**/uv.lock
📒 Files selected for processing (43)
CHANGELOG.mddesktop/package.jsondesktop/src/components/ui/__tests__/card.test.tsxdesktop/src/hooks/use-server-notifications.test.tsdocs/agent-coordination.mddocs/agent-manual/11-files-api.mddocs/agent-manual/index.mddocs/design/taosgo-mesh-join-foundation.mddocs/taos-agent-manual.mdpyproject.tomltests/cluster/test_worker_capacity.pytests/projects/test_lists_store.pytests/test_agent_internal_mint.pytests/test_agent_manual_compiled.pytests/test_agent_registry.pytests/test_base_store.pytests/test_feedback_route.pytests/test_permissions.pytests/test_project_a2a.pytests/test_restart_orchestrator.pytests/test_routes_agent_auth_requests.pytests/test_routes_agents.pytests/test_routes_catalog.pytests/test_routes_decisions_agent.pytests/test_routes_knowledge.pytests/test_routes_observatory.pytests/test_routes_projects_agent_tasks.pytests/test_routes_skills.pytests/test_routes_taos_agent.pytests/test_routes_torrent.pytinyagentos/__init__.pytinyagentos/auth_middleware.pytinyagentos/cli/taosctl/commands/observatory.pytinyagentos/projects/lists_store.pytinyagentos/routes/__init__.pytinyagentos/routes/agent_auth_requests.pytinyagentos/routes/agent_registry.pytinyagentos/routes/agents.pytinyagentos/routes/decisions.pytinyagentos/routes/observatory.pytinyagentos/routes/projects.pytinyagentos/taosnet/mesh.pytinyagentos/taosnet/mesh_credentials.py
|
Resolving the carried-over bot review threads to unblock this promote (master requires conversation resolution). Each adjudicated, NOT blanket-dismissed - and two were RIGHT: ACTIONED (carded tsk-a3er4a, fix-forward on dev - both already merged, so neither blocks a dev->master sync):
ACTIONED (correction added to existing card tsk-x7l76a):
ADJUDICATED NOISE (verified, no action):
This PR is a mechanical dev->master promote with tree identity asserted (diff vs dev EMPTY); the findings live on dev and are fixed forward there, not by diverging master. |
Promote beta.46 to master (23 commits: decisions auth-before-validation #2268, observatory fleet view #2267, deploy-time agent registry identity #2266, lead card-edit #2244, doc-review reconciliation, plus test coverage).
Conflict resolution (both to dev's canonical version, verified):
Promote-tree-identity asserted:
git diff origin/dev HEADis EMPTY - master will be byte-identical to dev.DELETED SYMBOLS, verified intentional (coverage INCREASED in every case, checked against dev before waiving):
Removes-Intentionally: tests/test_routes_knowledge.py:TestDeleteItem,tests/test_routes_knowledge.py:TestDeleteItem.test_delete_item_not_found,tests/test_routes_knowledge.py:TestGetItem,tests/test_routes_knowledge.py:TestGetItem.test_get_item_not_found,tests/test_routes_knowledge.py:TestGetItem.test_get_item_returns_item,tests/test_routes_knowledge.py:TestListItems,tests/test_routes_knowledge.py:TestListItems.test_list_items_returns_200_with_shape,tests/test_routes_knowledge.py:TestListItems.test_list_items_returns_seeded_items,tests/test_routes_knowledge.py:TestListRules,tests/test_routes_knowledge.py:TestListRules.test_list_rules_returns_200,tests/test_routes_knowledge.py:TestListRules.test_list_rules_returns_seeded_rules,tests/test_routes_projects_agent_tasks.py:TestAgentCanDriveOwnBoard.test_patch_task_is_session_only,tests/test_routes_taos_agent.py:app,tests/test_routes_taos_agent.py:client,tests/test_routes_taos_agent.py:tmp_data_dir
Summary by CodeRabbit
New Features
Bug Fixes
<subdomain>.taos.myformat.Documentation