feat(FAR-764): community execution gate + connector checklist UI - #339
Conversation
…ction_install_tracking PR #308 (FAR-761) adds 0206_collection_install_tracking on top of the prior head 0205_library_collection_type, so the chain head is now 0206. The stale reconciliation/guardrail tests still asserted the head was 0205, which broke get_heads() assertions and the migration health check. Update the head pointers (and the chain walk in test_eval_suite_run) to the new head. Content assertions that exercise 0205's DDL are left unchanged.
Apply the new-table ceremony (SET ROLE modulo_migrate + RLS ENABLE/FORCE + rls_org_isolation + GRANTs to modulo_app/modulo_system + ownership assertion), switch org_id -> organisation_id, use ix_<table>_<col> index naming, drop the redundant unique index on the PK, dialect-guard Postgres-only DDL for the SQLite parity path, add the reverse-lookup index on collection_install_entity, and widen collection_version to VARCHAR(50) for full semver. Add ORM models (CollectionInstall, CollectionInstallEntity) and a migration unit test exercising the ceremony/naming/round-trip so the migration is no longer unexercised. Resolves the CHANGES_REQUESTED findings from modulo-reviewbot on PR #308.
…AR-761) The 0206_collection_install_tracking migration adds collection_install and collection_install_entity. Update the stale schema-assertion tests: - test_initial_schema_contains_required_tables: include the two new tables - test_all_resource_tables_are_organisation_scoped: exclude collection_install_entity (intentionally non-org-scoped; access is via the org-scoped parent's install_id) - test_upgrade_covers_exactly_every_metadata_uuid_pk: scope the frozen 0194 coverage contract to pre-0194 tables so the count stops drifting on tables introduced by later migrations that own their own uuid-PK defaults
The architecture test test_no_compound_boolean_assertions flags 'assert "GRANT " in joined and "modulo_app" in joined' because a failure cannot name which condition broke. Split into two separate asserts so CI's test-suite-quality gate passes.
… secure entity table Align the ORM models to migration 0206_collection_install_tracking so the metadata no longer drifts from the migrated schema (the class of bug the PR-review loop kept re-finding): - CollectionInstall: PK is install_id (not the OrgScoped-inherited id), the table carries created_at only (no updated_at), and FK/CHECK/UNIQUE constraint names match the migration exactly. - CollectionInstallEntity FK now targets collection_install.install_id. - Migration 0206: collection_install_entity gets FORCE RLS with a parent-derived rls_org_isolation policy plus DML grants to modulo_app / modulo_system, so the app role can resolve the parent JOIN and cross-org rows stay scoped. Downgrade drops the policy / disables RLS. - Add ORM-vs-migration conformance assertions to the 0206 unit test.
…r materialize_import)
…llision Merge origin/main into deliver/FAR-764 and resolve conflicts: - origin/main renamed FAR-761's collection_install migration to 0207_collection_install_tracking and added its own 0206_deleted_defaults_signal_check, which collided with this branch's 0206_collection_install_tracking and 0207_community_gate numeric prefixes. - Delete the stale duplicate 0206_collection_install_tracking (main's 0207 already holds the base tables) and its test; renumber 0207_community_gate -> 0208_community_gate (down_revision 0207_collection_install_tracking). - Result: single linear head 0208_community_gate (0205 -> 0206_deleted_defaults_signal_check -> 0207_collection_install_tracking -> 0208_community_gate). - Resolve model + head-chain test conflicts to assert 0208_community_gate; keep community_sourced/agents_granted columns (FAR-764) and the Boolean import. Co-Authored-By: Branch Fixer Bot <bot@farnalabs.com>
Merge-conflict + migration-collision fix (Branch Fixer)Resolved the merge conflicts with
What changed
ResultSingle linear head: Commit: |
farnalabs
left a comment
There was a problem hiding this comment.
CI is failing on this commit. Failing checks: Lint (Backend), Frontend and WCAG, Schema freshness, Test (Backend). Please fix these before merge; a re-review will follow on the next push. (Feedback only - formal decision posted by the post-decision node.)
modulo-reviewbot
left a comment
There was a problem hiding this comment.
Blocking findings on head commit c4a0fdc:
- CI: Lint (Backend) failed
- CI: Frontend and WCAG failed
- CI: Schema freshness failed
- CI: Test (Backend) failed
Mergeability is OK (no conflicts), but the required CI checks are red on the head commit. Please fix the failing checks and re-push; full re-review will run on the next push with green CI.
…urn, lint) - Regenerate frontend/src/lib/api/schema.ts (stale OpenAPI types for the new collection install/grant endpoints). - Fix mypy errors: correct CollectionInstall.connector_checklist / installed_entities field types to list[...]; add missing return of CollectionInstallListResponse in list_collection_installs_endpoint; annotate the reused entity variable in uninstall.py so session.get resolves per branch. - Fix architecture-test violation: replace '== []' with 'assert not ...' in test_library_collection.py.
Automated fix: CI failures on
|
- Add missing return in list_collection_installs_endpoint so mypy (strict) sees a guaranteed CollectionInstallListResponse. - Correct CollectionInstall model field types: connector_checklist and installed_entities hold lists, not dicts, matching the code that builds/consumes them (fixes mypy arg-type assignment errors). - Use distinct per-branch variables in uninstall.py helper functions so mypy does not unify the reused binding to Schema|None (which made session.get(Agent/Pipeline) fail type-checking). - Regenerate frontend/src/lib/api/schema.ts to include the new collection-install list/grant endpoints (fixes schema-freshness and vue-tsc type-check failures in CollectionDetailView).
Branch Fixer: CI green on
|
|
CI failures on c4a0fdc are resolved by the concurrent Branch Fixer commits 9871ca0 / 92857df (already on this branch):
Re-running CI should go green; requesting re-review. |
farnalabs
left a comment
There was a problem hiding this comment.
Blocking finding on head commit 92857df:
PR has merge conflicts with main. Required CI checks are green on the head commit (SonarCloud coverage import is a parallel check still running), but the branch cannot be merged until it resolves conflicts with origin/main (currently at f63d80a).
Conflicted files (verified locally via test merge against origin/main):
- backend/src/modulo/api/routes/library.py
- backend/src/modulo/core/library_service/install.py
- backend/src/modulo/core/library_service/uninstall.py
- backend/tests/unit/api/test_library_collection.py
- backend/tests/unit/core/test_trigger_streak_engine.py
- backend/tests/unit/db/test_eval_suite_run.py
- backend/tests/unit/db/test_migration_guardrail_kill_switch.py
- backend/tests/unit/db/test_migration_guardrail_trust_pr_b.py
- backend/tests/unit/db/test_migration_ongoing_trigger.py
- backend/tests/unit/db/test_migration_reconcile_staging_schema.py
- backend/tests/unit/db/test_migration_sync_feature_flag_catalog.py
- backend/tests/unit/db/test_trigger_event_vocabulary.py
- frontend/src/lib/api/schema.ts
Please merge origin/main into deliver/FAR-764 (or rebase), resolve the conflicts, and re-push; full re-review will run on the next push.
modulo-reviewbot
left a comment
There was a problem hiding this comment.
Blocking finding: PR #339 (deliver/FAR-764 @ 92857df) has merge conflicts with origin/main.
Review node verified via a local test merge against origin/main (currently at f63d80a): 13 files conflict and must be resolved before merge.
Conflicting files:
- backend/src/modulo/api/routes/library.py
- backend/src/modulo/core/library_service/install.py
- backend/src/modulo/core/library_service/uninstall.py
- backend/tests/unit/api/test_library_collection.py
- backend/tests/unit/core/test_trigger_streak_engine.py
- backend/tests/unit/db/test_eval_suite_run.py
- backend/tests/unit/db/test_migration_guardrail_kill_switch.py
- backend/tests/unit/db/test_migration_guardrail_trust_pr_b.py
- backend/tests/unit/db/test_migration_ongoing_trigger.py
- backend/tests/unit/db/test_migration_reconcile_staging_schema.py
- backend/tests/unit/db/test_migration_sync_feature_flag_catalog.py
- backend/tests/unit/db/test_trigger_event_vocabulary.py
- frontend/src/lib/api/schema.ts
For frontend/src/lib/api/schema.ts: if taking mains schema changes, regenerate generated types rather than hand-editing.
Required changes: rebase/merge origin/main into this branch, resolve all conflicts, and verify a clean merge before re-requesting review. High-risk path flagged (core pipeline_engine files) was reviewed; no human HITL decision was present (gate condition_skipped).
…llision Re-merge origin/main into deliver/FAR-764 and resolve conflicts: - api/routes/library.py: keep grant imports + community_sourced/agents_granted response fields; adopt main's pipeline.create docstring and uninstall collection_id arg. - library_service/install.py: keep branch idempotent install that sets community_sourced; adopt main's robust bundle helper. - library_service/uninstall.py: take main's version (collection_id param + _entity_exists guard) required by merged library.py. - Renumber colliding 0208_community_gate -> 0209_community_gate; chain off main's 0208_notification_indexes_and_constraint so the migration graph has a single head again. Sweep all test references. - test files: keep branch FAR-764 grant tests + main FAR-762 uninstall tests. - frontend schema.ts: keep grant endpoint + community_sourced/agents_granted fields; adopt main's accurate docstring. Co-Authored-By: Branch Fixer Bot <bot@farnalabs.com>
Merge conflict resolved — push
|
# Conflicts: # backend/src/modulo/api/routes/library.py # backend/src/modulo/core/library_service/install.py # backend/src/modulo/core/library_service/uninstall.py # backend/tests/unit/api/test_library_collection.py # backend/tests/unit/core/test_trigger_streak_engine.py # backend/tests/unit/db/test_eval_suite_run.py # backend/tests/unit/db/test_migration_guardrail_kill_switch.py # backend/tests/unit/db/test_migration_guardrail_trust_pr_b.py # backend/tests/unit/db/test_migration_ongoing_trigger.py # backend/tests/unit/db/test_migration_reconcile_staging_schema.py # backend/tests/unit/db/test_migration_sync_feature_flag_catalog.py # backend/tests/unit/db/test_trigger_event_vocabulary.py # frontend/src/lib/api/schema.ts
…onflict resolution; remote drop of docs/manifest was defective)
Merge-conflict resolution —
|
farnalabs
left a comment
There was a problem hiding this comment.
CI is failing (Test (Backend)): tests/architecture/test_product_map_consistency.py::test_mapped_route_elements_cover_owning_view_testids asserts that static data-testids in frontend/src/views/CollectionDetailView.vue are missing from the product map elements for /library/collections/:id — ['collection-create-connector', 'collection-grant-agents'] are invisible to the product map. Register these testids in the product map elements for that route (or document them as intentionally unmapped), then re-push. Re-review will follow once CI is green.
modulo-reviewbot
left a comment
There was a problem hiding this comment.
Review: CHANGES_REQUESTED
Blocking finding (CI fails on head 81f07b3a — required check):
- frontend/src/views/CollectionDetailView.vue introduces static data-testids
collection-create-connectorandcollection-grant-agentsthat are not registered in the product map elements for/library/collections/:id, failingtests/architecture/test_product_map_consistency.py::test_mapped_route_elements_cover_owning_view_testids.
Required change: register these new data-testids in the product map for the owning view route before merging. The PR is otherwise mergeable but is blocked by this failing required check.
Reviewed head SHA: 81f07b3ab0f47c1371a97827c15671888630de8b
Add collection-create-connector and collection-grant-agents to the /library/collections/:id product-map elements so the product-map consistency architecture test stops failing (static data-testids must be documented for Remy's docs indexer / /api/v1/manifest).
Automated fix: product-map testid drift (FAR-764)The CI: Fast Validation Fix: added both testids to the Root cause: the view shipped before its product-map element entries were registered; the architecture test guards this reverse direction (view → map). Commit: 49abacf |
modulo-reviewbot
left a comment
There was a problem hiding this comment.
Review: CHANGES_REQUESTED (PR #339)
Blocking findings on head 49abacf06b7cb8306564153e87d73d3fdc504d65:
- CI: Test (Backend) check-run failed on this head — failing backend tests must be fixed before merge.
- CI: Lint (Backend) check-run failed on this head — lint errors must be fixed before merge.
Note: mergeability with main is clean (no conflicts); the PR is blocked solely by the CI failures above.
PR head SHA: 49abacf06b7cb8306564153e87d73d3fdc504d65
Automated Branch Fix — PR #339 (FAR-764)CI was red on Lint (Backend) (Semgrep) and Test (Backend). Addressed in commit 1. Test failure —
|
farnalabs
left a comment
There was a problem hiding this comment.
Review feedback (pre-decision, not a formal verdict)
Blocking: PR has merge conflicts with main. GitHub reports mergeable=false (state: dirty). Please merge origin/main and resolve the conflicting files, then re-run CI. Files changed on both sides (likely conflict points):
- backend/tests/unit/core/test_trigger_streak_engine.py
- backend/tests/unit/db/test_eval_suite_run.py
- backend/tests/unit/db/test_migration_guardrail_kill_switch.py
- backend/tests/unit/db/test_migration_guardrail_trust_pr_b.py
- backend/tests/unit/db/test_migration_ongoing_trigger.py
- backend/tests/unit/db/test_migration_reconcile_staging_schema.py
- backend/tests/unit/db/test_migration_sync_feature_flag_catalog.py
- backend/tests/unit/db/test_trigger_event_vocabulary.py
- frontend/src/locales/en-US.js
- frontend/src/manifest.yaml
Non-blocking code observations (re-check after the merge):
- backend/src/modulo/api/routes/library.py (grant endpoint): the AlreadyGrantedError handler is dead code - grant_collection_agents() returns the install as-is when already granted and never raises it (its own docstring says idempotent). Either raise the error in the service or drop the handler; also the endpoint docstring says "Idempotent" while mapping an error type that implies it is not.
- backend/src/modulo/core/pipeline_engine/node_runner.py: the gate matches
agent_id_raw in gatedwheregatedholdsstr(agent.id)keys from the executor. This assumes node_def agent_id is already a canonical lowercase UUID string; usestr(agent_id_raw)(or the parsed agent_id) to be robust to non-canonical representations. - backend/src/modulo/core/library_service/install.py: the error message dropped the offending install id (previously included the existing install_id), which makes operator debugging harder; consider keeping it.
Otherwise the community-gate design (default-deny until operator grant, stub artifact for gated nodes, migration 0209 + grant endpoint + checklist UI) looks coherent; test coverage exists for the gate and refusal-on-reinstall paths.
# Conflicts: # backend/tests/unit/core/test_trigger_streak_engine.py # backend/tests/unit/db/test_eval_suite_run.py # backend/tests/unit/db/test_migration_guardrail_kill_switch.py # backend/tests/unit/db/test_migration_guardrail_trust_pr_b.py # backend/tests/unit/db/test_migration_ongoing_trigger.py # backend/tests/unit/db/test_migration_reconcile_staging_schema.py # backend/tests/unit/db/test_migration_sync_feature_flag_catalog.py # backend/tests/unit/db/test_trigger_event_vocabulary.py
modulo-reviewbot
left a comment
There was a problem hiding this comment.
CHANGES_REQUESTED for PR #339 (head 9161306)
BLOCKING: PR cannot merge as-is. origin/main has advanced and the branch is dirty (GitHub mergeable=false) with ~10 files changed on both sides. Merge origin/main and resolve conflicts before this can merge.
Merge-conflict files (resolve after merging origin/main):
- backend/tests/unit/core/test_trigger_streak_engine.py
- backend/tests/unit/db/test_eval_suite_run.py
- backend/tests/unit/db/test_migration_guardrail_kill_switch.py
- backend/tests/unit/db/test_migration_guardrail_trust_pr_b.py
- backend/tests/unit/db/test_migration_ongoing_trigger.py
- backend/tests/unit/db/test_migration_reconcile_staging_schema.py
- backend/tests/unit/db/test_migration_sync_feature_flag_catalog.py
- backend/tests/unit/db/test_trigger_event_vocabulary.py
- frontend/src/locales/en-US.js
- frontend/src/manifest.yaml
Code findings:
- backend/src/modulo/api/routes/library.py: AlreadyGrantedError handler in the grant endpoint is dead code — grant_collection_agents() returns the install as-is when already granted and never raises; either raise in the service or drop the handler.
- backend/src/modulo/core/pipeline_engine/node_runner.py: community gate matches agent_id_raw in gated where gated holds str(agent.id) keys; assumes canonical lowercase UUID strings — use str(agent_id_raw) or the parsed agent_id for robustness.
- backend/src/modulo/core/library_service/install.py: re-install error message dropped the existing install id, making operator debugging harder; consider keeping it.
- frontend/src/views/CollectionDetailView.vue + frontend/src/lib/api/schema.ts: community gate fields added to response models and UI; re-verify wire contract after regenerating schema.ts post-merge.
Note: this run was flagged high-risk (pipeline_engine/** changes), but the HITL gate was condition-skipped and the review verdict is CHANGES_REQUESTED, so no approval path applies.
Automated fix: merge-conflict resolution + migration-collision renumber (FAR-764)Commit Root causeThe branch and
Both had Changes
Verification (local)
|
… on collection_install_id Migration 0207 already adds collection_install_id to schemas/agents/pipelines via ADD COLUMN IF NOT EXISTS. Migration 0209 re-added the same column with a plain op.add_column, raising DuplicateColumn on a fresh DB during BDD migrations. Mirror 0207's idempotent style for both the column and the index the ORM declares.
Branch Fixer: migration 0209 DuplicateColumn fixRoot cause: The BDD/E2E run (run 34520702556) failed during Migration Fix (commit Scope is limited to the migration; no tests or product docs were touched. |
farnalabs
left a comment
There was a problem hiding this comment.
Re-review after fix push 1a37d16 (merge conflicts resolved, migration 0209 made idempotent with ADD COLUMN IF NOT EXISTS / CREATE INDEX IF NOT EXISTS). CI still running on this head at time of review (parallel jobs pending). Feedback only — findings are non-blocking:
- backend/src/modulo/api/routes/library.py (~line 2329): the AlreadyGrantedError handler is dead code — grant_collection_agents() returns the install as-is when already granted (idempotent) and never raises it, and MappingAlreadyGranted to 400 contradicts the documented idempotency. Either raise it in the service or drop the handler.
- backend/src/modulo/core/pipeline_engine/node_runner.py (lines ~3010 and ~7791): the gate matches the raw agent_id string against str(agent.id) keys; works only if graph JSON stores canonical lowercase UUIDs. Consider comparing str(agent_id) after parsing for robustness.
- backend/src/modulo/core/library_service/install.py: the re-install error no longer includes the pre-existing install id; operators lose a useful debugging pointer.
- backend/tests/unit/api/test_library_collection.py, TestGrantCollectionAgentsEndpoint.test_grant_success: the mocked grant_collection_agents returns an install with agents_granted=False, so the 'successful grant' test asserts the un-granted passthrough state instead of the granted state — consider seeding agents_granted=True at the service layer or asserting on service-level behavior so the test proves the flip.
- install.py sets community_sourced = collection.source in ("community", "registry") while the 0210 migration docstring describes it as source != 'local' — align the wording.
None of the above blocks merge; the migration idempotency fix itself looks correct (mirrors 0207's style, keeps role switching, idempotent for re-runs).
modulo-reviewbot
left a comment
There was a problem hiding this comment.
Automated review decision: APPROVE (PR #339)
Head SHA: 1a37d16
Routing note
The policy-router flagged this PR as high-risk (changes in backend/src/modulo/core/pipeline_engine/**). The edge-level HITL gate in this topology auto-skipped (artifact: status=skipped, no human decision recorded); per the post-decision authorization rule the router APPROVE is executed here. Logging the high-risk flag for human visibility.
Review findings
Full-scope review of the community execution gate (grant service + endpoint, executor/node_runner default-deny enforcement, migrations 0209/0210, model columns, frontend CollectionDetailView grant UI) found no major or blocking issues. Prior CHANGES_REQUESTED (merge conflicts with origin/main) is resolved — mergeable=true. The migration 0209 idempotency fix (ADD/IF NOT EXISTS) is correct and mirrors 0207 style. CI was still pending on this head at review time; per policy that does not skip the review.
5 non-blocking feedback items from the review node:
backend/src/modulo/api/routes/library.py:AlreadyGrantedErrorhandler is dead code —grant_collection_agents()is documented idempotent and never raises it; raise it in the service or drop the handler.backend/src/modulo/core/pipeline_engine/node_runner.py: community gate matches rawagent_idagainststr(agent.id)keys; comparestr(agent_id)after parsing for robustness.backend/src/modulo/core/library_service/install.py: re-install error message dropped the pre-existing install id (debugging pointer for operators).backend/tests/unit/api/test_library_collection.pytest_grant_success: mocked grant returnsagents_granted=False, so the "successful grant" test asserts the un-granted state; assert the granted state to prove the flip.install.pyvs migration 0210 docstring:community_sourceddefined as source in (community, registry) but docstring says source != local; align wording.
None are blocking. Approving.
Branch Fixer — merge-conflict resolvedRoot cause: Fix: Merged
|
|
Branch Fixer: SonarCloud quality gate (PR #339)The SonarCloud Code Analysis check failed the Quality Gate on head 4c8c5f6 due to 2 new CRITICAL code-smell issues. Both are fixed by commit
Verified locally: the full cross-platform pre-commit suite (ruff, ruff-format, bandit, semgrep, gitleaks, import-linter, yaml/toml/json, merge-conflict, EOF, trailing-whitespace, no-commit-to-branch) passes. Pushing so SonarCloud re-analyses green. |


What
Stacked on FAR-762 (PR #317).