@enricai/barnacle 1.6.10 → 1.6.11

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 (93) hide show
  1. package/README.md +71 -3
  2. package/dist/api/routes/submissions.d.ts +21 -0
  3. package/dist/api/routes/submissions.d.ts.map +1 -0
  4. package/dist/api/routes/submissions.js +48 -0
  5. package/dist/api/routes/submissions.js.map +1 -0
  6. package/dist/api/schemas/submissions.d.ts +110 -0
  7. package/dist/api/schemas/submissions.d.ts.map +1 -0
  8. package/dist/api/schemas/submissions.js +77 -0
  9. package/dist/api/schemas/submissions.js.map +1 -0
  10. package/dist/config.d.ts +34 -0
  11. package/dist/config.d.ts.map +1 -1
  12. package/dist/config.js +5 -0
  13. package/dist/config.js.map +1 -1
  14. package/dist/lib/telemetry/beacon-capture.d.ts +37 -0
  15. package/dist/lib/telemetry/beacon-capture.d.ts.map +1 -0
  16. package/dist/lib/telemetry/beacon-capture.js +47 -0
  17. package/dist/lib/telemetry/beacon-capture.js.map +1 -0
  18. package/dist/lib/telemetry/reconciliation-record.d.ts +105 -0
  19. package/dist/lib/telemetry/reconciliation-record.d.ts.map +1 -0
  20. package/dist/lib/telemetry/reconciliation-record.js +76 -0
  21. package/dist/lib/telemetry/reconciliation-record.js.map +1 -0
  22. package/dist/lib/telemetry/reconciliation-source.d.ts +33 -0
  23. package/dist/lib/telemetry/reconciliation-source.d.ts.map +1 -0
  24. package/dist/lib/telemetry/reconciliation-source.js +91 -0
  25. package/dist/lib/telemetry/reconciliation-source.js.map +1 -0
  26. package/dist/lib/telemetry/s3-sink.d.ts.map +1 -1
  27. package/dist/lib/telemetry/s3-sink.js +1 -2
  28. package/dist/lib/telemetry/s3-sink.js.map +1 -1
  29. package/dist/lib/telemetry/submission-capture.d.ts +30 -9
  30. package/dist/lib/telemetry/submission-capture.d.ts.map +1 -1
  31. package/dist/lib/telemetry/submission-capture.js +32 -21
  32. package/dist/lib/telemetry/submission-capture.js.map +1 -1
  33. package/dist/lib/telemetry/submission-query.d.ts +32 -0
  34. package/dist/lib/telemetry/submission-query.d.ts.map +1 -0
  35. package/dist/lib/telemetry/submission-query.js +49 -0
  36. package/dist/lib/telemetry/submission-query.js.map +1 -0
  37. package/dist/lib/telemetry/submission-reader.d.ts +52 -0
  38. package/dist/lib/telemetry/submission-reader.d.ts.map +1 -0
  39. package/dist/lib/telemetry/submission-reader.js +111 -0
  40. package/dist/lib/telemetry/submission-reader.js.map +1 -0
  41. package/dist/lib/telemetry/submissions-s3-objects.d.ts +23 -0
  42. package/dist/lib/telemetry/submissions-s3-objects.d.ts.map +1 -0
  43. package/dist/lib/telemetry/submissions-s3-objects.js +132 -0
  44. package/dist/lib/telemetry/submissions-s3-objects.js.map +1 -0
  45. package/dist/lib/telemetry/submissions-s3-reader.d.ts +25 -0
  46. package/dist/lib/telemetry/submissions-s3-reader.d.ts.map +1 -0
  47. package/dist/lib/telemetry/submissions-s3-reader.js +63 -0
  48. package/dist/lib/telemetry/submissions-s3-reader.js.map +1 -0
  49. package/dist/lib/tracking-click.d.ts +13 -2
  50. package/dist/lib/tracking-click.d.ts.map +1 -1
  51. package/dist/lib/tracking-click.js +42 -4
  52. package/dist/lib/tracking-click.js.map +1 -1
  53. package/dist/plugins/loader.d.ts +17 -3
  54. package/dist/plugins/loader.d.ts.map +1 -1
  55. package/dist/plugins/loader.js +59 -6
  56. package/dist/plugins/loader.js.map +1 -1
  57. package/dist/scraper/cookie-jar.d.ts +10 -4
  58. package/dist/scraper/cookie-jar.d.ts.map +1 -1
  59. package/dist/scraper/cookie-jar.js +10 -5
  60. package/dist/scraper/cookie-jar.js.map +1 -1
  61. package/dist/scraper/deep-locator-candidates.d.ts +27 -5
  62. package/dist/scraper/deep-locator-candidates.d.ts.map +1 -1
  63. package/dist/scraper/deep-locator-candidates.js +57 -11
  64. package/dist/scraper/deep-locator-candidates.js.map +1 -1
  65. package/dist/scraper/deep-locator-fake.d.ts +28 -0
  66. package/dist/scraper/deep-locator-fake.d.ts.map +1 -1
  67. package/dist/scraper/deep-locator-fake.js +44 -2
  68. package/dist/scraper/deep-locator-fake.js.map +1 -1
  69. package/dist/scraper/flow-runner.d.ts +20 -0
  70. package/dist/scraper/flow-runner.d.ts.map +1 -1
  71. package/dist/scraper/flow-runner.js +81 -9
  72. package/dist/scraper/flow-runner.js.map +1 -1
  73. package/dist/scraper/frame-target.d.ts +60 -14
  74. package/dist/scraper/frame-target.d.ts.map +1 -1
  75. package/dist/scraper/frame-target.js +126 -38
  76. package/dist/scraper/frame-target.js.map +1 -1
  77. package/dist/scraper/stagehand-guard.d.ts +14 -0
  78. package/dist/scraper/stagehand-guard.d.ts.map +1 -1
  79. package/dist/scraper/stagehand-guard.js +28 -8
  80. package/dist/scraper/stagehand-guard.js.map +1 -1
  81. package/dist/scraper/watchdog.d.ts +38 -0
  82. package/dist/scraper/watchdog.d.ts.map +1 -0
  83. package/dist/scraper/watchdog.js +54 -0
  84. package/dist/scraper/watchdog.js.map +1 -0
  85. package/dist/scripts/recon-browser.d.ts.map +1 -1
  86. package/dist/scripts/recon-browser.js +14 -3
  87. package/dist/scripts/recon-browser.js.map +1 -1
  88. package/dist/server.d.ts.map +1 -1
  89. package/dist/server.js +2 -0
  90. package/dist/server.js.map +1 -1
  91. package/dist/site-plugin.d.ts +12 -0
  92. package/dist/site-plugin.d.ts.map +1 -1
  93. package/package.json +1 -1
package/README.md CHANGED
@@ -411,6 +411,41 @@ return {
411
411
 
412
412
  When `auditPayload` is present, core writes it — not `data` — to the submission-envelope telemetry record. Use this to strip PII or large blobs from the audit trail while keeping the full response in the API reply. When absent, `data` is written as-is.
413
413
 
414
+ ### Reconciliation join keys (`extractJoinKeys`)
415
+
416
+ Core has no opinion on what a reconciliation join key is named or how it's
417
+ shaped — that's site-specific vocabulary (an attribution vendor's click ID,
418
+ a job-reference composition rule, whatever the site needs). A plugin that
419
+ needs its submission and beacon-fire telemetry to be joinable back to its own
420
+ attribution provider declares an optional `extractJoinKeys` hook on its
421
+ `SitePlugin`:
422
+
423
+ ```ts
424
+ export const myPlugin: SitePlugin<MyPayload, MyResponse> = {
425
+ extractJoinKeys: (payload) =>
426
+ payload.someVendorClickId ? { vendorClickId: payload.someVendorClickId } : null,
427
+ // ...
428
+ };
429
+ ```
430
+
431
+ `dispatch()` (`src/plugins/loader.ts`) calls this once per submission and
432
+ stamps the opaque `Record<string, unknown>` result onto the submission
433
+ envelope and the beacon-fire record verbatim, under a `joinKeys` field —
434
+ core never inspects its contents. A plugin with no reconciliation needs
435
+ simply omits `extractJoinKeys`.
436
+
437
+ **Declaring `extractJoinKeys` also opts the plugin out of core's automatic
438
+ `TrackingUrl` fire.** If the site returns a post-submission click-tracking
439
+ URL, declare it on the plugin's `bodySchema` by composing `JobTrackingSchema`
440
+ (`src/lib/job-tracking.ts`) — `MySitePayloadSchema.extend(JobTrackingSchema.shape)`.
441
+ When a plugin has no `extractJoinKeys`, `dispatch()` fires that `TrackingUrl`
442
+ itself via `fireTrackingClick`, site-agnostically, after a successful submit.
443
+ When a plugin *does* declare `extractJoinKeys`, core assumes the plugin fires
444
+ its own post-submit tracking navigation (e.g. because the click and apply
445
+ navs must share one browser session for a vendor's device-cookie
446
+ attribution to work) and skips its own fire — firing both would open two
447
+ independent sessions against the same URL.
448
+
414
449
  ### Static fixtures
415
450
 
416
451
  If Phase 3b (auxiliary fixture detection) found static JSON endpoints (markets, currencies, labels), `recon:generate` copies them to `src/sites/<id>/fixtures/`. Load them at module init via `loadFixture()` — zero per-request overhead, fails fast on deploy if the fixture is missing or stale:
@@ -585,12 +620,13 @@ See [docs/playbook.md](./docs/playbook.md#6b--metrics-signals-the-detection-ladd
585
620
 
586
621
  ### NDJSON telemetry files
587
622
 
588
- Barnacle writes two append-only NDJSON files alongside its metrics:
623
+ Barnacle writes three append-only NDJSON files alongside its metrics:
589
624
 
590
625
  | File | Default path | Purpose |
591
626
  |------|-------------|---------|
592
627
  | LLM call samples | `.barnacle/calls.ndjson` | One line per LLM/Stagehand call; feed to the `judge:llm` and `slm-self-heal` skills |
593
628
  | Run event stream | `.barnacle/events/<runId>.ndjson` | Per-run event stream written by the event-stream subsystem; path surfaced in `/readyz` `telemetry.currentRunFile` |
629
+ | Submission reconciliation records | `.barnacle/submissions.ndjson` | One line per dispatch submit outcome or beacon-fire event; the durable, queryable join-key record — see [Submission record schema](#submission-record-schema) below and `GET /v1/submissions` under [Endpoints](#endpoints) |
594
630
 
595
631
  #### LLM call sample schema
596
632
 
@@ -622,6 +658,31 @@ Every line in `.barnacle/calls.ndjson` is a JSON object with these fields (sourc
622
658
  | `recon-flow-patch` | `src/scripts/recon-heal.ts` | Patch proposal from the recon-flow-patch-generator during the `recon-heal` self-healing loop |
623
659
  | `llm-prompt-patch` | `src/scripts/llm-heal.ts` | Patch proposal from the llm-call-patch-generator during the `llm-heal` self-healing loop |
624
660
 
661
+ #### Submission record schema
662
+
663
+ Every `"submit"`-kind line in `.barnacle/submissions.ndjson` is a JSON object
664
+ validated against `submissionEnvelopeSampleSchema`
665
+ (`src/lib/telemetry/submission-capture.ts`, an alias of `submitRecordSchema`
666
+ in `src/lib/telemetry/reconciliation-record.ts`):
667
+
668
+ | Field | Type | Description |
669
+ |-------|------|-------------|
670
+ | `kind` | `"submit"` | Discriminates this record from a `"beacon"` conversion-event record sharing the same sink; defaults to `"submit"` so lines written before this field existed still parse. |
671
+ | `siteId` | `string` | Which plugin handled the request — the cohort dimension for reconciliation. |
672
+ | `requestId` | `string` | Fastify-issued correlation ID; joins a later `"beacon"` record to this one by matching `requestId`. |
673
+ | `joinKeys` | `Record<string, unknown> \| null` | Opaque, plugin-owned reconciliation join keys, resolved once by the plugin's `extractJoinKeys` hook (see [Reconciliation join keys](#reconciliation-join-keys-extractjoinkeys) above); `null` when the plugin has no `extractJoinKeys` or it resolved nothing. |
674
+ | `inboundPayload` | `unknown` | The request body the caller posted, unredacted. |
675
+ | `status` | `"submitted" \| "error"` | Submit outcome. |
676
+ | `auditPayload` | `unknown` | The plugin's `SitePluginResult.auditPayload`, or `data` when absent; `null` on errors. |
677
+ | `errorMessage` | `string \| null` | Failure message on errors; `null` on success. |
678
+ | `durationMs` | `number` | Total dispatch wall time in milliseconds. |
679
+ | `ts` | `string` | ISO-8601 timestamp at write time. |
680
+
681
+ A `"beacon"`-kind record shares the same sink to record a later, independent
682
+ beacon-fire outcome for the same `requestId` — see
683
+ [Submission-envelope sink](docs/telemetry-and-judging.md#submission-envelope-sink)
684
+ for the full schema and the `GET /v1/submissions` read path.
685
+
625
686
  #### Tailing call samples with jq
626
687
 
627
688
  ```bash
@@ -678,6 +739,9 @@ process to exit on missing values; optional ones have safe defaults.
678
739
  | `STAGEHAND_API_TIMEOUT_MS` | `120000` | No | Anthropic SDK request timeout (ms). Raise on slow network paths to `api.anthropic.com`. |
679
740
  | `STAGEHAND_CONNECT_TIMEOUT_MS` | `120000` | No | TCP connect timeout for all outbound fetch calls (ms). Raised from the undici default of 10 s to match `STAGEHAND_API_TIMEOUT_MS`. |
680
741
  | `STEEL_SESSION_TIMEOUT_MS` | `3600000` | No | Steel session wall-clock timeout (ms). Default is 1 hour; lower on plans that enforce shorter maximum session durations. |
742
+ | `FRAME_READY_TIMEOUT_MS` | `20000` | No | How long `resolveFrameTarget` polls for a child iframe to attach before falling back to the main frame (ms). Raise further for cross-origin OOPIFs that attach slowly under advancedStealth + proxied CDP. |
743
+ | `FRAME_DOCUMENT_READY_TIMEOUT_MS` | `5000` | No | How long `waitForChildFrameReady` polls a resolved child frame's `document.readyState` before proceeding anyway (ms). Independent of `FRAME_READY_TIMEOUT_MS` — this wait settles in well under a second once attached. |
744
+ | `FRAME_EVALUATE_TIMEOUT_MS` | `30000` | No | Watchdog budget for a single frame-scoped evaluate/candidate-probe call (ms), so a call against a racy frame fails the attempt instead of hanging indefinitely. |
681
745
 
682
746
  ### AWS Bedrock (alternative LLM provider)
683
747
 
@@ -759,13 +823,15 @@ http/net/dns. Metrics have no such constraint.
759
823
  | `TELEMETRY_ENABLED` | `true` | Master switch — set `false` to disable all NDJSON telemetry writes. |
760
824
  | `TELEMETRY_EVENTS_DIR` | `.barnacle/events` | Directory for per-run NDJSON event stream files (`<eventsDir>/<runId>.ndjson`). |
761
825
  | `CALLS_NDJSON_PATH` | `.barnacle/calls.ndjson` | Append-only NDJSON sink for LLM/Stagehand call samples. One line per call; feed to the judge and self-heal skills. |
762
- | `SUBMISSIONS_NDJSON_PATH` | `.barnacle/submissions.ndjson` | Append-only NDJSON sink for dispatch submission envelopes. One line per plugin invocation captures siteId, requestId, inbound payload, status, audit payload, and duration — the durable source-of-truth for "what did we submit for jobId X and did it succeed." |
826
+ | `SUBMISSIONS_NDJSON_PATH` | `.barnacle/submissions.ndjson` | Append-only NDJSON sink for dispatch submission envelopes and beacon-fire outcomes. `kind:"submit"` lines (null/`"submit"`-defaulted on legacy lines) capture siteId, requestId, inbound payload, status, audit payload, and duration, plus the opaque `joinKeys` bag a plugin's `extractJoinKeys` hook resolved — the durable source-of-truth for "what did we submit for jobId X and did it succeed." `kind:"beacon"` lines record a later (or, for `beaconStatus: "skipped"`, immediate) independent beacon-fire outcome (`beaconStatus`: `fired`/`failed`/`skipped`, truncated `trackingUrl`) for the same `requestId`, so "submitted but the beacon did not fire" is measurable. A reader folds both kinds together by `requestId`, so a plugin can join runs to its own attribution provider's report without re-parsing `inboundPayload`. |
763
827
  | `TELEMETRY_MAX_FILE_SIZE_BYTES` | `104857600` (100 MB) | Rotate/drop the calls NDJSON once it exceeds this byte count. |
764
828
  | `TELEMETRY_MAX_RETENTION_MS` | `2592000000` (30 days) | Drop event-stream files older than this many milliseconds. |
765
829
  | `TELEMETRY_S3_BUCKET` | — | Optional — destination bucket for the buffered S3 telemetry mirror. Sink is entirely inert (no client, no network calls) when unset. Credentials/region resolve the same way as Bedrock (`AWS_REGION`, standard SDK credential order). |
766
830
  | `TELEMETRY_S3_PREFIX` | `telemetry` | Key prefix for uploaded NDJSON objects (`<prefix>/<calls\|submissions>/<date>/...`). |
767
831
  | `TELEMETRY_S3_FLUSH_INTERVAL_MS` | `60000` | How often buffered lines are flushed to S3. |
768
832
  | `TELEMETRY_S3_MAX_BUFFER_LINES` | `500` | Threshold-flush trigger — flush early if either buffer exceeds this many lines, ahead of the next scheduled interval. |
833
+ | `TELEMETRY_S3_READ_MAX_OBJECTS` | `200` | Upper bound on the number of S3 objects a single reconciliation read-path query is allowed to scan. |
834
+ | `TELEMETRY_S3_READ_CONCURRENCY` | `8` | Max concurrent object fetches for a single reconciliation read-path query. |
769
835
 
770
836
  ### LLM judging
771
837
 
@@ -913,7 +979,7 @@ Every response — success or error — uses the same envelope shape so clients
913
979
 
914
980
  Full definitions: `src/api/schemas/common.ts`.
915
981
 
916
- **How scraper exceptions map to API codes** (`src/plugins/loader.ts:149-153`):
982
+ **How scraper exceptions map to API codes** (`src/plugins/loader.ts:88-92`):
917
983
 
918
984
  - `CaptchaError` → `2004 CAPTCHA_ENCOUNTERED`
919
985
  - `EmptyResultsError` → `2005 EMPTY_RESULTS`
@@ -951,6 +1017,7 @@ Operational routes:
951
1017
  - `GET /readyz` — readiness probe (checks scraper credentials, queue depth)
952
1018
  - `GET /docs` — Swagger UI (when `ENABLE_DOCS=true`)
953
1019
  - `GET /v1/plugins` — authenticated plugin load report (see [Out-of-tree plugins](#out-of-tree-plugins))
1020
+ - `GET /v1/submissions` — authenticated, queryable submit+beacon reconciliation rows (filter by `siteId`, `requestId`, `status`, `beaconStatus`, `from`/`to`; each row's opaque `joinKeys` bag is a plugin-owned field, not filterable at this layer; see [Submission-envelope sink](docs/telemetry-and-judging.md#submission-envelope-sink))
954
1021
 
955
1022
  ## Commands
956
1023
 
@@ -1129,6 +1196,7 @@ readinessProbe:
1129
1196
  - Recon playbook (step-by-step): [docs/playbook.md](./docs/playbook.md)
1130
1197
  - Testing guide: [docs/testing.md](./docs/testing.md)
1131
1198
  - Telemetry & LLM judging concept guide: [docs/telemetry-and-judging.md](./docs/telemetry-and-judging.md)
1199
+ - Submission reconciliation runbook (join Barnacle runs to a plugin's own attribution provider's report): [docs/submission-reconciliation.md](./docs/submission-reconciliation.md)
1132
1200
  - Per-site recon findings: [docs/target-recon.md](./docs/target-recon.md) (populated after first `pnpm run recon:summarize`)
1133
1201
 
1134
1202
  ## License
@@ -0,0 +1,21 @@
1
+ import type { FastifyInstance } from "fastify";
2
+ /**
3
+ * Injectable options for `submissionsRoutes`. The sink path is passed in at
4
+ * registration time (mirrors `pluginsIntrospectionRoutes`'s `report`
5
+ * injection) so the route can be tested against a temp NDJSON file instead
6
+ * of the real `.barnacle/submissions.ndjson`.
7
+ */
8
+ export interface SubmissionsRoutesOptions {
9
+ /** Override the sink path; defaults to `config.telemetry.submissionsNdjsonPath` when omitted. */
10
+ sinkPath?: string;
11
+ }
12
+ /**
13
+ * Exposes the reconciled submit+beacon rows behind authentication, so a
14
+ * plugin can join runs to its own attribution provider's report over HTTP
15
+ * instead of re-parsing raw NDJSON. Kept out of `healthRoutes` because this
16
+ * payload carries applicant-run identifiers (the opaque `joinKeys` bag) —
17
+ * strictly more sensitive than the plugin-load report
18
+ * `pluginsIntrospectionRoutes` already gates behind auth.
19
+ */
20
+ export declare function submissionsRoutes(app: FastifyInstance, options?: SubmissionsRoutesOptions): Promise<void>;
21
+ //# sourceMappingURL=submissions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submissions.d.ts","sourceRoot":"","sources":["../../../src/api/routes/submissions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAY/C;;;;;GAKG;AACH,MAAM,WAAW,wBAAwB;IACvC,iGAAiG;IACjG,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAiBD;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,eAAe,EACpB,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,IAAI,CAAC,CA4Bf"}
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.submissionsRoutes = submissionsRoutes;
4
+ const envelope_1 = require("../../api/helpers/envelope");
5
+ const submissions_1 = require("../../api/schemas/submissions");
6
+ const reconciliation_source_1 = require("../../lib/telemetry/reconciliation-source");
7
+ const submission_query_1 = require("../../lib/telemetry/submission-query");
8
+ /**
9
+ * Narrows the reader's fold output (which carries the raw `beaconTs`/
10
+ * `beaconDurationMs` fold detail) down to the wire contract in
11
+ * `reconciliationRowSchema`, renaming `beaconTrackingUrl` to `trackingUrl`.
12
+ */
13
+ function toResponseRow(row) {
14
+ const { beaconTrackingUrl, beaconTs: _beaconTs, beaconDurationMs: _beaconDurationMs, ...rest } = row;
15
+ return { ...rest, trackingUrl: beaconTrackingUrl };
16
+ }
17
+ /**
18
+ * Exposes the reconciled submit+beacon rows behind authentication, so a
19
+ * plugin can join runs to its own attribution provider's report over HTTP
20
+ * instead of re-parsing raw NDJSON. Kept out of `healthRoutes` because this
21
+ * payload carries applicant-run identifiers (the opaque `joinKeys` bag) —
22
+ * strictly more sensitive than the plugin-load report
23
+ * `pluginsIntrospectionRoutes` already gates behind auth.
24
+ */
25
+ async function submissionsRoutes(app, options = {}) {
26
+ const { sinkPath } = options;
27
+ app.get("/v1/submissions", {
28
+ onRequest: [app.authenticate],
29
+ schema: {
30
+ querystring: submissions_1.submissionsQuerystringSchema,
31
+ response: { 200: submissions_1.submissionsResponseSchema },
32
+ },
33
+ }, async (request) => {
34
+ const { limit, offset, ...filter } = request.query;
35
+ const rows = await (0, reconciliation_source_1.readDurableReconciliationRows)({
36
+ sinkPath,
37
+ from: filter.from,
38
+ to: filter.to,
39
+ });
40
+ const matched = (0, submission_query_1.queryReconciliationRows)(rows, filter);
41
+ const paged = matched.slice(offset, offset + limit);
42
+ return (0, envelope_1.successEnvelope)({
43
+ submissions: paged.map(toResponseRow),
44
+ total: matched.length,
45
+ });
46
+ });
47
+ }
48
+ //# sourceMappingURL=submissions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submissions.js","sourceRoot":"","sources":["../../../src/api/routes/submissions.ts"],"names":[],"mappings":";;;AAEA,qDAAyD;AAKzD,2DAAoG;AACpG,iFAAsF;AACtF,uEAA2E;AAc3E;;;;GAIG;AACH,SAAS,aAAa,CAAC,GAAsB;IAC3C,MAAM,EACJ,iBAAiB,EACjB,QAAQ,EAAE,SAAS,EACnB,gBAAgB,EAAE,iBAAiB,EACnC,GAAG,IAAI,EACR,GAAG,GAAG,CAAC;IACR,OAAO,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC;AACrD,CAAC;AAED;;;;;;;GAOG;AACI,KAAK,4BACV,GAAoB,EACpB,OAAO,GAA6B,EAAE;IAEtC,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAE7B,GAAG,CAAC,GAAG,CACL,iBAAiB,EACjB;QACE,SAAS,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC;QAC7B,MAAM,EAAE;YACN,WAAW,EAAE,0CAA4B;YACzC,QAAQ,EAAE,EAAE,GAAG,EAAE,uCAAyB,EAAE;SAC7C;KACF,EACD,KAAK,EAAE,OAAO,EAAE,EAAE;QAChB,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC;QACnD,MAAM,IAAI,GAAG,MAAM,IAAA,qDAA6B,EAAC;YAC/C,QAAQ;YACR,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,EAAE,EAAE,MAAM,CAAC,EAAE;SACd,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,IAAA,0CAAuB,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACtD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC;QAEpD,OAAO,IAAA,0BAAe,EAAC;YACrB,WAAW,EAAE,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC;YACrC,KAAK,EAAE,OAAO,CAAC,MAAM;SACtB,CAAC,CAAC;IACL,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,110 @@
1
+ import { z } from "zod/v4";
2
+ /**
3
+ * Upper bound on `limit` so a query can't ask the read path to serialize the
4
+ * entire (potentially 100 MB) submissions sink into one response.
5
+ */
6
+ export declare const SUBMISSIONS_QUERY_LIMIT_MAX = 1000;
7
+ /**
8
+ * Querystring contract for the submissions read route. Every field is
9
+ * optional so a caller can filter by `siteId`/`requestId`, submit/beacon
10
+ * outcome, or a time window, and page through results. Site-specific join
11
+ * keys live in the opaque `joinKeys` bag on each row and are not filterable
12
+ * here — filter client-side, or on `siteId`/`requestId` first.
13
+ */
14
+ export declare const submissionsQuerystringSchema: z.ZodObject<{
15
+ siteId: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodOptional<z.ZodString>>;
16
+ requestId: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodOptional<z.ZodString>>;
17
+ status: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodOptional<z.ZodEnum<{
18
+ error: "error";
19
+ submitted: "submitted";
20
+ }>>>;
21
+ beaconStatus: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodOptional<z.ZodEnum<{
22
+ failed: "failed";
23
+ fired: "fired";
24
+ not_fired: "not_fired";
25
+ skipped: "skipped";
26
+ }>>>;
27
+ from: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodOptional<z.ZodISODateTime>>;
28
+ to: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodOptional<z.ZodISODateTime>>;
29
+ limit: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodDefault<z.ZodCoercedNumber<unknown>>>;
30
+ offset: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodDefault<z.ZodCoercedNumber<unknown>>>;
31
+ }, z.core.$strip>;
32
+ export type SubmissionsQuerystring = z.infer<typeof submissionsQuerystringSchema>;
33
+ /**
34
+ * One reconciled per-run row: the submit record's opaque `joinKeys` bag and
35
+ * outcome, plus the beacon-fire dimension folded on by `requestId`. Derived
36
+ * from `submitRecordSchema` (feat-002's durable record) rather than
37
+ * restated, so a field added to the writer can't silently drift from what
38
+ * the read path claims to expose — the same re-export-not-duplicate pattern
39
+ * as `src/api/schemas/telemetry.ts`. `inboundPayload`/`auditPayload` are
40
+ * omitted: they're the opaque blob this route exists to stop callers from
41
+ * having to re-parse.
42
+ */
43
+ export declare const reconciliationRowSchema: z.ZodObject<{
44
+ siteId: z.ZodString;
45
+ requestId: z.ZodString;
46
+ joinKeys: z.ZodDefault<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
47
+ status: z.ZodEnum<{
48
+ error: "error";
49
+ submitted: "submitted";
50
+ }>;
51
+ errorMessage: z.ZodNullable<z.ZodString>;
52
+ durationMs: z.ZodNumber;
53
+ ts: z.ZodString;
54
+ beaconStatus: z.ZodEnum<{
55
+ failed: "failed";
56
+ fired: "fired";
57
+ not_fired: "not_fired";
58
+ skipped: "skipped";
59
+ }>;
60
+ trackingUrl: z.ZodNullable<z.ZodString>;
61
+ }, z.core.$strip>;
62
+ export type ReconciliationRow = z.infer<typeof reconciliationRowSchema>;
63
+ /**
64
+ * Response contract for the submissions read route: the standard envelope
65
+ * plus the reconciled rows and a total count for pagination.
66
+ */
67
+ export declare const submissionsResponseSchema: z.ZodObject<{
68
+ status: z.ZodObject<{
69
+ httpStatus: z.ZodUnion<[z.ZodEnum<{
70
+ BAD_REQUEST: "BAD_REQUEST";
71
+ FORBIDDEN: "FORBIDDEN";
72
+ GATEWAY_TIMEOUT: "GATEWAY_TIMEOUT";
73
+ INTERNAL_SERVER_ERROR: "INTERNAL_SERVER_ERROR";
74
+ NOT_FOUND: "NOT_FOUND";
75
+ OK: "OK";
76
+ SERVICE_UNAVAILABLE: "SERVICE_UNAVAILABLE";
77
+ TOO_MANY_REQUESTS: "TOO_MANY_REQUESTS";
78
+ UNAUTHORIZED: "UNAUTHORIZED";
79
+ }>, z.ZodString]>;
80
+ dateTime: z.ZodString;
81
+ details: z.ZodDefault<z.ZodArray<z.ZodObject<{
82
+ code: z.ZodNumber;
83
+ codeDescription: z.ZodString;
84
+ detailType: z.ZodOptional<z.ZodString>;
85
+ message: z.ZodOptional<z.ZodString>;
86
+ }, z.core.$loose>>>;
87
+ }, z.core.$loose>;
88
+ submissions: z.ZodArray<z.ZodObject<{
89
+ siteId: z.ZodString;
90
+ requestId: z.ZodString;
91
+ joinKeys: z.ZodDefault<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
92
+ status: z.ZodEnum<{
93
+ error: "error";
94
+ submitted: "submitted";
95
+ }>;
96
+ errorMessage: z.ZodNullable<z.ZodString>;
97
+ durationMs: z.ZodNumber;
98
+ ts: z.ZodString;
99
+ beaconStatus: z.ZodEnum<{
100
+ failed: "failed";
101
+ fired: "fired";
102
+ not_fired: "not_fired";
103
+ skipped: "skipped";
104
+ }>;
105
+ trackingUrl: z.ZodNullable<z.ZodString>;
106
+ }, z.core.$strip>>;
107
+ total: z.ZodNumber;
108
+ }, z.core.$strip>;
109
+ export type SubmissionsResponse = z.infer<typeof submissionsResponseSchema>;
110
+ //# sourceMappingURL=submissions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submissions.d.ts","sourceRoot":"","sources":["../../../src/api/schemas/submissions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAK3B;;;GAGG;AACH,eAAO,MAAM,2BAA2B,OAAO,CAAC;AA6BhD;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;iBAevC,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAElF;;;;;;;;;GASG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;iBAKhC,CAAC;AAEL,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE;;;GAGG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAIpC,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC"}
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.submissionsResponseSchema = exports.reconciliationRowSchema = exports.submissionsQuerystringSchema = exports.SUBMISSIONS_QUERY_LIMIT_MAX = void 0;
4
+ const v4_1 = require("zod/v4");
5
+ const common_1 = require("../../api/schemas/common");
6
+ const reconciliation_record_1 = require("../../lib/telemetry/reconciliation-record");
7
+ /**
8
+ * Upper bound on `limit` so a query can't ask the read path to serialize the
9
+ * entire (potentially 100 MB) submissions sink into one response.
10
+ */
11
+ exports.SUBMISSIONS_QUERY_LIMIT_MAX = 1000;
12
+ const DEFAULT_LIMIT = 100;
13
+ const DEFAULT_OFFSET = 0;
14
+ /**
15
+ * Query params arrive as strings (or an empty string for a present-but-blank
16
+ * value, e.g. `?limit=`). Both cases mean "not provided" for an optional
17
+ * filter, so they're normalized to `undefined` ahead of the real schema
18
+ * rather than treating `""` as a literal filter value.
19
+ */
20
+ function blankToUndefined(value) {
21
+ return value === "" ? undefined : value;
22
+ }
23
+ const optionalTrimmedString = () => v4_1.z.preprocess(blankToUndefined, v4_1.z.string().optional());
24
+ /**
25
+ * The read path's beacon-status fold: the record-layer `beaconStatus`
26
+ * options (`beaconEventSchema.shape.beaconStatus`) plus `"not_fired"`, the
27
+ * value `submission-reader.ts` folds in when no beacon line ever arrived.
28
+ * Derived rather than restated so a status added at the record layer can't
29
+ * silently drift from what this read path advertises.
30
+ */
31
+ const reconciliationBeaconStatusSchema = v4_1.z.enum([
32
+ ...reconciliation_record_1.beaconEventSchema.shape.beaconStatus.options,
33
+ "not_fired",
34
+ ]);
35
+ /**
36
+ * Querystring contract for the submissions read route. Every field is
37
+ * optional so a caller can filter by `siteId`/`requestId`, submit/beacon
38
+ * outcome, or a time window, and page through results. Site-specific join
39
+ * keys live in the opaque `joinKeys` bag on each row and are not filterable
40
+ * here — filter client-side, or on `siteId`/`requestId` first.
41
+ */
42
+ exports.submissionsQuerystringSchema = v4_1.z.object({
43
+ siteId: optionalTrimmedString(),
44
+ requestId: optionalTrimmedString(),
45
+ status: v4_1.z.preprocess(blankToUndefined, reconciliation_record_1.submitRecordSchema.shape.status.optional()),
46
+ beaconStatus: v4_1.z.preprocess(blankToUndefined, reconciliationBeaconStatusSchema.optional()),
47
+ from: v4_1.z.preprocess(blankToUndefined, v4_1.z.iso.datetime({ offset: true }).optional()),
48
+ to: v4_1.z.preprocess(blankToUndefined, v4_1.z.iso.datetime({ offset: true }).optional()),
49
+ limit: v4_1.z.preprocess(blankToUndefined, v4_1.z.coerce.number().int().positive().max(exports.SUBMISSIONS_QUERY_LIMIT_MAX).default(DEFAULT_LIMIT)),
50
+ offset: v4_1.z.preprocess(blankToUndefined, v4_1.z.coerce.number().int().nonnegative().default(DEFAULT_OFFSET)),
51
+ });
52
+ /**
53
+ * One reconciled per-run row: the submit record's opaque `joinKeys` bag and
54
+ * outcome, plus the beacon-fire dimension folded on by `requestId`. Derived
55
+ * from `submitRecordSchema` (feat-002's durable record) rather than
56
+ * restated, so a field added to the writer can't silently drift from what
57
+ * the read path claims to expose — the same re-export-not-duplicate pattern
58
+ * as `src/api/schemas/telemetry.ts`. `inboundPayload`/`auditPayload` are
59
+ * omitted: they're the opaque blob this route exists to stop callers from
60
+ * having to re-parse.
61
+ */
62
+ exports.reconciliationRowSchema = reconciliation_record_1.submitRecordSchema
63
+ .omit({ kind: true, inboundPayload: true, auditPayload: true })
64
+ .extend({
65
+ beaconStatus: reconciliationBeaconStatusSchema,
66
+ trackingUrl: v4_1.z.string().nullable(),
67
+ });
68
+ /**
69
+ * Response contract for the submissions read route: the standard envelope
70
+ * plus the reconciled rows and a total count for pagination.
71
+ */
72
+ exports.submissionsResponseSchema = v4_1.z.object({
73
+ status: common_1.statusSchema,
74
+ submissions: v4_1.z.array(exports.reconciliationRowSchema),
75
+ total: v4_1.z.number().int().nonnegative(),
76
+ });
77
+ //# sourceMappingURL=submissions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submissions.js","sourceRoot":"","sources":["../../../src/api/schemas/submissions.ts"],"names":[],"mappings":";;;AAAA,+BAA2B;AAE3B,iDAAoD;AACpD,iFAA8F;AAE9F;;;GAGG;AACU,QAAA,2BAA2B,GAAG,IAAI,CAAC;AAEhD,MAAM,aAAa,GAAG,GAAG,CAAC;AAC1B,MAAM,cAAc,GAAG,CAAC,CAAC;AAEzB;;;;;GAKG;AACH,SAAS,gBAAgB,CAAC,KAAc;IACtC,OAAO,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;AAC1C,CAAC;AAED,MAAM,qBAAqB,GAAG,GAAG,EAAE,CAAC,MAAC,CAAC,UAAU,CAAC,gBAAgB,EAAE,MAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;AAE1F;;;;;;GAMG;AACH,MAAM,gCAAgC,GAAG,MAAC,CAAC,IAAI,CAAC;IAC9C,GAAG,yCAAiB,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO;IAC/C,WAAW;CACZ,CAAC,CAAC;AAEH;;;;;;GAMG;AACU,QAAA,4BAA4B,GAAG,MAAC,CAAC,MAAM,CAAC;IACnD,MAAM,EAAE,qBAAqB,EAAE;IAC/B,SAAS,EAAE,qBAAqB,EAAE;IAClC,MAAM,EAAE,MAAC,CAAC,UAAU,CAAC,gBAAgB,EAAE,0CAAkB,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;IAClF,YAAY,EAAE,MAAC,CAAC,UAAU,CAAC,gBAAgB,EAAE,gCAAgC,CAAC,QAAQ,EAAE,CAAC;IACzF,IAAI,EAAE,MAAC,CAAC,UAAU,CAAC,gBAAgB,EAAE,MAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;IACjF,EAAE,EAAE,MAAC,CAAC,UAAU,CAAC,gBAAgB,EAAE,MAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC/E,KAAK,EAAE,MAAC,CAAC,UAAU,CACjB,gBAAgB,EAChB,MAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,QAAA,2BAA2B,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAC3F;IACD,MAAM,EAAE,MAAC,CAAC,UAAU,CAClB,gBAAgB,EAChB,MAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC,CAC9D;CACF,CAAC,CAAC;AAIH;;;;;;;;;GASG;AACU,QAAA,uBAAuB,GAAG,0CAAkB;KACtD,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;KAC9D,MAAM,CAAC;IACN,YAAY,EAAE,gCAAgC;IAC9C,WAAW,EAAE,MAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACnC,CAAC,CAAC;AAIL;;;GAGG;AACU,QAAA,yBAAyB,GAAG,MAAC,CAAC,MAAM,CAAC;IAChD,MAAM,EAAE,qBAAY;IACpB,WAAW,EAAE,MAAC,CAAC,KAAK,CAAC,QAAA,uBAAuB,CAAC;IAC7C,KAAK,EAAE,MAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;CACtC,CAAC,CAAC"}
package/dist/config.d.ts CHANGED
@@ -60,6 +60,28 @@ export interface AppConfig {
60
60
  connectTimeoutMs: number;
61
61
  /** Steel session wall-clock timeout in ms. Default is 1 hour; lower via STEEL_SESSION_TIMEOUT_MS on plans with shorter limits. */
62
62
  steelSessionTimeoutMs: number;
63
+ /**
64
+ * How long `resolveFrameTarget` polls `page.frames()` for a child iframe
65
+ * to attach before falling back to the main-frame target. Raised from a
66
+ * hardcoded 5 s default because cross-origin OOPIFs (e.g. Talemetry's
67
+ * apply iframe) regularly exceed 5 s to attach under advancedStealth +
68
+ * proxied CDP, even though a bare session attaches in ~3-4 s.
69
+ */
70
+ frameReadyTimeoutMs: number;
71
+ /**
72
+ * How long `waitForChildFrameReady` polls a resolved child frame's
73
+ * `document.readyState` before proceeding anyway. Kept separate from
74
+ * `frameReadyTimeoutMs` — this wait settles in well under a second once
75
+ * the frame has attached, so raising the attach budget must not stretch
76
+ * this one too.
77
+ */
78
+ frameDocumentReadyTimeoutMs: number;
79
+ /**
80
+ * Watchdog budget for a single frame-scoped `evaluate`/candidate-probe
81
+ * call (e.g. `deepLocator().count()`/`.click()`), so a call against a
82
+ * racy OOPIF fails the attempt instead of hanging the step indefinitely.
83
+ */
84
+ frameEvaluateTimeoutMs: number;
63
85
  };
64
86
  bedrock: {
65
87
  region: string;
@@ -133,6 +155,18 @@ export interface AppConfig {
133
155
  flushIntervalMs: number;
134
156
  /** `TELEMETRY_S3_MAX_BUFFER_LINES` — threshold-flush trigger per buffer. */
135
157
  maxBufferLines: number;
158
+ /**
159
+ * `TELEMETRY_S3_READ_MAX_OBJECTS` — upper bound on the number of S3
160
+ * objects a single reconciliation read-path query is allowed to scan,
161
+ * so a query spanning months of shipped NDJSON cannot fan out
162
+ * unbounded S3 GETs or blow the response budget.
163
+ */
164
+ readMaxObjects: number;
165
+ /**
166
+ * `TELEMETRY_S3_READ_CONCURRENCY` — max concurrent object fetches for
167
+ * a single reconciliation read-path query.
168
+ */
169
+ readConcurrency: number;
136
170
  };
137
171
  };
138
172
  judging: {
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
package/dist/config.js CHANGED
@@ -67,6 +67,9 @@ function loadConfig() {
67
67
  anthropicTimeoutMs: (0, env_1.getNumericEnv)("STAGEHAND_API_TIMEOUT_MS", 120_000),
68
68
  connectTimeoutMs: (0, env_1.getNumericEnv)("STAGEHAND_CONNECT_TIMEOUT_MS", 120_000),
69
69
  steelSessionTimeoutMs: (0, env_1.getNumericEnv)("STEEL_SESSION_TIMEOUT_MS", 3_600_000),
70
+ frameReadyTimeoutMs: (0, env_1.getNumericEnv)("FRAME_READY_TIMEOUT_MS", 20_000),
71
+ frameDocumentReadyTimeoutMs: (0, env_1.getNumericEnv)("FRAME_DOCUMENT_READY_TIMEOUT_MS", 5_000),
72
+ frameEvaluateTimeoutMs: (0, env_1.getNumericEnv)("FRAME_EVALUATE_TIMEOUT_MS", 30_000),
70
73
  },
71
74
  bedrock: {
72
75
  region: (0, env_1.getEnv)("AWS_REGION", "us-east-1"),
@@ -98,6 +101,8 @@ function loadConfig() {
98
101
  prefix: (0, env_1.getEnv)("TELEMETRY_S3_PREFIX", "telemetry"),
99
102
  flushIntervalMs: (0, env_1.getNumericEnv)("TELEMETRY_S3_FLUSH_INTERVAL_MS", 60_000),
100
103
  maxBufferLines: (0, env_1.getNumericEnv)("TELEMETRY_S3_MAX_BUFFER_LINES", 500),
104
+ readMaxObjects: (0, env_1.getNumericEnv)("TELEMETRY_S3_READ_MAX_OBJECTS", 200),
105
+ readConcurrency: (0, env_1.getNumericEnv)("TELEMETRY_S3_READ_CONCURRENCY", 8),
101
106
  },
102
107
  },
103
108
  judging: {
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Append-only NDJSON writer for beacon-fire outcomes. A `"fired"`/`"failed"`
3
+ * beacon resolves strictly after dispatch already returned and wrote its
4
+ * submit line (see `tracking-click.ts`'s fire-and-forget click); a
5
+ * `"skipped"` beacon is instead written synchronously by `dispatch()` itself,
6
+ * before it returns, when there is no `TrackingUrl` to fire-and-forget at
7
+ * all. Either way it is recorded as its own `kind:"beacon"` line rather than
8
+ * a mutation of the submit line — a reader folds the two kinds together by
9
+ * `requestId` (see `reconciliation-record.ts`, `submission-reader.ts`).
10
+ *
11
+ * Writes to the SAME sink as submit lines (`appendSubmissionSinkLine`,
12
+ * feat-003), which is what lets the S3 mirror carry beacon lines for free
13
+ * with zero `s3-sink.ts` changes.
14
+ */
15
+ import type { z } from "zod/v4";
16
+ import type { beaconEventSchema } from "../../lib/telemetry/reconciliation-record";
17
+ /** Validated shape of one beacon-event sample. */
18
+ export type BeaconEventSample = z.infer<typeof beaconEventSchema>;
19
+ /**
20
+ * Input to `captureBeaconEvent` — `ts` and `kind` are derived internally so
21
+ * callers omit them.
22
+ */
23
+ export type BeaconEventInput = Omit<BeaconEventSample, "ts" | "kind">;
24
+ /** Options for `captureBeaconEvent`. */
25
+ export interface CaptureBeaconEventOptions {
26
+ /** Override the sink path; used in tests to avoid touching the real file. */
27
+ sinkPath?: string;
28
+ }
29
+ /**
30
+ * Appends one validated NDJSON line for a beacon-fire outcome to the
31
+ * configured submissions sink. Errors are logged and swallowed — telemetry
32
+ * must never break the happy path, matching the never-throw contract
33
+ * `captureSubmissionEnvelope` enforces (submission-capture.ts:52-56); the
34
+ * beacon caller (tracking-click) is already fire-and-forget.
35
+ */
36
+ export declare function captureBeaconEvent(input: BeaconEventInput, opts?: CaptureBeaconEventOptions): Promise<void>;
37
+ //# sourceMappingURL=beacon-capture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"beacon-capture.d.ts","sourceRoot":"","sources":["../../../src/lib/telemetry/beacon-capture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAIhC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAO/E,kDAAkD;AAClD,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAElE;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,iBAAiB,EAAE,IAAI,GAAG,MAAM,CAAC,CAAC;AAEtE,wCAAwC;AACxC,MAAM,WAAW,yBAAyB;IACxC,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,gBAAgB,EACvB,IAAI,GAAE,yBAA8B,GACnC,OAAO,CAAC,IAAI,CAAC,CAef"}
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ /**
3
+ * Append-only NDJSON writer for beacon-fire outcomes. A `"fired"`/`"failed"`
4
+ * beacon resolves strictly after dispatch already returned and wrote its
5
+ * submit line (see `tracking-click.ts`'s fire-and-forget click); a
6
+ * `"skipped"` beacon is instead written synchronously by `dispatch()` itself,
7
+ * before it returns, when there is no `TrackingUrl` to fire-and-forget at
8
+ * all. Either way it is recorded as its own `kind:"beacon"` line rather than
9
+ * a mutation of the submit line — a reader folds the two kinds together by
10
+ * `requestId` (see `reconciliation-record.ts`, `submission-reader.ts`).
11
+ *
12
+ * Writes to the SAME sink as submit lines (`appendSubmissionSinkLine`,
13
+ * feat-003), which is what lets the S3 mirror carry beacon lines for free
14
+ * with zero `s3-sink.ts` changes.
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.captureBeaconEvent = captureBeaconEvent;
18
+ const date_fns_1 = require("date-fns");
19
+ const config_1 = require("../../config");
20
+ const logging_1 = require("../../lib/logging");
21
+ const submission_capture_1 = require("../../lib/telemetry/submission-capture");
22
+ const logger = (0, logging_1.getLogger)({ name: "telemetry/beacon-capture" });
23
+ const TRACKING_URL_MAX_LENGTH = 120;
24
+ /**
25
+ * Appends one validated NDJSON line for a beacon-fire outcome to the
26
+ * configured submissions sink. Errors are logged and swallowed — telemetry
27
+ * must never break the happy path, matching the never-throw contract
28
+ * `captureSubmissionEnvelope` enforces (submission-capture.ts:52-56); the
29
+ * beacon caller (tracking-click) is already fire-and-forget.
30
+ */
31
+ async function captureBeaconEvent(input, opts = {}) {
32
+ const sinkPath = opts.sinkPath ?? config_1.config.telemetry.submissionsNdjsonPath;
33
+ const sample = {
34
+ ...input,
35
+ kind: "beacon",
36
+ trackingUrl: input.trackingUrl?.slice(0, TRACKING_URL_MAX_LENGTH) ?? null,
37
+ ts: (0, date_fns_1.formatISO)(new Date()),
38
+ };
39
+ try {
40
+ const line = `${JSON.stringify(sample)}\n`;
41
+ await (0, submission_capture_1.appendSubmissionSinkLine)(sinkPath, line);
42
+ }
43
+ catch (err) {
44
+ logger.error(`captureBeaconEvent: failed to write to ${sinkPath}: ${String(err)}`);
45
+ }
46
+ }
47
+ //# sourceMappingURL=beacon-capture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"beacon-capture.js","sourceRoot":"","sources":["../../../src/lib/telemetry/beacon-capture.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;;;AAEH,uCAAqC;AAGrC,qCAAkC;AAClC,2CAA0C;AAE1C,2EAA8E;AAE9E,MAAM,MAAM,GAAG,IAAA,mBAAS,EAAC,EAAE,IAAI,EAAE,0BAA0B,EAAE,CAAC,CAAC;AAE/D,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAiBpC;;;;;;GAMG;AACI,KAAK,6BACV,KAAuB,EACvB,IAAI,GAA8B,EAAE;IAEpC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,eAAM,CAAC,SAAS,CAAC,qBAAqB,CAAC;IACzE,MAAM,MAAM,GAAsB;QAChC,GAAG,KAAK;QACR,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,EAAE,uBAAuB,CAAC,IAAI,IAAI;QACzE,EAAE,EAAE,IAAA,oBAAS,EAAC,IAAI,IAAI,EAAE,CAAC;KAC1B,CAAC;IAEF,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC;QAC3C,MAAM,IAAA,6CAAwB,EAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACjD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,KAAK,CAAC,0CAA0C,QAAQ,KAAK,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACrF,CAAC;AACH,CAAC"}