feat(intelligence): wire canonical runs to the SDK — hooks, recordTrace, effort compiler#287
Merged
Merged
Conversation
…peAnalyst Thread an optional ScopeAnalyst<D> through ShapeContext / RunPersonifiedOptions / createShapeContext, and consult it at the two combinator steer gates (loopUntil.until, widen.gate.decide) instead of the hardcoded empty findings array. The analyst spawns into the SAME scope (createScopeAnalyst), so its compute stays on the conserved budget pool — equal-k holds by construction. Absent an analyst the gates keep the dormant [] default (no behavior change). Add registryScopeAnalyst: a ScopeAnalyst backed by an AnalystRegistryLike that merges N analyst kinds into one findings list and pipes them through the same assertTraceDerivedFindings firewall createScopeAnalyst uses (single-sourced selector≠judge). The ScopeAnalyzeInput→registry-inputs projection is caller-supplied (buildInputs), not an invented bridge.
…ce, effort compiler
Close the four small wiring gaps so a canonical runPersonified run observes and
ships through the Intelligence SDK without a new primitive on either side.
1. runPersonified can subscribe to the Supervisor stream. Add `hooks?: RuntimeHooks`
to RunPersonifiedOptions and forward it into supervisorOpts.hooks. The Supervisor
already threads opts.hooks into the root Scope, which already emits agent.spawn /
agent.child — this is the load-bearing one-liner, no kernel change.
2. recordTrace(events) on the IntelligenceClient builds a nested loop -> round ->
iteration OTLP span tree via the EXISTING buildLoopOtelSpans into one traceId. No
second span builder; the topology a viewer renders matches the kernel's.
3. compileEffort(EffortSettings) in intelligence/effort.ts is a pure compiler from the
effort policy to run-config overrides (withAnalyst / fanout / withLoops /
intelligenceBudgetUsd). No `if (effort)` leaks into the supervise kernel.
4. OFF/eco degrade by construction: at analysts:false the caller omits the analyst
(withAnalyst:false) so the dormant empty-findings path runs and the base agent still
works. The product fail-closed ("don't construct the analyst") stays separate from
the experiment fail-closed inside createScopeAnalyst ("hard abort"), which is untouched.
Tests: runPersonified({hooks}) forwards agent.spawn/agent.child to a mock hook;
recordTrace produces the loop/round/iteration tree (asserting buildLoopOtelSpans, not a
flat builder) under one traceId; compileEffort maps off -> no-analyst/fanout-1,
standard -> analyst-on. Full suite green (886).
tangletools
previously approved these changes
Jun 14, 2026
tangletools
left a comment
Contributor
There was a problem hiding this comment.
✅ Auto-approved PR — 6b5e83ef
Blanket team auto-approval is enabled for this reviewer service.
The full PR reviewer audit still runs separately and will publish findings if it detects issues.
tangletools · auto-approval · reason: blanket_auto_approve · 2026-06-14T01:03:34Z
# Conflicts: # src/runtime/personify/types.ts
tangletools
approved these changes
Jun 14, 2026
tangletools
left a comment
Contributor
There was a problem hiding this comment.
✅ Auto-approved PR — 9d2bc175
Blanket team auto-approval is enabled for this reviewer service.
The full PR reviewer audit still runs separately and will publish findings if it detects issues.
tangletools · auto-approval · reason: blanket_auto_approve · 2026-06-14T01:13:15Z
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.
Close the four small wiring gaps from the unification audit so a canonical
runPersonifiedrun observes and ships through the Intelligence SDK in one line. Reuse-first: no new primitive on either side.The four gaps (file:line)
runPersonifiedsubscribes to the Supervisor stream —RunPersonifiedOptions.hooks?: RuntimeHooks(src/runtime/personify/types.ts:245) forwarded intosupervisorOpts.hooks(src/runtime/personify/persona.ts:152). The Supervisor already threadsopts.hooksinto the rootScope(supervisor.ts:130), which already emitsagent.spawn/agent.child(scope.ts:~219,345). The load-bearing one-liner — no kernel change.recordTrace(events)emits loop topology, not a flat span —IntelligenceClient.recordTrace(src/intelligence/index.ts) builds a nestedloop → round → iterationOTLP span tree via the existingbuildLoopOtelSpansinto onetraceId. No second span builder.compileEffortmakesEffortPolicygate at runtime —compileEffort(EffortSettings)(src/intelligence/effort.ts) is a pure compiler to run-config overrides (withAnalyst/fanout/withLoops/intelligenceBudgetUsd). Noif (effort)scattered into the supervise kernel.OFF/eco degrade, not throw — gated at the EffortPolicy layer:
analysts:false ⇒ withAnalyst:false ⇒the caller omits the analyst, so the dormant empty-findings path runs and the base agent still works. The product fail-closed ("don't construct the analyst") stays separate from the experiment fail-closed insidecreateScopeAnalyst("hard abort"), which is untouched.How each reused an existing primitive
SupervisorOpts.hooks+ theScopeagent.spawn/agent.childstream (already shipped).buildLoopOtelSpans(the shipped topology builder) +createOtelExporter.exportSpan.EffortSettingsshape; the compiler is pure data, the caller reads it once.Tests (reused harnesses)
tests/loops/personify.test.ts:runPersonified({hooks})forwardsagent.spawn/agent.childto a mock hook (and stays silent with no hooks).src/intelligence/intelligence.test.ts:recordTraceproduces theloop/loop.round/loop.iterationtree under onetraceId(assertingbuildLoopOtelSpans, not a flat per-event builder);compileEffortmapsoff ⇒ no-analyst/fanout-1,eco ⇒ analyst-on/no-breadth,standard ⇒ analyst-on/breadth/loops.npx tsc --noEmit+ Biome clean; fullpnpm testgreen (886 pass, 0 fail).Note on base: branched from
feat/analyst-steer-wireper the brief; targetingmainbecause that branch's work is already merged there (#284). Merges cleanly intoorigin/main.