Skip to content

fix: honor --incognito by disabling the experience tracker (plan 009)#78

Closed
DavertMik wants to merge 3 commits into
mainfrom
fix/incognito-flag
Closed

fix: honor --incognito by disabling the experience tracker (plan 009)#78
DavertMik wants to merge 3 commits into
mainfrom
fix/incognito-flag

Conversation

@DavertMik

Copy link
Copy Markdown
Contributor

Implements plan 009 (plans/009-wire-incognito-flag.md) — a P2 bug fix (deferred finding CORRECTNESS-03).

Problem

explorbot --incognito promises "Run without recording experiences". The flag travels CLI → ExplorBot → Explorer, and Explorer calls new StateManager({ incognito: ... }) — but StateManager's constructor took no parameters, so the object argument was silently ignored and the ExperienceTracker it created was fully enabled. Incognito runs read and wrote ./experience/ exactly like normal runs; the user's explicit "don't learn from this session" request was dropped without any error (no typecheck gate to catch it).

Fix

Thread incognito into the constructor and pass it through to the tracker, which already supports { disabled }:

constructor(options: { incognito?: boolean } = {}) {
  this.experienceTracker = new ExperienceTracker({ disabled: options.incognito });

disabled: undefined collapses to false via the tracker's options.disabled ?? false, so the two argumentless new StateManager() call sites keep today's behavior. explorer.ts:85 was already correct and needs no edit.

Verification

  • New tests: new StateManager({ incognito: true }) → disabled tracker; default → enabled. (Asserted via the plan's sanctioned (tracker as any).disabled fallback.)
  • bun test tests/unit → 728 pass, 0 fail; bun run lint clean.

Known gap (out of scope, per plan)

Agents that construct their own ExperienceTracker (Navigator, Captain) bypass this flag until the DI-consolidation plan lands.

🤖 Generated with Claude Code

`explorbot --incognito` ("Run without recording experiences") flowed CLI ->
ExplorBot -> Explorer, and Explorer called `new StateManager({ incognito })` —
but StateManager's constructor took no parameters, so the flag was silently
dropped and the ExperienceTracker was always enabled. Incognito runs read and
wrote ./experience like normal runs.

Thread `incognito` into the StateManager constructor and pass
`{ disabled: options.incognito }` to ExperienceTracker (which already supports
`disabled`). Argumentless constructions keep today's enabled behavior via
`options.disabled ?? false`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 11, 2026

Copy link
Copy Markdown

Explorbot Self-Regression

Commit 5050c6c · run

Scenario Result Attempts Duration
basic (native) FAIL 3/3 26m

Attempt details

  • basic (native) attempt 1 — FAIL: login evidence: PASS (post-login plan=true, post-login research=true); research: PASS (files=8, wellFormed=true, keywords=7/3); scenarios: PASS (tests=7/5, features=4/3); tests passed: FAIL (3 passed, 2 failed (reporter: 3 passed, 2 failed))
  • basic (native) attempt 2 — FAIL: login evidence: PASS (post-login plan=true, post-login research=true); research: PASS (files=7, wellFormed=true, keywords=7/3); scenarios: PASS (tests=7/5, features=4/3); tests passed: FAIL (3 passed, 2 failed (reporter: 3 passed, 2 failed))
  • basic (native) attempt 3 — FAIL: login evidence: PASS (post-login plan=true, post-login research=true); research: PASS (files=6, wellFormed=true, keywords=7/3); scenarios: PASS (tests=6/5, features=4/3); tests passed: FAIL (4 passed, 1 failed (reporter: 4 passed, 1 failed))

Session analysis — basic (native):

Session Analysis

The Issues list page core flows work: creating new issues, searching by text, filtering by label, and viewing issue details all function correctly. The status filter functionality works (ET-3 verification passed), but the automation stalled after verification, requiring investigation.

Coverage

What works

  • New Issue formET-1 Create a new issue via toolbar button
  • Text searchET-2 Search for issues by text and verify filter works
  • Label filterET-4 Filter issues by label and verify results
  • Issue detail viewET-5 Open an issue from the list to view its details

Execution Issues

  • ET-3 Filter issues by status and verify results — verification passed (filter worked, correct issues shown) but automation stalled with "No browser progress after repeated attempts" after the test assertions succeeded

… (plan 010) (#79)

* refactor: delegate StateManager knowledge loading to KnowledgeTracker

StateManager contained a complete second implementation of knowledge-file
loading (scanKnowledgeFiles + its own cache + dir resolution) that had diverged
from KnowledgeTracker.loadKnowledgeFiles — most importantly, the StateManager
copy did NOT run ${env.*}/${config.*} interpolation. Researcher (the only
production consumer of the StateManager copy) therefore saw raw
${env.PASSWORD} text while Navigator, TaskAgent, ExperienceTracker and commands
saw interpolated content for the same page.

Delete the copy and delegate to KnowledgeTracker (the CLAUDE.md single owner of
the knowledge dir), sharing one tracker instance from Explorer. Make the tracker
scan recursively (superset of both implementations), invalidate its isLoaded
cache on addKnowledge (so a same-instance /learn read sees the write), and unify
the two divergent Knowledge types onto one exported interface.

Intended behavior deltas: the 30s rescan is gone (in-app writes picked up via
addKnowledge invalidation), recursive scan now applies to every consumer, and
Researcher now receives interpolated knowledge.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: give KnowledgeTracker a 30s refresh TTL (mid-session knowledge staleness)

Deleting StateManager's knowledge scanner (which rescanned every 30s) left the
shared KnowledgeTracker caching forever; addKnowledge's isLoaded invalidation is
per-instance, so /learn (which builds its own tracker) and hand-edited files were
never picked up by Explorer's shared instance until restart — and CLAUDE.md's
documented "30-second refresh" existed nowhere.

Restore the refresh in the single owner: loadKnowledgeFiles re-scans when the
cache is older than 30s (KNOWLEDGE_REFRESH_MS), so on-disk changes from any
source reach every consumer. Same-instance addKnowledge still forces an immediate
reload via isLoaded=false.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: DavertMik <davert@testomat.io>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
@DavertMik

Copy link
Copy Markdown
Contributor Author

Closing — re-creating plans 009 and 010 as separate independent PRs off main (this branch had both entangled).

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