fix: two 500s found by actually running the kernel, plus the tests that found them #2

Merged
john merged 1 commit from feat/exercise-the-api into dev 2026-07-27 00:45:36 +00:00
Owner

Nothing had ever hit an endpoint before this. Migrations applied and the container started, so CI was green while two routes returned 500. Both are drift between the routers in this repo and the pinned haskytech-haskos-kernel==0.2.0 services they call — invisible to imports and type checks.

Fixed

  • GET /entities/search unpacked the service's (list, total) return as if it were (entity, score) pairs.
  • POST /entities passed a description kwarg the service does not accept, for a column the model does not have. Dropped from both entity schemas.
  • GET /apps called ensure_builtins(), seeding HaskyOS's own stage apps into whatever database it ran against. SuperCleanOS would have claimed a sales and a pm stage app it does not run.

Added

  • tests/test_api_smoke.py — 12 tests driving every route against a real Postgres via ASGITransport, including unauthenticated rejection and the app-registry regression.
  • scripts/bootstrap_owner.py — a fresh company database has an empty user table behind require_role and there is no bootstrap endpoint by design. This is the way in. Password from env or stdin, never argv.
  • Session-scoped asyncio loops plus conftest.py, because haskos_kernel.database builds its engine at import and the pool outlives a per-test loop.

Local owner account created, credentials in Bitwarden at projects/companyos-kernel/dev-owner.

Nothing had ever hit an endpoint before this. Migrations applied and the container started, so CI was green while two routes returned 500. Both are drift between the routers in this repo and the pinned haskytech-haskos-kernel==0.2.0 services they call — invisible to imports and type checks. **Fixed** - `GET /entities/search` unpacked the service's `(list, total)` return as if it were `(entity, score)` pairs. - `POST /entities` passed a `description` kwarg the service does not accept, for a column the model does not have. Dropped from both entity schemas. - `GET /apps` called `ensure_builtins()`, seeding HaskyOS's own stage apps into whatever database it ran against. SuperCleanOS would have claimed a sales and a pm stage app it does not run. **Added** - `tests/test_api_smoke.py` — 12 tests driving every route against a real Postgres via ASGITransport, including unauthenticated rejection and the app-registry regression. - `scripts/bootstrap_owner.py` — a fresh company database has an empty user table behind `require_role` and there is no bootstrap endpoint by design. This is the way in. Password from env or stdin, never argv. - Session-scoped asyncio loops plus `conftest.py`, because `haskos_kernel.database` builds its engine at import and the pool outlives a per-test loop. Local owner account created, credentials in Bitwarden at `projects/companyos-kernel/dev-owner`.
fix: two 500s found by actually running the kernel, plus the tests that found them
Some checks failed
CI / Deploy (pull_request) Has been skipped
CI / Detect Changes (pull_request) Has been cancelled
CI / Docker Build (pull_request) Has been cancelled
CI / Backend (pull_request) Has been cancelled
b77954c3f4
Nothing had ever hit an endpoint. Migrations applied and the container started, so CI
was green while two routes were broken — both from drift between the routers in this
repo and the pinned haskytech-haskos-kernel==0.2.0 services they call. Neither shows
up in an import or a type check.

- GET /entities/search unpacked the service's (list, total) return as if it were
  (entity, score) pairs. ValueError, 500.
- POST /entities passed a "description" kwarg that EntityRegistryService.register
  does not accept, for a column RegisteredEntity does not have. TypeError, 500. The
  field is dropped from both entity schemas.

Also stops seeding HaskyOS's stage apps into every company database. A plain
GET /apps called AppRegistryService.ensure_builtins(), which inserts "HaskyOS
Kernel", "Sales Stage" and "PM Stage" — so SuperCleanOS would have claimed a sales
and a pm stage app it does not run. A listing endpoint should not write rows.

New:
- tests/test_api_smoke.py drives every route against a real Postgres via
  ASGITransport. 12 tests, including that unauthenticated calls are rejected and
  that listing apps seeds nothing.
- scripts/bootstrap_owner.py closes the gap the runbook could not describe: a fresh
  company database has an empty user table behind require_role, and there is no
  bootstrap endpoint by design. Password from env or stdin, never argv.
- conftest.py plus session-scoped asyncio loops, because haskos_kernel.database
  builds its engine at import and the pool outlives a per-test loop.

Local owner account created and stored in Bitwarden under
projects/companyos-kernel/dev-owner.
john merged commit 2e9b2bdbcc into dev 2026-07-27 00:45:36 +00:00
john deleted branch feat/exercise-the-api 2026-07-27 00:45:36 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
haskytech/companyos-kernel!2
No description provided.