Make the import-surface scan cover symlinked external plugins
All checks were successful
CI / backend (push) Successful in 23s
CI / naming (push) Successful in 1s
CI / frontend (push) Successful in 7s

Path.rglob does not descend symlinks, so a symlinked external plugin
(the ADR-003 dev loop) silently escaped the contract-purity scan. The
scanner now resolves plugin dirs before walking, a regression test
plants a symlinked plugin with a real violation and asserts it is
flagged, and the known-limitation notes in the external-repo docs are
lifted.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
cproudlock
2026-07-11 10:36:28 -04:00
parent 529b9f2fed
commit 81178b7be3
3 changed files with 52 additions and 14 deletions

View File

@@ -266,12 +266,13 @@ manifest parses, the `core_version` range admits the framework's
contract test run errors and the script exits nonzero), models expose
`__tablename__`, and hooks return the right shapes.
One gap to know about: the framework's `test_plugins_only_import_contract_surface`
scans `plugins/` with `Path.rglob`, which does not descend symlinked directories
on CPython 3.12. So that particular sub-test does not see a symlinked external
plugin's source. Keep an equivalent import-surface assertion in your own
`tests/` so your CI still enforces "core imports only via `shopdb.api`". A
minimal version:
The import-surface scan (`test_plugins_only_import_contract_surface`) covers
symlinked plugins too: the scanner resolves each plugin directory before
walking it, because `Path.rglob` alone does not descend symlinks (pinned by
`test_import_scan_covers_symlinked_plugins`). You can additionally keep an
equivalent import-surface assertion in your own `tests/`, so violations fail
in your repo's CI even when run without the framework harness. A minimal
version:
```python
# tests/test_import_surface.py