@afokapu/atdd-bun 0.6.2 → 0.7.1
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 +13 -3
- package/conventions/coder.bun/coder.bun.telemetry-forbidden-properties.convention.yaml +51 -0
- package/conventions/coder.bun/coder.bun.telemetry-implementation-binding.convention.yaml +45 -0
- package/conventions/coder.bun/coder.bun.telemetry-raw-string-emit.convention.yaml +53 -0
- package/conventions/coder.bun/coder.bun.telemetry-source-binding.convention.yaml +48 -0
- package/conventions/coder.bun/coder.bun.telemetry-vendor-sdk.convention.yaml +51 -0
- package/conventions/planner.telemetry/planner.telemetry.acceptance-decision.convention.yaml +58 -0
- package/conventions/planner.telemetry/planner.telemetry.logical-ownership.convention.yaml +50 -0
- package/conventions/planner.telemetry/planner.telemetry.metric-cardinality.convention.yaml +47 -0
- package/conventions/planner.telemetry/planner.telemetry.tracking-plan-schema.convention.yaml +75 -0
- package/conventions/tester.bun/tester.bun.telemetry-captured-sink.convention.yaml +47 -0
- package/conventions/tester.bun/tester.bun.telemetry-identity-assertion.convention.yaml +44 -0
- package/conventions/tester.bun/tester.bun.telemetry-required-item-coverage.convention.yaml +44 -0
- package/conventions/tester.bun/tester.bun.telemetry-test-binding.convention.yaml +52 -0
- package/conventions/tester.bun/tester.bun.telemetry-timing-semantics.convention.yaml +53 -0
- package/detectors/bun_telemetry_code/atdd.implementation.yaml +24 -0
- package/detectors/bun_telemetry_code/calls.mjs +104 -0
- package/detectors/bun_telemetry_code/checks/t_forbidden_properties.mjs +46 -0
- package/detectors/bun_telemetry_code/checks/t_implementation_binding.mjs +41 -0
- package/detectors/bun_telemetry_code/checks/t_raw_string_emit.mjs +34 -0
- package/detectors/bun_telemetry_code/checks/t_source_binding.mjs +48 -0
- package/detectors/bun_telemetry_code/checks/t_vendor_sdk.mjs +38 -0
- package/detectors/bun_telemetry_code/detect.mjs +50 -0
- package/detectors/bun_telemetry_code/fixtures/clean/plan/commons/E001.yaml +10 -0
- package/detectors/bun_telemetry_code/fixtures/clean/plan/commons/E002.yaml +7 -0
- package/detectors/bun_telemetry_code/fixtures/clean/plan/commons/_commons.yaml +6 -0
- package/detectors/bun_telemetry_code/fixtures/clean/src/wagons/commons/features/ingress/domain/accept-response.ts +8 -0
- package/detectors/bun_telemetry_code/fixtures/clean/src/wagons/commons/features/ingress/infrastructure/otel-adapter.ts +8 -0
- package/detectors/bun_telemetry_code/fixtures/clean/telemetry/commons/response-invocation-accepted/event.be.json +16 -0
- package/detectors/bun_telemetry_code/fixtures/clean/telemetry/commons/response-invocation-accepted/metric.be.duration.json +19 -0
- package/detectors/bun_telemetry_code/fixtures/clean/tests/wagons/commons/features/ingress/unit/accept-response.telemetry.test.ts +13 -0
- package/detectors/bun_telemetry_code/fixtures/clean/tests/wagons/commons/features/ingress/unit/accept-response.test.ts +9 -0
- package/detectors/bun_telemetry_code/fixtures/dirty/plan/commons/E001.yaml +8 -0
- package/detectors/bun_telemetry_code/fixtures/dirty/plan/commons/_commons.yaml +6 -0
- package/detectors/bun_telemetry_code/fixtures/dirty/src/wagons/commons/features/ingress/domain/accept-response.ts +13 -0
- package/detectors/bun_telemetry_code/fixtures/dirty/src/wagons/commons/features/ingress/domain/tracing.ts +3 -0
- package/detectors/bun_telemetry_code/fixtures/dirty/telemetry/commons/response-invocation-accepted/event.be.json +16 -0
- package/detectors/bun_telemetry_code/fixtures/dirty/tests/wagons/commons/features/ingress/unit/probe.test.ts +7 -0
- package/detectors/bun_telemetry_code/registry.mjs +34 -0
- package/detectors/bun_telemetry_test/_shared.mjs +92 -0
- package/detectors/bun_telemetry_test/atdd.implementation.yaml +24 -0
- package/detectors/bun_telemetry_test/checks/t_captured_sink.mjs +35 -0
- package/detectors/bun_telemetry_test/checks/t_identity_assertion.mjs +45 -0
- package/detectors/bun_telemetry_test/checks/t_required_item_coverage.mjs +37 -0
- package/detectors/bun_telemetry_test/checks/t_test_binding.mjs +56 -0
- package/detectors/bun_telemetry_test/checks/t_timing_semantics.mjs +51 -0
- package/detectors/bun_telemetry_test/detect.mjs +50 -0
- package/detectors/bun_telemetry_test/fixtures/clean/plan/commons/E001.yaml +10 -0
- package/detectors/bun_telemetry_test/fixtures/clean/plan/commons/E002.yaml +7 -0
- package/detectors/bun_telemetry_test/fixtures/clean/plan/commons/_commons.yaml +6 -0
- package/detectors/bun_telemetry_test/fixtures/clean/src/wagons/commons/features/ingress/domain/accept-response.ts +8 -0
- package/detectors/bun_telemetry_test/fixtures/clean/telemetry/commons/response-invocation-accepted/event.be.json +16 -0
- package/detectors/bun_telemetry_test/fixtures/clean/telemetry/commons/response-invocation-accepted/metric.be.duration.json +19 -0
- package/detectors/bun_telemetry_test/fixtures/clean/tests/wagons/commons/features/ingress/unit/accept-response.telemetry.test.ts +13 -0
- package/detectors/bun_telemetry_test/fixtures/clean/tests/wagons/commons/features/ingress/unit/accept-response.test.ts +7 -0
- package/detectors/bun_telemetry_test/fixtures/dirty/plan/commons/E001.yaml +10 -0
- package/detectors/bun_telemetry_test/fixtures/dirty/plan/commons/E002.yaml +7 -0
- package/detectors/bun_telemetry_test/fixtures/dirty/plan/commons/_commons.yaml +6 -0
- package/detectors/bun_telemetry_test/fixtures/dirty/src/wagons/commons/features/ingress/domain/accept-response.ts +8 -0
- package/detectors/bun_telemetry_test/fixtures/dirty/telemetry/commons/response-invocation-accepted/event.be.json +16 -0
- package/detectors/bun_telemetry_test/fixtures/dirty/telemetry/commons/response-invocation-accepted/metric.be.duration.json +19 -0
- package/detectors/bun_telemetry_test/fixtures/dirty/tests/wagons/commons/features/ingress/unit/dangling.telemetry.test.ts +9 -0
- package/detectors/bun_telemetry_test/fixtures/dirty/tests/wagons/commons/features/ingress/unit/loose.telemetry.test.ts +11 -0
- package/detectors/bun_telemetry_test/fixtures/dirty/tests/wagons/commons/features/ingress/unit/unbound.telemetry.test.ts +10 -0
- package/detectors/planner_telemetry_plan/atdd.implementation.yaml +22 -0
- package/detectors/planner_telemetry_plan/detect.mjs +9 -0
- package/detectors/planner_telemetry_plan/fixtures/clean/plan/commons/E001.yaml +10 -0
- package/detectors/planner_telemetry_plan/fixtures/clean/plan/commons/E002.yaml +7 -0
- package/detectors/planner_telemetry_plan/fixtures/clean/plan/commons/_commons.yaml +6 -0
- package/detectors/planner_telemetry_plan/fixtures/clean/src/wagons/commons/features/ingress/domain/accept-response.ts +8 -0
- package/detectors/planner_telemetry_plan/fixtures/clean/telemetry/commons/response-invocation-accepted/event.be.json +16 -0
- package/detectors/planner_telemetry_plan/fixtures/clean/telemetry/commons/response-invocation-accepted/metric.be.duration.json +19 -0
- package/detectors/planner_telemetry_plan/fixtures/clean/tests/wagons/commons/features/ingress/unit/accept-response.telemetry.test.ts +13 -0
- package/detectors/planner_telemetry_plan/fixtures/dirty/plan/commons/E001.yaml +9 -0
- package/detectors/planner_telemetry_plan/fixtures/dirty/plan/commons/E002.yaml +4 -0
- package/detectors/planner_telemetry_plan/fixtures/dirty/plan/commons/E003.yaml +7 -0
- package/detectors/planner_telemetry_plan/fixtures/dirty/plan/commons/_commons.yaml +6 -0
- package/detectors/planner_telemetry_plan/fixtures/dirty/telemetry/commons/extra.json +1 -0
- package/detectors/planner_telemetry_plan/fixtures/dirty/telemetry/commons/orphan-artifact/event.be.json +14 -0
- package/detectors/planner_telemetry_plan/fixtures/dirty/telemetry/commons/response-invocation-accepted/event.be.json +16 -0
- package/detectors/planner_telemetry_plan/fixtures/dirty/telemetry/commons/response-invocation-accepted/metric.be.duration.json +22 -0
- package/detectors/planner_telemetry_plan/fixtures/dirty/telemetry/commons/response-invocation-accepted/notes.json +1 -0
- package/integrity.json +94 -11
- package/lib/scan.mjs +37 -0
- package/package.json +1 -1
- package/planner-schemas/acceptance.schema.json +70 -1
- package/planner-schemas/telemetry-plan.schema.json +133 -0
- package/relationships.yaml +174 -0
- package/src/enforce.ts +2 -1
- package/src/index.ts +2 -0
- package/src/integrity.ts +25 -9
- package/src/setup.ts +17 -1
- package/src/telemetry-plan.ts +223 -0
- package/src/topology.ts +3 -1
- package/templates/github/atdd-bun.yml +5 -0
package/README.md
CHANGED
|
@@ -54,6 +54,7 @@ registerEnforcementTest({ root: import.meta.dir + "/..", profiles: ["traceabilit
|
|
|
54
54
|
| `traceability` | acceptance → Bun test → source closure: every acceptance tested, every binding and `Tested-By` resolving |
|
|
55
55
|
| `topology` | feature decomposition and the plan, source, test and E2E locations |
|
|
56
56
|
| `planner` | schemas for every plan artifact, graph integrity, the scoped planner rules |
|
|
57
|
+
| `telemetry` | the telemetry tracking plan: item shape, path-mirrored identity and versioning under `telemetry/`, wagon ownership of logical artifacts, the per-acceptance telemetry decision, metric label cardinality, source `Telemetry:` references, raw-string and forbidden-property emission, the vendor-SDK boundary around the TelemetryPort, and telemetry tests that bind the acceptance and item, assert the exact identity on a captured sink, cover every required item, and exercise declared timing semantics |
|
|
57
58
|
| `docs` | the documentation capability, including the generated journey view |
|
|
58
59
|
| `coder`, `tester`, `security`, `architecture`, `metrics`, `runtime` | Bun source and test conventions |
|
|
59
60
|
| `interlocking` | train/interlocking binding, infrastructure and route coverage |
|
|
@@ -76,8 +77,15 @@ profiles: [traceability, planner]
|
|
|
76
77
|
|
|
77
78
|
`all`, the hooks and the generated CI then run only those profiles. Any profile can still be run
|
|
78
79
|
by name (`bun run atdd-bun coder`) to see what remains. An unknown name or an empty list is an
|
|
79
|
-
error, never a silent run of nothing.
|
|
80
|
-
|
|
80
|
+
error, never a silent run of nothing.
|
|
81
|
+
|
|
82
|
+
With no `profiles:` field, every profile runs, but none is governed yet. The first explicit list is
|
|
83
|
+
the adoption that establishes the governed set, so a brownfield repository can declare
|
|
84
|
+
`profiles: [docs]` in an ordinary pull request. From then on, the integrity check reports, against
|
|
85
|
+
the base branch, removing a profile from the list and removing the list itself. The second closes
|
|
86
|
+
the two-step bypass `[docs, security]` → no list → `[docs]`. `init` writes a new `atdd-bun.yaml`
|
|
87
|
+
with every profile listed, so a greenfield repository is governed from its first commit; trim the
|
|
88
|
+
list before that commit to adopt gradually.
|
|
81
89
|
|
|
82
90
|
## Configuration
|
|
83
91
|
|
|
@@ -90,6 +98,7 @@ topology: # default layout; point it at exis
|
|
|
90
98
|
source_root: src/wagons
|
|
91
99
|
test_root: tests/wagons
|
|
92
100
|
e2e_root: e2e
|
|
101
|
+
telemetry_root: telemetry # tracking-plan registry; inert until the tree or a decision exists
|
|
93
102
|
frontend:
|
|
94
103
|
viewports: [375, 768, 1280]
|
|
95
104
|
breakpoints: [480, 768, 1024, 1280]
|
|
@@ -114,7 +123,8 @@ modify the toolkit itself, only the configuration it offers, and enable capabili
|
|
|
114
123
|
- the installed package differs from its published hashes;
|
|
115
124
|
- the dependency is not an npm registry version;
|
|
116
125
|
- a generated file (workflow, skills, instruction block, integrity test) was edited;
|
|
117
|
-
- `atdd-bun.yaml` is looser than on the base branch
|
|
126
|
+
- `atdd-bun.yaml` is looser than on the base branch (after the first explicit `profiles:` list,
|
|
127
|
+
dropping a profile or the list counts).
|
|
118
128
|
|
|
119
129
|
Each finding names its restore command.
|
|
120
130
|
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
schema_version: 1.1.0
|
|
2
|
+
rule_id: coder.bun.telemetry-forbidden-properties
|
|
3
|
+
kind: rule
|
|
4
|
+
status: active
|
|
5
|
+
name: Forbidden properties never reach an emit call
|
|
6
|
+
statement: >-
|
|
7
|
+
The object literal passed to an emit-like call naming a declared tracking-plan item MUST NOT
|
|
8
|
+
carry a property the plan forbids on that item (REQUIRED).
|
|
9
|
+
terms:
|
|
10
|
+
- term_id: forbidden_property
|
|
11
|
+
text: >-
|
|
12
|
+
a name in the item's forbidden_properties list (raw payloads, secrets, prompts): what must
|
|
13
|
+
never leave the process on that item. The plan writes snake_case; code may write camelCase;
|
|
14
|
+
comparison is normalized.
|
|
15
|
+
- term_id: properties_object
|
|
16
|
+
text: >-
|
|
17
|
+
the object literal following the first argument of the emit-like call, on the same statement.
|
|
18
|
+
content:
|
|
19
|
+
summary: >-
|
|
20
|
+
The forbidden list is a privacy and cost promise. It is enforced where the data leaves: the
|
|
21
|
+
emit call itself, against the plan entry the call names.
|
|
22
|
+
normative_text: |
|
|
23
|
+
When an emit-like call's first argument is a declared concrete id, the properties object is
|
|
24
|
+
scanned and every top-level key normalized (separators stripped, case folded) against the
|
|
25
|
+
item's forbidden list. Shorthand properties carry no name of their own and are invisible to
|
|
26
|
+
this scan; nested objects are judged at their own level. Properties the plan merely does not
|
|
27
|
+
declare are not forbidden — undeclared-key drift is the generated contract's concern, not this
|
|
28
|
+
rule's.
|
|
29
|
+
fix_hint: |
|
|
30
|
+
Pass the identifier, not the thing it identifies:
|
|
31
|
+
|
|
32
|
+
telemetry.emit("telemetry:event:be:commons:response-invocation-accepted", {
|
|
33
|
+
response_id: response.id, // the identifier: allowed, planned, high-cardinality-declared
|
|
34
|
+
// raw_payload: response.raw, // forbidden by the plan: never attach it
|
|
35
|
+
});
|
|
36
|
+
exceptions:
|
|
37
|
+
- >-
|
|
38
|
+
Only calls naming a declared item are checked: an id the registry does not hold is the
|
|
39
|
+
raw-string rule's finding, and double-reporting it here would be noise.
|
|
40
|
+
- >-
|
|
41
|
+
Inert until adoption, like every rule in this family.
|
|
42
|
+
metadata:
|
|
43
|
+
aliases:
|
|
44
|
+
- CODER-TELEMETRY-FORBIDDEN-PROPERTIES-001
|
|
45
|
+
severity: 3
|
|
46
|
+
# strict: atdd-bun fails on every finding; it has no advisory mode and no ratchet baseline.
|
|
47
|
+
disposition: strict
|
|
48
|
+
introduced_in: 0.7.0
|
|
49
|
+
implementation:
|
|
50
|
+
type: validator
|
|
51
|
+
ref: bun_telemetry_code
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
schema_version: 1.1.0
|
|
2
|
+
rule_id: coder.bun.telemetry-implementation-binding
|
|
3
|
+
kind: rule
|
|
4
|
+
status: active
|
|
5
|
+
name: Required telemetry is bound to its implementation
|
|
6
|
+
statement: >-
|
|
7
|
+
Every concrete telemetry item an acceptance requires MUST be bound to at least one non-test
|
|
8
|
+
implementation source file by a `// Telemetry:` header (REQUIRED).
|
|
9
|
+
terms:
|
|
10
|
+
- term_id: required_item
|
|
11
|
+
text: >-
|
|
12
|
+
a concrete telemetry URN listed by an acceptance whose telemetry disposition is required.
|
|
13
|
+
- term_id: implementation_binding
|
|
14
|
+
text: >-
|
|
15
|
+
a `// Telemetry:` header naming the item in non-test source — the source-to-telemetry edge
|
|
16
|
+
coder.bun.telemetry-source-binding resolves.
|
|
17
|
+
content:
|
|
18
|
+
summary: >-
|
|
19
|
+
The third leg of the traceability tripod: planned, implemented, tested. This rule closes the
|
|
20
|
+
second leg — a required item no source claims is telemetry the plan believes in and the code
|
|
21
|
+
has never heard of.
|
|
22
|
+
normative_text: |
|
|
23
|
+
Required items are collected from acceptance decisions; implementation bindings from every
|
|
24
|
+
resolved Telemetry: header in non-test source. Their difference is reported at the tracking-plan
|
|
25
|
+
item's own file, because that is where the remedy starts: either bind the emitting source, or
|
|
26
|
+
stop requiring what nothing emits. An unresolvable required URN is the acceptance-decision
|
|
27
|
+
rule's finding and is not double-reported here.
|
|
28
|
+
fix_hint: |
|
|
29
|
+
Bind the emitting source, or drop the requirement:
|
|
30
|
+
|
|
31
|
+
// src/.../accept-response.ts
|
|
32
|
+
// Telemetry: telemetry:metric:be:commons:response-invocation-accepted:duration
|
|
33
|
+
exceptions:
|
|
34
|
+
- >-
|
|
35
|
+
Inert until adoption, like every rule in this family.
|
|
36
|
+
metadata:
|
|
37
|
+
aliases:
|
|
38
|
+
- CODER-TELEMETRY-IMPLEMENTATION-BINDING-001
|
|
39
|
+
severity: 2
|
|
40
|
+
# strict: atdd-bun fails on every finding; it has no advisory mode and no ratchet baseline.
|
|
41
|
+
disposition: strict
|
|
42
|
+
introduced_in: 0.7.0
|
|
43
|
+
implementation:
|
|
44
|
+
type: validator
|
|
45
|
+
ref: bun_telemetry_code
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
schema_version: 1.1.0
|
|
2
|
+
rule_id: coder.bun.telemetry-raw-string-emit
|
|
3
|
+
kind: rule
|
|
4
|
+
status: active
|
|
5
|
+
name: No undeclared raw-string telemetry names
|
|
6
|
+
statement: >-
|
|
7
|
+
An emit-like call (emit, emitted, track, capture, record, logEvent, emitEvent, sendEvent) whose
|
|
8
|
+
first argument is a string literal naming an event MUST name an item declared in the tracking
|
|
9
|
+
plan (REQUIRED).
|
|
10
|
+
terms:
|
|
11
|
+
- term_id: emit_like_call
|
|
12
|
+
text: >-
|
|
13
|
+
a call to the emit vocabulary, as function or method, with a string literal first argument.
|
|
14
|
+
Calls with computed first arguments (variables, template literals, contract constants) are
|
|
15
|
+
invisible to this check by design.
|
|
16
|
+
- term_id: event_shaped_string
|
|
17
|
+
text: >-
|
|
18
|
+
a string that looks like a telemetry event name: a telemetry: URN, snake_case, camelCase with
|
|
19
|
+
an internal case shift, or a Title Case analytics name. Single lowercase words (log levels,
|
|
20
|
+
keys) are not event names.
|
|
21
|
+
content:
|
|
22
|
+
summary: >-
|
|
23
|
+
Undeclared event strings are how tracking plans rot: the string compiles, the dashboard never
|
|
24
|
+
fills, and nobody owns the difference. The registry is the list of names that may be emitted.
|
|
25
|
+
normative_text: |
|
|
26
|
+
When an emit-like call passes an event-shaped string, that string must be a declared concrete
|
|
27
|
+
telemetry id. A declared id passed as a raw string passes today; once generated contracts ship,
|
|
28
|
+
emitting even a declared id by string is the drift the contract exists to prevent, and this
|
|
29
|
+
rule tightens with it. This check does not attempt to prove transaction ordering or any other
|
|
30
|
+
runtime property — it is a name-resolution check.
|
|
31
|
+
fix_hint: |
|
|
32
|
+
Declare the item, then emit through the plan:
|
|
33
|
+
|
|
34
|
+
telemetry/commons/response-invocation-accepted/event.be.json # declares the id
|
|
35
|
+
telemetry.emit("telemetry:event:be:commons:response-invocation-accepted", { ... });
|
|
36
|
+
exceptions:
|
|
37
|
+
- >-
|
|
38
|
+
Test files are excluded: assertion code legitimately names events it is proving.
|
|
39
|
+
- >-
|
|
40
|
+
Strings that are not event-shaped (log levels like "info", single-word keys) never trigger the
|
|
41
|
+
check; the emit vocabulary with a non-event string is some other concern.
|
|
42
|
+
- >-
|
|
43
|
+
Inert until adoption, like every rule in this family.
|
|
44
|
+
metadata:
|
|
45
|
+
aliases:
|
|
46
|
+
- CODER-TELEMETRY-RAW-STRING-EMIT-001
|
|
47
|
+
severity: 3
|
|
48
|
+
# strict: atdd-bun fails on every finding; it has no advisory mode and no ratchet baseline.
|
|
49
|
+
disposition: strict
|
|
50
|
+
introduced_in: 0.7.0
|
|
51
|
+
implementation:
|
|
52
|
+
type: validator
|
|
53
|
+
ref: bun_telemetry_code
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
schema_version: 1.1.0
|
|
2
|
+
rule_id: coder.bun.telemetry-source-binding
|
|
3
|
+
kind: rule
|
|
4
|
+
status: active
|
|
5
|
+
name: Source Telemetry references resolve into the tracking plan
|
|
6
|
+
statement: >-
|
|
7
|
+
A `// Telemetry:` reference in implementation source names a concrete telemetry URN that resolves
|
|
8
|
+
to a tracking-plan item under the telemetry root (REQUIRED).
|
|
9
|
+
terms:
|
|
10
|
+
- term_id: telemetry_reference
|
|
11
|
+
text: >-
|
|
12
|
+
a line comment of the form `// Telemetry: telemetry:{kind}:{plane}:{theme}:{artifact}[:{measure}]`
|
|
13
|
+
in a non-test source file, binding the file to the concrete item it emits.
|
|
14
|
+
- term_id: tracking_plan_item
|
|
15
|
+
text: >-
|
|
16
|
+
a JSON registry entry under telemetry/<theme>/<artifact>/ whose id is the referenced URN.
|
|
17
|
+
content:
|
|
18
|
+
summary: >-
|
|
19
|
+
The Telemetry: header is the source-to-telemetry traceability edge. Like Tested-By, it is a
|
|
20
|
+
promise the package can check: the URN must be well-formed and the registry must hold it.
|
|
21
|
+
normative_text: |
|
|
22
|
+
Implementation source that emits telemetry says so, by name, in a header comment. Two failures
|
|
23
|
+
are reported: a reference that is not a concrete telemetry URN (grammar), and a reference that
|
|
24
|
+
is grammatical but names no tracking-plan item (resolution). A header inside a string literal
|
|
25
|
+
is not a header. Test files are implementation's mirror, not implementation: they are excluded,
|
|
26
|
+
because a telemetry test legitimately names items while asserting them.
|
|
27
|
+
fix_hint: |
|
|
28
|
+
Bind the file to the item it emits, and keep the binding current when the plan renames:
|
|
29
|
+
|
|
30
|
+
// Telemetry: telemetry:event:be:commons:response-invocation-accepted
|
|
31
|
+
export function acceptResponse(response, telemetry) { ... }
|
|
32
|
+
exceptions:
|
|
33
|
+
- >-
|
|
34
|
+
The capability is inert until adopted (no telemetry root and no acceptance telemetry declaration
|
|
35
|
+
anywhere): an unadopting repository emits nothing, whichever profiles it runs.
|
|
36
|
+
- >-
|
|
37
|
+
The header is a line comment in source syntax (`//`). Block comments and markup attributes are
|
|
38
|
+
not parsed in this realization.
|
|
39
|
+
metadata:
|
|
40
|
+
aliases:
|
|
41
|
+
- CODER-TELEMETRY-SOURCE-BINDING-001
|
|
42
|
+
severity: 2
|
|
43
|
+
# strict: atdd-bun fails on every finding; it has no advisory mode and no ratchet baseline.
|
|
44
|
+
disposition: strict
|
|
45
|
+
introduced_in: 0.7.0
|
|
46
|
+
implementation:
|
|
47
|
+
type: validator
|
|
48
|
+
ref: bun_telemetry_code
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
schema_version: 1.1.0
|
|
2
|
+
rule_id: coder.bun.telemetry-vendor-sdk
|
|
3
|
+
kind: rule
|
|
4
|
+
status: active
|
|
5
|
+
name: Telemetry vendor SDKs stay in infrastructure adapters
|
|
6
|
+
statement: >-
|
|
7
|
+
A layered source file outside the integration layer and infrastructure directories MUST NOT
|
|
8
|
+
import a telemetry vendor SDK (REQUIRED).
|
|
9
|
+
terms:
|
|
10
|
+
- term_id: vendor_sdk
|
|
11
|
+
text: >-
|
|
12
|
+
an exporter or agent package: @opentelemetry/*, @sentry/*, @datadog/*, dd-trace, newrelic,
|
|
13
|
+
segment (bare or @segment/*), mixpanel (bare or @mixpanel/*), amplitude (bare or
|
|
14
|
+
@amplitude/*), @posthog/*, @statsig/*, @braze/*, @heap/*, @rudderstack/*.
|
|
15
|
+
- term_id: adapter_location
|
|
16
|
+
text: >-
|
|
17
|
+
the integration layer, or an infrastructure/ directory — the outer ring where exporters are
|
|
18
|
+
wired to the neutral TelemetryPort.
|
|
19
|
+
content:
|
|
20
|
+
summary: >-
|
|
21
|
+
Core depends only on a TelemetryPort. The moment a domain module imports an exporter, every
|
|
22
|
+
wagon behind it inherits the vendor, and the plan's exporter-neutrality promise is gone.
|
|
23
|
+
normative_text: |
|
|
24
|
+
Files carrying a layer segment (domain, application, presentation, integration, assembly) may
|
|
25
|
+
import a vendor SDK only when the layer is integration or the path sits under infrastructure/.
|
|
26
|
+
Type-only imports count: the coupling is real even when erased. Unlayered entrypoints (a
|
|
27
|
+
composition root, a script) are outside this rule — they wire adapters, they do not become one.
|
|
28
|
+
fix_hint: |
|
|
29
|
+
Depend on the port; adapt at the edge:
|
|
30
|
+
|
|
31
|
+
// domain/accept-response.ts — no SDK, only the port parameter
|
|
32
|
+
export function acceptResponse(response, telemetry: TelemetryPort) { telemetry.emit(...); }
|
|
33
|
+
|
|
34
|
+
// infrastructure/otel-adapter.ts — the SDK lives here and only here
|
|
35
|
+
import { metrics } from "@opentelemetry/api";
|
|
36
|
+
exceptions:
|
|
37
|
+
- >-
|
|
38
|
+
The integration layer and infrastructure/ directories are exempt by design: that is where the
|
|
39
|
+
adapter belongs.
|
|
40
|
+
- >-
|
|
41
|
+
Inert until adoption, like every rule in this family.
|
|
42
|
+
metadata:
|
|
43
|
+
aliases:
|
|
44
|
+
- CODER-TELEMETRY-VENDOR-SDK-001
|
|
45
|
+
severity: 2
|
|
46
|
+
# strict: atdd-bun fails on every finding; it has no advisory mode and no ratchet baseline.
|
|
47
|
+
disposition: strict
|
|
48
|
+
introduced_in: 0.7.0
|
|
49
|
+
implementation:
|
|
50
|
+
type: validator
|
|
51
|
+
ref: bun_telemetry_code
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
schema_version: 1.1.0
|
|
2
|
+
rule_id: planner.telemetry.acceptance-decision
|
|
3
|
+
kind: rule
|
|
4
|
+
status: active
|
|
5
|
+
name: Every acceptance makes an explicit telemetry decision
|
|
6
|
+
statement: >-
|
|
7
|
+
Every acceptance declares telemetry with disposition required (naming at least one concrete
|
|
8
|
+
telemetry URN that resolves to a tracking-plan entry) or disposition not-applicable (with a
|
|
9
|
+
rationale), and every tracking-plan item's acceptance references resolve to declared acceptances
|
|
10
|
+
(REQUIRED).
|
|
11
|
+
terms:
|
|
12
|
+
- term_id: decision
|
|
13
|
+
text: >-
|
|
14
|
+
the acceptance's telemetry block: disposition plus, for required, concrete item lists
|
|
15
|
+
(events, metrics, traces, logs), or, for not-applicable, a rationale of at least 20 characters.
|
|
16
|
+
- term_id: required_item
|
|
17
|
+
text: >-
|
|
18
|
+
a concrete telemetry URN an acceptance demands be observed emitted. It must exist as a
|
|
19
|
+
tracking-plan item under the telemetry root.
|
|
20
|
+
content:
|
|
21
|
+
summary: >-
|
|
22
|
+
The decision removes the false choice between "test every debug log" and "have no observability
|
|
23
|
+
requirement". Not-applicable is a considered answer, not the absence of one.
|
|
24
|
+
normative_text: |
|
|
25
|
+
Once the capability is adopted, silence is not a disposition. An acceptance either requires
|
|
26
|
+
telemetry — and then each URN it lists must be a well-formed concrete URN present in the
|
|
27
|
+
tracking plan, or the requirement is unplannable — or it declares not-applicable with a
|
|
28
|
+
rationale long enough to be an answer (20 characters minimum). In the other direction, a
|
|
29
|
+
tracking-plan item that names an acceptance nothing declares is a dangling traceability link.
|
|
30
|
+
Resolution is checked in both directions; the lists are not required to be mirror images,
|
|
31
|
+
because an item may serve acceptances beyond those that first required it.
|
|
32
|
+
fix_hint: |
|
|
33
|
+
Decide, on every acceptance:
|
|
34
|
+
|
|
35
|
+
telemetry:
|
|
36
|
+
disposition: required
|
|
37
|
+
events: [telemetry:event:be:commons:response-invocation-accepted]
|
|
38
|
+
|
|
39
|
+
telemetry:
|
|
40
|
+
disposition: not-applicable
|
|
41
|
+
rationale: No externally useful observable outcome beyond the tested return value.
|
|
42
|
+
exceptions:
|
|
43
|
+
- >-
|
|
44
|
+
Diagnostic logs and internal spans are not automatically telemetry obligations. The decision is
|
|
45
|
+
per acceptance; nothing here requires a dedicated test for every debug-oriented record.
|
|
46
|
+
- >-
|
|
47
|
+
Inert until adoption: with no telemetry root and no acceptance telemetry declaration, this rule
|
|
48
|
+
emits nothing (see planner.telemetry.tracking-plan-schema).
|
|
49
|
+
metadata:
|
|
50
|
+
aliases:
|
|
51
|
+
- TELEMETRY-ACCEPTANCE-DECISION-001
|
|
52
|
+
severity: 2
|
|
53
|
+
# strict: atdd-bun fails on every finding; it has no advisory mode and no ratchet baseline.
|
|
54
|
+
disposition: strict
|
|
55
|
+
introduced_in: 0.7.0
|
|
56
|
+
implementation:
|
|
57
|
+
type: validator
|
|
58
|
+
ref: planner_telemetry_plan
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
schema_version: 1.1.0
|
|
2
|
+
rule_id: planner.telemetry.logical-ownership
|
|
3
|
+
kind: rule
|
|
4
|
+
status: active
|
|
5
|
+
name: Concrete telemetry resolves to exactly one wagon-owned logical artifact
|
|
6
|
+
statement: >-
|
|
7
|
+
Every concrete tracking-plan item's logical artifact is produced by exactly one wagon's
|
|
8
|
+
produce[] telemetry declaration, and the item's owner names that wagon (REQUIRED).
|
|
9
|
+
terms:
|
|
10
|
+
- term_id: ownership_declaration
|
|
11
|
+
text: >-
|
|
12
|
+
a wagon produce[] entry whose telemetry field (string or list) names the logical artifact
|
|
13
|
+
URN telemetry:{theme}:{artifact}. Ownership lives in the plan, not in the registry.
|
|
14
|
+
- term_id: owner
|
|
15
|
+
text: >-
|
|
16
|
+
the tracking-plan item field naming the wagon slug accountable for the artifact. It must equal
|
|
17
|
+
the wagon whose produce[] declares the logical artifact.
|
|
18
|
+
content:
|
|
19
|
+
summary: >-
|
|
20
|
+
A logical telemetry artifact with two producers is a coincidence waiting to diverge; with none,
|
|
21
|
+
it is emitted by code no plan stands behind. Both are plan defects, caught at the item.
|
|
22
|
+
normative_text: |
|
|
23
|
+
The registry does not grant ownership; it resolves against ownership the plan already declares.
|
|
24
|
+
For each item, the logical artifact must appear in exactly one wagon's produce[] telemetry, and
|
|
25
|
+
the item's owner field must equal that wagon's slug. Zero owners means no wagon has stood behind
|
|
26
|
+
the observable outcome; more than one means the emission contract has two authors with no
|
|
27
|
+
arbiter.
|
|
28
|
+
fix_hint: |
|
|
29
|
+
Declare the logical artifact on the producing wagon, and name that wagon as owner:
|
|
30
|
+
|
|
31
|
+
# plan/commons/_commons.yaml
|
|
32
|
+
produce:
|
|
33
|
+
- name: commons:response-invocation
|
|
34
|
+
contract: null
|
|
35
|
+
telemetry: telemetry:commons:response-invocation-accepted
|
|
36
|
+
exceptions:
|
|
37
|
+
- >-
|
|
38
|
+
Duplicate producers at the wagon level are also reported by planner.wagon.telemetry-filesystem
|
|
39
|
+
under the planner profile; this rule reports the same ambiguity at the item level under the
|
|
40
|
+
telemetry profile, so an adopting repository sees it whichever profile it runs.
|
|
41
|
+
metadata:
|
|
42
|
+
aliases:
|
|
43
|
+
- TELEMETRY-LOGICAL-OWNERSHIP-001
|
|
44
|
+
severity: 2
|
|
45
|
+
# strict: atdd-bun fails on every finding; it has no advisory mode and no ratchet baseline.
|
|
46
|
+
disposition: strict
|
|
47
|
+
introduced_in: 0.7.0
|
|
48
|
+
implementation:
|
|
49
|
+
type: validator
|
|
50
|
+
ref: planner_telemetry_plan
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
schema_version: 1.1.0
|
|
2
|
+
rule_id: planner.telemetry.metric-cardinality
|
|
3
|
+
kind: rule
|
|
4
|
+
status: active
|
|
5
|
+
name: High-cardinality identifiers are forbidden as metric labels
|
|
6
|
+
statement: >-
|
|
7
|
+
Metric tracking-plan items declare only low- or medium-cardinality dimensions, and no dimension
|
|
8
|
+
names a property declared cardinality high (REQUIRED).
|
|
9
|
+
terms:
|
|
10
|
+
- term_id: dimension
|
|
11
|
+
text: >-
|
|
12
|
+
a metric label: an entry of the metric item's dimensions list, with a name and a declared
|
|
13
|
+
cardinality (low, medium or high).
|
|
14
|
+
- term_id: high_cardinality_identifier
|
|
15
|
+
text: >-
|
|
16
|
+
a property whose distinct-value volume is unbounded or near-unbounded (request ids, user ids,
|
|
17
|
+
session tokens). Legal in event, log and trace properties where the plan justifies it; never as
|
|
18
|
+
a metric label.
|
|
19
|
+
content:
|
|
20
|
+
summary: >-
|
|
21
|
+
A high-cardinality metric label is a backend outage with a YAML file attached: every distinct
|
|
22
|
+
value becomes a new time series. The plan is where that mistake is cheapest to catch.
|
|
23
|
+
normative_text: |
|
|
24
|
+
Metric dimensions must declare cardinality, and high is rejected — both when the dimension
|
|
25
|
+
itself says high and when the dimension names a property the item declares cardinality high.
|
|
26
|
+
The identifier still belongs in the plan: carry it as an event, log or trace property, where
|
|
27
|
+
cardinality is the point rather than a liability.
|
|
28
|
+
fix_hint: |
|
|
29
|
+
Keep the identifier, change the signal:
|
|
30
|
+
|
|
31
|
+
# telemetry/commons/response-invocation-accepted/metric.be.duration.json
|
|
32
|
+
"dimensions": [{ "name": "outcome", "cardinality": "low" }]
|
|
33
|
+
# response_id moves to the sibling event's properties, declared cardinality high.
|
|
34
|
+
exceptions:
|
|
35
|
+
- >-
|
|
36
|
+
Event, log and trace properties may declare cardinality high where justified; this rule judges
|
|
37
|
+
metric dimensions only.
|
|
38
|
+
metadata:
|
|
39
|
+
aliases:
|
|
40
|
+
- TELEMETRY-METRIC-CARDINALITY-001
|
|
41
|
+
severity: 3
|
|
42
|
+
# strict: atdd-bun fails on every finding; it has no advisory mode and no ratchet baseline.
|
|
43
|
+
disposition: strict
|
|
44
|
+
introduced_in: 0.7.0
|
|
45
|
+
implementation:
|
|
46
|
+
type: validator
|
|
47
|
+
ref: planner_telemetry_plan
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
schema_version: 1.1.0
|
|
2
|
+
rule_id: planner.telemetry.tracking-plan-schema
|
|
3
|
+
kind: rule
|
|
4
|
+
status: active
|
|
5
|
+
name: Tracking-plan items are versioned, path-mirrored registry entries
|
|
6
|
+
statement: >-
|
|
7
|
+
Every JSON file under the telemetry root is one concrete tracking-plan item at
|
|
8
|
+
`telemetry/<theme>/<artifact>/{event|trace|metric|log}.<plane>[.<measure>].json`, shape-valid
|
|
9
|
+
against telemetry-plan.schema.json, with its id and logical artifact mirroring its path, a SemVer
|
|
10
|
+
version, and no concrete id declared twice (REQUIRED).
|
|
11
|
+
terms:
|
|
12
|
+
- term_id: tracking_plan_item
|
|
13
|
+
text: >-
|
|
14
|
+
one JSON file in the telemetry tree declaring a concrete observation: id, version,
|
|
15
|
+
logical_artifact, kind, plane, owner, purpose, acceptances, properties, required, and
|
|
16
|
+
optionally forbidden_properties and (for metrics) dimensions.
|
|
17
|
+
- term_id: concrete_item
|
|
18
|
+
text: >-
|
|
19
|
+
a telemetry URN with kind and plane: telemetry:{kind}:{plane}:{theme}:{artifact}[:{measure}].
|
|
20
|
+
Metric items carry a measure segment; event, trace and log items never do.
|
|
21
|
+
- term_id: logical_artifact
|
|
22
|
+
text: >-
|
|
23
|
+
the stable architectural identity of an observable outcome, telemetry:{theme}:{artifact}. Not
|
|
24
|
+
an exporter event; the concrete items under it are.
|
|
25
|
+
- term_id: telemetry_root
|
|
26
|
+
text: >-
|
|
27
|
+
the versioned tracking-plan source of truth, `telemetry/` by default, configurable as
|
|
28
|
+
topology.telemetry_root in atdd-bun.yaml.
|
|
29
|
+
content:
|
|
30
|
+
summary: >-
|
|
31
|
+
The telemetry tree is a registry, not a suggestion. Each file is schema-validated, and the
|
|
32
|
+
file's place in the tree is the authority for its identity: a renamed file or a hand-edited id
|
|
33
|
+
cannot drift apart silently.
|
|
34
|
+
normative_text: |
|
|
35
|
+
Local shape is the JSON Schema's job (telemetry-plan.schema.json): required identity fields, URN
|
|
36
|
+
grammar, SemVer core version, property declarations with classification and cardinality, and
|
|
37
|
+
metric dimensions that declare cardinality. Everything the Schema cannot see is this rule's
|
|
38
|
+
cross-artifact half: the file name's kind, plane and measure must match the declared fields; the
|
|
39
|
+
id must equal telemetry:{kind}:{plane}:{theme}:{artifact}[:{measure}] derived from the path; the
|
|
40
|
+
logical artifact must equal telemetry:{theme}:{artifact} from the path; every name in `required`
|
|
41
|
+
must be declared in `properties`; and no two files may declare the same concrete id.
|
|
42
|
+
fix_hint: |
|
|
43
|
+
Name the file for what it is and let the identity follow the path:
|
|
44
|
+
|
|
45
|
+
telemetry/commons/response-invocation-accepted/event.be.json
|
|
46
|
+
{
|
|
47
|
+
"id": "telemetry:event:be:commons:response-invocation-accepted",
|
|
48
|
+
"version": "1.0.0",
|
|
49
|
+
"logical_artifact": "telemetry:commons:response-invocation-accepted",
|
|
50
|
+
"kind": "event", "plane": "be", "owner": "commons",
|
|
51
|
+
"purpose": "Records that a response invocation passed acceptance so ingress health can be audited.",
|
|
52
|
+
"acceptances": ["acc:commons:E001-UNIT-001"],
|
|
53
|
+
"properties": { "response_id": { "type": "string", "classification": "internal", "cardinality": "high" } },
|
|
54
|
+
"required": ["response_id"],
|
|
55
|
+
"forbidden_properties": ["raw_payload", "secret", "prompt"]
|
|
56
|
+
}
|
|
57
|
+
exceptions:
|
|
58
|
+
- >-
|
|
59
|
+
The capability is inert until adopted. With no telemetry root and no acceptance telemetry
|
|
60
|
+
declaration anywhere, this rule emits nothing: upgrading the package must not fail a repository
|
|
61
|
+
that has not opted in. Adoption is a positive act — creating the tree, or making the first
|
|
62
|
+
acceptance decision.
|
|
63
|
+
- >-
|
|
64
|
+
The tree holds only tracking-plan items. Free-form JSON (notes, indexes, generated bundles)
|
|
65
|
+
does not belong under the telemetry root; every .json file is judged as an item.
|
|
66
|
+
metadata:
|
|
67
|
+
aliases:
|
|
68
|
+
- TELEMETRY-PLAN-SCHEMA-001
|
|
69
|
+
severity: 2
|
|
70
|
+
# strict: atdd-bun fails on every finding; it has no advisory mode and no ratchet baseline.
|
|
71
|
+
disposition: strict
|
|
72
|
+
introduced_in: 0.7.0
|
|
73
|
+
implementation:
|
|
74
|
+
type: validator
|
|
75
|
+
ref: planner_telemetry_plan
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
schema_version: 1.1.0
|
|
2
|
+
rule_id: tester.bun.telemetry-captured-sink
|
|
3
|
+
kind: rule
|
|
4
|
+
status: active
|
|
5
|
+
name: Telemetry tests assert on a captured sink
|
|
6
|
+
statement: >-
|
|
7
|
+
A telemetry test contains an assertion on the emission itself — `toHaveBeenCalled[With|Times]`, or
|
|
8
|
+
an expectation on `.emit` / `.emitted` / `.capture` / `.track` / `.record` (REQUIRED).
|
|
9
|
+
terms:
|
|
10
|
+
- term_id: captured_sink
|
|
11
|
+
text: >-
|
|
12
|
+
the spy, mock or captured array the emitter writes to: the thing whose CONTENT is the emission.
|
|
13
|
+
A return value is not a sink.
|
|
14
|
+
- term_id: telemetry_test
|
|
15
|
+
text: >-
|
|
16
|
+
a test file with a Telemetry: header, a TELEMETRY/EVENT/METRIC URN kind segment, or
|
|
17
|
+
*.telemetry.test.* colocation.
|
|
18
|
+
content:
|
|
19
|
+
summary: >-
|
|
20
|
+
Same obligation as tester.bun.telemetry-emit, carried into the telemetry profile and joined
|
|
21
|
+
with the exact-identity requirement: the event is the point, and only the sink saw it fire.
|
|
22
|
+
normative_text: |
|
|
23
|
+
A telemetry test that checks a return value has proven the function ran. It has not proven the
|
|
24
|
+
item fired — and dashboards, alerts and downstream analytics are built on the emission. The
|
|
25
|
+
predicate is deliberately the emission-assertion vocabulary, not a data-flow analysis: it names
|
|
26
|
+
what a test must contain, not what the runtime did.
|
|
27
|
+
fix_hint: |
|
|
28
|
+
Capture the emitter, assert on it:
|
|
29
|
+
|
|
30
|
+
const emit = mock(() => {});
|
|
31
|
+
acceptResponse({ id: "r-1" }, { emit });
|
|
32
|
+
expect(emit).toHaveBeenCalledWith("telemetry:event:be:commons:response-invocation-accepted", { response_id: "r-1" });
|
|
33
|
+
exceptions:
|
|
34
|
+
- >-
|
|
35
|
+
Only telemetry-identified tests are scanned; the tester profile's own rule governs the rest.
|
|
36
|
+
- >-
|
|
37
|
+
Inert until adoption, like every rule in this family.
|
|
38
|
+
metadata:
|
|
39
|
+
aliases:
|
|
40
|
+
- TESTER-TELEMETRY-CAPTURED-SINK-001
|
|
41
|
+
severity: 3
|
|
42
|
+
# strict: atdd-bun fails on every finding; it has no advisory mode and no ratchet baseline.
|
|
43
|
+
disposition: strict
|
|
44
|
+
introduced_in: 0.7.0
|
|
45
|
+
implementation:
|
|
46
|
+
type: validator
|
|
47
|
+
ref: bun_telemetry_test
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
schema_version: 1.1.0
|
|
2
|
+
rule_id: tester.bun.telemetry-identity-assertion
|
|
3
|
+
kind: rule
|
|
4
|
+
status: active
|
|
5
|
+
name: Telemetry tests assert the exact item identity
|
|
6
|
+
statement: >-
|
|
7
|
+
Every concrete telemetry URN a telemetry test claims in its `// Telemetry:` header appears in
|
|
8
|
+
the test's code as an assertion string; a telemetry test with no header asserts at least one
|
|
9
|
+
concrete telemetry URN (REQUIRED).
|
|
10
|
+
terms:
|
|
11
|
+
- term_id: exact_identity
|
|
12
|
+
text: >-
|
|
13
|
+
the concrete telemetry URN, verbatim, inside a string literal of the test. Not a prefix, not a
|
|
14
|
+
captured-anything matcher, not a comment.
|
|
15
|
+
content:
|
|
16
|
+
summary: >-
|
|
17
|
+
A test that mocks an emitter and asserts "called with anything" proves emission happened, not
|
|
18
|
+
that the planned item is the one that fired. Renames and copy-paste drift hide exactly there.
|
|
19
|
+
normative_text: |
|
|
20
|
+
The claimed URNs are the test's Telemetry: headers; each must appear in the comment-masked
|
|
21
|
+
source as a quoted string, so that the assertion and the plan cannot silently diverge. A
|
|
22
|
+
telemetry test identified only by URN segment or colocation must carry at least one concrete
|
|
23
|
+
telemetry: URN in code. When generated contracts ship, the contract identifier satisfies this
|
|
24
|
+
the same way.
|
|
25
|
+
fix_hint: |
|
|
26
|
+
Name the item in the assertion itself:
|
|
27
|
+
|
|
28
|
+
expect(emit).toHaveBeenCalledWith("telemetry:event:be:commons:response-invocation-accepted", { response_id: "r-1" });
|
|
29
|
+
exceptions:
|
|
30
|
+
- >-
|
|
31
|
+
Comments do not assert: a URN that appears only in the header or a comment does not satisfy
|
|
32
|
+
this rule.
|
|
33
|
+
- >-
|
|
34
|
+
Inert until adoption, like every rule in this family.
|
|
35
|
+
metadata:
|
|
36
|
+
aliases:
|
|
37
|
+
- TESTER-TELEMETRY-IDENTITY-ASSERTION-001
|
|
38
|
+
severity: 3
|
|
39
|
+
# strict: atdd-bun fails on every finding; it has no advisory mode and no ratchet baseline.
|
|
40
|
+
disposition: strict
|
|
41
|
+
introduced_in: 0.7.0
|
|
42
|
+
implementation:
|
|
43
|
+
type: validator
|
|
44
|
+
ref: bun_telemetry_test
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
schema_version: 1.1.0
|
|
2
|
+
rule_id: tester.bun.telemetry-required-item-coverage
|
|
3
|
+
kind: rule
|
|
4
|
+
status: active
|
|
5
|
+
name: Every required telemetry item has a telemetry test
|
|
6
|
+
statement: >-
|
|
7
|
+
Every concrete telemetry item an acceptance requires is bound by at least one test file's
|
|
8
|
+
`// Telemetry:` header (REQUIRED).
|
|
9
|
+
terms:
|
|
10
|
+
- term_id: required_item
|
|
11
|
+
text: >-
|
|
12
|
+
a concrete telemetry URN listed by an acceptance whose telemetry disposition is required and
|
|
13
|
+
that exists in the tracking plan.
|
|
14
|
+
content:
|
|
15
|
+
summary: >-
|
|
16
|
+
The evidence leg of the traceability tripod: planned, implemented, tested. The coder rule
|
|
17
|
+
binds the implementation; this binds the proof. A required item no test covers is a plan
|
|
18
|
+
nobody can rely on.
|
|
19
|
+
normative_text: |
|
|
20
|
+
Required items are collected from acceptance decisions; test bindings from every Telemetry:
|
|
21
|
+
header in test files. Their difference is reported at the tracking-plan item's own file.
|
|
22
|
+
Unresolvable required URNs belong to the acceptance-decision rule and are not double-reported.
|
|
23
|
+
fix_hint: |
|
|
24
|
+
Give the item its proof:
|
|
25
|
+
|
|
26
|
+
// tests/.../accept-response.telemetry.test.ts
|
|
27
|
+
// Acceptance: acc:commons:E001-UNIT-001
|
|
28
|
+
// Telemetry: telemetry:metric:be:commons:response-invocation-accepted:duration
|
|
29
|
+
exceptions:
|
|
30
|
+
- >-
|
|
31
|
+
Diagnostic logs and internal spans an acceptance does not require need no dedicated test —
|
|
32
|
+
only required items are covered by this closure.
|
|
33
|
+
- >-
|
|
34
|
+
Inert until adoption, like every rule in this family.
|
|
35
|
+
metadata:
|
|
36
|
+
aliases:
|
|
37
|
+
- TESTER-TELEMETRY-REQUIRED-ITEM-COVERAGE-001
|
|
38
|
+
severity: 2
|
|
39
|
+
# strict: atdd-bun fails on every finding; it has no advisory mode and no ratchet baseline.
|
|
40
|
+
disposition: strict
|
|
41
|
+
introduced_in: 0.7.0
|
|
42
|
+
implementation:
|
|
43
|
+
type: validator
|
|
44
|
+
ref: bun_telemetry_test
|