Skip to content

feat(web): add phase 3 Kanban console contracts#2557

Closed
MohAnghabo wants to merge 9 commits into
pingdotgg:mainfrom
MohAnghabo:feature/t3-kanban-phase-3-contracts
Closed

feat(web): add phase 3 Kanban console contracts#2557
MohAnghabo wants to merge 9 commits into
pingdotgg:mainfrom
MohAnghabo:feature/t3-kanban-phase-3-contracts

Conversation

@MohAnghabo
Copy link
Copy Markdown

@MohAnghabo MohAnghabo commented May 6, 2026

Summary

  • Add shared Effect Schema contracts for the Kanban Console domain so future integrations can replace mocks incrementally.
  • Move the Kanban mock data behind a provider-shaped runtime with transition, PR-watch, and auto-fix eligibility rules.
  • Add a stable /kanban review route and drag/drop card movement for browser validation.

Linked Work

  • Refs MohAnghabo/ai-starter-pro#43
  • Spec: docs/tasks/t3-kanban-project-console.md
  • Completed: Phase 3 contracts and mock runtime.
  • Out of scope: GitHub Project writes, live GitHub/git/CLI/provider integrations, and docs/product writes.

Testing Guide

  1. bun check
  2. bun run --cwd packages/contracts test -- kanbanConsole
  3. bun run --cwd apps/web test -- kanbanConsoleMock
  4. bun run --cwd apps/web test:browser -- KanbanConsoleMock
  5. Browser smoke: run bun dev, open http://localhost:5733/kanban, drag cards between columns, switch EN/AR, and click Git/Artifacts/PRs/GitOps/Settings views.

Risks and Rollback

  • Risk: New mock contracts may drift from future live GitHub/CLI provider shapes if integration phases bypass these schemas.
  • Risk: Drag/drop remains mock-local and does not write GitHub Project state.
  • Rollback: Revert this PR to restore the Phase 2 static mock surface and remove the Phase 3 contract layer.

Readiness Checklist

  • Relevant Markdown docs updated where needed
  • Tests added or updated for this change
  • Durable spec path linked when applicable
  • Task execution log updated when applicable
  • No GitHub Project, git, CLI, provider, or docs/product mutations
  • No real PII, secrets, tokens, or raw logs in fixtures or PR text
  • All required CI checks are green

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-readiness workflow, 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/web with drag-and-drop card movement, multi-view navigation, and EN/AR RTL toggle, with accompanying unit + browser tests. Also updates housekeeping (.gitignore for .local/, formatter excludes) and refreshes AGENTS.md to 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

  • Adds typed io-ts/Zod contracts in packages/contracts/src/kanbanConsole.ts covering columns, tasks, priorities, transition requests/results, and agent kinds, exported from the contracts package index.
  • Introduces 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 /kanban route.
  • Adds a full AI loop system under 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.
  • Adds a preflight check framework under 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.
  • Adds AI rule docs (.ai/rules/), Claude/Codex command runbooks (.claude/commands/, .codex/commands/), and project governance docs covering PDPL, IFRS, security, environments, and PR readiness.
  • Risk: the AI loop workflows (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 the X-Autofix-Executor: claude trailer 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
  • line 53: The config file path defaults to .github/ai-loop.yml (a YAML file), but the code uses JSON.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 a SyntaxError. 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
  • line 56: The function checks state.last_result_fingerprint but the calling code stores the fingerprint in state.last_signal_fingerprint. In router.ts, after computing findingSetFingerprint, it is assigned to last_signal_fingerprint (e.g., last_signal_fingerprint: findingSetFingerprint). However, shouldBlockRepeatedFindingSet compares against last_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
  • line 181: The doppler/yaml check provides a misleading hint even when the check passes. When files.length > 0 && !hasPlaceholder evaluates to true (status = "pass"), the hint is still set to "Replace placeholder Doppler project names." because the ternary at lines 182-185 only distinguishes between files.length === 0 and files.length > 0, not whether the check passed. Other checks in this file correctly use undefined for the hint when passing (e.g., line 221, line 250), but this one always provides a string hint. [ Failed validation ]

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 6, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 7d203872-e4fb-4238-bac4-b7768daa5743

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

@github-actions github-actions Bot added size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels May 6, 2026
@MohAnghabo
Copy link
Copy Markdown
Author

Closing: this PR was opened against upstream by mistake. The product-fork PR will be opened against MohAnghabo/kanban-console.

@MohAnghabo MohAnghabo closed this May 6, 2026
Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Fix All in Cursor

❌ 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`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Fix in Cursor Fix in Web

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>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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)
Fix in Cursor Fix in Web

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"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

Fix in Cursor Fix in Web

Triggered by project rule: Bugbot Project Brief

Reviewed by Cursor Bugbot for commit c661288. Configure here.

Comment on lines +34 to +46
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"));
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 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>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 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.

@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp Bot commented May 6, 2026

Approvability

Verdict: 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant