Skip to content

feat(council): role registry + member store (#1818 slice S1)#1833

Merged
jaylfc merged 1 commit into
devfrom
feat/council-role-registry
Jul 15, 2026
Merged

feat(council): role registry + member store (#1818 slice S1)#1833
jaylfc merged 1 commit into
devfrom
feat/council-role-registry

Conversation

@jaylfc

@jaylfc jaylfc commented Jul 15, 2026

Copy link
Copy Markdown
Owner

Implements Slice S1 of the taOS Council feature (#1818).

Changes:

  • tinyagentos/council/role_registry.py: seeded taxonomy of 10 roles (Coder, Reviewer, Writer, Editor, Summarizer, Translator, Researcher, Planner, Critic, Data-analyst) with gauge status and descriptions
  • tinyagentos/council/member_store.py: members with role assignments, autonomy dials, and trust state
  • tinyagentos/routes/council.py: read-only GET /api/council/roles and GET /api/council/members
  • Wired stores into tinyagentos/app.py and router into tinyagentos/routes/__init__.py
  • Added tests/test_council_stores.py and tests/test_council_routes.py

No writes beyond seeding; no identity interaction yet.

Docs-Reviewed: council role registry + member store slice per taos-council.md
@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@jaylfc, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 56 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: f51332ea-e2ea-4db8-8150-7db251b087be

📥 Commits

Reviewing files that changed from the base of the PR and between 70956ab and d32c4a9.

📒 Files selected for processing (9)
  • tests/conftest.py
  • tests/test_council_routes.py
  • tests/test_council_stores.py
  • tinyagentos/app.py
  • tinyagentos/council/__init__.py
  • tinyagentos/council/member_store.py
  • tinyagentos/council/role_registry.py
  • tinyagentos/routes/__init__.py
  • tinyagentos/routes/council.py
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/council-role-registry

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.

❤️ Share

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

@gitar-bot

gitar-bot Bot commented Jul 15, 2026

Copy link
Copy Markdown

Important

You are using the Gitar free plan. Upgrade to unlock code review, CI analysis, auto-apply, custom automations, and more.

Gitar

Comment thread tinyagentos/app.py

from tinyagentos.council.role_registry import RoleRegistry
from tinyagentos.council.member_store import MemberStore
council_role_registry = RoleRegistry(data_dir / "council.db")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

WARNING: Two stores open the same council.db file with separate connections

Both council_role_registry and council_member_store point at data_dir / "council.db" as independent BaseStore instances, so two separate aiosqlite connections are opened against one file. This is inconsistent with the rest of the codebase (every other store gets its own .db), and under any concurrent read/write from the two connections SQLite can raise "database is locked". Consider giving each store its own file (e.g. council_roles.db / council_members.db) or merging them into a single store.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.


async def list_members(self) -> list[dict]:
async with self._db.execute(
"SELECT id, canonical_id, model_id, provider, roles, autonomy, status, added_at FROM council_members ORDER BY added_at"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

SUGGESTION: list_members orders only by added_at, which uses second-granularity timestamps

added_at is formatted as %Y-%m-%dT%H:%M:%SZ (no sub-second precision) and it is the sole ORDER BY key. Members inserted within the same second have undefined order, which will make any future count/order assertion on list_members flaky. Add a deterministic secondary sort key, e.g. ORDER BY added_at, id (or canonical_id).


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

slug TEXT PRIMARY KEY,
display_name TEXT NOT NULL,
description TEXT NOT NULL DEFAULT '',
gauge_status TEXT NOT NULL,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

SUGGESTION: gauge_status (and the seed's "designed" value) is unconstrained

gauge_status TEXT NOT NULL has no CHECK constraint or validation, so arbitrary strings are accepted. The seed also introduces a "designed" status that the route tests never assert on (only "proven"/"provisional" are exercised) — if that isn't a defined gauge status it will be persisted silently. Add a CHECK constraint (e.g. gauge_status IN ('proven','designed','provisional',...)) and validate inputs.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

router = APIRouter()


@router.get("/api/council/roles")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

SUGGESTION: Read endpoints expose the internal council roster without any auth/authorization

GET /api/council/roles and GET /api/council/members return the seeded role taxonomy and any registered agent members with no authentication dependency. Since members carry provider/model_id/identity-style data, confirm these are intended to be publicly readable, or attach the app's existing auth dependency.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

) -> dict:
member_id = uuid.uuid4().hex
now = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
await self._db.execute(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

SUGGESTION: Duplicate canonical_id surfaces a raw sqlite3.IntegrityError

add_member performs the INSERT without handling the UNIQUE violation on canonical_id, so callers receive a low-level sqlite3.IntegrityError (the test only asserts Exception). Consider catching it and raising a domain-specific error, and explicitly rollback() so a failed transaction doesn't leak into subsequent statements on the shared connection.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

@kilo-code-bot

kilo-code-bot Bot commented Jul 15, 2026

Copy link
Copy Markdown

Code Review Summary

Status: 5 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 4
Issue Details (click to expand)

WARNING

File Line Issue
tinyagentos/app.py 300 Two stores (RoleRegistry, MemberStore) open the same council.db file via separate connections; "database is locked" risk under concurrent access and inconsistent with one-store-per-file convention.

SUGGESTION

File Line Issue
tinyagentos/council/member_store.py 71 list_members orders only by second-granularity added_at, so same-second inserts have undefined order (flaky future assertions).
tinyagentos/council/role_registry.py 15 gauge_status has no CHECK constraint / validation; seed also introduces an unverified "designed" value.
tinyagentos/routes/council.py 16 Read endpoints expose the internal council roster with no auth/authorization.
tinyagentos/council/member_store.py 41 Duplicate canonical_id raises a raw sqlite3.IntegrityError with no domain error or rollback.
Files Reviewed (9 files)
  • tests/conftest.py - 0 issues (council stores correctly wired eagerly in app.py, so fixture setup is valid)
  • tests/test_council_routes.py - 0 issues
  • tests/test_council_stores.py - 0 issues
  • tinyagentos/app.py - 1 issue (shared db file)
  • tinyagentos/council/__init__.py - 0 issues
  • tinyagentos/council/member_store.py - 2 issues
  • tinyagentos/council/role_registry.py - 1 issue
  • tinyagentos/routes/__init__.py - 0 issues
  • tinyagentos/routes/council.py - 1 issue

Fix these issues in Kilo Cloud


Reviewed by hy3:free · Input: 98.9K · Output: 23.5K · Cached: 667.5K

@jaylfc
jaylfc merged commit b07bf9d into dev Jul 15, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant