dominus-sdk-nodejs 11.0.6 → 11.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +2 -2
  2. package/dist/index.d.ts +7 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +6 -0
  5. package/dist/index.js.map +1 -1
  6. package/dist/namespaces/artifacts.d.ts.map +1 -1
  7. package/dist/namespaces/artifacts.js +13 -2
  8. package/dist/namespaces/artifacts.js.map +1 -1
  9. package/dist/namespaces/authority.d.ts +8 -0
  10. package/dist/namespaces/authority.d.ts.map +1 -1
  11. package/dist/namespaces/authority.js +21 -0
  12. package/dist/namespaces/authority.js.map +1 -1
  13. package/dist/namespaces/recipes.d.ts +17 -1
  14. package/dist/namespaces/recipes.d.ts.map +1 -1
  15. package/dist/namespaces/recipes.js +23 -2
  16. package/dist/namespaces/recipes.js.map +1 -1
  17. package/dist/namespaces/secrets.js +4 -4
  18. package/dist/namespaces/secrets.js.map +1 -1
  19. package/dist/refs/grammar.d.ts +54 -0
  20. package/dist/refs/grammar.d.ts.map +1 -0
  21. package/dist/refs/grammar.js +179 -0
  22. package/dist/refs/grammar.js.map +1 -0
  23. package/dist/refs/resolve.d.ts +49 -0
  24. package/dist/refs/resolve.d.ts.map +1 -0
  25. package/dist/refs/resolve.js +129 -0
  26. package/dist/refs/resolve.js.map +1 -0
  27. package/dist/refs/types.d.ts +56 -0
  28. package/dist/refs/types.d.ts.map +1 -0
  29. package/dist/refs/types.js +15 -0
  30. package/dist/refs/types.js.map +1 -0
  31. package/docs/agent-guide/2026-08-25-2103-sdk-nodejs/00-reading-order.md +42 -0
  32. package/docs/agent-guide/2026-08-25-2103-sdk-nodejs/01-purpose-and-boundaries.md +45 -0
  33. package/docs/agent-guide/2026-08-25-2103-sdk-nodejs/02-repo-map-and-entrypoints.md +36 -0
  34. package/docs/agent-guide/2026-08-25-2103-sdk-nodejs/03-api-surface.md +59 -0
  35. package/docs/agent-guide/2026-08-25-2103-sdk-nodejs/04-data-state-and-storage.md +36 -0
  36. package/docs/agent-guide/2026-08-25-2103-sdk-nodejs/05-integrations-and-runtime.md +36 -0
  37. package/docs/agent-guide/2026-08-25-2103-sdk-nodejs/06-workflows-commands-and-ci.md +45 -0
  38. package/docs/agent-guide/2026-08-25-2103-sdk-nodejs/07-operations-release-and-live-proof.md +43 -0
  39. package/docs/agent-guide/2026-08-25-2103-sdk-nodejs/08-security-privacy-and-secrets.md +42 -0
  40. package/docs/agent-guide/2026-08-25-2103-sdk-nodejs/09-known-risks-and-debt.md +37 -0
  41. package/docs/agent-guide/2026-08-25-2103-sdk-nodejs/10-agent-playbook.md +51 -0
  42. package/docs/agent-guide/INDEX.md +19 -8
  43. package/docs/agent-guide/current.md +9 -8
  44. package/docs/atlas/INDEX.md +5 -1
  45. package/docs/janitor/2026-08-25-2103-sdk-nodejs-cleanup-audit.md +112 -0
  46. package/docs/routes-services.md +5 -0
  47. package/docs/usage-reference.md +15 -0
  48. package/package.json +1 -1
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Ref transport — the resolver seam that turns a parsed ref into a resolved,
3
+ * service-native receipt.
4
+ *
5
+ * `resolve()` owns transport and owns NO judgment: it asks the owning service
6
+ * for the answer and passes the response back unmodified as a discriminated
7
+ * receipt. It never re-derives tier, scope, or backend selection — those
8
+ * decisions belong to the services (enforced by E1). `parse()` is used only to
9
+ * pick the answering service and reject garbage; for `ar://` the original ref
10
+ * string crosses the wire verbatim and is never decomposed (enforced by E2).
11
+ *
12
+ * `recipe://` transport borrows the `/svc/stash/compose` fall-through contract:
13
+ * probe the Stash lane first, and on a typed `stash.not_found.*` or
14
+ * `stash.forbidden.scope_not_allowed` miss, fall through to the recipe-worker
15
+ * route. Every other `stash.*` error aborts and propagates unmodified — the
16
+ * overlay never reclassifies an upstream failure (the `SharedNeonClient.query()`
17
+ * anti-pattern this seam refuses to repeat). Backend selection is keyed on
18
+ * `err.code`, never on HTTP status.
19
+ */
20
+ import type { DominusClient } from '../lib/client.js';
21
+ import type { KernelRef } from './grammar.js';
22
+ import type { ResolvedRef } from './types.js';
23
+ /** Call-site options for {@link RefResolver.resolve}. */
24
+ export interface ResolveOptions {
25
+ /** Stash-lane read scope; consumed by the `recipe://` arm (no default). */
26
+ env?: string;
27
+ }
28
+ export declare class RefResolver {
29
+ private client;
30
+ constructor(client: DominusClient);
31
+ /**
32
+ * Parse a ref into its discriminated {@link KernelRef} with no I/O.
33
+ * Delegates to the pure grammar module (`src/refs/grammar.ts`); the
34
+ * resolver owns transport, not grammar.
35
+ */
36
+ parse(ref: string): KernelRef;
37
+ resolve(ref: string, options?: ResolveOptions): Promise<ResolvedRef>;
38
+ private resolveArtifact;
39
+ private resolveRecipe;
40
+ private resolveRecipeWorker;
41
+ }
42
+ /**
43
+ * The two typed legs that may fall through to the recipe-worker route. Keyed on
44
+ * `err.code`, never HTTP status — a 403-coded `scope_not_allowed` falls through
45
+ * while a 401-coded auth failure aborts. Exported so `RecipesNamespace.get`
46
+ * reuses the same predicate instead of maintaining a second copy.
47
+ */
48
+ export declare function isFallThrough(err: unknown): boolean;
49
+ //# sourceMappingURL=resolve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/refs/resolve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,cAAc,CAAC;AAEzD,OAAO,KAAK,EAA4B,WAAW,EAA0B,MAAM,YAAY,CAAC;AAEhG,yDAAyD;AACzD,MAAM,WAAW,cAAc;IAC7B,2EAA2E;IAC3E,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAKD,qBAAa,WAAW;IACV,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,aAAa;IAEzC;;;;OAIG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS;IAIvB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,WAAW,CAAC;YAkBhE,eAAe;YAgBf,aAAa;YA2Cb,mBAAmB;CAclC;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAInD"}
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Ref transport — the resolver seam that turns a parsed ref into a resolved,
3
+ * service-native receipt.
4
+ *
5
+ * `resolve()` owns transport and owns NO judgment: it asks the owning service
6
+ * for the answer and passes the response back unmodified as a discriminated
7
+ * receipt. It never re-derives tier, scope, or backend selection — those
8
+ * decisions belong to the services (enforced by E1). `parse()` is used only to
9
+ * pick the answering service and reject garbage; for `ar://` the original ref
10
+ * string crosses the wire verbatim and is never decomposed (enforced by E2).
11
+ *
12
+ * `recipe://` transport borrows the `/svc/stash/compose` fall-through contract:
13
+ * probe the Stash lane first, and on a typed `stash.not_found.*` or
14
+ * `stash.forbidden.scope_not_allowed` miss, fall through to the recipe-worker
15
+ * route. Every other `stash.*` error aborts and propagates unmodified — the
16
+ * overlay never reclassifies an upstream failure (the `SharedNeonClient.query()`
17
+ * anti-pattern this seam refuses to repeat). Backend selection is keyed on
18
+ * `err.code`, never on HTTP status.
19
+ */
20
+ import { DominusError, ValidationError } from '../lib/errors.js';
21
+ import { parse as parseGrammar, routeFor } from './grammar.js';
22
+ export class RefResolver {
23
+ client;
24
+ constructor(client) {
25
+ this.client = client;
26
+ }
27
+ /**
28
+ * Parse a ref into its discriminated {@link KernelRef} with no I/O.
29
+ * Delegates to the pure grammar module (`src/refs/grammar.ts`); the
30
+ * resolver owns transport, not grammar.
31
+ */
32
+ parse(ref) {
33
+ return parseGrammar(ref);
34
+ }
35
+ async resolve(ref, options = {}) {
36
+ const parsed = parseGrammar(ref);
37
+ if (parsed.scheme === 'ar') {
38
+ return this.resolveArtifact(parsed.ref);
39
+ }
40
+ if (parsed.scheme === 'unresolvable') {
41
+ throw new DominusError(`No route for ${parsed.attemptedScheme}:// refs: ${parsed.missingContract} (owner: ${parsed.owningService})`, 400, { code: 'ref.scheme.unresolvable', category: 'validation' });
42
+ }
43
+ return this.resolveRecipe(parsed, ref, options);
44
+ }
45
+ async resolveArtifact(ref) {
46
+ const receipt = await this.client.request({
47
+ endpoint: '/api/artifact/v2/retrieve',
48
+ method: 'POST',
49
+ body: { ref },
50
+ useGateway: true,
51
+ });
52
+ return {
53
+ source: 'artifact',
54
+ ref,
55
+ payload: receipt.data ?? '',
56
+ receipt,
57
+ };
58
+ }
59
+ async resolveRecipe(parsed, ref, options) {
60
+ const env = options.env;
61
+ if (env === undefined || env === '') {
62
+ throw new ValidationError('recipe:// stash-lane reads require an explicit env', 400, {
63
+ code: 'ref.env.required',
64
+ category: 'validation',
65
+ });
66
+ }
67
+ const version = toStashVersion(parsed.version);
68
+ try {
69
+ const response = await this.client.request({
70
+ endpoint: '/svc/stash/get',
71
+ method: 'POST',
72
+ body: {
73
+ env,
74
+ kind: parsed.type,
75
+ scope: 'self',
76
+ key: parsed.name,
77
+ ...(version !== undefined ? { version } : {}),
78
+ },
79
+ useGateway: true,
80
+ });
81
+ return {
82
+ source: 'stash',
83
+ ref,
84
+ payload: response.value,
85
+ receipt: response,
86
+ };
87
+ }
88
+ catch (err) {
89
+ if (isFallThrough(err)) {
90
+ return this.resolveRecipeWorker(parsed, ref);
91
+ }
92
+ throw err;
93
+ }
94
+ }
95
+ async resolveRecipeWorker(parsed, ref) {
96
+ const resolved = await this.client.request({
97
+ endpoint: `/api/recipe/recipes/${routeFor(parsed)}`,
98
+ method: 'GET',
99
+ useGateway: true,
100
+ });
101
+ return {
102
+ source: 'recipe-worker',
103
+ ref,
104
+ payload: resolved.body,
105
+ receipt: resolved.metadata,
106
+ };
107
+ }
108
+ }
109
+ /**
110
+ * The two typed legs that may fall through to the recipe-worker route. Keyed on
111
+ * `err.code`, never HTTP status — a 403-coded `scope_not_allowed` falls through
112
+ * while a 401-coded auth failure aborts. Exported so `RecipesNamespace.get`
113
+ * reuses the same predicate instead of maintaining a second copy.
114
+ */
115
+ export function isFallThrough(err) {
116
+ if (!(err instanceof DominusError))
117
+ return false;
118
+ const code = err.code ?? '';
119
+ return code.startsWith('stash.not_found.') || code === 'stash.forbidden.scope_not_allowed';
120
+ }
121
+ /** Map a `recipe://` version token to the stash version selector. */
122
+ function toStashVersion(version) {
123
+ if (version === undefined || version === 'head' || version === 'latest') {
124
+ return version;
125
+ }
126
+ const numeric = version.startsWith('v') ? version.slice(1) : version;
127
+ return Number(numeric);
128
+ }
129
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/refs/resolve.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Ref receipt types — the public return contract of the ref resolver seam.
3
+ *
4
+ * `ResolvedRef` is discriminated on `source` (the answering service). Each
5
+ * variant carries that service's own response as its `receipt`, unmodified —
6
+ * provenance is passed through, never normalized, never synthesized. Because
7
+ * `owner` exists on the recipe-worker variant (it is a field of the worker's
8
+ * own `RecipeMetadata`) and does NOT exist on the stash variant, an empty
9
+ * owner (`owner: ''`) is unrepresentable at compile time. E4 proves this.
10
+ *
11
+ * Shared across variants: `ref`, `source`, and `payload` only. No provenance
12
+ * field (tier, scope, owner, backend) is shared across variants.
13
+ */
14
+ import type { RecipeMetadata } from '../namespaces/recipes.js';
15
+ /** The `/svc/artifact/v2/retrieve` response (artifact-worker V2 retrieve). */
16
+ export interface ArtifactRetrieveResponse {
17
+ resolved_ref: string | null;
18
+ head_ref: string | null;
19
+ snapshot_ref: string | null;
20
+ version: number | null;
21
+ data: string | null;
22
+ content_type: string | null;
23
+ storage_type: 'redis' | 'b2' | null;
24
+ size_bytes: number | null;
25
+ expires_at: string | null;
26
+ }
27
+ /**
28
+ * The fields `/svc/stash/get` actually returns (stash-worker pointer-text
29
+ * `get`). `scope_resolved` is the worker's own `tierMeta(...)` expansion.
30
+ */
31
+ export interface StashResolutionReceipt {
32
+ resolved_tier: string;
33
+ source_scope: string;
34
+ scope_resolved: Record<string, unknown>;
35
+ scope_hash: string;
36
+ value_hash: string;
37
+ version: number;
38
+ }
39
+ /** A resolved ref, keyed on the answering service. */
40
+ export type ResolvedRef = {
41
+ source: 'artifact';
42
+ ref: string;
43
+ payload: string;
44
+ receipt: ArtifactRetrieveResponse;
45
+ } | {
46
+ source: 'recipe-worker';
47
+ ref: string;
48
+ payload: string;
49
+ receipt: RecipeMetadata;
50
+ } | {
51
+ source: 'stash';
52
+ ref: string;
53
+ payload: unknown;
54
+ receipt: StashResolutionReceipt;
55
+ };
56
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/refs/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE/D,8EAA8E;AAC9E,MAAM,WAAW,wBAAwB;IACvC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,EAAE,OAAO,GAAG,IAAI,GAAG,IAAI,CAAC;IACpC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,sDAAsD;AACtD,MAAM,MAAM,WAAW,GACnB;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,wBAAwB,CAAA;CAAE,GACvF;IAAE,MAAM,EAAE,eAAe,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,cAAc,CAAA;CAAE,GAClF;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,sBAAsB,CAAA;CAAE,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Ref receipt types — the public return contract of the ref resolver seam.
3
+ *
4
+ * `ResolvedRef` is discriminated on `source` (the answering service). Each
5
+ * variant carries that service's own response as its `receipt`, unmodified —
6
+ * provenance is passed through, never normalized, never synthesized. Because
7
+ * `owner` exists on the recipe-worker variant (it is a field of the worker's
8
+ * own `RecipeMetadata`) and does NOT exist on the stash variant, an empty
9
+ * owner (`owner: ''`) is unrepresentable at compile time. E4 proves this.
10
+ *
11
+ * Shared across variants: `ref`, `source`, and `payload` only. No provenance
12
+ * field (tier, scope, owner, backend) is shared across variants.
13
+ */
14
+ export {};
15
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/refs/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG"}
@@ -0,0 +1,42 @@
1
+ # Dominus SDK for Node.js — reading order
2
+
3
+ Snapshot: 2026-08-25-2103, production source commit `4f7b377`, SDK v11.0.7.
4
+
5
+ ## Read first
6
+
7
+ 1. `README.md` — package usage, Quick Start, workflow lifecycle.
8
+ 2. `docs/agent-guide/2026-08-25-2103-sdk-nodejs/01-purpose-and-boundaries.md`
9
+ 3. `docs/agent-guide/2026-08-25-2103-sdk-nodejs/02-repo-map-and-entrypoints.md`
10
+ 4. `docs/agent-guide/2026-08-25-2103-sdk-nodejs/03-api-surface.md`
11
+ 5. `docs/agent-guide/2026-08-25-2103-sdk-nodejs/10-agent-playbook.md`
12
+
13
+ ## Source files to open only for specific task types
14
+
15
+ | Task | File |
16
+ |---|---|
17
+ | Public surface / namespace wiring | `src/index.ts` |
18
+ | Request lifecycle, auth, retries, streaming/binary | `src/lib/client.ts` |
19
+ | Error hierarchy and endpoint-typed errors | `src/lib/errors.ts` |
20
+ | Env resolution / gateway config | `src/lib/config.ts` |
21
+ | JWT cache / circuit breaker | `src/lib/cache.ts` |
22
+ | `recipe://` / `ar://` ref resolution | `src/refs/resolve.ts`, `src/refs/types.ts` |
23
+ | Wire contracts (node envelope, projections, session) | `src/contract/*.ts`, `src/contracts/versioned-storage.ts` |
24
+ | Release + CI | `.github/workflows/publish-*.yml`, `tests.yml` |
25
+
26
+ ## Docs that are stale or superseded
27
+
28
+ - `docs/agent-guide/2026-06-27-0849-sdk-orient/` — v6.6.0-era pack; superseded by
29
+ the 2026-08-04 pack and this snapshot. Kept for historical context.
30
+ - `docs/agent-guide/2026-08-04-sdk-nodejs/` — partial pack (00/01/03/10 only);
31
+ superseded by this snapshot.
32
+ - `docs/architecture.md`, `docs/routes-services.md`, `docs/usage-reference.md` —
33
+ still useful but aging; verify claims against `src/` before trusting a route,
34
+ namespace, or behavior fact. `docs/architecture.md` §10 "no committed tests"
35
+ claim was already corrected in the 2026-06-27 pack (`tests/` is committed).
36
+
37
+ ## Atlas and audit to consult
38
+
39
+ - Atlas: `docs/atlas/2026-08-04-sdk-nodejs-truthmap.md`,
40
+ `docs/atlas/2026-08-04-sdk-nodejs-proof-ladder.md`,
41
+ `docs/atlas/2026-08-04-sdk-nodejs-blockers.md`.
42
+ - Latest cleanup audit: `docs/janitor/2026-08-25-2103-sdk-nodejs-cleanup-audit.md`.
@@ -0,0 +1,45 @@
1
+ # Purpose and boundaries
2
+
3
+ ## Main purpose
4
+
5
+ `dominus-sdk-nodejs` is the TypeScript/ESM SDK for the Dominus gateway-first
6
+ platform. It exposes a singleton `dominus` (from `src/index.ts`) with
7
+ namespace-based APIs for auth, data, storage, AI/runtime, workflow execution,
8
+ job processing, and platform administration. It is published to the npm
9
+ registry as `dominus-sdk-nodejs` (v11.0.7 at snapshot time).
10
+
11
+ ## What the repo owns
12
+
13
+ - SDK client and transport: `src/lib/client.ts` (HTTP/base64 protocol, JWT
14
+ mint/cache, SSE streaming, binary IO).
15
+ - Namespace facades: `src/namespaces/*.ts` (28 files), each wired as a `public
16
+ readonly` property on the `dominus` singleton in `src/index.ts`.
17
+ - Error hierarchy and endpoint-typed errors: `src/lib/errors.ts`.
18
+ - Ref resolver seam (`recipe://`, `ar://`): `src/refs/*`.
19
+ - Wire-contract module: `src/contract/*` and `src/contracts/versioned-storage.ts`.
20
+ - Committed test suite: `tests/` (35 `.test.js` files + type tests; HEAD commit
21
+ `4f7b377` reports 179 tests green).
22
+
23
+ ## What it explicitly does not own
24
+
25
+ - Worker implementations (gateway, authority, logs, stash, artifact, etc.).
26
+ The SDK only calls their `/svc/*` or `/api/*` routes through the gateway.
27
+ - The Dominus platform kernel or deploy lanes of other repos.
28
+ - `dist/` — generated build output (`npm run build`), not a design source.
29
+
30
+ ## Boundary
31
+
32
+ - This is a library repo (npm package), not a deployed service. It crosses
33
+ Dominus platform contracts (gateway routes, worker wire shapes) so
34
+ contract-sensitive changes belong to `dominus-expert` review.
35
+
36
+ ## Runtime / deployment class
37
+
38
+ - Node.js `>=18`, ESM (`"type": "module"`), single export entry
39
+ `exports["."] → dist/index.js`.
40
+ - Released by pushing to `production` (see `07-operations-release-and-live-proof.md`).
41
+
42
+ ## PHI / secrets / safety
43
+
44
+ - Never write PHI, secrets, credentials, raw reports, or response bodies into
45
+ docs. `DOMINUS_TOKEN` is a PSK; treat it as secret.
@@ -0,0 +1,36 @@
1
+ # Repo map and entrypoints
2
+
3
+ ## Directory map
4
+
5
+ | Path | Purpose |
6
+ |---|---|
7
+ | `src/index.ts` | Public surface: `dominus` singleton, namespace wiring, root shortcuts, error re-exports, crypto helpers |
8
+ | `src/lib/` | Transport + support: `client.ts`, `cache.ts`, `errors.ts`, `config.ts`, `console-capture.ts`, `conversation-format.ts`, `crypto.ts`, `page-rules.ts`, `recovery-action.ts`, `schema-builder.ts`, `trace.ts`, `user-session.ts` |
9
+ | `src/namespaces/` | 28 service facades, one file per namespace (see `03-api-surface.md`) |
10
+ | `src/refs/` | Ref resolver seam: `grammar.ts`, `resolve.ts`, `types.ts` (`recipe://`, `ar://`, receipt types) |
11
+ | `src/contract/` | Wire-contract module: `index.ts`, `node-envelope.ts`, `node-projections.ts`, `session.ts` |
12
+ | `src/contracts/` | `versioned-storage.ts` — versioned storage contract |
13
+ | `tests/` | Committed tests: 35 `*.test.js` files, `*.typecheck.ts` compile tests, `src/` + `tests/` fixture subdirs |
14
+ | `.github/workflows/` | `tests.yml` (PR + production push), `publish-development.yml`, `publish-staging.yml`, `publish-production.yml` |
15
+ | `docs/` | `architecture.md`, `routes-services.md`, `usage-reference.md`, `migration-error-base.md`, `workflow-hard-cut-release.md`, `atlas/`, `agent-guide/`, `janitor/`, `plans/` |
16
+ | `dist/` | Build output (generated, gitignored — never a design source) |
17
+ | `node_modules/` | Dependencies (gitignored) |
18
+ | `_worktrees/` | Linked git worktrees (untracked user scratch — do not touch) |
19
+
20
+ ## Entrypoints
21
+
22
+ - **Package entry**: `src/index.ts` → built to `dist/index.js` /
23
+ `dist/index.d.ts`; imported as `import { dominus } from 'dominus-sdk-nodejs'`.
24
+ No subpath exports.
25
+ - **Test entry**: `npm test` runs `npm run build && npm run test:types && node
26
+ --test tests/*.test.js`; type tests via `tsc -p tsconfig.type-tests.json`.
27
+ - **Build/typecheck**: `npm run build` (`tsc`), `npm run typecheck` /
28
+ `npm run lint` (`tsc --noEmit`).
29
+ - **CI**: `.github/workflows/tests.yml` (Node 20, `npm ci`, `npm test`) on
30
+ PR + push to `production`.
31
+ - **Publish**: `.github/workflows/publish-production.yml` on push to
32
+ `production` (npm publish with NPM_TOKEN + trusted-publishing fallback).
33
+
34
+ ## Generated / scratch directories to avoid
35
+
36
+ - `dist/` (build output), `node_modules/` (deps), `_worktrees/` (user worktrees).
@@ -0,0 +1,59 @@
1
+ # API surface
2
+
3
+ Public surface is the `dominus` singleton exported from `src/index.ts`. Root
4
+ shortcuts and namespace properties are wired there. Re-exported errors and
5
+ crypto helpers are also part of the package surface.
6
+
7
+ ## Root-level shortcuts (on `dominus`)
8
+
9
+ Secrets: `get`, `upsert`. DB: `listTables`, `queryTable`, `insertRow` (see the
10
+ docblock in `src/index.ts`). These map to the `secrets` / `db` namespaces.
11
+
12
+ ## Namespaces (`src/namespaces/`, 28 files)
13
+
14
+ | Namespace | File | Notes |
15
+ |---|---|---|
16
+ | secrets | `secrets.ts` | Secret presence/preview; root-level `get`/`upsert` shortcuts |
17
+ | db | `db.ts` | DB queries/tables/rows |
18
+ | redis | `redis.ts` | Redis get/set/keys/streams |
19
+ | files | `files.ts` | File upload/download (category-scoped) |
20
+ | auth | `auth.ts` | Auth users |
21
+ | ddl | `ddl.ts` | Table DDL |
22
+ | logs | `logs.ts` | `ingest`/`ingestBatch` (writes swallow), `tail`/`query` (reads propagate) |
23
+ | portal | `portal.ts` | Portal sessions, `sendInvite` |
24
+ | courier | `courier.ts` | Email sends |
25
+ | health | `health.ts` | Health check |
26
+ | secure | `secure.ts` | Secure-table access with audit (`query`, `reason`, `actor`) |
27
+ | admin | `admin.ts` | Admin surfaces |
28
+ | ai | `ai.ts` | Batch speech-to-text via `/api/agent/stt` on agent-runtime |
29
+ | workflow | `workflow.ts` | Authority-backed `workflow.ensure` lifecycle |
30
+ | jobs | `jobs.ts` | Job processing |
31
+ | processor | `processor.ts` | Processor runs |
32
+ | artifacts | `artifacts.ts` | Artifact V2 (`ar://` addressed) |
33
+ | authority | `authority.ts` | Runs, timelines, verdicts, schedules, deploy registry |
34
+ | browser | `browser.ts` | Browser automation; must use `/api/browser/*` with `useGateway: true` |
35
+ | deployer | `deployer.ts` | Deploy records |
36
+ | warden | `warden.ts` | Warden/credential surfaces |
37
+ | stash | `stash.ts` | Primary storage surface: pointer-text get/put, versioned items, bookmarks, watchers |
38
+ | stash-tables | `stash-tables.ts` | Stash managed tables |
39
+ | recipes | `recipes.ts` | Recipe publish/get/list/validate |
40
+ | platform | `platform.ts` | Platform groups/repos/policy decisions |
41
+ | coder | `coder.ts` | Coder Runtime runs |
42
+ | publisher | `publisher.ts` | Publisher channel pins/artifacts/builds |
43
+
44
+ ## Non-namespace public surface
45
+
46
+ - `src/refs/resolve.ts` → `RefResolver` for `recipe://` and `ar://` refs;
47
+ receipt types in `src/refs/types.ts`.
48
+ - Error exports from `src/index.ts`: `DominusError`, `AuthenticationError`,
49
+ `AuthorizationError`, `NotFoundError`, `ValidationError`, `ConflictError`,
50
+ `ServiceError`, `ConnectionError`, `TimeoutError`, `SecureTableError`, etc.
51
+ - Crypto helpers: `hashPassword`, `hashPsk`, `generateToken`.
52
+ - `DominusError.recoveryAction` accessor (recovery-action.ts) for D6 guidance.
53
+
54
+ ## Transport contract
55
+
56
+ Namespace methods normalize input, then call `this.client.request` /
57
+ `streamRequest` / `binaryUpload` / `binaryDownload` in `src/lib/client.ts`.
58
+ Gateway-first route transforms and typed error/wire contracts live in
59
+ `src/contract/*` and `src/contracts/versioned-storage.ts`.
@@ -0,0 +1,36 @@
1
+ # Data, state, and storage
2
+
3
+ This SDK is a client library: it holds no server-side database of its own. All
4
+ persistent state lives in platform services reached through the gateway.
5
+
6
+ ## In-process state (owned by this repo)
7
+
8
+ | Surface | File | Notes |
9
+ |---|---|---|
10
+ | `dominusCache` | `src/lib/cache.ts` | In-process encrypted cache; encryption key set from `DOMINUS_TOKEN` at import. Backs the service-JWT cache and circuit-breaker helpers. |
11
+ | Service-JWT cache | `src/lib/client.ts` / `cache.ts` | Minted service JWT cached 55 min (`JWT_CACHE_TTL = 3300000`), refreshed 5 min before expiry via `ensureValidJwt` mutex. `mintServiceJwt({ forceRefresh: true })` is the cache-bypass hook. |
12
+ | Page-rules cache | `src/lib/page-rules.ts` | Portal JWT / page-access local cache |
13
+ | User-session cache | `src/lib/user-session.ts` | Portal session local cache |
14
+
15
+ ## Platform storage surfaces the SDK talks to
16
+
17
+ - **`dominus.stash.*`** — the primary storage surface. Pointer-text
18
+ `get`/`put`, versioned items, bookmarks, watchers, scope/role resolution
19
+ (`src/namespaces/stash.ts`, `stash-tables.ts`).
20
+ - **Building blocks** — `redis`, `db`, `files`, `artifacts` are lower-level
21
+ building blocks underneath the stash facade (`docs/architecture.md` §2a).
22
+
23
+ ## State-safety rules
24
+
25
+ - Reads propagate; only *writes* swallow. `logs.ingest` / `ingestBatch` catch
26
+ and fall back to local logging on purpose; `logs.tail` and every other read
27
+ must let the error throw (v11.0.0 breaking change). Do not re-add a catch to
28
+ a read.
29
+ - Ref resolution receipts preserve the answering service's own response,
30
+ unmodified (`src/refs/types.ts`). No provenance field is shared across
31
+ variants.
32
+
33
+ ## Migrations
34
+
35
+ None — this is a library. Schema/DDL lives behind `dominus.ddl.*` /
36
+ `dominus.db.*` for platform tables, not in this repo.
@@ -0,0 +1,36 @@
1
+ # Integrations and runtime
2
+
3
+ ## Runtime
4
+
5
+ - Node.js `>=18`, ESM (`"type": "module"`).
6
+ - Single export entry: `package.json` → `exports["."]` → `dist/index.js`.
7
+
8
+ ## Environment variables (by category, no secret values)
9
+
10
+ | Category | Variable | Resolved in |
11
+ |---|---|---|
12
+ | Auth (PSK) | `DOMINUS_TOKEN` | `src/lib/config.ts`; used to set the cache encryption key at import |
13
+ | Scope | `DOMINUS_PROJECT` | project-scope selection for gateway calls |
14
+ | Gateway | `DOMINUS_GATEWAY_URL` (and related) | `src/lib/config.ts` gateway/proxy config |
15
+
16
+ ## External services / platform integrations
17
+
18
+ - **Gateway** — the SDK mints a service JWT from `DOMINUS_TOKEN` (PSK) via the
19
+ gateway `/jwt/mint` route, then calls gateway `/svc/*` routes. Route
20
+ transforms and wire contracts are defined in namespace code + `src/contract/*`.
21
+ - **Service-JWT lifetime** — `dominus-jwt-worker` `JWT_EXPIRY_SECONDS = 3600`
22
+ (1 hour); SDK cache TTL is 55 min with a 5-min refresh window. Do not regress
23
+ this TTL without first raising the jwt-worker expiry.
24
+ - **Browser automation** — `dominus.browser.*` must use SDK `/api/browser/*`
25
+ paths with `useGateway: true`, which the gateway exposes as authenticated
26
+ `/svc/browser/*`. Never point SDK methods at worker-local `/runs/*` routes
27
+ directly.
28
+ - **AI/STT** — `dominus.ai.stt` → `/api/agent/stt` on agent-runtime (no legacy
29
+ WebSocket STT path). Not server-only-Node.
30
+
31
+ ## Cross-repo / domain boundary
32
+
33
+ - This repo crosses Dominus platform contracts (gateway routes, worker wire
34
+ shapes). Contract-sensitive findings route to `dominus-expert`.
35
+ - CareBridge product surfaces (portal, courier) are thin client calls; product
36
+ behavior is backend-owned.
@@ -0,0 +1,45 @@
1
+ # Workflows, commands, and CI
2
+
3
+ All commands are defined in `package.json` `scripts`.
4
+
5
+ ## Commands
6
+
7
+ | Command | Script | What it runs |
8
+ |---|---|---|
9
+ | Install | `npm ci` / `npm install` | Install deps (`bcryptjs`, `jose`; dev: `typescript`, `@types/node`, `@types/bcryptjs`) |
10
+ | Build | `npm run build` | `tsc` → `dist/` |
11
+ | Typecheck | `npm run typecheck` | `tsc --noEmit` |
12
+ | Type tests | `npm run test:types` | `tsc -p tsconfig.type-tests.json` |
13
+ | Lint | `npm run lint` | `tsc --noEmit` (typecheck) |
14
+ | Test | `npm test` | `npm run build && npm run test:types && node --test tests/*.test.js` |
15
+ | Clean | `npm run clean` | `rm -rf dist` |
16
+
17
+ ## Fast local validation
18
+
19
+ ```bash
20
+ npm run build && npm run lint
21
+ ```
22
+
23
+ ## Full validation
24
+
25
+ ```bash
26
+ npm test
27
+ ```
28
+
29
+ HEAD commit `4f7b377` reports 179 tests green (35 `.test.js` files + type
30
+ tests). `tests/` also contains `src/` and `tests/` fixture subdirs used by the
31
+ runtime tests.
32
+
33
+ ## CI workflows
34
+
35
+ | Workflow | Trigger | Signal |
36
+ |---|---|---|
37
+ | `tests.yml` | PR + push to `production` | Node 20, `npm ci`, `npm test` |
38
+ | `publish-development.yml` | push to `development` | npm publish (development lane) |
39
+ | `publish-staging.yml` | push to `staging` | npm publish (staging lane) |
40
+ | `publish-production.yml` | push to `production` | `npm run build` + `npm test`, then npm publish with `NPM_TOKEN` (GitHub Environment `production`) and a trusted-publishing fallback; skips if the version already exists |
41
+
42
+ ## Known flaky / slow checks
43
+
44
+ None reported at snapshot time. `npm test` includes a build, so expect it to be
45
+ slower than a pure runtime test run.
@@ -0,0 +1,43 @@
1
+ # Operations, release, and live proof
2
+
3
+ ## Deployment lane
4
+
5
+ This is a library, not a deployed service. "Deploy" is npm publication gated
6
+ by git branch:
7
+
8
+ - Push to `production` → `.github/workflows/publish-production.yml` → build +
9
+ test, then `npm publish` (requires GitHub Environment `production` with
10
+ `NPM_TOKEN`). Falls back to `--provenance` trusted publishing if the token
11
+ publish fails, and skips when the version is already on the registry.
12
+ - `development` / `staging` lanes use `publish-development.yml` /
13
+ `publish-staging.yml` respectively.
14
+
15
+ ## Release files and version rules
16
+
17
+ - `package.json` `version` is the canonical release version (11.0.7 at
18
+ snapshot time).
19
+ - `CHANGELOG.md` documents per-version behavior changes (e.g. v11.0.0 breaking:
20
+ `logs.tail` reads propagate errors).
21
+ - Version bumps are deliberate commits on the branch (HEAD `4f7b377` bumps
22
+ 11.0.6 → 11.0.7).
23
+ - Release metadata should not be hand-set to a version already present on the
24
+ npm registry (the publish workflow guards this).
25
+
26
+ ## Live proof
27
+
28
+ - `npm view dominus-sdk-nodejs@<version>` against the npm registry confirms a
29
+ published release.
30
+ - Package install: `npm install dominus-sdk-nodejs` and import
31
+ `import { dominus } from 'dominus-sdk-nodejs'`.
32
+
33
+ ## Rollback / recovery
34
+
35
+ - Fix-forward: a corrected version bump + push to `production`.
36
+ - Cache recovery: `mintServiceJwt({ forceRefresh: true })` drops a rejected
37
+ cached JWT and mints fresh (key-rotation recovery).
38
+
39
+ ## What counts as done
40
+
41
+ - `npm run build` + `npm run lint` + `npm test` green locally.
42
+ - For releases: version bumped in `package.json` + `CHANGELOG.md` entry, push to
43
+ `production`, publish workflow completes or reports already-published.