Skip to content

fix(console): stop inviting members to create namespaces they cannot create - #2983

Merged
freeqaz merged 4 commits into
mainfrom
fix-2059
Oct 20, 2026
Merged

freeqaz merged 4 commits into
mainfrom
fix-2059

Conversation

@freeqaz

@freeqaz freeqaz commented Oct 20, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

Dogfood D654 (board finding 2059, medium): a member with no Namespace-create right opens Namespaces and sees a filled Create Namespace button and an empty state that says "Create a Namespace to get started". The 403 arrives only after she types a name and submits. After she closes the refused form, the page still offers the same button.

The API has no advisory Installation-scope permission answer (unlike GET /namespaces/{id}/permissions for Agent create), so the console cannot know in advance whether a non-administrator holds a Namespace create grant.

Change

Uses only signals the console already has. No API or IAM change.

  • Not an Installation administrator (the existing /observability access probe answered 403): Create Namespace is a secondary button instead of the filled primary, and the empty state says "Ask an administrator for access to an existing Namespace, or create one if your role allows it." The button stays usable, because a role can grant Namespace creation without Installation administration (the create-only creator path from fix(console): check namespace names at the field and keep focus after creation #2969 still works).
  • The API refused this person's create (403): after the form closes, Create Namespace is disabled and described by "Your access does not include creating Namespaces in this Installation.", focus moves to that sentence (the opener is now disabled), and the empty state says "Ask an administrator to create a Namespace or grant access to an existing one." This is kept in memory for the same session owner; Refresh keeps it and a browser reload asks the API again.
  • Administrators and unknown probe answers: unchanged (primary button, current copy).
  • Storybook: Pages/Namespaces → Empty for a member and Create refused, then closed; the namespace-create workflow and the console guide name both states.

The server part (an Installation-scope advisory permissions read, so the console can gate creation exactly before any attempt) is filed as a follow-up board finding instead of changed here.

Verification

Screenshots (real controller + IAM fixture, member without grants and administrator)

State Before 1440 After 1440 Before 390 After 390
Member, no Namespaces
Member, after the 403 and Cancel
Administrator (unchanged)

Storybook: Pages/Namespaces → Empty for a member, Create refused, then closed.

Risks

  • A non-administrator who does hold a Namespace create grant now sees a secondary button and slightly longer empty-state copy; creation itself is unchanged.
  • The refusal memory is per page load and per session owner; a grant added mid-session takes effect after a browser reload, as the guide says.

…create

A person who does not administer the Installation got a filled Create
Namespace button and an empty state inviting creation; the 403 came only
after submit (finding 2059, dogfood D654). The API has no advisory
Installation permission answer, so the console now uses the signals it
already has: the Installation-access probe makes Create Namespace a
secondary action with ask-an-administrator copy for non-administrators
(a role may still grant creation), and a real 403 disables the button
with its reason until the page reloads.
@freeqaz
freeqaz requested a review from a team as a code owner October 20, 2026 01:02
@clawsweeper

clawsweeper Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

ClawSweeper review complete

ClawSweeper finished reviewing this revision. The review result is being finalized.

View the workflow run.

Review follow-up for #2983: the refusal sentence is a status only when it
answers the attempt just closed, not on every later render; the test now
proves Refresh rerendered (a second list read, a new node) and covers
Escape after a refusal on a reloaded page; the guide's wording says a
non-administrator needs a role that grants creation.
@clawsweeper clawsweeper Bot added the clawsweeper:intake:bug Preliminary submission classification; full source review pending. label Oct 20, 2026
@clawsweeper clawsweeper Bot added clawsweeper:intake:needs-environment Preliminary submission classification; full source review pending. P2 Normal priority bug or improvement with limited blast radius. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed clawsweeper:intake:bug Preliminary submission classification; full source review pending. clawsweeper:intake:needs-environment Preliminary submission classification; full source review pending. labels Oct 20, 2026
@clawsweeper

clawsweeper Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge.

What this changes

This PR reduces creation prompts for non-administrators and disables Namespace creation after an actual permission denial until browser reload.

Example: A member without create permission submits the Namespace name “Support” and closes the refused form.

  • Before: The page continues offering an enabled Create Namespace button.
  • After: The button is disabled, explains the refusal, and moves focus to that explanation.

Review scores

Measure Result What it means
Overall readiness 🦪 silver shellfish (2/6) The focused patch has meaningful integration coverage and no identified defects, but visual proof does not meet the repository gate.
Proof confidence 🦪 silver shellfish (2/6) Real behavior proof is not required for maintainer- or bot-authored pull requests.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Product

Kind: Bug fix · Worth it: Yes · Fix scope: Complete
User problem: Members are encouraged to submit Namespace creation requests that their permissions reject, then receive the same invitation again.
Reason: The collaborator-authored direction reduces misleading prompts while explicitly preserving delegated creation and accepting reload-based recovery.

Merge readiness

✅ Ready for maintainer review

Keep this PR open: it addresses misleading Namespace creation prompts that remain on current main, and no actionable code defects were found.

Priority: P2
Reviewed head: 96db769bb1fe88a9cd93535c5fd1c35d4239cd1a

Before merge

None.

Findings

None.

Tests

  • Missing end-to-end proof: Supply the required short UI walkthrough showing denial, dismissal, disabled creation, and reload recovery, with screenshots and video attached natively to GitHub.
Agent review details

How this fits together

The console renders Namespaces from authenticated API responses; creation passes through the existing controller, IAM authorization, storage, and audit path.

flowchart TB
  A[Signed-in member] --> B[Namespaces console]
  B --> C[Namespace API]
  C --> D[Controller and IAM]
  D -->|Authorized| E[Namespace storage and audit]
  D -->|403 denial| F[Console refusal state]
Loading

Technical review

Best possible solution:

Retain the focused console repair and existing server authorization boundary.

Do we have a high-confidence way to reproduce the issue?

Current-main source shows the unconditional primary creation prompt and no retained denial; supplied before screenshots corroborate it, and the author reports base-failing browser regressions.

Is this the best way to solve the issue?

This is a focused repair using existing signals, preserves create-only roles, and avoids treating Installation administration as an exact create-permission answer.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning medium; reviewed against 4ebee7b51f50.

Provenance checked

Testing

Proof path: shipped entry point.

Security

None.

Evidence

What I checked:

  • Introduced change: The pinned diff changes console presentation and remembers an actual 403 for the current operator without changing API or IAM contracts. (apps/controller/src/console/namespaces.mjs:35, 96db769bb1fe)
  • Current-main behavior: Current main still renders the primary creation button and invitation without retaining a creation denial. (apps/controller/src/console/namespaces.mjs:30, 4ebee7b51f50)
  • Backend authorization remains authoritative: createNamespace authorizes the principal before creating storage state; the API retains transactional mutation auditing. (packages/occ/src/index.ts:4065, 96db769bb1fe)
  • Meaningful browser coverage: The extended browser tests cover administrator emphasis, successful create-only access, real IAM denial, dismissal focus, Refresh retention, reload recovery, absent denied writes, and denial auditing through the production Fastify application with in-memory storage. (tests/browser/console-namespace-create.test.mjs:308, 96db769bb1fe)
  • Visual evidence and repository gate: Inspected the four prepared desktop/mobile before-and-after screenshots, which show the changed member action and copy. The full body supplies Gist screenshots but no walkthrough video or native GitHub media attachments, both required by repository policy. Additional image inspection was limited by a read-only scratch mount and an inaccessible image URL. (AGENTS.md:460, 96db769bb1fe)
  • Previous review resolved: The flow now describes refusal-specific dismissal, and exact-head Static Checks passed, including documentation checks and build; the earlier documentation failure needs no further action. (docs/flows/platform-console.md:190, 96db769bb1fe)

Likely related people:

  • Derek Carr: Raw commit 5a2cb36 adds apps/controller/src/console/namespaces.mjs:3 relative to its recorded parents. This identifies author metadata, not feature responsibility or a PR merger. (role: source-line author; confidence: high; commits: 5a2cb363d5b2; files: apps/controller/src/console/namespaces.mjs)
  • Free Wortley: Raw commit 4671b2f adds apps/controller/src/console/namespaces.mjs:16 relative to its recorded parents. This identifies author metadata, not feature responsibility or a PR merger. (role: source-line author; confidence: high; commits: 4671b2f58f61; files: apps/controller/src/console/namespaces.mjs)

Labels

Label changes:

  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR.
  • remove status: ⏳ waiting on author: Current PR status label is status: 👀 ready for maintainer look.

Label justifications:

  • P2: Misleading creation prompts cause avoidable failed attempts while the backend correctly enforces permissions.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR.

Rank-up moves

Optional improvements that raise the rating; they are not merge blockers.

  • Attach native GitHub screenshots and a short recording of the changed refusal-and-recovery interaction.

Rating scale

6/6 🦀 challenger crab · 5/6 🦞 diamond lobster · 4/6 🐚 platinum hermit · 3/6 🦐 gold shrimp · 2/6 🦪 silver shellfish · 1/6 🧂 unranked krab. Overall follows the weaker of proof and patch quality; ✨ marks media proof (a screenshot, video, or linked artifact) that directly shows the changed behavior.

Workflow

ClawSweeper edits this one comment on every review. Comment @clawsweeper re-review for a fresh review only. Repair and merge execution lanes are retired.

History

Review history (2 earlier review cycles)
  • reviewed 2026-10-20T01:36:58.679Z sha a076198 :: needs changes before merge. :: [P3] Update the console flow for denial-specific dismissal
  • reviewed 2026-10-20T02:06:06.255Z sha 0f48233 :: needs changes before merge. :: none

Reviewed October 19, 2026, 10:53 PM ET / October 20, 2026, 02:53 UTC (Revision 3).

@freeqaz

freeqaz commented Oct 20, 2026

Copy link
Copy Markdown
Collaborator Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

🦞👀
Exact review queued.

Re-review progress:

@clawsweeper clawsweeper Bot added clawsweeper:intake:bug Preliminary submission classification; full source review pending. clawsweeper:intake:needs-environment Preliminary submission classification; full source review pending. and removed clawsweeper:intake:bug Preliminary submission classification; full source review pending. clawsweeper:intake:needs-environment Preliminary submission classification; full source review pending. labels Oct 20, 2026
The 403 sentence pushed platform-console.md past the 2,500-word docs
check. Say it in fewer words and tighten the /backends sentence beside it.
@freeqaz

freeqaz commented Oct 20, 2026

Copy link
Copy Markdown
Collaborator Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

🦞👀
Exact review queued.

Re-review progress:

@clawsweeper clawsweeper Bot added clawsweeper:intake:bug Preliminary submission classification; full source review pending. clawsweeper:intake:needs-environment Preliminary submission classification; full source review pending. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. clawsweeper:intake:bug Preliminary submission classification; full source review pending. clawsweeper:intake:needs-environment Preliminary submission classification; full source review pending. labels Oct 20, 2026
@freeqaz
freeqaz merged commit 9ab26af into main Oct 20, 2026
66 checks passed
@freeqaz
freeqaz deleted the fix-2059 branch October 20, 2026 03:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P2 Normal priority bug or improvement with limited blast radius. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant