4.1 KiB
4.1 KiB
Task 5 report — backend principal enforcement
RED
Added backend route/auth tests before implementation. The initial focused run failed in
seven new assertions: getPrincipal did not exist, upstream requests still required the
legacy identity header, foreign session/SSE routes were not hidden, admin scope was not
enforced, new sessions had no trusted principal binding, and settings were global.
GREEN
- Focused backend suite:
66 passedacross auth, sessions, SSE, and settings tests. - Complete backend Vitest suite:
209 passedacross22files. npx tsc --noEmit -p .,npm run build,git diff --check, and changed Python source Ruff all exit successfully.- Harness targeted repository/local/migration tests and Python bytecode compilation exit
successfully. The new
tht session preferences get|setcommands are registered and expose the expected Typer help. A direct local CLI preference smoke was not run because the checked-in local workspace requires unavailableTHT_DB_HOSTconfiguration.
Route and child-process coverage
GET /mereturns the requestPrincipalContext; upstream accepts only the portal's normalizedX-Thoth-*identity tuple, with the legacy header ignored. Local mode uses the same stableTHT_HOME/~/.thothii/identity.jsonUUID contract as the harness.- All session operations are principal-scoped: list (
mineand admin-onlyall), show, create, resume, close, delete, rename, group, archive, unarchive, documents, reviewer response, steer, SQL preview/export, and SSE. Missing and foreign sessions are 404; absent upstream identity is 401. SSE is authorized before response headers or hub subscription, so a rejected request cannot attach to a live stream. - New/resumed Pi runtimes and every route-spawned
thtprocess receiveTHT_PRINCIPAL_ISSUER,THT_PRINCIPAL_SUBJECT, optional display name, and admin flag. The readinessthtchild is also principal-bound. - Settings use asynchronous repository-backed
tht session preferences get|setin the production runner, which isolates preferences by principal. The legacy settings file is retained only as an injected-runner compatibility fallback for existing isolated tests. - Repository/settings authorization failures map to 503 before model startup. SQL execution errors remain 500 after authorization, preserving the prior API distinction.
Self-review and concerns
- Confirmed the Task 4 portal emits lowercase
true/falsefor the admin header; the parser accepts that exact normalized form plus the repository's existing1/0compatibility form, and rejects all other values. - The harness principal resolver is the ownership authority; the backend never accepts an
owner supplied in request bodies. Its route guards use a repository-scoped
session showbefore every session resource operation. - Existing dependency-injected route fakes without
sessionShowretain a narrow test seam; productionThtRunneralways has that method, so deployed requests cannot bypass the repository authorization check.
Review follow-up
RED
Focused regressions initially failed exactly at the three review findings: stale ambient
display names survived into both tht and Pi child environments; mutation/document runner
methods dropped the selected workspace; and expandLocalHome did not exist.
GREEN
- Child environments now remove all four
THT_PRINCIPAL_*keys from their cloned base environment before applying the exact request principal. Regression tests prove an absent display name does not inherit a stale ambient value in either child path. setName,setGroup,archive,unarchive, anddocumentsnow take and retain an optional workspace. The rename route regression provessession showauthorization and the mutation use the same non-default workspace.- Local principal paths expand
~/~/...; existing local home and identity file modes are repaired to POSIX0700/0600when applicable, with Windows left unchanged. - Focused suite:
74 passed; full backend suite:213 passedacross22files, followed by TypeScript typecheck, production build, and diff check.