hot-fix(critic-sdk): event capture field-name mismatch broke brainstormer#147
Merged
Merged
Conversation
…rmer Dogfood-caught running ``forge-loop brainstorm`` against Titan: ``empty SDK output`` on every invocation. Root cause: a two-field mismatch between _critic_sdk and _worker_sdk. forge_loop._worker_sdk emits events with key ``kind`` (NOT ``type``) and the session-end kind is ``final_result`` (NOT ``result``). _critic_sdk's on_event capture looked for ``event["type"] == "result"`` and silently never matched, so every assistant text was discarded. Also, the SDKRunResult fallback at ``getattr(result, "last_message", "")`` returned "" because the field is actually ``final_result_text``. Result: critic, PO, and brainstormer SDK paths ALL returned empty ``last_message`` in production — which previously surfaced as a parse error after the empty text. The bundled CLI is healthy (verified with a direct call); only the field-name plumbing was broken. Fix: - _critic_sdk._capture now reads ``event["kind"]`` first, falls back to ``event["type"]`` for forward/backward compat. Matches kind ``final_result`` (canonical) and ``assistant_text``. - The result fallback now checks ``final_result_text`` first, then legacy ``last_message``. Tests: tests/test_critic_sdk_event_capture.py — 3 new - Headline regression pin: ``event["kind"] == "final_result"`` populates ``result.last_message``. - Fallback: ``final_result_text`` on the SDKRunResult is the second source of truth. - Defensive: legacy ``event["type"]`` field still tolerated. Full suite: 927 passed (was 783; net +144 from loop's recent work + 3 from me).
5 tasks
hadamrd
added a commit
that referenced
this pull request
May 28, 2026
…loop) (#149) Closes the feedback loop the CTO described: every bug we fix becomes a permanent gate. Today's PR #147 (critic SDK event-capture mismatch) exposed a 4-PR train of bugs with the same shape — #97, #120, #128, #147 — all driven by string-literal discriminators that didn't match across module boundaries. The critic (PR #141) reads the quality manifesto + flags sev1 violations. This rule + the critic infrastructure together mean the next worker that writes ``event["type"] == "result"`` (or similar cross-module string-comparison) gets the PR auto-blocked with the manifesto rationale.
hadamrd
added a commit
that referenced
this pull request
May 28, 2026
Adds the customer-facing documentation for the manifestos + brainstormer feature that closed the cosmetic-tickets gap. Real customers consuming this OSS need to know: 1. The four files they own (.forge/product-vision.md, axes.yaml, quality-manifesto.md, testing-manifesto.md). 2. The brainstormer dry-run + --apply workflow. 3. The feedback loop (`forge-loop manifesto suggest --from-pr <N>`) where every bug becomes a permanent gate. 4. What the worker + critic see (manifestos injected into briefs; sev1 violations block auto-merge). README: new section "Manifestos & the brainstormer (axis-aligned tickets)" between Briefs and CLI reference. CLI reference table gains `brainstorm`, `brainstorm --apply`, `manifesto suggest --from-pr`. GUIDE: new section 4 "Manifestos: drive what gets built (not just how)" between "discipline matters" and "the brief is your contract" — with the real Titan brainstormer output as the worked example. Sections 5-10 renumbered accordingly. Both docs cite PR #147 as the canonical feedback-loop example: a stringly-typed event-boundary bug that surfaced after #97/#120/#128 all had the same shape; the fix landed the manifesto rule that the critic now enforces.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Dogfood-caught running forge-loop brainstorm against Titan: every invocation returned empty SDK output. The capture looked for event['type'] == 'result' but worker SDK emits event['kind'] == 'final_result'. Two-field-name mismatch. Same bug had been silently breaking critic + PO SDK paths since #103/#123. Three regression tests pin the canonical + fallback + legacy paths.