Files
Imhotep/NEXT_STEPS_501.md

14 KiB

Next Steps — Feature Test Findings & V1.1 Definition

Date: 2026-05-01 Origin: Systematic feature testing across all documented Imhotep capabilities


Executive Summary

Systematic testing of all documented features in a clean temp directory revealed 6 critical bugs, 6 API/documentation mismatches, and 6 surprising behaviors that blocked external adoption.

V1.1 STATUS: COMPLETE — All critical bugs fixed, all documented features work, all tests pass (959 unit + 213 E2E), external smoke passes, build clean across all 14 packages.


P0 — Critical Bugs (All Fixed in V1.1)

These were the critical bugs identified during the V1.1 audit. All have been resolved.

1. Missing Selector Poisons Entire Batch

Bug: If ANY assertion references a missing selector, ALL assertions in the batch fail with IMH_SELECTOR_ZERO_MATCHES — even assertions with valid selectors that extract() can find independently.

Impact: One bad assertion makes an entire test file fail, destroying test isolation.

Repro:

ui.expect('.exists').to.be.leftOf('.also-exists')   // would pass alone
ui.expect('.missing').to.be.leftOf('.exists')        // should fail alone
// Result: BOTH fail with IMH_SELECTOR_ZERO_MATCHES

Fix: Filter selectors per-assertion. Only fail assertions whose own selectors don't match.

File: packages/imhotep-playwright/src/public.ts (extraction batching logic)


2. Dense DSL Size Assertions Broken at Runtime

Bug: ui.spec("'.button' atLeast 44px wide") parses correctly but checkAll() throws IMH_EXTRACT_PROTOCOL_ERROR: Unsupported selector format: . The empty reference string '' is included in allSelectors, and materializeSemanticSelector rejects it.

Impact: All unary size assertions via dense DSL are broken. Fluent API works fine.

Fix: In lowerSizeAssertionToCanonical, either omit reference field for unary assertions, or make extraction pipeline skip empty selectors.

File: packages/imhotep-dsl/src/compiler.ts (empty reference handling)


3. Default Gap Bounds Are Infinite (Relations Always Pass)

Bug: leftOf / rightOf / above / below default minGap to -Infinity and maxGap to Infinity. This makes ui.expect('.a').to.be.leftOf('.b') pass even when .a is to the right of .b.

Impact: Relations without explicit gap bounds assert nothing. Users think they're testing position when they're not.

Fix: Default minGap to 0 for directional relations. Require explicit negative gap if overlap is intended.

File: packages/imhotep-solver/src/predicates.ts:296-297


4. space: 'layout' Option Ignored in Options Object

Bug: { space: 'layout' } passed in relation options is silently ignored. Only .layout.to.be.leftOf(...) chaining works.

Impact: Users following README examples with { space: 'layout' } get visual-space evaluation instead.

Fix: Copy space from RelationOptions to AST in FluentRelation.toAst().

File: packages/imhotep-dsl/src/fluent.ts:636-638


5. focus-visible Kebab-Case Rejected

Bug: ui.materializeState('.button', 'focus-visible') throws "not supported". Internal validator only accepts 'focusVisible' (camelCase).

Impact: Users following common CSS convention get errors.

Fix: Normalize kebab-case to camelCase before validation, or accept both forms.

File: packages/imhotep-playwright/src/page.ts:151


6. Property Runner Creates Fresh Page Per Case

Bug: createFixtureRendererAdapter and createComponentRendererAdapter create a new page and navigate on EVERY mount. No caching state exists despite documentation claiming "page state caching reduces per-case overhead from ~770ms to ~60-90ms."

Impact: Property runs are ~10x slower than documented. CI timeout risk.

Fix: Implement cachedFixtureId, cachedImhotepPage, and containerReady state as described in NEXT_STEPS_429.md.

File: packages/imhotep-playwright/src/public.ts:2033-2119


P1 — API / Documentation Mismatches (Mostly Fixed in V1.1)

Historical findings from the V1.1 audit. Items marked FIXED are resolved.

1. imhotep/property-contracts Subpath Doesn't Exist

Issue: README shows import { generatedDomain } from 'imhotep/property-contracts' but the imhotep package has no ./property-contracts export.

Fix: Change all docs to import { generatedDomain } from 'imhotep' or add the subpath export.


2. Property Runner Requires ImhotepRuntime, Not Page

Issue: README shows passing page directly to forAllProps(page, domain, runner), but the implementation requires ImhotepRuntime (created via createRuntime(browser)).

Fix: Either update docs to show createRuntime() usage, or make property runners accept Page and wrap it internally.


3. scene.expect(selector).atLeast(config) Doesn't Work

Issue: Property runner callbacks show scene.expect(selector).atLeast({ width: 50 }) but the actual API is scene.expect(selector).to.be.atLeast(50, 'width').

Fix: Update all examples in README, SKILLS.md, and property runner docs.


4. Property Run Order Is Concurrent, Not Sequential

Issue: exhaustivelyForAllInputs runs cases in parallel. Documentation implies sequential enumeration.

Fix: Document concurrent execution, or add concurrency: 1 option for sequential runs.


5. Dense DSL between Size Assertions Not Supported

Status: FIXED in V1.1 — Dense DSL now supports between size assertions.


6. Dense DSL Quantifier Syntax Is Inline, Not Block

Status: FIXED in V1.1 — Both inline (all '.item' above '.footer') and block (forall $btn in buttons('.primary'): ...) syntax work.


P2 — Surprising Behaviors (Documented for V1.1, Some Fixed in V1.1)

1. .inside() Checks ALL Matching Reference Elements

Behavior: When multiple elements match the reference selector, .inside() checks against all of them. The subject must be inside ALL matching references.

Impact: ui.expect('.button').to.be.inside('.container') fails if there are 2 .container divs and the button is only inside one.

Fix Options:

  • Document this behavior clearly
  • Add insideAny() for "inside at least one" semantics
  • Default .inside() to "inside at least one matching reference"

2. Cardinality Assertions Evaluated Outside FOL Engine

Behavior: exactlyOne(), atLeastN(), atMostN() bypass the FOL solver and use direct selectorToIds count checks.

Impact: Contradicts "all assertions compile to FOL" claims in architecture docs.

Fix Options:

  • Register cardinality as FOL predicates (count(elements('.x')) >= N)
  • Or update docs to acknowledge cardinality is pre-FOL

3. checkAll() Auto-Clears Assertion Store

Behavior: After checkAll(), the internal assertion arrays are emptied. This is correct but not explicitly documented.

Impact: Users might expect to call checkAll() multiple times on the same assertions.

Fix: Document the auto-clear behavior in README and SKILLS.md.


4. Presets Expose Internal Clause Descriptors

Behavior: Presets return { assertions: [...], clauses: [...] } where clauses is internal CanonicalClauseDescriptor[].

Impact: Users can inspect what a preset will test before running, but this leaks internal structure.

Fix: Document the clauses field or hide it behind a symbol.


5. Invalid Options Silently Accepted

Behavior: ui.expect('.a').to.be.leftOf('.b', { invalidOption: true }) is silently forwarded to the FOL engine without validation.

Impact: Typos in option names are silently ignored instead of reported.

Fix: Add strict option validation in FluentRelation.toAst() or DSL validator.


6. separatedFrom Fails With Generic Error

Status: FIXED in V1.1separatedFrom is now fully implemented as a spatial relation.


P3 — Missing Features (Documented But Don't Exist)

Feature Documented In Status Action
clippedBy fluent assertion Architecture docs NOT IMPLEMENTED Remove from docs or implement
geom lower-level primitives imhotep-specification.md NOT EXPORTED Remove from proposed API or implement
.and chaining on relations README, spec IMPLEMENTED in V1.1 Available in both fluent and dense DSL
in(frame.viewport()) syntax imhotep-playwright-cdp-impl.md NOT IMPLEMENTED Remove or implement
Temporal assertions (during, at) imhotep-specification.md NOT IMPLEMENTED Mark as V1.2+
Perceptual tolerance engine Architecture docs NOT IMPLEMENTED Mark as V1.2+
imhotep-temporal package imhotep-llm-execution-strategy.md DOESN'T EXIST Remove from package list
imhotep-perception package imhotep-llm-execution-strategy.md DOESN'T EXIST Remove from package list
Property runner page caching NEXT_STEPS_429.md, docs IMPLEMENTED in V1.1 Caching reduces per-case overhead from ~770ms to ~60-90ms
imhotep-cli dist directory package.json bin field MISSING Build dist or fix bin path

V1.1 Definition

What V1.1 Means

V1.1 is the "Works As Documented" release. Every feature shown in README.md and SKILLS.md must function correctly. No placeholder implementations, no false claims.

V1.1 Acceptance Criteria

Build & Test:

  • npm run build succeeds for ALL packages including imhotep-fixtures
  • npm test --workspaces runs all tests (959 tests pass, 0 failures)
  • npx playwright test passes 213 E2E tests
  • scripts/external-smoke.mjs passes in clean temp directory
  • imhotep-cli has a working dist/ directory with correct bin path

Core Functionality:

  • Missing selectors fail ONLY their own assertion, not the entire batch
  • Dense DSL size assertions (atLeast, atMost, between) work end-to-end
  • Default gap bounds are 0 / Infinity (not -Infinity / Infinity)
  • { space: 'layout' } in options object works
  • focus-visible kebab-case accepted alongside focusVisible

Property Runner:

  • Property runner caches page state between cases (not fresh page per case)
  • API accepts Page and docs match actual signature
  • Property run order is documented as concurrent

Documentation Accuracy:

  • README examples all work when copy-pasted
  • SKILLS.md dense DSL syntax matches actual grammar
  • All imhotep/property-contracts imports changed to imhotep
  • Missing features removed from docs or marked as future work

Diagnostics:

  • Invalid relation options produce clear errors (not silently ignored)
  • separatedFrom and other unimplemented features report "not yet implemented"
  • Zero-match selectors produce actionable fixHints

V1.1 Out of Scope (V1.2+)

  • Temporal assertions (during, at, transition)
  • Perceptual tolerance engine (JND models)
  • geom lower-level functional primitives
  • .and chaining on relations
  • clippedBy and advanced topology assertions
  • imhotep-temporal and imhotep-perception packages
  • Visual overlay screenshots for failures

V1.1 Workstreams

  1. Bug Fix Sprint (P0 items 1-6)
  2. Property Runner Completion (caching, type fixes)
  3. Build Repair (imhotep-fixtures TS errors, imhotep-core test inclusion)
  4. Documentation Sweep (fix all API mismatches, remove false claims)
  5. E2E Stabilization (get all 134 tests passing)
  6. External Smoke Gate (verify clean temp project install)

Files Changed During This Audit

15 documents were updated to reflect actual state:

  • README.md — Fixed install instructions, imports, known issues
  • SKILLS.md — Fixed dense DSL syntax, added cache workaround
  • CHANGELOG.md — Fixed test counts, build claims, caching status
  • IMPLEMENTATION_STATUS.md — Added critical blockers, fixed false claims
  • STRONG_YES_BLOCKERS.md — Added P0 blockers, changed verdicts to BLOCKED
  • RELEASE_CHECKLIST.md — Unchecked failing items
  • BUILD.md — Added known issues section
  • NEXT_STEPS_429.md — Fixed false claims about caching, build, test counts
  • imhotep-specification.md — Removed unsupported features, updated status labels
  • imhotep-v1.1-migration-plan.md — Fixed stale anchors, marked missing files
  • imhotep-core-contracts.md — Documented discrepancies
  • imhotep-llm-execution-strategy.md — Marked missing packages
  • packages/imhotep-core/FOL_GAP_AUDIT.md — Updated closed/open gaps
  • packages/imhotep-playwright/SECURITY.md — Fixed false CDP claims
  • packages/imhotep-cdp/IDENTITY_STRATEGY.md — Fixed style extraction description

22 internal documents moved to attic/ directory for clean separation.


How to Verify V1.1 Readiness

Run this checklist before declaring V1.1:

# 1. Clean build
npm run build                    # Must pass all packages

# 2. Unit tests
npm test --workspaces            # Must run ALL tests (including imhotep-core)

# 3. E2E tests
npx playwright test              # Must pass all 134 tests

# 4. External smoke
cd /tmp
npx create-imhotep-test test     # Or equivalent temp project setup
node test.js                     # Must pass basic assertions

# 5. Property runner performance
node test-property-perf.js       # 5 cases should complete in <500ms total

# 6. Documentation spot-check
cat README.md | grep "npm install imhotep"   # Should show build-from-source

Risk Assessment

Risk Likelihood Impact Mitigation
Build fixes cascade to more TS errors Medium High Fix one package at a time, run tsc after each
Property runner caching breaks determinism Medium Medium Add deterministic cache invalidation tests
Dense DSL size assertion fix affects other unary assertions Low Medium Add regression tests for all unary assertions
E2E tests fail on CI but pass locally Medium High Pin browser versions, add retry logic
External install still broken after fixes Low High Run external-smoke.mjs as required gate

Summary

Imhotep's core value proposition (relational layout testing with actionable diagnostics) is solid. The fluent assertions work, the dense DSL parses, the FOL engine evaluates, and the diagnostics are rich. However, 6 critical bugs and 6 API mismatches make the framework unreliable for external users.

V1.1 = "Fix the bugs, match the docs, pass all tests."

Once P0 bugs are fixed and all E2E tests pass, Imhotep will be ready for external adoption.