Skip to content

Phase 5 — finish the deferred surfaces & hardening - #7

Merged
hutusi merged 6 commits into
mainfrom
phase-5-finish
Jun 19, 2026
Merged

Phase 5 — finish the deferred surfaces & hardening#7
hutusi merged 6 commits into
mainfrom
phase-5-finish

Conversation

@hutusi

@hutusi hutusi commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Phase 5 — finish the deferred surfaces & hardening

Closes out the four items deferred across Phases 0–4. One PR, one commit per track.

Tracks

  • Dev QA (chore: adopt Biome + lefthook + commitlint) — Biome (format + lint) folded into bun run check; lefthook hooks (pre-commit: biome + typecheck; commit-msg: commitlint; pre-push: tests) installed via prepare; conventional-commit enforcement. One-time biome check --write reformatted 53 files.
  • Live Docker + Postgres in CI (feat(ci): live Docker + Postgres integration job + tests) — DATABASE_URL-gated integration tests exercise PostgresJobStore, PostgresAuditLog + the append-only triggers, and GraphileQueue live; a new CI integration job (postgres:17 service + AURIGA_DOCKER_TESTS=1) runs the Docker sandbox + Postgres/graphile paths for real on the runner. The default local gate stays hermetic.
  • Capella console (feat(console): add Capella web console) — apps/console: Next.js App Router + Tailwind v4 + shadcn-style components (dashboard, jobs, job detail + trace, skills), a thin HTTP client of apps/api with tenant headers. Excluded from the Bun gate; verified via next build (compiles + typechecks, all 5 routes). Deploys to Vercel; not deployed here.
  • ChatOps / Slack (feat(chatops): add Slack ChatOps surface) — packages/chatops: a command parser + handler (list/status/approve/dashboard/submit, tenant-scoped, RBAC submit gate) + a Slack HMAC signature-verifying adapter. Fully unit-tested; the live Slack flow needs a real Slack app.

Verification

  • bun run check195 pass / 12 skip, typecheck + Biome clean.
  • apps/console: next build succeeds (5 routes).
  • The integration CI job is the live proof for the Docker/Postgres/graphile paths (no local Docker here).
  • Git hooks verified by use — they blocked a start-case commit subject mid-PR.

Honest scope notes

  • The console is build/typecheck-verified, not browser-verified (no browser here) and not deployed.
  • The Slack adapter's logic + signature verification are unit-tested; the live Slack round-trip is documented as needing a real Slack app + credentials.

This finishes the Auriga roadmap: Phases 0–5 across 12 packages + 2 apps.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Launched Capella console web app with dashboard, job management, and skills marketplace.
    • Added ChatOps integration supporting Slack with signature verification and slash commands.
  • Documentation

    • Updated project status to Phase 5, documenting UI hardening, CI integration tests, and ChatOps completion.
  • Infrastructure

    • Integrated Postgres-backed integration tests in CI pipeline with Docker sandbox support.
    • Added Biome code linter, Commitlint for commit validation, and Lefthook for Git hooks.

hutusi added 4 commits June 19, 2026 15:16
- Biome (format + lint) folded into `bun run check` (tsc -> biome -> test);
  `bun run format` to apply. Pragmatic config (TS only, excludes apps/console +
  fixtures; relaxes no-explicit-any / non-null / param-assign for our style).
- lefthook git hooks: pre-commit (biome on staged + typecheck), commit-msg
  (commitlint conventional), pre-push (bun test); installed via prepare.
- commitlint config-conventional (body/footer line-length relaxed for detailed bodies).
- one-time `biome check --write` reformatted 53 files (formatting only).
- postgres.integration.test.ts (gated on DATABASE_URL, skipped locally): exercises
  PostgresJobStore CRUD/checkpoint/trace/listByFactio, PostgresAuditLog + the
  append-only UPDATE/DELETE triggers, and GraphileQueue migrate/enqueue live
- CI `integration` job: postgres:17 service + AURIGA_DOCKER_TESTS=1, runs the
  habenae + sandbox suites so the Docker sandbox + Postgres/graphile paths run for
  real on the runner; default `bun run check` stays hermetic
…tyle)

- apps/console: Next.js App Router + Tailwind v4 + shadcn-style components
  (Card/Badge/Table). Pages: dashboard, jobs (tenant-scoped via x-auriga headers),
  job detail + trace, skill marketplace. Thin HTTP client of apps/api (own types,
  no server-package imports).
- excluded from the root Bun tsc/biome/test gate; verified via `next build`
  (compiles + typechecks, all 5 routes). Deploys to Vercel; not deployed here.
- packages/chatops: platform-agnostic command parser (list/status/approve/
  dashboard/submit/help) + handler dispatching to the control plane, scoped to the
  caller's factio and through the RBAC submit gate (audit best-effort)
- Slack adapter: v0 HMAC signature verification (with replay window) + slash-command
  parsing + end-to-end dispatch; fully unit-tested (live Slack flow needs a real app)
- README: Phase 5 done
@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@hutusi, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 38 minutes and 59 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more credits in the billing tab to continue.

⌛ How to resolve this issue?

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

🚦 How do rate limits work?

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

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, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7c0aabb9-c216-47ca-81e6-eb49686ffa2c

📥 Commits

Reviewing files that changed from the base of the PR and between b9cb9b3 and 63cca99.

📒 Files selected for processing (11)
  • .github/workflows/ci.yml
  • apps/console/app/jobs/[id]/page.tsx
  • apps/console/app/jobs/page.tsx
  • apps/console/app/skills/page.tsx
  • apps/console/components/ui/table.tsx
  • packages/chatops/src/handler.test.ts
  • packages/chatops/src/handler.ts
  • packages/habenae/src/dashboard.ts
  • packages/habenae/src/postgres.integration.test.ts
  • packages/sandbox/src/docker.ts
  • packages/sandbox/src/sandbox.test.ts
📝 Walkthrough

Walkthrough

This PR completes Phase 5 by adding Biome/lefthook/commitlint tooling, a new @auriga/chatops package with Slack signature verification and slash-command dispatch, the @auriga/console Next.js web console (dashboard, jobs, skills pages), Postgres integration tests for habenae, a CI integration job, and widespread Biome-driven formatting normalization across existing files.

Changes

New Features and Tooling

Layer / File(s) Summary
Biome, lefthook, commitlint wiring
biome.json, lefthook.yml, commitlint.config.js, package.json, README.md
Introduces Biome formatter/linter config, Lefthook git hooks (pre-commit, commit-msg, pre-push), commitlint conventional config, and extends root package.json scripts/devDependencies.
ChatOps command parsing and handler
packages/chatops/package.json, packages/chatops/tsconfig.json, packages/chatops/src/commands.ts, packages/chatops/src/commands.test.ts, packages/chatops/src/handler.ts, packages/chatops/src/handler.test.ts
Adds the @auriga/chatops package; defines Command union type, HELP, and parseCommand; implements handleCommand switching on all command kinds with tenant isolation, RBAC policy checks, audit writes, and formatted text replies.
Slack signature verification and slash-command adapter
packages/chatops/src/slack.ts, packages/chatops/src/slack.test.ts, packages/chatops/src/index.ts
Adds verifySlackSignature (HMAC-SHA256, 300 s replay window, constant-time comparison), parseSlashCommand, SlackRequest, and handleSlackCommand; re-exports the full chatops public API surface from the index.
Capella console: foundation
apps/console/package.json, apps/console/tsconfig.json, apps/console/next.config.mjs, apps/console/postcss.config.mjs, apps/console/.gitignore, apps/console/lib/..., apps/console/components/ui/*, tsconfig.json
Creates the @auriga/console Next.js app: package manifest, configs, cn util, api.ts HTTP client (types + get<T> helper + api object), and UI primitives (Badge, Card, CardTitle, Table/THead/TBody/TR/TH/TD).
Capella console: pages
apps/console/app/globals.css, apps/console/app/layout.tsx, apps/console/app/page.tsx, apps/console/app/jobs/..., apps/console/app/skills/page.tsx, apps/console/README.md
Adds root layout with nav, global CSS, and four server pages: dashboard (summary cards + tenant/audit tables), jobs list (table with Badge state), job detail (job card + trace card), and skills marketplace table.
Postgres integration tests and CI job
packages/habenae/src/postgres.integration.test.ts, .github/workflows/ci.yml
Adds a DATABASE_URL-gated integration test suite covering PostgresJobStore, PostgresAuditLog (append-only trigger), and GraphileQueue; adds a CI integration job with a Postgres 17 service container.

Biome-Driven Formatting Normalization

Layer / File(s) Summary
Formatting: apps/api, packages/habenae, packages/capella
apps/api/src/app.ts, apps/api/src/app.test.ts, packages/habenae/src/*, packages/capella/src/*
Reformats multi-line object literals, safeAudit/submitJob call sites, test fixtures, and tracing switch cases with no behavior changes.
Formatting: packages/core, currus, provider, sandbox, cli, evals, skill-registry
packages/core/src/..., packages/currus/src/..., packages/provider/src/..., packages/sandbox/src/..., packages/cli/src/..., packages/evals/src/..., packages/skill-registry/src/...
Reformats object literals, import statements, and function signatures across existing packages; includes Object.hasOwn substitution in verification.ts and typed SandboxSnapshot variable; no behavior changes.

Sequence Diagram(s)

sequenceDiagram
  participant Slack
  participant handleSlackCommand
  participant verifySlackSignature
  participant parseSlashCommand
  participant parseCommand
  participant handleCommand
  participant JobStore

  Slack->>handleSlackCommand: POST /slack (body, X-Slack-Signature, X-Slack-Request-Timestamp)
  handleSlackCommand->>verifySlackSignature: signingSecret, timestamp, body, signature
  verifySlackSignature-->>handleSlackCommand: false (stale/tampered)
  handleSlackCommand-->>Slack: 401 "invalid signature"

  Note over handleSlackCommand,verifySlackSignature: valid path
  verifySlackSignature-->>handleSlackCommand: true
  handleSlackCommand->>parseSlashCommand: body (URL-encoded)
  parseSlashCommand-->>handleSlackCommand: text, userId, userName
  handleSlackCommand->>parseCommand: text
  parseCommand-->>handleSlackCommand: Command (list/status/approve/submit/...)
  handleSlackCommand->>handleCommand: Command + ChatContext
  handleCommand->>JobStore: list/get/update
  JobStore-->>handleCommand: jobs/job
  handleCommand-->>handleSlackCommand: ChatReply { text }
  handleSlackCommand-->>Slack: 200 + reply text
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • ainaive/auriga#1: Overlaps directly with formatting changes in packages/sandbox/src/docker.ts within the same DockerSandbox/DockerSandboxDriver command construction paths.
  • ainaive/auriga#3: Both PRs touch packages/capella/src/tracing.ts in the emitSpans implementation.
  • ainaive/auriga#6: Overlaps at code level in apps/api/src/app.ts/app.test.ts (same /jobs, safeAudit, dashboard handlers) and .github/workflows/ci.yml, as that PR introduced the underlying Phase 4 control-plane API and its CI baseline.

Poem

🐰 A rabbit typed fast and the linter agreed,
Biome checked every line with remarkable speed.
ChatOps now whispers to Slack with a sign,
The console gleams bright with each dashboard line.
Postgres confirms every audit and deed—
Phase five is complete! Time to plant a new seed. 🌱

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 31.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Phase 5 — finish the deferred surfaces & hardening' clearly and specifically summarizes the main change: completing Phase 5 with four deferred deliverables (Biome/lefthook, integration tests, Capella console, ChatOps/Slack).
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch phase-5-finish

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.

…t time out

The first `docker run` pulls oven/bun:1 inside the first test, blowing past the
default 5s timeout on a cold CI runner (later tests reuse the warm image and pass
in ~440ms). Pull the image at module load, outside any per-test timeout, so each
test measures sandbox behavior rather than a one-time image fetch. Export
DEFAULT_IMAGE so the test pulls exactly what the driver runs.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🧹 Nitpick comments (1)
package.json (1)

17-17: ⚡ Quick win

Fail-open hook installation can silently disable local gates.

lefthook install || true suppresses real install failures in normal git clones, so pre-commit/commit-msg checks can be missing without notice. Prefer skipping only when .git is absent, not on actual install errors.

Suggested change
-    "prepare": "lefthook install || true"
+    "prepare": "if [ -d .git ]; then lefthook install; fi"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@package.json` at line 17, The prepare script in package.json currently uses
lefthook install || true, which suppresses all installation errors including
legitimate failures that should be visible to developers. Instead of silently
ignoring all errors, modify the prepare script to only skip lefthook
installation when the .git directory is absent (which occurs in scenarios like
npm package installations outside a git repository). This way, actual
installation failures in normal git clones will surface and notify developers
that their pre-commit/commit-msg hooks may not be properly configured, rather
than silently disabling local gates.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/ci.yml:
- Around line 51-53: The setup-bun action in both the check job and integration
job uses bun-version set to latest, making CI non-deterministic and vulnerable
to breaking changes when new Bun versions release. Replace bun-version: latest
with an explicit, pinned version number (e.g., bun-version: 1.x.x where x.x is a
specific release) in both occurrences of the setup-bun action to ensure
reproducible and stable CI behavior across all runs and PRs.

In `@apps/console/app/jobs/`[id]/page.tsx:
- Line 10: In the job page component, the condition checking if a job is missing
needs to be updated to properly return an HTTP 404 status code. Replace the
current return statement that renders a message with a call to the notFound()
function imported from 'next/navigation'. Import notFound from 'next/navigation'
at the top of the file, then in the if (!job) block, call notFound() instead of
returning JSX to ensure the correct HTTP status is sent to the client.

In `@apps/console/app/jobs/page.tsx`:
- Line 33: The job ID in the Link component's href attribute is being
interpolated without URL encoding. If the job ID contains special characters
like forward slashes, question marks, hashes, or percent signs, it will break
the URL routing. Wrap the j.id value with encodeURIComponent() when building the
href in the Link component to properly encode any special characters and ensure
the route works correctly regardless of the ID's content.

In `@apps/console/app/skills/page.tsx`:
- Line 29: The TR component is using s.name as the key, which causes collisions
when multiple versions of the same skill exist in the marketplace. Replace the
key prop value from s.name to a unique identifier that combines the skill name
with its version (such as s.name concatenated with s.version, or if available,
use a unique identifier like s.id that accounts for both name and version
uniqueness). This ensures each row has a distinct key even when skills with
identical names but different versions are present.

In `@apps/console/components/ui/table.tsx`:
- Around line 20-21: The TH component is missing the scope attribute on the th
element, which is required for proper accessibility with screen readers. In the
TH function, add the scope="col" attribute to the th element. This tells
assistive technologies that the header cell applies to its entire column,
improving accessibility for users relying on screen readers.

In `@apps/console/lib/api.ts`:
- Around line 77-82: The dashboard and skills API methods in the api object are
missing the second parameter that enables tenant/role headers (x-auriga-*),
while jobs, job, and trace methods all include true as the second parameter to
enable these headers. Update both the dashboard and skills method calls to
include true as the second parameter (like get<Dashboard>("/dashboard", true)
and get<Skill[]>("/skills", true)) to ensure all console API calls consistently
apply tenant/role headers for proper tenant isolation.

In `@packages/chatops/src/handler.ts`:
- Around line 70-74: The dashboard case is building and returning global
organization-wide aggregates that violate tenant isolation. Modify the
buildDashboard call in the "dashboard" case to include tenant filtering so it
only aggregates data for the requesting tenant. Pass the tenant context (likely
available from ctx) to buildDashboard so that d.totals.jobs, d.totals.tenants,
and d.totals.cost_usd reflect only the current tenant's data, not
organization-wide metrics. This ensures the dashboard command respects the
tenant-scoped isolation contract.
- Around line 57-61: The approve case block currently only validates that the
actor's factio matches the record's factio before approving a job, but lacks
role-based access control enforcement. Before calling ctx.store.update for the
approval in the approve case, add a check to verify that ctx.actor has the
appropriate permission or role to approve jobs, not just that they belong to the
same factio. This ensures only authorized actors can approve jobs, preventing
unauthorized same-factio actors from changing the approval state.

In `@packages/habenae/src/postgres.integration.test.ts`:
- Around line 28-34: The database cleanup using truncate statements is only
performed once in beforeAll, which causes tests to be coupled to execution order
and not isolated. Move the truncate operations (the pool.query calls for
truncating jobs, checkpoints, traces, and audit_events) from the beforeAll hook
to a new beforeEach hook, keeping the pool initialization and migration in
beforeAll. This ensures each test starts with a clean database state regardless
of execution order.

---

Nitpick comments:
In `@package.json`:
- Line 17: The prepare script in package.json currently uses lefthook install ||
true, which suppresses all installation errors including legitimate failures
that should be visible to developers. Instead of silently ignoring all errors,
modify the prepare script to only skip lefthook installation when the .git
directory is absent (which occurs in scenarios like npm package installations
outside a git repository). This way, actual installation failures in normal git
clones will surface and notify developers that their pre-commit/commit-msg hooks
may not be properly configured, rather than silently disabling local gates.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d8884bd7-af27-4940-94bb-ebd8c22ee741

📥 Commits

Reviewing files that changed from the base of the PR and between 5a52531 and b9cb9b3.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (87)
  • .github/workflows/ci.yml
  • README.md
  • apps/api/src/app.test.ts
  • apps/api/src/app.ts
  • apps/console/.gitignore
  • apps/console/README.md
  • apps/console/app/globals.css
  • apps/console/app/jobs/[id]/page.tsx
  • apps/console/app/jobs/page.tsx
  • apps/console/app/layout.tsx
  • apps/console/app/page.tsx
  • apps/console/app/skills/page.tsx
  • apps/console/components/ui/badge.tsx
  • apps/console/components/ui/card.tsx
  • apps/console/components/ui/table.tsx
  • apps/console/lib/api.ts
  • apps/console/lib/utils.ts
  • apps/console/next.config.mjs
  • apps/console/package.json
  • apps/console/postcss.config.mjs
  • apps/console/tsconfig.json
  • biome.json
  • commitlint.config.js
  • lefthook.yml
  • package.json
  • packages/capella/src/cost.test.ts
  • packages/capella/src/observability.test.ts
  • packages/capella/src/rollup.ts
  • packages/capella/src/tracing.test.ts
  • packages/capella/src/tracing.ts
  • packages/chatops/package.json
  • packages/chatops/src/commands.test.ts
  • packages/chatops/src/commands.ts
  • packages/chatops/src/handler.test.ts
  • packages/chatops/src/handler.ts
  • packages/chatops/src/index.ts
  • packages/chatops/src/slack.test.ts
  • packages/chatops/src/slack.ts
  • packages/chatops/tsconfig.json
  • packages/cli/src/e2e.test.ts
  • packages/cli/src/main.ts
  • packages/core/src/job/spec.test.ts
  • packages/core/src/provider/helpers.ts
  • packages/core/src/skill/crypto.ts
  • packages/core/src/skill/hash.ts
  • packages/core/src/skill/verify.test.ts
  • packages/core/src/skill/verify.ts
  • packages/core/src/trace/trace.test.ts
  • packages/core/src/trace/types.ts
  • packages/currus/src/context.ts
  • packages/currus/src/dispatcher.test.ts
  • packages/currus/src/job-runner.test.ts
  • packages/currus/src/job-runner.ts
  • packages/currus/src/loop.ts
  • packages/currus/src/routing.test.ts
  • packages/currus/src/skills.test.ts
  • packages/currus/src/tools/git.ts
  • packages/currus/src/tools/sandbox-tools.test.ts
  • packages/currus/src/tools/search.ts
  • packages/currus/src/trace-emit.test.ts
  • packages/currus/src/verification.ts
  • packages/evals/src/runner.test.ts
  • packages/habenae/src/audit.test.ts
  • packages/habenae/src/audit.ts
  • packages/habenae/src/dag.ts
  • packages/habenae/src/dashboard.test.ts
  • packages/habenae/src/feedback.test.ts
  • packages/habenae/src/file-store.ts
  • packages/habenae/src/governance.test.ts
  • packages/habenae/src/governance.ts
  • packages/habenae/src/postgres-store.ts
  • packages/habenae/src/postgres.integration.test.ts
  • packages/habenae/src/provider-routing.test.ts
  • packages/habenae/src/scheduler.test.ts
  • packages/habenae/src/scheduler.ts
  • packages/habenae/src/worker.ts
  • packages/provider/src/anthropic.test.ts
  • packages/provider/src/anthropic.ts
  • packages/provider/src/contract.ts
  • packages/provider/src/provider-router.ts
  • packages/provider/src/stub.test.ts
  • packages/sandbox/src/docker.ts
  • packages/sandbox/src/sandbox.test.ts
  • packages/skill-registry/src/bundle.ts
  • packages/skill-registry/src/local-registry.ts
  • packages/skill-registry/src/marketplace.test.ts
  • tsconfig.json

Comment thread .github/workflows/ci.yml Outdated
Comment thread apps/console/app/jobs/[id]/page.tsx Outdated
Comment thread apps/console/app/jobs/page.tsx Outdated
Comment thread apps/console/app/skills/page.tsx Outdated
Comment thread apps/console/components/ui/table.tsx Outdated
Comment thread apps/console/lib/api.ts
Comment on lines +77 to +82
dashboard: () => get<Dashboard>("/dashboard"),
jobs: () => get<Job[]>("/jobs", true),
job: (id: string) => get<Job>(`/jobs/${encodeURIComponent(id)}`, true),
trace: (id: string) => get<Trace>(`/jobs/${encodeURIComponent(id)}/trace`, true),
skills: () => get<Skill[]>("/skills"),
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Apply tenant/role headers to all console API calls.

dashboard and skills skip x-auriga-* headers, while the PR objective says console pages are tenant-scoped via those headers. This can weaken tenant isolation or return unintended data depending on API defaults.

Proposed fix
 export const api = {
-  dashboard: () => get<Dashboard>("/dashboard"),
+  dashboard: () => get<Dashboard>("/dashboard", true),
   jobs: () => get<Job[]>("/jobs", true),
   job: (id: string) => get<Job>(`/jobs/${encodeURIComponent(id)}`, true),
   trace: (id: string) => get<Trace>(`/jobs/${encodeURIComponent(id)}/trace`, true),
-  skills: () => get<Skill[]>("/skills"),
+  skills: () => get<Skill[]>("/skills", true),
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
dashboard: () => get<Dashboard>("/dashboard"),
jobs: () => get<Job[]>("/jobs", true),
job: (id: string) => get<Job>(`/jobs/${encodeURIComponent(id)}`, true),
trace: (id: string) => get<Trace>(`/jobs/${encodeURIComponent(id)}/trace`, true),
skills: () => get<Skill[]>("/skills"),
};
dashboard: () => get<Dashboard>("/dashboard", true),
jobs: () => get<Job[]>("/jobs", true),
job: (id: string) => get<Job>(`/jobs/${encodeURIComponent(id)}`, true),
trace: (id: string) => get<Trace>(`/jobs/${encodeURIComponent(id)}/trace`, true),
skills: () => get<Skill[]>("/skills", true),
};
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/console/lib/api.ts` around lines 77 - 82, The dashboard and skills API
methods in the api object are missing the second parameter that enables
tenant/role headers (x-auriga-*), while jobs, job, and trace methods all include
true as the second parameter to enable these headers. Update both the dashboard
and skills method calls to include true as the second parameter (like
get<Dashboard>("/dashboard", true) and get<Skill[]>("/skills", true)) to ensure
all console API calls consistently apply tenant/role headers for proper tenant
isolation.

Comment thread packages/chatops/src/handler.ts
Comment thread packages/chatops/src/handler.ts Outdated
Comment thread packages/habenae/src/postgres.integration.test.ts
chatops (real isolation gaps):
- approve now enforces the same RBAC gate as submit — a tenant match alone let
  any same-factio role approve; require the actor's role to be policy-permitted
- dashboard command is scoped to the caller's factio (was returning org-wide
  job/tenant/cost aggregates, violating the handler's tenant-isolation contract)
- buildDashboard gains an optional `factio` filter (admin HTTP view stays org-wide)
- tests: RBAC-denied approve + tenant-scoped dashboard

console (correctness/a11y quick wins):
- job detail returns a real 404 via notFound() instead of a 200 with a message
- encode job IDs in route hrefs; key skill rows by name@version; th scope="col"

ci: pin bun-version to 1.3.12 in both jobs (was `latest` — non-deterministic)

test: reset Postgres state per-test (beforeEach) so outcomes don't depend on order

Not changed: CodeRabbit flagged the console dashboard/skills calls for missing
auth headers — those API routes are intentionally open admin/governance views
(gated by the deployment proxy; the API ignores actor headers there), so adding
headers would be a no-op.
@hutusi
hutusi merged commit e400b14 into main Jun 19, 2026
3 checks passed
@hutusi
hutusi deleted the phase-5-finish branch June 19, 2026 08:30
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