Skip to content

test: package boundary contracts for the campus-core carve - #977

Merged
ngjunsiang merged 1 commit into
refactor/audit-http-movefrom
test/package-boundaries
Oct 27, 2026
Merged

ngjunsiang merged 1 commit into
refactor/audit-http-movefrom
test/package-boundaries

Conversation

@nycomp

@nycomp nycomp commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

Closes the contract-tests line of #970 (phase 1). Stack: 3/3 on #976 (which needs #975) — CI runs per link.

Change

tests/unit/test_package_boundaries.py encodes the layering agreed on #970 as executable rules, so the phase-3 distribution split stays mechanical:

AST rules (shared layers: common, config, model, storage, webauth, services):

  • may depend only on the campus layers in SHARED_ALLOWED (e.g. storage → common+model; common → nothing);
  • must never import a service layer (auth, api, audit, yapper, flask_campus, deploy) — module level or lazy;
  • no flask/werkzeug at module level (the documented lazy exception: the emailotp template renders at call time);
  • campus.common's only allowed module-level third-party import is bcrypt (utils/secret.py) — keeps requests from ever riding back in.

Runtime rule:

  • importing campus.storage must not load psycopg2/pymongo/boto3 (drivers stay per-backend lazy; subprocess-based, since the test process may have them loaded).

These rules are green on today's tree — the phase-0 work (#972/#973) and the #976 move are exactly what made that true. Mutation-verified: a module-level import flask added to campus/model/base.py fails with the exact file/line/rule, then the tree reverts clean.

Verification

Full unit (842), contract, integration, and ruff check . green at this tip.

Encodes the layering agreed on #970 as executable rules:

- AST: shared layers (common, config, model, storage, webauth,
  services) may depend only on SHARED_ALLOWED campus layers, must
  never import a service layer (even lazily), and must keep
  flask/werkzeug out of module level; campus.common's only allowed
  module-level third-party import is bcrypt (utils/secret).
- Runtime: importing campus.storage must not load psycopg2, pymongo,
  or boto3 (drivers stay per-backend lazy).

Relative imports resolve to absolute campus-rooted targets: the
resolver anchors at the file's containing package, so rule
violations written as 'from ..audit import ...' are caught too
(both sides mutation-verified: a module-level 'import flask' and a
relative service-layer import in campus/model/base.py each fail
with the exact file/line/rule).

If these stay green, phase 3 packaging is mechanical.
@nycomp
nycomp force-pushed the test/package-boundaries branch from 2741f43 to efc38a5 Compare October 27, 2026 15:52
@ngjunsiang
ngjunsiang merged commit 5909847 into weekly Oct 27, 2026
22 checks passed
@nycomp
nycomp deleted the test/package-boundaries branch October 27, 2026 16:00
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.

2 participants