Skip to content

fix(auth/command): team-scoped palette actions + team-access editor clarity - #496

Open
enyineer wants to merge 3 commits into
mainfrom
fix/team-scoped-palette-and-team-ux
Open

fix(auth/command): team-scoped palette actions + team-access editor clarity#496
enyineer wants to merge 3 commits into
mainfrom
fix/team-scoped-palette-and-team-ux

Conversation

@enyineer

@enyineer enyineer commented Jul 26, 2026

Copy link
Copy Markdown
Owner

Addresses 5 of the 6 feedback notes. (The "Manage X / Create X feel duplicated" note was dropped — both commands stay, per feedback that having both is good.)

1. Bug — Command Palette hid create-actions from team members

command-backend filtered commands against the caller's global access rules only, so a user whose team holds a create-capability grant (but no global incident.incident.manage) never saw "Create Incident" / "Create Maintenance" or their shortcuts. The palette hid the actions from exactly the people authorized to run them — the same "global-only gate excludes team-scoped users" class as .claude/rules/rlac.md.

Commands may now declare manageCapability (mirroring routes/nav). filterByAccessRules admits an item on the global rules OR a team grant on the declared type; the backend resolves that per request via hasAnyTypeGrant (with includeCreator, so a would-be creator qualifies before owning an instance) and fails closed.

Also removed useGlobalShortcuts' userAccessRules re-check: it tested global rules only and would have dropped team users' shortcuts — both call sites already defeated it by passing ["*"], so it was dead, misleading code.

2. Team-access editor clarity + safety

  • "Manage" → "Can edit", gear icon removed. It sets the team's grant on this resource, but the label + gear read as "manage the team".
  • Team name is now a link to /teams?team=<id>, opening that team's members dialog. "Go to the team" gets its own affordance instead of being conflated with the checkbox. The Teams page consumes the param once, then clears it.
  • Self-lockout guard: revoking your own team's only edit grant now confirms first — afterwards you could neither change the resource nor restore the permission. Global teams.manage admins are exempt (they can always restore). Extracted as the pure, unit-tested isSelfRevokingChange.
  • Add-member field explained: placeholder "Add a user by name or email" + helper text stating it adds a new member from the directory (not a filter over current members) and that users are only findable after their first sign-in.

Verification

  • typecheck ✓ · lint ✓ · full unit suite 10,315 pass / 0 fail
  • New behavioral tests: filter-access.test.ts (10 cases, pins the palette regression) and selfLockout.test.ts (8 cases)

3. Create an incident / maintenance from the system overview

The system overview listed a system.s incidents and maintenances but offered no way to open one for it - you had to navigate away and re-pick the system by hand.

Both panels now carry an action ("Report incident" / "Schedule maintenance") that deep-links to the editor with the system already selected, via ?action=create&systemId=<id>. The pages consume and clear both params, so a refresh does not reopen the dialog.

The action is gated on useProcedureAccess over the CREATE procedure.s contract, so it appears for a global manager AND for someone who can manage that system through a team (the create.parent gate) - exactly who the backend accepts. Gating on the bare global rule would have hidden it from the team-scoped users it helps most (the same mistake as bug 1).

Editors gain presetSystemIds, and their unsaved-changes baseline accounts for the pre-selection - otherwise opening a pre-scoped form and closing it would falsely prompt to discard.

Verification

  • typecheck OK, lint OK, full unit suite 10,315 pass / 0 fail
  • New behavioral tests: filter-access.test.ts (10 cases, pins the palette regression) and selfLockout.test.ts (8 cases)

Only the "Manage X / Create X feel duplicated" note is intentionally not addressed - per feedback, having both commands is good.

enyineer and others added 2 commits July 26, 2026 04:55
The palette filtered commands by GLOBAL access rules only, so a user whose team
holds a create-capability grant (and no global *.manage rule) never saw "Create
Incident" / "Create Maintenance" or their shortcuts - it hid the actions from
exactly the people authorized to run them.

Commands may now declare `manageCapability`, mirroring the gate routes/nav use.
filterByAccessRules admits an item on the global rules OR a team grant on the
declared type; the backend resolves that per request via hasAnyTypeGrant
(includeCreator, so a would-be creator qualifies before owning an instance) and
fails closed. Incident + maintenance commands declare their types.

useGlobalShortcuts drops its userAccessRules re-check: the server-filtered list
is authoritative, the check tested global rules only, and both call sites already
defeated it by passing ["*"].

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Hccsjzvqr6xfhGicNBjRgB
From user feedback on the "Who can change this" editor:

- Relabel the "Manage" checkbox to "Can edit" and drop its gear icon. It sets the
  team's grant on THIS resource, but the wording + gear read as "manage the
  team", so people expected it to open the Teams UI.
- Make the team name a link to /teams?team=<id>, which opens that team's members
  dialog. "Go to the team" now has its own affordance instead of being conflated
  with the grant checkbox. TeamsTab consumes the param once, then clears it.
- Confirm before a user revokes their OWN team's only edit grant: afterwards they
  could neither change the resource nor restore the permission. Global
  teams.manage admins are exempt (they can always restore). The decision is
  extracted as the pure, unit-tested isSelfRevokingChange.
- Explain the add-member field: it adds a NEW member from the directory (not a
  filter over current members), and only users who have signed in at least once
  exist there.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Hccsjzvqr6xfhGicNBjRgB
@changeset-bot

changeset-bot Bot commented Jul 26, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 303fcd9

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 80 packages
Name Type
@checkstack/command-common Minor
@checkstack/command-backend Minor
@checkstack/command-frontend Minor
@checkstack/incident-backend Patch
@checkstack/maintenance-backend Patch
@checkstack/incident-frontend Minor
@checkstack/maintenance-frontend Minor
@checkstack/auth-frontend Minor
@checkstack/dashboard-frontend Patch
@checkstack/sdk Patch
@checkstack/announcement-backend Patch
@checkstack/auth-backend Patch
@checkstack/automation-backend Patch
@checkstack/catalog-backend Patch
@checkstack/dependency-backend Patch
@checkstack/gitops-backend Patch
@checkstack/healthcheck-backend Patch
@checkstack/integration-backend Patch
@checkstack/notification-backend Patch
@checkstack/satellite-backend Patch
@checkstack/script-packages-backend Patch
@checkstack/secrets-backend Patch
@checkstack/slo-backend Patch
@checkstack/status-page-backend Patch
@checkstack/frontend Patch
@checkstack/announcement-frontend Patch
@checkstack/automation-frontend Patch
@checkstack/catalog-frontend Patch
@checkstack/healthcheck-frontend Patch
@checkstack/logstream-frontend Patch
@checkstack/metricstream-frontend Patch
@checkstack/notification-frontend Patch
@checkstack/slo-frontend Patch
@checkstack/status-page-frontend Patch
@checkstack/telemetry-frontend Patch
@checkstack/theme-frontend Patch
@checkstack/tips-frontend Patch
@checkstack/tracestream-frontend Patch
@checkstack/dependency-frontend Patch
@checkstack/ai-backend Patch
@checkstack/screenshots Patch
@checkstack/script-packages-frontend Patch
@checkstack/theme-backend Patch
@checkstack/tips-backend Patch
@checkstack/auth-credential-backend Patch
@checkstack/auth-github-backend Patch
@checkstack/auth-ldap-backend Patch
@checkstack/auth-saml-backend Patch
@checkstack/integration-jira-backend Patch
@checkstack/integration-script-backend Patch
@checkstack/integration-teams-backend Patch
@checkstack/integration-webex-backend Patch
@checkstack/integration-webhook-backend Patch
@checkstack/anomaly-backend Patch
@checkstack/notification-backstage-backend Patch
@checkstack/notification-discord-backend Patch
@checkstack/notification-gotify-backend Patch
@checkstack/notification-pushover-backend Patch
@checkstack/notification-slack-backend Patch
@checkstack/notification-smtp-backend Patch
@checkstack/notification-teams-backend Patch
@checkstack/notification-telegram-backend Patch
@checkstack/notification-webex-backend Patch
@checkstack/notification-webhook-backend Patch
@checkstack/logstream-backend Patch
@checkstack/metricstream-backend Patch
@checkstack/telemetry-backend Patch
@checkstack/tracestream-backend Patch
@checkstack/satellite Patch
@checkstack/script-packages-store-postgres Patch
@checkstack/script-packages-store-s3 Patch
@checkstack/healthcheck-script-backend Patch
@checkstack/secrets-backend-local Patch
@checkstack/secrets-backend-vault Patch
@checkstack/anomaly-frontend Patch
@checkstack/gitops-frontend Patch
@checkstack/integration-frontend Patch
@checkstack/pluginmanager-frontend Patch
@checkstack/satellite-frontend Patch
@checkstack/k8s-events-backend Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions

Copy link
Copy Markdown
Contributor

❌ PR Checks Failed

Check Status
Typecheck ✅ Passed
Lint ✅ Passed
Deps ✅ Passed
Test ✅ Passed
Integration ✅ Passed
Security (deps) ❌ Failed
Security (container) ✅ Passed
E2E ✅ Passed
❌ Security Audit Failures (dependency graph)
🔎 Security Audit (dependency graph, incl. devDependencies)

❌ Fixable vulnerabilities (2) — an upgrade path exists, so these fail the build:
  [MEDIUM] tar 7.5.20 -> fixed in 7.5.21  (GHSA-r292-9mhp-454m)
  [HIGH] brace-expansion 5.0.7 -> fixed in 5.0.8  (CVE-2026-14257)

⚠️  Known unfixed vulnerabilities (0) — surfaced, not gated:
  (none)

How to fix: This gate scans the whole dependency graph (incl. devDependencies) and fails only on findings with an upgrade path (a fixed version exists); unfixed findings are warnings, not gated. Run bun run audit:security locally to reproduce. Bump the affected direct dependency, or for a transitive package add a documented entry to security/managed-overrides.json plus matching overrides/resolutions in package.json (then bun install). Re-run bun run audit:overrides:check to confirm the override is consistent.

@enyineer The above code quality issues were found in this PR. Please fix them before merging.

The system overview listed a system's incidents/maintenances but gave no way to
open one for it - you had to go to the incidents page and re-pick the system.

Both system panels now offer "Report incident" / "Schedule maintenance", deep
-linking to the editor with the system pre-selected via
?action=create&systemId=<id>. The config pages consume and clear both params.

The action is gated on useProcedureAccess over the CREATE procedure's contract,
so it shows for a global manager AND for someone who manages the system via a
team (create.parent) - the bare global rule would have hidden it from exactly the
team-scoped users it helps most.

Editors gain `presetSystemIds`, and their unsaved-changes baseline accounts for
it so opening a pre-scoped form and closing it does not nag to discard.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Hccsjzvqr6xfhGicNBjRgB
@github-actions

Copy link
Copy Markdown
Contributor

❌ PR Checks Failed

Check Status
Typecheck ✅ Passed
Lint ✅ Passed
Deps ✅ Passed
Test ✅ Passed
Integration ✅ Passed
Security (deps) ❌ Failed
Security (container) ✅ Passed
E2E ✅ Passed
❌ Security Audit Failures (dependency graph)
🔎 Security Audit (dependency graph, incl. devDependencies)

❌ Fixable vulnerabilities (2) — an upgrade path exists, so these fail the build:
  [MEDIUM] tar 7.5.20 -> fixed in 7.5.21  (GHSA-r292-9mhp-454m)
  [HIGH] brace-expansion 5.0.7 -> fixed in 5.0.8  (CVE-2026-14257)

⚠️  Known unfixed vulnerabilities (0) — surfaced, not gated:
  (none)

How to fix: This gate scans the whole dependency graph (incl. devDependencies) and fails only on findings with an upgrade path (a fixed version exists); unfixed findings are warnings, not gated. Run bun run audit:security locally to reproduce. Bump the affected direct dependency, or for a transitive package add a documented entry to security/managed-overrides.json plus matching overrides/resolutions in package.json (then bun install). Re-run bun run audit:overrides:check to confirm the override is consistent.

@enyineer The above code quality issues were found in this PR. Please fix them before merging.

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