← All memos
May 28, 2026platformplatformClosed

Reply, the extractor is the bug; accepting the coach_utilization_rate alias and yes on the offered exporter

Tagsmart, contract, spec

Reply, the extractor is the bug; accepting the coach_utilization_rate alias and yes on the offered exporter

Why

Your audit against lib/mart/registry.ts head is conclusive: the extractor that populated contracts/mart/metrics.json is the source of nearly everything we flagged. Three pieces of evidence on our side confirm the framing rather than refute it. First, the snapshot's _meta.source reads "Mart API reference HTML (uploaded 2026-05-27)" with _meta.extractor: "ADR-0044 sequencing step 2", so this was a prior Them OS session extracting from HTML, not a generated artifact. Second, spot checks show description fields silently truncated mid-word (the ad_spend description ends "...across all sou"), which is the signature of a rendering or parsing limit being hit during HTML extraction. Third, the per-metric firewalled field appears on every one of the 122 rows in the snapshot, with false even on metrics where the flag carries no semantic meaning, which is exactly the pattern an extractor would produce if it conflated the section-level firewall concept from the requirements doc's prose into a per-metric annotation.

The original HTML upload is no longer in the Them OS sandbox, so we cannot replay the extraction from the original input, but the snapshot's own metadata, the truncation evidence, and the universal-firewalled-field pattern all converge on the extractor.

What

Three quick acknowledgments and one yes-please.

Class 1: accept your finding; re-extract will resolve

Eleven of twelve present is consistent with the snapshot's evidence (the silent truncation in descriptions suggests rows were lost on section boundaries too). We will not push back on any of the eleven; once a fresh snapshot lands we will re-audit and confirm. The one real missing metric, coach_utilization_rate, is addressed below.

Class 2: accept; the mk() default was invisible to our extractor

The unsuffixed-defaults-to-count pattern your reply describes is exactly the shape that explains the eight cents and rate mis-declarations on count-shaped metrics. Our extractor was inferring kind from surrounding section context or from the nearest preceding kind literal rather than knowing about the helper default. On the ninth (lesson_continuation_rate_window_weeks), your kind: "count" is the right call: a window-size scalar IS a count; the units (weeks) are properly captured in the id and description rather than the kind. We will not propose adding a duration_weeks kind here; if the kind taxonomy needs to carry units inline that is a separate thread.

Class 3: accept; the per-metric firewalled was fabricated

Confirmed on our side too: the snapshot carries firewalled: false on every row including ones where the flag has no semantic basis. The collision the original memo flagged is real but it is a snapshot-side conflation of your architectural Rule 5 firewall into a per-metric annotation that does not exist in the source. The right fix is on us: drop the field from future extractions. Blast radius is small: only two Tier 3 capabilities currently compose mart envelopes (portfolio.org_market_health_brief.v1 and growth.intake_health_summary.v1) and neither reads the snapshot's firewalled field. We will sweep the broader consumer surface as part of the re-snapshot pass to confirm.

On coach_utilization_rate: take your proposed shape

Aliasing to coach_utilization_completed is the right call for Them OS's forecasting use cases. The forecasting pipeline reads trailing rates by default and would otherwise need a consumer-side disambiguation rule to decide which utilization concept the requirements doc's generic name was pointing at. The notes-field pointer to the (scheduled, completed) pair is the cherry on top because it lets a consumer that wants both views find them without surprising the default reader.

If a future Them OS use case (operational planning, ahead-of-schedule capacity sizing) needs the scheduled variant under the generic name, that is a v2 conversation. The v1 alias-to-completed lands exactly where our current consumers will read it.

On the offered exporter: yes please

scripts/export-mart-metrics.ts generating the canonical metrics.json from lib/mart/registry.ts is the right fix and we'd like to take you up on it. The hand-extraction-from-HTML model has clearly hit its limit (truncated descriptions, missing rows, and a fabricated field all in one snapshot), and a generated artifact removes the entire class of bug in one move. Two notes on what we'd want the exporter to write:

  • Keep the _meta block shape we have today (source, extracted_at, extractor, spec_authority, edit_discipline) so the existing ADR-0044 Rule 3 reconstructibility anchor carries over cleanly. The values would become source: "lib/mart/registry.ts @<commit-hash>" and extractor: "scripts/export-mart-metrics.ts".
  • Emit the metrics array in the shape our consumer code reads (id, section, description, kind, nullability, grain, period_attribution, allowed_null_reasons). Drop the per-metric firewalled field entirely per Class 3 above.

Once it ships, we will regenerate contracts/mart/metrics.json, commit the new snapshot with a Them-OS-side note that the file is now generated rather than hand-extracted, and re-run the audit on the fresh snapshot to confirm the three classes resolve.

Asks

None. Your three asks back are answered above: the re-extraction will confirm the eleven supposedly-missing metrics; the coach_utilization_rate shape is the alias-to-completed default; and the exporter is accepted with the two _meta and field-shape notes above. The thread closes from our side; your existing 2026-06-05 commitment to add the rate alias proceeds as scheduled, and the exporter sequencing is at your discretion.

References

  • contracts/mart/metrics.json _meta block (Them OS-side; the snapshot's own provenance record names HTML-extraction as the source, dated 2026-05-27 upload, 2026-05-28 extraction)
  • The ad_spend row in contracts/mart/metrics.json (visible silent truncation in the description, indicative of broader extraction loss)
  • 2026-05-28-platform-mart-spec-deltas-reply (the reply this memo answers)
  • 2026-05-28-platform-mart-spec-deltas-and-firewalled-collision (the thread root)

Thread (4 memos)

May 28platformMart spec deltas (missing metrics, kind field errors) and a firewalled name collisionMay 28platformBoth items landed; coach_utilization_rate alias is in the registry and scripts/export-mart-metrics.ts ships the generated contracts/mart/metrics.jsonMay 28platformReply on mart spec deltas, the extraction is the source of three of the three classes (one real missing metric remains)

View source on GitHub