feat(web): add phase 3 Kanban console contracts#2557
Conversation
chore: adopt kanban governance baseline
…console feat(web): add phase 2 mock kanban console
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 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 |
|
Closing: this PR was opened against upstream by mistake. The product-fork PR will be opened against MohAnghabo/kanban-console. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 3 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit c661288. Configure here.
|
|
||
| - Minimum before committing product changes: `bun check`. | ||
| - For governance/adoption changes, also run: | ||
| `bash scripts/verify-template-adoption.sh --profile minimal --manifest /Users/mohanghabo/Projects/ai-starter-pro/.template/adoption/minimal-files.txt` |
There was a problem hiding this comment.
Hardcoded local absolute path in rule file
Medium Severity
The validation command contains a hardcoded absolute path /Users/mohanghabo/Projects/ai-starter-pro/.template/adoption/minimal-files.txt which is machine-specific and will fail for any other developer. This also exposes a personal filesystem username in a committed rule file, which conflicts with the "No real PII in code, logs, fixtures, docs" blocking rule.
Triggered by project rule: Bugbot Project Brief
Reviewed by Cursor Bugbot for commit c661288. Configure here.
| <SheetFooter> | ||
| <Button variant="ghost" onClick={() => setMoveTaskId(null)}> | ||
| Cancel | ||
| </Button> |
There was a problem hiding this comment.
Multiple user-facing strings missing Arabic translations
Medium Severity
The "Cancel" button text and numerous other interactive labels ("Registered monorepos", "Branch status", "Current", "Upstream", "Changed files", detail row labels, etc.) are hardcoded in English without Arabic translations. The component already has a locale-aware messages system, and the project rules require AR/EN for every user-facing string. These strings remain English even when the user switches to Arabic mode.
Additional Locations (2)
Triggered by project rule: Bugbot Project Brief
Reviewed by Cursor Bugbot for commit c661288. Configure here.
| shell: bash | ||
| run: | | ||
| findings_file="$RUNNER_TEMP/ai-loop-findings.json" | ||
| printf '%s' '${{ inputs.findings_b64 }}' | base64 --decode > "$findings_file" |
There was a problem hiding this comment.
Unsafe shell interpolation of workflow dispatch input
Low Severity
The ${{ inputs.findings_b64 }} value is interpolated directly inside single quotes in a run: shell step. If the input ever contains a single quote (e.g., from a malformed dispatch), it breaks shell quoting and enables command injection. The safer pattern is to pass the value through an environment variable.
Triggered by project rule: Bugbot Project Brief
Reviewed by Cursor Bugbot for commit c661288. Configure here.
| if ( | ||
| checks.some((check) => check.id === "stack-b/convex-deployment" && check.status === "error") | ||
| ) { | ||
| fixes.push(await runProviderCli(context, deps, "convex-dev")); | ||
| } | ||
|
|
||
| if (hasFixableIssue(checks, "stack-b/vercel-link")) { | ||
| fixes.push(await runProviderCli(context, deps, "vercel-link")); | ||
| } | ||
|
|
||
| if (checks.some((check) => check.id === "stack-a/neon-url" && check.status === "error")) { | ||
| fixes.push(await runProviderCli(context, deps, "neon-project-create")); | ||
| } |
There was a problem hiding this comment.
🟢 Low fix/apply.ts:34
The conditions for stack-b/convex-deployment (line 35) and stack-a/neon-url (line 44) check only status === "error" without verifying fixable, unlike other fixes that use hasFixableIssue. This causes runProviderCli to execute even when a check explicitly reports fixable: false, running potentially expensive or destructive CLI commands for issues marked as non-auto-fixable.
- if (
- checks.some((check) => check.id === "stack-b/convex-deployment" && check.status === "error")
- ) {
+ if (hasFixableIssue(checks, "stack-b/convex-deployment")) {
fixes.push(await runProviderCli(context, deps, "convex-dev"));
}
if (hasFixableIssue(checks, "stack-b/vercel-link")) {
fixes.push(await runProviderCli(context, deps, "vercel-link"));
}
- if (checks.some((check) => check.id === "stack-a/neon-url" && check.status === "error")) {
+ if (hasFixableIssue(checks, "stack-a/neon-url")) {
fixes.push(await runProviderCli(context, deps, "neon-project-create"));
}🤖 Copy this AI Prompt to have your agent fix this:
In file scripts/preflight/fix/apply.ts around lines 34-46:
The conditions for `stack-b/convex-deployment` (line 35) and `stack-a/neon-url` (line 44) check only `status === "error"` without verifying `fixable`, unlike other fixes that use `hasFixableIssue`. This causes `runProviderCli` to execute even when a check explicitly reports `fixable: false`, running potentially expensive or destructive CLI commands for issues marked as non-auto-fixable.
Evidence trail:
scripts/preflight/fix/apply.ts lines 10-14 (hasFixableIssue checks fixable), lines 34-38 (convex-deployment bypasses fixable), lines 44-45 (neon-url bypasses fixable), lines 26,30,40 (other fixes use hasFixableIssue). scripts/preflight/checks/support.ts line 37 (fixable defaults to false). scripts/preflight/checks/stack.ts lines 99-107 (convex-deployment check never sets fixable), lines 21-23 (neon-url error check never sets fixable), line 140 (vercel-link explicitly sets fixable: !linked).
| </h2> | ||
| <div className="mt-3 flex flex-wrap gap-1"> | ||
| <Badge variant="outline">{task.repo}</Badge> | ||
| <Badge variant={task.priority === "P0" ? "error" : "warning"}>{task.priority}</Badge> |
There was a problem hiding this comment.
🟡 Medium components/KanbanConsoleMock.tsx:506
TaskDetailPanel uses task.priority === "P0" ? "error" : "warning" for the priority badge, so P2 priorities render as "warning" (yellow). This is inconsistent with TaskCard, which uses three-way logic to render P2 as "info" (blue). Consider using the same three-way logic in TaskDetailPanel so P2 displays consistently across both views.
🤖 Copy this AI Prompt to have your agent fix this:
In file apps/web/src/components/KanbanConsoleMock.tsx around line 506:
`TaskDetailPanel` uses `task.priority === "P0" ? "error" : "warning"` for the priority badge, so P2 priorities render as "warning" (yellow). This is inconsistent with `TaskCard`, which uses three-way logic to render P2 as "info" (blue). Consider using the same three-way logic in `TaskDetailPanel` so P2 displays consistently across both views.
Evidence trail:
apps/web/src/components/KanbanConsoleMock.tsx line 506: `<Badge variant={task.priority === "P0" ? "error" : "warning"}>{task.priority}</Badge>` (two-way logic in TaskDetailPanel). apps/web/src/components/KanbanConsoleMock.tsx line 459: `variant={task.priority === "P0" ? "error" : task.priority === "P1" ? "warning" : "info"}` (three-way logic in TaskCard). Commit: REVIEWED_COMMIT.
ApprovabilityVerdict: Needs human review 1 blocking correctness issue found. Diff is too large for automated approval analysis. A human reviewer should evaluate this PR. You can customize Macroscope's approvability policy. Learn more. |


Summary
/kanbanreview route and drag/drop card movement for browser validation.Linked Work
Testing Guide
bun checkbun run --cwd packages/contracts test -- kanbanConsolebun run --cwd apps/web test -- kanbanConsoleMockbun run --cwd apps/web test:browser -- KanbanConsoleMockbun dev, openhttp://localhost:5733/kanban, drag cards between columns, switch EN/AR, and click Git/Artifacts/PRs/GitOps/Settings views.Risks and Rollback
Readiness Checklist
Note
Medium Risk
Moderate risk: introduces multiple new GitHub Actions workflows (AI review/auto-fix router/executor and PR-readiness) and updates CI runner/required check names, which could affect PR gating/automation despite being disabled by default. Also adds a large new mock UI + tests, but changes are mostly additive and non-production-facing.
Overview
Adds a governance + agent-ops toolkit: new
.ai/rules/*guidance (security, secrets, PDPL/IFRS, PR readiness, environment topology, orchestration), Claude/Codex slash-command runbooks, and supporting i18n banner strings.Introduces PR automation and gating: a new
pr-readinessworkflow, optional AI review/auto-fix workflows gated by.github/ai-loop.yml(default disabled), updates the PR template, and adjusts CI job naming/runner plus required-check expectations.Adds a Phase-3 Kanban Console mock UI surface in
apps/webwith drag-and-drop card movement, multi-view navigation, and EN/AR RTL toggle, with accompanying unit + browser tests. Also updates housekeeping (.gitignorefor.local/, formatter excludes) and refreshesAGENTS.mdto reflect the new workflow and rules.Reviewed by Cursor Bugbot for commit c661288. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Add phase 3 Kanban console contracts, mock UI, and AI loop infrastructure
packages/contracts/src/kanbanConsole.tscovering columns, tasks, priorities, transition requests/results, and agent kinds, exported from the contracts package index.apps/web/src/components/KanbanConsoleMock.tsx, a functional kanban board UI with drag-and-drop task movement, EN/AR locale switching (RTL support), and a/kanbanroute.scripts/ai-loop/(router, executor state, GitHub client, finding normalization, sticky PR comments) and three GitHub Actions workflows for automated review, fix routing, and fix execution via Claude.scripts/preflight/with integration, stack, and environment checks, fix applicators (secret generation, Better Auth URL derivation, provider CLI bootstrap), and JSON/Markdown/terminal report output..ai/rules/), Claude/Codex command runbooks (.claude/commands/,.codex/commands/), and project governance docs covering PDPL, IFRS, security, environments, and PR readiness.ai-fix-router,ai-fix-executor-claude) are disabled by default via.github/ai-loop.yml(enabled: false) but introduce new GitHub App token usage and automated commits with theX-Autofix-Executor: claudetrailer when enabled.📊 Macroscope summarized c661288. 36 files reviewed, 10 issues evaluated, 3 issues filtered, 2 comments posted
🗂️ Filtered Issues
scripts/ai-loop/config.ts — 0 comments posted, 1 evaluated, 1 filtered
.github/ai-loop.yml(a YAML file), but the code usesJSON.parse()to parse it. YAML is a superset of JSON, meaning valid JSON is valid YAML, but not vice versa. If the config file uses any YAML-specific syntax (like unquoted strings, multi-line strings with|, anchors, etc.),JSON.parse()will throw aSyntaxError. Either the file extension should be.json, or a YAML parser library should be used. [ Failed validation ]scripts/ai-loop/router-logic.ts — 0 comments posted, 1 evaluated, 1 filtered
state.last_result_fingerprintbut the calling code stores the fingerprint instate.last_signal_fingerprint. Inrouter.ts, after computingfindingSetFingerprint, it is assigned tolast_signal_fingerprint(e.g.,last_signal_fingerprint: findingSetFingerprint). However,shouldBlockRepeatedFindingSetcompares againstlast_result_fingerprint, which is a different field that is never populated with the finding fingerprint. This means the repeated-finding-set detection will never trigger, defeating the intended blocking behavior. [ Failed validation ]scripts/preflight/checks/integrations.ts — 0 comments posted, 1 evaluated, 1 filtered
doppler/yamlcheck provides a misleading hint even when the check passes. Whenfiles.length > 0 && !hasPlaceholderevaluates to true (status ="pass"), the hint is still set to"Replace placeholder Doppler project names."because the ternary at lines 182-185 only distinguishes betweenfiles.length === 0andfiles.length > 0, not whether the check passed. Other checks in this file correctly useundefinedfor the hint when passing (e.g., line 221, line 250), but this one always provides a string hint. [ Failed validation ]