fix(skills/app-screenshot-capture): read OPP_NAME from run_state.yaml, not slug-reassembly#356
Merged
Merged
Conversation
…, not slug-reassembly
Phase 6's `connect-claim-opp.yaml` recipe matches the opportunity tile in
Connect via an `assertVisible(text: ${OPP_NAME})`. The subagent was
composing OPP_NAME from slug pieces — `"<org_slug> - <slug> (run <date>)"`
with an ASCII hyphen and the org slug as prefix — while the live tile text
Connect renders is `"<display_name> — <slug> (run <date>)"` with an em-dash
(U+2014) and the display name. Result: every Phase 6 first attempt missed
the tile, then self-corrected mid-dispatch by calling
`connect_get_opportunity` — one wasted recipe cycle per run.
Phase 4 (`connect-opp-setup`) already writes the exact tile name to
`phases.connect-setup.products.connect.opportunity.name` at the moment it
creates the opportunity in Connect. Verified live on malaria-itn-fgd run
20260515-1645 — the field IS present and IS the em-dash form. The schema
in `connect-opp-setup` just didn't document it.
Fix (docs-only — the slug-reassembly was prose, not code):
- `skills/app-screenshot-capture/SKILL.md` Step 4 — declare an authoritative
read of `phases.connect-setup.products.connect.opportunity.name`, with a
`[WARN]`-logged `connect_get_opportunity().name` fallback only for legacy
runs missing the field. Update the now-outdated "Step 4 OPP_NAME
uniqueness" prose to cite the live em-dash format. Tighten the
recipe-sanity-probe remediation row and the "no matching tile" failure
row to point at the canonical source.
- `agents/qa-and-training.md` Pre-flight checklist — name the field path
explicitly so the subagent doesn't paraphrase.
- `mcp/mobile/recipes/static/connect-claim-opp.yaml` header — cite the
field path + spell out the slug-reassembly anti-pattern with the live
malaria-itn-fgd example.
- `skills/connect-opp-setup/SKILL.md` schema block — document the `name:`
field (was already being written, just undocumented).
Structural rationale: insulate Phase 6 from Connect's name-formatting
changes. Read what Phase 4 wrote when it created the opp, not what the
Connect UI happens to render today. The slug-reassembly path is now a
named anti-pattern.
Live reproducer: malaria-itn-fgd run 20260515-1645 Phase 6 attempt 9.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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.
Summary
Phase 6's
connect-claim-opp.yamlrecipe matches the opportunity tile in Connect viaassertVisible(text: ${OPP_NAME}). The subagent was composing OPP_NAME from slug pieces —"<org_slug> - <slug> (run <date>)"with ASCII hyphen + org slug prefix — while the live tile text Connect renders is"<display_name> — <slug> (run <date>)"with em-dash (U+2014) + display-name prefix. Result: every Phase 6 first attempt missed the tile, then self-corrected mid-dispatch viaconnect_get_opportunity— one wasted recipe cycle per run.Phase 4 (
connect-opp-setup) already writes the exact tile name tophases.connect-setup.products.connect.opportunity.name. Verified live on malaria-itn-fgd run 20260515-1645 — field present with the em-dash form. The schema inconnect-opp-setupjust didn't document it.This is a docs-only patch (the slug-reassembly was subagent prose interpretation, not code):
skills/app-screenshot-capture/SKILL.mdStep 4 — declare authoritative read ofphases.connect-setup.products.connect.opportunity.name, with[WARN]-loggedconnect_get_opportunity().namefallback for legacy runs. Update outdated "OPP_NAME uniqueness" prose to cite the live em-dash format. Tighten failure-mode remediation rows.agents/qa-and-training.mdPre-flight — name the field path explicitly so the subagent doesn't paraphrase.mcp/mobile/recipes/static/connect-claim-opp.yamlheader — cite the field path + spell out the slug-reassembly anti-pattern with the live malaria-itn-fgd example.skills/connect-opp-setup/SKILL.mdschema block — document thename:field (already written, just undocumented).Structural rationale: insulate Phase 6 from Connect's name-formatting changes. Read what Phase 4 wrote when it created the opp, not what the Connect UI happens to render today.
Live reproducer: malaria-itn-fgd run 20260515-1645 Phase 6 attempt 9.
Test plan
npm test— only failure is pre-existing OCS atom-count snapshot drift (reproduces on origin/main without my changes), unrelated to this docs-only patchphases.connect-setup.products.connect.opportunity.nameexists in live run_state.yaml (malaria-itn-fgd/20260515-1645) with the em-dash formconnect_get_opportunityself-correction in transcript)🤖 Generated with Claude Code