@stacksjs/buddy 0.70.258 → 0.70.260

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 (112) hide show
  1. package/dist/cli.d.ts +11 -1
  2. package/dist/cli.js +5 -164
  3. package/dist/commands/about.js +1 -35
  4. package/dist/commands/add.js +1 -25
  5. package/dist/commands/ai-context.js +4 -27
  6. package/dist/commands/auth.js +1 -68
  7. package/dist/commands/build.js +1 -221
  8. package/dist/commands/cd.js +8 -39
  9. package/dist/commands/changelog.js +1 -32
  10. package/dist/commands/clean.js +1 -44
  11. package/dist/commands/cloud.js +2 -519
  12. package/dist/commands/commit.js +1 -16
  13. package/dist/commands/completion.js +6 -42
  14. package/dist/commands/config-migrate.js +6 -94
  15. package/dist/commands/configure.js +2 -45
  16. package/dist/commands/create.js +1 -162
  17. package/dist/commands/deploy.js +13 -1676
  18. package/dist/commands/desktop-apple.js +12 -399
  19. package/dist/commands/dev.js +6 -1083
  20. package/dist/commands/dns.js +3 -103
  21. package/dist/commands/docs/buddy-commands.js +10 -132
  22. package/dist/commands/docs/buddy-commands.test.js +1 -38
  23. package/dist/commands/docs/framework-repo.js +1 -14
  24. package/dist/commands/docs/framework-repo.test.js +1 -68
  25. package/dist/commands/docs/generated-artifacts.js +3 -70
  26. package/dist/commands/docs/generated-artifacts.test.js +1 -19
  27. package/dist/commands/docs/links.js +2 -85
  28. package/dist/commands/docs/links.test.js +4 -66
  29. package/dist/commands/docs.js +1 -24
  30. package/dist/commands/doctor.js +2 -478
  31. package/dist/commands/domains.js +2 -152
  32. package/dist/commands/email.js +31 -503
  33. package/dist/commands/env.js +1 -312
  34. package/dist/commands/extension.js +1 -239
  35. package/dist/commands/features.js +9 -345
  36. package/dist/commands/fresh.js +1 -46
  37. package/dist/commands/generate.js +2 -152
  38. package/dist/commands/http.js +1 -33
  39. package/dist/commands/index.js +1 -57
  40. package/dist/commands/install.js +1 -22
  41. package/dist/commands/key.js +1 -23
  42. package/dist/commands/link.js +2 -147
  43. package/dist/commands/lint.js +2 -84
  44. package/dist/commands/list.js +1 -140
  45. package/dist/commands/mail.js +15 -1477
  46. package/dist/commands/maintenance.js +1 -141
  47. package/dist/commands/make.js +1 -392
  48. package/dist/commands/migrate-project.js +1 -49
  49. package/dist/commands/migrate.js +27 -625
  50. package/dist/commands/outdated.js +1 -19
  51. package/dist/commands/package.js +1 -17
  52. package/dist/commands/phone.js +17 -181
  53. package/dist/commands/ports.js +2 -118
  54. package/dist/commands/prepublish.js +1 -17
  55. package/dist/commands/projects.js +1 -29
  56. package/dist/commands/protocol/craft-evidence.js +4 -98
  57. package/dist/commands/protocol/craft-evidence.test.js +1 -20
  58. package/dist/commands/protocol/desktop-lifecycle-report.js +3 -57
  59. package/dist/commands/protocol/desktop-lifecycle-report.test.js +1 -32
  60. package/dist/commands/protocol/desktop-support.js +2 -32
  61. package/dist/commands/protocol/desktop-workflow.test.js +3 -35
  62. package/dist/commands/protocol/driver-registry.js +2 -71
  63. package/dist/commands/protocol/pantry-evidence.js +4 -144
  64. package/dist/commands/protocol/pantry-evidence.test.js +1 -29
  65. package/dist/commands/protocol/release-manifest.js +3 -102
  66. package/dist/commands/protocol/release-manifest.test.js +2 -34
  67. package/dist/commands/protocol/run-conformance.js +4 -346
  68. package/dist/commands/protocol/run-conformance.test.js +1 -52
  69. package/dist/commands/protocol/run-driver-contracts.js +4 -83
  70. package/dist/commands/protocol/run-driver-contracts.test.js +1 -18
  71. package/dist/commands/protocol/source-manifest.js +3 -113
  72. package/dist/commands/protocol/sync-suite.js +3 -136
  73. package/dist/commands/protocol/sync-suite.test.js +1 -44
  74. package/dist/commands/protocol.js +1 -60
  75. package/dist/commands/publish.js +8 -500
  76. package/dist/commands/queue.js +1 -248
  77. package/dist/commands/release.js +1 -42
  78. package/dist/commands/route.js +1 -21
  79. package/dist/commands/run-tool.js +1 -9
  80. package/dist/commands/saas.js +1 -25
  81. package/dist/commands/schedule.js +1 -61
  82. package/dist/commands/search.js +1 -84
  83. package/dist/commands/seed.js +1 -47
  84. package/dist/commands/serve.js +1 -55
  85. package/dist/commands/setup-ai.js +2 -121
  86. package/dist/commands/setup.js +2 -305
  87. package/dist/commands/share.js +1 -214
  88. package/dist/commands/sms.js +32 -319
  89. package/dist/commands/stacks.js +1 -72
  90. package/dist/commands/telemetry.js +1 -74
  91. package/dist/commands/test.js +1 -130
  92. package/dist/commands/tinker.js +1 -37
  93. package/dist/commands/types.js +1 -18
  94. package/dist/commands/upgrade.js +1 -98
  95. package/dist/commands/user.js +3 -84
  96. package/dist/commands/version.js +1 -14
  97. package/dist/config.js +1 -231
  98. package/dist/custom-cli.js +1 -23
  99. package/dist/database-preflight.js +1 -88
  100. package/dist/global-options.js +1 -4
  101. package/dist/index.js +1 -1
  102. package/dist/lazy-commands.js +1 -241
  103. package/dist/migrators/index.js +2 -62
  104. package/dist/migrators/laravel/index.js +1 -148
  105. package/dist/migrators/laravel/migrations.js +4 -231
  106. package/dist/migrators/laravel/models.js +8 -111
  107. package/dist/migrators/rails/index.js +1 -11
  108. package/dist/production-server.js +1 -257
  109. package/dist/project-setup.js +1 -36
  110. package/dist/serve-entry.js +1 -5
  111. package/dist/version-info.js +1 -5
  112. package/package.json +53 -46
@@ -1,274 +1,5 @@
1
- import { createHash } from "node:crypto";
2
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
3
- import { arch, platform } from "node:os";
4
- import { resolve } from "node:path";
5
- import Ajv2020 from "ajv/dist/2020.js";
6
- import addFormats from "ajv-formats";
7
- import { Action } from "../../../../actions/src/index";
8
- import { assertCapabilityAvailable, capabilityRegistry } from "../../../../config/src/capabilities";
9
- import { decryptValue, encryptValue, generateKeypair } from "../../../../env/src/crypto";
10
- import { escapeHtml } from "../../../../error-handling/src/error-page-template";
11
- import { appPath, defaultsAppPath } from "../../../../path/src/index";
12
- import { createValidationErrorResponse } from "../../../../router/src/error-handler";
13
- import { timingSafeEqualString } from "../../../../security/src/hash";
14
- import { object, string } from "../../../../validation/src/index";
15
- const root = resolve(import.meta.dir, "../../../../../../.."), suiteRoot = resolve(root, ".github/protocol/suite/1.0-draft");
16
- function git(...arguments_) {
17
- const result = Bun.spawnSync(["git", ...arguments_], { cwd: root });
18
- if (result.exitCode !== 0)
19
- throw Error(result.stderr.toString().trim());
20
- return result.stdout.toString().trim();
21
- }
22
- function exactSourceDigest() {
23
- const tree = git("rev-parse", "HEAD^{tree}");
24
- return `sha256:${createHash("sha256").update(tree).digest("hex")}`;
25
- }
26
- function tamper(ciphertext) {
27
- const prefix = "encrypted:", payload = Buffer.from(ciphertext.slice(prefix.length), "base64"), last = payload.length - 1;
28
- if (last >= 0)
29
- payload[last] = (payload[last] ?? 0) ^ 1;
30
- return `${prefix}${payload.toString("base64")}`;
31
- }
32
- function blob(revision, path) {
33
- return `https://github.com/stacksjs/stacks/blob/${revision}/${path}`;
34
- }
35
- export function executeSecurityEvidence(revision) {
36
- const evidence = new Map, cryptoUrl = blob(revision, "storage/framework/core/env/src/crypto.ts"), comparisonUrl = blob(revision, "storage/framework/core/security/src/hash.ts"), renderUrl = blob(revision, "storage/framework/core/error-handling/src/error-page-template.ts"), started = performance.now();
37
- try {
38
- const { publicKey, privateKey } = generateKeypair(), encrypted = encryptValue("secret", publicKey), roundTrip = decryptValue(encrypted, privateKey);
39
- let tamperRejected = !1;
40
- try {
41
- decryptValue(tamper(encrypted), privateKey);
42
- } catch {
43
- tamperRejected = !0;
44
- }
45
- const passed = roundTrip === "secret" && !encrypted.includes("secret") && tamperRejected;
46
- evidence.set("CORE-SEC-05", {
47
- status: passed ? "pass" : "fail",
48
- evidenceUrl: cryptoUrl,
49
- durationMs: Math.max(0, performance.now() - started),
50
- notes: passed ? "Authenticated-encryption round trip passed and modified ciphertext was rejected." : "Authenticated-encryption fixture failed."
51
- });
52
- } catch (error) {
53
- evidence.set("CORE-SEC-05", {
54
- status: "fail",
55
- evidenceUrl: cryptoUrl,
56
- durationMs: Math.max(0, performance.now() - started),
57
- notes: `Authenticated-encryption fixture threw: ${error instanceof Error ? error.message : String(error)}`
58
- });
59
- }
60
- const comparisonStarted = performance.now(), unequal = timingSafeEqualString("token-a", "token-b") === !1;
61
- evidence.set("CORE-SEC-07", {
62
- status: unequal ? "pass" : "fail",
63
- evidenceUrl: comparisonUrl,
64
- durationMs: Math.max(0, performance.now() - comparisonStarted),
65
- notes: unequal ? "The public authenticator comparison helper uses the runtime timing-safe primitive." : "Timing-safe comparison fixture failed."
66
- });
67
- const renderStarted = performance.now(), renderOk = escapeHtml("<script>alert(1)</script>") === "&lt;script&gt;alert(1)&lt;/script&gt;";
68
- evidence.set("CORE-SEC-02", {
69
- status: renderOk ? "pass" : "fail",
70
- evidenceUrl: renderUrl,
71
- durationMs: Math.max(0, performance.now() - renderStarted),
72
- notes: renderOk ? "Untrusted markup is converted to HTML entities by the default escaper." : "Default render-escaping fixture failed."
73
- });
74
- return evidence;
75
- }
76
- export function executeConfigEvidence(revision) {
77
- const evidence = new Map, url = blob(revision, "storage/framework/core/config/src/capabilities.ts"), started = performance.now();
78
- let failedClosed = !1, message = "";
79
- try {
80
- assertCapabilityAvailable("queue", "planned");
81
- } catch (error) {
82
- failedClosed = !0;
83
- message = error instanceof Error ? error.message : String(error);
84
- }
85
- evidence.set("CORE-CONFIG-02", {
86
- status: failedClosed ? "pass" : "fail",
87
- evidenceUrl: url,
88
- durationMs: Math.max(0, performance.now() - started),
89
- notes: failedClosed ? `Selecting an unavailable driver is rejected before use: ${message}` : "Fail-closed capability guard accepted an unavailable driver."
90
- });
91
- const drvStarted = performance.now();
92
- let drvFailedClosed = !1;
93
- try {
94
- assertCapabilityAvailable("queue", "planned-driver");
95
- } catch {
96
- drvFailedClosed = !0;
97
- }
98
- evidence.set("STD-DRV-01", {
99
- status: drvFailedClosed ? "pass" : "fail",
100
- evidenceUrl: url,
101
- durationMs: Math.max(0, performance.now() - drvStarted),
102
- notes: drvFailedClosed ? "A planned driver is rejected loudly with no silent fallback." : "Driver-failure fixture did not reject a planned driver."
103
- });
104
- return evidence;
105
- }
106
- export async function executeValidationEvidence(revision) {
107
- const evidence = new Map, validationUrl = blob(revision, "storage/framework/core/validation/src/validator.ts"), envelopeUrl = blob(revision, "storage/framework/core/router/src/error-handler.ts"), started = performance.now(), result = await object({ profile: object({ email: string().email() }) }).validate({ profile: { email: "bad" } }), valOk = result.valid === !1 && Object.keys(result.errors).includes("profile.email");
108
- evidence.set("CORE-VAL-01", {
109
- status: valOk ? "pass" : "fail",
110
- evidenceUrl: validationUrl,
111
- durationMs: Math.max(0, performance.now() - started),
112
- notes: valOk ? "Nested invalid input produced a stable field-keyed error at profile.email." : "Field-keyed validation fixture failed."
113
- });
114
- const envStarted = performance.now(), fieldErrors = {};
115
- for (const [field, errors] of Object.entries(result.errors))
116
- fieldErrors[field] = errors.map((entry) => entry.message ?? String(entry));
117
- const response = createValidationErrorResponse(fieldErrors, new Request("http://conformance.local/profile", { method: "POST" })), body = await response.text(), durationEnv = Math.max(0, performance.now() - envStarted), envelopeOk = response.status === 422 && body.includes('"message":"Validation failed"') && body.includes("profile.email");
118
- evidence.set("CORE-ERR-01", {
119
- status: envelopeOk ? "pass" : "fail",
120
- evidenceUrl: envelopeUrl,
121
- durationMs: durationEnv,
122
- notes: envelopeOk ? "Validation failure serialized to a stable 422 envelope with error, message, status, and field errors." : "Error-envelope fixture failed."
123
- });
124
- const leaks = ["stack", "password", "SELECT", "/home/"].filter((token) => body.includes(token));
125
- evidence.set("CORE-ERR-02", {
126
- status: envelopeOk && leaks.length === 0 ? "pass" : "fail",
127
- evidenceUrl: envelopeUrl,
128
- durationMs: durationEnv,
129
- notes: leaks.length === 0 ? "Production error envelope contained no stack trace, credentials, raw query, or filesystem path." : `Production error envelope leaked: ${leaks.join(", ")}.`
130
- });
131
- return evidence;
132
- }
133
- export function executeConventionsEvidence(revision) {
134
- const evidence = new Map, rolesUrl = blob(revision, "storage/framework/core/path/src/index.ts"), overrideUrl = blob(revision, "storage/framework/core/router/src/stacks-router.ts"), started = performance.now(), conv01Ok = appPath("Actions/Greet").endsWith("/app/Actions/Greet");
135
- evidence.set("CORE-CONV-01", {
136
- status: conv01Ok ? "pass" : "fail",
137
- evidenceUrl: rolesUrl,
138
- durationMs: Math.max(0, performance.now() - started),
139
- notes: conv01Ok ? "The Action role maps to its documented app/Actions/<name> path." : "Role-to-path mapping fixture failed."
140
- });
141
- const overrideStarted = performance.now(), logical = "Actions/NotifyUser.ts", userCandidate = appPath(logical), defaultCandidate = defaultsAppPath(logical), resolved = existsSync(userCandidate) ? userCandidate : defaultCandidate, conv02Ok = existsSync(userCandidate) && existsSync(defaultCandidate) && resolved === userCandidate;
142
- evidence.set("CORE-CONV-02", {
143
- status: conv02Ok ? "pass" : "fail",
144
- evidenceUrl: overrideUrl,
145
- durationMs: Math.max(0, performance.now() - overrideStarted),
146
- notes: conv02Ok ? "With the same logical path present in both app/ and framework defaults, resolution selects the app-owned file." : "Override-precedence fixture failed."
147
- });
148
- return evidence;
149
- }
150
- export async function executeLifecycleEvidence(revision) {
151
- const evidence = new Map, url = blob(revision, "storage/framework/core/actions/src/action.ts"), started = performance.now(), mvaOk = (await new Action({
152
- name: "Increment",
153
- handle(request) {
154
- return { value: request.body.value + 1 };
155
- }
156
- }).handle({ body: { value: 1 } }))?.value === 2;
157
- evidence.set("CORE-MVA-01", {
158
- status: mvaOk ? "pass" : "fail",
159
- evidenceUrl: url,
160
- durationMs: Math.max(0, performance.now() - started),
161
- notes: mvaOk ? "An Action was invoked directly with no HTTP transport and returned its computed result." : "Direct Action invocation fixture failed."
162
- });
163
- return evidence;
164
- }
165
- export async function executeQueryEvidence(revision) {
166
- const evidence = new Map, url = blob(revision, "storage/framework/core/database/src/types.ts"), started = performance.now();
167
- try {
168
- const { sql } = await import("../../../../database/src/types"), attack = "' OR 1=1 --", query = sql`SELECT * FROM users WHERE email = ${attack}`, parameterized = query.sql === "SELECT * FROM users WHERE email = ?" && Array.isArray(query.parameters) && query.parameters.length === 1 && query.parameters[0] === attack;
169
- evidence.set("CORE-SEC-01", {
170
- status: parameterized ? "pass" : "fail",
171
- evidenceUrl: url,
172
- durationMs: Math.max(0, performance.now() - started),
173
- notes: parameterized ? "Untrusted input is bound as a positional parameter and never inlined into the SQL text." : "Query-parameterization fixture failed."
174
- });
175
- } catch (error) {
176
- evidence.set("CORE-SEC-01", {
177
- status: "skipped",
178
- evidenceUrl: null,
179
- durationMs: Math.max(0, performance.now() - started),
180
- notes: `Query builder unavailable in this environment: ${error instanceof Error ? error.message.slice(0, 100) : String(error)}`
181
- });
182
- }
183
- return evidence;
184
- }
185
- export async function executeDatabaseEvidence(revision) {
186
- const evidence = new Map, url = blob(revision, "storage/framework/core/query-builder/src/index.ts"), started = performance.now();
187
- try {
188
- const { createQueryBuilder, setConfig } = await import("../../../../query-builder/src/index");
189
- setConfig({ dialect: "sqlite", database: ":memory:" });
190
- const db = createQueryBuilder();
191
- await db.raw`DROP TABLE IF EXISTS conformance_widgets`.execute();
192
- await db.raw`CREATE TABLE conformance_widgets (id INTEGER PRIMARY KEY, name TEXT)`.execute();
193
- await db.insertInto("conformance_widgets").values({ id: 1, name: "a" }).execute();
194
- const created = await db.selectFrom("conformance_widgets").selectAll().execute();
195
- await db.updateTable("conformance_widgets").set({ name: "b" }).where("id", "=", 1).execute();
196
- const updated = await db.selectFrom("conformance_widgets").select(["name"]).where("id", "=", 1).execute();
197
- await db.deleteFrom("conformance_widgets").where("id", "=", 1).execute();
198
- const afterDelete = await db.selectFrom("conformance_widgets").selectAll().execute(), crudOk = created.length === 1 && created[0]?.name === "a" && updated[0]?.name === "b" && afterDelete.length === 0;
199
- evidence.set("CORE-DATA-01", {
200
- status: crudOk ? "pass" : "fail",
201
- evidenceUrl: url,
202
- durationMs: Math.max(0, performance.now() - started),
203
- notes: crudOk ? "Create, read, update, and delete round-trip succeeded against SQLite." : "CRUD fixture failed."
204
- });
205
- const txStarted = performance.now();
206
- await db.insertInto("conformance_widgets").values({ id: 1, name: "keep" }).execute();
207
- let rolledBack = !1;
208
- try {
209
- await db.transaction(async (trx) => {
210
- await trx.insertInto("conformance_widgets").values({ id: 2, name: "temp" }).execute();
211
- throw Error("force rollback");
212
- });
213
- } catch {
214
- rolledBack = !0;
215
- }
216
- const rows = await db.selectFrom("conformance_widgets").selectAll().execute(), txOk = rolledBack && rows.length === 1 && rows[0]?.id === 1;
217
- evidence.set("CORE-DATA-03", {
218
- status: txOk ? "pass" : "fail",
219
- evidenceUrl: url,
220
- durationMs: Math.max(0, performance.now() - txStarted),
221
- notes: txOk ? "A failing transaction rolled back its writes, leaving prior state intact." : "Transaction-rollback fixture failed."
222
- });
223
- const relStarted = performance.now();
224
- await db.raw`DROP TABLE IF EXISTS conformance_books`.execute();
225
- await db.raw`DROP TABLE IF EXISTS conformance_authors`.execute();
226
- await db.raw`CREATE TABLE conformance_authors (id INTEGER PRIMARY KEY, name TEXT)`.execute();
227
- await db.raw`CREATE TABLE conformance_books (id INTEGER PRIMARY KEY, author_id INTEGER, title TEXT)`.execute();
228
- await db.insertInto("conformance_authors").values({ id: 1, name: "Ada" }).execute();
229
- await db.insertInto("conformance_books").values([{ id: 1, author_id: 1, title: "B1" }, { id: 2, author_id: 1, title: "B2" }]).execute();
230
- const related = await db.selectFrom("conformance_books").innerJoin("conformance_authors", "conformance_authors.id", "=", "conformance_books.author_id").select(["conformance_books.title", "conformance_authors.name"]).where("conformance_authors.id", "=", 1).execute(), relationOk = related.length === 2 && related.every((row) => row.name === "Ada");
231
- evidence.set("CORE-DATA-02", {
232
- status: relationOk ? "pass" : "fail",
233
- evidenceUrl: url,
234
- durationMs: Math.max(0, performance.now() - relStarted),
235
- notes: relationOk ? "A relation query joined related rows across two tables." : "Relation fixture failed."
236
- });
237
- } catch (error) {
238
- const note = `Query builder unavailable in this environment: ${error instanceof Error ? error.message.slice(0, 100) : String(error)}`;
239
- for (const id of ["CORE-DATA-01", "CORE-DATA-02", "CORE-DATA-03"])
240
- if (!evidence.has(id))
241
- evidence.set(id, { status: "skipped", evidenceUrl: null, durationMs: Math.max(0, performance.now() - started), notes: note });
242
- }
243
- return evidence;
244
- }
245
- function validateSemantics(report, catalog, fixtures) {
246
- const errors = [], expected = new Set(catalog.requirements.map((requirement) => requirement.id)), seen = new Set, fixtureIds = new Set(fixtures.fixtures.map((fixture) => fixture.id));
247
- for (const result of report.results) {
248
- if (seen.has(result.requirementId))
249
- errors.push(`${result.requirementId}: duplicate result`);
250
- if (!expected.has(result.requirementId))
251
- errors.push(`${result.requirementId}: unknown requirement`);
252
- if (result.fixtureId && !fixtureIds.has(result.fixtureId))
253
- errors.push(`${result.requirementId}: unknown fixture`);
254
- if (result.status === "pass" && !result.evidenceUrl)
255
- errors.push(`${result.requirementId}: pass requires evidence`);
256
- seen.add(result.requirementId);
257
- }
258
- for (const id of expected)
259
- if (!seen.has(id))
260
- errors.push(`${id}: missing result`);
261
- if (report.profileClaim !== null)
262
- errors.push("The Stacks adapter must remain unverified until profile calculation is implemented");
263
- return errors;
264
- }
265
- function renderSummary(report) {
266
- const counts = new Map;
267
- for (const result of report.results)
268
- counts.set(result.status, (counts.get(result.status) || 0) + 1);
269
- const rows = [...counts].sort(([a], [b]) => a.localeCompare(b)).map(([status, count]) => `| ${status} | ${count} |`).join(`
270
- `);
271
- return `# Stacks protocol conformance report
1
+ import{createHash}from"node:crypto";import{existsSync,mkdirSync,readFileSync,writeFileSync}from"node:fs";import{arch,platform}from"node:os";import{resolve}from"node:path";import Ajv2020 from"ajv/dist/2020.js";import addFormats from"ajv-formats";import{Action}from"../../../../actions/src/index";import{assertCapabilityAvailable,capabilityRegistry}from"../../../../config/src/capabilities";import{decryptValue,encryptValue,generateKeypair}from"../../../../env/src/crypto";import{escapeHtml}from"../../../../error-handling/src/error-page-template";import{appPath,defaultsAppPath}from"../../../../path/src/index";import{createValidationErrorResponse}from"../../../../router/src/error-handler";import{timingSafeEqualString}from"../../../../security/src/hash";import{object,string}from"../../../../validation/src/index";const root=resolve(import.meta.dir,"../../../../../../.."),suiteRoot=resolve(root,".github/protocol/suite/1.0-draft");function git(...arguments_){const result=Bun.spawnSync(["git",...arguments_],{cwd:root});if(result.exitCode!==0)throw Error(result.stderr.toString().trim());return result.stdout.toString().trim()}function exactSourceDigest(){const tree=git("rev-parse","HEAD^{tree}");return`sha256:${createHash("sha256").update(tree).digest("hex")}`}function tamper(ciphertext){const prefix="encrypted:",payload=Buffer.from(ciphertext.slice(prefix.length),"base64"),last=payload.length-1;if(last>=0)payload[last]=(payload[last]??0)^1;return`${prefix}${payload.toString("base64")}`}function blob(revision,path){return`https://github.com/stacksjs/stacks/blob/${revision}/${path}`}export function executeSecurityEvidence(revision){const evidence=new Map,cryptoUrl=blob(revision,"storage/framework/core/env/src/crypto.ts"),comparisonUrl=blob(revision,"storage/framework/core/security/src/hash.ts"),renderUrl=blob(revision,"storage/framework/core/error-handling/src/error-page-template.ts"),started=performance.now();try{const{publicKey,privateKey}=generateKeypair(),encrypted=encryptValue("secret",publicKey),roundTrip=decryptValue(encrypted,privateKey);let tamperRejected=!1;try{decryptValue(tamper(encrypted),privateKey)}catch{tamperRejected=!0}const passed=roundTrip==="secret"&&!encrypted.includes("secret")&&tamperRejected;evidence.set("CORE-SEC-05",{status:passed?"pass":"fail",evidenceUrl:cryptoUrl,durationMs:Math.max(0,performance.now()-started),notes:passed?"Authenticated-encryption round trip passed and modified ciphertext was rejected.":"Authenticated-encryption fixture failed."})}catch(error){evidence.set("CORE-SEC-05",{status:"fail",evidenceUrl:cryptoUrl,durationMs:Math.max(0,performance.now()-started),notes:`Authenticated-encryption fixture threw: ${error instanceof Error?error.message:String(error)}`})}const comparisonStarted=performance.now(),unequal=timingSafeEqualString("token-a","token-b")===!1;evidence.set("CORE-SEC-07",{status:unequal?"pass":"fail",evidenceUrl:comparisonUrl,durationMs:Math.max(0,performance.now()-comparisonStarted),notes:unequal?"The public authenticator comparison helper uses the runtime timing-safe primitive.":"Timing-safe comparison fixture failed."});const renderStarted=performance.now(),renderOk=escapeHtml("<script>alert(1)</script>")==="&lt;script&gt;alert(1)&lt;/script&gt;";evidence.set("CORE-SEC-02",{status:renderOk?"pass":"fail",evidenceUrl:renderUrl,durationMs:Math.max(0,performance.now()-renderStarted),notes:renderOk?"Untrusted markup is converted to HTML entities by the default escaper.":"Default render-escaping fixture failed."});return evidence}export function executeConfigEvidence(revision){const evidence=new Map,url=blob(revision,"storage/framework/core/config/src/capabilities.ts"),started=performance.now();let failedClosed=!1,message="";try{assertCapabilityAvailable("queue","planned")}catch(error){failedClosed=!0;message=error instanceof Error?error.message:String(error)}evidence.set("CORE-CONFIG-02",{status:failedClosed?"pass":"fail",evidenceUrl:url,durationMs:Math.max(0,performance.now()-started),notes:failedClosed?`Selecting an unavailable driver is rejected before use: ${message}`:"Fail-closed capability guard accepted an unavailable driver."});const drvStarted=performance.now();let drvFailedClosed=!1;try{assertCapabilityAvailable("queue","planned-driver")}catch{drvFailedClosed=!0}evidence.set("STD-DRV-01",{status:drvFailedClosed?"pass":"fail",evidenceUrl:url,durationMs:Math.max(0,performance.now()-drvStarted),notes:drvFailedClosed?"A planned driver is rejected loudly with no silent fallback.":"Driver-failure fixture did not reject a planned driver."});return evidence}export async function executeValidationEvidence(revision){const evidence=new Map,validationUrl=blob(revision,"storage/framework/core/validation/src/validator.ts"),envelopeUrl=blob(revision,"storage/framework/core/router/src/error-handler.ts"),started=performance.now(),result=await object({profile:object({email:string().email()})}).validate({profile:{email:"bad"}}),valOk=result.valid===!1&&Object.keys(result.errors).includes("profile.email");evidence.set("CORE-VAL-01",{status:valOk?"pass":"fail",evidenceUrl:validationUrl,durationMs:Math.max(0,performance.now()-started),notes:valOk?"Nested invalid input produced a stable field-keyed error at profile.email.":"Field-keyed validation fixture failed."});const envStarted=performance.now(),fieldErrors={};for(const[field,errors]of Object.entries(result.errors))fieldErrors[field]=errors.map((entry)=>entry.message??String(entry));const response=createValidationErrorResponse(fieldErrors,new Request("http://conformance.local/profile",{method:"POST"})),body=await response.text(),durationEnv=Math.max(0,performance.now()-envStarted),envelopeOk=response.status===422&&body.includes('"message":"Validation failed"')&&body.includes("profile.email");evidence.set("CORE-ERR-01",{status:envelopeOk?"pass":"fail",evidenceUrl:envelopeUrl,durationMs:durationEnv,notes:envelopeOk?"Validation failure serialized to a stable 422 envelope with error, message, status, and field errors.":"Error-envelope fixture failed."});const leaks=["stack","password","SELECT","/home/"].filter((token)=>body.includes(token));evidence.set("CORE-ERR-02",{status:envelopeOk&&leaks.length===0?"pass":"fail",evidenceUrl:envelopeUrl,durationMs:durationEnv,notes:leaks.length===0?"Production error envelope contained no stack trace, credentials, raw query, or filesystem path.":`Production error envelope leaked: ${leaks.join(", ")}.`});return evidence}export function executeConventionsEvidence(revision){const evidence=new Map,rolesUrl=blob(revision,"storage/framework/core/path/src/index.ts"),overrideUrl=blob(revision,"storage/framework/core/router/src/stacks-router.ts"),started=performance.now(),conv01Ok=appPath("Actions/Greet").endsWith("/app/Actions/Greet");evidence.set("CORE-CONV-01",{status:conv01Ok?"pass":"fail",evidenceUrl:rolesUrl,durationMs:Math.max(0,performance.now()-started),notes:conv01Ok?"The Action role maps to its documented app/Actions/<name> path.":"Role-to-path mapping fixture failed."});const overrideStarted=performance.now(),logical="Actions/NotifyUser.ts",userCandidate=appPath(logical),defaultCandidate=defaultsAppPath(logical),resolved=existsSync(userCandidate)?userCandidate:defaultCandidate,conv02Ok=existsSync(userCandidate)&&existsSync(defaultCandidate)&&resolved===userCandidate;evidence.set("CORE-CONV-02",{status:conv02Ok?"pass":"fail",evidenceUrl:overrideUrl,durationMs:Math.max(0,performance.now()-overrideStarted),notes:conv02Ok?"With the same logical path present in both app/ and framework defaults, resolution selects the app-owned file.":"Override-precedence fixture failed."});return evidence}export async function executeLifecycleEvidence(revision){const evidence=new Map,url=blob(revision,"storage/framework/core/actions/src/action.ts"),started=performance.now(),mvaOk=(await new Action({name:"Increment",handle(request){return{value:request.body.value+1}}}).handle({body:{value:1}}))?.value===2;evidence.set("CORE-MVA-01",{status:mvaOk?"pass":"fail",evidenceUrl:url,durationMs:Math.max(0,performance.now()-started),notes:mvaOk?"An Action was invoked directly with no HTTP transport and returned its computed result.":"Direct Action invocation fixture failed."});return evidence}export async function executeQueryEvidence(revision){const evidence=new Map,url=blob(revision,"storage/framework/core/database/src/types.ts"),started=performance.now();try{const{sql}=await import("../../../../database/src/types"),attack="' OR 1=1 --",query=sql`SELECT * FROM users WHERE email = ${attack}`,parameterized=query.sql==="SELECT * FROM users WHERE email = ?"&&Array.isArray(query.parameters)&&query.parameters.length===1&&query.parameters[0]===attack;evidence.set("CORE-SEC-01",{status:parameterized?"pass":"fail",evidenceUrl:url,durationMs:Math.max(0,performance.now()-started),notes:parameterized?"Untrusted input is bound as a positional parameter and never inlined into the SQL text.":"Query-parameterization fixture failed."})}catch(error){evidence.set("CORE-SEC-01",{status:"skipped",evidenceUrl:null,durationMs:Math.max(0,performance.now()-started),notes:`Query builder unavailable in this environment: ${error instanceof Error?error.message.slice(0,100):String(error)}`})}return evidence}export async function executeDatabaseEvidence(revision){const evidence=new Map,url=blob(revision,"storage/framework/core/query-builder/src/index.ts"),started=performance.now();try{const{createQueryBuilder,setConfig}=await import("../../../../query-builder/src/index");setConfig({dialect:"sqlite",database:":memory:"});const db=createQueryBuilder();await db.raw`DROP TABLE IF EXISTS conformance_widgets`.execute();await db.raw`CREATE TABLE conformance_widgets (id INTEGER PRIMARY KEY, name TEXT)`.execute();await db.insertInto("conformance_widgets").values({id:1,name:"a"}).execute();const created=await db.selectFrom("conformance_widgets").selectAll().execute();await db.updateTable("conformance_widgets").set({name:"b"}).where("id","=",1).execute();const updated=await db.selectFrom("conformance_widgets").select(["name"]).where("id","=",1).execute();await db.deleteFrom("conformance_widgets").where("id","=",1).execute();const afterDelete=await db.selectFrom("conformance_widgets").selectAll().execute(),crudOk=created.length===1&&created[0]?.name==="a"&&updated[0]?.name==="b"&&afterDelete.length===0;evidence.set("CORE-DATA-01",{status:crudOk?"pass":"fail",evidenceUrl:url,durationMs:Math.max(0,performance.now()-started),notes:crudOk?"Create, read, update, and delete round-trip succeeded against SQLite.":"CRUD fixture failed."});const txStarted=performance.now();await db.insertInto("conformance_widgets").values({id:1,name:"keep"}).execute();let rolledBack=!1;try{await db.transaction(async(trx)=>{await trx.insertInto("conformance_widgets").values({id:2,name:"temp"}).execute();throw Error("force rollback")})}catch{rolledBack=!0}const rows=await db.selectFrom("conformance_widgets").selectAll().execute(),txOk=rolledBack&&rows.length===1&&rows[0]?.id===1;evidence.set("CORE-DATA-03",{status:txOk?"pass":"fail",evidenceUrl:url,durationMs:Math.max(0,performance.now()-txStarted),notes:txOk?"A failing transaction rolled back its writes, leaving prior state intact.":"Transaction-rollback fixture failed."});const relStarted=performance.now();await db.raw`DROP TABLE IF EXISTS conformance_books`.execute();await db.raw`DROP TABLE IF EXISTS conformance_authors`.execute();await db.raw`CREATE TABLE conformance_authors (id INTEGER PRIMARY KEY, name TEXT)`.execute();await db.raw`CREATE TABLE conformance_books (id INTEGER PRIMARY KEY, author_id INTEGER, title TEXT)`.execute();await db.insertInto("conformance_authors").values({id:1,name:"Ada"}).execute();await db.insertInto("conformance_books").values([{id:1,author_id:1,title:"B1"},{id:2,author_id:1,title:"B2"}]).execute();const related=await db.selectFrom("conformance_books").innerJoin("conformance_authors","conformance_authors.id","=","conformance_books.author_id").select(["conformance_books.title","conformance_authors.name"]).where("conformance_authors.id","=",1).execute(),relationOk=related.length===2&&related.every((row)=>row.name==="Ada");evidence.set("CORE-DATA-02",{status:relationOk?"pass":"fail",evidenceUrl:url,durationMs:Math.max(0,performance.now()-relStarted),notes:relationOk?"A relation query joined related rows across two tables.":"Relation fixture failed."})}catch(error){const note=`Query builder unavailable in this environment: ${error instanceof Error?error.message.slice(0,100):String(error)}`;for(const id of["CORE-DATA-01","CORE-DATA-02","CORE-DATA-03"])if(!evidence.has(id))evidence.set(id,{status:"skipped",evidenceUrl:null,durationMs:Math.max(0,performance.now()-started),notes:note})}return evidence}function validateSemantics(report,catalog,fixtures){const errors=[],expected=new Set(catalog.requirements.map((requirement)=>requirement.id)),seen=new Set,fixtureIds=new Set(fixtures.fixtures.map((fixture)=>fixture.id));for(const result of report.results){if(seen.has(result.requirementId))errors.push(`${result.requirementId}: duplicate result`);if(!expected.has(result.requirementId))errors.push(`${result.requirementId}: unknown requirement`);if(result.fixtureId&&!fixtureIds.has(result.fixtureId))errors.push(`${result.requirementId}: unknown fixture`);if(result.status==="pass"&&!result.evidenceUrl)errors.push(`${result.requirementId}: pass requires evidence`);seen.add(result.requirementId)}for(const id of expected)if(!seen.has(id))errors.push(`${id}: missing result`);if(report.profileClaim!==null)errors.push("The Stacks adapter must remain unverified until profile calculation is implemented");return errors}function renderSummary(report){const counts=new Map;for(const result of report.results)counts.set(result.status,(counts.get(result.status)||0)+1);const rows=[...counts].sort(([a],[b])=>a.localeCompare(b)).map(([status,count])=>`| ${status} | ${count} |`).join(`
2
+ `);return`# Stacks protocol conformance report
272
3
 
273
4
  **Profile claim:** Unverified
274
5
  **Implementation:** \`${report.implementation.revision}\` (${report.implementation.version})
@@ -281,78 +12,5 @@ function renderSummary(report) {
281
12
  ${rows}
282
13
 
283
14
  Only executable adapter checks are marked \`pass\`. All remaining requirements stay \`skipped\` until their fixtures are wired to Stacks public APIs.
284
- `;
285
- }
286
- export async function buildReport() {
287
- const startedAt = new Date, catalog = JSON.parse(readFileSync(resolve(suiteRoot, "catalog.json"), "utf8")), fixtures = JSON.parse(readFileSync(resolve(suiteRoot, "fixtures/conformance.json"), "utf8")), lock = JSON.parse(readFileSync(resolve(root, ".github/protocol/suite.lock.json"), "utf8")), packageJson = JSON.parse(readFileSync(resolve(root, "package.json"), "utf8")), revision = process.env.GITHUB_SHA || git("rev-parse", "HEAD"), runUrl = process.env.GITHUB_SERVER_URL && process.env.GITHUB_REPOSITORY && process.env.GITHUB_RUN_ID ? `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}` : `https://github.com/stacksjs/stacks/commit/${revision}`, evidence = executeSecurityEvidence(revision);
288
- for (const [id, value] of executeConfigEvidence(revision))
289
- evidence.set(id, value);
290
- for (const [id, value] of executeConventionsEvidence(revision))
291
- evidence.set(id, value);
292
- for (const [id, value] of await executeValidationEvidence(revision))
293
- evidence.set(id, value);
294
- for (const [id, value] of await executeLifecycleEvidence(revision))
295
- evidence.set(id, value);
296
- for (const [id, value] of await executeQueryEvidence(revision))
297
- evidence.set(id, value);
298
- for (const [id, value] of await executeDatabaseEvidence(revision))
299
- evidence.set(id, value);
300
- const fixtureByRequirement = new Map(fixtures.fixtures.flatMap((fixture) => fixture.requirements.map((id) => [id, fixture.id]))), results = catalog.requirements.map((requirement) => ({
301
- requirementId: requirement.id,
302
- fixtureId: fixtureByRequirement.get(requirement.id) || null,
303
- ...evidence.get(requirement.id) || {
304
- status: "skipped",
305
- evidenceUrl: null,
306
- durationMs: 0,
307
- notes: requirement.evidence === "behavior" ? "Fixture adapter is not implemented yet." : "Inspection evidence is not linked yet."
308
- }
309
- })), drivers = capabilityRegistry.map((driver) => ({
310
- category: driver.category,
311
- name: driver.name,
312
- version: packageJson.version,
313
- serviceVersion: null,
314
- topology: driver.topology,
315
- status: driver.status,
316
- evidenceUrl: driver.testEvidence[0] ? `https://github.com/stacksjs/stacks/blob/${revision}/${driver.testEvidence[0]}` : null,
317
- prerequisites: driver.prerequisites
318
- }));
319
- return {
320
- reportVersion: "1.0.0-draft.1",
321
- protocol: { version: catalog.protocolVersion, catalogRevision: catalog.catalogRevision, suiteVersion: fixtures.suiteVersion, rfcsRevision: lock.rfcsRevision },
322
- implementation: { name: "Stacks", version: packageJson.version, revision, repository: "https://github.com/stacksjs/stacks", sourceDigest: exactSourceDigest() },
323
- execution: {
324
- startedAt: startedAt.toISOString(),
325
- completedAt: new Date().toISOString(),
326
- runtime: { name: "bun", version: Bun.version },
327
- platform: { os: platform(), architecture: arch() },
328
- ci: { provider: process.env.GITHUB_ACTIONS ? "github-actions" : "local", runUrl, artifactUrl: `${runUrl}#artifacts` }
329
- },
330
- profileClaim: null,
331
- results,
332
- drivers,
333
- extensions: catalog.extensions.map((extension) => extension.id === "EXT-DESKTOP-01" ? { id: extension.id, status: "experimental", evidenceUrl: `https://github.com/stacksjs/stacks/blob/${revision}/protocol/evidence/desktop-support.json`, notes: "Craft targets are explicitly experimental pending native release evidence and signing infrastructure." } : { id: extension.id, status: "unsupported", evidenceUrl: null, notes: "Not evaluated by this adapter." }),
334
- exceptions: [],
335
- generator: { name: "@stacksjs/protocol-adapter", version: "1.0.0-draft.1", revision }
336
- };
337
- }
338
- export async function run() {
339
- const report = await buildReport(), schema = JSON.parse(readFileSync(resolve(suiteRoot, "schemas/conformance-report.schema.json"), "utf8")), catalog = JSON.parse(readFileSync(resolve(suiteRoot, "catalog.json"), "utf8")), fixtures = JSON.parse(readFileSync(resolve(suiteRoot, "fixtures/conformance.json"), "utf8")), ajv = new Ajv2020({ allErrors: !0, strict: !1 });
340
- addFormats(ajv);
341
- const validate = ajv.compile(schema), errors = [
342
- ...validate(report) ? [] : (validate.errors || []).map((error) => `${error.instancePath || "/"} ${error.message || "is invalid"}`),
343
- ...validateSemantics(report, catalog, fixtures)
344
- ];
345
- if (errors.length > 0) {
346
- for (const error of errors)
347
- console.error(`error: ${error}`);
348
- process.exit(1);
349
- }
350
- const outputDirectory = resolve(process.env.PROTOCOL_REPORT_DIR || resolve(root, ".github/protocol/reports"));
351
- mkdirSync(outputDirectory, { recursive: !0 });
352
- writeFileSync(resolve(outputDirectory, "stacks-conformance.json"), `${JSON.stringify(report, null, 2)}
353
- `);
354
- writeFileSync(resolve(outputDirectory, "stacks-conformance.md"), renderSummary(report));
355
- console.log(`Protocol report generated in ${outputDirectory}`);
356
- }
357
- if (import.meta.main)
358
- await run();
15
+ `}export async function buildReport(){const startedAt=new Date,catalog=JSON.parse(readFileSync(resolve(suiteRoot,"catalog.json"),"utf8")),fixtures=JSON.parse(readFileSync(resolve(suiteRoot,"fixtures/conformance.json"),"utf8")),lock=JSON.parse(readFileSync(resolve(root,".github/protocol/suite.lock.json"),"utf8")),packageJson=JSON.parse(readFileSync(resolve(root,"package.json"),"utf8")),revision=process.env.GITHUB_SHA||git("rev-parse","HEAD"),runUrl=process.env.GITHUB_SERVER_URL&&process.env.GITHUB_REPOSITORY&&process.env.GITHUB_RUN_ID?`${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`:`https://github.com/stacksjs/stacks/commit/${revision}`,evidence=executeSecurityEvidence(revision);for(const[id,value]of executeConfigEvidence(revision))evidence.set(id,value);for(const[id,value]of executeConventionsEvidence(revision))evidence.set(id,value);for(const[id,value]of await executeValidationEvidence(revision))evidence.set(id,value);for(const[id,value]of await executeLifecycleEvidence(revision))evidence.set(id,value);for(const[id,value]of await executeQueryEvidence(revision))evidence.set(id,value);for(const[id,value]of await executeDatabaseEvidence(revision))evidence.set(id,value);const fixtureByRequirement=new Map(fixtures.fixtures.flatMap((fixture)=>fixture.requirements.map((id)=>[id,fixture.id]))),results=catalog.requirements.map((requirement)=>({requirementId:requirement.id,fixtureId:fixtureByRequirement.get(requirement.id)||null,...evidence.get(requirement.id)||{status:"skipped",evidenceUrl:null,durationMs:0,notes:requirement.evidence==="behavior"?"Fixture adapter is not implemented yet.":"Inspection evidence is not linked yet."}})),drivers=capabilityRegistry.map((driver)=>({category:driver.category,name:driver.name,version:packageJson.version,serviceVersion:null,topology:driver.topology,status:driver.status,evidenceUrl:driver.testEvidence[0]?`https://github.com/stacksjs/stacks/blob/${revision}/${driver.testEvidence[0]}`:null,prerequisites:driver.prerequisites}));return{reportVersion:"1.0.0-draft.1",protocol:{version:catalog.protocolVersion,catalogRevision:catalog.catalogRevision,suiteVersion:fixtures.suiteVersion,rfcsRevision:lock.rfcsRevision},implementation:{name:"Stacks",version:packageJson.version,revision,repository:"https://github.com/stacksjs/stacks",sourceDigest:exactSourceDigest()},execution:{startedAt:startedAt.toISOString(),completedAt:new Date().toISOString(),runtime:{name:"bun",version:Bun.version},platform:{os:platform(),architecture:arch()},ci:{provider:process.env.GITHUB_ACTIONS?"github-actions":"local",runUrl,artifactUrl:`${runUrl}#artifacts`}},profileClaim:null,results,drivers,extensions:catalog.extensions.map((extension)=>extension.id==="EXT-DESKTOP-01"?{id:extension.id,status:"experimental",evidenceUrl:`https://github.com/stacksjs/stacks/blob/${revision}/protocol/evidence/desktop-support.json`,notes:"Craft targets are explicitly experimental pending native release evidence and signing infrastructure."}:{id:extension.id,status:"unsupported",evidenceUrl:null,notes:"Not evaluated by this adapter."}),exceptions:[],generator:{name:"@stacksjs/protocol-adapter",version:"1.0.0-draft.1",revision}}}export async function run(){const report=await buildReport(),schema=JSON.parse(readFileSync(resolve(suiteRoot,"schemas/conformance-report.schema.json"),"utf8")),catalog=JSON.parse(readFileSync(resolve(suiteRoot,"catalog.json"),"utf8")),fixtures=JSON.parse(readFileSync(resolve(suiteRoot,"fixtures/conformance.json"),"utf8")),ajv=new Ajv2020({allErrors:!0,strict:!1});addFormats(ajv);const validate=ajv.compile(schema),errors=[...validate(report)?[]:(validate.errors||[]).map((error)=>`${error.instancePath||"/"} ${error.message||"is invalid"}`),...validateSemantics(report,catalog,fixtures)];if(errors.length>0){for(const error of errors)console.error(`error: ${error}`);process.exit(1)}const outputDirectory=resolve(process.env.PROTOCOL_REPORT_DIR||resolve(root,".github/protocol/reports"));mkdirSync(outputDirectory,{recursive:!0});writeFileSync(resolve(outputDirectory,"stacks-conformance.json"),`${JSON.stringify(report,null,2)}
16
+ `);writeFileSync(resolve(outputDirectory,"stacks-conformance.md"),renderSummary(report));console.log(`Protocol report generated in ${outputDirectory}`)}if(import.meta.main)await run();
@@ -1,52 +1 @@
1
- import { describe, expect, it } from "bun:test";
2
- import { buildReport, executeConfigEvidence, executeConventionsEvidence, executeDatabaseEvidence, executeLifecycleEvidence, executeQueryEvidence, executeSecurityEvidence, executeValidationEvidence } from "./run-conformance";
3
- const REVISION = "0".repeat(40);
4
- describe("protocol adapter evidence", () => {
5
- it("executes authenticated encryption, timing-safe comparison, and default escaping checks", () => {
6
- const evidence = executeSecurityEvidence(REVISION);
7
- expect(evidence.get("CORE-SEC-05")?.status).toBe("pass");
8
- expect(evidence.get("CORE-SEC-07")?.status).toBe("pass");
9
- expect(evidence.get("CORE-SEC-02")?.status).toBe("pass");
10
- });
11
- it("rejects unavailable and planned drivers loudly, before any work begins", () => {
12
- const evidence = executeConfigEvidence(REVISION);
13
- expect(evidence.get("CORE-CONFIG-02")?.status).toBe("pass");
14
- expect(evidence.get("STD-DRV-01")?.status).toBe("pass");
15
- });
16
- it("invokes an Action directly, independent of any HTTP transport", async () => {
17
- const evidence = await executeLifecycleEvidence(REVISION);
18
- expect(evidence.get("CORE-MVA-01")?.status).toBe("pass");
19
- });
20
- it("parameterizes untrusted values instead of inlining them into SQL", async () => {
21
- const evidence = await executeQueryEvidence(REVISION);
22
- expect(evidence.get("CORE-SEC-01")?.status).toBe("pass");
23
- });
24
- it("performs a CRUD round-trip, a relation join, and rolls back a failed transaction", async () => {
25
- const evidence = await executeDatabaseEvidence(REVISION);
26
- expect(evidence.get("CORE-DATA-01")?.status).toBe("pass");
27
- expect(evidence.get("CORE-DATA-02")?.status).toBe("pass");
28
- expect(evidence.get("CORE-DATA-03")?.status).toBe("pass");
29
- });
30
- it("produces field-keyed validation errors and a redacted 422 envelope", async () => {
31
- const evidence = await executeValidationEvidence(REVISION);
32
- expect(evidence.get("CORE-VAL-01")?.status).toBe("pass");
33
- expect(evidence.get("CORE-ERR-01")?.status).toBe("pass");
34
- expect(evidence.get("CORE-ERR-02")?.status).toBe("pass");
35
- });
36
- it("maps canonical roles to paths and prefers app-owned overrides", () => {
37
- const evidence = executeConventionsEvidence(REVISION);
38
- expect(evidence.get("CORE-CONV-01")?.status).toBe("pass");
39
- expect(evidence.get("CORE-CONV-02")?.status).toBe("pass");
40
- });
41
- it("reports each registered driver independently", async () => {
42
- const report = await buildReport();
43
- expect(report.drivers.length).toBeGreaterThan(7);
44
- expect(report.drivers).toContainEqual(expect.objectContaining({ category: "database", name: "sqlite" }));
45
- expect(report.drivers).toContainEqual(expect.objectContaining({ category: "queue", name: "sqs" }));
46
- });
47
- it("marks every passing requirement with a source evidence url", async () => {
48
- const passing = (await buildReport()).results.filter((result) => result.status === "pass");
49
- expect(passing.length).toBeGreaterThanOrEqual(15);
50
- expect(passing.every((result) => typeof result.evidenceUrl === "string" && result.evidenceUrl.startsWith("https://"))).toBe(!0);
51
- });
52
- });
1
+ import{describe,expect,it}from"bun:test";import{buildReport,executeConfigEvidence,executeConventionsEvidence,executeDatabaseEvidence,executeLifecycleEvidence,executeQueryEvidence,executeSecurityEvidence,executeValidationEvidence}from"./run-conformance";const REVISION="0".repeat(40);describe("protocol adapter evidence",()=>{it("executes authenticated encryption, timing-safe comparison, and default escaping checks",()=>{const evidence=executeSecurityEvidence(REVISION);expect(evidence.get("CORE-SEC-05")?.status).toBe("pass");expect(evidence.get("CORE-SEC-07")?.status).toBe("pass");expect(evidence.get("CORE-SEC-02")?.status).toBe("pass")});it("rejects unavailable and planned drivers loudly, before any work begins",()=>{const evidence=executeConfigEvidence(REVISION);expect(evidence.get("CORE-CONFIG-02")?.status).toBe("pass");expect(evidence.get("STD-DRV-01")?.status).toBe("pass")});it("invokes an Action directly, independent of any HTTP transport",async()=>{const evidence=await executeLifecycleEvidence(REVISION);expect(evidence.get("CORE-MVA-01")?.status).toBe("pass")});it("parameterizes untrusted values instead of inlining them into SQL",async()=>{const evidence=await executeQueryEvidence(REVISION);expect(evidence.get("CORE-SEC-01")?.status).toBe("pass")});it("performs a CRUD round-trip, a relation join, and rolls back a failed transaction",async()=>{const evidence=await executeDatabaseEvidence(REVISION);expect(evidence.get("CORE-DATA-01")?.status).toBe("pass");expect(evidence.get("CORE-DATA-02")?.status).toBe("pass");expect(evidence.get("CORE-DATA-03")?.status).toBe("pass")});it("produces field-keyed validation errors and a redacted 422 envelope",async()=>{const evidence=await executeValidationEvidence(REVISION);expect(evidence.get("CORE-VAL-01")?.status).toBe("pass");expect(evidence.get("CORE-ERR-01")?.status).toBe("pass");expect(evidence.get("CORE-ERR-02")?.status).toBe("pass")});it("maps canonical roles to paths and prefers app-owned overrides",()=>{const evidence=executeConventionsEvidence(REVISION);expect(evidence.get("CORE-CONV-01")?.status).toBe("pass");expect(evidence.get("CORE-CONV-02")?.status).toBe("pass")});it("reports each registered driver independently",async()=>{const report=await buildReport();expect(report.drivers.length).toBeGreaterThan(7);expect(report.drivers).toContainEqual(expect.objectContaining({category:"database",name:"sqlite"}));expect(report.drivers).toContainEqual(expect.objectContaining({category:"queue",name:"sqs"}))});it("marks every passing requirement with a source evidence url",async()=>{const passing=(await buildReport()).results.filter((result)=>result.status==="pass");expect(passing.length).toBeGreaterThanOrEqual(15);expect(passing.every((result)=>typeof result.evidenceUrl==="string"&&result.evidenceUrl.startsWith("https://"))).toBe(!0)})});
@@ -1,29 +1,5 @@
1
- import { Database } from "bun:sqlite";
2
- import { mkdirSync, writeFileSync } from "node:fs";
3
- import { arch, platform } from "node:os";
4
- import { resolve } from "node:path";
5
- import { capabilityRegistry } from "../../../../config/src/capabilities";
6
- const root = resolve(import.meta.dir, "../../../../../../.."), reportRoot = resolve(process.env.PROTOCOL_REPORT_DIR || resolve(root, ".github/protocol/reports"));
7
- export function planDriverContracts(drivers) {
8
- const tests = [...new Set(drivers.filter((driver) => driver.status === "supported").flatMap((driver) => driver.testEvidence))].sort(), records = drivers.map((driver) => ({
9
- ...driver,
10
- execution: driver.status === "supported" ? "run" : "not-run",
11
- reason: driver.status === "supported" ? null : `Maturity is ${driver.status}; prerequisites and missing evidence are reported without promotion.`
12
- }));
13
- return { tests, records };
14
- }
15
- function sqliteVersion() {
16
- const database = new Database(":memory:");
17
- try {
18
- return database.query("select sqlite_version() as version").get().version;
19
- } finally {
20
- database.close();
21
- }
22
- }
23
- function markdown(report) {
24
- const rows = report.drivers.map((driver) => `| ${driver.category} | ${driver.name} | ${driver.maturity} | ${driver.execution} | ${driver.topology} | ${driver.reason || "Retained test paths passed."} |`).join(`
25
- `);
26
- return `# Stacks driver contract matrix
1
+ import{Database}from"bun:sqlite";import{mkdirSync,writeFileSync}from"node:fs";import{arch,platform}from"node:os";import{resolve}from"node:path";import{capabilityRegistry}from"../../../../config/src/capabilities";const root=resolve(import.meta.dir,"../../../../../../.."),reportRoot=resolve(process.env.PROTOCOL_REPORT_DIR||resolve(root,".github/protocol/reports"));export function planDriverContracts(drivers){const tests=[...new Set(drivers.filter((driver)=>driver.status==="supported").flatMap((driver)=>driver.testEvidence))].sort(),records=drivers.map((driver)=>({...driver,execution:driver.status==="supported"?"run":"not-run",reason:driver.status==="supported"?null:`Maturity is ${driver.status}; prerequisites and missing evidence are reported without promotion.`}));return{tests,records}}function sqliteVersion(){const database=new Database(":memory:");try{return database.query("select sqlite_version() as version").get().version}finally{database.close()}}function markdown(report){const rows=report.drivers.map((driver)=>`| ${driver.category} | ${driver.name} | ${driver.maturity} | ${driver.execution} | ${driver.topology} | ${driver.reason||"Retained test paths passed."} |`).join(`
2
+ `);return`# Stacks driver contract matrix
27
3
 
28
4
  - Source: \`${report.sourceRevision}\`
29
5
  - Runtime: Bun \`${report.environment.runtime.version}\` on \`${report.environment.platform.os}/${report.environment.platform.architecture}\`
@@ -35,60 +11,5 @@ function markdown(report) {
35
11
  | Category | Driver | Maturity | Execution | Topology | Evidence boundary |
36
12
  | --- | --- | --- | --- | --- | --- |
37
13
  ${rows}
38
- `;
39
- }
40
- export function runDriverContracts() {
41
- const plan = planDriverContracts(capabilityRegistry);
42
- if (!plan.tests.length)
43
- throw Error("No supported driver contracts were selected");
44
- const revisionResult = Bun.spawnSync(["git", "rev-parse", "HEAD"], { cwd: root });
45
- if (revisionResult.exitCode !== 0)
46
- throw Error("Could not resolve the Stacks revision");
47
- const started = performance.now(), result = Bun.spawnSync(["bun", "test", ...plan.tests], { cwd: root, stdout: "inherit", stderr: "inherit" }), durationMs = Math.round(performance.now() - started), status = result.exitCode === 0 ? "pass" : "fail", report = {
48
- schemaVersion: "1.0.0",
49
- sourceRevision: revisionResult.stdout.toString().trim(),
50
- environment: {
51
- runtime: { name: "bun", version: Bun.version },
52
- platform: { os: platform(), architecture: arch() },
53
- ci: process.env.GITHUB_ACTIONS === "true" ? "github-actions" : "local",
54
- services: {
55
- sqlite: sqliteVersion(),
56
- redis: {
57
- version: process.env.REDIS_SERVICE_VERSION || "unreported",
58
- url: process.env.REDIS_URL ? "redis://127.0.0.1:6379/0" : "not provisioned",
59
- topology: "single-node loopback process provisioned by Pantry Action"
60
- },
61
- otherExternal: "not provisioned; partial/experimental drivers are not promoted"
62
- }
63
- },
64
- testRun: { status, durationMs, files: plan.tests },
65
- drivers: plan.records.map((driver) => ({
66
- category: driver.category,
67
- name: driver.name,
68
- maturity: driver.status,
69
- execution: driver.execution === "run" ? status : driver.execution,
70
- topology: driver.topology,
71
- prerequisites: driver.prerequisites,
72
- evidence: driver.testEvidence,
73
- limitations: driver.limitations,
74
- reason: driver.reason
75
- }))
76
- };
77
- mkdirSync(reportRoot, { recursive: !0 });
78
- writeFileSync(resolve(reportRoot, "driver-matrix.json"), `${JSON.stringify(report, null, 2)}
79
- `);
80
- writeFileSync(resolve(reportRoot, "driver-matrix.md"), markdown(report));
81
- if (status === "fail")
82
- throw Error("Supported driver contract tests failed");
83
- console.log(`Driver contract matrix passed ${plan.tests.length} retained test files`);
84
- }
85
- export async function run() {
86
- try {
87
- runDriverContracts();
88
- } catch (error) {
89
- console.error(error instanceof Error ? error.message : String(error));
90
- process.exit(1);
91
- }
92
- }
93
- if (import.meta.main)
94
- await run();
14
+ `}export function runDriverContracts(){const plan=planDriverContracts(capabilityRegistry);if(!plan.tests.length)throw Error("No supported driver contracts were selected");const revisionResult=Bun.spawnSync(["git","rev-parse","HEAD"],{cwd:root});if(revisionResult.exitCode!==0)throw Error("Could not resolve the Stacks revision");const started=performance.now(),result=Bun.spawnSync(["bun","test",...plan.tests],{cwd:root,stdout:"inherit",stderr:"inherit"}),durationMs=Math.round(performance.now()-started),status=result.exitCode===0?"pass":"fail",report={schemaVersion:"1.0.0",sourceRevision:revisionResult.stdout.toString().trim(),environment:{runtime:{name:"bun",version:Bun.version},platform:{os:platform(),architecture:arch()},ci:process.env.GITHUB_ACTIONS==="true"?"github-actions":"local",services:{sqlite:sqliteVersion(),redis:{version:process.env.REDIS_SERVICE_VERSION||"unreported",url:process.env.REDIS_URL?"redis://127.0.0.1:6379/0":"not provisioned",topology:"single-node loopback process provisioned by Pantry Action"},otherExternal:"not provisioned; partial/experimental drivers are not promoted"}},testRun:{status,durationMs,files:plan.tests},drivers:plan.records.map((driver)=>({category:driver.category,name:driver.name,maturity:driver.status,execution:driver.execution==="run"?status:driver.execution,topology:driver.topology,prerequisites:driver.prerequisites,evidence:driver.testEvidence,limitations:driver.limitations,reason:driver.reason}))};mkdirSync(reportRoot,{recursive:!0});writeFileSync(resolve(reportRoot,"driver-matrix.json"),`${JSON.stringify(report,null,2)}
15
+ `);writeFileSync(resolve(reportRoot,"driver-matrix.md"),markdown(report));if(status==="fail")throw Error("Supported driver contract tests failed");console.log(`Driver contract matrix passed ${plan.tests.length} retained test files`)}export async function run(){try{runDriverContracts()}catch(error){console.error(error instanceof Error?error.message:String(error));process.exit(1)}}if(import.meta.main)await run();
@@ -1,18 +1 @@
1
- import { describe, expect, it } from "bun:test";
2
- import { planDriverContracts } from "./run-driver-contracts";
3
- describe("driver contract matrix planning", () => {
4
- it("runs only supported evidence and reports all other maturity states explicitly", () => {
5
- const plan = planDriverContracts([
6
- { category: "cache", name: "memory", status: "supported", implementation: "memory.ts", testEvidence: ["memory.test.ts"], topology: "memory", prerequisites: [], limitations: [] },
7
- { category: "cache", name: "redis", status: "partial", implementation: "redis.ts", testEvidence: ["redis.test.ts"], topology: "redis", prerequisites: ["Redis"], limitations: ["No live evidence"] },
8
- { category: "queue", name: "sqs", status: "unsupported", implementation: null, testEvidence: [], topology: "sqs", prerequisites: ["AWS"], limitations: ["Reserved"] }
9
- ]);
10
- expect(plan.tests).toEqual(["memory.test.ts"]);
11
- expect(plan.records.map((record) => [record.name, record.execution])).toEqual([
12
- ["memory", "run"],
13
- ["redis", "not-run"],
14
- ["sqs", "not-run"]
15
- ]);
16
- expect(plan.records[1].reason).toContain("partial");
17
- });
18
- });
1
+ import{describe,expect,it}from"bun:test";import{planDriverContracts}from"./run-driver-contracts";describe("driver contract matrix planning",()=>{it("runs only supported evidence and reports all other maturity states explicitly",()=>{const plan=planDriverContracts([{category:"cache",name:"memory",status:"supported",implementation:"memory.ts",testEvidence:["memory.test.ts"],topology:"memory",prerequisites:[],limitations:[]},{category:"cache",name:"redis",status:"partial",implementation:"redis.ts",testEvidence:["redis.test.ts"],topology:"redis",prerequisites:["Redis"],limitations:["No live evidence"]},{category:"queue",name:"sqs",status:"unsupported",implementation:null,testEvidence:[],topology:"sqs",prerequisites:["AWS"],limitations:["Reserved"]}]);expect(plan.tests).toEqual(["memory.test.ts"]);expect(plan.records.map((record)=>[record.name,record.execution])).toEqual([["memory","run"],["redis","not-run"],["sqs","not-run"]]);expect(plan.records[1].reason).toContain("partial")})});