Phase 2B.2 of the convention pass. Closes the inconsistency where
arts/aapp used APP_* prefix while libs/aapp already used AAPP_*.
After this commit every constant under arts/aapp and libs/aapp uses
the canonical 4-letter alias `AAPP_` (rule 1 of docs/conventions.md).
Constants renamed (~24 total):
- APP_EVENT_* → AAPP_EVENT_* (the 6 public events)
- APP_USER_IDENTITY_CAUSE_* → AAPP_USER_IDENTITY_CAUSE_*
- APP_ORCHESTRATION_* → AAPP_ORCHESTRATION_*
- APP_ERROR_* → AAPP_ERROR_*
- APP_LOG_MSG_* → AAPP_LOG_MSG_*
- APP_CONNECTION_CLOSE_REASON_* → AAPP_CONNECTION_CLOSE_REASON_*
- APP_EVENT_RUNTIMES → AAPP_EVENT_RUNTIMES
Wire-format change for the public app event values:
- 'app.user.identity.changed' → 'aapp.user.identity.changed'
- 'app.tenant.switched' → 'aapp.tenant.switched'
- 'app.permissions.refresh.requested'→ 'aapp.permissions.refresh.requested'
- 'app.connectivity.changed' → 'aapp.connectivity.changed'
- 'app.cache.invalidate.requested' → 'aapp.cache.invalidate.requested'
- 'app.dispose.starting' → 'aapp.dispose.starting'
Per docs/conventions.md rule 5, every event-identifier string value
must start with the module's 4-letter alias. Now that AAPP_MODULE = 'aapp'
(set in phase 2B.1) is the canonical module identifier, the event
scope follows. External observers of these events must update string
filters from `app.*` to `aapp.*`. The framework has not been tagged 0.1
yet so the wire format is still in flight.
Translation keys (`'app.title'`, `'app.cart'`, `'app.boot'`, etc. used
by `App.Lang.t(...)` in the demo / ecosystem test pages) are NOT
events and were intentionally left untouched — they're paths in the
lang schema, independent of the AAPP module identity.
Verification: svelte-check 1395 / 0 errors. Server 1230 tests, client
19 tests — all green.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ -1826,9 +1826,9 @@ export function createEngineSession(options: EngineSessionOptions) {
{
title:'App.Event Contract',
body:[
'Stable public app events live in $libs/aapp/events, not inside individual artifacts. Examples are APP_EVENT_USER_IDENTITY_CHANGED, APP_EVENT_TENANT_SWITCHED, APP_EVENT_PERMISSIONS_REFRESH_REQUESTED, APP_EVENT_CONNECTIVITY_CHANGED, APP_EVENT_CACHE_INVALIDATE_REQUESTED and APP_EVENT_DISPOSE_STARTING.',
'Event constants are mandatory, and app events should normally flow through onApp* / publishApp* helpers. Those helpers keep payload typing, runtime guards and unsafe-payload checks in one place. Raw bus.on(APP_EVENT_...) is acceptable for low-level tests; raw bus.publish("app...") is not application code.',
'The string value stays lowercase scoped; the exported symbol is uppercase snake. Current built-in translators publish APP_EVENT_USER_IDENTITY_CHANGED from SESS_EVENT_CHANGED and APP_EVENT_DISPOSE_STARTING during App.dispose(). The other app events are stable contract points for explicit app code and future translators.'
'Stable public app events live in $libs/aapp/events, not inside individual artifacts. Examples are AAPP_EVENT_USER_IDENTITY_CHANGED, AAPP_EVENT_TENANT_SWITCHED, AAPP_EVENT_PERMISSIONS_REFRESH_REQUESTED, AAPP_EVENT_CONNECTIVITY_CHANGED, AAPP_EVENT_CACHE_INVALIDATE_REQUESTED and AAPP_EVENT_DISPOSE_STARTING.',
'Event constants are mandatory, and app events should normally flow through onApp* / publishApp* helpers. Those helpers keep payload typing, runtime guards and unsafe-payload checks in one place. Raw bus.on(AAPP_EVENT_...) is acceptable for low-level tests; raw bus.publish("app...") is not application code.',
'The string value stays lowercase scoped; the exported symbol is uppercase snake. Current built-in translators publish AAPP_EVENT_USER_IDENTITY_CHANGED from SESS_EVENT_CHANGED and AAPP_EVENT_DISPOSE_STARTING during App.dispose(). The other app events are stable contract points for explicit app code and future translators.'
]
},
{
@ -1873,7 +1873,7 @@ export function createEngineSession(options: EngineSessionOptions) {
{
name:'orchestration: standard',
purpose:'Enables the App translator.',
notes:'Session changes can become APP_EVENT_USER_IDENTITY_CHANGED.'
notes:'Session changes can become AAPP_EVENT_USER_IDENTITY_CHANGED.'
'When Session is created through App, App injects App.Bus. Session publishes safe sess.* events after state has been updated; aapp can translate SESS_EVENT_CHANGED into APP_EVENT_USER_IDENTITY_CHANGED.',
'When Session is created through App, App injects App.Bus. Session publishes safe sess.* events after state has been updated; aapp can translate SESS_EVENT_CHANGED into AAPP_EVENT_USER_IDENTITY_CHANGED.',
'Cache, Permissions and Connections do not listen to sess.* directly. They react only to public app.* events and only when their own autoInvalidateOn or autoReauthOn option opts in.'
'ActivePermissions can subscribe to public app.* events when App injects App.Bus. The default is safe: no automatic invalidation happens unless autoInvalidateOn is configured.',
"autoInvalidateOn: 'standard' currently invalidates the local decision cache on APP_EVENT_USER_IDENTITY_CHANGED, APP_EVENT_PERMISSIONS_REFRESH_REQUESTED and APP_EVENT_TENANT_SWITCHED.",
"autoInvalidateOn: 'standard' currently invalidates the local decision cache on AAPP_EVENT_USER_IDENTITY_CHANGED, AAPP_EVENT_PERMISSIONS_REFRESH_REQUESTED and AAPP_EVENT_TENANT_SWITCHED.",
'Permissions does not listen to sess.*, auth internals or cache internals directly. The public bus contract keeps the client reflector decoupled from the source of the identity or policy change.'
'App injects App.Bus into App.Cache. By default Cache only observes its own cache events; it does not clear when the app publishes identity or tenant facts.',
"Set cache.autoInvalidateOn: 'standard' to clear the active cache on APP_EVENT_USER_IDENTITY_CHANGED and APP_EVENT_TENANT_SWITCHED. Use a list such as ['userIdentityChange'] for narrower behavior.",
"Set cache.autoInvalidateOn: 'standard' to clear the active cache on AAPP_EVENT_USER_IDENTITY_CHANGED and AAPP_EVENT_TENANT_SWITCHED. Use a list such as ['userIdentityChange'] for narrower behavior.",
'Cache listens only to public app.* events. It should not import sess, auth or perm internals to decide when private data becomes unsafe.'
],
code:{
@ -3915,7 +3915,7 @@ await Chat.connect();`
{
title:'App.Bus Reauth Source',
body:[
'If autoReauthOn is enabled in the registry, Connections derives a ConnectionSessionSource from APP_EVENT_USER_IDENTITY_CHANGED. It does not listen to sess.* directly and does not import auth, perm or cache internals.',
'If autoReauthOn is enabled in the registry, Connections derives a ConnectionSessionSource from AAPP_EVENT_USER_IDENTITY_CHANGED. It does not listen to sess.* directly and does not import auth, perm or cache internals.',
'Each connection still decides whether to react through its own session option. Reauthentication additionally requires an auth provider; without auth there is no credential payload to send, so the connection can only be observed or manually handled.'