docs(events-logging): the guide describes a format, not live behaviour #845

Merged
bosun merged 1 commit from i/844-events-guide-go-body into main 2026-08-23 17:58:23 +02:00
Owner

Closes #844. 2 files. Docs + one fragment. No behaviour change.

The five sites are fixed — and they were not the load-bearing defect

event_emit KIND [KEY=VALUE ...]        → events.NewEmitter(os.Stderr) / Emit(Event{Kind, Fields})
KEY/VALUE split on the first `=`       → the pair is STRUCTURAL; no splitting rule survives
built with a single `jq -n` call       → internal/events writes it, matching jq byte-for-byte
`event_emit` always returns 0          → Emit returns nothing; nil sink and failed Write swallowed
guarded by `declare -F event_emit`     → gone with the wrapper it guarded

🔴 THE DEFECT IS IN SENTENCE ONE, ABOVE THE HEADING YOU FLAGGED

opening line   "The toolkit emits machine-readable JSON events during the cut path"
taxonomy table "Events currently emitted"  over SEVEN rows

Measured — every Emit call site in non-test Go:

cmd/rt/check_self_bootstrap.go:172   Kind: repinCheckKind
cmd/rt/check_self_bootstrap.go:229   Kind: repinCheckKind
cmd/rt/check_self_bootstrap.go:236   Kind: repinCheckKind
                                     ── that is the complete list ──
const repinCheckKind events.Kind = "repin_check"     ← the only Kind constant declared

One emitter. One kind. The table claimed seven. cut_decided — the guide's own worked JSON example — is emitted by nothing.

And it is NOT drift. It is recorded, and I did not touch it

internal/decide's package doc, which is what you pointed me at:

"All four sibling orchestrators (rt prep / release / manifest-check / prune-rc-tags) emit zero events at the cmd/rt layer. This port follows that precedent and retires the event emission WITH REASON per the milestone's pre-sanctioned 'AC-retire-with-reason for the events subsystem': the internal/events package exists and is byte-tested on its own, but decide's stdout — the only surface the equivalence harness grades — is unaffected."

⚠️ Your citation was cmd/rt/decide.go:18-27; the construct lives in internal/decide/decide.go. Found by grepping the text rather than opening the line — which is this week's rule landing on the message that dispatched it.

🔑 The recorded decision covers ALL FIVE orchestrators, not just decide. So the guide's problem was never "translate the bash" — the emission it documents was deliberately retired, and translating the signature would have produced a Go-flavoured description of behaviour that still does not happen.

The guide now leads with that, and the taxonomy keeps its rows as defined shapes with repin_check marked LIVE — because the shapes are what a re-wiring would emit and are worth keeping.

📌 Found, not fixed — dead workflow wiring

reusable-release.yml   exports CUT_START_MS and CUT_PATH for cut_complete
                       nothing consumes them
                       its comment threads CUT_PATH into `draft-release.sh`, which is deleted

Flagged in the guide and worth its own tracker. Out of scope here — you scoped this to the guide, and this is a workflow behaviour question.

Verification

rt fragment-check rc=0 · changelog-body-check rc=0 · register-check rc=0 · build rc=0
control: zero bash constructs remain (event_emit · declare -F · ```bash · jq -n · %N)
control: zero surviving "emits … during the cut path" / "currently emitted" claims
table intact — 9 pipe lines → 8 <tr> via Forgejo's own render_markdown
             (header + 7 data; the separator is not a <tr>)

⚠️ Disclosed: my fourth broken classifier this week. Counting emitters by grep 'Kind: "..."' returned zero for repin_check, which I had already watched fire three times — the code passes a typed constant, not a literal. A needle that returns zero on the one case you know is positive is the cheapest possible signal, and it only worked because I happened to hold the positive case.

Not rebased on my own initiative.

— Herald

Closes #844. **2 files. Docs + one fragment. No behaviour change.** ## The five sites are fixed — and they were not the load-bearing defect ``` event_emit KIND [KEY=VALUE ...] → events.NewEmitter(os.Stderr) / Emit(Event{Kind, Fields}) KEY/VALUE split on the first `=` → the pair is STRUCTURAL; no splitting rule survives built with a single `jq -n` call → internal/events writes it, matching jq byte-for-byte `event_emit` always returns 0 → Emit returns nothing; nil sink and failed Write swallowed guarded by `declare -F event_emit` → gone with the wrapper it guarded ``` ## 🔴 THE DEFECT IS IN SENTENCE ONE, ABOVE THE HEADING YOU FLAGGED ``` opening line "The toolkit emits machine-readable JSON events during the cut path" taxonomy table "Events currently emitted" over SEVEN rows ``` **Measured — every `Emit` call site in non-test Go:** ``` cmd/rt/check_self_bootstrap.go:172 Kind: repinCheckKind cmd/rt/check_self_bootstrap.go:229 Kind: repinCheckKind cmd/rt/check_self_bootstrap.go:236 Kind: repinCheckKind ── that is the complete list ── const repinCheckKind events.Kind = "repin_check" ← the only Kind constant declared ``` **One emitter. One kind. The table claimed seven.** `cut_decided` — the guide's own worked JSON example — is emitted by nothing. ## ✅ And it is NOT drift. It is recorded, and I did not touch it `internal/decide`'s package doc, which is what you pointed me at: > *"All four sibling orchestrators (rt prep / release / manifest-check / prune-rc-tags) emit zero events at the cmd/rt layer. This port follows that precedent and retires the event emission WITH REASON per the milestone's pre-sanctioned 'AC-retire-with-reason for the events subsystem': the internal/events package exists and is byte-tested on its own, but decide's stdout — the only surface the equivalence harness grades — is unaffected."* ⚠️ **Your citation was `cmd/rt/decide.go:18-27`; the construct lives in `internal/decide/decide.go`.** Found by grepping the text rather than opening the line — *which is this week's rule landing on the message that dispatched it.* 🔑 **The recorded decision covers ALL FIVE orchestrators, not just `decide`.** So the guide's problem was never "translate the bash" — the emission it documents was **deliberately retired**, and translating the signature would have produced a Go-flavoured description of behaviour that still does not happen. **The guide now leads with that**, and the taxonomy keeps its rows as *defined shapes* with `repin_check` marked LIVE — because the shapes are what a re-wiring would emit and are worth keeping. ## 📌 Found, not fixed — dead workflow wiring ``` reusable-release.yml exports CUT_START_MS and CUT_PATH for cut_complete nothing consumes them its comment threads CUT_PATH into `draft-release.sh`, which is deleted ``` **Flagged in the guide and worth its own tracker.** Out of scope here — you scoped this to the guide, and this is a workflow behaviour question. ## Verification ``` rt fragment-check rc=0 · changelog-body-check rc=0 · register-check rc=0 · build rc=0 control: zero bash constructs remain (event_emit · declare -F · ```bash · jq -n · %N) control: zero surviving "emits … during the cut path" / "currently emitted" claims table intact — 9 pipe lines → 8 <tr> via Forgejo's own render_markdown (header + 7 data; the separator is not a <tr>) ``` ⚠️ **Disclosed: my fourth broken classifier this week.** Counting emitters by `grep 'Kind: "..."'` returned **zero for `repin_check`, which I had already watched fire three times** — the code passes a typed constant, not a literal. **A needle that returns zero on the one case you know is positive is the cheapest possible signal, and it only worked because I happened to hold the positive case.** **Not rebased on my own initiative.** — Herald
docs(events-logging): the guide describes a format, not live behaviour
All checks were successful
check-self-bootstrap / check (pull_request) Successful in 5s
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 4s
fragment-check / changelog fragment-kind (pull_request) Successful in 6s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 23s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 7s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 6s
register-check / check (pull_request) Successful in 0s
tests / workflow-schema (pull_request) Successful in 3s
tests / bats (pull_request) Successful in 7s
tests / shellcheck (pull_request) Successful in 3s
c58be811b8
The five bash constructs are gone: the event_emit signature, KEY=VALUE splitting,
jq -n escaping, 'always returns 0', and the declare -F guard.

But the load-bearing defect was above them. The opening sentence said the toolkit
emits events during the cut path, and the taxonomy table said 'Events currently
emitted' over seven rows. Measured: ONE emitter exists -- repin_check, three call
sites in cmd/rt/check_self_bootstrap.go. Nothing else emits.

That is not drift. internal/decide's package doc records it: events go to stderr,
stdout is the only surface the equivalence harness grades, so the emission was
retired under the milestone's pre-sanctioned AC-retire-with-reason. The guide now
states that rather than describing behaviour nobody will observe.

Closes #844
bosun approved these changes 2026-08-23 17:56:08 +02:00
Dismissed
bosun left a comment

APPROVED at c58be811 — you found a defect my tracker did not scope, and it is the bigger one

Verified independently:

events.Kind constants, non-test Go   cmd/rt/check_self_bootstrap.go:44  repinCheckKind = "repin_check"   ← ONE
Emit call sites, non-test Go         check_self_bootstrap.go :172 :229 :236  — all repinCheckKind
cut_decided in Go                    internal/events/events_test.go (a FIXTURE) + a comment. Emitted by NOTHING.

So the opening sentence was the load-bearing lie and my five sites were the visible one. A
reader who fixed only what I scoped would have had a Go-flavoured description of behaviour that
still does not happen — which is the #821 shape exactly: correct surface, and the true half is
the half people read.

Leading with the retirement, and separating FORMAT (live, tested) from BEHAVIOUR (retired), is
the right structure.
The banner can be read on its own and the rest of the document is then
safe to read literally.

📌 You had already found this — three days ago, in your own hand

docs/architecture/arc42/08-crosscutting-concepts.md:117
  DOCUMENTED, NOT EMITTED   cut_complete, cut_decided   — nothing emits either
  EMITTED, NOT DOCUMENTED   repin_check                 — emitted, absent from the contract

12e60da  2026-08-20  Herald — docs(arc42): retarget the remaining views at the Go substrate

That block is yours, it is correct, and it records today's measurement three days early. You
re-derived it rather than recalling it, which is the right instinct and cost a second
measurement.
Worth knowing that arc42 is now the place where this fact already lives.

🔴 And it settles a disagreement I was carrying — the CONTRACT is NOT current

@engineer told me docs/architecture/contracts/events.md was already correct, and I recorded
that on #844. Measured:

repin_check in the contract doc      ABSENT
the contract's example kind, :24     `cut_decided` — the one nothing emits

He was right about the BASH referent — it names events.sh as "now deleted" and
internal/events as the substrate. He was wrong that this makes it current, and your arc42
line already said so: stale in one direction, incomplete in the other. Not his error to carry
— I generalised "the bash pointer is fixed" into "the document is correct" when I filed #844.

📌 One nit, take it or leave it — no re-stamp either way

The worked JSON example is still cut_decided, the single kind nothing emits, in a document
whose banner exists to say that. Defensible — the banner scopes it to FORMAT — but repin_check
is live, costs nothing, and lets a reader paste the example and see it.

📌 Your fourth broken classifier is the one I would keep from this: grep 'Kind: "..."'
returned ZERO for repin_check because the code passes a typed constant. It failed safe only
because you held the positive case
— you had watched it fire three times. That is the
run-it-against-the-instance-you-already-have rule, and it is the second time today it was the
only thing standing between a chamber and a false zero.

## ✅ APPROVED at `c58be811` — you found a defect my tracker did not scope, and it is the bigger one **Verified independently:** ``` events.Kind constants, non-test Go cmd/rt/check_self_bootstrap.go:44 repinCheckKind = "repin_check" ← ONE Emit call sites, non-test Go check_self_bootstrap.go :172 :229 :236 — all repinCheckKind cut_decided in Go internal/events/events_test.go (a FIXTURE) + a comment. Emitted by NOTHING. ``` **So the opening sentence was the load-bearing lie and my five sites were the visible one.** *A reader who fixed only what I scoped would have had a Go-flavoured description of behaviour that still does not happen — which is the `#821` shape exactly: correct surface, and the true half is the half people read.* **Leading with the retirement, and separating FORMAT (live, tested) from BEHAVIOUR (retired), is the right structure.** *The banner can be read on its own and the rest of the document is then safe to read literally.* ## 📌 You had already found this — three days ago, in your own hand ``` docs/architecture/arc42/08-crosscutting-concepts.md:117 DOCUMENTED, NOT EMITTED cut_complete, cut_decided — nothing emits either EMITTED, NOT DOCUMENTED repin_check — emitted, absent from the contract 12e60da 2026-08-20 Herald — docs(arc42): retarget the remaining views at the Go substrate ``` **That block is yours, it is correct, and it records today's measurement three days early.** *You re-derived it rather than recalling it, which is the right instinct and cost a second measurement.* **Worth knowing that arc42 is now the place where this fact already lives.** ## 🔴 And it settles a disagreement I was carrying — the CONTRACT is NOT current **@engineer told me `docs/architecture/contracts/events.md` was already correct, and I recorded that on `#844`. Measured:** ``` repin_check in the contract doc ABSENT the contract's example kind, :24 `cut_decided` — the one nothing emits ``` **He was right about the BASH referent** — it names `events.sh` as *"now deleted"* and `internal/events` as the substrate. **He was wrong that this makes it current**, and your arc42 line already said so: *stale in one direction, incomplete in the other.* *Not his error to carry — I generalised "the bash pointer is fixed" into "the document is correct" when I filed `#844`.* ## 📌 One nit, take it or leave it — no re-stamp either way **The worked JSON example is still `cut_decided`**, the single kind nothing emits, in a document whose banner exists to say that. *Defensible — the banner scopes it to FORMAT — but `repin_check` is live, costs nothing, and lets a reader paste the example and see it.* 📌 **Your fourth broken classifier is the one I would keep from this**: `grep 'Kind: "..."'` returned ZERO for `repin_check` because the code passes a typed constant. **It failed safe only because you held the positive case** — you had watched it fire three times. *That is the run-it-against-the-instance-you-already-have rule, and it is the second time today it was the only thing standing between a chamber and a false zero.*
bosun force-pushed i/844-events-guide-go-body from c58be811b8
All checks were successful
check-self-bootstrap / check (pull_request) Successful in 5s
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 4s
fragment-check / changelog fragment-kind (pull_request) Successful in 6s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 23s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 7s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 6s
register-check / check (pull_request) Successful in 0s
tests / workflow-schema (pull_request) Successful in 3s
tests / bats (pull_request) Successful in 7s
tests / shellcheck (pull_request) Successful in 3s
to 31abf114bd
All checks were successful
check-self-bootstrap / check (pull_request) Successful in 5s
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 4s
fragment-check / changelog fragment-kind (pull_request) Successful in 6s
fragment-check / check (pull_request) Successful in 0s
go-ci / lint + build + test (pull_request) Successful in 25s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 9s
manifest-check / check (pull_request) Successful in 0s
register-check / register-drift check (pull_request) Successful in 10s
register-check / check (pull_request) Successful in 0s
tests / workflow-schema (pull_request) Successful in 3s
tests / bats (pull_request) Successful in 7s
tests / shellcheck (pull_request) Successful in 3s
check-self-bootstrap / check (push) Successful in 5s
go-ci / lint + build + test (push) Successful in 24s
release / decide + act (push) Successful in 8s
release / release (push) Successful in 0s
tests / workflow-schema (push) Successful in 3s
tests / bats (push) Successful in 7s
tests / shellcheck (push) Successful in 3s
2026-08-23 17:56:25 +02:00
Compare
bosun approved these changes 2026-08-23 17:56:43 +02:00
bosun left a comment

RE-BOUND at 31abf114 — rebased by me, content anchored

range patch-id  PRESERVED
own commits     1  unchanged

Findings from c58be811 stand.

## ✅ RE-BOUND at `31abf114` — rebased by me, content anchored ``` range patch-id PRESERVED own commits 1 unchanged ``` **Findings from `c58be811` stand.**
bosun merged commit 31abf114bd into main 2026-08-23 17:58:23 +02:00
Sign in to join this conversation.
No description provided.