Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions greenfield/bun.lock

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions greenfield/bunfig.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
peer = false

[test]
coverageReporter = ["text", "lcov"]
coverageDir = "coverage"
preload = ["./src/test/setup.ts"]
coverageSkipTestFiles = true
coveragePathIgnorePatterns = [
"scripts/**",
"src/**/*.d.ts",
"src/**/test/**",
"src/**/testSupport/**",
"src/server/test/**",
"src/test/**",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ environment against the exact candidate binary:
transactions, prepared-statement disposal, backup, restore, and process termination.
5. Frontend build tests for HTML imports, Tailwind, React Compiler, lazy chunks, CSP, source
maps, cache hashes, precompression, and bundle budgets.
6. `bun test --isolate` tests for fake timers, leaked handles, deterministic shutdown, and
bounded concurrency.
6. Same-process Bun tests for fake timers, leaked handles, deterministic shutdown, and
bounded concurrency, with explicit teardown after every test.

The historical 2026-08-06 Phase 0 qualification round passed on exact revision
`17d6843606d76620cb55d31424d7fb0aed51c367`: its then-current dedicated typecheck and full evidence
Expand Down Expand Up @@ -330,7 +330,7 @@ Additional safeguards:
- no unbounded `Promise.all` over files, containers, tests, sessions, or API results;
- server-side pagination or cursors for every append-only history;
- run the Bun and browser type-aware lint partitions sequentially on the VPS;
- cap Bun test concurrency and isolate tests that leak global runtime state; and
- cap Bun test concurrency and require deterministic same-process cleanup of global state; and
- record cgroup OOM/limit exits as failed jobs with an actionable message.

## Build, Test, and Quality Tooling
Expand All @@ -340,8 +340,8 @@ Additional safeguards:
The exact naming may change as product areas arrive. The future-root package exposes one
`typecheck` gate over the root solution; focused browser and Bun child checks may remain as
developer aliases. There are no per-domain, server, worker, script, or qualification TypeScript
projects. `check:boundaries` and `test:boundaries` enforce the finer source roles. Retained Phase 0
mechanisms run through the ordinary integration, parity, or audit suites. Product and
projects. `check:boundaries` enforces the finer source roles. Retained Phase 0 mechanisms run
through the ordinary Bun test graph. Product and
cross-process integration tests live under `src/`; a focused test of a repository script may
remain colocated with that script.

Expand All @@ -351,13 +351,9 @@ build deterministic browser and server/worker artifacts
typecheck root TypeScript solution (browser + Bun), no emit
lint oxlint type-aware rules and type-check diagnostics, partitioned by runtime
format / format:check oxfmt
test:unit pure domain and utility tests
test:database temporary SQLite repository/migration tests
test:contracts tRPC caller, raw HTTP registry, schema, and docs tests
test:realtime SSE/outbox/reconnect/race/backpressure tests
test:frontend Happy DOM + Testing Library behavior tests
test:integration Bun server/worker/Gateway fixture tests
test:parity named current-feature acceptance suite
test Bun graph followed by browser graph
test:bun scripts, server, worker, contracts, integration, and parity tests
test:browser Happy DOM + Testing Library behavior tests
test:coverage all tests + 85% executable-source line gate and LCOV
docs:generate/check deterministic generated documentation
verify sequential local gate with explicit resource caps
Expand Down
17 changes: 10 additions & 7 deletions greenfield/docs/development/testing-and-prs.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,18 @@ policy.

Browser tests are checked by the browser graph with DOM/JSX and the narrow `bun:test` declaration.
All remaining tests are included by the Bun graph. Every `*.test.ts(x)`, `*.spec.ts(x)`,
`__tests__/`, and `testSupport/` file must therefore remain type-checked.
`__tests__/`, `test/`, and `testSupport/` file must therefore remain type-checked.

## Test ownership

Keep a module's tests beside that module. If one production module needs multiple concern-focused
suites, use `<module><Concern>.test.ts` rather than creating an omnibus suite.

- Put reusable executable helpers in the owning module's `testSupport/` directory.
- Keep browser-wide setup and self-contained browser build fixtures under `src/browser/test/`.
- Put genuinely cross-domain server harnesses in `src/server/test/support/`.
- Reserve `fixtures/` for immutable payloads and reviewed evidence.
- Reserve `fixtures/` for immutable payloads, reviewed evidence, and self-contained build inputs;
never put reusable helper logic there.
- Put cross-module contracts in `src/server/test/contracts/`.
- Put composition-root behavior in `src/server/test/system/`.
- Keep executable repository audits and tools under `scripts/`. Tests that directly verify one
Expand All @@ -68,11 +70,12 @@ and additionally fails an otherwise green suite when output contains a React mis
warning, an unconfigured React act environment warning, or a Bun panic/crash banner. Do not bypass
that runner in repository test scripts.

The browser suite preloads only the Happy DOM globals and React act-environment marker it needs;
the tests themselves remain in the browser TypeScript graph. The product-shell test renders the
real QueryClient, router, accessible route, and error-boundary composition. Build tests separately
exercise the actual HTML entrypoint, React Compiler, Tailwind, code splitting, compression, CSP
policy, and bundle budgets.
Every suite preloads the process-private test root and mock cleanup. The browser suite additionally
preloads Happy DOM, Testing Library matchers and cleanup, the React act-environment marker, and the
Headless UI animation mock. Browser tests and their support remain in the browser TypeScript graph.
The product-shell test renders the real QueryClient, router, accessible route, and error-boundary
composition. Build tests separately exercise the actual HTML entrypoint, React Compiler, Tailwind,
code splitting, compression, CSP policy, and bundle budgets.

## Lint and boundaries

Expand Down
2 changes: 2 additions & 0 deletions greenfield/docs/generated/packages-and-runtime.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@
| `drizzle-kit` | `1.0.0-rc.4` | `1.0.0-rc.4` | development |
| `eventsource` | `4.1.1` | `4.1.1` | development |
| `happy-dom` | `^20.11.1` | `20.11.1` | development |
| `jsdom-testing-mocks` | `^1.16.0` | `1.16.0` | development |
| `jsonc-parser` | `3.3.1` | `3.3.1` | development |
| `lcov-result-merger` | `^6.0.0` | `6.0.0` | development |
| `oxfmt` | `^0.62.0` | `0.62.0` | development |
| `oxlint` | `^1.77.0` | `1.77.0` | development |
| `oxlint-config-presets` | `^0.1.18` | `0.1.18` | development |
Expand Down
3 changes: 3 additions & 0 deletions greenfield/docs/generated/procedures.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
| `auth.loginTotp` | mutation | auth | Pending MFA login | [input](./schemas/auth.loginTotp.input.schema.json) | [output](./schemas/auth.loginTotp.output.schema.json) | `SERVICE_UNAVAILABLE`, `TOO_MANY_REQUESTS`, `UNAUTHORIZED` | None | Consumes a pending login with a TOTP proof and creates the browser session. |
| `auth.loginWebAuthn` | mutation | auth | Pending MFA login | [input](./schemas/auth.loginWebAuthn.input.schema.json) | [output](./schemas/auth.loginWebAuthn.output.schema.json) | `SERVICE_UNAVAILABLE`, `TOO_MANY_REQUESTS`, `UNAUTHORIZED` | None | Consumes a pending login and WebAuthn challenge to create the browser session. |
| `auth.logout` | mutation | auth | Public | [input](./schemas/auth.logout.input.schema.json) | [output](./schemas/auth.logout.output.schema.json) | `SERVICE_UNAVAILABLE` | None | Revokes current session and pending-login state and clears both cookies. |
| `auth.revokeAllSessions` | mutation | auth | Recent password when MFA is disabled; recent MFA when enabled | [input](./schemas/auth.revokeAllSessions.input.schema.json) | [output](./schemas/auth.revokeAllSessions.output.schema.json) | `FORBIDDEN`, `SERVICE_UNAVAILABLE`, `UNAUTHORIZED` | `step_up_required` | Revokes every browser session, including the current session. |
| `auth.revokeOtherSessions` | mutation | auth | Recent password when MFA is disabled; recent MFA when enabled | [input](./schemas/auth.revokeOtherSessions.input.schema.json) | [output](./schemas/auth.revokeOtherSessions.output.schema.json) | `FORBIDDEN`, `SERVICE_UNAVAILABLE`, `UNAUTHORIZED` | `step_up_required` | Revokes every browser session except the current session. |
| `auth.revokeSession` | mutation | auth | Recent password when MFA is disabled; recent MFA when enabled | [input](./schemas/auth.revokeSession.input.schema.json) | [output](./schemas/auth.revokeSession.output.schema.json) | `FORBIDDEN`, `SERVICE_UNAVAILABLE`, `UNAUTHORIZED` | `step_up_required` | Revokes one browser session owned by the current user. |
| `auth.sessions` | query | auth | Authenticated browser session | [input](./schemas/auth.sessions.input.schema.json) | [output](./schemas/auth.sessions.output.schema.json) | `FORBIDDEN`, `UNAUTHORIZED` | None | Lists the current user's browser sessions without validators. |
| `auth.status` | query | auth | Public | [input](./schemas/auth.status.input.schema.json) | [output](./schemas/auth.status.output.schema.json) | None | None | Returns bootstrap, pending MFA, and current browser-session state. |
Expand All @@ -39,4 +41,5 @@
| `automationSecurity.revokeCredential` | mutation | automation-security | MFA enrollment required; recent MFA when enabled | [input](./schemas/automationSecurity.revokeCredential.input.schema.json) | [output](./schemas/automationSecurity.revokeCredential.output.schema.json) | `CONFLICT`, `FORBIDDEN`, `NOT_FOUND`, `SERVICE_UNAVAILABLE`, `UNAUTHORIZED` | `mfa_enrollment_required`, `step_up_required` | Explicitly revokes one automation credential after client cutover. |
| `automationSecurity.rotateCredential` | mutation | automation-security | MFA enrollment required; recent MFA when enabled | [input](./schemas/automationSecurity.rotateCredential.input.schema.json) | [output](./schemas/automationSecurity.rotateCredential.output.schema.json) | `CONFLICT`, `FORBIDDEN`, `NOT_FOUND`, `PRECONDITION_FAILED`, `SERVICE_UNAVAILABLE`, `UNAUTHORIZED` | `mfa_enrollment_required`, `step_up_required` | Stages a linked replacement credential without revoking its predecessor. |
| `events.stream` | subscription | events | Authenticated; per-topic: notifications:read, reports:read | [input](./schemas/events.stream.input.schema.json) | [output](./schemas/events.stream.output.schema.json) | `BAD_REQUEST`, `FORBIDDEN`, `SERVICE_UNAVAILABLE`, `TOO_MANY_REQUESTS`, `UNAUTHORIZED` | None | Streams authorized durable changes with tracked resume cursors. |
| `securityAudit.listEvents` | query | securityAudit | Authenticated browser session | [input](./schemas/securityAudit.listEvents.input.schema.json) | [output](./schemas/securityAudit.listEvents.output.schema.json) | `FORBIDDEN`, `UNAUTHORIZED` | None | Lists redacted immutable security events in stable newest-first order. |
| `system.runtimeIdentity` | query | system | Public | [input](./schemas/system.runtimeIdentity.input.schema.json) | [output](./schemas/system.runtimeIdentity.output.schema.json) | None | None | Returns the Bun runtime identity of the serving process. |
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$id": "urn:mira-dashboard:auth.revokeAllSessions.input",
"type": "object",
"properties": {},
"required": [],
"additionalProperties": false,
"default": {},
"$schema": "https://json-schema.org/draft/2020-12/schema"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"$id": "urn:mira-dashboard:auth.revokeAllSessions.output",
"type": "object",
"properties": {
"revokedSessions": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
}
},
"required": [
"revokedSessions"
],
"additionalProperties": false,
"$schema": "https://json-schema.org/draft/2020-12/schema"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$id": "urn:mira-dashboard:auth.revokeOtherSessions.input",
"type": "object",
"properties": {},
"required": [],
"additionalProperties": false,
"default": {},
"$schema": "https://json-schema.org/draft/2020-12/schema"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"$id": "urn:mira-dashboard:auth.revokeOtherSessions.output",
"type": "object",
"properties": {
"revokedSessions": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
}
},
"required": [
"revokedSessions"
],
"additionalProperties": false,
"$schema": "https://json-schema.org/draft/2020-12/schema"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"$id": "urn:mira-dashboard:securityAudit.listEvents.input",
"type": "object",
"properties": {
"cursor": {
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 36,
"maxLength": 36,
"format": "uuid",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
},
"occurredAtMs": {
"type": "integer",
"minimum": 0,
"maximum": 8640000000000000
}
},
"required": [
"id",
"occurredAtMs"
],
"additionalProperties": false
},
"limit": {
"type": "integer",
"minimum": 1,
"maximum": 50,
"default": 20
}
},
"required": [],
"additionalProperties": false,
"$schema": "https://json-schema.org/draft/2020-12/schema"
}
Loading