Skip to content

docs(spike): make live-surface recon a first-class phase - #704

Merged
ffroliva merged 1 commit into
developfrom
feature/spike-first-class
Sep 6, 2026
Merged

ffroliva merged 1 commit into
developfrom
feature/spike-first-class

Conversation

@ffroliva

@ffroliva ffroliva commented Sep 6, 2026

Copy link
Copy Markdown
Owner

Summary

The HAR/DOM harness landed in #703, but nothing routed to it — so an agent still had to stumble on it. That is the failure that cost a day: a working feature was declared impossible because nobody measured it, and the harness that would have settled it in thirty minutes sat undiscovered.

This makes recon a phase, not a tool.

  • skills/spike/SKILL.md — canonical, agent-agnostic (Codex / Cursor / Aider read the same file), plus the /gflow:spike wrapper
  • AGENTS.md Skill Routing — added as the first row, because it gates the others
  • Standard Workflow Sequence — new Phase 0: Recon, before Triage
  • issue-assessment — a "Before you classify an absence" section. A verdict of INVALID / "not supported on this host" is a claim about the live product, and that skill is read-only, so it cannot produce one from the code alone. Closing a reporter's issue on an unmeasured negative tells a user their working feature is impossible.

The rule

A selector that does not match is evidence about the SELECTOR.
It is never evidence about the FEATURE.
Never put a guard in front of a probe.

Both halves come from the same failure. "character create is a labs-only surface — renders no prompt textbox for it, ever" came from one 20 s selector timeout and reached four places: a code comment, the CHANGELOG, the v0.70.0 release ledger, and a test class name. #701 then added a guard that aborted before probing the DOM — which made the claim unfalsifiable, because no run could ever look.

New finding recorded, not yet acted on

docs/superpowers/spikes/2026-09-06-migrated-character-surface-and-recaptcha.md records the full recon behind #703, plus something new:

flow.google.com CAN mint a reCAPTCHA Enterprise token.

route recaptcha scripts site key grecaptcha.enterprise mint
flow.google.com/ (root grid) 0 — false ❌ RecaptchaError
flow.google.com/project/<id> 2 6LdsFiUsAAAA… true ✅ OK, 2404-char token

The mint guard refuses the whole host when the pooled bootstrap page is simply on the wrong route. That is the mechanism behind #692 — whose reporter's bundle showed route: "/", and diagnostics.py maps both hosts to host_category: flow_app, so the route is the only tell.

Deliberately not claimed: that fixing the mint unblocks gflow image. That path is UI-driven (mint → drive the composer), and the migrated project composer inventories as video-only — movie, apps_spark_2, crop_16_9, [role=tab] = 0, no image-mode control. Image generation exists on that host only inside the character editor. So the mint is necessary, not sufficient, and "one anchor sweep away" is recorded as unproven.

Test plan

  • All six doc/hygiene gates green (check_doc_links, check_repo_hygiene over 1008 files, check_council_memory, generate_website_docs --check, check_website_docs_pii, ruff)
  • 43 documentation/skill/agents gate tests pass
  • scripts/dev/spike_migrated_recaptcha_mint.py is committed and re-runnable; its evidence is gitignored
  • Docs-only plus one spike script — no Flow surface touched, so no e2e applies (AGENTS.md's explicit out-of-scope case)

gflow-cli drives a product it does not own, so every claim about what Flow
does is either measured or guessed — and a guess written into code or docs
becomes a fact nobody re-checks. The harness for measuring existed but was
not routed to, so it was not used.

Adds `skills/spike/SKILL.md` (canonical, agent-agnostic) plus its
`/gflow:spike` wrapper, and wires it in where it actually bites:

  * AGENTS.md Skill Routing — first row, because it gates the others
  * the Standard Workflow Sequence gains Phase 0 (Recon) before Triage
  * `issue-assessment` gets a "Before you classify an absence" section: a
    verdict of INVALID / "not supported on this host" is a claim about the
    live product, and that skill is read-only, so it cannot produce one from
    the code alone

The rule it enforces:

    A selector that does not match is evidence about the SELECTOR.
    It is never evidence about the FEATURE.
    Never put a guard in front of a probe.

Both halves are written from the same failure. "character create is a
labs-only surface, it renders no prompt textbox EVER" came from one 20 s
selector timeout and reached four places — a code comment, the CHANGELOG,
the v0.70.0 release ledger, and a test class NAME. #701 then added a guard
that aborted before probing the DOM, which made the claim unfalsifiable:
no run could look. The feature had worked the whole time.

Also records the recon itself, including a result that is new and not yet
acted on: flow.google.com CAN mint a reCAPTCHA Enterprise token. On
/project/<id> the enterprise script and site key are present and a mint
returns a 2404-char token; on the root grid there is no script at all. The
mint guard refuses the host when the pooled page is simply on the wrong
route — the mechanism behind #692, whose reporter's bundle showed
route: "/". Deliberately NOT claimed: that fixing the mint unblocks
`gflow image`. That path is UI-driven and the migrated project composer
inventories as video-only, so the mint is necessary, not sufficient.
@ffroliva
ffroliva merged commit b69e7ae into develop Sep 6, 2026
15 checks passed
ffroliva added a commit that referenced this pull request Sep 6, 2026
Two corrections in one, both prompted by the operator asking whether
`diagnostics` was really the right home.

NAME. `recon` is five letters against eleven, and it is already this
repo's word: 16 doc occurrences including ASSET_TAGGING_RECON.md, plus
the "Phase 0: Recon" the workflow gained in #704. It also means exactly
what this does — observing terrain we do not control. Rejected:
`probe` (collides with scripts/dev/probes/), `trace` (observability.py
owns that vocabulary), `capture` (collides with #707's likely command
name), `evidence` (good, but the word appears 84 times in docs already).

STRUCTURE, and this is the more important half. Folding live capture into
`diagnostics` was conflation, not consolidation. `diagnostics` classifies
and summarises what already went wrong, post-hoc, for an incident bundle.
Recon actively drives a browser to observe a live surface. Different
activity, different lifecycle. Promoting a shipped 1890-line module with
four importers to a package would have been risk taken for no benefit.

What actually needed consolidating was never the module count — it was
REDACTION, which has three implementations today (redaction.py,
diagnostics.sanitize_url, extract_har_summary's header/URL handling).
Task 2 still merges them, and both diagnostics and recon share the
result. The plan keeps the real fix and drops the imagined one.

diagnostics.py is now listed as UNCHANGED apart from sanitize_url
delegating, so its four importers are untouched.
@ffroliva
ffroliva deleted the feature/spike-first-class branch October 22, 2026 19:14
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.

1 participant