Sign In

@ultimat3/core

Package Overview
Dependencies
Maintainers
1
Versions
20
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ultimat3/core - npm Package Compare versions

Comparing version
7.0.0
to
8.0.0
+47
src/format-bytes.ts
// Single responsibility: a byte count as the short, machine-ish string an error message carries.
//
// Tier 0 because two tier-4 packages need exactly this and neither may import the other:
// `@ultimat3/render`'s `X_BUDGET_EXCEEDED` cause and `@ultimat3/pwa`'s precache warning. Each kept
// its own copy and they had diverged — render's stopped at `kb`, so one 5 MiB route read `5120kb`
// in the budget error and `5mb` in the warning about the same bytes.
/** 1024-based, because every producer here counts bundle bytes, which tooling reports in KiB. */
const STEP = 1024;
/**
* Ascending, so the index into it IS the power of `STEP`. `gb` is the last rung on purpose: a
* precache or a route bundle past a terabyte is a bug in the caller, not a unit this should grow.
*/
const UNITS = ['b', 'kb', 'mb', 'gb'] as const;
const round1 = (value: number): number => Math.round(value * 10) / 10;
/**
* A size a message can state — `1023b`, `4.5kb`, `5mb`, `1.2gb`.
*
* Not `@ultimat3/ui`'s `formatBytes(bytes, locale)`, which is `Intl`-formatted, DECIMAL (kB = 1000
* B, because that is what `Intl`'s unit means) and for a human reading a file picker. This one is
* for an error's `cause:`, where the number has to line up with a bundler's own KiB figures and
* must not change with the reader's locale.
*
* A negative or non-finite input answers `0b` rather than `-5b` or `NaNb`: axiom 4 says an error is
* an instruction, and `NaNb` instructs nobody. A size is never negative, so the input was already
* wrong by the time it arrived.
*/
export const formatBytes = (bytes: number): string => {
if (!Number.isFinite(bytes) || bytes <= 0) return `0${UNITS[0]}`;
let value = bytes;
let index = 0;
while (index < UNITS.length - 1 && value >= STEP) {
value /= STEP;
index += 1;
}
// One more rung when ROUNDING crosses the boundary the raw value did not: 1048575 is under a
// mebibyte, but one decimal place renders it `1024kb` — a number that disagrees with its own
// unit, the same class of bug as render's missing `mb` branch.
if (index < UNITS.length - 1 && round1(value) >= STEP) {
value /= STEP;
index += 1;
}
return `${round1(value)}${UNITS[index] ?? 'b'}`;
};
// Single responsibility: the declared name a mistyped one most likely meant, so any error can lead
// with the real one. It lives in core because three packages need the same answer — `@ultimat3/cli`
// for an unknown command, flag or positional, `@ultimat3/policy` for an unknown permission — and
// two copies of one cutoff are two suggestions for one typo.
/**
* Levenshtein distance. A grid rather than two rolling rows because `noUncheckedIndexedAccess`
* makes every read an `?? 0`, and one `at()` reads better than four of them.
*/
const distance = (a: string, b: string): number => {
const rows = a.length + 1;
const cols = b.length + 1;
const grid: number[] = new Array<number>(rows * cols).fill(0);
const at = (r: number, c: number): number => grid[r * cols + c] ?? 0;
for (let r = 0; r < rows; r += 1) grid[r * cols] = r;
for (let c = 0; c < cols; c += 1) grid[c] = c;
for (let r = 1; r < rows; r += 1) {
for (let c = 1; c < cols; c += 1) {
const cost = a[r - 1] === b[c - 1] ? 0 : 1;
grid[r * cols + c] = Math.min(at(r - 1, c) + 1, at(r, c - 1) + 1, at(r - 1, c - 1) + cost);
}
}
return at(rows - 1, cols - 1);
};
/** Past this many edits the "suggestion" is a different word, and a wrong lead is worse than none. */
const MAX_EDITS = 3;
/**
* The nearest candidate within `MAX_EDITS`, or `undefined` when nothing is close enough. Ties keep
* the FIRST candidate, which is the order the caller declared them in — `definePermissions([...])`
* and a `CommandSpec` list are both authored orders, and a stable answer is what lets a test pin one.
*/
export const nearestName = (input: string, candidates: readonly string[]): string | undefined => {
let best: string | undefined;
let bestScore = MAX_EDITS + 1;
for (const candidate of candidates) {
const score = distance(input, candidate);
if (score < bestScore) {
best = candidate;
bestScore = score;
}
}
return best;
};
+58
-4

@@ -82,8 +82,13 @@ # @ultimat3/core — agent notes

`describeValue` in `error-render.ts` is a character-for-character duplicate of `describeValue` in
`describeValue` in `error-render.ts` is a deliberate duplicate of `describeValue` in
`packages/schema/src/describe-value.ts`, for the same tier-0 reason `SCHEMA_ERROR_CODE_TITLES` is
one: schema and core are both tier 0 and `core → schema` is **not** a declared edge in
`scripts/lib/tiers.ts`, so neither may import the other. Keep the two identical; a pin test in
`scripts/lib/tiers.ts`, so neither may import the other. Keep the two ANSWERING identically — that
is the contract, and the source is no longer character-for-character: schema counts characters
through `char-count.ts`, which core copies privately. A pin test in
`@ultimat3/cli` (which may legally import both) is the mechanical half, the same shape as
`schema-error-codes-pin.test.ts`. The rule it enforces: a `cause` reaches the log index AND the
`schema-error-codes-pin.test.ts`. **A string's length is CODE POINTS in both, `As of 2026-08-22`**
— `validators.ts` rejects in that unit and `json-schema.ts` publishes `minLength` in it, so
`.length` made `t.string.min(3).safeParse('👍a')` say "at least 3 chars, received a string of 3
characters". The rule it enforces: a `cause` reaches the log index AND the
HTTP problem document, redaction is by log FIELD key, and a value baked into a message string has

@@ -179,2 +184,13 @@ no key left to redact — so `parseId`/`uuidTimestamp` describe a rejected id and never echo it.

`format-bytes.ts` is the same rule at its smallest, `As of 2026-08-22`: one `formatBytes(bytes)`,
1024-base, `b|kb|mb|gb`, for the byte count an error message carries. `@ultimat3/render` (t4) and
`@ultimat3/pwa` (t4) each had one and they had diverged — render's stopped at `kb`, so a 5 MiB route
read `5120kb` in `X_BUDGET_EXCEEDED` and `5mb` in the precache warning about the same bytes, and
`@ultimat3/cli`'s budget error imported render's. Deliberately NOT
`@ultimat3/ui`'s `formatBytes(bytes, locale)`, which is a different function and stays: that one is
`Intl`-formatted and DECIMAL (kB = 1000 B, which is what `Intl`'s unit means), for a human reading a
file picker, where this one must line up with a bundler's own KiB figures and must not move with the
reader's locale. **Not mechanised** — no gate refuses a third copy, unlike `render-modes.ts` for the
route vocabulary; a `formatBytes` reappearing in `packages/*/src` is caught by review only.
`mcp-exposure.ts` is the same shape for a declaration rather than an algorithm: `isMcpExposed` is

@@ -212,2 +228,12 @@ the ONE answer to "did this primitive opt into being an MCP tool?", asked by `action`, `query`

**An empty `spanId` means "no inbound decision", and every reader must honour it, `As of
2026-08-22`.** `currentSpanContext()` synthesises `{ traceId, spanId: '', traceFlags: 1 }` from the
request context — a trace id this process minted, plus the header it would send onward. Handing
that to `Sampler.shouldSample` as a parent made `parentBasedRatioSampler` inherit a bit nobody sent,
so at ratio 0 a root span outside a request exported 0 and one inside exported 1 — and
`@ultimat3/http`'s `pipeline.ts` is `runWithContext` then `withSpan`, so **every HTTP root span was
exported at every ratio**. `startSpan` now narrows through `inboundParent()`: the trace id is
carried, the decision is not. It is the same discriminator `end()` already used to drop a synthetic
`parentSpanId`.
The OTLP exporters are built, not wrapped, and the case is in

@@ -222,2 +248,11 @@ [`docs/idea/18-build-vs-wrap.md`](../../docs/idea/18-build-vs-wrap.md): OTLP/HTTP JSON is `fetch`

**Three OTLP variables, three codes, `As of 2026-08-22`** — `X_OTLP_ENDPOINT_INVALID`,
`X_OTLP_HEADERS_INVALID`, `X_OTLP_PROTOCOL_UNSUPPORTED`, one per variable an operator sets. The
headers one is not a duplicate of the endpoint one: `otlpHeaders` percent-decodes, so `%zz` in
`OTEL_EXPORTER_OTLP_HEADERS` used to take the process down with a bare `URIError` at exporter
construction, and raising the ENDPOINT code instead would send the first reader of
`x errors explain` to inspect a variable that is fine. A title is what an agent reads first, and an
accurate `cause:` does not rescue one that misdirects. The header **key** is in the cause, the fix
and `meta`; the **value** is in none of them — it is the collector's credential.
`error-reporter.ts` is the same shape a third time: `ErrorReporter`, a no-op default, a memory

@@ -254,3 +289,13 @@ reporter for tests, and a transport on the wire (`error-reporter-sentry.ts`, an optional separate

named check passes, and `HealthReport.checks` carries them by name because "alert on check
failures by check name" is not writable against a boolean. Checks are **synchronous** on purpose:
failures by check name" is not writable against a boolean. `HealthReport.registered` carries the
COUNT beside it, `As of 2026-08-22`: `checks: {}` reads identically for "every check passed" and
"nobody registered one", and only the second is a `/readyz` meaning no more than "the socket is
bound". Reported, never enforced — **an empty registry is still `ready`, and `/readyz` still
answers 200**: `Object.values({}).every(…)` is vacuously true, and that is deliberate so a role
with no dependency does not have to invent a check to boot. `registered` is the field a caller
reads to tell "all checks passed" from "there were none".
`readinessChecks()` builds its record through `Object.fromEntries`, never by assigning
`results[name]` — assignment to the one name `__proto__` sets the PROTOTYPE rather than adding a
key, so a check by that name disappeared from the report and a `failing` one answered 200. Checks are **synchronous** on purpose:
a probe that awaits a network call turns a slow dependency into a wedged endpoint and a restart

@@ -262,2 +307,11 @@ loop, so the owner of the dependency keeps a boolean fresh and this reads it. Liveness ignores

**`drain()`'s memo is published BEFORE the first hook runs, `As of 2026-08-22`, and that ordering
is the whole of the function.** A hook may call back into `drain()` and one does — `handle.stop()`
in `@ultimat3/http` is `drain('manual')`, and an `accept` hook is exactly where a server stops
listening — while `settleWithin` invokes a hook SYNCHRONOUSLY. `drainPromise = (async () => …)()`
had therefore not assigned when the first hook ran: the re-entrant call read `undefined`, started a
second whole drain and recursed **~4,700 deep** until the stack ran out, every level swallowed by
`settleWithin` as `shutdown hook failed`. The guard and the registration are now one synchronous
step (`jobs`' `worker.ts` states the same rule), with the phases in `runDrain`.
**The drain deadline is enforced, not merely computed, and there is no unbounded state.**

@@ -264,0 +318,0 @@ `ShutdownReason.deadlineAt` was always handed to every hook and **no hook has ever read it** —

+1
-1
{
"name": "@ultimat3/core",
"version": "7.0.0",
"version": "8.0.0",
"description": "Ultimate's foundation: errors, context, env, config, clock, ids, logging, telemetry, lifecycle",

@@ -5,0 +5,0 @@ "license": "MIT",

@@ -325,2 +325,11 @@ # 🧱 @ultimat3/core

`shutdownHookCount()` is the test-only probe that makes the leak assertable.
- `registerReadinessCheck(name, check)` is what makes `/readyz` mean **usable** rather than
**bound**. `ReadinessCheck` is `() => boolean` and must stay synchronous — a probe that awaits its
dependency turns a slow dependency into a wedged endpoint and then a restart loop; keep a boolean
fresh and let the check read it. It returns an unregister. `HealthReport.checks` is a map of name
→ `'ok' | 'failing'`, so "alert on check failures by check name" is writable.
- **`HealthReport.registered` is the third state.** `checks: {}` reads identically for "every check
passed" and "nobody registered one", and an **empty registry is still ready** — reported, never
enforced, so a role with no dependency does not have to invent a check to boot. Read `registered`
before trusting an empty `checks`.
- Anything that opens a socket calls `markListening(server.url.origin)` and releases it on close.

@@ -327,0 +336,0 @@ That is what tells the sealed test network a loopback request is this process, not egress.

@@ -25,3 +25,3 @@ // Single responsibility: `app.config.ts` — the one config file. Deeply optional with real

/**
* Where a browser that failed `auth: 'required'` is sent, and where it lands afterwards.
* Where a browser that failed `auth: 'required'` is sent.
*

@@ -32,28 +32,20 @@ * `signInPath: null` is the default and the redirect stays off until an app names its page: the

* right answer for an agent, and what a browser got in production until this existed.
*
* `afterSignInPath` was removed 2026-08 for the reason `urlEnv`, `poolSize` and `schema` were
* (below): accepted, defaulted and merged here, and read by NO file — `dummy/social-media-clone`
* set `/dashboard` and got whatever its sign-in route did on its own. The landing path belongs to
* the app's sign-in route, which is the only code that can honour it.
*/
export interface AuthConfig {
readonly signInPath: string | null;
/**
* Where sign-in lands when there is nowhere to return to, or `?next=` is not same-origin.
*
* **Consulted by nothing, `As of 2026-08.`** Accepted, defaulted and merged here and read by no
* file in the repo — `dummy/social-media-clone/app.config.ts` sets `/dashboard` and gets
* whatever the sign-in route does on its own. Same shape `urlEnv`, `poolSize` and `schema` were
* deleted for below; this one is not deleted yet only because its writer is a tracked app's
* config, so removing the key and the line that sets it is one commit across two file sets.
*/
readonly afterSignInPath: string;
}
/**
* `installPrompt` was removed 2026-08, same rule: `@ultimat3/pwa`'s `createInstallController` is
* real and complete, nothing ever threaded the flag into it, and both tracked apps plus every
* scaffolded app set a switch with no wire. Call the controller from your own affordance instead.
*/
export interface PwaConfig {
readonly enabled: boolean;
readonly offline: OfflineStrategy;
/**
* **Consulted by nothing, `As of 2026-08.`** `wiki/Configuration.md` describes it as "render
* your own install affordance from the deferred event", both tracked apps set it, and
* `x new`'s scaffold writes it into every generated app — and no file reads it.
* `@ultimat3/pwa`'s `install.ts` is real and complete; nothing threads this flag into it.
* Delete the key or thread it; leaving it is a switch with no wire.
*/
readonly installPrompt: boolean;
readonly backgroundSync: boolean;

@@ -128,14 +120,12 @@ readonly push: boolean;

/**
* No `modelEnv`. It named the env KEY holding the model id, "so no model string is baked into the
* image" — and its only reader was this file's own merge, copying input to output. Nothing
* consumed the merged value, so `modelEnv: 'ANTHROPIC_MODEL'` selected no model: `@ultimat3/ai`
* reads env for API KEYS only, and the model is `request.model ?? DEFAULT_MODEL`, a compile-time
* constant in `models.ts`. The exact thing the key existed to prevent is what it delivered.
* Deleted 2026-08 — pass `model` on the request, or read your own env key and pass it.
*/
export interface AiConfig {
readonly mcp: McpConfig;
/**
* Env key for the model id, so no model string is baked into the image — **an intention, not a
* behaviour, `As of 2026-08`.** The only read of it in the repo is the merge two hundred lines
* below, which copies it from input to output; nothing consumes the merged value, so
* `examples/dummy`'s `modelEnv: 'ANTHROPIC_MODEL'` selects no model. `@ultimat3/ai` reads env
* for API KEYS only (`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`); the model is
* `request.model ?? DEFAULT_MODEL`, a compile-time constant in `models.ts`. So the exact thing
* this key exists to prevent — a model string baked into the image — is what actually happens.
*/
readonly modelEnv: string | undefined;
}

@@ -162,3 +152,4 @@

export interface AiConfigInput extends Input<Omit<AiConfig, 'mcp'>> {
/** `mcp` is the only member, and it is NESTED — `Input<AiConfig>` would make it all-or-nothing. */
export interface AiConfigInput {
readonly mcp?: Input<McpConfig> | undefined;

@@ -231,10 +222,4 @@ }

theme: { defaultMode: 'system', tokens: {} },
auth: { signInPath: null, afterSignInPath: '/' },
pwa: {
enabled: false,
offline: 'network-only',
installPrompt: false,
backgroundSync: false,
push: false,
},
auth: { signInPath: null },
pwa: { enabled: false, offline: 'network-only', backgroundSync: false, push: false },
roles: [...ROLES],

@@ -251,3 +236,3 @@ database: { driver: 'postgres', ssl: false },

realtime: { enabled: false, tier: 'channels', transport: 'memory', urlEnv: undefined },
ai: { mcp: { expose: true, path: '/mcp' }, modelEnv: undefined },
ai: { mcp: { expose: true, path: '/mcp' } },
};

@@ -346,6 +331,3 @@ }

realtime: section(base.realtime, merged.realtime),
ai: {
mcp: section(base.ai.mcp, merged.ai?.mcp),
modelEnv: merged.ai?.modelEnv ?? base.ai.modelEnv,
},
ai: { mcp: section(base.ai.mcp, merged.ai?.mcp) },
};

@@ -352,0 +334,0 @@

@@ -73,3 +73,9 @@ // Single responsibility: the ambient request context. Authz, tracing, locale, tz and the

export type CtxPatch = Omit<CtxInit, 'requestId'>;
/**
* Neither id a child may change. `requestId` because one request is one request however many
* scopes it opens; `buildId` because a child context is the same DEPLOY — `withChildContext`
* has always forwarded the parent's, so accepting the key was an option that read as honoured and
* was dropped in silence. Pinned in `type-pins.ts`.
*/
export type CtxPatch = Omit<CtxInit, 'requestId' | 'buildId'>;

@@ -76,0 +82,0 @@ /**

@@ -51,3 +51,2 @@ /**

function compare(left: Decimal, right: Decimal): number {
if (left.negative !== right.negative) return left.negative ? -1 : 1;
const width = Math.max(left.fraction.length, right.fraction.length);

@@ -58,2 +57,7 @@ const scaled = (value: Decimal): bigint =>

const second = scaled(right);
// Magnitude BEFORE sign, because a `numeric` has exactly one zero: `select '-0'::numeric =
// '0'::numeric` is true, and so is `'-0.00' = '0'`. Comparing the sign first answered `-1` for
// that pair and cut a keyset page boundary between two rows the database calls equal.
if (first === 0n && second === 0n) return 0;
if (left.negative !== right.negative) return left.negative ? -1 : 1;
// Never a subtraction: the difference between two `bigint`s is exact and the return type is a

@@ -60,0 +64,0 @@ // `number`, which cannot hold it.

@@ -56,2 +56,5 @@ // Single responsibility: the framework-wide error-code registry (code -> title + docs).

X_OTLP_ENDPOINT_INVALID: 'the OTLP collector endpoint is missing or malformed',
// Its own code rather than the endpoint's, because a title is what an agent reads first:
// `x errors explain X_OTLP_ENDPOINT_INVALID` would send it to inspect a variable that is fine.
X_OTLP_HEADERS_INVALID: 'OTEL_EXPORTER_OTLP_HEADERS is malformed',
X_OTLP_PROTOCOL_UNSUPPORTED: 'the OTLP protocol requested is not OTLP/HTTP JSON',

@@ -58,0 +61,0 @@ X_READINESS_CHECK_DUPLICATE: 'a readiness check name is registered twice',

@@ -255,6 +255,6 @@ // Single responsibility: turn a value the framework does not control into text for an error's

*
* A deliberate, character-for-character duplicate of `describeValue` in
* `packages/schema/src/describe-value.ts`, for the reason `SCHEMA_ERROR_CODE_TITLES` is one:
* `@ultimat3/schema` is tier 0 alongside this package, so neither may import the other. Keep the
* two identical; changing one alone is the bug.
* A deliberate duplicate of `describeValue` in `packages/schema/src/describe-value.ts`, for the
* reason `SCHEMA_ERROR_CODE_TITLES` is one: `@ultimat3/schema` is tier 0 alongside this package,
* so neither may import the other. Keep the two answering IDENTICALLY — that is what
* `packages/cli/src/describe-value-pin.test.ts` holds — and changing one alone is the bug.
*/

@@ -266,3 +266,3 @@ export function describeValue(value: unknown): string {

case 'string':
return countOf(value.length, 'string', 'character');
return countOf(charCount(value), 'string', 'character');
case 'number':

@@ -299,1 +299,13 @@ return describeNumber(value);

}
/**
* The twin of `@ultimat3/schema`'s `char-count.ts`, duplicated for the same reason `describeValue`
* is: both packages are tier 0 and neither may import the other. Code points, because the rules
* that reject a string count in them and the message must quote the same unit — `'👍'.length` is 2.
* Only a surrogate makes the two counts differ, so every ASCII value keeps the O(1) read.
*/
const HAS_SURROGATE = /[\uD800-\uDBFF]/;
function charCount(value: string): number {
return HAS_SURROGATE.test(value) ? [...value].length : value.length;
}

@@ -45,2 +45,3 @@ // The observability slice of `@ultimat3/core`'s public surface, in one place: logging, metrics,

setLoggerContextFields,
setLogStream,
} from '../logger';

@@ -92,2 +93,3 @@ export type {

OtlpEndpointInvalidError,
OtlpHeadersInvalidError,
OtlpProtocolUnsupportedError,

@@ -94,0 +96,0 @@ otlpAttributes,

@@ -271,2 +271,3 @@ // Single responsibility: the public API of @ultimat3/core. Explicit named exports only —

OtlpEndpointInvalidError,
OtlpHeadersInvalidError,
OtlpProtocolUnsupportedError,

@@ -307,2 +308,3 @@ OVERFLOW_ATTRIBUTE,

setLoggerContextFields,
setLogStream,
startMetricExport,

@@ -374,2 +376,3 @@ startSpan,

} from './exports/secrets';
export { formatBytes } from './format-bytes';
export type { Brand, Id } from './ids';

@@ -465,13 +468,15 @@ export {

} from './lifecycle';
export {
isSelfOrigin,
listeningOrigins,
markListening,
resetListeners,
} from './listeners';
export { isSelfOrigin, listeningOrigins, markListening, resetListeners } from './listeners';
export { isMcpExposed, type McpExposureDeclaration } from './mcp-exposure';
export { nearestName } from './nearest-name';
export { type CappedBody, readWithinLimit } from './read-capped';
export type { ModuleRegistrar, PrimitiveKind, RegisteredPrimitive } from './registrar';
export type {
ModuleRegistrar,
PrimitiveFactory,
PrimitiveKind,
RegisteredPrimitive,
} from './registrar';
export {
hasPrimitiveRegistrar,
PRIMITIVE_FACTORIES,
PRIMITIVE_KINDS,

@@ -478,0 +483,0 @@ primitiveRegistrar,

@@ -85,2 +85,10 @@ // Single responsibility: process lifecycle and graceful drain. Every role runs the same three

readonly checks: Readonly<Record<string, ReadinessStatus>>;
/**
* How many checks are registered. `checks: {}` reads identically for "every check passed" and
* "nobody registered one", and only the second is a `/readyz` that means no more than "the
* socket is bound" — which is what the chart's and compose's healthchecks route traffic on.
* Reported rather than enforced: an empty registry is still ready, so a role that genuinely has
* no dependency does not have to invent a check to boot.
*/
readonly registered: number;
}

@@ -196,14 +204,21 @@

/** Every check, run now, by name. A check that throws is `failing` — never an unhandled error. */
/**
* Every check, run now, by name. A check that throws is `failing` — never an unhandled error.
*
* Built through `Object.fromEntries`, never by assigning `results[name]`: assignment to the one
* name `__proto__` sets the PROTOTYPE instead of adding a key, so that check vanished from the
* report, `ready` was computed over an empty object — vacuously true — and a failing check
* answered 200. `fromEntries` defines own properties and has no such name.
*/
export function readinessChecks(): Readonly<Record<string, ReadinessStatus>> {
const results: Record<string, ReadinessStatus> = {};
const results: [string, ReadinessStatus][] = [];
for (const [name, check] of readiness) {
try {
results[name] = check() ? 'ok' : 'failing';
results.push([name, check() ? 'ok' : 'failing']);
} catch (thrown) {
results[name] = 'failing';
results.push([name, 'failing']);
report('warn', 'readiness check threw', { check: name, error: thrown });
}
}
return results;
return Object.fromEntries(results);
}

@@ -333,3 +348,46 @@

/** Idempotent: concurrent signals join the same drain. */
/** The three phases, in order, under one budget. Never rejects — `drain()` depends on that. */
async function runDrain(signal: string, reason: ShutdownReason): Promise<void> {
try {
report('info', 'draining', { signal, deadlineMs, inflight });
await runPhase('accept', reason);
// Real monotonic, like `deadlineAt` itself: `waitForIdle` sleeps on a real `setTimeout`, and
// a budget read off an injected clock is a number that timer will never honour.
const remaining = Math.max(0, reason.deadlineAt - systemClock.monotonic());
const idle = await waitForIdle(remaining);
if (!idle) {
report('warn', 'X_SHUTDOWN_TIMEOUT', {
code: 'X_SHUTDOWN_TIMEOUT',
cause: `${inflight} in-flight operations still running after ${deadlineMs}ms`,
fix: 'raise the budget past the slowest handler — configureLifecycle({ deadlineMs: 600_000 }) for a 10-minute one — and set terminationGracePeriodSeconds to at least as many seconds, or shorten the handler',
});
}
await runPhase('inflight', reason);
await runPhase('close', reason);
} catch (thrown) {
// Nothing above should reach here — every hook is caught by `settleWithin` and every line
// goes through `report`. If something does, the drain still ENDS: a rejected `drainPromise`
// is a memo that re-rejects for every later caller and an unhandled rejection that kills the
// process mid-drain, which is strictly worse than a drain that finished badly and said so.
report('error', 'drain failed', { signal, error: thrown });
} finally {
state = 'stopped';
}
report('info', 'stopped', { signal });
}
/**
* Idempotent: concurrent signals join the same drain, and so does a RE-ENTRANT one.
*
* The memo is published before `runDrain` is called, and that ordering is the whole of this
* function. A hook may call back in here — `handle.stop()` in `@ultimat3/http` is `drain('manual')`
* and an `accept` hook is exactly where a server stops listening — and `settleWithin` invokes a
* hook SYNCHRONOUSLY, so the old `drainPromise = (async () => …)()` had not assigned yet when the
* first hook ran: the re-entrant call saw `undefined`, started a second whole drain, and recursed
* ~4,700 deep until the stack ran out, every level swallowed by `settleWithin` as
* `shutdown hook failed`. Same rule as `packages/jobs/src/worker.ts` — guard and registration in
* one synchronous step.
*/
export function drain(signal = 'manual'): Promise<void> {

@@ -339,34 +397,10 @@ if (drainPromise !== undefined) return drainPromise;

const reason: ShutdownReason = { signal, deadlineAt: systemClock.monotonic() + deadlineMs };
drainPromise = (async () => {
try {
report('info', 'draining', { signal, deadlineMs, inflight });
await runPhase('accept', reason);
// Real monotonic, like `deadlineAt` itself: `waitForIdle` sleeps on a real `setTimeout`, and
// a budget read off an injected clock is a number that timer will never honour.
const remaining = Math.max(0, reason.deadlineAt - systemClock.monotonic());
const idle = await waitForIdle(remaining);
if (!idle) {
report('warn', 'X_SHUTDOWN_TIMEOUT', {
code: 'X_SHUTDOWN_TIMEOUT',
cause: `${inflight} in-flight operations still running after ${deadlineMs}ms`,
fix: 'raise the budget past the slowest handler — configureLifecycle({ deadlineMs: 600_000 }) for a 10-minute one — and set terminationGracePeriodSeconds to at least as many seconds, or shorten the handler',
});
}
await runPhase('inflight', reason);
await runPhase('close', reason);
} catch (thrown) {
// Nothing above should reach here — every hook is caught by `settleWithin` and every line
// goes through `report`. If something does, the drain still ENDS: a rejected `drainPromise`
// is a memo that re-rejects for every later caller and an unhandled rejection that kills the
// process mid-drain, which is strictly worse than a drain that finished badly and said so.
report('error', 'drain failed', { signal, error: thrown });
} finally {
state = 'stopped';
}
report('info', 'stopped', { signal });
})();
let published!: () => void;
drainPromise = new Promise<void>((resolve) => {
published = resolve;
});
// Both settle paths, for the reason `installSignalHandlers` gives below: `runDrain` cannot
// reject today — that is its `try/finally`, not luck — and a rejected memo would re-reject for
// every later caller and end the process the drain was trying to end cleanly.
void runDrain(signal, reason).then(published, published);
return drainPromise;

@@ -417,2 +451,3 @@ }

checks,
registered: readiness.size,
};

@@ -419,0 +454,0 @@ }

@@ -104,4 +104,24 @@ // Single responsibility: structured JSON logging. One line per event, machine-readable by

/**
* Where a line with no explicit writer lands, for everything below `error`. A fact about the
* PROCESS and not about the line: a container's stdout IS its log stream (12-factor), while a
* CLI's stdout is the answer it was asked for. `x db migrate --json` printed the boot logger's
* `ultimate migrate applied` and then the command's own JSON to fd 1, so a caller doing what
* `--json` exists for — parsing the output — raised on the second object.
*/
let logStream: 'stdout' | 'stderr' = 'stdout';
/**
* Send everything below `error` to stderr, or back to stdout. The process's own call, made once at
* entry: a per-line choice would be the second logging path axiom 1 refuses, and a per-logger one
* already exists as `LoggerOptions.writer` — what had no seam is the module-scope `logger`, which
* is the one `serve.ts` and every boot path write through.
*/
export function setLogStream(stream: 'stdout' | 'stderr'): void {
logStream = stream;
}
function defaultWriter(line: string, level: LogLevel): void {
const stream = LEVEL_WEIGHT[level] >= LEVEL_WEIGHT.error ? process.stderr : process.stdout;
const toStderr = logStream === 'stderr' || LEVEL_WEIGHT[level] >= LEVEL_WEIGHT.error;
const stream = toStderr ? process.stderr : process.stdout;
stream.write(`${line}\n`);

@@ -108,0 +128,0 @@ }

@@ -18,2 +18,16 @@ // Single responsibility: the pieces both OTLP exporters share — endpoint resolution from the env

/**
* Separate from `OtlpEndpointInvalidError` on purpose. The endpoint code's title says the ENDPOINT
* is missing or malformed, so raising it for a bad header escape sends the first reader of
* `x errors explain` to inspect `OTEL_EXPORTER_OTLP_ENDPOINT` — a variable that is fine. An
* accurate `cause:` does not rescue a title that misdirects.
*/
export class OtlpHeadersInvalidError extends UltimateError {
static readonly code = 'X_OTLP_HEADERS_INVALID';
override readonly name = 'OtlpHeadersInvalidError';
constructor(init: CodedErrorInit) {
super({ ...init, code: OtlpHeadersInvalidError.code });
}
}
export class OtlpProtocolUnsupportedError extends UltimateError {

@@ -116,2 +130,21 @@ static readonly code = 'X_OTLP_PROTOCOL_UNSUPPORTED';

/**
* One header value, percent-decoded. `decodeURIComponent` throws a bare `URIError` on a malformed
* escape (`%zz`, a lone `%`), and the whole of `otlpHeaders` runs at exporter construction — so a
* typo in an operator-set variable took the process down with an error carrying no code, no cause
* and no fix. Refused instead, naming the variable and the header KEY: the value is the
* collector's credential and a `cause:` is folded into a log line.
*/
function decodeHeaderValue(key: string, raw: string): string {
try {
return decodeURIComponent(raw);
} catch {
throw new OtlpHeadersInvalidError({
cause: `${OTLP_HEADERS_KEY} carries a malformed percent-escape in the "${key}" value, so the header cannot be decoded`,
fix: `set ${OTLP_HEADERS_KEY}=${key}=<encoded>, where <encoded> is what bun -e 'console.log(encodeURIComponent(process.argv[1]))' <value> prints — or drop the stray % from the "${key}" value if it was meant literally`,
meta: { header: key },
});
}
}
/** `key=value,key2=value2`, percent-decoded — the spec's format for collector auth headers. */

@@ -130,3 +163,3 @@ export function otlpHeaders(

if (key === '') continue;
headers[key] = decodeURIComponent(pair.slice(index + 1).trim());
headers[key] = decodeHeaderValue(key, pair.slice(index + 1).trim());
}

@@ -133,0 +166,0 @@ }

@@ -30,3 +30,40 @@ // Hands a module of primitives to the package that owns them, without a sideways import:

/** One factory over one primitive: the export's name, the package that ships it, what it returns. */
export interface PrimitiveFactory {
readonly factory: string;
/** The package specifier the factory is imported from, so a `fix:` can be pasted. */
readonly pkg: string;
readonly kind: PrimitiveKind;
}
/**
* The other half of "never invent a ninth": the factories that already exist, in one table.
*
* Prose counted them — "the fourth instance of the framework's factory rule" — in three files that
* cannot see each other, so every ordinal was wrong the moment a fifth landed and none of them
* could be checked. A list here can be: `@ultimat3/cli` is tier 5, may import `ai`, `jobs` and
* `scraping`, and pins that every exported function returning an `Action`/`JobHandle` from outside
* their owning packages has a row. Adding a factory means adding a row, not editing a sentence.
*
* Sorted by package then name so the diff of a new row is one line.
*
* Every ROW is frozen, not just the list. `readonly` fields are a compile-time claim and this is a
* public export: freezing the array alone left `PRIMITIVE_FACTORIES[0].kind = 'entity'` a silent
* write from any untyped caller, which is the same defect `@ultimat3/money`'s currency rows
* carried — a table the framework hands out is a constant at RUNTIME or it is not a constant.
*/
export const PRIMITIVE_FACTORIES = Object.freeze<readonly PrimitiveFactory[]>(
(
[
{ factory: 'agent', pkg: '@ultimat3/ai', kind: 'action' },
{ factory: 'agentJob', pkg: '@ultimat3/ai', kind: 'job' },
{ factory: 'hive', pkg: '@ultimat3/ai', kind: 'action' },
{ factory: 'llm', pkg: '@ultimat3/ai', kind: 'action' },
{ factory: 'backfill', pkg: '@ultimat3/jobs', kind: 'job' },
{ factory: 'scrape', pkg: '@ultimat3/scraping', kind: 'job' },
] satisfies readonly PrimitiveFactory[]
).map((entry) => Object.freeze(entry)),
);
/**
* What a registrar hands back: the primitives it actually took, each carrying the name

@@ -33,0 +70,0 @@ * registration stamped on it. Returning the registered set — rather than nothing — is what lets

@@ -170,3 +170,9 @@ // Single responsibility: OpenTelemetry-shaped tracing that is always on. The default exporter

/** The trace the caller is inside: active span, else the request context, else a fresh trace. */
/**
* The trace the caller is inside: active span, else the request context, else a fresh trace.
*
* The context branch carries an EMPTY `spanId` on purpose, and that emptiness is the discriminator
* every reader must honour: it is a trace id this process minted, not a span an upstream reported.
* `traceFlags: 1` here is the header this process would send onward, never a decision it received.
*/
export function currentSpanContext(): SpanContext | undefined {

@@ -180,4 +186,16 @@ const span = activeSpan.get();

/**
* A parent an upstream actually reported, as opposed to the synthetic one `currentSpanContext()`
* builds from a request context. Only the first carries a sampling decision: reading the synthetic
* one as inbound made `parentBasedRatioSampler` inherit a bit nobody sent, so every HTTP root span
* was exported at every ratio — `pipeline.ts` is `runWithContext` then `withSpan`, which is that
* exact pair — and the one lever between "tracing is on" and "the collector melts" did nothing.
*/
function inboundParent(parent: SpanContext | undefined): SpanContext | undefined {
return parent === undefined || parent.spanId === '' ? undefined : parent;
}
export function startSpan(name: string, options?: StartSpanOptions): Span {
const parent = options?.parent ?? currentSpanContext();
const inbound = inboundParent(parent);
const attributes: Record<string, AttributeValue> = { ...(options?.attributes ?? {}) };

@@ -191,3 +209,3 @@ // The bit is decided ONCE, here, and every child of this span inherits it through `parent` —

spanId: newSpanId(),
traceFlags: currentSampler().shouldSample(name, parent, attributes) ? 1 : 0,
traceFlags: currentSampler().shouldSample(name, inbound, attributes) ? 1 : 0,
};

@@ -251,3 +269,3 @@ const events: SpanEvent[] = [];

const endedAt = clock.now().getTime();
const parentSpanId = parent === undefined || parent.spanId === '' ? undefined : parent.spanId;
const parentSpanId = inbound?.spanId;
exporter.export({

@@ -254,0 +272,0 @@ name,

@@ -1,2 +0,3 @@

// Compile-time pins for the actor-facts seam, the config surface and the route vocabulary.
// Compile-time pins for the actor-facts seam, the config surface, the request-context patch and
// the route vocabulary.
// Source, not a `.test.ts`, on purpose: `tsconfig.json` excludes `src/**/*.test.ts`, so `tsc -b`

@@ -8,2 +9,3 @@ // never reads a test file and a type-level assertion written there can never fail. This module

import type { AppConfigInput, DatabaseConfig } from './config';
import type { CtxPatch } from './context';
import type { HydrateStrategy, OfflineStrategy, RenderMode } from './route-vocabulary';

@@ -104,2 +106,19 @@

/**
* Neither id a child context may patch. `withChildContext` forwards the parent's `buildId`
* verbatim, so `{ buildId }` on the patch was an option that read as honoured and was dropped
* without a word — the same silent-no-op class as the three `database` fields above, one tier
* lower. `requestId` is here beside it because the two are refused for the same reason.
*/
type UnpatchableCtxKey = 'requestId' | 'buildId';
type _CtxPatchRefusesTheIds = Assert<
Extract<keyof CtxPatch, UnpatchableCtxKey> extends never ? true : false
>;
/** And the keys a child MAY change are still there — a pin that empties the type is not a pin. */
type _CtxPatchStillPatchesTheRest = Assert<
'actor' | 'locale' | 'tz' extends keyof CtxPatch ? true : false
>;
/**
* Mutual assignability, not one-way. The tuples are load-bearing: a bare `A extends B` distributes

@@ -106,0 +125,0 @@ * over a union and answers `true` for every member separately, so it cannot see a widening — which