opencode-swarm 7.136.5 → 7.137.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.
Files changed (75) hide show
  1. package/dist/agents/agent-output-schema.d.ts +2 -2
  2. package/dist/cli/{config-doctor-n3hatm9d.js → config-doctor-vyx82nx2.js} +2 -2
  3. package/dist/cli/{core-jpjk2qvt.js → core-6w5sd5bc.js} +1 -1
  4. package/dist/cli/{curation-policy-c4g08bg1.js → curation-policy-8tvs4pa0.js} +7 -6
  5. package/dist/cli/{curator-jc5cc980.js → curator-43xqs75k.js} +25 -25
  6. package/dist/cli/{curator-llm-factory-atfnhbn6.js → curator-llm-factory-8nywfdsh.js} +25 -25
  7. package/dist/cli/{evidence-summary-service-nse06dqr.js → evidence-summary-service-85gw9p2m.js} +7 -7
  8. package/dist/cli/{gate-evidence-kdygjr56.js → gate-evidence-s2kytsrj.js} +4 -4
  9. package/dist/cli/{guardrail-explain-v6f8efve.js → guardrail-explain-8kkqz8tx.js} +26 -26
  10. package/dist/cli/{guardrail-log-0mrq14g9.js → guardrail-log-e2v9qw71.js} +3 -3
  11. package/dist/cli/{hive-promoter-wyejhz8b.js → hive-promoter-jt9ky0hn.js} +25 -25
  12. package/dist/cli/{index-45y0y3xh.js → index-1zrb3vt2.js} +7 -7
  13. package/dist/cli/{index-d2sf9an1.js → index-5r6kkhd7.js} +4 -4
  14. package/dist/cli/{index-ne28wyyc.js → index-5wjw05dy.js} +2 -2
  15. package/dist/cli/{index-84se71v1.js → index-72wzb81c.js} +3 -3
  16. package/dist/cli/{index-7t3vjw5e.js → index-877ah4kx.js} +1 -1
  17. package/dist/cli/{index-tncy55bp.js → index-8ehyt3rx.js} +1 -1
  18. package/dist/cli/{index-j7ja83v5.js → index-91kk2e9j.js} +1 -1
  19. package/dist/cli/{index-hbzh7yyz.js → index-92v63zzr.js} +55 -55
  20. package/dist/cli/{index-bqan4y2y.js → index-aze9n64z.js} +2 -2
  21. package/dist/cli/{index-tr0ctbhq.js → index-d00q9kpq.js} +5 -5
  22. package/dist/cli/{index-akc6rp3x.js → index-d0nhz96c.js} +2 -2
  23. package/dist/cli/{index-hh34tyv7.js → index-dxatvs3f.js} +1 -1
  24. package/dist/cli/{index-yj61bped.js → index-f24r6yqk.js} +3 -3
  25. package/dist/cli/{index-qhbr4h5n.js → index-fgkhpdc6.js} +6 -6
  26. package/dist/cli/{index-w6j1n5az.js → index-gv00q5gc.js} +1 -1
  27. package/dist/cli/index-h5sbn1zr.js +1670 -0
  28. package/dist/cli/{index-xvcctb2t.js → index-j2ghsdzz.js} +27 -27
  29. package/dist/cli/{index-f5qs217h.js → index-j6ewv2pe.js} +1 -1
  30. package/dist/cli/{index-nfm9f10v.js → index-k3mezk96.js} +1 -1
  31. package/dist/cli/{index-6kd0ezgd.js → index-mg26zd8x.js} +2 -2
  32. package/dist/cli/{index-eeb35dnx.js → index-mwdzkr6k.js} +3 -2
  33. package/dist/cli/{index-b3jfcptk.js → index-n3h6rmbe.js} +1 -1
  34. package/dist/cli/{index-vm05set2.js → index-p124rnwb.js} +4 -4
  35. package/dist/cli/{index-pyz1p8qv.js → index-pcwjz5de.js} +1 -1
  36. package/dist/cli/{index-kym0cctr.js → index-qy3rgmkc.js} +1 -1
  37. package/dist/cli/{index-d61h3f3h.js → index-s3j9fsab.js} +2 -2
  38. package/dist/cli/{index-zzhyws9g.js → index-vft1pg34.js} +1 -1
  39. package/dist/cli/{index-8f4346kf.js → index-wg98bsxz.js} +2 -2
  40. package/dist/cli/{index-xp2pfbpq.js → index-y25nsyaq.js} +1 -1
  41. package/dist/cli/index.js +25 -25
  42. package/dist/cli/{knowledge-escalator-2xe8z24p.js → knowledge-escalator-9k0kbx6b.js} +8 -7
  43. package/dist/cli/{knowledge-events-wecrshsx.js → knowledge-events-8nz3sa2d.js} +6 -5
  44. package/dist/cli/{knowledge-link-zr40rnwr.js → knowledge-link-t94b79qe.js} +5 -4
  45. package/dist/cli/{knowledge-store-9f74whxw.js → knowledge-store-esghe3f9.js} +6 -5
  46. package/dist/cli/{knowledge-validator-4ng7x9dr.js → knowledge-validator-bjxag1jp.js} +9 -8
  47. package/dist/cli/{pending-delegations-0h5b18p7.js → pending-delegations-kshh66s2.js} +3 -3
  48. package/dist/cli/{pr-subscriptions-jn0h047q.js → pr-subscriptions-5fpzz4f3.js} +3 -3
  49. package/dist/cli/{runner-deeswadt.js → runner-d820ws7y.js} +5 -5
  50. package/dist/cli/{scan-cursor-yzj9n225.js → scan-cursor-t212v00f.js} +7 -6
  51. package/dist/cli/{schema-cr1nr1w0.js → schema-11gyrec3.js} +1 -1
  52. package/dist/cli/{scope-persistence-5xc9ntdh.js → scope-persistence-sjz200dt.js} +4 -4
  53. package/dist/cli/{skill-generator-ybncj9et.js → skill-generator-a07hpmw6.js} +10 -9
  54. package/dist/cli/{telemetry-6678gya0.js → telemetry-h7h7f0ez.js} +2 -1
  55. package/dist/cli/{worktree-collision-ownership-wt7cc850.js → worktree-collision-ownership-xzwab4xt.js} +3 -3
  56. package/dist/config/constants.d.ts +1 -1
  57. package/dist/config/evidence-schema.d.ts +103 -103
  58. package/dist/config/plan-schema.d.ts +10 -10
  59. package/dist/config/schema.d.ts +8 -8
  60. package/dist/consensus/contracts.d.ts +3 -3
  61. package/dist/hooks/hive-promoter.d.ts +1 -1
  62. package/dist/index.js +72 -72
  63. package/dist/observability/catalog.d.ts +84 -0
  64. package/dist/observability/envelope.d.ts +401 -0
  65. package/dist/observability/ids.d.ts +97 -0
  66. package/dist/observability/index.d.ts +58 -0
  67. package/dist/observability/legacy.d.ts +68 -0
  68. package/dist/observability/observe.d.ts +112 -0
  69. package/dist/observability/otel-mapping.d.ts +48 -0
  70. package/dist/observability/relationships.d.ts +44 -0
  71. package/dist/observability/sampling.d.ts +77 -0
  72. package/dist/summaries/schema.d.ts +2 -2
  73. package/dist/telemetry.d.ts +4 -1
  74. package/package.json +3 -2
  75. package/dist/cli/index-cze4bq1x.js +0 -358
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Legacy telemetry adapter (issue #2029 item 4 / AC2).
3
+ *
4
+ * Its real production input is the untyped `data: Record<string, unknown>` that
5
+ * `src/telemetry.ts:emit()` receives from 40+ call sites: caller-ordered,
6
+ * unversioned, with extra and missing fields. That is legacy-shaped input by
7
+ * definition, and adapting it is this module's genuine job.
8
+ *
9
+ * Two hard constraints govern every function here:
10
+ * 1. **Never throw.** `emit()` documents a never-throw guarantee
11
+ * (`src/telemetry.ts:266,294`) and `src/telemetry.test.ts:137-162`
12
+ * exercises circular objects, functions, `Symbol`s and `BigInt`s.
13
+ * 2. **Never deep-traverse, clone, or serialize the payload.** Only
14
+ * `Object.keys` (shallow) and own-key reads. See `LegacyProjectionSchema`
15
+ * for why `raw` must stay an alias.
16
+ *
17
+ * Import rules: no filesystem, network, subprocess, or OTel SDK.
18
+ */
19
+ import type { LegacyProjection, Outcome, WorkflowIds } from './envelope.js';
20
+ /** The store these payloads are written to. */
21
+ export declare const LEGACY_TELEMETRY_SOURCE_STORE = ".swarm/telemetry.jsonl";
22
+ /** Marker recorded in `legacy.unknown` when the payload is not an object. */
23
+ export declare const NON_OBJECT_PAYLOAD_MARKER = "<non-object-payload>";
24
+ /**
25
+ * Marker recorded when the payload resisted shallow introspection — a Proxy
26
+ * whose `ownKeys` trap throws, or a throwing getter. The payload is still kept
27
+ * by reference; only our description of it is degraded.
28
+ */
29
+ export declare const INTROSPECTION_FAILED_MARKER = "<payload-introspection-failed>";
30
+ /**
31
+ * The adapter rules, stated as a checkable list.
32
+ *
33
+ * These are the item-4 rules of issue #2029. They are exported as data (not
34
+ * prose in a doc file) so the static contract check and the unit tests can
35
+ * assert against the same statement of intent the implementation follows.
36
+ */
37
+ export declare const LEGACY_ADAPTER_RULES: readonly string[];
38
+ /**
39
+ * Payload keys each producer is known to emit.
40
+ *
41
+ * Derived from the emit call sites in source, NOT from captured output: a key
42
+ * whose value is `undefined` is elided by `JSON.stringify`, so a captured line
43
+ * under-reports the producer's key set. Listing those keys here is precisely
44
+ * what makes `legacy.unknown` non-vacuous — `delegation_end` naming `model`,
45
+ * `gate` and `retry_index` lets the adapter say "the producer did not know
46
+ * these" instead of silently omitting them.
47
+ */
48
+ export declare const KNOWN_TELEMETRY_KEYS: Readonly<Record<string, readonly string[]>>;
49
+ export declare function adaptLegacyTelemetryPayload(kind: string, data: unknown, knownKeys: readonly string[]): LegacyProjection;
50
+ /**
51
+ * Extract recognized correlation IDs from a legacy payload.
52
+ *
53
+ * Shallow, never throws, and NEVER synthesizes: an ID that is absent, empty, or
54
+ * of the wrong type stays `undefined`. Only the mappings a producer actually
55
+ * populates are implemented — `sessionId` to `hostSessionId`, `taskId`, `phase`
56
+ * to `phaseId`, `laneId`, `batchId`. The remaining eight recognized IDs have no
57
+ * current producer, and inventing an extraction for them would manufacture
58
+ * exactly the joins issue #2029 item 2 forbids.
59
+ */
60
+ export declare function extractWorkflowIds(data: unknown): WorkflowIds;
61
+ /**
62
+ * Extract terminal disposition from a legacy payload.
63
+ *
64
+ * Shallow and never throws. `durationMs` is deliberately never populated: no
65
+ * current producer reports a duration, and deriving one would fabricate a
66
+ * measurement.
67
+ */
68
+ export declare function extractOutcome(data: unknown): Outcome;
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Observation construction and the legacy line projection (issue #2029).
3
+ *
4
+ * Import rules: no filesystem, network, subprocess, or OTel SDK. Everything here
5
+ * is synchronous and allocation-only.
6
+ *
7
+ * ## Module state
8
+ *
9
+ * Four process-scoped variables. None is session-keyed, so AGENTS.md invariant 8
10
+ * (session-scoped state must be keyed by `sessionID` and bounded) does not
11
+ * apply: `_provenance` and `_lineage` are single small frozen-by-convention
12
+ * records describing THIS process, `_sampleRate` is a scalar, and
13
+ * `_writerSequence` is a scalar counter. None of them grows with session count,
14
+ * so there is nothing to evict. All four have a reset seam
15
+ * ({@link resetObservabilityForTesting}) so no test's assertions become order
16
+ * dependent.
17
+ */
18
+ import { type ObservabilityEvent, type Provenance } from './envelope.js';
19
+ /** Violation code stamped on a fallback event. */
20
+ export declare const OBSERVATION_BUILD_FAILED = "observation_build_failed";
21
+ /** Input to {@link initObservability}. */
22
+ export interface InitObservabilityInput {
23
+ /** Absolute project root. Pseudonymized, never stored. */
24
+ directory?: string;
25
+ /** Cohort label (e.g. a swarm id). Pseudonymized together with `directory`. */
26
+ cohortLabel?: string;
27
+ /** Worktree identity. Pseudonymized, never stored. */
28
+ worktreeId?: string;
29
+ provenance?: Provenance;
30
+ sampleRate?: number;
31
+ }
32
+ /**
33
+ * Install process provenance and lineage.
34
+ *
35
+ * Performs ZERO I/O — it hashes strings the caller already holds. That matters
36
+ * for AGENTS.md invariant 1: this runs on the plugin init path, and init-path
37
+ * work must be fast, bounded and side-effect-minimal.
38
+ *
39
+ * Lineage refs are computed ONCE here and reused by every subsequent
40
+ * observation. Computing them per-emit would put three SHA-256 digests on the
41
+ * hot path for values that never change within a process.
42
+ *
43
+ * NEVER THROWS. The whole body is guarded: a failure here must not prevent the
44
+ * plugin manifest from being returned (invariant 1, fail-open).
45
+ */
46
+ export declare function initObservability(input: InitObservabilityInput): void;
47
+ /**
48
+ * Build the canonical observation for one emit.
49
+ *
50
+ * **NEVER THROWS.** Not on a circular object, not on a function / `Symbol` /
51
+ * `BigInt` payload, not on an unknown kind, not on `null` or `undefined` data.
52
+ * It never calls `JSON.stringify`, never clones, and never deep-traverses
53
+ * `data` — `src/telemetry.test.ts:137-162` emits exactly those payloads and
54
+ * asserts `emit()` does not throw, and `src/telemetry.ts:266` documents the
55
+ * never-throw guarantee. If anything inside fails, a minimal valid event is
56
+ * returned carrying `relationshipViolations: ['observation_build_failed']`.
57
+ *
58
+ * An UNCATALOGUED kind is classified (`category: 'unrecognized'`), never
59
+ * dropped. Preventing new unrecognized kinds is the static contract check's job,
60
+ * not a runtime drop.
61
+ *
62
+ * `occurredAt` is set equal to `observedAt`. That is a recorded finding, not an
63
+ * invention: no current producer supplies a distinct time at which the described
64
+ * thing happened, so claiming one would fabricate precision the source does not
65
+ * have.
66
+ */
67
+ export declare function createObservation(kind: string, data: unknown): ObservabilityEvent;
68
+ /**
69
+ * Project a canonical event onto the legacy `.swarm/telemetry.jsonl` record.
70
+ *
71
+ * ## This projection is LOSSY and LEGACY-PINNED
72
+ *
73
+ * The envelope's non-legacy fields — `eventId`, `trace` (`traceId`, `spanId`,
74
+ * `parentSpanId`, `links`), `lineage`, `provenance`, `policy`, `writerSequence`,
75
+ * `schemaVersion` and `relationshipViolations` — are **currently DISCARDED**.
76
+ * Nothing in this change consumes them; their consumer lands in **#2047**. That
77
+ * is stated here rather than buried: a reader of this function must not conclude
78
+ * the written line is the canonical record. It is not.
79
+ *
80
+ * ## Byte-for-byte preservation
81
+ *
82
+ * The caller's object is spread **LAST**, exactly as the pre-change inline line
83
+ * construction in `src/telemetry.ts` `emit()` did. Three properties depend on
84
+ * that ordering, and all three are observable in
85
+ * `tests/fixtures/observability/telemetry-lines-golden.json` (issue #2029 item
86
+ * 5 arm (a) — "preserve the existing output"):
87
+ *
88
+ * 1. **Caller key order** is preserved after `timestamp` and `event`.
89
+ * 2. **Caller key collisions win on value.** `conflict-resolution.ts:55-66`
90
+ * supplies its own `timestamp` and `type`; the caller's `timestamp` value
91
+ * overwrites the envelope's while the key keeps position 1.
92
+ * 3. **`undefined`-key elision** is unchanged, because the caller's own object
93
+ * is spread rather than a reconstruction of it.
94
+ *
95
+ * `timestamp` is taken from `event.observedAt` — a real, load-bearing data
96
+ * dependency on the canonical event, which is why this composition is not the
97
+ * identity function on the emit path.
98
+ *
99
+ * A non-object, `null`, or array payload yields just `{ timestamp, event }`,
100
+ * matching what `JSON.stringify({ timestamp, event, ...data })` produces for
101
+ * those inputs.
102
+ */
103
+ export declare function toLegacyTelemetryLine(event: ObservabilityEvent): Record<string, unknown>;
104
+ /**
105
+ * Reset all four module-scoped variables.
106
+ *
107
+ * Called alongside `resetTelemetryForTesting` so no test's assertions become
108
+ * dependent on how many events an earlier test emitted.
109
+ *
110
+ * @internal - For testing only
111
+ */
112
+ export declare function resetObservabilityForTesting(): void;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * External-convention attribute mappings (issue #2029 item 6).
3
+ *
4
+ * These are INERT LOOKUP TABLES. There is no OpenTelemetry SDK dependency, no
5
+ * exporter, and no runtime consumer in this change: the tables are consumed as
6
+ * data by the static contract check (which asserts every catalog entry records a
7
+ * mapping decision) and by `docs/observability-event-contract.md`. The runtime
8
+ * consumer lands in #2049.
9
+ *
10
+ * Import rules: no filesystem, network, subprocess, or OTel SDK.
11
+ */
12
+ import type { OtelMappingKind } from './catalog.js';
13
+ /**
14
+ * OpenTelemetry semantic-convention generation these GenAI attribute names track.
15
+ *
16
+ * Pinned SEPARATELY from `OBSERVABILITY_SCHEMA_VERSION`. That separation is the
17
+ * whole point of issue #2029 item 6: the GenAI conventions are an external,
18
+ * still-unstable vocabulary. If they were versioned together, an upstream rename
19
+ * would force a bump of the internal envelope version and every consumer would
20
+ * be told the domain shape changed when nothing about the domain changed.
21
+ * External convention churn must never change internal domain state.
22
+ */
23
+ export declare const OTEL_GENAI_MAPPING_VERSION = "1.29.0";
24
+ /**
25
+ * OpenInference specification generation these attribute names track. Pinned
26
+ * separately from both {@link OTEL_GENAI_MAPPING_VERSION} and
27
+ * `OBSERVABILITY_SCHEMA_VERSION`, for the same reason.
28
+ */
29
+ export declare const OPENINFERENCE_MAPPING_VERSION = "0.1.14";
30
+ /**
31
+ * Internal envelope path to OTel GenAI attribute name.
32
+ *
33
+ * Keys are dotted paths into `ObservabilityEvent`. `legacy.raw.*` paths reach
34
+ * into the aliased producer payload, which is where token counts and the
35
+ * resolved model live today.
36
+ */
37
+ export declare const OTEL_GENAI_ATTRIBUTES: Readonly<Record<string, string>>;
38
+ /** Internal envelope path to OpenInference attribute name. */
39
+ export declare const OPENINFERENCE_ATTRIBUTES: Readonly<Record<string, string>>;
40
+ /**
41
+ * Resolve the attribute table a catalog entry projects onto.
42
+ *
43
+ * `'none'` is a real, recorded decision — "this kind has no external
44
+ * equivalent" — not a missing value. It returns an empty table, never
45
+ * `undefined`, so a consumer never has to distinguish "no mapping" from "not
46
+ * asked".
47
+ */
48
+ export declare function mappingForEntry(mapping: OtelMappingKind): Readonly<Record<string, string>>;
@@ -0,0 +1,44 @@
1
+ import type { ObservabilityEvent } from './envelope.js';
2
+ /** Verdict from {@link validateEventRelationships}. */
3
+ export type RelationshipValidationResult = {
4
+ ok: true;
5
+ } | {
6
+ ok: false;
7
+ violations: string[];
8
+ };
9
+ /**
10
+ * Stable violation codes.
11
+ *
12
+ * Codes are machine-readable and must not be renamed once emitted — they are the
13
+ * join key a downstream consumer will group on. The suffix after `:` is the
14
+ * offending identifier or link index.
15
+ */
16
+ export declare const RELATIONSHIP_VIOLATION_CODES: Readonly<{
17
+ unknownKind: "unknown_kind";
18
+ requiredWorkflowIdMissing: "required_workflow_id_missing";
19
+ forbiddenWorkflowIdPresent: "forbidden_workflow_id_present";
20
+ parentSpanNotAllowed: "parent_span_not_allowed";
21
+ parentSpanMissing: "parent_span_missing";
22
+ malformedParentSpanId: "malformed_parent_span_id";
23
+ linksNotAllowed: "links_not_allowed";
24
+ malformedLinkTraceId: "malformed_link_trace_id";
25
+ malformedLinkSpanId: "malformed_link_span_id";
26
+ validationFailed: "relationship_validation_failed";
27
+ }>;
28
+ /**
29
+ * Validate an event against its catalogued relationship rules.
30
+ *
31
+ * Checks, in order:
32
+ * (a) the kind is catalogued;
33
+ * (b) every `requiredWorkflowIds` entry is present;
34
+ * (c) no `forbiddenWorkflowIds` entry is present (a present one means an ID
35
+ * was manufactured upstream — issue #2029 item 2);
36
+ * (d) a parent span is absent when the kind does not take one;
37
+ * (e) a parent span is present when the kind requires one;
38
+ * (f) a present parent span is a well-formed W3C span id;
39
+ * (g) links are absent when the kind does not allow them;
40
+ * (h) every link carries a well-formed trace/span id pair.
41
+ *
42
+ * @returns `{ ok: true }` or `{ ok: false, violations }`. Never throws.
43
+ */
44
+ export declare function validateEventRelationships(event: ObservabilityEvent): RelationshipValidationResult;
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Sampling and metric-cardinality policy (issue #2029).
3
+ *
4
+ * Import rules: no filesystem, network, subprocess, or OTel SDK.
5
+ */
6
+ /**
7
+ * Default sample rate.
8
+ *
9
+ * `1` = sample everything. This PR introduces no dropping: a drop that no
10
+ * consumer can see is exactly the silent data loss the issue names, and the
11
+ * consumer that would make a drop observable lands in #2047.
12
+ */
13
+ export declare const DEFAULT_SAMPLE_RATE = 1;
14
+ /**
15
+ * Decide whether a trace is sampled.
16
+ *
17
+ * **Deterministic by construction.** The decision is a pure function of the
18
+ * trace id and the rate: the LAST 8 hex characters of the trace id are read as
19
+ * an unsigned integer and compared against `rate * 0xffffffff`. The same trace
20
+ * therefore samples identically in every process, on every host, and across
21
+ * restarts — no shared state, no RNG, no coordination. That is what makes a
22
+ * sampled distributed trace complete rather than a set of disconnected
23
+ * fragments, and it is why the decision is not `Math.random()`.
24
+ *
25
+ * **CAVEAT — that property is currently VACUOUS in this system, and saying so
26
+ * is the point.** `createObservation` mints a FRESH `traceId` per event, with
27
+ * `links: []` and no `parentSpanId`, so every event today is its own
28
+ * single-span trace. At a rate below 1 the decision is therefore independent
29
+ * PER EVENT, not per logical trace: a "trace" never spans two events, so
30
+ * nothing can be kept whole or torn apart. Trace continuation — propagating one
31
+ * trace id across the events that belong together — is #2047's work, and only
32
+ * then does trace-coherent sampling become a real property rather than a
33
+ * latent one. Nothing is dropped today regardless: {@link DEFAULT_SAMPLE_RATE}
34
+ * is `1`.
35
+ *
36
+ * **Fail-open.** Every unusable input returns `true`. Dropping an event because
37
+ * an id was malformed would lose data silently, which is the failure mode this
38
+ * contract exists to prevent. A non-finite rate also fails open, for the same
39
+ * reason: `NaN` would otherwise fall through both bounds and make every
40
+ * comparison `false`, silently dropping everything.
41
+ *
42
+ * @param traceId - 32 lowercase hex characters.
43
+ * @param rate - `>= 1` samples everything, `<= 0` samples nothing.
44
+ */
45
+ export declare function shouldSample(traceId: string, rate: number): boolean;
46
+ /**
47
+ * The only labels permitted on a metric.
48
+ *
49
+ * Every member is bounded: a small, enumerable set of values that cannot grow
50
+ * with traffic. The rule this enforces, from issue #2029: **IDs, paths, users,
51
+ * tasks, and repositories belong in traces and logs, not metric labels.** A
52
+ * single unbounded label multiplies the time-series count by its cardinality and
53
+ * takes a metrics backend down; the trace already carries that detail, keyed to
54
+ * the same event.
55
+ */
56
+ export declare const METRIC_LABEL_ALLOWLIST: readonly string[];
57
+ /** Verdict from {@link assertBoundedCardinality}. */
58
+ export type CardinalityResult = {
59
+ ok: true;
60
+ } | {
61
+ ok: false;
62
+ violations: string[];
63
+ };
64
+ /** Stable violation codes, suffixed with the offending label. */
65
+ export declare const CARDINALITY_VIOLATION_CODES: Readonly<{
66
+ notAllowlisted: "label_not_allowlisted";
67
+ highCardinalityShape: "high_cardinality_label_shape";
68
+ }>;
69
+ /**
70
+ * Check a metric's label set against the allowlist and against high-cardinality
71
+ * shapes.
72
+ *
73
+ * RETURNS a verdict; never throws. A label can produce both codes — the shape
74
+ * check runs independently of the allowlist check so that a newly-allowlisted
75
+ * label with an unbounded shape is still reported.
76
+ */
77
+ export declare function assertBoundedCardinality(labels: readonly string[]): CardinalityResult;
@@ -95,10 +95,10 @@ export declare const PhaseArchitectureSummarySchema: z.ZodObject<{
95
95
  export type PhaseArchitectureSummary = z.infer<typeof PhaseArchitectureSummarySchema>;
96
96
  export declare const SupervisorFindingSchema: z.ZodObject<{
97
97
  severity: z.ZodEnum<{
98
+ critical: "critical";
98
99
  low: "low";
99
100
  medium: "medium";
100
101
  high: "high";
101
- critical: "critical";
102
102
  }>;
103
103
  category: z.ZodString;
104
104
  agents: z.ZodDefault<z.ZodArray<z.ZodString>>;
@@ -135,10 +135,10 @@ export declare const ArchitectureSupervisorReportSchema: z.ZodObject<{
135
135
  }>;
136
136
  findings: z.ZodDefault<z.ZodArray<z.ZodObject<{
137
137
  severity: z.ZodEnum<{
138
+ critical: "critical";
138
139
  low: "low";
139
140
  medium: "medium";
140
141
  high: "high";
141
- critical: "critical";
142
142
  }>;
143
143
  category: z.ZodString;
144
144
  agents: z.ZodDefault<z.ZodArray<z.ZodString>>;
@@ -1,3 +1,4 @@
1
+ import { createObservation, toLegacyTelemetryLine } from './observability/index.js';
1
2
  import type { DelegationCostFields } from './services/cost-accounting.js';
2
3
  export type TelemetryEvent = 'session_started' | 'session_ended' | 'agent_activated' | 'delegation_begin' | 'delegation_end' | 'task_state_changed' | 'gate_passed' | 'gate_failed' | 'gate_parse_error' | 'reviewer_gate_decision' | 'phase_changed' | 'budget_updated' | 'model_fallback' | 'hard_limit_hit' | 'revision_limit_hit' | 'loop_detected' | 'no_op_strong_warning' | 'scope_violation' | 'qa_skip_violation' | 'heartbeat' | 'turbo_mode_changed' | 'auto_oversight_escalation' | 'environment_detected' | 'evidence_lock_acquired' | 'evidence_lock_contended' | 'evidence_lock_stale_recovered' | 'plan_ledger_cas_retry' | 'plan_md_write_failed' | 'snapshot_failed' | 'gate_denial_loop'
3
4
  /**
@@ -25,7 +26,7 @@ export type TelemetryEvent = 'session_started' | 'session_ended' | 'agent_activa
25
26
  * `prm_hard_stop` TRIGGER emitted by `src/prm/escalation.ts`. A trigger with
26
27
  * no matching delivery means the containment never reached the agent.
27
28
  */
28
- | 'prm_hard_stop_delivered';
29
+ | 'prm_hard_stop_delivered' | 'agent_conflict_detected';
29
30
  /** Stable classification for how a reviewer-gate decision was established. */
30
31
  export type ReviewerGateEvidenceKind = 'genuine' | 'fallback' | 'data_quality' | 'block';
31
32
  /**
@@ -157,4 +158,6 @@ export declare const _internals: {
157
158
  emit: typeof emit;
158
159
  rotateTelemetryIfNeeded: typeof rotateTelemetryIfNeeded;
159
160
  heartbeatListenerCount: () => number;
161
+ createObservation: typeof createObservation;
162
+ toLegacyTelemetryLine: typeof toLegacyTelemetryLine;
160
163
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.136.5",
3
+ "version": "7.137.0",
4
4
  "description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -104,7 +104,8 @@
104
104
  "prepare": "bun run build",
105
105
  "repro:704": "node scripts/repro-704.mjs",
106
106
  "repro:1144": "bun scripts/repro-1144.mjs",
107
- "repro:1873": "bun build scripts/repro-1873-entry.ts --outdir dist-build-test/repro-1873 --target node --format esm && node scripts/repro-1873.mjs"
107
+ "repro:1873": "bun build scripts/repro-1873-entry.ts --outdir dist-build-test/repro-1873 --target node --format esm && node scripts/repro-1873.mjs",
108
+ "check:events": "bun run scripts/check-event-contract.ts"
108
109
  },
109
110
  "dependencies": {
110
111
  "@opencode-ai/plugin": "^1.18.3",