gateproof 0.1.1 → 0.2.0

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.
package/README.md CHANGED
@@ -1,47 +1,108 @@
1
1
  # gateproof
2
2
 
3
- E2E testing harness. Observe logs, run actions, assert results.
3
+ Build software in reverse. PRD defines what should exist. Gates verify reality. Agent iterations refine until gates pass.
4
4
 
5
5
  ## What gateproof does
6
6
 
7
- gateproof **executes gates**. It does not define intent, plans, or workflows.
7
+ gateproof enables **agent iterations** with minimal context overhead.
8
8
 
9
- A gate is a test specification: observe logs, run actions, assert results. gateproof runs it and returns evidence.
9
+ **The workflow:**
10
+ 1. PRD defines stories (what should exist)
11
+ 2. Gates verify reality (does it work?)
12
+ 3. Agent gets PRD + gate failure (minimal context)
13
+ 4. Agent fixes, gates re-run
14
+ 5. Iterate until all gates pass
10
15
 
11
- You define stories (gates) in your PRD. gateproof executes gate files.
16
+ **Why this works:**
17
+ - PRD is single source of truth (clear intent, minimal context)
18
+ - Gates provide concrete feedback (not vague requirements)
19
+ - Agent gets context only when needed (efficient)
20
+ - Iteration ensures correctness (converges to working code)
21
+
22
+ gateproof **executes gates**. It does not define intent, plans, or workflows. A gate is a test specification: observe logs, run actions, assert results. gateproof runs it and returns evidence.
12
23
 
13
24
  **Authority chain:**
14
- - **PRD (`prd.ts` / `prd.json`)** — authority on intent, order, and state
25
+ - **PRD (`prd.ts`)** — authority on intent, order, and dependencies (if you use the PRD runner)
15
26
  - **Gate implementations** — authority on how reality is observed
16
27
  - **gateproof runtime** — authority on enforcement only
17
28
 
18
- gateproof never decides *what* to build. It only decides *when you are allowed to proceed*.
29
+ gateproof never decides *what* to build. It returns results; your CI/CD decides whether you are allowed to proceed.
30
+
31
+ ## Agent Iterations: The Loop
32
+
33
+ The core innovation: agents work from PRD only, gates verify, iterate until correct.
34
+
35
+ **The iteration loop:**
36
+ 1. Run PRD → executes gates in dependency order
37
+ 2. Gate fails → agent gets: codebase context (e.g., `AGENTS.md`) + failure output
38
+ 3. Agent fixes → makes changes to codebase
39
+ 4. Loop repeats → re-run PRD, check if gates pass
40
+ 5. All gates pass → done
41
+
42
+ **Why minimal context:**
43
+ - Agent starts with PRD only (no full codebase upfront)
44
+ - Agent gets context only when gates fail (just-in-time)
45
+ - PRD stays as authority (what to build)
46
+ - Gates provide concrete feedback (what's wrong)
47
+
48
+ **Example loop script:**
49
+ ```bash
50
+ # patterns/prd/agent-iteration-loop.sh
51
+ while true; do
52
+ bun run prd.ts || {
53
+ # Gate failed - agent gets PRD + failure output
54
+ agent --context prd.ts --failure "$(cat gate-output.txt)"
55
+ # Agent fixes, loop continues
56
+ }
57
+ break # All gates passed
58
+ done
59
+ ```
60
+
61
+ **The guardrails:**
62
+ - Max failures (default: 5) → auto-pause if stuck
63
+ - Git diff check → agent must make changes
64
+ - Pause file → manual control
65
+
66
+ This solves the context management problem: agents don't need full codebase context upfront. They get minimal context (PRD), concrete feedback (gate failures), and iterate until correct.
19
67
 
20
68
  ## Stories as gates
21
69
 
22
70
  A PRD (Product Requirements Document) defines stories. Stories are gates. Each story references a gate file. The gate file verifies the story against reality.
23
71
 
24
- Reality decides when you can proceed.
72
+ Reality is the source of truth; gates make it enforceable in CI.
25
73
 
26
74
  ### prd.ts example
27
75
 
28
76
  ```typescript
29
77
  // prd.ts
30
- export const stories = [
31
- {
32
- id: "user-signup",
33
- title: "User can sign up",
34
- gateFile: "./gates/user-signup.gate.ts",
35
- status: "pending"
36
- },
37
- {
38
- id: "email-verification",
39
- title: "User receives verification email",
40
- gateFile: "./gates/email-verification.gate.ts",
41
- dependsOn: ["user-signup"],
42
- status: "pending"
78
+ import { definePrd } from "gateproof/prd";
79
+
80
+ export const prd = definePrd({
81
+ stories: [
82
+ {
83
+ id: "user-signup",
84
+ title: "User can sign up",
85
+ gateFile: "./gates/user-signup.gate.ts",
86
+ },
87
+ {
88
+ id: "email-verification",
89
+ title: "User receives verification email",
90
+ gateFile: "./gates/email-verification.gate.ts",
91
+ dependsOn: ["user-signup"],
92
+ },
93
+ ] as const, // keep story IDs as literal types
94
+ });
95
+
96
+ // Make it executable
97
+ if (import.meta.main) {
98
+ const { runPrd } = await import("gateproof/prd");
99
+ const result = await runPrd(prd);
100
+ if (!result.success) {
101
+ if (result.failedStory) console.error(`Failed at: ${result.failedStory.id}`);
102
+ process.exit(1);
43
103
  }
44
- ];
104
+ process.exit(0);
105
+ }
45
106
  ```
46
107
 
47
108
  Each story references a gate file. The gate file uses gateproof's API:
@@ -51,55 +112,111 @@ Each story references a gate file. The gate file uses gateproof's API:
51
112
  import { Gate, Act, Assert } from "gateproof";
52
113
  import { CloudflareProvider } from "gateproof/cloudflare";
53
114
 
54
- const provider = CloudflareProvider({
55
- accountId: process.env.CLOUDFLARE_ACCOUNT_ID!,
56
- apiToken: process.env.CLOUDFLARE_API_TOKEN!
57
- });
115
+ export async function run() {
116
+ const provider = CloudflareProvider({
117
+ accountId: process.env.CLOUDFLARE_ACCOUNT_ID!,
118
+ apiToken: process.env.CLOUDFLARE_API_TOKEN!,
119
+ });
120
+
121
+ const result = await Gate.run({
122
+ name: "user-signup",
123
+ observe: provider.observe({ backend: "analytics", dataset: "worker_logs" }),
124
+ act: [Act.browser({ url: "https://app.example.com/signup" })],
125
+ assert: [
126
+ Assert.noErrors(),
127
+ Assert.hasAction("user_created"),
128
+ ],
129
+ });
130
+
131
+ return { status: result.status };
132
+ }
133
+ ```
58
134
 
59
- const result = await Gate.run({
60
- name: "user-signup",
61
- observe: provider.observe({ backend: "analytics", dataset: "worker_logs" }),
62
- act: [Act.browser({ url: "https://app.example.com/signup" })],
63
- assert: [
64
- Assert.noErrors(),
65
- Assert.hasAction("user_created")
66
- ]
67
- });
135
+ **gateproof does not own your PRD’s intent or state.** If you choose to use `gateproof/prd`, your PRD must match a small capsule shape (`stories[]` with `id/title/gateFile/dependsOn?`). Otherwise, orchestrate gates however you want — gateproof only cares about executing gate files.
68
136
 
69
- if (result.status !== "success") process.exit(1);
137
+ Stories execute in dependency order. The runner stops on first failure. Progress is not declared. It is proven.
138
+
139
+ ## How it works
140
+
141
+ The PRD defines stories. Stories reference gate files. Gate files use gateproof's API. Gates can be enforced in CI before merge/deploy.
142
+
143
+ **The sequence:** PRD story → gate file → gate execution → story marked "done" only when gate passes.
144
+
145
+ **For agent iterations:** PRD → gate fails → agent fixes → gate re-runs → loop until pass.
146
+
147
+ Run your PRD:
148
+
149
+ ```bash
150
+ bun run prd.ts
151
+ ```
152
+
153
+ Run agent iteration loop:
154
+
155
+ ```bash
156
+ bash patterns/prd/agent-iteration-loop.sh
157
+ ```
158
+
159
+ ## Hardening `prd.ts` (recommended)
160
+
161
+ Treat `prd.ts` like code: typecheck + validate before push + enforce in CI.
162
+
163
+ - **Validate PRD**:
164
+
165
+ ```bash
166
+ bun run prd:validate
70
167
  ```
71
168
 
72
- ### prd.json example
169
+ - **Pre-push (default for everyone on your team)**: add to your `prepush` script (Husky calls it).
73
170
 
74
171
  ```json
75
172
  {
76
- "stories": [
77
- {
78
- "id": "user-signup",
79
- "title": "User can sign up",
80
- "gateFile": "./gates/user-signup.gate.ts",
81
- "status": "pending"
82
- }
83
- ]
173
+ "scripts": {
174
+ "prepush": "bun run typecheck && bun run prd:validate && bun test"
175
+ }
84
176
  }
85
177
  ```
86
178
 
87
- **gateproof does not parse or own your PRD.** It's your repo's artifact. **You decide the format. gateproof only executes the gate files your PRD references.**
88
-
89
- Stories carry state. The PRD tracks which stories are pending, in progress, or done. gateproof does not manage this state. It only enforces: proceed only when gates pass.
90
-
91
- ## How it works
179
+ - **CI**: run the validator before running PRD/tests.
92
180
 
93
- The PRD defines stories. Stories reference gate files. Gate files use gateproof's API. Gates can be enforced in CI before merge/deploy.
181
+ ```yaml
182
+ - name: Validate PRD
183
+ run: bun run prd:validate
184
+ ```
94
185
 
95
- The sequence: PRD story gate file gate execution → story marked "done" only when gate passes.
186
+ - **Monorepo**: validate any PRD file by path.
96
187
 
97
- Progress is not declared. It is proven.
188
+ ```bash
189
+ bun run scripts/prd-validate.ts packages/api/prd.ts
190
+ ```
98
191
 
99
192
  ## Design notes
100
193
 
101
194
  - [Effect and Schema: Gateproof's Foundation](docs/effect-and-schema.md)
102
195
 
196
+ ## Writing good gates (agent-first)
197
+
198
+ Gates can fail loudly. They can also pass on silence if you write weak assertions.
199
+
200
+ - **Always assert at least one positive signal**: `Assert.hasAction(...)` and/or `Assert.hasStage(...)`. If your backend can be silent, add an explicit “evidence must exist” custom assertion.
201
+ - **Don’t rely on absence-only checks**: `Assert.noErrors()` alone can pass if you collect no logs.
202
+ - **Treat observability as part of the system**: your confidence is bounded by what you can observe.
203
+
204
+ ## Limits / Non-goals
205
+
206
+ - **Not a planner or orchestrator**: gateproof executes gates; your PRD (or CI) decides what to run and in what context.
207
+ - **Not a truth oracle**: if your backend drops logs, a gate can be wrong. Gateproof can’t fix missing telemetry.
208
+ - **Enforcement is external**: gateproof returns results; CI/CD decides whether to block merge/deploy.
209
+
210
+ ## Common objections (and answers)
211
+
212
+ - **"Isn't this just E2E tests?"** Similar goal, different anchor. Gates are evidence-first (logs/telemetry + explicit assertions), not DOM-only. The contract is: observe → act → assert → evidence.
213
+
214
+ - **"What about flaky telemetry?"** Gates don't fix missing telemetry. They make the dependency explicit. If your backend drops logs, a gate can be wrong — but you'll know immediately, not in production.
215
+
216
+ - **"Isn't this overhead?"** It can be. The pitch isn't "gate everything." It's "gate the few transitions that are expensive to get wrong." Start with one critical path.
217
+
218
+ - **"Will this lock us in?"** Gates are just TypeScript files. If you stop using gateproof, you keep the scripts and the intent. No vendor lock-in.
219
+
103
220
  ## Quick Start
104
221
 
105
222
  The API is minimal: three concepts (Gate, Act, Assert). Here's a gate:
@@ -110,14 +227,14 @@ import { CloudflareProvider } from "gateproof/cloudflare";
110
227
 
111
228
  const provider = CloudflareProvider({
112
229
  accountId: process.env.CLOUDFLARE_ACCOUNT_ID!,
113
- apiToken: process.env.CLOUDFLARE_API_TOKEN!
230
+ apiToken: process.env.CLOUDFLARE_API_TOKEN!,
114
231
  });
115
232
 
116
233
  const result = await Gate.run({
117
234
  name: "api-health-check",
118
235
  observe: provider.observe({ backend: "analytics", dataset: "worker_logs" }),
119
236
  act: [Act.browser({ url: "https://my-worker.workers.dev" })],
120
- assert: [Assert.noErrors(), Assert.hasAction("request_received")]
237
+ assert: [Assert.noErrors(), Assert.hasAction("request_received")],
121
238
  });
122
239
 
123
240
  if (result.status !== "success") process.exit(1);
@@ -163,6 +280,42 @@ Assert.custom("name", fn) // Custom: (logs) => boolean
163
280
  }
164
281
  ```
165
282
 
283
+ ## PRD Runner
284
+
285
+ gateproof provides a PRD runner that executes stories in dependency order:
286
+
287
+ ```typescript
288
+ import { definePrd, runPrd } from "gateproof/prd";
289
+
290
+ const prd = definePrd({
291
+ stories: [
292
+ {
293
+ id: "story-1",
294
+ title: "First story",
295
+ gateFile: "./gates/story-1.gate.ts",
296
+ },
297
+ {
298
+ id: "story-2",
299
+ title: "Second story",
300
+ gateFile: "./gates/story-2.gate.ts",
301
+ dependsOn: ["story-1"],
302
+ },
303
+ ] as const, // keep story IDs as literal types
304
+ });
305
+
306
+ const result = await runPrd(prd);
307
+ if (!result.success) {
308
+ console.error(`Failed at: ${result.failedStory?.id}`);
309
+ process.exit(1);
310
+ }
311
+ ```
312
+
313
+ The runner:
314
+ - Validates dependencies (unknown IDs and cycles throw)
315
+ - Topologically sorts stories by `dependsOn`
316
+ - Executes gates in order
317
+ - **Stops on first failure**
318
+
166
319
  ## Plug Your Backend
167
320
 
168
321
  gateproof works with any observability backend. Just implement the `Backend` interface:
@@ -202,18 +355,34 @@ See `patterns/` for complete examples:
202
355
  - `patterns/cloudflare/` - Cloudflare-specific patterns
203
356
  - `patterns/ci-cd/` - CI/CD integration
204
357
  - `patterns/advanced/` - Advanced patterns
358
+ - `patterns/prd/` - PRD-as-code + agent iteration loop examples
359
+ - `patterns/agent-first/` - Spec interview → PRD stories (agent-first)
360
+ - `examples/hello-world-agent/` - Minimal agent with 5 tools + end-to-end gates
361
+
362
+ Run the hello-world agent example (requires `OPENCODE_ZEN_API_KEY` and network access to `opencode.ai`):
363
+
364
+ ```bash
365
+ export OPENCODE_ZEN_API_KEY="your_key_here"
366
+ bun run examples/hello-world-agent/prd.ts
367
+ ```
205
368
 
206
369
  ## CI/CD
207
370
 
208
371
  gateproof enforces gates in CI/CD. See `patterns/ci-cd/github-actions.ts` for examples.
209
372
 
373
+ Run your PRD in CI:
374
+
375
+ ```yaml
376
+ - name: Run PRD
377
+ run: bun run prd.ts
378
+ ```
379
+
210
380
  ## Requirements
211
381
 
212
382
  - Node.js 18+ or Bun
213
383
  - `playwright` (optional, for Act.browser)
214
384
  - Cloudflare credentials (for CloudflareProvider, or bring your own backend)
215
385
 
216
-
217
386
  ## License
218
387
 
219
388
  MIT
package/dist/index.d.ts CHANGED
@@ -63,4 +63,6 @@ export type { Provider } from "./provider";
63
63
  export { createEmptyBackend, createEmptyObserveResource, runGateWithErrorHandling } from "./utils";
64
64
  export { createTestObserveResource } from "./test-helpers";
65
65
  export { createHttpObserveResource } from "./http-backend";
66
+ export type { GateResultV1, PrdReportV1, StoryResultV1, SerializableError } from "./report";
67
+ export { serializeError, toGateResultV1 } from "./report";
66
68
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAwC,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC7E,OAAO,KAAK,EAAE,UAAU,EAAO,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAU,eAAe,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;;;;;;AAUxC,qBAAa,SAAU,SAAQ,cAE7B;CAAG;;;;;;;;AAEL,qBAAa,eAAgB,SAAQ,oBAOpC;CAAG;AAEJ,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,eAAe,GAAG,eAAe,GAAG,wBAAwB,GAAG,kBAAkB,CAAC;AAE1H,MAAM,WAAW,QAAQ;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,eAAe,CAAC;IACzB,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB;;;;;;;;;;;OAWG;IACH,IAAI,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;CAC5B;AA8ID,yBAAiB,IAAI,CAAC;IACpB,SAAgB,GAAG,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,CAEvD;IAED,SAAgB,SAAS,CACvB,IAAI,EAAE,QAAQ,GACb,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,aAAa,EAAE,KAAK,CAAC,KAAK,CAAC,CAiGvD;CACF;AAqBD,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC1D,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AACnG,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAwC,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC7E,OAAO,KAAK,EAAE,UAAU,EAAO,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAU,eAAe,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;;;;;;AAYxC,qBAAa,SAAU,SAAQ,cAE7B;CAAG;;;;;;;;AAEL,qBAAa,eAAgB,SAAQ,oBAOpC;CAAG;AAEJ,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,eAAe,GAAG,eAAe,GAAG,wBAAwB,GAAG,kBAAkB,CAAC;AAE1H,MAAM,WAAW,QAAQ;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,eAAe,CAAC;IACzB,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB;;;;;;;;;;;OAWG;IACH,IAAI,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;CAC5B;AA8ID,yBAAiB,IAAI,CAAC;IACpB,SAAgB,GAAG,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,CAEvD;IAED,SAAgB,SAAS,CACvB,IAAI,EAAE,QAAQ,GACb,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,aAAa,EAAE,KAAK,CAAC,KAAK,CAAC,CAiGvD;CACF;AAuBD,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC1D,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AACnG,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC5F,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC"}
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@ import { Assert } from "./assert";
3
3
  import { Schema } from "@effect/schema";
4
4
  import { getActionExecutor } from "./action-executors";
5
5
  import { DEFAULT_IDLE_MS, DEFAULT_MAX_MS, MAX_LOG_BUFFER, LOG_BUFFER_CAPACITY } from "./constants";
6
+ import { sortDeterministic, toGateResultV1 } from "./report";
6
7
  export class GateError extends Schema.TaggedError()("GateError", {
7
8
  cause: Schema.Unknown
8
9
  }) {
@@ -29,10 +30,10 @@ function summarize(logs) {
29
30
  errorTags.add(log.error.tag);
30
31
  }
31
32
  return {
32
- requestIds: [...requestIds],
33
- stagesSeen: [...stages],
34
- actionsSeen: [...actions],
35
- errorTags: [...errorTags]
33
+ requestIds: sortDeterministic([...requestIds]),
34
+ stagesSeen: sortDeterministic([...stages]),
35
+ actionsSeen: sortDeterministic([...actions]),
36
+ errorTags: sortDeterministic([...errorTags])
36
37
  };
37
38
  }
38
39
  function makeLogTimeoutError(stop, cause) {
@@ -201,7 +202,9 @@ function printResult(report, result) {
201
202
  }
202
203
  }
203
204
  else {
204
- console.log(JSON.stringify(result, null, 2));
205
+ // Use serializable version for JSON output
206
+ const serializable = toGateResultV1(result);
207
+ console.log(JSON.stringify(serializable, null, 2));
205
208
  }
206
209
  }
207
210
  export { Act } from "./act";
@@ -209,4 +212,5 @@ export { Assert } from "./assert";
209
212
  export { createEmptyBackend, createEmptyObserveResource, runGateWithErrorHandling } from "./utils";
210
213
  export { createTestObserveResource } from "./test-helpers";
211
214
  export { createHttpObserveResource } from "./http-backend";
215
+ export { serializeError, toGateResultV1 } from "./report";
212
216
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { Prd } from "./types";
2
+ /**
3
+ * Helper to define a PRD with type-safe story IDs.
4
+ * Preserves literal union types for StoryId.
5
+ */
6
+ export declare function definePrd<TId extends string>(prd: Prd<TId>): Prd<TId>;
7
+ //# sourceMappingURL=define-prd.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-prd.d.ts","sourceRoot":"","sources":["../../src/prd/define-prd.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AAEnC;;;GAGG;AACH,wBAAgB,SAAS,CAAC,GAAG,SAAS,MAAM,EAC1C,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,GACZ,GAAG,CAAC,GAAG,CAAC,CAEV"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Helper to define a PRD with type-safe story IDs.
3
+ * Preserves literal union types for StoryId.
4
+ */
5
+ export function definePrd(prd) {
6
+ return prd;
7
+ }
8
+ //# sourceMappingURL=define-prd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-prd.js","sourceRoot":"","sources":["../../src/prd/define-prd.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,SAAS,CACvB,GAAa;IAEb,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,5 @@
1
+ export type { Prd, Story, GateResult, StoryScope } from "./types";
2
+ export { definePrd } from "./define-prd";
3
+ export { runPrd, type RunPrdResult } from "./runner";
4
+ export { validateScope, getDiffStats, type ScopeViolation } from "./scope-check";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prd/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { definePrd } from "./define-prd";
2
+ export { runPrd } from "./runner";
3
+ export { validateScope, getDiffStats } from "./scope-check";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prd/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,MAAM,EAAqB,MAAM,UAAU,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAuB,MAAM,eAAe,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { Prd, Story } from "./types";
2
+ import type { PrdReportV1 } from "../report";
3
+ export interface RunPrdResult {
4
+ success: boolean;
5
+ failedStory?: Story;
6
+ error?: Error;
7
+ report?: PrdReportV1;
8
+ }
9
+ /**
10
+ * Runs a PRD by executing story gates in dependency order.
11
+ * Stops on first failure.
12
+ *
13
+ * @param options.reportPath - If provided, writes a structured JSON report to this path
14
+ * @param options.checkScope - If true, validates scope constraints against git diff
15
+ * @param options.baseRef - Git ref to compare against for scope checking (default: "HEAD" for local, "origin/main" for CI)
16
+ */
17
+ export declare function runPrd<TId extends string>(prd: Prd<TId>, cwd?: string, options?: {
18
+ reportPath?: string;
19
+ checkScope?: boolean;
20
+ baseRef?: string;
21
+ }): Promise<RunPrdResult>;
22
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/prd/runner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAc,MAAM,SAAS,CAAC;AACtD,OAAO,KAAK,EAAE,WAAW,EAAoC,MAAM,WAAW,CAAC;AAI/E,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,KAAK,CAAC;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAkFD;;;;;;;GAOG;AACH,wBAAsB,MAAM,CAAC,GAAG,SAAS,MAAM,EAC7C,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,EACb,GAAG,GAAE,MAAsB,EAC3B,OAAO,GAAE;IACP,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CACb,GACL,OAAO,CAAC,YAAY,CAAC,CAyJvB"}
@@ -0,0 +1,221 @@
1
+ import { resolve } from "path";
2
+ import { readFileSync } from "node:fs";
3
+ import { serializeError } from "../report";
4
+ import { validateScope, getDiffStats } from "./scope-check";
5
+ /**
6
+ * Validates that all story dependencies exist and there are no cycles.
7
+ */
8
+ function validateDependencies(stories) {
9
+ const byId = new Map(stories.map((s) => [s.id, s]));
10
+ for (const story of stories) {
11
+ const deps = story.dependsOn ?? [];
12
+ for (const depId of deps) {
13
+ if (!byId.has(depId)) {
14
+ throw new Error(`Story "${story.id}" depends on unknown story "${depId}"`);
15
+ }
16
+ }
17
+ }
18
+ }
19
+ /**
20
+ * Topologically sorts stories by their dependencies.
21
+ * Throws if there's a cycle or missing dependency.
22
+ */
23
+ function orderStories(stories) {
24
+ validateDependencies(stories);
25
+ const byId = new Map(stories.map((s) => [s.id, s]));
26
+ const out = [];
27
+ const remaining = new Set(stories.map((s) => s.id));
28
+ const visiting = new Set();
29
+ function visit(id) {
30
+ if (visiting.has(id)) {
31
+ throw new Error(`PRD dependency cycle detected involving "${id}"`);
32
+ }
33
+ if (!remaining.has(id)) {
34
+ return;
35
+ }
36
+ visiting.add(id);
37
+ const story = byId.get(id);
38
+ if (!story) {
39
+ throw new Error(`Unknown story id: ${id}`);
40
+ }
41
+ const deps = story.dependsOn ?? [];
42
+ for (const depId of deps) {
43
+ visit(depId);
44
+ }
45
+ visiting.delete(id);
46
+ remaining.delete(id);
47
+ out.push(story);
48
+ }
49
+ while (remaining.size > 0) {
50
+ const nextId = Array.from(remaining)[0];
51
+ visit(nextId);
52
+ }
53
+ return out;
54
+ }
55
+ /**
56
+ * Loads default forbidden paths from .gateproof/scope.defaults.json
57
+ */
58
+ function loadDefaultForbidden(cwd) {
59
+ try {
60
+ const defaultsPath = resolve(cwd, ".gateproof/scope.defaults.json");
61
+ const content = readFileSync(defaultsPath, "utf-8");
62
+ const parsed = JSON.parse(content);
63
+ return parsed.forbiddenPaths ?? [];
64
+ }
65
+ catch {
66
+ return [];
67
+ }
68
+ }
69
+ /**
70
+ * Runs a PRD by executing story gates in dependency order.
71
+ * Stops on first failure.
72
+ *
73
+ * @param options.reportPath - If provided, writes a structured JSON report to this path
74
+ * @param options.checkScope - If true, validates scope constraints against git diff
75
+ * @param options.baseRef - Git ref to compare against for scope checking (default: "HEAD" for local, "origin/main" for CI)
76
+ */
77
+ export async function runPrd(prd, cwd = process.cwd(), options = {}) {
78
+ const ordered = orderStories(prd.stories);
79
+ const storyResults = [];
80
+ const startTime = Date.now();
81
+ const defaultForbidden = loadDefaultForbidden(cwd);
82
+ const baseRef = options.baseRef ?? (process.env.CI ? "origin/main" : "HEAD");
83
+ for (const story of ordered) {
84
+ const storyStartTime = Date.now();
85
+ let storyError;
86
+ try {
87
+ if (options.checkScope && story.scope) {
88
+ const diffStats = getDiffStats(baseRef);
89
+ const violations = validateScope(story, diffStats, defaultForbidden);
90
+ if (violations.length > 0) {
91
+ const violation = violations[0];
92
+ storyError = {
93
+ name: "ScopeViolation",
94
+ message: violation.message,
95
+ tag: violation.category,
96
+ };
97
+ storyResults.push({
98
+ id: story.id,
99
+ title: story.title,
100
+ gateFile: story.gateFile,
101
+ status: "failed",
102
+ durationMs: Date.now() - storyStartTime,
103
+ error: storyError,
104
+ });
105
+ return {
106
+ success: false,
107
+ failedStory: story,
108
+ error: new Error(violation.message),
109
+ report: {
110
+ version: "1",
111
+ success: false,
112
+ stories: storyResults,
113
+ failedStory: {
114
+ id: story.id,
115
+ title: story.title,
116
+ gateFile: story.gateFile,
117
+ },
118
+ totalDurationMs: Date.now() - startTime,
119
+ },
120
+ };
121
+ }
122
+ }
123
+ const gatePath = resolve(cwd, story.gateFile);
124
+ const mod = await import(`file://${gatePath}`);
125
+ const run = mod.run;
126
+ if (typeof run !== "function") {
127
+ throw new Error(`Gate file must export "run" function: ${story.gateFile}`);
128
+ }
129
+ console.log(`\n--- ${story.id}: ${story.title}`);
130
+ const result = (await run());
131
+ const durationMs = Date.now() - storyStartTime;
132
+ if (result.status !== "success") {
133
+ storyError = result.error ? serializeError(result.error) : {
134
+ name: "GateFailed",
135
+ message: `Gate failed with status: ${result.status}`,
136
+ };
137
+ storyResults.push({
138
+ id: story.id,
139
+ title: story.title,
140
+ gateFile: story.gateFile,
141
+ status: result.status,
142
+ durationMs,
143
+ error: storyError,
144
+ });
145
+ const report = {
146
+ version: "1",
147
+ success: false,
148
+ stories: storyResults,
149
+ failedStory: {
150
+ id: story.id,
151
+ title: story.title,
152
+ gateFile: story.gateFile,
153
+ },
154
+ totalDurationMs: Date.now() - startTime,
155
+ };
156
+ if (options.reportPath) {
157
+ const { writeFileSync } = await import("node:fs");
158
+ writeFileSync(options.reportPath, JSON.stringify(report, null, 2));
159
+ }
160
+ return {
161
+ success: false,
162
+ failedStory: story,
163
+ error: new Error(`Gate failed with status: ${result.status}`),
164
+ report,
165
+ };
166
+ }
167
+ storyResults.push({
168
+ id: story.id,
169
+ title: story.title,
170
+ gateFile: story.gateFile,
171
+ status: "success",
172
+ durationMs,
173
+ });
174
+ }
175
+ catch (error) {
176
+ const durationMs = Date.now() - storyStartTime;
177
+ storyError = serializeError(error);
178
+ storyResults.push({
179
+ id: story.id,
180
+ title: story.title,
181
+ gateFile: story.gateFile,
182
+ status: "failed",
183
+ durationMs,
184
+ error: storyError,
185
+ });
186
+ const report = {
187
+ version: "1",
188
+ success: false,
189
+ stories: storyResults,
190
+ failedStory: {
191
+ id: story.id,
192
+ title: story.title,
193
+ gateFile: story.gateFile,
194
+ },
195
+ totalDurationMs: Date.now() - startTime,
196
+ };
197
+ if (options.reportPath) {
198
+ const { writeFileSync } = await import("node:fs");
199
+ writeFileSync(options.reportPath, JSON.stringify(report, null, 2));
200
+ }
201
+ return {
202
+ success: false,
203
+ failedStory: story,
204
+ error: error instanceof Error ? error : new Error(String(error)),
205
+ report,
206
+ };
207
+ }
208
+ }
209
+ const report = {
210
+ version: "1",
211
+ success: true,
212
+ stories: storyResults,
213
+ totalDurationMs: Date.now() - startTime,
214
+ };
215
+ if (options.reportPath) {
216
+ const { writeFileSync } = await import("node:fs");
217
+ writeFileSync(options.reportPath, JSON.stringify(report, null, 2));
218
+ }
219
+ return { success: true, report };
220
+ }
221
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/prd/runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { Story } from "./types";
2
+ export interface ScopeViolation {
3
+ category: "scope_violation";
4
+ message: string;
5
+ details: {
6
+ storyId: string;
7
+ violation: "forbidden_path" | "max_files_exceeded" | "max_lines_exceeded" | "default_forbidden";
8
+ path?: string;
9
+ actualFiles?: number;
10
+ maxFiles?: number;
11
+ actualLines?: number;
12
+ maxLines?: number;
13
+ };
14
+ }
15
+ export interface DiffStats {
16
+ changedFiles: string[];
17
+ totalLines: number;
18
+ }
19
+ /**
20
+ * Gets git diff stats against a base ref.
21
+ * For CI PRs, use origin/main. For local, use HEAD or a passed ref.
22
+ */
23
+ export declare function getDiffStats(baseRef?: string): DiffStats;
24
+ /**
25
+ * Validates that changed files match the story's scope constraints.
26
+ */
27
+ export declare function validateScope(story: Story, diffStats: DiffStats, defaultForbidden?: string[]): ScopeViolation[];
28
+ //# sourceMappingURL=scope-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope-check.d.ts","sourceRoot":"","sources":["../../src/prd/scope-check.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAc,MAAM,SAAS,CAAC;AAEjD,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE;QACP,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,gBAAgB,GAAG,oBAAoB,GAAG,oBAAoB,GAAG,mBAAmB,CAAC;QAChG,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,MAAM,WAAW,SAAS;IACxB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE,MAAe,GAAG,SAAS,CA8BhE;AAiBD;;GAEG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,SAAS,EACpB,gBAAgB,GAAE,MAAM,EAAO,GAC9B,cAAc,EAAE,CAyFlB"}
@@ -0,0 +1,135 @@
1
+ import { execSync } from "node:child_process";
2
+ import { resolve } from "node:path";
3
+ /**
4
+ * Gets git diff stats against a base ref.
5
+ * For CI PRs, use origin/main. For local, use HEAD or a passed ref.
6
+ */
7
+ export function getDiffStats(baseRef = "HEAD") {
8
+ try {
9
+ const changedFiles = execSync(`git diff --name-only ${baseRef}`, {
10
+ encoding: "utf-8",
11
+ cwd: process.cwd(),
12
+ })
13
+ .trim()
14
+ .split("\n")
15
+ .filter((f) => f.length > 0);
16
+ let totalLines = 0;
17
+ if (changedFiles.length > 0) {
18
+ const diffStat = execSync(`git diff --shortstat ${baseRef}`, {
19
+ encoding: "utf-8",
20
+ cwd: process.cwd(),
21
+ }).trim();
22
+ const match = diffStat.match(/(\d+)\s+files? changed/);
23
+ if (match) {
24
+ const linesMatch = diffStat.match(/(\d+)\s+insertions?/);
25
+ const deletionsMatch = diffStat.match(/(\d+)\s+deletions?/);
26
+ const insertions = linesMatch ? parseInt(linesMatch[1], 10) : 0;
27
+ const deletions = deletionsMatch ? parseInt(deletionsMatch[1], 10) : 0;
28
+ totalLines = insertions + deletions;
29
+ }
30
+ }
31
+ return { changedFiles, totalLines };
32
+ }
33
+ catch (error) {
34
+ throw new Error(`Failed to get git diff stats: ${error instanceof Error ? error.message : String(error)}`);
35
+ }
36
+ }
37
+ /**
38
+ * Checks if a path matches any of the glob patterns.
39
+ * Simple prefix/suffix matching for now (not full glob).
40
+ */
41
+ function matchesPattern(path, pattern) {
42
+ if (pattern.includes("**")) {
43
+ const prefix = pattern.replace(/\*\*/g, "");
44
+ return path.startsWith(prefix);
45
+ }
46
+ if (pattern.endsWith("*")) {
47
+ return path.startsWith(pattern.slice(0, -1));
48
+ }
49
+ return path === pattern;
50
+ }
51
+ /**
52
+ * Validates that changed files match the story's scope constraints.
53
+ */
54
+ export function validateScope(story, diffStats, defaultForbidden = []) {
55
+ const violations = [];
56
+ const scope = story.scope;
57
+ if (!scope) {
58
+ return violations;
59
+ }
60
+ const { changedFiles, totalLines } = diffStats;
61
+ for (const file of changedFiles) {
62
+ const filePath = resolve(process.cwd(), file);
63
+ if (scope.forbiddenPaths) {
64
+ for (const forbidden of scope.forbiddenPaths) {
65
+ if (matchesPattern(file, forbidden)) {
66
+ violations.push({
67
+ category: "scope_violation",
68
+ message: `Story "${story.id}" changed forbidden path: ${file}`,
69
+ details: {
70
+ storyId: story.id,
71
+ violation: "forbidden_path",
72
+ path: file,
73
+ },
74
+ });
75
+ }
76
+ }
77
+ }
78
+ for (const forbidden of defaultForbidden) {
79
+ if (matchesPattern(file, forbidden)) {
80
+ const isAllowed = scope.allowedPaths?.some((allowed) => matchesPattern(file, allowed));
81
+ if (!isAllowed) {
82
+ violations.push({
83
+ category: "scope_violation",
84
+ message: `Story "${story.id}" changed default-forbidden path: ${file}`,
85
+ details: {
86
+ storyId: story.id,
87
+ violation: "default_forbidden",
88
+ path: file,
89
+ },
90
+ });
91
+ }
92
+ }
93
+ }
94
+ if (scope.allowedPaths && scope.allowedPaths.length > 0) {
95
+ const isAllowed = scope.allowedPaths.some((allowed) => matchesPattern(file, allowed));
96
+ if (!isAllowed) {
97
+ violations.push({
98
+ category: "scope_violation",
99
+ message: `Story "${story.id}" changed path outside allowed scope: ${file}`,
100
+ details: {
101
+ storyId: story.id,
102
+ violation: "forbidden_path",
103
+ path: file,
104
+ },
105
+ });
106
+ }
107
+ }
108
+ }
109
+ if (scope.maxChangedFiles !== undefined && changedFiles.length > scope.maxChangedFiles) {
110
+ violations.push({
111
+ category: "scope_violation",
112
+ message: `Story "${story.id}" changed ${changedFiles.length} files, max allowed: ${scope.maxChangedFiles}`,
113
+ details: {
114
+ storyId: story.id,
115
+ violation: "max_files_exceeded",
116
+ actualFiles: changedFiles.length,
117
+ maxFiles: scope.maxChangedFiles,
118
+ },
119
+ });
120
+ }
121
+ if (scope.maxChangedLines !== undefined && totalLines > scope.maxChangedLines) {
122
+ violations.push({
123
+ category: "scope_violation",
124
+ message: `Story "${story.id}" changed ${totalLines} lines, max allowed: ${scope.maxChangedLines}`,
125
+ details: {
126
+ storyId: story.id,
127
+ violation: "max_lines_exceeded",
128
+ actualLines: totalLines,
129
+ maxLines: scope.maxChangedLines,
130
+ },
131
+ });
132
+ }
133
+ return violations;
134
+ }
135
+ //# sourceMappingURL=scope-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope-check.js","sourceRoot":"","sources":["../../src/prd/scope-check.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ export interface StoryScope {
2
+ allowedPaths?: string[];
3
+ forbiddenPaths?: string[];
4
+ maxChangedFiles?: number;
5
+ maxChangedLines?: number;
6
+ }
7
+ export type Story<TId extends string = string> = {
8
+ id: TId;
9
+ title: string;
10
+ gateFile: string;
11
+ dependsOn?: TId[];
12
+ scope?: StoryScope;
13
+ };
14
+ export type Prd<TId extends string = string> = {
15
+ stories: readonly Story<TId>[];
16
+ };
17
+ export type GateResult = {
18
+ status: "success" | "failed" | "timeout";
19
+ [key: string]: unknown;
20
+ };
21
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/prd/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,KAAK,CAAC,GAAG,SAAS,MAAM,GAAG,MAAM,IAAI;IAC/C,EAAE,EAAE,GAAG,CAAC;IACR,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,GAAG,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,GAAG,CAAC,GAAG,SAAS,MAAM,GAAG,MAAM,IAAI;IAC7C,OAAO,EAAE,SAAS,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IACzC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/prd/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Stable, versioned report schemas for machine-readable gate outputs.
3
+ * All types are fully JSON-serializable (no Error objects, no functions).
4
+ */
5
+ export interface SerializableError {
6
+ tag?: string;
7
+ name: string;
8
+ message: string;
9
+ stack?: string;
10
+ }
11
+ export interface GateResultV1 {
12
+ version: "1";
13
+ status: "success" | "failed" | "timeout";
14
+ durationMs: number;
15
+ logs: unknown[];
16
+ evidence: {
17
+ requestIds: string[];
18
+ stagesSeen: string[];
19
+ actionsSeen: string[];
20
+ errorTags: string[];
21
+ };
22
+ error?: SerializableError;
23
+ }
24
+ export interface StoryResultV1 {
25
+ id: string;
26
+ title: string;
27
+ gateFile: string;
28
+ status: "success" | "failed" | "timeout";
29
+ durationMs: number;
30
+ error?: SerializableError;
31
+ }
32
+ export interface PrdReportV1 {
33
+ version: "1";
34
+ success: boolean;
35
+ stories: StoryResultV1[];
36
+ failedStory?: {
37
+ id: string;
38
+ title: string;
39
+ gateFile: string;
40
+ };
41
+ totalDurationMs: number;
42
+ }
43
+ /**
44
+ * Converts an Error (or Error-like object) into a SerializableError.
45
+ * Preserves Effect-tagged errors (_tag) when present.
46
+ */
47
+ export declare function serializeError(error: unknown): SerializableError;
48
+ /**
49
+ * Sorts arrays deterministically (alphabetically) for stable output.
50
+ */
51
+ export declare function sortDeterministic<T>(arr: T[]): T[];
52
+ /**
53
+ * Converts a GateResult to a fully serializable GateResultV1.
54
+ */
55
+ export declare function toGateResultV1(result: {
56
+ status: "success" | "failed" | "timeout";
57
+ durationMs: number;
58
+ logs: unknown[];
59
+ evidence: {
60
+ requestIds: string[];
61
+ stagesSeen: string[];
62
+ actionsSeen: string[];
63
+ errorTags: string[];
64
+ };
65
+ error?: Error | unknown;
66
+ }): GateResultV1;
67
+ //# sourceMappingURL=report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,iBAAiB;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,GAAG,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,QAAQ,EAAE;QACR,UAAU,EAAE,MAAM,EAAE,CAAC;QACrB,UAAU,EAAE,MAAM,EAAE,CAAC;QACrB,WAAW,EAAE,MAAM,EAAE,CAAC;QACtB,SAAS,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;IACF,KAAK,CAAC,EAAE,iBAAiB,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,iBAAiB,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,GAAG,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,WAAW,CAAC,EAAE;QACZ,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,iBAAiB,CAwBhE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAElD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE;IACrC,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,OAAO,EAAE,CAAC;IAChB,QAAQ,EAAE;QACR,UAAU,EAAE,MAAM,EAAE,CAAC;QACrB,UAAU,EAAE,MAAM,EAAE,CAAC;QACrB,WAAW,EAAE,MAAM,EAAE,CAAC;QACtB,SAAS,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;IACF,KAAK,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC;CACzB,GAAG,YAAY,CASf"}
package/dist/report.js ADDED
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Stable, versioned report schemas for machine-readable gate outputs.
3
+ * All types are fully JSON-serializable (no Error objects, no functions).
4
+ */
5
+ /**
6
+ * Converts an Error (or Error-like object) into a SerializableError.
7
+ * Preserves Effect-tagged errors (_tag) when present.
8
+ */
9
+ export function serializeError(error) {
10
+ if (error instanceof Error) {
11
+ const errorWithTag = error;
12
+ return {
13
+ tag: errorWithTag._tag,
14
+ name: error.name || "Error",
15
+ message: error.message || String(error),
16
+ stack: error.stack,
17
+ };
18
+ }
19
+ if (error && typeof error === "object" && "_tag" in error) {
20
+ const tagged = error;
21
+ return {
22
+ tag: tagged._tag,
23
+ name: tagged._tag,
24
+ message: tagged.message || String(error),
25
+ };
26
+ }
27
+ return {
28
+ name: "Error",
29
+ message: String(error),
30
+ };
31
+ }
32
+ /**
33
+ * Sorts arrays deterministically (alphabetically) for stable output.
34
+ */
35
+ export function sortDeterministic(arr) {
36
+ return [...arr].sort();
37
+ }
38
+ /**
39
+ * Converts a GateResult to a fully serializable GateResultV1.
40
+ */
41
+ export function toGateResultV1(result) {
42
+ return {
43
+ version: "1",
44
+ status: result.status,
45
+ durationMs: result.durationMs,
46
+ logs: result.logs,
47
+ evidence: result.evidence,
48
+ error: result.error ? serializeError(result.error) : undefined,
49
+ };
50
+ }
51
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA4CH;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,MAAM,YAAY,GAAG,KAAkC,CAAC;QACxD,OAAO;YACL,GAAG,EAAE,YAAY,CAAC,IAAI;YACtB,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,OAAO;YAC3B,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC;YACvC,KAAK,EAAE,KAAK,CAAC,KAAK;SACnB,CAAC;IACJ,CAAC;IAED,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;QAC1D,MAAM,MAAM,GAAG,KAAiE,CAAC;QACjF,OAAO;YACL,GAAG,EAAE,MAAM,CAAC,IAAI;YAChB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC;SACzC,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC;KACvB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAI,GAAQ;IAC3C,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AACzB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,MAW9B;IACC,OAAO;QACL,OAAO,EAAE,GAAG;QACZ,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;KAC/D,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gateproof",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "description": "E2E testing harness. Observe logs, run actions, assert results.",
6
6
  "main": "./dist/index.js",
@@ -13,6 +13,10 @@
13
13
  "./cloudflare": {
14
14
  "types": "./dist/cloudflare/index.d.ts",
15
15
  "import": "./dist/cloudflare/index.js"
16
+ },
17
+ "./prd": {
18
+ "types": "./dist/prd/index.d.ts",
19
+ "import": "./dist/prd/index.js"
16
20
  }
17
21
  },
18
22
  "files": [
@@ -24,6 +28,7 @@
24
28
  "build": "bun run build:tsc",
25
29
  "build:tsc": "tsc -p tsconfig.build.json",
26
30
  "typecheck": "tsc --noEmit",
31
+ "prd:validate": "bun run scripts/prd-validate.ts",
27
32
  "test": "bun test",
28
33
  "test:demo": "bun test test/demo.test.ts",
29
34
  "test:production": "bun test test/demo.production.test.ts",
@@ -37,7 +42,7 @@
37
42
  "gate:dev": "bun run gate:framework && bun run gate:demo && bun run gate:local",
38
43
  "gate:all": "bun run gate:dev && bun run gate:production",
39
44
  "demo:gate": "bun run gate:production",
40
- "prepush": "bun run gate:dev",
45
+ "prepush": "bun run typecheck && bun run prd:validate && bun test",
41
46
  "prepublishOnly": "bun run build && bun test"
42
47
  },
43
48
  "keywords": [