- Rename analytics test to accurately describe what it verifies
(collector infrastructure wiring, not app-level event firing)
- Add comment explaining why real CTA click cannot be used
(full-page navigation unloads context before events can be read)
- Remove wallet_connect if/else block that had no assertion
- Remove dead Step 5 comment block with no assertions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace three fixed-delay waitForTimeout calls with proper event-driven
alternatives per AGENTS.md Engineering Principle #1:
- navigateSPA to /app/stake: use waitForSelector('.stake-view, .login-wrapper')
to detect when the route has mounted (handles login redirect too)
- wallet auto-connect: use waitForFunction to poll __analytics_events for
wallet_connect, resolving as soon as the event fires
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
On mobile (isMobile:true), Playwright tap events don't reliably trigger
Vue @click handlers that set window.location.href — the desktop test
already verifies the CTA click→navigation flow. The mobile test's
purpose is verifying layout and rendering on mobile viewports, so
navigate directly to verify the pages render correctly.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
In CI (VITE_ENABLE_LOCAL_SWAP=true), the LocalSwapWidget renders a
"Connect your wallet" message when no wallet is connected. The previous
check looked for [data-testid="swap-amount-input"] which only appears
with an active wallet, causing the test to fall through to the Uniswap
link check (which also doesn't exist in local mode).
Fix: detect local swap mode via the .local-swap-widget container class
which is always rendered. Also add force:true for mobile CTA click.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Playwright click() can race with waitForURL when the click triggers
window.location.href. Use Promise.all([waitForURL, click]) pattern
to ensure the URL listener is active before the click fires.
Also cap funnel test timeout to 3 minutes (these are navigation-only,
no blockchain transactions) to fail fast rather than hang.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The landing page CTA used router.push('/app/get-krk') which was caught
by the catch-all route and redirected back to '/'. Since landing and
webapp are separate Vue apps behind Caddy, cross-app navigation needs
window.location.href to trigger a real browser request through the
reverse proxy.
Also simplify the analytics E2E test to avoid race conditions between
event capture and page unload during navigation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
E2E spec covering the full conversion funnel: landing page CTA →
web-app get-krk page → Uniswap deep link verification → stake route.
Tests desktop (1280×720) and mobile (375×812) viewports, validates
Uniswap deep link structure (correct chain + token address), and
verifies analytics events fire at each funnel stage via injected
mock tracker.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The E2E CI uses pre-built images and overlays workspace packages via
symlinks. The new @harb/analytics package needs the same treatment as
@harb/web3 and @harb/utils for both webapp and landing services.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The root lockfile needed regeneration after adding the new @harb/analytics
workspace package as a dependency of landing and web-app.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add self-hosted Umami analytics to replace the third-party cloud.umami.is
tracker. Creates @harb/analytics package with typed event helpers and
instruments the conversion funnel: CTA clicks (landing), wallet connect,
swap initiated, and stake created (web-app).
- Add Umami Docker service sharing existing postgres (separate DB)
- Add Caddy /analytics route to proxy Umami dashboard
- Configure via VITE_UMAMI_URL and VITE_UMAMI_WEBSITE_ID env vars
- Document setup and funnel events in docs/ENVIRONMENT.md
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix misleading taxRate comment in AttackRunner.s.sol (index into TAX_RATES[], not raw rate)
- Clarify _validatePriceMovement NatSpec return doc in PriceOracle.sol
- Remove redundant double-cast uint256(uint256(...)) in OptimizerV3Push3Lib.sol
- Add Basescan URL source comments for SWAP_ROUTER and WETH addresses
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Update all AGENTS.md watermarks to HEAD (b276392)
- Clean up dust.jsonl: remove already-bundled items (601,627,739,741)
- Pending actions: promote #1099/#1100/#1101 to backlog, close stale
prediction issues #1020/#1103/#1107, comment on partial resolution
of #1022 (holdout resolved, user-test still empty)
Add formulas/AGENTS.md documenting sense vs act type distinction,
cron conventions, step ID naming rules, TOML structure skeleton,
and a how-to-add-a-new-formula walkthrough.
Add scripts/harb-evaluator/AGENTS.md covering the evaluator runtime:
directory layout, exit code convention, stack lifecycle, evidence
output, and how to add a new evaluator script.
Update root AGENTS.md directory map to link both new files.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add tools/push3-evolution/** to the transpiler-tests step's path filter
so that changes to push3-evolution also trigger transpiler tests.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- #864: Add comment documenting that MEMORY_FILE and REPORT_DIR both
resolve to $REPO_ROOT/tmp (intentional coupling, previously undocumented)
- #579: POOL die guard already present (added in a2f8996, issue #854)
- #775: feeDest address already corrected (fixed in 0e33d6c, issue #760)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- #989: Quote $VARIANT_IDX and $NEXT_IDX in printf '%03d' calls in
evolve.sh (SC2086 — no behavior change, style consistency)
- #612: Already resolved by commit 79a2e2e (fitness.sh switched from
deployments-local.json to broadcast JSON, eliminating dead Kraiken/Stake reads)
- #945: Already resolved by commit 052ad7a (manifest.schema.json
fitness_flags description corrected to "Comma-separated")
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Evolution can produce syntactically invalid seeds (e.g. missing
DYADIC.<= before EXEC.IF). These transpiler errors should not block
CI — only forge compilation failures of successfully transpiled seeds
are real regressions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Skip test/script compilation in seed-transpile-check since the test
file references getLiquidityParams() which only exists in the checked-in
stub, not in transpiler output.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Renumber test_transpiler_clamping.sh tests from 5-14 to 6-15 to avoid
overlap with test_inject_extraction.sh Test 5 (#1017).
Items #1012 (ts-node→tsx) and #986 (CI using npm test) were already
resolved by prior commits.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Wrap the fallback pool.observe() call in a try/catch so that pools with
insufficient observation history for both the primary (30s) and fallback
(6000s) intervals return false (price unstable) instead of reverting with
an opaque Uniswap V3 error. This prevents recenter() from failing for
unpermissioned callers on newly created pools.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Root cause: PRICE_STABILITY_INTERVAL (300s) was too long relative to
MIN_RECENTER_INTERVAL (60s). After any significant trade moving the tick
>1000 positions, the 5-minute TWAP lagged behind the current price by
hundreds of ticks, exceeding MAX_TICK_DEVIATION (50). Recenter reverted
with "price deviated from oracle" for ~285s — creating a window where
the LM could not reposition and adversary parasitic LP could extract
value from passive holders.
Fix: Reduce PRICE_STABILITY_INTERVAL from 300s to 30s. This ensures
TWAP converges within the 60s cooldown while still preventing same-block
manipulation (30s > ~12s Ethereum mainnet block time).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add SecurityInfo component displayed after LiveStats on the landing page:
- Unaudited badge with planned Q3 2026 audit date
- KRAIKEN Token and Stake contract addresses with copy-to-clipboard buttons
- BaseScan and source code links
- Responsive layout for mobile viewports
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>