@everystack/cli 0.4.59 → 0.4.61

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 (116) hide show
  1. package/package.json +2 -2
  2. package/src/backfill.ts +3 -3
  3. package/src/cli/alter-type-dependents.ts +1 -1
  4. package/src/cli/apply-authority.ts +1 -1
  5. package/src/cli/apply-execute.ts +10 -10
  6. package/src/cli/audit-api.ts +4 -4
  7. package/src/cli/audit-source-api.ts +2 -2
  8. package/src/cli/authz-adoption-class.ts +4 -4
  9. package/src/cli/authz-baseline.ts +2 -2
  10. package/src/cli/authz-canonical.ts +2 -2
  11. package/src/cli/authz-compile.ts +3 -3
  12. package/src/cli/authz-contract-io.ts +2 -2
  13. package/src/cli/authz-contract.ts +4 -4
  14. package/src/cli/authz-derive.ts +2 -2
  15. package/src/cli/authz-identity.ts +1 -1
  16. package/src/cli/authz-ownership.ts +1 -1
  17. package/src/cli/authz-reconcile.ts +4 -4
  18. package/src/cli/authz-redteam.ts +1 -1
  19. package/src/cli/authz-render.ts +2 -2
  20. package/src/cli/aws.ts +53 -4
  21. package/src/cli/backfill.ts +3 -3
  22. package/src/cli/branch-db.ts +5 -5
  23. package/src/cli/bundle-weight.ts +2 -2
  24. package/src/cli/commands/analyze.ts +2 -2
  25. package/src/cli/commands/audit.ts +10 -10
  26. package/src/cli/commands/bundle.ts +6 -6
  27. package/src/cli/commands/cache.ts +75 -3
  28. package/src/cli/commands/console.ts +6 -6
  29. package/src/cli/commands/db-apply.ts +25 -25
  30. package/src/cli/commands/db-approvers.ts +4 -4
  31. package/src/cli/commands/db-authz.ts +15 -15
  32. package/src/cli/commands/db-backfill.ts +10 -10
  33. package/src/cli/commands/db-backup.ts +25 -36
  34. package/src/cli/commands/db-branch.ts +8 -8
  35. package/src/cli/commands/db-build.ts +7 -7
  36. package/src/cli/commands/db-check.ts +16 -16
  37. package/src/cli/commands/db-diff.ts +6 -6
  38. package/src/cli/commands/db-exec.ts +8 -8
  39. package/src/cli/commands/db-export.ts +10 -10
  40. package/src/cli/commands/db-fingerprint.ts +14 -14
  41. package/src/cli/commands/db-fork.ts +15 -15
  42. package/src/cli/commands/db-generate.ts +19 -19
  43. package/src/cli/commands/db-plan.ts +25 -25
  44. package/src/cli/commands/db-pull.ts +18 -18
  45. package/src/cli/commands/db-reconcile.ts +14 -14
  46. package/src/cli/commands/db-refresh.ts +7 -7
  47. package/src/cli/commands/db-snapshot.ts +5 -5
  48. package/src/cli/commands/db-swap.ts +49 -37
  49. package/src/cli/commands/db-sync.ts +18 -18
  50. package/src/cli/commands/db.ts +15 -15
  51. package/src/cli/commands/deploy.ts +39 -5
  52. package/src/cli/commands/diag.ts +4 -4
  53. package/src/cli/commands/lighthouse.ts +3 -3
  54. package/src/cli/commands/logs.ts +5 -5
  55. package/src/cli/commands/pipeline-run.ts +7 -7
  56. package/src/cli/commands/runbook.ts +5 -5
  57. package/src/cli/commands/secrets.ts +5 -5
  58. package/src/cli/commands/security-probe.ts +4 -4
  59. package/src/cli/commands/security.ts +6 -6
  60. package/src/cli/commands/status.ts +3 -3
  61. package/src/cli/commands/task-probe.ts +4 -4
  62. package/src/cli/commands/ui-audit.ts +5 -5
  63. package/src/cli/commands/update.ts +64 -8
  64. package/src/cli/component-audit.ts +5 -5
  65. package/src/cli/config.ts +2 -2
  66. package/src/cli/db-build.ts +6 -6
  67. package/src/cli/db-source.ts +2 -2
  68. package/src/cli/declared-derived.ts +5 -5
  69. package/src/cli/declared-diff.ts +5 -5
  70. package/src/cli/deploy-probe.ts +3 -3
  71. package/src/cli/derived-apply.ts +5 -5
  72. package/src/cli/derived-compile.ts +4 -4
  73. package/src/cli/derived-grants.ts +1 -1
  74. package/src/cli/derived-introspect.ts +3 -3
  75. package/src/cli/derived-lint.ts +2 -2
  76. package/src/cli/derived-plan.ts +5 -5
  77. package/src/cli/derived-render.ts +6 -6
  78. package/src/cli/direct-venue.ts +2 -2
  79. package/src/cli/discover.ts +2 -2
  80. package/src/cli/edge-plan.ts +8 -8
  81. package/src/cli/exec-digest.ts +1 -1
  82. package/src/cli/exec-execute.ts +1 -1
  83. package/src/cli/exec-log.ts +1 -1
  84. package/src/cli/exec-run.ts +2 -2
  85. package/src/cli/git-descent.ts +5 -5
  86. package/src/cli/index.ts +46 -46
  87. package/src/cli/migration-compile.ts +7 -7
  88. package/src/cli/migration-generate.ts +6 -6
  89. package/src/cli/model-api.ts +16 -16
  90. package/src/cli/model-render.ts +6 -6
  91. package/src/cli/mutation-lease.ts +1 -1
  92. package/src/cli/observability.ts +1 -1
  93. package/src/cli/refresh-execute.ts +2 -2
  94. package/src/cli/runbook/generate.ts +3 -3
  95. package/src/cli/runbook/index.ts +7 -7
  96. package/src/cli/runbook/sections.ts +2 -2
  97. package/src/cli/schema-compile.ts +4 -4
  98. package/src/cli/schema-diff.ts +1 -1
  99. package/src/cli/schema-fingerprint.ts +7 -7
  100. package/src/cli/schema-introspect.ts +3 -3
  101. package/src/cli/schema-source.ts +1 -1
  102. package/src/cli/schema-swap.ts +4 -4
  103. package/src/cli/security-catalog.ts +1 -1
  104. package/src/cli/stage-backup.ts +229 -0
  105. package/src/cli/stage-read-consistency.ts +6 -6
  106. package/src/cli/state-apply.ts +7 -7
  107. package/src/cli/swap-execute.ts +3 -3
  108. package/src/cli/swap-heartbeat.ts +1 -1
  109. package/src/cli/swap-pair.ts +7 -7
  110. package/src/cli/task-poll.ts +2 -2
  111. package/src/cli/ui-bloat.ts +1 -1
  112. package/src/cli/utils/secrets.ts +1 -1
  113. package/src/exec.ts +7 -7
  114. package/src/reconcile.ts +2 -2
  115. package/src/refresh.ts +2 -2
  116. package/src/sst.ts +1 -1
@@ -0,0 +1,229 @@
1
+ /**
2
+ * The fingerprint sandwich around a stage backup — ONE implementation, three callers.
3
+ *
4
+ * A `db:backup` artifact carries a live base-schema fingerprint in its `.meta.json`, and the
5
+ * destructive-apply gate compares it against `plan.from`. That comparison is only meaningful if the
6
+ * fingerprint describes the schema the dump ACTUALLY holds. A dump taken across a concurrent
7
+ * migration holds a schema matching NEITHER endpoint, so its stamped fingerprint is a lie the gate
8
+ * would later trust. The sandwich reads the schema before the dump and again after it, and keeps
9
+ * the artifact only if the two agree.
10
+ *
11
+ * WHY THIS LIVES IN THE CLI: it used to run inside the task image, which imported
12
+ * `@everystack/cli/apply` to do it. The image is published and digest-pinned, so that froze a copy
13
+ * of the very CLI internals the gate depends on while the operator's checkout kept moving — a
14
+ * silent version skew on a safety-critical input. Here it runs from the operator's own checkout,
15
+ * the same code `db:apply` uses, so the two can never disagree about what a fingerprint means.
16
+ *
17
+ * WHY IT IS SHARED: `fingerprint` is a REQUIRED field on the backup job. Three commands dispatch
18
+ * backups (db:backup, db:fork, db:swap --snapshot logical), and when the field was added to one of
19
+ * them the other two silently broke. One implementation, one contract.
20
+ *
21
+ * The dispatch/poll/retract wiring is dependency-injected so the whole decision table is testable
22
+ * without AWS.
23
+ */
24
+
25
+ import { invokeAction, lambdaSessionRunner } from './aws';
26
+ import { pollTaskUntilStopped } from './task-poll';
27
+
28
+ /** The verdict on a completed dump's fingerprint pair. Pure — the heart of the sandwich. */
29
+ export type SandwichVerdict = { ok: true } | { ok: false; reason: string };
30
+
31
+ /**
32
+ * Did the schema hold still across the dump window?
33
+ *
34
+ * Agreement proves no DDL landed ANYWHERE between the two reads, so the fingerprint genuinely
35
+ * describes the dump's schema. Disagreement means the artifact is unusable as a safety net —
36
+ * better a refused backup than a false one.
37
+ */
38
+ export function judgeSandwich(fpBefore: string, fpAfter: string): SandwichVerdict {
39
+ if (fpBefore === fpAfter) return { ok: true };
40
+ return {
41
+ ok: false,
42
+ reason:
43
+ `the schema changed during the dump (${fpBefore.slice(0, 12)} → ${fpAfter.slice(0, 12)}), `
44
+ + 'so the backup spans a migration and its fingerprint cannot be proven. Re-run when no migration is concurrent.',
45
+ };
46
+ }
47
+
48
+ export interface StageBackupDeps {
49
+ /** Read the live base-schema fingerprint. Called twice, bracketing the dump. */
50
+ readFingerprint: () => Promise<string>;
51
+ /** Dispatch `db:backup` with the operator-computed fingerprint. */
52
+ dispatch: (fingerprint: string) => Promise<{ runId: string; taskArn: string; id: string; key: string; warning?: string }>;
53
+ /**
54
+ * Wait for the task to stop; resolve ok, or a human reason it did not.
55
+ *
56
+ * `stampedFingerprint` is what the task reported writing into the artifact's `.meta.json`. It is
57
+ * the evidence the image honored the job — see the skew check in runStageBackup.
58
+ */
59
+ awaitTask: (ids: { runId: string; taskArn: string; id: string }) => Promise<{ ok: true; bytes?: number; stampedFingerprint?: string } | { ok: false; reason: string }>;
60
+ /** Delete a retracted artifact (the ops Lambda's db:backup:retract). */
61
+ retract: (key: string) => Promise<void>;
62
+ /** Progress output. Optional so tests stay quiet. */
63
+ onStep?: (message: string) => void;
64
+ }
65
+
66
+ export type StageBackupResult =
67
+ | { ok: true; id: string; key: string; bytes?: number; fingerprint: string; warning?: string }
68
+ | { ok: false; reason: string; retracted?: boolean; orphanKey?: string };
69
+
70
+ /**
71
+ * Take a stage backup whose fingerprint is PROVEN stable, or refuse.
72
+ *
73
+ * Never throws for an expected failure — every outcome is a verdict the caller renders, so the
74
+ * three commands can word their own consequences ("the swap was NOT applied", "the fork stopped")
75
+ * without re-deriving the logic.
76
+ */
77
+ export async function runStageBackup(deps: StageBackupDeps): Promise<StageBackupResult> {
78
+ const step = deps.onStep ?? (() => {});
79
+
80
+ step('Reading the live schema fingerprint (before the dump)...');
81
+ let fpBefore: string;
82
+ try {
83
+ fpBefore = await deps.readFingerprint();
84
+ } catch (err: any) {
85
+ // Refuse BEFORE dispatching: a dump whose fingerprint cannot be proven is not a safety net, and
86
+ // taking one anyway would burn the dump window and still leave nothing trustworthy.
87
+ return { ok: false, reason: `the schema fingerprint could not be read, so no backup was dispatched: ${err?.message ?? String(err)}` };
88
+ }
89
+
90
+ let dispatched: { runId: string; taskArn: string; id: string; key: string; warning?: string };
91
+ try {
92
+ dispatched = await deps.dispatch(fpBefore);
93
+ } catch (err: any) {
94
+ return { ok: false, reason: `the backup would not dispatch: ${err?.message ?? String(err)}` };
95
+ }
96
+
97
+ const finished = await deps.awaitTask(dispatched);
98
+ if (!finished.ok) return { ok: false, reason: finished.reason };
99
+
100
+ // Did the image actually USE the fingerprint we sent?
101
+ //
102
+ // This is the version-skew guard, and it deliberately does not rely on the image cooperating. An
103
+ // older task image ignores the job's `fingerprint` field entirely and computes its own, stamping
104
+ // the manifest with a value this CLI never produced — the exact stale-internals problem the
105
+ // operator-side move exists to remove, arriving through a pinned digest nobody re-published. A
106
+ // protocol handshake cannot catch that, because an old image does not know to check it. Comparing
107
+ // what came back against what we sent works against ANY image, old or new.
108
+ if (finished.stampedFingerprint !== undefined && finished.stampedFingerprint !== fpBefore) {
109
+ step('Retracting the backup (the task stamped a fingerprint we did not send)...');
110
+ const mismatch =
111
+ `the task stamped fingerprint ${finished.stampedFingerprint.slice(0, 12)} but the operator sent `
112
+ + `${fpBefore.slice(0, 12)} — the task image computed its own instead of using the job's, which means it `
113
+ + 'predates the operator-side fingerprint contract. Re-publish the Task image (or pin a newer digest).';
114
+ try {
115
+ await deps.retract(dispatched.key);
116
+ return { ok: false, reason: `${mismatch} Backup ${dispatched.id} was retracted.`, retracted: true };
117
+ } catch (err: any) {
118
+ return {
119
+ ok: false,
120
+ reason: `${mismatch} Backup ${dispatched.id} could ALSO not be retracted (${err?.message ?? String(err)}) — delete it by hand.`,
121
+ retracted: false,
122
+ orphanKey: dispatched.key,
123
+ };
124
+ }
125
+ }
126
+
127
+ step('Re-reading the schema fingerprint (after the dump)...');
128
+ let fpAfter: string;
129
+ try {
130
+ fpAfter = await deps.readFingerprint();
131
+ } catch (err: any) {
132
+ // The dump exists but is unproven. Do NOT retract — an unreadable fingerprint is not evidence
133
+ // the schema moved, and silently destroying a good backup is the worse error.
134
+ return {
135
+ ok: false,
136
+ reason: `the dump finished but the schema fingerprint could not be re-read (${err?.message ?? String(err)}), so backup ${dispatched.id} is NOT proven stable. Verify no migration ran during the dump, or re-run.`,
137
+ orphanKey: dispatched.key,
138
+ };
139
+ }
140
+
141
+ const verdict = judgeSandwich(fpBefore, fpAfter);
142
+ if (verdict.ok) {
143
+ // A task that reported no fingerprint at all is not the skew case above — the result-ledger
144
+ // write is explicitly best-effort, so a blip there loses the whole result row. Failing the
145
+ // backup for that would turn a cosmetic outage into a lost safety net, so say it and continue.
146
+ const unverified = finished.stampedFingerprint === undefined
147
+ ? 'the task did not report the fingerprint it stamped, so the artifact could not be verified against what the operator sent (the result-ledger write is best-effort)'
148
+ : undefined;
149
+ const warning = [dispatched.warning, unverified].filter(Boolean).join('; ') || undefined;
150
+ return { ok: true, id: dispatched.id, key: dispatched.key, bytes: finished.bytes, fingerprint: fpBefore, warning };
151
+ }
152
+
153
+ step('Retracting the backup (its fingerprint cannot be proven)...');
154
+ try {
155
+ await deps.retract(dispatched.key);
156
+ return { ok: false, reason: `${verdict.reason} Backup ${dispatched.id} was retracted.`, retracted: true };
157
+ } catch (err: any) {
158
+ // The artifact outlived the failure. Say so loudly with the key — an unproven backup left in
159
+ // the bucket is exactly what the destructive-apply gate must never pick up.
160
+ return {
161
+ ok: false,
162
+ reason: `${verdict.reason} Backup ${dispatched.id} could ALSO not be retracted (${err?.message ?? String(err)}) — delete it by hand so the destructive-apply gate never trusts it.`,
163
+ retracted: false,
164
+ orphanKey: dispatched.key,
165
+ };
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Bind the sandwich to a real stage: the ops Lambda supplies the session the fingerprint is read
171
+ * over, dispatches the task, reports status, and performs the retraction — so the operator never
172
+ * holds a database URL or an S3 credential for any of it.
173
+ *
174
+ * The ONE place the wiring is written. A caller that hand-rolled this is how `fingerprint` became
175
+ * required in db:backup while db:fork and db:swap kept dispatching without it.
176
+ */
177
+ export function stageBackupDeps(
178
+ config: { region: string },
179
+ opsFn: string,
180
+ stage: string | undefined,
181
+ hooks: { onStep?: (message: string) => void; onDispatch?: (d: { runId: string; taskArn: string; id: string; warning?: string }) => void } = {},
182
+ ): StageBackupDeps {
183
+ return {
184
+ // BOTH ends of the sandwich read over this ONE closure, so they cannot land on different lanes.
185
+ // That matters: a before-read over a direct session and an after-read over the two-invoke
186
+ // ops-Lambda blend could manufacture a false mismatch — or, worse, a false match. The symmetry
187
+ // is structural here rather than asserted; if a caller ever needs to override one end, it has to
188
+ // override both.
189
+ readFingerprint: async () => {
190
+ // The SAME helper db:apply's concurrency lock uses — that shared definition is the point.
191
+ const { liveBaseFingerprint } = await import('./apply-execute');
192
+ return (await liveBaseFingerprint(lambdaSessionRunner(config.region, opsFn))).hash;
193
+ },
194
+ dispatch: async (fingerprint) => {
195
+ const dispatched: any = await invokeAction(config.region, opsFn, 'db:backup', {
196
+ stage, actor: process.env.USER ?? null, fingerprint,
197
+ });
198
+ if (dispatched?.error) throw new Error(dispatched.error);
199
+ hooks.onDispatch?.(dispatched);
200
+ return dispatched;
201
+ },
202
+ awaitTask: async (ids) => {
203
+ const poll = await pollTaskUntilStopped(config.region, opsFn, { runId: ids.runId, taskArn: ids.taskArn });
204
+ if (poll.outcome === 'timeout') {
205
+ return { ok: false, reason: `the dump did not finish in time (last status: ${poll.lastStatus}). Run id ${ids.runId} — reconcile via ECS / everystack.task_log.` };
206
+ }
207
+ if (poll.outcome === 'error') {
208
+ return { ok: false, reason: `the task status could not be read (${poll.status.error}). The dump may still be running — reconcile run id ${ids.runId}.` };
209
+ }
210
+ if (poll.status.exitCode !== 0) {
211
+ return { ok: false, reason: `the dump exited ${poll.status.exitCode ?? 'unknown'}${poll.status.stoppedReason ? ` — ${poll.status.stoppedReason}` : ''}. Read the task logs (CloudWatch).` };
212
+ }
213
+ return {
214
+ ok: true,
215
+ bytes: poll.status.result?.bytes as number | undefined,
216
+ // What the task says it wrote into the artifact's .meta.json — the skew evidence.
217
+ stampedFingerprint: poll.status.result?.fingerprint as string | undefined,
218
+ };
219
+ },
220
+ retract: async (key) => {
221
+ // `stage` scopes what the action is willing to delete — it refuses any key outside this
222
+ // stage's backup prefix, so a retraction cannot reach an export artifact or a restore intent.
223
+ const res: any = await invokeAction(config.region, opsFn, 'db:backup:retract', { key, stage });
224
+ if (res?.error) throw new Error(res.error);
225
+ if (!res?.retracted) throw new Error(`the ops function did not confirm the retraction (returned ${JSON.stringify(res)})`);
226
+ },
227
+ onStep: hooks.onStep,
228
+ };
229
+ }
@@ -30,12 +30,12 @@
30
30
  * Lambda's db:apply action, for refusals that reach it.
31
31
  */
32
32
 
33
- import type { AuthzContract } from './authz-contract.js';
34
- import type { SessionRunner } from './session.js';
35
- import { introspectContract } from './authz-contract.js';
36
- import { introspectSchema, type SchemaSnapshot } from './schema-introspect.js';
37
- import { FUNCTIONS_SQL, contractFunctionRow } from './security-catalog.js';
38
- import { fingerprintLive } from './schema-fingerprint.js';
33
+ import type { AuthzContract } from './authz-contract';
34
+ import type { SessionRunner } from './session';
35
+ import { introspectContract } from './authz-contract';
36
+ import { introspectSchema, type SchemaSnapshot } from './schema-introspect';
37
+ import { FUNCTIONS_SQL, contractFunctionRow } from './security-catalog';
38
+ import { fingerprintLive } from './schema-fingerprint';
39
39
 
40
40
  /** One complete read of a target's base state, with its content address. */
41
41
  export interface StageReadPair {
@@ -19,14 +19,14 @@
19
19
 
20
20
  import { execSync } from 'node:child_process';
21
21
  import type { ModelDescriptor } from '@everystack/model';
22
- import { introspectContract, type AuthzContract, type QueryRunner } from './authz-contract.js';
23
- import type { SessionRunner } from './session.js';
24
- import { introspectSchema, type SchemaSnapshot } from './schema-introspect.js';
25
- import { FUNCTIONS_SQL, contractFunctionRow } from './security-catalog.js';
26
- import { generateMigrationSql, HELD_DROP_PREFIX } from './migration-generate.js';
22
+ import { introspectContract, type AuthzContract, type QueryRunner } from './authz-contract';
23
+ import type { SessionRunner } from './session';
24
+ import { introspectSchema, type SchemaSnapshot } from './schema-introspect';
25
+ import { FUNCTIONS_SQL, contractFunctionRow } from './security-catalog';
26
+ import { generateMigrationSql, HELD_DROP_PREFIX } from './migration-generate';
27
27
  import type { SequenceDescriptor } from '@everystack/model';
28
- import { fingerprintLive } from './schema-fingerprint.js';
29
- import { ENSURE_RECONCILER_SQL, renderSchemaLogInsert, renderSchemaLogFingerprintUpdate } from './derived-apply.js';
28
+ import { fingerprintLive } from './schema-fingerprint';
29
+ import { ENSURE_RECONCILER_SQL, renderSchemaLogInsert, renderSchemaLogFingerprintUpdate } from './derived-apply';
30
30
 
31
31
  const NOTICE_PREFIX = '-- NOTICE';
32
32
 
@@ -20,9 +20,9 @@
20
20
  */
21
21
 
22
22
  import type { ModelDescriptor } from '@everystack/model';
23
- import type { QueryRunner } from './authz-contract.js';
24
- import type { SessionRunner } from './session.js';
25
- import { renderSchemaSwap, dropRetiringSql } from './schema-swap.js';
23
+ import type { QueryRunner } from './authz-contract';
24
+ import type { SessionRunner } from './session';
25
+ import { renderSchemaSwap, dropRetiringSql } from './schema-swap';
26
26
 
27
27
  /** One validator's result. A `fatal` (default) failure rolls back; a `warn` failure is surfaced only. */
28
28
  export interface SwapCheck {
@@ -39,7 +39,7 @@
39
39
  * waiting for a client that has stopped sending. `Lock` is never healthy here and reports at once.
40
40
  */
41
41
 
42
- import type { QueryRunner } from './authz-contract.js';
42
+ import type { QueryRunner } from './authz-contract';
43
43
 
44
44
  /** One poll: what has landed, and what the loading backend is doing. */
45
45
  export interface HeartbeatSample {
@@ -50,13 +50,13 @@
50
50
  */
51
51
 
52
52
  import type { ModelDescriptor, DerivedDescriptor } from '@everystack/model';
53
- import { parseQualified } from './derived-source.js';
54
- import type { SourceObject } from './derived-source.js';
55
- import { rewriteStatementLineMulti, splitCodeSpans } from './schema-rewrite.js';
56
- import { parseGrantAttachments } from './derived-grants.js';
57
- import { derivedSearchPath, renderSetSearchPath, renderProvenanceUpsert, ENSURE_RECONCILER_SQL } from './derived-apply.js';
58
- import type { LiveObject } from './derived-introspect.js';
59
- import { compileTableContract } from './authz-compile.js';
53
+ import { parseQualified } from './derived-source';
54
+ import type { SourceObject } from './derived-source';
55
+ import { rewriteStatementLineMulti, splitCodeSpans } from './schema-rewrite';
56
+ import { parseGrantAttachments } from './derived-grants';
57
+ import { derivedSearchPath, renderSetSearchPath, renderProvenanceUpsert, ENSURE_RECONCILER_SQL } from './derived-apply';
58
+ import type { LiveObject } from './derived-introspect';
59
+ import { compileTableContract } from './authz-compile';
60
60
 
61
61
  const SAFE_SCHEMA = /^[a-z_][a-z0-9_$]*$/;
62
62
 
@@ -9,8 +9,8 @@
9
9
  * row + ECS both carry it). This owns the loop; the caller owns the success/failure messaging.
10
10
  */
11
11
 
12
- import { invokeAction } from './aws.js';
13
- import { info } from './output.js';
12
+ import { invokeAction } from './aws';
13
+ import { info } from './output';
14
14
 
15
15
  const POLL_INTERVAL_MS = 5_000;
16
16
  /** Backup/export/restore can run minutes on large databases — far longer than the probe's handshake. */
@@ -29,7 +29,7 @@
29
29
  * mangled, pathless) — that is the local source auditor's job; this proves magnitude.
30
30
  */
31
31
 
32
- import type { AuditFinding } from './bundle-audit.js';
32
+ import type { AuditFinding } from './bundle-audit';
33
33
 
34
34
  /** Thresholds for the design-bloat gates. All counts are occurrences in the bundle. */
35
35
  export interface UiBloatBudget {
@@ -15,7 +15,7 @@
15
15
 
16
16
  import crypto from 'node:crypto';
17
17
  import { gunzipSync } from 'node:zlib';
18
- import { ensureOptionalAws } from '../aws.js';
18
+ import { ensureOptionalAws } from '../aws';
19
19
 
20
20
  /**
21
21
  * Preflight the two optional-peer clients EVERY secrets operation needs (ssm for the passphrase,
package/src/exec.ts CHANGED
@@ -8,13 +8,13 @@
8
8
  * URL on the operator's machine.
9
9
  */
10
10
 
11
- export { executeExec, assertNoTxnControl, execSha } from './cli/exec-execute.js';
12
- export type { ExecIntent, ExecOutcome, ExecuteExecOptions, ExecResult } from './cli/exec-execute.js';
11
+ export { executeExec, assertNoTxnControl, execSha } from './cli/exec-execute';
12
+ export type { ExecIntent, ExecOutcome, ExecuteExecOptions, ExecResult } from './cli/exec-execute';
13
13
 
14
- export { runExecInTx, SchemaChangedError, railStatements, EXEC_RAIL_DEFAULTS } from './cli/exec-run.js';
15
- export type { TxRunner, ExecStmtResult, ExecRails, RunExecInTxOptions } from './cli/exec-run.js';
14
+ export { runExecInTx, SchemaChangedError, railStatements, EXEC_RAIL_DEFAULTS } from './cli/exec-run';
15
+ export type { TxRunner, ExecStmtResult, ExecRails, RunExecInTxOptions } from './cli/exec-run';
16
16
 
17
- export { catalogDigestQuery } from './cli/exec-digest.js';
17
+ export { catalogDigestQuery } from './cli/exec-digest';
18
18
 
19
- export { ENSURE_EXEC_LOG_SQL, renderExecIntentInsert, renderExecOutcomeUpdate } from './cli/exec-log.js';
20
- export type { ExecIntentRow, ExecOutcomeRow } from './cli/exec-log.js';
19
+ export { ENSURE_EXEC_LOG_SQL, renderExecIntentInsert, renderExecOutcomeUpdate } from './cli/exec-log';
20
+ export type { ExecIntentRow, ExecOutcomeRow } from './cli/exec-log';
package/src/reconcile.ts CHANGED
@@ -7,5 +7,5 @@
7
7
  * --stage` needs no raw admin URL on the deployer's machine.
8
8
  */
9
9
 
10
- export { executeReconcile, buildReconcileReport } from './cli/commands/db-reconcile.js';
11
- export type { ReconcileRun, ExecuteOptions } from './cli/commands/db-reconcile.js';
10
+ export { executeReconcile, buildReconcileReport } from './cli/commands/db-reconcile';
11
+ export type { ReconcileRun, ExecuteOptions } from './cli/commands/db-reconcile';
package/src/refresh.ts CHANGED
@@ -7,5 +7,5 @@
7
7
  * machine. The CLI ships the declared matview identities (dependency order); this refreshes them.
8
8
  */
9
9
 
10
- export { executeRefresh, matviewIdentities } from './cli/refresh-execute.js';
11
- export type { RefreshRun, RefreshRunner } from './cli/refresh-execute.js';
10
+ export { executeRefresh, matviewIdentities } from './cli/refresh-execute';
11
+ export type { RefreshRun, RefreshRunner } from './cli/refresh-execute';
package/src/sst.ts CHANGED
@@ -11,7 +11,7 @@
11
11
  * @module
12
12
  */
13
13
 
14
- import { loadEnvConfig, type EnvConfig } from './env.js';
14
+ import { loadEnvConfig, type EnvConfig } from './env';
15
15
 
16
16
  export { loadEnvConfig, type EnvConfig };
17
17