Skip to content

chore(pivot): wave 1 — release + docs alignment + PR-E blocker#174

Merged
trilamsr merged 1 commit into
mainfrom
chore/pivot-wave1-docs-release-clockreceiver
May 31, 2026
Merged

chore(pivot): wave 1 — release + docs alignment + PR-E blocker#174
trilamsr merged 1 commit into
mainfrom
chore/pivot-wave1-docs-release-clockreceiver

Conversation

@trilamsr

Copy link
Copy Markdown
Contributor

What this PR does

Bundles three RFC-0013 PR slices that have zero file overlap with each other.

PR-C: release pipeline → goreleaser stack

  • New .goreleaser.yaml: linux/amd64 + linux/arm64 builds; reproducible via SOURCE_DATE_EPOCH; LDFLAGS shape matches the Makefile build target.
  • Rewritten .github/workflows/release.yml: invokes goreleaser, anchore/sbom-action, sigstore/cosign-installer, slsa-framework/slsa-github-generator (tag-pinned per SLSA OIDC subject identity requirement; all other actions SHA-pinned per repo security policy), actions/attest-build-provenance.
  • Old release.yml moved to .github/workflows/archived/release.yml.legacy.
  • Goreleaser builds the legacy cmd/tracecore binary; OCB-output migration deferred to PR-D (image build → ko), per inline comment in .goreleaser.yaml.

PR-G + PR-H: RFC supersession + top-level docs alignment

PR-E: clockreceiver swap — BLOCKED

  • telemetrygeneratorreceiver does not exist in opentelemetry-collector-contrib at any version. Verified against the Go module proxy, GitHub tree API at v0.95→v0.130, and the full receiver listing at v0.110.0 (94 receivers; no telemetrygenerator, loadgen, mockreceiver, dummyreceiver, or any *generator*). The RFC-0013 §1 example shape referenced it speculatively; it was never upstreamed.
  • builder-config.yaml: replaced the misleading "no v0.110.0 tag" omission comment with a verified TODO block describing the actual blocker (receiver doesn't exist anywhere) and decision rationale.
  • bench/install/tracecore-values.yaml: appended [BLOCKED] marker on the clockreceiver→telgen mapping; bench continues to use in-tree clockreceiver until PR-F deletes it (likely rewires to hostmetricsreceiver).

Root cause (PR-E blocker)

RFC-0013 §1 listed telemetrygeneratorreceiver as the swap target without verifying the receiver existed upstream. Reality: the OTel contrib repo has no such module path at any tag. PR-E cannot complete until either (a) the receiver lands upstream, or (b) a different replacement is chosen (e.g., hostmetricsreceiver for heartbeat semantics). Tracked in the in-file TODO block; revisit in PR-F (delete clockreceiver) or as a separate followup.

Release notes

[CHANGE] Release pipeline migrated to goreleaser + SBOM + SLSA provenance + cosign signing. The release.yml workflow now invokes goreleaser instead of building binaries directly. Operators consuming release artifacts: artifact shape (filename, archive contents, checksum file format) follows goreleaser defaults; see CHANGELOG.md for the migration note.

Test plan

  • make verify runs and passes
  • make actionlint passes (new release.yml workflow + suppression-block YAML valid)
  • make zizmor passes (SLSA reusable-workflow tag-pin justified inline + accepted)
  • make build (legacy) still works
  • make build-ocb (OCB) still works
  • Goreleaser dry-run in CI on first push to a tag (gated until a tag exists)

Bundles three RFC-0013 PR slices that have zero overlap with each other:

**PR-C (release pipeline → goreleaser stack):**
- New `.goreleaser.yaml`: linux/amd64 + linux/arm64 builds with reproducible
  SOURCE_DATE_EPOCH + matching Makefile LDFLAGS shape.
- Rewritten `.github/workflows/release.yml`: invokes goreleaser, anchore/sbom-action,
  sigstore/cosign-installer, slsa-framework/slsa-github-generator (tag-pinned per
  SLSA OIDC subject identity requirement), actions/attest-build-provenance. All
  other actions SHA-pinned per repo security policy.
- Old release.yml moved to `.github/workflows/archived/release.yml.legacy`.
- Goreleaser builds legacy `cmd/tracecore` binary; OCB-output migration deferred
  to PR-D (image build → ko).

**PR-G + PR-H (RFC supersession + top-level docs):**
- Audit confirmed all 12 RFCs already carry the correct supersedence headers
  from prior pivot work; only NORTHSTARS.md and CHANGELOG.md needed alignment.
- NORTHSTARS.md O1 caveat: replaced "own-binary architecture" assumption with
  OCB-distribution-posture wording; closed Open Question #1 by RFC-0013 ref.
- CHANGELOG.md: appended pivot-wave-1 PR list (#166/#168/#169/#170/#171/#172/#173)
  citing PR-A as the next step before this commit.

**PR-E (clockreceiver swap) — BLOCKED:**
- `telemetrygeneratorreceiver` does not exist in opentelemetry-collector-contrib
  at any version (verified against Go module proxy, GitHub tree API at v0.95→v0.130,
  and full receiver listing at v0.110.0). The RFC-0013 §1 example shape referenced
  it speculatively; it was never upstreamed.
- `builder-config.yaml`: replaced misleading omission comment with verified TODO
  block describing the blocker and decision rationale.
- `bench/install/tracecore-values.yaml`: appended [BLOCKED] marker on the
  clockreceiver→telgen mapping; bench continues to use in-tree clockreceiver
  until PR-F deletes it (likely rewires to hostmetricsreceiver).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Signed-off-by: Tri Lam <tri@maydow.com>
@trilamsr trilamsr enabled auto-merge (squash) May 31, 2026 01:03
@trilamsr trilamsr merged commit a9c3b1e into main May 31, 2026
11 checks passed
@trilamsr trilamsr deleted the chore/pivot-wave1-docs-release-clockreceiver branch May 31, 2026 01:08
trilamsr added a commit that referenced this pull request May 31, 2026
…#175)

## What this PR does

Cleans up drift from PR #174 surfaced by self-review, plus deletes the
half-measure "archive" per the no-bloat directive.

### Deletions

- `.github/workflows/archived/release.yml.legacy` (700+ lines) — git
history is the archive. Removed the empty `.github/workflows/archived/`
directory too.
- `workflow_dispatch` trigger from `release.yml` — tag-push is the only
legitimate release path; manual dispatch was a bypass scenario that
complicated signing identity verification (`cosign verify-blob`
hardcodes `--certificate-github-workflow-trigger 'push'`).

### Drift fixes

- `docs/reproducibility.md` — 4 refs to the non-existent
`goreleaser.yml` corrected to the actual workflow name `release.yml`.
- `.goreleaser.yaml` comment — removed reference to a non-existent
"reproducible flag"; determinism comes from `mod_timestamp` (already in
the config).
- `CHANGELOG.md`, `MILESTONES.md`, `docs/notes/ci.md`, `release.yml`
header — prose updated from "archived under .github/workflows/archived/"
→ "preserved in git history".

## Root cause

PR #174 self-review identified five findings; this PR fixes all of them
in one pass instead of accumulating a TODO list. Two patterns surfaced:

1. **Half-measure archives** — keeping a "legacy" copy alongside the
rewrite costs read time, hides intent, and can't actually run without
further opt-in. Git history is the durable archive.
2. **Doc-vs-config drift** — the goreleaser stack was added by name
across multiple docs ahead of the actual filename (`release.yml`)
landing, leaving four cross-references that point at a workflow that
doesn't exist.

## Release notes

```release-notes
NONE
```

## Test plan

- [x] `make verify` runs and passes
- [x] `make actionlint` passes (release.yml without workflow_dispatch is
still valid)
- [x] `grep -r "goreleaser.yml" docs/` returns no hits
- [x] `grep -r "workflows/archived" .` returns only the (untouched) RFC
reference at docs/rfcs/0013-distro-first-pivot.md line 235 — that one
stays unchanged here per RFC binding-doc policy; can be cleaned in a
future RFC patch

Signed-off-by: Tri Lam <tri@maydow.com>
Co-authored-by: Tri Lam <tri@maydow.com>
trilamsr added a commit that referenced this pull request May 31, 2026
#176)

## What this PR does

Three RFC-0013 workstreams bundled. Velocity push.

### PR-D: production container image build → `ko`

- New `.ko.yaml` at repo root:
`gcr.io/distroless/static-debian12:nonroot` pinned by digest (matches
prior Dockerfile pin bit-for-bit, preserving chart's `runAsUser: 65532`
posture), `linux/{amd64,arm64}`, ldflags matched to `.goreleaser.yaml`
so in-image binary is shape-identical to the goreleaser archive.
- New `ko-publish` job in `.github/workflows/release.yml`: runs after
`goreleaser`, multi-arch build, cosign-keyless sign of manifest by
digest, `actions/attest-build-provenance` pushed into the registry.
Pinned `ko-build/setup-ko@v0.9` by SHA.
- **DELETED root `Dockerfile`** — replaced by `.ko.yaml`; git history is
the archive (no-bloat directive). Chart-local
`install/kubernetes/tracecore/Dockerfile` retained (kind-CI reference,
used by `chart.yml` + `install-bench.yml`).
- `scripts/base-digest-check.sh` reads pin from
`.ko.yaml::defaultBaseImage` instead of the deleted Dockerfile.
- `install/kubernetes/tracecore/README.md` local-build snippet swap: `ko
build --local`; clarifies chart-local Dockerfile is kind-CI only.
- Chart `image.repository` unchanged (`ghcr.io/tracecoreai/tracecore`
already matches ko-published path).

### Fix: `make fmt` / `make license-check` walked `_build/`

After `make build-ocb`, the OCB-generated output dir `_build/` poisoned
`make verify` because gofumpt + license-check recursed into
upstream-licensed generated files. Bug surfaced during PR #174
self-review.

- `make fmt` / `make fmt-fix`: pipe through `grep -v '^_build/'` after
gofumpt.
- `make license-check` / `make license-fix`: add `-not -path
'./_build/*'` to find.

### PR-B reframed: self-tel rename is a side-effect of PR-A + PR-F, not
a caller rewrite

Investigation found the upstream APIs RFC-0013 §migration PR-B
prescribes are architecturally incompatible with PR-B's "replace
`internal/selftelemetry/` callers" framing:

- `service/telemetry` exposes one-per-binary boot-time setup, not
per-component
`IncError`/`IncEmissions`/`ObserveLatency`/`SetDegraded`/`MarkActivity`.
- `componentstatus` is a status-event surface
(`StatusOK/StatusRecoverableError/StatusPermanentError`), not a metrics
emitter.
- The standard `otelcol_*` metrics RFC-0013 §2 promises are emitted by
upstream `receiver/scraperhelper`, `exporter/exporterhelper`, and the
OCB-generated pipeline runtime — NOT by our in-tree receivers, which
don't use those helpers.

The rename therefore arrives automatically once PR-A's OCB binary boots
and PR-F deletes the in-tree receivers. No caller rewrite is needed in
between. RFC-0013 §migration PR-B collapses into PR-F; the standalone
PR-B step becomes documentation-only and lives in the new CHANGELOG
entry.

Investigation evidence: 30 non-test importers of
`internal/selftelemetry/`, 11 `tracecore.*` metric emit sites, `go list
-m go.opentelemetry.io/collector/component` returns "not a known
dependency" (the packages live inside the OCB-assembled binary, not the
per-component module graph).

## Root cause

- **PR-D:** straightforward swap; Dockerfile complexity disappears into
`.ko.yaml`.
- **`_build/` walker bug:** `make fmt` / `license-check` used `.` as the
find root with no excludes; OCB output is generated under `./_build/` so
it ended up in scope.
- **PR-B reframe:** RFC-0013 §migration PR-B was scoped before measuring
the upstream API surface. Reality is that `componentstatus` and
`service/telemetry` were the wrong abstractions to point at; the rename
is a free side-effect of the binary swap, not a separate task.

## Release notes

```release-notes
[CHANGE] Production container image build moved to `ko`. Root `Dockerfile` deleted; `.ko.yaml` at repo root drives a multi-arch (`linux/{amd64,arm64}`) build of `./cmd/tracecore` on top of the same `gcr.io/distroless/static-debian12:nonroot` digest pin the deleted Dockerfile used. Chart `image.repository` unchanged. Image is now built, signed, and attested in the same `release.yml` workflow as the binary archives.
```

## Test plan

- [x] `make verify` runs and passes
- [x] `make build-ocb` builds OCB binary
- [x] `make fmt` passes WITH `_build/` populated (filter works)
- [x] `make license-check` passes WITH `_build/` populated (filter
works)
- [x] `scripts/base-digest-check.sh --warn` confirms ko pin matches live
registry
- [x] `make actionlint` + `make zizmor` pass on the new ko-publish
workflow job
- [ ] End-to-end ko build via CI on first tag push (gated until a tag
exists)

---------

Signed-off-by: Tri Lam <tri@maydow.com>
Co-authored-by: Tri Lam <tri@maydow.com>
trilamsr added a commit that referenced this pull request May 31, 2026
## Summary

PR-H sliver per [RFC-0013
§migration](docs/rfcs/0013-distro-first-pivot.md#migration--rollout).
Sweeps `PRINCIPLES.md` + `CONTRIBUTING.md` for distribution-first pivot
drift. Net -128 lines.

## Root cause

Two unrelated drift accumulations, both fixed at source:

1. **PRINCIPLES.md §2 example was factually wrong.** The text "we
deferred GoReleaser, SBOM signing, eBPF integration, the Helm chart, the
OTel `pdata` import — none has cost us" predates the work that landed
since: PR-C (#174) shipped the goreleaser + SBOM + cosign stack; M5b
shipped the Helm chart; OCB adoption (#171 PR-A) pulls `pdata` in via
upstream. The illustrative example for "default to *not* adding" was
listing items we *did* add. Deleted the example; the principle's first
paragraph + bullet list above it carry the message without the
contradiction.

2. **CONTRIBUTING.md carried two layers of pivot drift.**
- **External-repo references stale post-#181.** Three mentions of
`tracecoreai/tracecore-components` (separate-repo framing) survived the
PR #181 rescope to in-repo `module/` Go submodule. Updated to
`github.com/tracecoreai/tracecore/module` with layout
`module/receiver/<name>/`, `module/processor/<name>/`.
- **Adding-a-component tutorial contradicted RFC-0013 policy.** ~130
lines of tutorial taught contributors to add receivers under
`components/` referencing `clockreceiver` / `dcgm` / `kernelevents` as
canonical shapes — but RFC-0013 §6 forbids new in-tree components
("Nothing else is built in-house"), and all three canonical references
are queued for v0.1.0 or v0.2.0 deletion per §7. The routing block 100
lines above already declared the forbidding policy, so the tutorial was
a live-policy contradiction with deleted-receiver examples. Replaced
with a ~10-line routing block covering the three actual branches
(upstream first / moat → `module/` / RFC for fifth scope) plus a
one-liner on the surviving factory shape. This is also why the four
explicit `clockreceiver` references (lines 139/142/149/152 pre-edit)
were resolved by deletion-of-containing-section rather than name-swap:
no candidate survivor exists (`dcgm` deletes v0.1.0,
`clockreceiver`/`kernelevents`/`k8sevents`/`containerstdout` delete
v0.2.0, `nccl_fr` is logs-only and moves out to `module/` in PR-I.1).

## Changes

- `PRINCIPLES.md` — delete one stale concrete-example paragraph (3 lines
net).
- `CONTRIBUTING.md` —
  - L21, L32: `tracecoreai/tracecore-components` → in-repo `module/`.
- L103-L235 (old): collapse "Adding a component" tutorial → 7-line
routing block.

## Scope-discipline notes

Per prompt scope-fence:
- `MILESTONES.md` / `CHANGELOG.md` deletion-table drift untouched
(historic / intentional per prompt).
- `docs/STRATEGY.md` untouched (out of scope per prompt).
- `PRINCIPLES.md` §16 already cites RFC-0013 — no additional edit
needed.
- `STYLE.md` lines 106/115 reference `clockreceiver` as a Go-import
example; left in place — code example for `package clockreceiver`
import-form is shape-illustrative (will rotate when source actually
deletes in PR-K). Flagged for the next sweep, not PR-H.
- `cmd/tracecore/`, `bench/install/`, `install/kubernetes/`,
`AGENTS.md`, `tools/components-gen/` all carry `clockreceiver`
references and are explicitly *out of PR-H scope* — those migrations
land in PR-K (test-fixture coordination) per CHANGELOG line 16.

## Test plan

- [x] `make check` — clean (golangci-lint 0 issues, vet clean,
mod-verify ok).
- [x] `make doc-check` — clean (505 markdown links resolve including new
`#upstream-contribution-policy` + `#rfc-process` cross-links;
banned-phrase lint clean across 109 markdown files).
- [x] `make ci` (via pre-push hook) — clean (actionlint + zizmor +
alert-check + chart-appversion-check + no-autoupdate-check + clean-tree
all pass).
- [x] `grep -n "clockreceiver\|tracecore-components" CONTRIBUTING.md
PRINCIPLES.md` — zero hits post-edit.
- [x] Anchor verification: `#upstream-contribution-policy` resolves to
`## Upstream contribution policy` (L15); `#rfc-process` resolves to `###
RFC process` (L39).

Doc-only diff; no Go test corpus changes.

Signed-off-by: Tri Lam <tri@maydow.com>
Co-authored-by: Tri Lam <tri@maydow.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant