Skip to content

feat: detect Drupal extensions, workspace roots, and Payload/Next generated code - #16

Closed
Cenadros wants to merge 2 commits into
mainfrom
feat/detection-profiles-workspaces
Closed

Cenadros wants to merge 2 commits into
mainfrom
feat/detection-profiles-workspaces

Conversation

@Cenadros

Copy link
Copy Markdown
Contributor

Summary

Subproject E of the Runroom rollout: make the gate detect the code that real Runroom repositories actually contain, and stop reporting generated or framework entry files as findings.

  • Drupal profile scans .module, .theme, .install, .inc, .profile and .engine as PHP in PHPCS (extensions arg), jscpd (formatsExts) and the advisory HTML report, with structural anchors mapped to the PHP grammar.
  • Workspace roots from manifests: pnpm-workspace.yaml, package.json workspaces, depth-1 directories with their own package.json, composer.json autoload, [tool.uv.workspace] and [tool.setuptools.packages.find].where. Members map to <member>/src when present, must contain their manifest, and are unioned with conventional and depth-1 discovered roots. Patterns go through a bounded segment matcher (no picomatch on consumer input), with 200-pattern / 200-char caps and pnpm ./ normalisation. Drupal keeps its curated PHP roots.
  • Payload/Next profile: next.config.* at the root or payload.config.* at the root or src/ excludes payload-types.ts, importMap.js, app/(payload)/**, migrations/**, migrations-*/**, seed/**, .next/** and next-env.d.ts, scoped to the TypeScript roots so PHP/Python code in hybrid repos is untouched. A Notice: identifies the profile.
  • Knip: static framework entries (Next app/pages routes, middleware, instrumentation, Payload/Vite/Vitest/Playwright configs) detected per workspace owner; one workspaces block per owner with its own ignore; a mandatory "." block; ignoreWorkspaces for manifest members owning no source root; owner and member names validated before being emitted as Knip patterns. Plugin toggles are now generated from the complete knip 6.35.1 runtime registry (183 plugins) instead of a 22-entry hand-written list, and a test fails if the installed knip registry drifts.
  • No new ResolvedConfig field: the configuration hash of every existing fixture is byte-identical. The hash changes only for Payload/Next repositories (exclusions are recorded in exclude).

Fixtures and verification

New integration fixtures drupal-project, payload-project (local file:stubs/* dependencies) and monorepo-project, with mutations including a negative one (complexity added to src/payload-types.ts must not regress).

  • pnpm verify: typecheck, lint, 620 tests, build.
  • pnpm docker:build && pnpm integration: 24/24 rows green (7 fixtures, 11 mutations).
  • Existing fixture baselines under fixtures/*/quality/ unchanged.

Dependencies

  • smol-toml@1.8.0 (runtime, bundled) for pyproject.toml parsing.
  • knip@6.35.1 (dev) so the plugin-registry test reads the pinned version.

Docs

docs/configuration.md (workspace roots, Drupal extensions, new Payload/Next profile section), docs/checks.md (Knip entries and workspaces), docs/security.md (plugin toggles from the full registry; static entry patterns are parsed, never executed), docs/development.md, README.md.

…erated code

Reduce first-run noise on real repository layouts:

- Drupal profile scans .module, .theme, .install, .inc, .profile and .engine
  files as PHP in PHPCS and jscpd, with structural tree-sitter anchors.
- Source roots add workspace members from manifests (pnpm-workspace.yaml,
  package.json workspaces, depth-1 packages, composer autoload, uv workspace,
  setuptools where), unioned with conventional and discovered roots. Member
  patterns use a bounded segment matcher instead of picomatch.
- Payload/Next profile excludes generated types, import map, admin route
  group, migrations, seed data and Next build output, scoped to the resolved
  TypeScript roots, and reports a Notice.
- Knip receives static framework entry patterns per workspace owner, one
  workspace block per owner with its own ignore list, ignoreWorkspaces for
  members owning no source root, and plugin toggles generated from the
  complete knip 6.35.1 plugin registry (verified by a test).
- New fixtures drupal-project, payload-project and monorepo-project run in
  the integration suite, including a negative mutation for excluded code.

Adds smol-toml (runtime) and knip (dev) as exact dependencies.
@Cenadros
Cenadros requested a review from a team September 14, 2026 15:13
@Cenadros

Copy link
Copy Markdown
Contributor Author

Superseded by the combined PR from feat/runtime-toolchain, which includes these commits plus fixes from the final review.

@Cenadros Cenadros closed this Sep 23, 2026
Cenadros added a commit that referenced this pull request Sep 23, 2026
…ain (#17)

## Summary

Combines subproject E (detection without noise) and subproject B
(consumer toolchain and runtime targeting). Supersedes #16, whose
commits are included here together with fixes from the final combined
review.

**Detection (E)**
- Drupal profile scans `.module`, `.theme`, `.install`, `.inc`,
`.profile` and `.engine` as PHP (PHPCS, jscpd, anchors).
- Source roots add workspace members from `pnpm-workspace.yaml`,
`package.json` `workspaces`, depth-1 packages, `composer.json`
`autoload`, `[tool.uv.workspace]` and setuptools `where`, through a
bounded segment matcher.
- Next and Payload profiles, detected per workspace owner: Next excludes
build output only; Payload (config file or dependency) also excludes
generated types, import map, admin route group, migrations and seed.
- Knip gets static framework entries per workspace owner and plugin
toggles generated from the full knip 6.35.1 registry (183 plugins),
verified by a test.

**Runtime (B)**
- Image ships corepack (pnpm 10.17.1 default, 11.5.2 and yarn 1.22.22
cached), uv 0.12.14, CPython 3.14.7 and `/opt/venv314`.
- Python target from the root or uv workspace members selects
`/opt/venv314` at 3.14+, sets Ruff `target-version`, and joins the
configuration hash when Python is resolved.
- The version gate probes each tool through the environment its check
uses.
- `doctor` and `versions` gain a Runtime group.

## Migration

`POLICY_VERSION` is now `2026-09-23.1`: plugin toggles, Drupal
extensions and profile scoping change findings. After upgrading, remove
`quality/` and run `code-quality check --initialize`. No Runroom
repository has a `.code-quality.yml` yet.

## Decisions

- PHPStan `phpVersion` is not injected: PHPStan infers it from
`config.platform.php`, and a lower Composer floor produces diagnostics
the fail-closed adapter rejects.
- `doctor` probes only `corepack`; the pnpm/yarn shims read
`packageManager` from the analysed repository.
- Known limits (documented): directories without a manifest inside a
workspace container need `paths.<language>`; Payload exclusions scoped
to a TS root also apply to other languages under it; the Knip
`node_modules` guard checks the root only.

## Verification

- `pnpm verify`: typecheck, lint, 700 tests, build.
- `pnpm docker:build && pnpm integration`: 26/26 rows (10 fixtures
including `drupal-project`, `payload-project`, `monorepo-project`,
`python314-project`; mutations including negative ones).
- All fixture and repository baselines regenerated under the new policy;
hashes match `loadConfig`.
@Cenadros
Cenadros deleted the feat/detection-profiles-workspaces branch September 23, 2026 07:45
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