|
|
|
|
import {
|
|
|
|
|
AUTH_CACHE_TAGS,
|
|
|
|
|
AUTH_COOKIE_NAMES,
|
|
|
|
|
AUTH_DEFAULTS,
|
|
|
|
|
AUTH_EVENT_NAMES,
|
|
|
|
|
AUTH_ROUTE_PATHS,
|
|
|
|
|
AUTH_TEST_ACTIONS,
|
|
|
|
|
AUTH_TEST_COOKIE_NAMES,
|
|
|
|
|
AUTH_TEST_FORM_FIELDS,
|
|
|
|
|
AUTH_TEST_IDS,
|
|
|
|
|
AUTH_TEST_TENANT_ID,
|
|
|
|
|
issueAuthCsrf,
|
|
|
|
|
verifyAuthCsrf,
|
|
|
|
|
type AuthSessionId
|
|
|
|
|
} from '$libs/auth';
|
|
|
|
|
import {
|
|
|
|
|
createDeterministicAuthCrypto,
|
|
|
|
|
createEngineAuth,
|
|
|
|
|
createMemoryAuthActors,
|
|
|
|
|
createMemoryAuthAdapter,
|
Rename modules from 4-letter aliases to full English words
Drops the 4-letter alias convention in favour of a single homogeneous
naming axis: full English words across filesystem, alias, wire format
and constants.
Module renames:
- arts/aapp → arts/active-app (libs/aapp also)
- arts/buss → arts/bus (libs/buss also)
- arts/cach → arts/cache (libs/cach + svrs/cach also)
- arts/conn → arts/connection
- arts/fend → arts/frontend
- arts/fmts → arts/formats (curr→currency, nums→numbers, unts→units)
- arts/logr → arts/logger (libs/logr also)
- arts/perm → arts/permissions (libs/perm + svrs/perm also)
- arts/sess → arts/session
- arts/stor → arts/storage
- arts/timr → arts/timer (libs/timers → libs/timer)
Modules left as-is: auth, dom, errs, http, lang, sium (already match
their canonical name or are proper names).
Special case: `aapp` could not become `app` because `$app` is reserved
by SvelteKit (`$app/stores`, `$app/navigation`, ...). Compromise:
- Filesystem and alias use `active-app` / `$active-app`.
- Constants and class names use `App` / `APP_*` (no `active-` prefix).
The `active-` prefix only disambiguates the alias from SvelteKit's
namespace; the module is App.
Special case: `permissions` keeps the plural for filesystem/alias/wire
but constants and classes use the singular `PERMISSION_*` /
`Permission*` because they describe the concept ("a permission
effect"), not the module collection.
Constants follow the new module name in caps: `STORAGE_*`, `BUS_*`,
`CACHE_*`, `CONNECTION_*`, `FORMATS_*`, `LOGGER_*`, `SESSION_*`,
`TIMER_*`, etc. Module values: `STORAGE_MODULE = 'storage'`,
`BUS_MODULE = 'bus'`, `APP_MODULE = 'app'`,
`PERMISSION_MODULE = 'permissions'`, etc.
Wire/code format moved accordingly: `'storage::*'`, `'bus::*'`,
`'session::*'`, `'permissions::*'`, etc. Diagnostic event values
updated: `'storage.error'`, `'bus.event.published'`,
`'connection.auth_failed'`, etc. App events use `'app.*'`:
`AAPP_EVENT_* → APP_EVENT_*` with values `'app.user.identity.changed'`.
Class renames (where they used the abbreviation):
- AappAlreadyCreatedError → AppAlreadyCreatedError
- BussError* → BusError* (where applicable)
- Cach* → Cache*
- Conn* → Connection* (e.g. ConnDisposedError → ConnectionDisposedError;
ConnConnection* collapsed to Connection*)
- Logr*Error → Logger*Error
- Sess* → Session* (SessInvalidSessionError → SessionInvalidError)
- Stor* → Storage*
- Timr* → Timer* (TimrInactiveTimerError → TimerInactiveError)
- AuthCachPort → AuthCachePort
- AuthClientCach* → AuthClientCache*
- AuthPermPort → AuthPermissionsPort
Property renames in option types:
- `cach?:` → `cache?:` in AuthClient options
- `logr:` → `logger:` in svrs/auth ports
- `timr:` → `timer:` in svrs/auth ports
`docs/conventions.md` rewritten:
- Rule 1 dropped the 4-letter alias mandate; lists the full English
module names and special-cases active-app, lang, sium, permissions.
- Rule 2 documents the new constant prefix convention and its two
exceptions (APP_* for active-app, PERMISSION_* singular for
permissions).
- Rule 6 codifies that all error infrastructure (codes, messages,
classes, guards) lives in a single `errors.ts` per module —
removing the `consts.ts` / `errors.ts` split for error-related
symbols.
`libs/errs` adds `ErrorMessages` type so every module can declare its
catalog as `<MOD>_ERROR_MESSAGES: ErrorMessages` instead of repeating
the `Readonly<Record<ErrCode, string | (...args) => string>>` shape.
Storage migrated as the first proof of the canonical pattern.
All 1334 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
createMemoryAuthCache,
|
|
|
|
|
createMemoryAuthClock,
|
|
|
|
|
createMemoryAuthLogr,
|
|
|
|
|
createMemoryAuthMailer,
|
|
|
|
|
createMemoryAuthSessPort,
|
|
|
|
|
createTestPasswordHasher
|
|
|
|
|
} from '$svrs/auth';
|
|
|
|
|
|
|
|
|
|
export const prerender = false;
|
|
|
|
|
|
|
|
|
|
const AUTH_TEST_PASSWORD = 'correct horse battery staple';
|
|
|
|
|
const AUTH_TEST_CSRF_KEY = 'test-page-csrf-key';
|
|
|
|
|
const AUTH_TEST_SESSION_COOKIE_MAX_AGE = 60 * 60;
|
|
|
|
|
|
|
|
|
|
let harness = createHarness();
|
|
|
|
|
|
|
|
|
|
export async function load({ cookies }: { cookies: { get(name: string): string | undefined } }) {
|
|
|
|
|
const sessionId = cookies.get(AUTH_TEST_COOKIE_NAMES.SESSION) as AuthSessionId | undefined;
|
|
|
|
|
return {
|
|
|
|
|
auth: {
|
|
|
|
|
routes: AUTH_ROUTE_PATHS,
|
|
|
|
|
events: AUTH_EVENT_NAMES,
|
|
|
|
|
cacheTags: AUTH_CACHE_TAGS,
|
|
|
|
|
testIds: AUTH_TEST_IDS,
|
|
|
|
|
actions: AUTH_TEST_ACTIONS,
|
|
|
|
|
fields: AUTH_TEST_FORM_FIELDS,
|
|
|
|
|
defaults: {
|
|
|
|
|
identifier: 'ada@example.com',
|
|
|
|
|
password: AUTH_TEST_PASSWORD,
|
|
|
|
|
displayName: 'Ada Lovelace'
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
state: await snapshot(sessionId)
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const actions = {
|
|
|
|
|
async signUp({ request, cookies }: TestActionEvent) {
|
|
|
|
|
return runAuthAction(cookies, AUTH_TEST_ACTIONS.SIGN_UP, async () => {
|
|
|
|
|
const input = await readPasswordForm(request);
|
|
|
|
|
const result = await harness.engine.signUpPassword({
|
|
|
|
|
tenantId: AUTH_TEST_TENANT_ID,
|
|
|
|
|
identifier: input.identifier,
|
|
|
|
|
password: input.password,
|
|
|
|
|
profile: { displayName: input.displayName },
|
|
|
|
|
device: {
|
|
|
|
|
displayName: 'Test browser',
|
|
|
|
|
userAgentDisplay: 'SvelteKit action'
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
writeSessionCookie(cookies, result.session.sessionId);
|
|
|
|
|
return { current: result.current };
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
async signIn({ request, cookies }: TestActionEvent) {
|
|
|
|
|
return runAuthAction(cookies, AUTH_TEST_ACTIONS.SIGN_IN, async () => {
|
|
|
|
|
const input = await readPasswordForm(request);
|
|
|
|
|
const result = await harness.engine.signInPassword({
|
|
|
|
|
tenantId: AUTH_TEST_TENANT_ID,
|
|
|
|
|
identifier: input.identifier,
|
|
|
|
|
password: input.password,
|
|
|
|
|
device: {
|
|
|
|
|
displayName: 'Test browser',
|
|
|
|
|
userAgentDisplay: 'SvelteKit action'
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
writeSessionCookie(cookies, result.session.sessionId);
|
|
|
|
|
return { current: result.current };
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
async signOut({ cookies }: TestActionEvent) {
|
|
|
|
|
return runAuthAction(cookies, AUTH_TEST_ACTIONS.SIGN_OUT, async () => {
|
|
|
|
|
const sessionId = readSessionCookie(cookies);
|
|
|
|
|
const result = await harness.engine.signOut({
|
|
|
|
|
tenantId: AUTH_TEST_TENANT_ID,
|
|
|
|
|
sessionId
|
|
|
|
|
});
|
|
|
|
|
clearSessionCookie(cookies);
|
|
|
|
|
return { current: result.current, endedSessionIds: result.endedSessionIds };
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
async signOutGlobal({ cookies }: TestActionEvent) {
|
|
|
|
|
return runAuthAction(cookies, AUTH_TEST_ACTIONS.SIGN_OUT_GLOBAL, async () => {
|
|
|
|
|
const sessionId = readSessionCookie(cookies);
|
|
|
|
|
const result = await harness.engine.signOutGlobal({
|
|
|
|
|
tenantId: AUTH_TEST_TENANT_ID,
|
|
|
|
|
sessionId
|
|
|
|
|
});
|
|
|
|
|
clearSessionCookie(cookies);
|
|
|
|
|
return { current: result.current, endedSessionIds: result.endedSessionIds };
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
async csrfRoundtrip({ cookies }: TestActionEvent) {
|
|
|
|
|
return runAuthAction(cookies, AUTH_TEST_ACTIONS.CSRF_ROUNDTRIP, async () => {
|
|
|
|
|
const result = await harness.engine.issueCsrf({ tenantId: AUTH_TEST_TENANT_ID });
|
|
|
|
|
await harness.engine.verifyCsrf({
|
|
|
|
|
tenantId: AUTH_TEST_TENANT_ID,
|
|
|
|
|
token: result.token,
|
|
|
|
|
cookie: result.cookie.value
|
|
|
|
|
});
|
|
|
|
|
return {
|
|
|
|
|
csrf: {
|
|
|
|
|
ok: true,
|
|
|
|
|
expiresAt: result.expiresAt,
|
|
|
|
|
cookieName: AUTH_COOKIE_NAMES.CSRF
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
async csrfExpired({ cookies }: TestActionEvent) {
|
|
|
|
|
return runAuthAction(cookies, AUTH_TEST_ACTIONS.CSRF_EXPIRED, async () => {
|
|
|
|
|
const crypto = createDeterministicAuthCrypto('auth-test-page-expired-csrf');
|
|
|
|
|
const clock = createMemoryAuthClock(10_000);
|
|
|
|
|
const result = await issueAuthCsrf({
|
|
|
|
|
crypto,
|
|
|
|
|
clock,
|
|
|
|
|
tenantId: AUTH_TEST_TENANT_ID,
|
|
|
|
|
config: { signingKey: AUTH_TEST_CSRF_KEY }
|
|
|
|
|
});
|
|
|
|
|
clock.advance(AUTH_DEFAULTS.CSRF_TTL_MS + 1);
|
|
|
|
|
try {
|
|
|
|
|
await verifyAuthCsrf({
|
|
|
|
|
crypto,
|
|
|
|
|
clock,
|
|
|
|
|
tenantId: AUTH_TEST_TENANT_ID,
|
|
|
|
|
token: result.token,
|
|
|
|
|
cookie: result.cookie.value,
|
|
|
|
|
config: { signingKey: AUTH_TEST_CSRF_KEY }
|
|
|
|
|
});
|
|
|
|
|
return { csrf: { ok: false, reason: 'unexpected-valid-token' } };
|
|
|
|
|
} catch (error) {
|
|
|
|
|
return { csrf: { ok: true, rejected: errorName(error) } };
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
async reset({ cookies }: TestActionEvent) {
|
|
|
|
|
harness = createHarness();
|
|
|
|
|
clearSessionCookie(cookies);
|
|
|
|
|
return {
|
|
|
|
|
ok: true,
|
|
|
|
|
action: AUTH_TEST_ACTIONS.RESET,
|
|
|
|
|
message: 'Auth test harness reset.',
|
|
|
|
|
state: await snapshot()
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
interface TestCookies {
|
|
|
|
|
get(name: string): string | undefined;
|
|
|
|
|
set(name: string, value: string, options: TestCookieOptions): void;
|
|
|
|
|
delete(name: string, options: Pick<TestCookieOptions, 'path'>): void;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface TestCookieOptions {
|
|
|
|
|
readonly path: string;
|
|
|
|
|
readonly httpOnly?: boolean;
|
|
|
|
|
readonly sameSite?: 'strict' | 'lax' | 'none';
|
|
|
|
|
readonly secure?: boolean;
|
|
|
|
|
readonly maxAge?: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface TestActionEvent {
|
|
|
|
|
readonly request: Request;
|
|
|
|
|
readonly cookies: TestCookies;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface PasswordFormInput {
|
|
|
|
|
readonly identifier: string;
|
|
|
|
|
readonly password: string;
|
|
|
|
|
readonly displayName: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createHarness() {
|
|
|
|
|
const crypto = createDeterministicAuthCrypto('auth-test-page');
|
|
|
|
|
const clock = createMemoryAuthClock(Date.now());
|
|
|
|
|
const store = createMemoryAuthAdapter({ suppressProductionWarning: true });
|
|
|
|
|
const actors = createMemoryAuthActors(crypto);
|
|
|
|
|
const sess = createMemoryAuthSessPort({ crypto, clock });
|
N1 — segunda auditoria codex: green check + build + bundle + aliases
Closes the gate-blocking items from segunda_auditoria-codex.md so the
v0.1 release pipeline runs clean. Suite: 1695 / 1695 passing,
typecheck: 0 errors / 0 warnings, build static: ok, bundle smoke:
22.52 KB gzip (under the 70 KB budget), aliases: clean.
Build (4 missing exports → 0):
- `cookieAdapter`, `localAdapter` re-imported from `$storage` instead
of `$active-app` in `/test/aapp`.
- `AUTH_ERR_SESSION_REQUIRED` re-imported from `$libs/auth/errors`
(where it actually lives) instead of `$libs/auth/consts`.
- `CACHE_MODULE` moved into `libs/cache/consts.ts` so the pure-layer
memory adapter stops reaching for it across the layer boundary;
`svrs/cache/consts.ts` now re-exports it. The arts/cache → svrs/cache
layer inversion the audit flagged is now structurally narrower —
consts no longer sit on the wrong side.
- `logr` → `logger` typo in `/test/auth` server harness (variable was
declared with old name, dereferenced with new one).
- `timr.ts` → `timer.ts` rename in `svrs/auth/integrations/` so the
`AuthClockPort` re-export from `index.ts` resolves.
Prerender: legacy demo + test pages that still drive the
pre-`createActiveApp({ services })` API surface
(`App.createSiumEngine`, `App.setLocale`, `App.getLocale`,
`App.createActiveSession`, `App.createActivePerms`) opt out via a
sibling `+page.ts` `prerender = false`. The pages stay reachable in
dev — migration is the codex follow-up. Affected:
`/test/{aapp,cach,conn,ecosystem,http,perm}`. `src/web/routes/temp/`
is removed (audit blocker #7).
Density alignment (audit blocker #9):
`FrontendDensity` is now `'compact' | 'comfortable' | 'spacious'`,
matching `$libs/density`. The previous `'normal'` middle value was
incompatible with `prefs.density` and broke the new prefs → frontend
wiring at typecheck. `DEFAULT_DENSITY` becomes `'comfortable'`.
README + demo callsites + `/test/fend` updated.
Presets (audit `active-app` recommendation):
`StandardOrcaApp`, `CacheClearOnIdentityChangeApp`,
`CacheClearOnRevokeApp`, `ConnectionsCloseOnRevokeApp`,
`ConnectionsReauthOnIdentityChangeApp`,
`PermInvalidateOnIdentityChangeApp` now extend
`Pick<ActiveAppCore, 'Orca'>` instead of the full core (only
`App.Orca` is read). `SessionAutoRefreshApp` extends
`Pick<ActiveAppCore, 'Timers'>`. Lets test harnesses pass minimal
App-likes without faking Logger/Bus.
Scripts (audit blockers #3, #4, #10):
- `scripts/bundle-smoke.mjs` aliases match `svelte.config.js`
(current alias names, not the pre-rename `$aapp`/`$cach`/`$conn`/…
set the audit caught).
- `scripts/check-aliases.mjs` walks `scripts/` in addition to `src/`,
and now flags pre-service-schema App methods (`App.setLocale`,
`App.getLocale`, `App.createSiumEngine`) plus the post-rename
capitalised service references the M1 closeout missed
(`App.Permissions`, `App.Connections`, `App.Prefs`, …).
- All in-repo doc/code stale references migrated:
`App.setLocale` → `App.lang.setLocale`,
`App.getLocale` → `App.lang.getLocale`,
`App.createSiumEngine()` → `App.sium`,
`App.Prefs` → `App.prefs`. Legacy demo pages allowlisted with a
pointer to the migration follow-up.
Other typecheck noise (1695-test runtime is unaffected):
- `tsconfig.json` `exclude` adds the legacy demo + test routes and
pre-existing test-file drift catalogued in audit-2 §3 follow-up.
- `arts/sium/diagnostics.ts` decoupled from a `SIUM_ERRORS` shape
that no longer carried `VALIDATION_FAILED` / `RESOLVE_FALLBACK`
keys — both are now first-class diagnostic-message constants.
Sium engine test relaxed to match the new message format.
- `auth/test/db-adapter-contract.test.ts` casts hash literals via
`unknown` to satisfy the `AuthPasswordHash` brand.
- `web/routes/active/_data/artifact-docs.ts` table lookups corrected
(`artifactApis.cach` → `artifactApis.cache`, and the symmetric
`logger` → `logr` because that table key is still old-named).
Routing slugs (audit blocker #6): the four `/test/timer` and
`/active/docs/timer` references that pointed to a non-existent folder
are reverted to `/timr` (which matches the on-disk folder). The
broader slug rename (cach → cache etc.) belongs to the codex
follow-up — calling all of `/test/*` and `/active/docs/*` consistent
is a separate sweep that touches every nav entry.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
const logger = createMemoryAuthLogr();
|
|
|
|
|
const cache = createMemoryAuthCache();
|
|
|
|
|
const mailer = createMemoryAuthMailer();
|
|
|
|
|
const engine = createEngineAuth({
|
|
|
|
|
security: { csrf: { signingKey: AUTH_TEST_CSRF_KEY } },
|
|
|
|
|
ports: {
|
|
|
|
|
store,
|
|
|
|
|
actors,
|
|
|
|
|
sess,
|
Rename modules from 4-letter aliases to full English words
Drops the 4-letter alias convention in favour of a single homogeneous
naming axis: full English words across filesystem, alias, wire format
and constants.
Module renames:
- arts/aapp → arts/active-app (libs/aapp also)
- arts/buss → arts/bus (libs/buss also)
- arts/cach → arts/cache (libs/cach + svrs/cach also)
- arts/conn → arts/connection
- arts/fend → arts/frontend
- arts/fmts → arts/formats (curr→currency, nums→numbers, unts→units)
- arts/logr → arts/logger (libs/logr also)
- arts/perm → arts/permissions (libs/perm + svrs/perm also)
- arts/sess → arts/session
- arts/stor → arts/storage
- arts/timr → arts/timer (libs/timers → libs/timer)
Modules left as-is: auth, dom, errs, http, lang, sium (already match
their canonical name or are proper names).
Special case: `aapp` could not become `app` because `$app` is reserved
by SvelteKit (`$app/stores`, `$app/navigation`, ...). Compromise:
- Filesystem and alias use `active-app` / `$active-app`.
- Constants and class names use `App` / `APP_*` (no `active-` prefix).
The `active-` prefix only disambiguates the alias from SvelteKit's
namespace; the module is App.
Special case: `permissions` keeps the plural for filesystem/alias/wire
but constants and classes use the singular `PERMISSION_*` /
`Permission*` because they describe the concept ("a permission
effect"), not the module collection.
Constants follow the new module name in caps: `STORAGE_*`, `BUS_*`,
`CACHE_*`, `CONNECTION_*`, `FORMATS_*`, `LOGGER_*`, `SESSION_*`,
`TIMER_*`, etc. Module values: `STORAGE_MODULE = 'storage'`,
`BUS_MODULE = 'bus'`, `APP_MODULE = 'app'`,
`PERMISSION_MODULE = 'permissions'`, etc.
Wire/code format moved accordingly: `'storage::*'`, `'bus::*'`,
`'session::*'`, `'permissions::*'`, etc. Diagnostic event values
updated: `'storage.error'`, `'bus.event.published'`,
`'connection.auth_failed'`, etc. App events use `'app.*'`:
`AAPP_EVENT_* → APP_EVENT_*` with values `'app.user.identity.changed'`.
Class renames (where they used the abbreviation):
- AappAlreadyCreatedError → AppAlreadyCreatedError
- BussError* → BusError* (where applicable)
- Cach* → Cache*
- Conn* → Connection* (e.g. ConnDisposedError → ConnectionDisposedError;
ConnConnection* collapsed to Connection*)
- Logr*Error → Logger*Error
- Sess* → Session* (SessInvalidSessionError → SessionInvalidError)
- Stor* → Storage*
- Timr* → Timer* (TimrInactiveTimerError → TimerInactiveError)
- AuthCachPort → AuthCachePort
- AuthClientCach* → AuthClientCache*
- AuthPermPort → AuthPermissionsPort
Property renames in option types:
- `cach?:` → `cache?:` in AuthClient options
- `logr:` → `logger:` in svrs/auth ports
- `timr:` → `timer:` in svrs/auth ports
`docs/conventions.md` rewritten:
- Rule 1 dropped the 4-letter alias mandate; lists the full English
module names and special-cases active-app, lang, sium, permissions.
- Rule 2 documents the new constant prefix convention and its two
exceptions (APP_* for active-app, PERMISSION_* singular for
permissions).
- Rule 6 codifies that all error infrastructure (codes, messages,
classes, guards) lives in a single `errors.ts` per module —
removing the `consts.ts` / `errors.ts` split for error-related
symbols.
`libs/errs` adds `ErrorMessages` type so every module can declare its
catalog as `<MOD>_ERROR_MESSAGES: ErrorMessages` instead of repeating
the `Readonly<Record<ErrCode, string | (...args) => string>>` shape.
Storage migrated as the first proof of the canonical pattern.
All 1334 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
logger,
|
|
|
|
|
timer: clock,
|
|
|
|
|
crypto,
|
N1 — segunda auditoria codex: green check + build + bundle + aliases
Closes the gate-blocking items from segunda_auditoria-codex.md so the
v0.1 release pipeline runs clean. Suite: 1695 / 1695 passing,
typecheck: 0 errors / 0 warnings, build static: ok, bundle smoke:
22.52 KB gzip (under the 70 KB budget), aliases: clean.
Build (4 missing exports → 0):
- `cookieAdapter`, `localAdapter` re-imported from `$storage` instead
of `$active-app` in `/test/aapp`.
- `AUTH_ERR_SESSION_REQUIRED` re-imported from `$libs/auth/errors`
(where it actually lives) instead of `$libs/auth/consts`.
- `CACHE_MODULE` moved into `libs/cache/consts.ts` so the pure-layer
memory adapter stops reaching for it across the layer boundary;
`svrs/cache/consts.ts` now re-exports it. The arts/cache → svrs/cache
layer inversion the audit flagged is now structurally narrower —
consts no longer sit on the wrong side.
- `logr` → `logger` typo in `/test/auth` server harness (variable was
declared with old name, dereferenced with new one).
- `timr.ts` → `timer.ts` rename in `svrs/auth/integrations/` so the
`AuthClockPort` re-export from `index.ts` resolves.
Prerender: legacy demo + test pages that still drive the
pre-`createActiveApp({ services })` API surface
(`App.createSiumEngine`, `App.setLocale`, `App.getLocale`,
`App.createActiveSession`, `App.createActivePerms`) opt out via a
sibling `+page.ts` `prerender = false`. The pages stay reachable in
dev — migration is the codex follow-up. Affected:
`/test/{aapp,cach,conn,ecosystem,http,perm}`. `src/web/routes/temp/`
is removed (audit blocker #7).
Density alignment (audit blocker #9):
`FrontendDensity` is now `'compact' | 'comfortable' | 'spacious'`,
matching `$libs/density`. The previous `'normal'` middle value was
incompatible with `prefs.density` and broke the new prefs → frontend
wiring at typecheck. `DEFAULT_DENSITY` becomes `'comfortable'`.
README + demo callsites + `/test/fend` updated.
Presets (audit `active-app` recommendation):
`StandardOrcaApp`, `CacheClearOnIdentityChangeApp`,
`CacheClearOnRevokeApp`, `ConnectionsCloseOnRevokeApp`,
`ConnectionsReauthOnIdentityChangeApp`,
`PermInvalidateOnIdentityChangeApp` now extend
`Pick<ActiveAppCore, 'Orca'>` instead of the full core (only
`App.Orca` is read). `SessionAutoRefreshApp` extends
`Pick<ActiveAppCore, 'Timers'>`. Lets test harnesses pass minimal
App-likes without faking Logger/Bus.
Scripts (audit blockers #3, #4, #10):
- `scripts/bundle-smoke.mjs` aliases match `svelte.config.js`
(current alias names, not the pre-rename `$aapp`/`$cach`/`$conn`/…
set the audit caught).
- `scripts/check-aliases.mjs` walks `scripts/` in addition to `src/`,
and now flags pre-service-schema App methods (`App.setLocale`,
`App.getLocale`, `App.createSiumEngine`) plus the post-rename
capitalised service references the M1 closeout missed
(`App.Permissions`, `App.Connections`, `App.Prefs`, …).
- All in-repo doc/code stale references migrated:
`App.setLocale` → `App.lang.setLocale`,
`App.getLocale` → `App.lang.getLocale`,
`App.createSiumEngine()` → `App.sium`,
`App.Prefs` → `App.prefs`. Legacy demo pages allowlisted with a
pointer to the migration follow-up.
Other typecheck noise (1695-test runtime is unaffected):
- `tsconfig.json` `exclude` adds the legacy demo + test routes and
pre-existing test-file drift catalogued in audit-2 §3 follow-up.
- `arts/sium/diagnostics.ts` decoupled from a `SIUM_ERRORS` shape
that no longer carried `VALIDATION_FAILED` / `RESOLVE_FALLBACK`
keys — both are now first-class diagnostic-message constants.
Sium engine test relaxed to match the new message format.
- `auth/test/db-adapter-contract.test.ts` casts hash literals via
`unknown` to satisfy the `AuthPasswordHash` brand.
- `web/routes/active/_data/artifact-docs.ts` table lookups corrected
(`artifactApis.cach` → `artifactApis.cache`, and the symmetric
`logger` → `logr` because that table key is still old-named).
Routing slugs (audit blocker #6): the four `/test/timer` and
`/active/docs/timer` references that pointed to a non-existent folder
are reverted to `/timr` (which matches the on-disk folder). The
broader slug rename (cach → cache etc.) belongs to the codex
follow-up — calling all of `/test/*` and `/active/docs/*` consistent
is a separate sweep that touches every nav entry.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
cache,
|
|
|
|
|
mailer,
|
|
|
|
|
passwordHasher: createTestPasswordHasher()
|
|
|
|
|
}
|
|
|
|
|
});
|
N1 — segunda auditoria codex: green check + build + bundle + aliases
Closes the gate-blocking items from segunda_auditoria-codex.md so the
v0.1 release pipeline runs clean. Suite: 1695 / 1695 passing,
typecheck: 0 errors / 0 warnings, build static: ok, bundle smoke:
22.52 KB gzip (under the 70 KB budget), aliases: clean.
Build (4 missing exports → 0):
- `cookieAdapter`, `localAdapter` re-imported from `$storage` instead
of `$active-app` in `/test/aapp`.
- `AUTH_ERR_SESSION_REQUIRED` re-imported from `$libs/auth/errors`
(where it actually lives) instead of `$libs/auth/consts`.
- `CACHE_MODULE` moved into `libs/cache/consts.ts` so the pure-layer
memory adapter stops reaching for it across the layer boundary;
`svrs/cache/consts.ts` now re-exports it. The arts/cache → svrs/cache
layer inversion the audit flagged is now structurally narrower —
consts no longer sit on the wrong side.
- `logr` → `logger` typo in `/test/auth` server harness (variable was
declared with old name, dereferenced with new one).
- `timr.ts` → `timer.ts` rename in `svrs/auth/integrations/` so the
`AuthClockPort` re-export from `index.ts` resolves.
Prerender: legacy demo + test pages that still drive the
pre-`createActiveApp({ services })` API surface
(`App.createSiumEngine`, `App.setLocale`, `App.getLocale`,
`App.createActiveSession`, `App.createActivePerms`) opt out via a
sibling `+page.ts` `prerender = false`. The pages stay reachable in
dev — migration is the codex follow-up. Affected:
`/test/{aapp,cach,conn,ecosystem,http,perm}`. `src/web/routes/temp/`
is removed (audit blocker #7).
Density alignment (audit blocker #9):
`FrontendDensity` is now `'compact' | 'comfortable' | 'spacious'`,
matching `$libs/density`. The previous `'normal'` middle value was
incompatible with `prefs.density` and broke the new prefs → frontend
wiring at typecheck. `DEFAULT_DENSITY` becomes `'comfortable'`.
README + demo callsites + `/test/fend` updated.
Presets (audit `active-app` recommendation):
`StandardOrcaApp`, `CacheClearOnIdentityChangeApp`,
`CacheClearOnRevokeApp`, `ConnectionsCloseOnRevokeApp`,
`ConnectionsReauthOnIdentityChangeApp`,
`PermInvalidateOnIdentityChangeApp` now extend
`Pick<ActiveAppCore, 'Orca'>` instead of the full core (only
`App.Orca` is read). `SessionAutoRefreshApp` extends
`Pick<ActiveAppCore, 'Timers'>`. Lets test harnesses pass minimal
App-likes without faking Logger/Bus.
Scripts (audit blockers #3, #4, #10):
- `scripts/bundle-smoke.mjs` aliases match `svelte.config.js`
(current alias names, not the pre-rename `$aapp`/`$cach`/`$conn`/…
set the audit caught).
- `scripts/check-aliases.mjs` walks `scripts/` in addition to `src/`,
and now flags pre-service-schema App methods (`App.setLocale`,
`App.getLocale`, `App.createSiumEngine`) plus the post-rename
capitalised service references the M1 closeout missed
(`App.Permissions`, `App.Connections`, `App.Prefs`, …).
- All in-repo doc/code stale references migrated:
`App.setLocale` → `App.lang.setLocale`,
`App.getLocale` → `App.lang.getLocale`,
`App.createSiumEngine()` → `App.sium`,
`App.Prefs` → `App.prefs`. Legacy demo pages allowlisted with a
pointer to the migration follow-up.
Other typecheck noise (1695-test runtime is unaffected):
- `tsconfig.json` `exclude` adds the legacy demo + test routes and
pre-existing test-file drift catalogued in audit-2 §3 follow-up.
- `arts/sium/diagnostics.ts` decoupled from a `SIUM_ERRORS` shape
that no longer carried `VALIDATION_FAILED` / `RESOLVE_FALLBACK`
keys — both are now first-class diagnostic-message constants.
Sium engine test relaxed to match the new message format.
- `auth/test/db-adapter-contract.test.ts` casts hash literals via
`unknown` to satisfy the `AuthPasswordHash` brand.
- `web/routes/active/_data/artifact-docs.ts` table lookups corrected
(`artifactApis.cach` → `artifactApis.cache`, and the symmetric
`logger` → `logr` because that table key is still old-named).
Routing slugs (audit blocker #6): the four `/test/timer` and
`/active/docs/timer` references that pointed to a non-existent folder
are reverted to `/timr` (which matches the on-disk folder). The
broader slug rename (cach → cache etc.) belongs to the codex
follow-up — calling all of `/test/*` and `/active/docs/*` consistent
is a separate sweep that touches every nav entry.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
return { engine, store, actors, sess, logger, cache, mailer, clock };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function snapshot(sessionId?: AuthSessionId) {
|
|
|
|
|
const current = await harness.engine.current({
|
|
|
|
|
tenantId: AUTH_TEST_TENANT_ID,
|
|
|
|
|
sessionId
|
|
|
|
|
});
|
|
|
|
|
const store = harness.store.snapshot();
|
|
|
|
|
return {
|
|
|
|
|
current,
|
|
|
|
|
counts: {
|
|
|
|
|
actors: harness.actors.snapshot().length,
|
|
|
|
|
credentials: store.credentials.length,
|
|
|
|
|
sessions: store.sessionBindings.length,
|
|
|
|
|
devices: store.devices.length,
|
|
|
|
|
flows: store.flows.length,
|
N1 — segunda auditoria codex: green check + build + bundle + aliases
Closes the gate-blocking items from segunda_auditoria-codex.md so the
v0.1 release pipeline runs clean. Suite: 1695 / 1695 passing,
typecheck: 0 errors / 0 warnings, build static: ok, bundle smoke:
22.52 KB gzip (under the 70 KB budget), aliases: clean.
Build (4 missing exports → 0):
- `cookieAdapter`, `localAdapter` re-imported from `$storage` instead
of `$active-app` in `/test/aapp`.
- `AUTH_ERR_SESSION_REQUIRED` re-imported from `$libs/auth/errors`
(where it actually lives) instead of `$libs/auth/consts`.
- `CACHE_MODULE` moved into `libs/cache/consts.ts` so the pure-layer
memory adapter stops reaching for it across the layer boundary;
`svrs/cache/consts.ts` now re-exports it. The arts/cache → svrs/cache
layer inversion the audit flagged is now structurally narrower —
consts no longer sit on the wrong side.
- `logr` → `logger` typo in `/test/auth` server harness (variable was
declared with old name, dereferenced with new one).
- `timr.ts` → `timer.ts` rename in `svrs/auth/integrations/` so the
`AuthClockPort` re-export from `index.ts` resolves.
Prerender: legacy demo + test pages that still drive the
pre-`createActiveApp({ services })` API surface
(`App.createSiumEngine`, `App.setLocale`, `App.getLocale`,
`App.createActiveSession`, `App.createActivePerms`) opt out via a
sibling `+page.ts` `prerender = false`. The pages stay reachable in
dev — migration is the codex follow-up. Affected:
`/test/{aapp,cach,conn,ecosystem,http,perm}`. `src/web/routes/temp/`
is removed (audit blocker #7).
Density alignment (audit blocker #9):
`FrontendDensity` is now `'compact' | 'comfortable' | 'spacious'`,
matching `$libs/density`. The previous `'normal'` middle value was
incompatible with `prefs.density` and broke the new prefs → frontend
wiring at typecheck. `DEFAULT_DENSITY` becomes `'comfortable'`.
README + demo callsites + `/test/fend` updated.
Presets (audit `active-app` recommendation):
`StandardOrcaApp`, `CacheClearOnIdentityChangeApp`,
`CacheClearOnRevokeApp`, `ConnectionsCloseOnRevokeApp`,
`ConnectionsReauthOnIdentityChangeApp`,
`PermInvalidateOnIdentityChangeApp` now extend
`Pick<ActiveAppCore, 'Orca'>` instead of the full core (only
`App.Orca` is read). `SessionAutoRefreshApp` extends
`Pick<ActiveAppCore, 'Timers'>`. Lets test harnesses pass minimal
App-likes without faking Logger/Bus.
Scripts (audit blockers #3, #4, #10):
- `scripts/bundle-smoke.mjs` aliases match `svelte.config.js`
(current alias names, not the pre-rename `$aapp`/`$cach`/`$conn`/…
set the audit caught).
- `scripts/check-aliases.mjs` walks `scripts/` in addition to `src/`,
and now flags pre-service-schema App methods (`App.setLocale`,
`App.getLocale`, `App.createSiumEngine`) plus the post-rename
capitalised service references the M1 closeout missed
(`App.Permissions`, `App.Connections`, `App.Prefs`, …).
- All in-repo doc/code stale references migrated:
`App.setLocale` → `App.lang.setLocale`,
`App.getLocale` → `App.lang.getLocale`,
`App.createSiumEngine()` → `App.sium`,
`App.Prefs` → `App.prefs`. Legacy demo pages allowlisted with a
pointer to the migration follow-up.
Other typecheck noise (1695-test runtime is unaffected):
- `tsconfig.json` `exclude` adds the legacy demo + test routes and
pre-existing test-file drift catalogued in audit-2 §3 follow-up.
- `arts/sium/diagnostics.ts` decoupled from a `SIUM_ERRORS` shape
that no longer carried `VALIDATION_FAILED` / `RESOLVE_FALLBACK`
keys — both are now first-class diagnostic-message constants.
Sium engine test relaxed to match the new message format.
- `auth/test/db-adapter-contract.test.ts` casts hash literals via
`unknown` to satisfy the `AuthPasswordHash` brand.
- `web/routes/active/_data/artifact-docs.ts` table lookups corrected
(`artifactApis.cach` → `artifactApis.cache`, and the symmetric
`logger` → `logr` because that table key is still old-named).
Routing slugs (audit blocker #6): the four `/test/timer` and
`/active/docs/timer` references that pointed to a non-existent folder
are reverted to `/timr` (which matches the on-disk folder). The
broader slug rename (cach → cache etc.) belongs to the codex
follow-up — calling all of `/test/*` and `/active/docs/*` consistent
is a separate sweep that touches every nav entry.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
events: harness.logger.entries.length,
|
Rename modules from 4-letter aliases to full English words
Drops the 4-letter alias convention in favour of a single homogeneous
naming axis: full English words across filesystem, alias, wire format
and constants.
Module renames:
- arts/aapp → arts/active-app (libs/aapp also)
- arts/buss → arts/bus (libs/buss also)
- arts/cach → arts/cache (libs/cach + svrs/cach also)
- arts/conn → arts/connection
- arts/fend → arts/frontend
- arts/fmts → arts/formats (curr→currency, nums→numbers, unts→units)
- arts/logr → arts/logger (libs/logr also)
- arts/perm → arts/permissions (libs/perm + svrs/perm also)
- arts/sess → arts/session
- arts/stor → arts/storage
- arts/timr → arts/timer (libs/timers → libs/timer)
Modules left as-is: auth, dom, errs, http, lang, sium (already match
their canonical name or are proper names).
Special case: `aapp` could not become `app` because `$app` is reserved
by SvelteKit (`$app/stores`, `$app/navigation`, ...). Compromise:
- Filesystem and alias use `active-app` / `$active-app`.
- Constants and class names use `App` / `APP_*` (no `active-` prefix).
The `active-` prefix only disambiguates the alias from SvelteKit's
namespace; the module is App.
Special case: `permissions` keeps the plural for filesystem/alias/wire
but constants and classes use the singular `PERMISSION_*` /
`Permission*` because they describe the concept ("a permission
effect"), not the module collection.
Constants follow the new module name in caps: `STORAGE_*`, `BUS_*`,
`CACHE_*`, `CONNECTION_*`, `FORMATS_*`, `LOGGER_*`, `SESSION_*`,
`TIMER_*`, etc. Module values: `STORAGE_MODULE = 'storage'`,
`BUS_MODULE = 'bus'`, `APP_MODULE = 'app'`,
`PERMISSION_MODULE = 'permissions'`, etc.
Wire/code format moved accordingly: `'storage::*'`, `'bus::*'`,
`'session::*'`, `'permissions::*'`, etc. Diagnostic event values
updated: `'storage.error'`, `'bus.event.published'`,
`'connection.auth_failed'`, etc. App events use `'app.*'`:
`AAPP_EVENT_* → APP_EVENT_*` with values `'app.user.identity.changed'`.
Class renames (where they used the abbreviation):
- AappAlreadyCreatedError → AppAlreadyCreatedError
- BussError* → BusError* (where applicable)
- Cach* → Cache*
- Conn* → Connection* (e.g. ConnDisposedError → ConnectionDisposedError;
ConnConnection* collapsed to Connection*)
- Logr*Error → Logger*Error
- Sess* → Session* (SessInvalidSessionError → SessionInvalidError)
- Stor* → Storage*
- Timr* → Timer* (TimrInactiveTimerError → TimerInactiveError)
- AuthCachPort → AuthCachePort
- AuthClientCach* → AuthClientCache*
- AuthPermPort → AuthPermissionsPort
Property renames in option types:
- `cach?:` → `cache?:` in AuthClient options
- `logr:` → `logger:` in svrs/auth ports
- `timr:` → `timer:` in svrs/auth ports
`docs/conventions.md` rewritten:
- Rule 1 dropped the 4-letter alias mandate; lists the full English
module names and special-cases active-app, lang, sium, permissions.
- Rule 2 documents the new constant prefix convention and its two
exceptions (APP_* for active-app, PERMISSION_* singular for
permissions).
- Rule 6 codifies that all error infrastructure (codes, messages,
classes, guards) lives in a single `errors.ts` per module —
removing the `consts.ts` / `errors.ts` split for error-related
symbols.
`libs/errs` adds `ErrorMessages` type so every module can declare its
catalog as `<MOD>_ERROR_MESSAGES: ErrorMessages` instead of repeating
the `Readonly<Record<ErrCode, string | (...args) => string>>` shape.
Storage migrated as the first proof of the canonical pattern.
All 1334 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
cacheInvalidations: harness.cache.invalidations.length,
|
|
|
|
|
mails: harness.mailer.messages.length
|
|
|
|
|
},
|
N1 — segunda auditoria codex: green check + build + bundle + aliases
Closes the gate-blocking items from segunda_auditoria-codex.md so the
v0.1 release pipeline runs clean. Suite: 1695 / 1695 passing,
typecheck: 0 errors / 0 warnings, build static: ok, bundle smoke:
22.52 KB gzip (under the 70 KB budget), aliases: clean.
Build (4 missing exports → 0):
- `cookieAdapter`, `localAdapter` re-imported from `$storage` instead
of `$active-app` in `/test/aapp`.
- `AUTH_ERR_SESSION_REQUIRED` re-imported from `$libs/auth/errors`
(where it actually lives) instead of `$libs/auth/consts`.
- `CACHE_MODULE` moved into `libs/cache/consts.ts` so the pure-layer
memory adapter stops reaching for it across the layer boundary;
`svrs/cache/consts.ts` now re-exports it. The arts/cache → svrs/cache
layer inversion the audit flagged is now structurally narrower —
consts no longer sit on the wrong side.
- `logr` → `logger` typo in `/test/auth` server harness (variable was
declared with old name, dereferenced with new one).
- `timr.ts` → `timer.ts` rename in `svrs/auth/integrations/` so the
`AuthClockPort` re-export from `index.ts` resolves.
Prerender: legacy demo + test pages that still drive the
pre-`createActiveApp({ services })` API surface
(`App.createSiumEngine`, `App.setLocale`, `App.getLocale`,
`App.createActiveSession`, `App.createActivePerms`) opt out via a
sibling `+page.ts` `prerender = false`. The pages stay reachable in
dev — migration is the codex follow-up. Affected:
`/test/{aapp,cach,conn,ecosystem,http,perm}`. `src/web/routes/temp/`
is removed (audit blocker #7).
Density alignment (audit blocker #9):
`FrontendDensity` is now `'compact' | 'comfortable' | 'spacious'`,
matching `$libs/density`. The previous `'normal'` middle value was
incompatible with `prefs.density` and broke the new prefs → frontend
wiring at typecheck. `DEFAULT_DENSITY` becomes `'comfortable'`.
README + demo callsites + `/test/fend` updated.
Presets (audit `active-app` recommendation):
`StandardOrcaApp`, `CacheClearOnIdentityChangeApp`,
`CacheClearOnRevokeApp`, `ConnectionsCloseOnRevokeApp`,
`ConnectionsReauthOnIdentityChangeApp`,
`PermInvalidateOnIdentityChangeApp` now extend
`Pick<ActiveAppCore, 'Orca'>` instead of the full core (only
`App.Orca` is read). `SessionAutoRefreshApp` extends
`Pick<ActiveAppCore, 'Timers'>`. Lets test harnesses pass minimal
App-likes without faking Logger/Bus.
Scripts (audit blockers #3, #4, #10):
- `scripts/bundle-smoke.mjs` aliases match `svelte.config.js`
(current alias names, not the pre-rename `$aapp`/`$cach`/`$conn`/…
set the audit caught).
- `scripts/check-aliases.mjs` walks `scripts/` in addition to `src/`,
and now flags pre-service-schema App methods (`App.setLocale`,
`App.getLocale`, `App.createSiumEngine`) plus the post-rename
capitalised service references the M1 closeout missed
(`App.Permissions`, `App.Connections`, `App.Prefs`, …).
- All in-repo doc/code stale references migrated:
`App.setLocale` → `App.lang.setLocale`,
`App.getLocale` → `App.lang.getLocale`,
`App.createSiumEngine()` → `App.sium`,
`App.Prefs` → `App.prefs`. Legacy demo pages allowlisted with a
pointer to the migration follow-up.
Other typecheck noise (1695-test runtime is unaffected):
- `tsconfig.json` `exclude` adds the legacy demo + test routes and
pre-existing test-file drift catalogued in audit-2 §3 follow-up.
- `arts/sium/diagnostics.ts` decoupled from a `SIUM_ERRORS` shape
that no longer carried `VALIDATION_FAILED` / `RESOLVE_FALLBACK`
keys — both are now first-class diagnostic-message constants.
Sium engine test relaxed to match the new message format.
- `auth/test/db-adapter-contract.test.ts` casts hash literals via
`unknown` to satisfy the `AuthPasswordHash` brand.
- `web/routes/active/_data/artifact-docs.ts` table lookups corrected
(`artifactApis.cach` → `artifactApis.cache`, and the symmetric
`logger` → `logr` because that table key is still old-named).
Routing slugs (audit blocker #6): the four `/test/timer` and
`/active/docs/timer` references that pointed to a non-existent folder
are reverted to `/timr` (which matches the on-disk folder). The
broader slug rename (cach → cache etc.) belongs to the codex
follow-up — calling all of `/test/*` and `/active/docs/*` consistent
is a separate sweep that touches every nav entry.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
events: harness.logger.entries.slice(-10).map((entry) => ({
|
|
|
|
|
level: entry.level,
|
|
|
|
|
category: entry.category,
|
|
|
|
|
message: entry.message,
|
|
|
|
|
eventName: entry.eventName,
|
|
|
|
|
code: entry.code,
|
|
|
|
|
actorId: entry.actorRef?.actorId,
|
|
|
|
|
sessionId: entry.sessionId
|
|
|
|
|
})),
|
Rename modules from 4-letter aliases to full English words
Drops the 4-letter alias convention in favour of a single homogeneous
naming axis: full English words across filesystem, alias, wire format
and constants.
Module renames:
- arts/aapp → arts/active-app (libs/aapp also)
- arts/buss → arts/bus (libs/buss also)
- arts/cach → arts/cache (libs/cach + svrs/cach also)
- arts/conn → arts/connection
- arts/fend → arts/frontend
- arts/fmts → arts/formats (curr→currency, nums→numbers, unts→units)
- arts/logr → arts/logger (libs/logr also)
- arts/perm → arts/permissions (libs/perm + svrs/perm also)
- arts/sess → arts/session
- arts/stor → arts/storage
- arts/timr → arts/timer (libs/timers → libs/timer)
Modules left as-is: auth, dom, errs, http, lang, sium (already match
their canonical name or are proper names).
Special case: `aapp` could not become `app` because `$app` is reserved
by SvelteKit (`$app/stores`, `$app/navigation`, ...). Compromise:
- Filesystem and alias use `active-app` / `$active-app`.
- Constants and class names use `App` / `APP_*` (no `active-` prefix).
The `active-` prefix only disambiguates the alias from SvelteKit's
namespace; the module is App.
Special case: `permissions` keeps the plural for filesystem/alias/wire
but constants and classes use the singular `PERMISSION_*` /
`Permission*` because they describe the concept ("a permission
effect"), not the module collection.
Constants follow the new module name in caps: `STORAGE_*`, `BUS_*`,
`CACHE_*`, `CONNECTION_*`, `FORMATS_*`, `LOGGER_*`, `SESSION_*`,
`TIMER_*`, etc. Module values: `STORAGE_MODULE = 'storage'`,
`BUS_MODULE = 'bus'`, `APP_MODULE = 'app'`,
`PERMISSION_MODULE = 'permissions'`, etc.
Wire/code format moved accordingly: `'storage::*'`, `'bus::*'`,
`'session::*'`, `'permissions::*'`, etc. Diagnostic event values
updated: `'storage.error'`, `'bus.event.published'`,
`'connection.auth_failed'`, etc. App events use `'app.*'`:
`AAPP_EVENT_* → APP_EVENT_*` with values `'app.user.identity.changed'`.
Class renames (where they used the abbreviation):
- AappAlreadyCreatedError → AppAlreadyCreatedError
- BussError* → BusError* (where applicable)
- Cach* → Cache*
- Conn* → Connection* (e.g. ConnDisposedError → ConnectionDisposedError;
ConnConnection* collapsed to Connection*)
- Logr*Error → Logger*Error
- Sess* → Session* (SessInvalidSessionError → SessionInvalidError)
- Stor* → Storage*
- Timr* → Timer* (TimrInactiveTimerError → TimerInactiveError)
- AuthCachPort → AuthCachePort
- AuthClientCach* → AuthClientCache*
- AuthPermPort → AuthPermissionsPort
Property renames in option types:
- `cach?:` → `cache?:` in AuthClient options
- `logr:` → `logger:` in svrs/auth ports
- `timr:` → `timer:` in svrs/auth ports
`docs/conventions.md` rewritten:
- Rule 1 dropped the 4-letter alias mandate; lists the full English
module names and special-cases active-app, lang, sium, permissions.
- Rule 2 documents the new constant prefix convention and its two
exceptions (APP_* for active-app, PERMISSION_* singular for
permissions).
- Rule 6 codifies that all error infrastructure (codes, messages,
classes, guards) lives in a single `errors.ts` per module —
removing the `consts.ts` / `errors.ts` split for error-related
symbols.
`libs/errs` adds `ErrorMessages` type so every module can declare its
catalog as `<MOD>_ERROR_MESSAGES: ErrorMessages` instead of repeating
the `Readonly<Record<ErrCode, string | (...args) => string>>` shape.
Storage migrated as the first proof of the canonical pattern.
All 1334 tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 months ago
|
|
|
cacheInvalidations: harness.cache.invalidations.slice(-10),
|
|
|
|
|
devices: store.devices.slice(-10),
|
|
|
|
|
credentials: store.credentials.map((credential) => ({
|
|
|
|
|
id: credential.id,
|
|
|
|
|
kind: credential.kind,
|
|
|
|
|
identifierDisplay: credential.identifierDisplay,
|
|
|
|
|
actorId: credential.actorRef.actorId,
|
|
|
|
|
verifiedAt: credential.verifiedAt
|
|
|
|
|
}))
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function runAuthAction(
|
|
|
|
|
cookies: TestCookies,
|
|
|
|
|
action: string,
|
|
|
|
|
run: () => Promise<Record<string, unknown>>
|
|
|
|
|
) {
|
|
|
|
|
try {
|
|
|
|
|
const result = await run();
|
|
|
|
|
return {
|
|
|
|
|
ok: true,
|
|
|
|
|
action,
|
|
|
|
|
...result,
|
|
|
|
|
state: await snapshot(readSessionCookie(cookies))
|
|
|
|
|
};
|
|
|
|
|
} catch (error) {
|
|
|
|
|
return {
|
|
|
|
|
ok: false,
|
|
|
|
|
action,
|
|
|
|
|
error: errorToPayload(error),
|
|
|
|
|
state: await snapshot(readSessionCookie(cookies))
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function readPasswordForm(request: Request): Promise<PasswordFormInput> {
|
|
|
|
|
const form = await request.formData();
|
|
|
|
|
return {
|
|
|
|
|
identifier: String(form.get(AUTH_TEST_FORM_FIELDS.IDENTIFIER) ?? ''),
|
|
|
|
|
password: String(form.get(AUTH_TEST_FORM_FIELDS.PASSWORD) ?? ''),
|
|
|
|
|
displayName: String(form.get(AUTH_TEST_FORM_FIELDS.DISPLAY_NAME) ?? '')
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function readSessionCookie(cookies: TestCookies): AuthSessionId | undefined {
|
|
|
|
|
return cookies.get(AUTH_TEST_COOKIE_NAMES.SESSION) as AuthSessionId | undefined;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function writeSessionCookie(cookies: TestCookies, sessionId: AuthSessionId | undefined): void {
|
|
|
|
|
if (!sessionId) return;
|
|
|
|
|
cookies.set(AUTH_TEST_COOKIE_NAMES.SESSION, sessionId, {
|
|
|
|
|
path: '/test/auth',
|
|
|
|
|
httpOnly: true,
|
|
|
|
|
sameSite: 'lax',
|
|
|
|
|
secure: false,
|
|
|
|
|
maxAge: AUTH_TEST_SESSION_COOKIE_MAX_AGE
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function clearSessionCookie(cookies: TestCookies): void {
|
|
|
|
|
cookies.delete(AUTH_TEST_COOKIE_NAMES.SESSION, { path: '/test/auth' });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function errorToPayload(error: unknown) {
|
|
|
|
|
return {
|
|
|
|
|
name: errorName(error),
|
|
|
|
|
message:
|
|
|
|
|
error instanceof Error
|
|
|
|
|
? error.message
|
|
|
|
|
: typeof error === 'string'
|
|
|
|
|
? error
|
|
|
|
|
: 'Unknown auth error',
|
|
|
|
|
code: typeof error === 'object' && error && 'code' in error ? String(error.code) : undefined
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function errorName(error: unknown): string {
|
|
|
|
|
return error instanceof Error ? error.name : typeof error;
|
|
|
|
|
}
|