fix(activity): spawn's docs named a recipe purpose that resolves to NOTHING (#274) - #2277
Open
joelteply wants to merge 1 commit into
Open
fix(activity): spawn's docs named a recipe purpose that resolves to NOTHING (#274)#2277joelteply wants to merge 1 commit into
joelteply wants to merge 1 commit into
Conversation
…OTHING (#274) `activity/spawn` told every caller — human, citizen, and schema consumer — that the recipe argument takes `benchmark`. No such purpose exists. The authored recipe's purpose is `benchmark/hard-rs`, and `RecipeExperienceSource` keys on the exact string, with `unknown_purpose_yields_none` pinning that an unknown purpose resolves to `None`. So a caller following the documented affordance got a room bound to a purpose nothing can project. Per the binding comment in spawn's own `run`, that room then "will project as a plain chat room". A benchmark run silently becoming a chat room is the academy failure in miniature — and academy is exactly what we have: 131 cards accumulated in ONE room, 130,954 work events against 910 messages, 36 cards frozen under claims heartbeating unbroken since 2026-08-07. The stale list appeared TWICE — the command DESCRIPTION (what a citizen reads when choosing a tool) and the `recipe` param doc (what schema consumers read). Both fixed. Deliberately NOT replaced with a corrected list. Recipes are DATA, overlaid from disk by `builtins_with_overlay`, so any enumeration in a comment is stale the moment someone authors a recipe — re-hardcoding exactly what the loader exists to keep dynamic. Both docs now point at the catalogue and state the rule that matters: the purpose is EXACT, family names do not resolve. NOT FIXED, and it is the bigger half: spawn does not VALIDATE that the recipe resolves. A typo still mints a chat room silently — a fallback, in a subsystem whose own loader cites [[fallbacks-are-illegal-fail-loud]]. The fix needs the experience source threaded into ActivitySpawn so it can refuse with the live `purposes()` list, which already exists. Tracked on #274. Docs only; no behaviour change beyond what callers are told. No generated TS binding exists for ActivitySpawnParams, so no binding drift. Verified: rustfmt --check clean on the changed file, cargo check -p continuum-core --lib --features metal,accelerate clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LoTjvf5j3Ez13g6k8mRkFo
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.
activity/spawntold every caller — human, citizen, and schema consumer — that the recipe argument takesbenchmark. No such purpose exists.The authored recipe's purpose is
benchmark/hard-rs.RecipeExperienceSourcekeys on the exact string, andunknown_purpose_yields_nonepins that an unknown purpose resolves toNone. So anyone following the documented affordance got a room bound to a purpose nothing can project — and per the binding comment in spawn's ownrun, that room then "will project as a plain chat room."A benchmark run silently becoming a chat room is the academy failure in miniature. And academy is what we have: 131 cards accumulated in one room, 130,954 work events against 910 messages, 36 cards frozen under claims heartbeating unbroken since 2026-08-07 with two releases ever.
The stale list appeared twice — the command
DESCRIPTION(what a citizen reads when choosing a tool) and therecipeparam doc (what schema consumers read). Both fixed.Why not just substitute a corrected list
Recipes are data, overlaid from disk by
builtins_with_overlay. Any enumeration in a comment is stale the moment someone authors a recipe — it re-hardcodes precisely what the loader exists to keep dynamic. Both docs now point at the catalogue and state the rule that actually matters: the purpose is exact, family names do not resolve.Not fixed here, and it's the larger half
Spawn does not validate that the recipe resolves. A typo still mints a chat room silently — a fallback, in a subsystem whose own loader cites
[[fallbacks-are-illegal-fail-loud]]. The fix needs the experience source threaded intoActivitySpawnso it can refuse with the livepurposes()list, which already exists. Tracked on #274.Related and also open: the only authored benchmark recipe is one specific gym, so
academy/bench/<swe-run>has no template. Per this module's own design that's an authoring act — a new recipe file, zero code — not a mechanism to invent.Verification
rustfmt --checkclean on the changed filecargo check -p continuum-core --lib --features metal,acceleratecleanActivitySpawnParams, so no binding drift🤖 Generated with Claude Code
https://claude.ai/code/session_01LoTjvf5j3Ez13g6k8mRkFo