- Extend DomainResolver.resolve() signature to accept optional BindingEnv
so that parentVar domains can be resolved with runtime variable bindings
- Pass BindingEnv through evaluateForAll/evaluateExists to resolver calls
- Add buildAncestorIndex() to precompute DOM ancestor sets from CDP data
- SelectorDomainResolver now filters descendant domains by the bound parent
when domain.parentVar is present and ancestor index is available
- Return undefined for parentVar domains when no ancestor index or env
(prevents silent fallback to global domain resolution)
- Update all test DomainResolver mocks for new resolve interface
- Add 10 unit tests covering ancestor index construction, backward compat,
descendant filtering, exclusion of non-descendants, empty descendants,
missing parentVar/env, and no-ancestor-index safety
Perspective: a developer onboarding to contribute to Imhotep, and a developer evaluating whether to adopt the tooling in their own repositories or team workflows.
Perspective: a developer onboarding to contribute to Imhotep, and a developer evaluating whether to adopt the tooling in their own repositories, team workflows, or CI responsibilities.
## Executive Summary
Imhotep has a strong technical core: the package split is coherent, the test surface is unusually broad for an early framework, diagnostics are treated as first-class product output, and the public concept is compelling for UI teams that need declarative spatial, semantic, and property-based UI assertions.
Imhotep has a compelling and unusually ambitious core: declarative UI geometry contracts, dense and fluent authoring styles, finite first-order logic evaluation, structured diagnostics, Playwright integration, property runners, and a package split that mostly reflects the conceptual model. The design promise is high, and several implementation choices already support that promise: broad tests, typed diagnostic shapes, canonical lowering, deterministic evaluation, and real browser fixture coverage.
The biggest risk is not lack of capability. The biggest risk is trust erosion from repository polish, release hygiene, and command ergonomics. A new contributor or adopting team will hit confusing docs, failing root scripts, CI that cannot currently install dependencies, branch mismatch in Gitea Actions, stale version/test-count metadata, and a very large public integration file that is difficult to reason about safely.
The current adoption risk is trust, not ambition. A skeptical developer will find working internals next to misleading quick-start instructions, stale examples, package metadata drift, a contaminated lockfile, and several places where syntax support appears ahead of runtime semantics. That mismatch matters because this project sells correctness. If a tool promises First Order Logic Geometric Contract and Property Testing for the Web, every documented example, diagnostic, and CI signal needs to be boringly reproducible.
The recommended immediate focus is to make the repository boringly reproducible: fix the lockfile/CI path, align branch and version metadata, make root scripts truthful, replace the scaffolded root README with a real project README, and reduce the public API monolith into reviewable units.
The most important next step is a hardening pass that makes the public story match the implementation. Fix the CLI and quick-start path, modernize examples, remove stale “not wired yet” expectations, clean the lockfile, add portable E2E paths, align package versions/peers, and explicitly label or hide internal surfaces. After that, focus on semantic correctness gaps: variable-bound domains, topology predicate semantics, diagnostic metric propagation, and world-schema consolidation.
| Core FOL model | Clear finite-domain evaluator with quantifier semantics | Medium | Harden |
| Geometry extraction | Useful fast and CDP paths, but multiple world shapes | Medium | Consolidate |
| Public docs | Improved root README, but examples and quick-start have broken expectations | High | Immediate |
| CLI/scaffolding | Exists, but consumer invocation and generated files are inconsistent | High | Immediate |
| CI/tooling | Gitea workflow exists, but reproducibility signals need cleanup | Medium | High |
| Tests | Broad, but some tests encode stale assumptions | Medium | High |
| Diagnostics | Strong schema, but data loss/drift remains | Medium | High |
| API governance | Public/internal annotations exist, but internals are still exported | Medium | Medium |
| Contributor ergonomics | Package map is understandable, but production path is hard to trace | Medium | Medium |
## Strengths Worth Preserving
- The package architecture has sensible domain boundaries: `imhotep-core`, `imhotep-dsl`, `imhotep-solver`, `imhotep-cdp`, `imhotep-playwright`, `imhotep-reporter`, and supporting packages each have a recognizable responsibility.
- The test suite is broad and exercises real browser behavior. The fixture E2E suite currently reports 215 passing Playwright tests when invoked through the fixture workspace.
- The project treats diagnostics as a product surface, not just internal errors. `packages/imhotep-core/src/diagnostics.ts` has a broad taxonomy of parse, validation, extraction, selector, relation, topology, logic, and property-run diagnostic codes.
- The external smoke test is the right kind of release gate. `scripts/external-smoke.mjs` creates a clean project, installs local package paths, launches Chromium, imports from the meta-package, and exercises the public API.
-The Gitea workflow is directionally right: lint, build/typecheck, Node matrix tests, E2E, external smoke, benchmark tests, and package checks are separated into stages.
-The public API aims for several adoption paths: direct Playwright page use, fixture files, component rendering, Storybook-like scenarios, dense DSL strings, fluent API, semantic subject references, and property-based test runners.
- The repository has a real product thesis: layout assertions as relational contracts, not screenshot diffs or imperative Playwright coordinate checks. `README.md:3` explains spatial, semantic, dimensional, and property-based layout assertions through fluent API or dense DSL.
- The package split mostly matches the mental model: `imhotep-core`, `imhotep-dsl`, `imhotep-solver`, `imhotep-playwright`, `imhotep-cdp`, `imhotep-reporter`, `imhotep-geometry`, `imhotep-topology`, and related packages each have recognizable responsibilities. See the package table in `README.md:15-32`.
- The public fluent path is compact from a user perspective: `const ui = await imhotep(page)`, register assertions, then `await ui.checkAll()`. This is the right product shape for adoption. See `README.md:5-13`.
- The test surface is broad: unit tests, property-style tests, integration tests, Playwright E2E fixtures, docs-example tests, externalsmoke, and benchmarks are all represented under `packages/*/src` and root scripts in `package.json:9-18`.
-Diagnostics are treated as a product surface rather than incidental thrown errors. Public tests assert diagnostic schema fields, source references, fix hints, LLM output, and traceability.
-CI now exists under `.gitea/workflows/ci.yml` and targets `master`, with separate lint, build/typecheck, unit, E2E, external smoke, and packaging stages.
- The primary package READMEs now exist for `packages/imhotep`, `packages/imhotep-playwright`, `packages/imhotep-dsl`, and `packages/imhotep-core`.
- Recent barrel export classification in `packages/imhotep-playwright/src/index.ts` is a good governance step. The `@public` and `@internal` markers make intent visible.
## Immediate Blockers
## Critical And High-Priority Findings
### 1. CI uses `npm ci`, but there is no lockfile
### 1. The Consumer Quick Start Advertises A CLI Command That Likely Will Not Work
Evidence: `.gitea/workflows/ci.yml:19`, `.gitea/workflows/ci.yml:30`, `.gitea/workflows/ci.yml:52`, and `.gitea/workflows/ci.yml:68` all run `npm ci`.
`README.md:36-40` tells users to run:
Evidence: no `package-lock.json` is present at the repository root.
```bash
npm install imhotep
npx imhotep init --preset react
```
Observed result: `npm ci --ignore-scripts --dry-run` fails immediately with `The npm ci command can only install with an existing package-lock.json or npm-shrinkwrap.json`.
But the published `imhotep` meta-package has no `bin` field in `packages/imhotep/package.json:14-28`, while the executable is defined by a separate package, `imhotep-cli`, in `packages/imhotep-cli/package.json:16-18`.
Impact: every CI job will fail before lint, build, typecheck, or tests start.
That means `npx imhotep init` is not a reliable consumer command unless npm resolves to `imhotep-cli` through unpublished/local workspace behavior. A team trying this from a clean project may hit “could not determine executable to run” or install the library package without a binary.
Recommendation: either commit a root `package-lock.json` and keep using `npm ci`, or change CI and docs to use `npm install` intentionally. For a monorepo intended for contribution and release, committing the lockfile is the better default.
Recommendation: make one of these true before publishing docs:
### 2. Gitea CI targets `main`, but the repository is currently on `master`
1. Add a `bin` entry to the `imhotep` meta-package that delegates to the CLI.
2. Rename/publish the CLI package so `npx imhotep init` resolves to it intentionally.
3. Change docs to `npx imhotep-cli init --preset react` and explain the relationship.
Evidence: `.gitea/workflows/ci.yml:5` and `.gitea/workflows/ci.yml:7` restrict push and pull request triggers to `main`.
### 2. The README Quick Start Order Conflicts With The Scaffolder
Observed state: the current branch is`master`.
The README says to install `imhotep` before running init. The scaffolder skips files that already exist, including `package.json`, via `safeWrite()` in `packages/imhotep-cli/src/init.ts:16-23` and the package write in`packages/imhotep-cli/src/init.ts:53-57`.
Impact: CI may not run on the branch users actually push unless Gitea is configured with a renamed default branch later. This is a high-confidence broken expectation for a contributor pushing the current repo state.
If a user starts in an existing project or creates a package before init, the preset package scripts and dependencies may not be written. The result is an apparently successful scaffold with missing setup.
Recommendation: either rename the branch to `main` before pushing, or update the workflow to target `master`. If the plan is to create `main` on Gitea, document that in `BUILD.md` or a release checklist.
Recommendation: either scaffold into an empty directory first, or make `init` merge known-safe fields into existing `package.json`. At minimum, print a clear warning when package metadata is skipped and document `--force` or `--merge` behavior if added.
### 3. Root test scripts advertise commands that fail
### 3. Scaffolded Projects Are ESM But Generated Configs Are CommonJS `.js`
Evidence: `package.json:13` defines `test:unit` as`npm run test:unit --workspaces`, but workspaces do not define `test:unit`.
Preset package JSON sets `"type": "module"` in `packages/imhotep-cli/src/presets/react-playwright.ts:95-108` and`packages/imhotep-cli/src/presets/vue-vitest.ts:115-127`, but generated `imhotep.config.js` uses `module.exports` in `react-playwright.ts:6-24` and `vue-vitest.ts:6-26`.
Evidence: `package.json:14` defines `test:integration` as `npm run test:integration --workspaces`, but only `imhotep-playwright` appears to define that script.
That is a runtime footgun. In an ESM project, `module.exports` in `.js` is not valid CommonJS unless the file is `.cjs` or the package type differs.
Evidence: `package.json:15` defines `test:e2e` as `npm run test:e2e --workspaces`, but only `imhotep-fixtures` defines that script.
Recommendation: generate `imhotep.config.cjs`, or generate ESM config with `export default`. The root `imhotep.config.js:1-19` has the same scaffold-residue smell and should be removed or converted if it is intentional.
Observed result: `npm run test:unit --dry-run`, `npm run test:integration --dry-run`, and `npm run test:e2e --dry-run` all exit non-zero because npm reports missing scripts in most workspaces. The E2E workspace still ran and passed 215 tests, but the root command failed afterward due missing scripts elsewhere.
### 4. Generated Preset READMEs Show Invalid Imhotep Usage
Impact: contributors will not know which commands are canonical. CI could fail if it uses the root scripts without `--if-present` or targeted workspaces.
The React preset README template shows:
Recommendation: make root scripts precise. Suggested surface: `test` for all package tests, `test:e2e` for `npm run test:e2e -w imhotep-fixtures`, `test:integration` for `npm run test:integration -w imhotep-playwright`, and remove `test:unit` unless packages actually implement it.
The actual API used by tests is `const ui = await imhotep(page)` and then synchronous assertion registration followed by `await ui.checkAll()`, as seen in `react-playwright.ts:29-37`.
Evidence: `README.md:3` says it was scaffolded with `imhotep init --preset react`.
The Vue preset has the same issue at `packages/imhotep-cli/src/presets/vue-vitest.ts:151-154`.
Evidence: `README.md:13` through `README.md:18` describes `tests/` and `fixtures/`, but this repository is a 14-package monorepo.
Recommendation: update every generated README snippet to use the exact tested API shape:
Impact: the first file a contributor or evaluator reads gives the wrong mental model. It makes the repository look like a generated example rather than the source of the framework.
Recommendation: replace the root README with a contributor/product README that explains what Imhotep is, the package map, installation expectations, quick-start for consumers, local development commands, release process, and links to `BUILD.md`, `SECURITY.md`, and examples.
### 5. Root Examples Are Stale And Teach The Old Extraction-Only Pattern
### 5. Release/version metadata is inconsistent
`examples/page-test.js:4-5` says the primary V1.0 pattern is `ui.extract()` plus Playwright assertions. `examples/page-test.js:7-8` and `examples/responsive-test.js:7-8` use CommonJS `require`, while the repo root is ESM in `package.json:5`.
Evidence: `CHANGELOG.md:3` declares `1.1.0`.
This conflicts with the current README, which presents `ui.expect(...).to.be...` plus `ui.checkAll()` as the main experience in `README.md:5-13`.
Evidence: root `package.json:3` is `1.0.0`.
Worse, the docs-example test suite preserves the stale expectation that examples should not use the now-working public API: `packages/imhotep-fixtures/src/docs-examples.test.ts:51-52`, `docs-examples.test.ts:65-66`, `docs-examples.test.ts:76-78`, `docs-examples.test.ts:88-89`, and `docs-examples.test.ts:134-137` assert that examples avoid `ui.expect`, `checkAll`, or higher-level APIs.
Evidence: `packages/imhotep/package.json:3`, `packages/imhotep-playwright/package.json:3`, `packages/imhotep-core/package.json:3`, `packages/imhotep-dsl/package.json:3`, `packages/imhotep-cli/package.json:3`, and `packages/imhotep-fixtures/package.json:3` are all `1.0.0` in the sampled manifests.
Recommendation: rewrite examples to ESM and current API usage. Then invert the docs tests: they should assert that canonical examples use `await imhotep(page)`, `ui.expect`, `ui.spec`, `checkAll`, and failure diagnostics correctly.
Evidence: `.gitea/ISSUE_TEMPLATE/bug_report.yml:15` uses `1.1.0` as the example version.
### 6. README DSL And Property Examples Do Not Match The Parser/API
Impact: an adopter cannot tell whether they are testing/reviewing 1.0.0 or 1.1.0. Release notes may not match the packages that would be published.
The dense DSL examples in `README.md:83-88` omit selector quotes:
Recommendation: define whether the current release is 1.0.0 or 1.1.0 and align every package manifest, changelog, docs, issue templates, and commit/tag naming before publication.
```typescript
ui.spec('.button leftOf .icon gap 8px');
ui.spec('all .card centeredWithin .container');
ui.spec('forall $c in .card: $c width >= 200');
```
## Onboarding Feedback
But parse guidance in diagnostics says selectors must be single-quoted strings, e.g. `packages/imhotep-playwright/src/extraction.ts:1522-1527`. E2E tests also use quoted selectors, such as `packages/imhotep-fixtures/src/e2e-semantic-dsl.test.ts:65-77`.
### Documentation Has Useful Pieces, But No Coherent Entry Path
The property example in `README.md:90-96` calls `imhotepFixture(...).forAllProps(...)`, but fixture handles expose `forAllInputs` and `exhaustivelyForAllInputs` in `packages/imhotep-playwright/src/public.ts:882-907`. `forAllProps` exists for component/story targets at `public.ts:776-819`, not fixture targets.
The repository has `BUILD.md`, `SECURITY.md`, `CHANGELOG.md`, `SKILLS.md`, `FEEDBACK.md`, and `NEXT_STEPS_501.md`, but only the root README is automatically discovered by most developers and package viewers. Right now the root README is misleading.
Recommendation: make README examples executable and cover them with docs tests. If the desired DSL syntax is unquoted selectors, implement it explicitly and test ambiguity. If not, document quoted selectors consistently.
Recommendation: make the README the map, not the manual. It should answer: what problem Imhotep solves, why it is different from plain Playwright assertions, which package a user imports, which package a contributor edits, how to run the normal validation loop, how to run only E2E, and what is considered stable public API.
### 7. One E2E Test Contains An Absolute Workstation Path
Evidence: `CHANGELOG.md:27` also says 959 unit tests pass, while `CHANGELOG.md:28` says 215 E2E tests pass.
That will not run on CI, another developer’s machine, or another checkout path. Most neighboring tests use shared fixture helpers or `import.meta.url`, so this is likely accidental.
Impact: stale verification numbers make readers question whether the document is a living source of truth.
Recommendation: use `fileURLToPath(import.meta.url)` plus `pathToFileURL`, or route through the existing fixture harness.
Recommendation: avoid static test counts in docs unless a release process updates them. Prefer command examples and "expected to pass" statements, or add a release checklist that updates counts intentionally.
### 8. The Lockfile Contains Sibling-Project Links
### Package-Level READMEs Are Missing
`package-lock.json` references `../Operator/node_modules` at lines `25`, `38`, `1055`, and `2942`.
Evidence: only the root `README.md` was found.
Even if `npm install` works locally, a public/release lockfile should not encode paths into a sibling checkout. This is exactly the kind of artifact that causes skeptical adopters to question release hygiene.
Impact: contributors landing in `packages/imhotep-playwright`, `packages/imhotep-dsl`, or `packages/imhotep-solver` do not get local context. Adopters browsing npm package pages may see weak package descriptions if package READMEs are absent from published tarballs.
Recommendation: regenerate the lockfile from a clean checkout with no sibling-linked packages. Then switch CI to `npm ci` once the lockfile is clean.
Recommendation: add concise package READMEs for at least `imhotep`, `imhotep-playwright`, `imhotep-dsl`, and `imhotep-core`. They do not need to be long; they should state status, import examples, public API surface, and relationship to the meta-package.
### 9. Internal Dependency Ranges Lag Behind The Current Version
### Security Policy Still Mentions GitHub
Packages are versioned `1.1.0`, but internal dependency ranges are still `^1.0.0`. Examples:
Evidence: `SECURITY.md:51` says to open a GitHub issue for non-sensitive reports.
-`packages/imhotep/package.json:3` is `1.1.0`, but dependencies in `packages/imhotep/package.json:33-43` are `^1.0.0`.
-`packages/imhotep-playwright/package.json:3` is `1.1.0`, but dependencies in `packages/imhotep-playwright/package.json:34-39` are `^1.0.0`.
-`packages/imhotep-cli/package.json:32-35` depends on `^1.0.0` packages.
Impact: this conflicts with the Gitea migration and could route sensitive or operational reports to the wrong place.
This may resolve to `1.1.0` if all packages are published and semver picks latest versions, but it undermines the synchronized monorepo release story.
Recommendation: update `SECURITY.md`for Gitea and define a private disclosure mechanism. If private security reports are not supported by the Gitea instance, provide a security email or other private channel.
Recommendation: choose the release policy. For lockstep releases, use `^1.1.0` or exact `1.1.0` internal ranges. For independently versioned packages, document compatibility and add cross-version smoke tests.
## Tooling and CI Feedback
### 10. Playwright Peer Ranges Disagree Across The Main Entry Points
### CI Is Directionally Good, But Currently Non-Executable
The meta-package allows Playwright `^1.40.0` in `packages/imhotep/package.json:45-48`, while `imhotep-playwright` requires `^1.59.1` in `packages/imhotep-playwright/package.json:30-33`.
The job split is sensible, but CI cannot currently get past install because of the missing lockfile. It may also not trigger due the branch mismatch.
The meta-package re-exports Playwright integration, so adopters should see one clear supported Playwright range.
Recommendation: fix install and branch first. Then run the workflow once on Gitea before treating the repository as ready.
Recommendation: align peer dependency ranges. If `1.40` is genuinely supported, prove it in CI. If `1.59.1` is required for extraction/runtime behavior, make the meta-package match.
### Gitea Workflow Mixes Gitea and GitHub Action URLs
## Architecture And Semantics Findings
Evidence: checkout/setup-node/upload/download use `https://gitea.com/actions/...` at `.gitea/workflows/ci.yml:14`, `.gitea/workflows/ci.yml:15`, `.gitea/workflows/ci.yml:33`, and `.gitea/workflows/ci.yml:53`.
### 11. Variable-Bound Dense FOL Domains Parse And Compile But Are Not Resolved Correctly At Runtime
Evidence: browser cache uses`https://github.com/actions/cache@v4` at `.gitea/workflows/ci.yml:73`.
The DSL supports syntax such as `descendants($card, '.title')` and preserves `parentVar`; see`packages/imhotep-dsl/src/compiler.ts:940-959` and tests in `packages/imhotep-dsl/src/fol-dense-combinations.test.ts:391-403`.
Impact: this may work depending on the Gitea Actions runner configuration, but it is inconsistent with the Gitea-only intent and can fail in locked-down environments.
However, the runtime resolver interface is `resolve(domain: DomainRef)` with no binding environment in `packages/imhotep-solver/src/logic-engine.ts:99-101`, and `SelectorDomainResolver.resolve()` simply returns `this.domains.get(domain.selector ?? domain.domain)` in `packages/imhotep-playwright/src/extraction.ts:958-960`.
Recommendation: use a Gitea-compatible cache action consistently, or document why the GitHub action URL is required and verified.
That means scoped runtime semantics like “titles under this card” likely degrade into global `.title` resolution or cannot resolve variable-only domains. For a FOL contract system, this is a high-value correctness gap because the syntax implies relational scoping.
### Root Build Is Manually Dependency-Ordered
Recommendation: extend domain resolution to receive the current binding environment, or precompute dependent domains keyed by parent subject ID. Add E2E tests for `descendants($var, selector)`, `children($var)`, and failing cases where a global match would pass but scoped semantics should fail.
Evidence: `package.json:10` contains a long chained `npm run build --workspace=...` command across all packages.
### 12. `inStackingContext` Has An Arity/Semantics Mismatch
Impact: adding, renaming, or reordering packages is error-prone. A contributor has to understand dependency order manually.
The solver descriptor declares `inStackingContext` with arity 1 in `packages/imhotep-solver/src/predicates.ts:83`, while the Playwright FOL compiler emits `inStackingContext(subjectVar, refVar)` for relation options in `packages/imhotep-playwright/src/fol-compiler.ts:326-331`.
Recommendation: consider TypeScript project references with `tsc -b`, a small build orchestrator script, or npm workspace build with explicit per-package dependency management. If keeping the manual chain, add a comment or generated package-order check.
The grammar also supports both standalone topology assertions and relation options around `packages/imhotep-dsl/src/grammar.ts:1305-1360`. Topology package tests model a two-argument context comparison, e.g. `packages/imhotep-topology/src/topology.test.ts:390-405`.
### `noEmitOnError` Is Disabled In Package Builds
Recommendation: decide the product semantics. If `inStackingContext` is unary, the relation option should not emit a reference argument. If it is binary, update predicate metadata/evaluation and tests. Do not leave “same context” behavior as a known accepted failure in E2E.
Evidence: `packages/imhotep-playwright/tsconfig.json:12`, `packages/imhotep-core/tsconfig.build.json:8`, `packages/imhotep-dsl/tsconfig.json:8`, `packages/imhotep-solver/tsconfig.json:8`, `packages/imhotep-topology/tsconfig.json:8`, and `packages/imhotep-geometry/tsconfig.json:8` set `noEmitOnError` to `false`.
### 13. Public Runtime Orchestration Bypasses Several Cleaner-Looking Abstractions
Impact: packages can emit JS and declarations even when TypeScript reports errors. CI does run typecheck after build, but the build artifact stage can still produce output from a bad compilation state.
The conceptual architecture includes `imhotep-core/src/pipeline.ts`, `imhotep-extractor/src/planner.ts`, canonical adapters, CDP extraction, fast extraction, and Playwright-specific orchestration. The actual public `checkAll()` path runs primarily through `packages/imhotep-playwright/src/check-all.ts`, `fol-compiler.ts`, and `extraction.ts`.
Recommendation: default to `noEmitOnError: true` for release packages. If there is a specific reason to emit on error during tests, isolate that behavior in test configs rather than production build configs.
This is understandable in a growing framework, but it increases onboarding cost. A contributor can easily modify a generic-looking pipeline or planner and not affect the production public API.
### Ignored Generated Files Are Still Littering `src/`
Recommendation: document the actual golden path for contributors:
Evidence: `.gitignore:11` through `.gitignore:14` explicitly ignores `packages/*/src/**/*.js`, `packages/*/src/**/*.d.ts`, and `packages/*/src/**/*.map`.
Observed state: `git status --ignored --short` shows hundreds of ignored generated files under `packages/*/src/`.
Then either retire unused abstractions, mark them experimental/internal, or add tests proving they are equivalent to the public path.
Impact: ignored files do not affect commits, but they do affect local search results, editor symbol discovery, test discovery confusion, and contributor confidence. They also make it easier to accidentally debug stale generated JS instead of source TS.
### 14. World Schema Duplication Makes Predicate Changes Riskier Than They Need To Be
Recommendation: add a cleanup script that removes these files, and update `npm run clean` to include `packages/*/src/**/*.js`, `packages/*/src/**/*.d.ts`, and `packages/*/src/**/*.map`. Also verify why they were produced and prevent recurrence.
There are multiple world shapes and adapters:
### Lint Is Too Permissive To Be A Strong Quality Signal
- Core geometry world schema in `packages/imhotep-core/src/world.ts`.
- Canonical world schema in `packages/imhotep-core/src/canonical.ts`.
- CDP snapshot/world extraction in `packages/imhotep-cdp/src/extractor.ts`.
- Playwright fast-path world builder in `packages/imhotep-playwright/src/world-builder.ts`.
- Solver predicates that sometimes reach through optional/adapted fields using `as any`, e.g. `packages/imhotep-solver/src/predicates.ts:163-169` and `predicates.ts:242-262`.
The result is that a predicate author must know whether a fact is present in fast extraction, CDP extraction, canonical adaptation, test mocks, and solver-world adaptation.
Evidence: `.eslintrc.cjs:19` through `.eslintrc.cjs:25` make several hygiene rules warnings rather than errors.
Recommendation: define one canonical solver input contract and make every extraction path adapt into it before predicate evaluation. Add a “fact availability matrix” for each predicate so contributors can see which extraction facts are required and which paths provide them.
Evidence: `.eslintrc.cjs:27` ignores all `*.js` and `*.d.ts` globally.
### 15. `imhotep-core` Contains Test/Mock Helpers That Import Downstream Packages
Impact: "lint passes" mostly means there are no syntax-level or recommended-rule errors in TS files. It does not mean the public API is strongly typed or that generated artifacts are absent.
`packages/imhotep-core/src/integration-mocks.ts:8-14` imports types from `imhotep-solver` and `imhotep-state`, but `packages/imhotep-core/package.json:1-61` lists no dependencies.
Recommendation: keep `no-explicit-any` off temporarily if needed, but add targeted stricter rules for public packages over time. Consider a separate `lint:public-api` or `lint:strict` gate for `packages/imhotep`, `packages/imhotep-playwright/src/index.ts`, and exported declarations.
This file is not exported from the core barrel, but it is still source under a publishable package and can end up in dist output. It violates the expected direction of dependency flow: core should not know about solver/state.
## Package and Release Feedback
Recommendation: move integration mocks into a test-only package or `packages/imhotep-core/test-support` that is not included in production package files. Alternatively add explicit dependencies and accept the architectural coupling, but that seems worse.
### Root Package Name Conflicts With Workspace Package Name
### 16. Public/Internal API Classification Is Visible But Not Enforced
Evidence: root `package.json:2` is named `imhotep`.
`packages/imhotep-playwright/src/index.ts:64-98` labels pools, page wrapper, environment helpers, and target resolution as `@internal`, but still exports them from the public package root.
Evidence: `packages/imhotep/package.json:2` is also named `imhotep`.
This is better than accidental export, but it is still a semver hazard. Users can import internals directly from `imhotep-playwright`, and package managers will treat them as public unless documentation and export maps say otherwise.
Impact: npm output and workspace targeting become ambiguous. The root is private, but duplicate names still confuse humans and tooling logs.
Recommendation: move internals to explicit subpaths such as `imhotep-playwright/internal` or remove them from the package root before a stable release. If they must remain for tests/tooling, document that `@internal` exports are not semver-stable.
Recommendation: rename the private root package to something like `imhotep-monorepo`.
### 17. The Meta-Package Does Not Re-Export The Full Recommended Public Surface
### Root Dependencies Include Publish Packages
`packages/imhotep-playwright/src/index.ts:34-52` exports renderer registry and renderer descriptors (`react`, `vue`, `storybook`, `custom`), but `packages/imhotep/src/index.ts:1-26` does not re-export those. A user following `import { imhotep } from 'imhotep'` may hit missing APIs for component/story/custom renderer workflows.
Evidence: root `package.json:31` through `package.json:35` lists `@playwright/test`, `imhotep`, `imhotep-dsl`, and `imhotep-playwright` as dependencies, not just dev dependencies.
Recommendation: decide whether `imhotep` is the single recommended import path. If yes, re-export the stable Playwright public API from the meta-package. If no, the README should clearly say when to use `imhotep` versus `imhotep-playwright`.
Impact: the private root is not published, so production dependencies at the root are usually unnecessary. The `imhotep` dependency is especially confusing because the root package has the same name.
### 18. Large Central Files Make Contributor Review Hard
Recommendation: keep root dependency declarations minimal. Use workspace dependencies where necessary for package manifests, and dev dependencies at the root for tooling.
Key files are large enough to slow down safe changes:
Evidence: `packages/imhotep/package.json:9`, `packages/imhotep-playwright/package.json:8`, `packages/imhotep-core/package.json:8`, `packages/imhotep-dsl/package.json:8`, `packages/imhotep-cli/package.json:8`, and `packages/imhotep-fixtures/package.json:8` all point to `https://github.com/anomalyco/imhotep.git` in the sampled manifests.
Large files are not automatically wrong, but these contain multiple responsibilities: parsing, AST shaping, extraction planning, world adaptation, public handles, diagnostics mapping, and evaluation orchestration.
Impact: package metadata conflicts with the Gitea hosting decision. npm package pages and bug reports could route users to the wrong forge.
Recommendation: split by responsibility after the current hardening pass. Good seams include extraction planning versus browser execution, diagnostic mapping versus evaluation, public types versus public factory construction, and predicate families by geometry/topology/size/alignment.
Recommendation: update all package `repository` fields to the canonical Gitea URL before publishing.
### 19. FOL Diagnostic Mapping Drops Metrics And Source References
Observed state: sampled packages have name, version, license, repository, engines, main/types/files/exports, but most do not have descriptions, keywords, homepage, bugs, funding, sideEffects, or package-specific README.
`mapFolDiagnostic()` returns empty `metrics` and `sourceRef` in `packages/imhotep-playwright/src/extraction.ts:1536-1547`.
Impact: npm consumers evaluating individual packages get weak discovery and support metadata.
The project’s value proposition depends heavily on actionable diagnostics. A schema-valid diagnostic with empty measured context is less useful than a plain Playwright assertion in many failure investigations.
Recommendation: add descriptions and metadata at least for public-facing packages. Mark internal-only packages private if they are not intended for standalone npm consumption.
Recommendation: preserve predicate metrics, witness IDs, selector/domain provenance, source labels, and clause source references through FOL diagnostic mapping. Add regression tests that assert compound and quantified failures include non-empty measured context.
### Export Conditions Are Inconsistent
### 20. Boolean Connectives Drop Operand Metrics
Evidence: `packages/imhotep/package.json:20` through `packages/imhotep/package.json:27` uses `import` conditions.
`evaluatePredicate()` preserves `predicateResult.metrics` in `packages/imhotep-solver/src/logic-engine.ts:837-843`, but `evaluateAnd`, `evaluateOr`, `evaluateNot`, and `evaluateImplies` construct new `FormulaResult` objects without carrying operand metrics in `logic-engine.ts:526-667`.
Evidence: `packages/imhotep-playwright/package.json:23` through `packages/imhotep-playwright/package.json:27` and `packages/imhotep-core/package.json:22` through `packages/imhotep-core/package.json:42` use `default` conditions.
For compound contracts, this can make failures less actionable precisely when users need more explanation.
Impact: this may work, but it makes package behavior less predictable across bundlers and Node resolution modes.
Recommendation: define a metric aggregation policy for connectives. For failing `and`, preserve the failing side’s metrics. For failing `or`, preserve both failed sides if possible. For `not`, preserve operand metrics when it fails because the operand passed.
Recommendation: standardize export condition shape across packages, ideally with explicit `types` and `import` for ESM packages.
### 21. Diagnostic Code Metadata Has Multiple Sources Of Truth
## Architecture and API Feedback
The core diagnostic union and default categorization live in `packages/imhotep-core/src/diagnostics.ts`, while reporter code metadata is duplicated in `packages/imhotep-reporter/src/codes.ts`.
### `imhotep-playwright/src/public.ts` Is Too Large And Too Central
This can drift. One concrete example identified during review: reporter metadata classifies topology unsupported behavior differently from core fallback categorization.
Evidence: `packages/imhotep-playwright/src/public.ts` is 3580 lines.
Recommendation: generate reporter metadata from the core diagnostic registry, or move the canonical registry into core and import it everywhere.
Evidence: it contains public interfaces, compatibility reports, cache namespace management, extraction stats hooks, selector resolution, property run handles, FOL compilation/evaluation bridging, runtime integration, component/story/fixture entry points, LLM formatting, and no-op fast-check fallback behavior.
## Testing And Verification Findings
Impact: this file is hard to review, hard to test in isolation, and risky to change. For a contributor, it is not clear where one responsibility ends and another begins.
### 22. Root `npm test` Depends On Prebuilt `dist` For Most Packages
Recommendation: split by responsibility. Good candidate modules: `public-types.ts`, `semantic-subjects.ts`, `compatibility-report.ts`, `check-all.ts`, `llm-output.ts`, `property-handles.ts`, `fixture-entry.ts`, `component-entry.ts`, and `extraction-cache.ts`.
The root `test` script is `npm run test --workspaces` in `package.json:12`. Many workspace tests run `node --test dist/**/*.test.js` without compiling first, for example `packages/imhotep-dsl/package.json:19-22`, `packages/imhotep-solver/package.json:19-22`, and `packages/imhotep/package.json:29-32`.
Recommendation: either make `npm test` run `npm run build` first at the root, or make every package test script compile what it runs. A fresh clone should not be able to pass or fail tests based on stale `dist` output.
Given the lockfile contamination noted above, using `npm install` may currently be pragmatic. But for a release-quality repository, CI should prove lockfile reproducibility.
Impact: TypeScript interface merging makes this legal, but it is surprising in a public API file. A contributor may not realize fields are accumulated across declarations.
Recommendation: clean the lockfile, then switch CI to `npm ci`. Add a local command in `BUILD.md` that matches CI exactly.
Recommendation: collapse each public interface into a single declaration.
### 24. E2E Command Documentation Mixes Built Output And Source Paths
### Public API Surface May Be Too Broad For A 1.x Promise
`BUILD.md:50-55` correctly says Playwright config targets compiled E2E tests under `packages/imhotep-fixtures/dist/`, but `BUILD.md:72-74` suggests running a source TypeScript file directly:
Evidence: `packages/imhotep-playwright/src/index.ts:10` through `packages/imhotep-playwright/src/index.ts:101` exports runtime internals, pools, fixtures, environment helpers, renderer registry APIs, adapters, targets, semantic subjects, and presets.
```bash
npx playwright test packages/imhotep-fixtures/src/e2e-public.test.ts
That may not work with the configured `testDir`/`testMatch`, and it gives contributors two incompatible mental models.
Impact: once published as 1.x, these exports become compatibility burden. It may be unclear what is stable versus exposed for tests/tooling.
Recommendation: document one reliable targeted path, likely by building first and using `--config packages/imhotep-fixtures/playwright.config.ts --grep ...` or pointing at the compiled test if that is the intended mode.
Recommendation: explicitly classify exports as stable, experimental, or internal. Consider subpath exports such as `imhotep-dsl/internal` or `imhotep-playwright/experimental` for surfaces that are not yet stable.
### 25. External Smoke Uses Local Package Directories, Not Packed Tarballs
### Core Uses Broad Star Exports
`scripts/external-smoke.mjs:16-37` installs dependencies via `file:` paths to package directories. This is valuable, but it does not fully prove package tarball contents. CI packs packages later in `.gitea/workflows/ci.yml:81-88`, but does not appear to install and run from those tarballs.
Evidence: `packages/imhotep-core/src/index.ts:13` through `packages/imhotep-core/src/index.ts:51` export almost every module wholesale.
Recommendation: add a publish-smoke mode that runs `npm pack`, installs the generated `.tgz` files into a clean temp project, andexecutes the same smoke. This catches missing `files`, bad exports, missing README/package metadata, and package dependency drift.
Impact: this maximizes convenience but makes API governance difficult. Types and helpers can become public accidentally.
### 26. Fixture Registry Validation Does Not Cover All Fixture Pages
Recommendation: define a curated public core barrel, and move internal/test-only types behind subpath exports if they truly need to remain importable.
The fixture harness validates named categories in `packages/imhotep-fixtures/src/harness.ts`, while several pages used by E2E tests live outside that registry. This means duplicate `data-testid`s, missing required fixtures, or structure drift can slip through for some pages.
### Type Safety Has Known Escape Hatches In Core Paths
Recommendation: either register every fixture page or add a generic validation pass over `packages/imhotep-fixtures/src/pages/*.html`.
Evidence: `packages/imhotep-dsl/src/validator.ts:315`, `packages/imhotep-dsl/src/validator.ts:331`, `packages/imhotep-dsl/src/validator.ts:362`, and `packages/imhotep-dsl/src/validator.ts:391` accept `any` for AST validation paths.
## Adoption Readiness Findings
Evidence: `packages/imhotep-playwright/src/public.ts` contains many `as any` uses across selector handling, AST walking, world adaptation, result augmentation, and fluent proxy wrapping.
### 27. Package READMEs Exist Only For The Main Four Packages
Impact: some `any` usage is pragmatic at parser/runtime boundaries, but the current amount makes it harder to trust refactors and harder to understand where data is validated.
Package READMEs exist for `imhotep`, `imhotep-playwright`, `imhotep-dsl`, and `imhotep-core`. Other publishable packages have package metadata but no package-level usage/status docs.
Recommendation: prioritize typed boundary objects over eliminating all `any`. Good first targets are AST node discriminated unions in `validator.ts` and result/context augmentation in `public.ts`.
That is acceptable if those packages are internal implementation details, but then they should be marked private or clearly described as internal. If they are public, npm browsers need enough context to evaluate them.
## Testing Feedback
Recommendation: classify all packages as public, internal-but-published, or private. Add short READMEs for public packages and mark truly internal packages private if they should not be adopted directly.
### Test Breadth Is A Major Strength
### 28. Export Conditions Are Inconsistent Across Packages
The repository has unit tests, integration tests, E2E tests, property-style tests, smoke tests, and mutation-test configuration. This is better than many tools at a similar maturity level.
The meta-package uses explicit `types` and `import` conditions in `packages/imhotep/package.json:19-28`, while other packages use `types` and `default`, e.g. `packages/imhotep-playwright/package.json:24-29` and `packages/imhotep-core/package.json:23-43`.
Recommendation: preserve this breadth while improving commandergonomics and documentation.
This may work in Node ESM, but inconsistent export condition shapes make behavior harder to reason about across bundlers and TypeScript module resolution modes.
### Root Verification Commands Need To Match CI And Docs
Recommendation: standardize on explicit ESM export conditions, ideally `types` plus `import`, across publishable packages.
Evidence: `BUILD.md:31` recommends `npm test --workspaces` for unit/integration test sweep.
### 29. Type Escape Hatches Are Concentrated In Boundary Code
Evidence: `package.json:12` defines root `test` as`npm run test --workspaces`.
There are many `any` and `as any` usages in parser/runtime boundary code, especially `packages/imhotep-playwright/src/public.ts`, `packages/imhotep-playwright/src/extraction.ts`, `packages/imhotep-dsl/src/grammar.ts`, and`packages/imhotep-solver/src/predicates.ts`.
Evidence: CI uses `npm test` at `.gitea/workflows/ci.yml:56` and then `npm run test:integration --workspaces --if-present` at `.gitea/workflows/ci.yml:57`.
Some of this is expected around JS proxies, browser evaluation, parser AST construction, and adapted world schemas. The risk is not that `any` exists; the risk is that a contributor cannot tell which casts are intentional boundary escapes versus accidental type debt.
Impact: there are several subtly different command paths. Contributors need one canonical local command for "what CI will do".
Recommendation: do not chase zero `any` blindly. Instead, add local typed boundary interfaces for proxy metadata, browser-injected globals, adapted world extensions, and parser node unions. Add comments only where a cast is truly necessary.
Recommendation: document and enforce exact commands. If CI uses targeted scripts, local docs should use the same commands.
## Broken Expectations And Open Questions
### Some Tests Encode Broken Expectations As Passing Behavior
- Is `npx imhotep init` intended to be the canonical CLI command, or should the CLI package name be user-facing?
- Is `imhotep` intended to be the only recommended import path, or should advanced users import `imhotep-playwright` directly?
- Are all packages intended to be published independently, or should packages like `imhotep-cdp`, `imhotep-extractor`, `imhotep-state`, `imhotep-topology`, and `imhotep-bench` be private/internal?
- Should dense DSL support unquoted CSS selectors, or should all examples use quoted selectors?
- What is the intended runtime semantics for `descendants($var, selector)` and `children($var)`?
- Is `inStackingContext` unary (“has any stacking context”) or binary (“shares/is in a specific context”)?
- Which world schema is canonical for predicate authors?
- Should CI test against the minimum supported Playwright version or only the latest supported version?
- Should package tests be runnable from a fresh checkout without an explicit build?
- Are `@internal` root exports semver-stable or explicitly unsupported?
- Should external smoke validate local package directories, packed tarballs, or both?
Evidence: `packages/imhotep-fixtures/src/e2e-edge.test.ts:195` says `clippedBy is mentioned in docs but may not be implemented`.
### Phase 1: Make The Public Story True
Evidence: `packages/imhotep-fixtures/src/e2e-edge.test.ts:205` logs `clippedBy is NOT implemented on be proxy`, and `packages/imhotep-fixtures/src/e2e-edge.test.ts:206` expects `hasClippedBy` to be false.
1. Fix the CLI command and README quick start.
2. Fix generated config format for ESM projects.
3. Fix generated preset README snippets.
4. Rewrite root examples to current ESM `ui.expect`/`ui.spec`/`checkAll` patterns.
5. Update docs-example tests so they protect current public API examples rather than old “not wired yet” assumptions.
6. Fix README dense DSL and property examples.
Impact: this turns an incomplete feature/documentation mismatch into a passing test. It protects awareness, but it can also normalize broken expectations.
### Phase 2: Make The Repo Reproducible Everywhere
Recommendation: convert these into explicit TODO tests, issue-linked tests, or docs corrections. A passing E2E suite should not include console output announcing missing documented features.
1. Replace the hardcoded E2E fixture path.
2. Regenerate `package-lock.json` from a clean checkout.
3. Switch CI from `npm install` to `npm ci` after lock cleanup.
4. Make `npm test` source-reproducible or document/build-enforce its dependency on `dist`.
5. Align internal package dependency ranges and Playwright peer ranges.
6. Add tarball-based external smoke.
### E2E Config Assumes Built Output In `dist`
### Phase 3: Close Semantic Correctness Gaps
Evidence: `packages/imhotep-fixtures/playwright.config.ts:4` sets `testDir` to `./dist` and `packages/imhotep-fixtures/playwright.config.ts:5` matches `e2e*.test.js`.
1. Implement environment-aware domain resolution for variable-bound domains.
2. Decide and fix `inStackingContext` arity/semantics.
3. Preserve metrics/source references through FOL diagnostics and boolean connectives.
4. Add E2E tests for scoped domains where global resolution would produce a false positive.
5. Add negative fluent compound tests where one side fails and diagnostics must remain actionable.
Impact: `playwright test` relies on a prior build and copied fixture pages. This is acceptable, but it is easy to run from the wrong place or without build output.
### Phase 4: Govern API And Architecture
Recommendation: keep the targeted workspace script, but rename or document it as build-dependent. Consider making `test:e2e` run `test:e2e:build` or adding a `pretest:e2e` step if local ergonomics matter more than speed.
## CLI and Scaffolding Feedback
### CLI Init Writes Over Existing Files Without Guardrails
Evidence: `packages/imhotep-cli/src/init.ts:23` through `packages/imhotep-cli/src/init.ts:55` writes config, test, fixture, package.json, and README directly.
Impact: `imhotep init --dir .` can overwrite existing project files. That is risky for a scaffolding command adopted into real repositories.
Recommendation: refuse to overwrite by default, print a file list before writing, and add `--force` for explicit overwrite behavior.
### CLI Argument Parsing Is Minimal
Evidence: `packages/imhotep-cli/src/cli.ts:27` through `packages/imhotep-cli/src/cli.ts:64` hand-parses `init`, `--preset`, and `--dir`.
Impact: missing values, repeated flags, aliases, unknown flags, and Windows path quirks may produce weak UX.
Recommendation: either keep hand parsing but add defensive checks and tests, or use a tiny CLI parser. Given this package is a scaffolder, UX quality matters.
### Scaffolded README Leaked Into Root
Evidence: root `README.md:3` says the project was scaffolded with `imhotep init --preset react`.
Impact: this suggests the CLI template content may have been copied into the monorepo root accidentally. That is exactly the kind of polish issue adopters notice.
Recommendation: ensure scaffold templates are clearly separated from repository docs and add a test that root README does not contain scaffold-only phrasing.
## Adoption Feedback For Teams
### What Would Make Me Comfortable Trying This In A Team Repo
- A root README that explains the value proposition in one minute and shows one complete Playwright example.
- A stable package import recommendation: ideally `import { imhotep } from 'imhotep/playwright'` or `import { imhotep } from 'imhotep'`, with the preferred path clearly documented.
- A compatibility matrix covering Node, Playwright, Chromium/browser requirements, framework presets, and operating systems.
- A clear explanation of when Imhotep uses CDP, what browser privileges it requires, and whether remote browsers are supported.
- A "known limitations" page that covers transformed layouts, stacking contexts, iframes, shadow DOM, virtualized lists, animations, screenshots, state materialization approximations, and unsupported topology helpers.
- A release process that proves packages are published together, versions match, package metadata points to the correct forge, and external smoke tests run from packed tarballs rather than only local paths.
### What Would Make Me Hesitate Today
- CI cannot install dependencies without a lockfile.
- Root README is not trustworthy for this repository.
- Root commands fail or do something different from their names.
- Version and release metadata disagree.
- There are many ignored generated files in source directories locally.
- The public Playwright integration implementation is too large to audit quickly.
- Some passing tests explicitly tolerate missing documented functionality.
## Open Questions
- Is the canonical branch intended to be `main` or `master` when pushed to Gitea?
- Is the current release supposed to be `1.0.0` or `1.1.0`?
- Are all 14 packages intended to be published independently, or should some packages be marked private/internal?
- Is `imhotep-playwright/src/public.ts` considered stable public implementation, or is a refactor acceptable before release?
- Should root installation be lockfile-reproducible with npm, or is the project intentionally avoiding a package lock?
- Are generated files in `packages/*/src/` expected historical residue, or does a current command still produce them?
- Should `clippedBy` be documented and implemented, or should references to it be removed until ready?
- What is the private security disclosure channel for the Gitea-hosted project?
- Should CI run package tests once on Node 22 and smoke on Node 18/20/22, or is the full unit matrix on all Node versions worth the runtime?
- What API surfaces are semver-stable for 1.x, and which are internal/experimental?
## Suggested Remediation Sequence
### Phase 1: Make The Repo Reproducible
1. Commit `package-lock.json` or replace all `npm ci` calls with intentional `npm install` usage.
2. Align CI branch triggers with the actual Gitea default branch.
3. Fix root scripts so every advertised command exits correctly.
4. Update `BUILD.md` to match the fixed scripts.
5. Update `npm run clean` to remove ignored generated files under `packages/*/src/`.
### Phase 2: Make The Repo Trustworthy To Readers
1. Replace the root README with a real Imhotep project README.
2. Align all versions and release notes.
3. Update repository URLs and security reporting instructions for Gitea.
4. Add package-level READMEs for public packages.
5. Remove static test counts from docs or automate their update during release.
### Phase 3: Make The Public Surface Governable
1. Classify exports as stable, experimental, or internal.
2. Split `packages/imhotep-playwright/src/public.ts` into focused modules.
3. Collapse duplicate public interface declarations.
4. Type the most important `any` boundaries in the DSL validator and Playwright public path.
5. Standardize package export conditions.
### Phase 4: Increase Quality Signals
1. Turn `noEmitOnError` back on for package build configs.
2. Add stricter lint targets for public API packages.
3. Convert "known missing feature" tests into skipped/TODO tests with issue links or implement/remove the feature.
4. Add smoke testing from packed tarballs, not only local package paths.
5. Add a release checklist that verifies package versions, repository metadata, tarball contents, and external install behavior.
1. Decide which packages are public and add READMEs or mark internal packages private.
2. Move internal exports to explicit internal subpaths or remove them from root barrels.
3. Standardize package export conditions.
4. Document the actual contributor golden path.
5. Consolidate world schemas or document a fact availability matrix.
6. Move test mocks out of `imhotep-core` production source.
7. Split large central files along stable seams.
## Bottom Line
Imhotep looks promising and technically ambitious. The core idea, package boundaries, diagnostic taxonomy, and test breadth are strong enough to justify continued investment.
Imhotep is promising enough to justify high standards. The core concept and much of the implementation already look like a serious framework rather than a toy wrapper around Playwright. The current weaknesses are fixable, but they are highly visible: a broken/misleading CLI path, stale examples, lockfile contamination, hardcoded local paths, and semantics that parse before they truly resolve.
The immediate work should be operational rather than feature-driven. Before adding more assertions or integrations, make the repo install, build, test, document, and publish in a way that a skeptical outside developer can reproduce without insider knowledge.
For a developer evaluating adoption, I would recommend a short hardening sprint before team rollout. For a developer onboarding to contribute, I would start with documentation truthfulness and reproducibility first, then move into variable-bound domain semantics and diagnostic fidelity. Those improvements would make the project live up much more closely to its stated goal: First Order Logic Geometric Contract and Property Testing for the Web.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.