feat: differentiate system/agent/human blocker origins visually (#487)#530
Conversation
Add created_by field to blockers to visually distinguish origin types in the BlockerResolutionView UI. Changes: - core/blockers.py: add BlockerOrigin enum (system/agent/human), created_by field on Blocker dataclass, update create/get/list DB queries - core/workspace.py: add created_by column to blockers schema + migration for existing databases (defaults to 'human') - ui/routers/blockers_v2.py: expose created_by in BlockerResponse; API-created blockers always use 'human' origin (prevents spoofing via API) - core/react_agent.py: stall blockers use created_by='system', agent blockers use created_by='agent' - core/agent.py, adapters/verification_wrapper.py, adapters/builtin.py, prd_discovery.py: all agent-initiated blockers use created_by='agent' - web-ui/src/types/index.ts: add BlockerOrigin type, created_by field on Blocker - web-ui/src/components/blockers/BlockerCard.tsx: origin badge (icon + color per origin) and guidance text beneath the metadata row - tests/core/test_blocker_origin.py: 8 new tests (TDD, all green) - web-ui/__tests__/…/BlockerCard.test.tsx: 6 new origin badge tests Closes #487
|
Caution Review failedPull request was closed or merged during review WalkthroughThis PR adds a blocker origin tracking system by introducing a Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Review: feat: differentiate system/agent/human blocker origins (#487)Overall this is solid work — clean enum design, good backward-compat migration strategy, and proper TDD with tests written before implementation. The security decision to lock API-created blockers to A few things worth addressing before merge: Bug / Semantic Mismatch — In But
Either the guidance needs to be generic enough to cover both cases (e.g. "System-initiated pause. Review the context and answer to continue."), or Fragile Magic String in origin = "system" if reason == "stall_detected" else "agent"This couples the origin logic to a raw string with no constant defined. If the string ever changes at the call site, this silently degrades to Migration Test Doesn't Exercise the ALTER TABLE Path
The test validates the COALESCE fallback (good!), but the migration path itself has no coverage. A test that creates a DB, drops the Minor: Weak Typing on
from codeframe.core.blockers import BlockerOrigin
created_by: BlockerOrigin = BlockerOrigin.HUMANNit:
Summary: The two items worth fixing before merge are the semantic mismatch on |
## Summary Follow-up fixes after #530 was merged without reading claude-review output: - System guidance text generalized to cover stall-timeout + PRD discovery pause - `_REASON_STALL_DETECTED` constant extracted (eliminates 5 magic string usages) - Migration ALTER TABLE test added to cover the actual schema migration path - `BlockerResponse.created_by` typed as `BlockerOrigin` enum for Pydantic validation + OpenAPI docs - `blockers.create()` parameter typed as `Union[BlockerOrigin, str]` ## Validation - All CI checks green including claude-review and CodeRabbit - 9 Python tests, 20 React tests passing, no regressions - SQLite serialization confirmed: INSERT uses `origin.value` (stores plain string, not enum repr)
Summary
Implements #487: UX: Differentiate system vs agent vs human-created blockers visually
BlockerOriginenum (system | agent | human) to the Python Blocker modelcreated_bycolumn to the blockers DB schema with migration (existing rows default to'human')created_byinBlockerResponse; the create endpoint always uses'human'(internal callers set agent/system origin directly)react_agent.py,agent.py,adapters/, andprd_discovery.pypass the correct originBlockerCardshows an origin badge (icon + color) and origin-specific guidance text beneath the metadata rowAcceptance Criteria
created_byfield in blocker responseTest Plan
tests/core/test_blocker_origin.pyweb-ui/__tests__/components/blockers/BlockerCard.test.tsxruff check)npm run build)created_byfrom external API to prevent origin spoofing)Implementation Notes
'human';system/agentorigins are set exclusively by internal code pathsCOALESCEin queries so existing workspaces without the column return'human'gracefullyshows success statetest failure inBlockerCard.test.tsxis unrelated to this PR (present on main before this branch)Closes #487
Summary by CodeRabbit
New Features
Tests