docs(go.d): add V1-to-V2 parity-manifest recipe and V2-collector patterns (#22656)
Ilya Mashchenko committed
Jun 8, 2026 at 13:29 UTC
a5c633dd02ec2de9897f7f2f08fd354ffa5a9685
2 files changed
+44
.agents/skills/project-writing-go-modules-framework-v2/SKILL.md
+13
@@ -78,6 +78,19 @@ source files for evidence.
78
gauges.
79
- Put multipliers, divisors, hidden flags, and float formatting in the chart
80
template, not ad hoc chart-emission code.
81
+- `metrix` registers a descriptor per metric NAME permanently (no unregister), so
82
+ re-registering a name with a changed kind, summary quantile set, or histogram
83
+ bounds PANICS. When a name's contract can drift across cycles, keep the per-name
84
+ handle for the job lifetime and SKIP a drifted series instead of re-registering.
85
+- To reproduce a V1 chart context in a migration, inject `context_namespace` (the
86
+ fixed prefix, or `prefix.<app>` per job) so autogen rebuilds `prefix.<metric>` /
87
+ `prefix.<app>.<metric>` without hand-built chart IDs.
88
+- Skip empty distributions -- e.g. a summary whose every quantile is NaN -- so a
89
+ chart waits for real data, matching how scalar NaN values are already skipped.
90
+- For dynamic surfaces whose label sets churn, `metrix`'s `Vec` handle cache is
91
+ unbounded; cache per-series instruments yourself and evict handles unseen for N
92
+ cycles to stay bounded. Prefer a framework fix if the need is general
93
+ (Decision Discipline).
94
95
## Compatibility Rules
96
src/go/plugin/go.d/docs/migrate-v1-to-v2.md
+31
@@ -351,6 +351,37 @@ variable-equivalent design, or approved alert change.
351
Prefer table-driven tests using `map[string]struct{}` keyed by case name when
352
cases share setup and assertion shape.
353
354
+### Parity manifest recipe
355
+
356
+When chart-identity parity needs the compiled fields above and no shared helper
357
+observes them, this is a concrete form of that "manual comparison recipe": prove
358
+context/dimension/value parity by rendering BOTH collectors into one manifest
359
+shape, without depending on chart-ID string equality.
360
+
361
+1. Freeze the V1 output as a golden manifest. For representative fixtures, run
362
+ the V1 `Collect()` + `Charts()` and serialize, per chart: context, type,
363
+ family, units, priority, and per dimension the name, algorithm, and de-scaled
364
+ value (the V1 `map[string]int64` value divided by the dimension `Div`). Commit
365
+ the goldens under `testdata/`.
366
+2. Render the V2 path into the same shape. Load the collector's LIVE
367
+ `ChartTemplateYAML()` into a real `chartengine`, run a cycle through the real
368
+ `Collect()` and `metrix` store, plan against the store, and read the plan's
369
+ create/update actions into the same per-chart structure.
370
+3. Compare structurally with a float tolerance. V1 truncates `value*Div` to
371
+ `int64` while V2 stores the true float, so compare values within a tolerance
372
+ (for example `1e-3`), not for exact equality. Assert that context, family,
373
+ units, dimension names, and dimension algorithms match.
374
+
375
+Compare chart IDs too when the migration preserves them (the default). Omit only
376
+chart-ID equality when the user approved a breaking chart-ID change -- then the
377
+preserved contract is the context, and chart-ID-keyed alert examples in
378
+`src/health/REFERENCE.md` must be updated. A gap (NaN or absent value) MUST fail
379
+the comparison loudly; never silently map it to 0.
380
+
381
+The render MUST go through the collector's LIVE `ChartTemplateYAML()` and store,
382
+not a separately rebuilt template -- a test that rebuilds the template can pass
383
+even when the shipped `ChartTemplateYAML()` is wrong.
384
+
385
## Validation
386
387
Run the narrowest commands that prove the changed contract. Typical migration