DUNIN7 · LOOMWORKS · RECORD
record.dunin7.com
Status Current
Path scoping-notes/loomworks-session-scoped-list-refusal-scoping-note-stub-v0_1.md

Loomworks — session-scoped list routes: refuse or answer empty? — scoping-note stub — v0.1

Version. 0.1 Date. 2026-07-18 Author. Claude Code on DUNIN7-M4, on Operator direction. Status. STUB. Deferred out of perimeter Stage 1 to its own scoping. No change was made in that build. Origin. Surfaced during Stage 1 Step 2 verification; carried through the Step 6 authorization design; deferred by Operator ruling 2026-07-18.


Plain-language summary

GET /engagements answers an unauthenticated request with HTTP 200 and an empty list, not 401. No data leaks — the route scopes by session, so an anonymous caller's scope is genuinely empty. The question is whether an empty answer is the right shape of answer, or whether a caller with no session should be told so.

This is a product decision about API shape. It is not a security hole in either form, which is why it was deferred rather than fixed in flight.

How it surfaced

While verifying the production /api/* proxy in Stage 1 Step 2, /api/engagements was used as a test target and returned 200 {"total_count":0,...,"engagements":[]} with no session. That made it unusable as a demonstration of Stage 1 section 9 item 4 ("an unauthenticated request to a protected surface is refused") — the refusal check was moved to a founder-gated /admin/grants route instead, which demonstrates it cleanly.

So Stage 1 was unblocked. The underlying question was left standing.

The case for leaving it as-is

The case for changing it to 401

What a real scoping would have to settle

  1. Which routes are in scope. /engagements is the one observed; the same shape likely exists on other session-scoped list routes. The sweep is part of the work, not a precondition to it.
  2. The frontend's empty-state handling, considered alongside the change rather than after it. If the client currently treats empty-list as a legitimate render, flipping to 401 changes what it must handle — and doing that unilaterally on the server is how an empty dashboard becomes a redirect loop.
  3. Whether the answer differs for "no session" versus "valid session, no rows." These are the two cases the current behavior conflates, and any fix has to keep the second one answering 200 with an empty list.

Explicitly not decided here

Nothing. This stub records both sides and the reasons for deferring; it does not lean toward either outcome. It exists so the question is not silently lost between Stage 1 and whatever build picks it up.


DUNIN7 — Done In Seven LLC — Miami, Florida Loomworks — session-scoped list refusal — scoping-note stub — v0_1 — 2026-07-18