Kotte Regression Report For Blackcurrant 1.0.0
=============================================

Summary
-------

After upgrading Kotte from `@mika/blackcurrant 0.3.5` to `1.0.0`, we observed a new user-visible regression:

- after logout, the app could show a global error banner with the message:
  `Authentication required.`

This behavior was not present in Kotte before the `1.0.0` upgrade.


Observed Product Impact In Kotte
--------------------------------

Kotte has several private stores with eager `initialRequest: {}` initialization, for example:

- `public/stores/users.js`
- `public/stores/groups.js`
- `public/stores/memberships.js`
- `public/stores/rules.js`
- `public/stores/skips.js`
- `public/stores/images.js`
- `public/stores/versions.js`

In Kotte, these stores route their errors to the app-global error surface.

Relevant call shape:

- store files use `onError(...) => reportGlobalError(...)`
- Kotte global error surface is in `public/error-manager.js`

The user-visible regression in Kotte was:

1. user logs out normally
2. app transitions into expected logged-out state
3. one or more eager private stores re-run fulfillment with their existing request
4. Blackcurrant emits `ERR_AUTH_REQUIRED`
5. Kotte displays that as a visible global error

This was a regression because intentional logout is not an error case in the Kotte product.


Why We Think This Comes From Blackcurrant 1.0.0
-----------------------------------------------

The relevant behavior is in `store.js` from Blackcurrant `1.0.0`.

Key lines from Kotte-installed package:

- `store.request = initialRequest` if `initialRequest !== null`
- `communication.onStart(handleStart)`
- `handleStart()` calls `fulfill(store.request)` when a request exists
- `fulfill(...)` now emits `ERR_AUTH_REQUIRED` when a private store has no scope

Installed package references from Kotte:

- `node_modules/@mika/blackcurrant/store.js:111-113`
- `node_modules/@mika/blackcurrant/store.js:136-139`
- `node_modules/@mika/blackcurrant/store.js:191-205`

Quoted behavior from those lines:

- eager request initialization persists for private stores
- on start, the store fulfills again if it has a request
- if `currentScope()` is absent, private store calls:
  `onError(errorWithCode("Authentication required.", "ERR_AUTH_REQUIRED"))`

This means that after logout, or any other expected no-auth steady state, a private store with an existing request can emit an auth error even though the app is not in an exceptional auth-failure condition.


Kotte Evidence
--------------

1. Kotte private stores are eagerly requested.

Relevant examples:

- `public/stores/users.js:6-15`
- `public/stores/groups.js:25-34`
- `public/stores/memberships.js:43-52`
- `public/stores/rules.js:62-72`
- `public/stores/skips.js:81-98`
- `public/stores/images.js:107-116`
- `public/stores/versions.js:125-134`

Each of these uses `initialRequest: {}` and forwards errors to the global error surface.

2. Kotte global errors are user-visible.

Relevant file:

- `public/error-manager.js`

This component displays incoming errors to the user. During the migration, we had to suppress:

- `ERR_AUTH_REQUIRED`
- `Authentication required.`

to restore Kotte's pre-upgrade behavior.

3. The regression only appeared after the Blackcurrant `1.0.0` upgrade.

Before the upgrade, Kotte did not show this banner during normal logout.


Why This Looks Like An Upstream Design Issue
--------------------------------------------

From the Kotte side, the stores are behaving the same way they already did before:

- they remain instantiated
- they keep their private request
- they react to runtime lifecycle events

What changed is that Blackcurrant `1.0.0` now treats "private store still has a request, but auth is absent" as an error condition rather than an expected steady state.

For Kotte, that distinction matters:

- intentional logout is expected product behavior
- logged-out startup is expected product behavior
- transient no-auth state after logout is expected product behavior

In all of those cases, the app should not receive an error that is naturally rendered as a user-facing failure.


Likely Root Cause
-----------------

The root issue is not only that the error is visible in Kotte.

The deeper issue is:

- Blackcurrant continues to call `fulfill(...)` for private stores that still have a request
- `fulfill(...)` emits `ERR_AUTH_REQUIRED` whenever auth is absent
- this happens even during expected logged-out operation, not just actual auth failures

In other words, Blackcurrant is not distinguishing between:

- expected no-auth steady state
- actual auth error/problem


What Kotte Had To Do
--------------------

To keep Kotte behavior unchanged during the migration, we added app-side suppression for:

- `ERR_AUTH_REQUIRED`
- `Authentication required.`

in `public/error-manager.js`.

This restored the old user-visible behavior, but it feels like mitigation rather than a true root-cause fix.


Suggested Upstream Investigation
--------------------------------

Please review whether private stores should emit `ERR_AUTH_REQUIRED` during:

- intentional logout
- logged-out startup
- other expected no-auth steady states

The likely better upstream behavior would be one of:

1. Treat missing auth for a private store with an existing request as a suspended state, not an error, during expected logged-out operation.
2. Avoid calling `onError(ERR_AUTH_REQUIRED)` during normal logout/no-auth transitions.
3. Provide a first-class private-store suspension/clear mechanism so expected auth loss does not look like an auth failure.


Notes
-----

- This report is based on the behavior observed while migrating Kotte to Blackcurrant `1.0.0`.
- Kotte kept all stores private; no public-store migration behavior was involved in this specific regression.
- The user-visible regression was confirmed during the Kotte upgrade work and required an app-level compatibility patch.
