From 531c58a23246ff378b13cda08dba5fe0c9a6c3ca Mon Sep 17 00:00:00 2001 From: Tri Lam Date: Tue, 19 May 2026 14:59:53 -0700 Subject: [PATCH 1/2] [docs] capture session-derived RFC conventions + review-pattern lessons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 5-pass review on RFC-0010 (PR #94) and the broader M15 session accumulated 11 binding rubric additions + 3 review-pattern lessons in session-ephemeral state that would have been lost when the worktree was cleaned. Promoting the load-bearing ones to durable docs. docs/rfcs/README.md additions: - §"Authoring conventions" — 8 binding rules for receiver-scope RFCs (Operator-surfaces section, Rubric-trace appendix, Performance budget, wire-attribute table, sibling-symbol compile-resolve, cross-RFC join-key resolution, post-fix symbol grep, FOLLOWUPS strikethrough). Each carries a falsifying grep/test. - §"Component registration" — the components.yaml + `make generate` codegen pattern documented for the next receiver author. docs/notes/reviews.md additions (matches existing format): - Multi-pass review accretes propagation gaps; grep after every applied fix. Anchor: RFC-0010 commit 63dccbb caught Phase-2 fixes that landed in one section and missed sibling sections. - Rubric self-violation sneaks in when the rubric is fresh. Anchor: Phase-2 accepted §Operator-surfaces rubric AND deferred the section in the same commit; Phase 4 caught it. - Single-maintainer projects collapse multi-stakeholder meeting processes to ~30-minute solo decision exercises. Anchor: RFC-0010 §15.6 framing presumed three stakeholders; resolved by one person. Closes the 4 documentation gaps surfaced in the session-summary audit. No code touched. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/notes/reviews.md | 57 +++++++++++++++++++++++++++++++++++++++++++ docs/rfcs/README.md | 31 +++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/docs/notes/reviews.md b/docs/notes/reviews.md index 3b3971b3..29d53792 100644 --- a/docs/notes/reviews.md +++ b/docs/notes/reviews.md @@ -64,3 +64,60 @@ wins and clutters the follow-up list. Anchor: `docs/FOLLOWUPS.md` § `k8sevents post-merge` — every deferral in that section has a real out-of-PR dependency (extension surface, milestone-blocked, breaking change). + +### Multi-pass review accretes propagation gaps; grep after every applied fix + +A 5-phase review on a 338-line RFC produced 80+ findings across +Phases 1-4. Three of the "applied" fixes (a Kind split, a ClusterRole +rename, a cross-doc reference qualification) each landed correctly +in the section that raised the finding but were missed in one to +three sibling sections of the same RFC. Phase 3's adversarial pass +caught the propagation gaps by grepping the whole file for every +introduced or removed symbol. The fix is mechanical (one Edit per +sibling site) but the reviewer who DOESN'T grep ships the +inconsistency. + +Anchor: RFC-0010 commit `63dccbb` (the adversarial-review pushback +table) — specifically the `KindCardinality` split at line 188 missed +line 172 and line 368; the `tracecore-containerstdout-clusterrole` +rename at line 196 missed line 369. Both caught only because the adversarial +reviewer ran `grep -n` against the whole file after reading the +diff. Promoted to a binding RFC-authoring rule at +[`docs/rfcs/README.md` § Authoring conventions](../rfcs/README.md#authoring-conventions-binding-derived-from-rfc-0009--rfc-0010-review-trail). + +### Rubric self-violation sneaks in when the rubric is fresh + +When a review phase accepts a new binding rubric ("alpha-receiver +RFCs MUST contain §Operator-surfaces"), the same phase's "deferred +to FOLLOWUPS" list tends to include exactly the work the new rubric +forbids deferring. The rubric is too new to feel binding to the +author; deferring is the path of least resistance. The next phase +catches the violation — at which point the cost to inline the +deferred work is mechanical (one new subsection) but the cycle ran +twice. Lesson: when a phase proposes AND accepts a rubric in the same +session, the synthesis step MUST re-check the current PR's deferral +list against the new rubric before committing. + +Anchor: RFC-0010 Phase-2 accepted "alpha-receiver RFCs MUST contain +§Operator-surfaces" AND deferred the §Operator-surfaces subsection to +FOLLOWUPS in the same commit. Phase-4 A+ pass flagged it; commit +`be3db09` (the A+ aspiration pushback table) inlined the section. +One avoidable cycle. + +### Single-maintainer projects collapse stakeholder-meeting processes to solo decision exercises + +Multi-stakeholder design RFCs often include a §"How to resolve OD-N +in one week" section presuming roles like "M16 owner, O2 stakeholder, +milestone-planning lead". In a single-maintainer project, all three +roles are the same person; the literal stakeholder meeting collapses +to a ~1-hour solo decision exercise (pre-declare M16's preferred +implementation approach; decide O4 namespace posture; record OD +resolution in a decision artifact). The RFC framing presuming a team +is still correct for the project's eventual multi-maintainer state +but should not block solo execution today. + +Anchor: RFC-0010 § 15.6 reads as a multi-stakeholder meeting agenda +but was actually resolved by Tree wearing all three hats in ~30 +minutes during the session that closed PR #94. Documented for the +next single-maintainer RFC author so they don't read the framing as +a literal blocker. diff --git a/docs/rfcs/README.md b/docs/rfcs/README.md index 039541e6..dfa3fe7f 100644 --- a/docs/rfcs/README.md +++ b/docs/rfcs/README.md @@ -65,3 +65,34 @@ naming inconsistency (`0006` is `RFC-0006-*.md`, others are the old one. The superseded RFC's `Status:` flips to `superseded by RFC-NNNN` and the body stays in-tree as historical record. + +## Authoring conventions (binding, derived from RFC-0009 + RFC-0010 review trail) + +Apply to every receiver-scope RFC. Each rule is falsifiable by the grep / test stated. + +**Required sections in alpha-receiver RFCs:** + +- §Operator surfaces — names `components/receivers//RUNBOOK.md`, `prometheus-alerts.example.yaml`, and `docs/FAILURE-MODES.md` rows as Phase-4 deliverables (one alert row per `IncError(Kind)`). Inline OR explicitly waive with a stated reason. Falsifying: `grep -L "RUNBOOK.md\|prometheus-alerts" docs/rfcs/000[7-9]*.md docs/rfcs/0010*.md docs/rfcs/0011*.md` returns empty. +- §Rubric trace appendix — table mapping every MILESTONES.md `M` rubric line to the RFC subsection that addresses it (or to a FOLLOWUPS trigger + out-of-scope rationale). Falsifying: row count in the trace table equals bullet count under the rubric block. +- §Performance budget — required when MILESTONES rubric states CPU / RSS / Mbps thresholds. Table of (Concern, Commitment, Falsifying bench). Falsifying: `grep -nE "benchmem|alloc/op|ns/op" docs/rfcs/.md` returns ≥1 per stated threshold. + +**Required cross-checks:** + +- **Wire-attribute name table** when the RFC declares a typed record consumed by downstream receivers — every exported field has a row, and the row's wire-attribute name string greps against the relevant MILESTONES rubric block. +- **Sibling-package symbol compile-resolve** — every `.` cited in RFC prose must resolve under `git grep -nE "\b" components/` at HEAD, OR carry the `(planned per ; not yet at HEAD)` marker. "Compile-time pin" / "enforced at compile time" reserved for symbols that resolve today. +- **Cross-RFC join-keys** — label names, attribute namespaces, and any field both M and M read or write MUST resolve to one canonical spelling at design-lock. Resolve in this PR or the sibling RFC's PR; do not defer to "whichever lands first" (the second author pays). + +**Review-hygiene gates (apply during the review of an RFC PR):** + +- **Symbol consistency after every applied fix** — when a fix renames or splits a symbol (Kind, ClusterRole, attribute), grep the whole RFC for the old name before commit. Phase-N "applied" findings consistently miss sibling-section propagation; the grep audit closes the loop. +- **FOLLOWUPS entries resolved by the closing PR** MUST be struck-through with a "Resolved by RFC-XXXX §Y" pointer, not silently left as open boxes. Preserves the audit trail and prevents inverse-drift (FOLLOWUPS rows that no longer correspond to live deferrals). + +## Component registration (receiver factory codegen) + +Receivers register via `cmd/tracecore/components.yaml` + `make generate`: + +1. Add a new receiver entry to `cmd/tracecore/components.yaml` with `type:` and `package:` keys (sorted alphabetically; the generator enforces order). +2. Run `make generate` to regenerate `cmd/tracecore/components.go` from the YAML. Do NOT hand-edit the generated file — the header carries a `DO NOT EDIT` warning. +3. The generator (`tools/components-gen/main.go`) emits an import alias and a factory map entry like `pipeline.MustNewType(""): .NewFactory()`. + +This is the only file edit the registration step requires; the receiver's own factory function lives in `components/receivers//factory.go` per the [`0004-clockreceiver-stdoutexporter.md`](0004-clockreceiver-stdoutexporter.md) contract. From cd6ad54b01cae5007cb893931b83f69f32071f31 Mon Sep 17 00:00:00 2001 From: Tri Lam Date: Tue, 19 May 2026 15:27:19 -0700 Subject: [PATCH 2/2] [docs] AGENTS.md: cross-receiver join contracts + RFC-authoring topic-index pointer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds one load-bearing lesson and one topic-index pointer derived from the M15 / RFC-0010 review trail. Load-bearing lesson: - Cross-receiver join contracts resolve at design-lock, not at implementation-merge. Every `M-X emits Y` MILESTONES.md rubric is implicitly a contract with every `M-Z consumes Y` receiver. Before opening a receiver-scope RFC, grep for every attribute / label / field name introduced; reconcile divergences in-PR, not in a FOLLOWUPS row. Anchor: PR #94 (M15 RFC-0010) caught the tracecore.io/rank vs gen_ai.training.io/rank divergence with RFC-0009 in Phase-3 review and amended MILESTONES.md line 358 in the same PR. Topic-index pointer: - `docs/rfcs/README.md` — surfaces the receiver-scope RFC conventions (Operator surfaces, Rubric trace, Performance budget, wire-attribute table, cross-RFC join-key resolution, components.yaml codegen) promoted to that file in the body of this PR. Without the index entry, the next agent has to know the file exists. Co-Authored-By: Claude Opus 4.7 (1M context) --- AGENTS.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index 7c7da5aa..b23bf9f6 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -104,6 +104,20 @@ Universal rules every change should respect. The file is capped at Anchor: `bench_test.go` PR #76 commit `869450b`; `impl_test.go` PR #78 commit `06b9ddf`. +- **Cross-receiver join contracts resolve at design-lock, not + implementation-merge.** Every `M-X emits Y` rubric line in + MILESTONES.md is implicitly a contract with every `M-Z consumes Y` + receiver. Before opening a receiver-scope RFC PR, grep MILESTONES.md + and every sibling RFC for each attribute name, label name, or field + name the new receiver introduces; reconcile divergences in the same + PR (or its sibling-RFC's PR), not in a FOLLOWUPS row saying + "whichever lands first". The "first-author-pays, second-author-fights-the-amendment" + pattern is the failure mode. Anchor: PR #94 found that the M15 + rubric's pod-label fallback `tracecore.io/rank` diverged from + RFC-0009's `gen_ai.training.io/rank`; Phase-3 review caught it, + amended MILESTONES.md line 358 in-PR, and the FOLLOWUPS row was + marked resolved in the same commit. + ## Topic index — repo-wide Per-topic notes that apply to anyone working in this codebase. Read @@ -125,6 +139,11 @@ the relevant note when work touches that area. Format conventions: gates. - [Branch protection](docs/notes/branch-protection.md) — rule trade-offs on main, three-sources-of-truth, escape hatches. +- [RFC authoring](docs/rfcs/README.md) — receiver-scope RFC required + sections (Operator surfaces, Rubric trace, Performance budget), + cross-checks (wire-attribute table, sibling-symbol resolve, + cross-RFC join-key), and the `components.yaml` + `make generate` + codegen pattern. ## Topic index — agent-internal