Skip to content

kernel: govern the M6 event pathway — t_hook firings stage governance_proposals (closes #53)#56

Merged
MSD21091969 merged 2 commits into
masterfrom
feat/t250-m6-event-governance
Jul 9, 2026
Merged

kernel: govern the M6 event pathway — t_hook firings stage governance_proposals (closes #53)#56
MSD21091969 merged 2 commits into
masterfrom
feat/t250-m6-event-governance

Conversation

@MSD21091969

Copy link
Copy Markdown
Collaborator

HG URN: urn:moos:session:sam.kernel-proper

Summary

  • The M6 event pathway no longer auto-applies react_template results ungoverned: event-fired t_hooks now stage an ADD-governance_proposal + firing_state pending→proposed pair — parity with the TIME sweep (Sam ruling t250-Q4, recorded 93c86ce; fp-fruits finding v).
  • reactive.Firing + EvaluateDetailed add pass provenance (reactor | t_hook); Evaluate stays a thin wrapper (all call sites unchanged).
  • Staging-pair builder stageHookProposalPair extracted from SweepOnce — parity by construction; sweep behavior byte-preserved (URN scheme, counter arithmetic, property set).
  • Event staging: idempotency filter (firing_state ∈ {"", pending}), substituted proposed_envelope normalized to JSON-map form (CI-4 Go-value replay parity), per-firing URN discriminator -evt<seq>-n<i>, M8 gate pre-flight on the whole pair (fail-closed batch parity), PropertySpec injection + registry-less fallback.
  • applyStagedLocked mirrors ApplyProgram's checks for kernel-internal staging (no ValidateMUTATE — the sweep path never calls it; requiring a rewrite_category would silently reject hooks carrying explicit firing_state and spam one duplicate proposal per trigger).

Why

runtime.go runReactive folded t_hook react_template results straight into state — skipping §M11/§M12, M8 gates, and the firing_state machine (F-a class). Ruling: govern it, unless a load-bearing fast path is demonstrated. Fleet inventory: zero live react_templates across all 5 reachable folds → the ruling's default branch; no allowlist machinery built (nothing to declare — a future consumer that needs the fast path is the change that declares it).

Watcher/reactor (WF17 Pass-1) keeps immediate apply — same F-a class, out of this ruling's scope; follow-up issue to be filed.

Adversarial review (pre-PR)

12-agent, 3-lens refute-verify workflow: 8 confirmed findings → 4 root defects, all folded:

  1. ValidateMUTATE standard-path rejection for hooks with explicit firing_state → unbounded duplicate proposals (major)
  2. M8 gate bypass on event staging vs sweep fail-closed (major)
  3. Same-slug proposal-URN collision, loser dropped with no retry clock (minor)
  4. Typed graph.Envelope live vs map[string]any replayed — CI-4 Go-value divergence (minor)

Validation

go test ./...   — all packages ok (fold, graph, hdc, kernel, operad, reactive, tday, transport)
go vet ./...    — clean

Live throwaway :8899 (real 4.0.1 ontology, registry mode), both hook shapes:

  • additive (no firing_state authored): trigger → log +3 exact, template withheld, hook parks proposed, 2nd trigger +1 / still 1 proposal
  • explicit-pending (defect-1 case): identical — staging lands via the standard fold path, no duplicate spam
  • staged URN carries the -n discriminator: urn:moos:proposal:kernel.<slug>-t250-evt<seq>-n0

New tests: THookStagesProposal (rewrites the old fast-path test), THookExplicitPendingStages, THookGateBlocksStaging, THookSameSlugNoCollision, THookEventIdempotency.

Notes

Closes #53

🤖 Generated with Claude Code

…_proposals (closes #53)

Parity with the TIME sweep per Sam ruling t250-Q4: event-fired t_hooks now
stage an ADD-governance_proposal + firing_state pending->proposed pair
instead of auto-applying react_template ungoverned (fp-fruits finding v,
F-a class). Watcher/reactor (WF17 Pass-1) keeps immediate apply - same
class, out of ruling scope, flagged follow-up.

- reactive: Firing{Proposal,SourceHook,Kind} + EvaluateDetailed; Evaluate
  stays as a provenance-erasing wrapper (call sites unchanged)
- kernel: stageHookProposalPair extracted from SweepOnce (shared builder,
  parity by construction); runReactive routes by Kind
- stageEventHookLocked: firing_state idempotency filter (sweep parity),
  substituted proposed_envelope normalized to JSON map (CI-4 Go-value
  replay parity), per-firing URN discriminator -evt<seq>-n<i>, M8 gate
  pre-flight on the whole pair (fail-closed batch parity), PropertySpec
  injection + registry-less fallback
- applyStagedLocked: staging apply that mirrors ApplyProgram's checks (no
  ValidateMUTATE - the sweep path never calls it; requiring a category
  would reject hooks carrying explicit firing_state and spam duplicates)
- applyReactiveLocked returns bool (landed or not)
- tests: THookFires rewritten as THookStagesProposal; new
  THookExplicitPendingStages, THookGateBlocksStaging,
  THookSameSlugNoCollision, THookEventIdempotency

Adversarial review (12 agents, 3 lenses, refute-verify): 8 confirmed
findings folded (4 root defects: ValidateMUTATE standard-path rejection ->
duplicate-proposal spam; M8 gate bypass; same-slug URN collision; typed-
struct vs replay-map divergence). Live throwaway gates: additive AND
explicit-pending cases stage exactly (+3), template withheld, idempotent.

Zero live react_templates fleet-wide (5 folds inventoried) -> no
load-bearing fast path -> ruling default (govern), no allowlist machinery.

authored-by: agent:claude-cowork.hp-z440 / session:sam.z440-cowork-workspace / t250-m6-event-governance

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR changes the kernel’s M6 event-pathway handling of t_hook firings so they no longer immediately apply react_template results, and instead stage them as governed governance_proposal + firing_state transitions to match TIME sweep behavior.

Changes:

  • Adds provenance-aware reactive evaluation (EvaluateDetailed) so the runtime can distinguish t_hook firings from watcher/reactor firings.
  • Extracts and reuses a shared staging-pair builder (stageHookProposalPair) for both TIME sweep and event-pathway staging.
  • Implements event-pathway staging in the runtime with idempotency filtering, M8 gate preflight on the whole pair, and replay-parity normalization of proposed_envelope, plus new tests for these behaviors.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
internal/reactive/engine.go Introduces Firing and EvaluateDetailed to carry provenance (reactor vs t_hook) to the kernel.
internal/kernel/sweep.go Extracts stageHookProposalPair so sweep staging and event staging share the same two-envelope shape.
internal/kernel/runtime.go Routes reactive firings: stage t_hook firings as proposals; keep watcher/reactor immediate apply; adds staging helper paths.
internal/kernel/runtime_reactive_test.go Replaces the prior fast-path test with governed staging tests (idempotency, gates, collisions, explicit pending).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +594 to +599
switch f.Kind {
case "t_hook":
rt.stageEventHookLocked(f, trigger, i)
default: // "reactor" — WF17 watcher/reactor chain, unchanged.
rt.applyReactiveLocked(f.Proposal)
}
Comment on lines +27 to +31
type Firing struct {
Proposal graph.Envelope
SourceHook graph.URN // set when Kind == "t_hook"
Kind string // "reactor" | "t_hook"
}
…il-closed routing on unknown kinds

authored-by: agent:claude-cowork.hp-z440 / session:sam.z440-cowork-workspace / t250-m6-event-governance

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@MSD21091969 MSD21091969 merged commit 7a4981f into master Jul 9, 2026
1 check passed
@MSD21091969 MSD21091969 deleted the feat/t250-m6-event-governance branch July 9, 2026 11:38
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.

M6 event pathway: govern the react_template fast path (parity with TIME) — Sam ruling t250-Q4

2 participants