Skip to content

test: establish architecture extraction gates - #30

Merged
IAnMove merged 2 commits into
mainfrom
refactor/wizard-control-plane-foundation
Aug 31, 2026
Merged

test: establish architecture extraction gates#30
IAnMove merged 2 commits into
mainfrom
refactor/wizard-control-plane-foundation

Conversation

@IAnMove

@IAnMove IAnMove commented Aug 31, 2026

Copy link
Copy Markdown
Owner

Note

Low Risk
Test and documentation only; no application or API behavior changes.

Overview
Adds static architecture contracts for the HocusPocus refactor plan: no runtime imports of _launch_runtime, FastAPI, or WanGP.

scripts/architecture_contracts.py AST-parses launch wiring and emits two reviewed fixtures: route_table.json (method, path, ordinal, and source for every route, with mounted app/routers/* factories expanded at each api.include_router site) and architecture_wire_inventory.json (Python/UI tests tied to _launch_runtime or useStore.ts, each labeled behavior, symbol_importable, architecture_rule, or fragile_source). The script fails if fixtures are stale; --write refreshes them after an intentional move.

tests/test_architecture_contracts.py locks those fixtures in pytest and adds a WanGP (wgp) import allowlist over first-party app/ code (vendor trees excluded): new imports fail; the list is meant to shrink only during the WanGP boundary work.

docs/development/ARCHITECTURE_FOUNDATION.md documents how to run and update the gates.

Reviewed by Cursor Bugbot for commit 0fe366b. Configure here.

@IAnMove

IAnMove commented Aug 31, 2026

Copy link
Copy Markdown
Owner Author

cursor review

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown

PR Review — Loreframe Studio

Risk: medium
Scope: 5 file(s); +3834/-0; docs, repo scripts / CI

Automated review from scripts/analyze_pr.py. This is a heuristic pass (no LLM) so humans still own the merge decision.

Findings

  • medium — Dangerous dynamic execution (scripts/architecture_contracts.py)
    scripts/architecture_contracts.py adds exec(). Confirm the input is trusted and sandboxed.
  • medium — Large pull request
    3834 additions / 0 deletions. Reviewers will have an easier time with smaller, focused PRs.
  • medium — Very large file change (tests/fixtures/architecture_wire_inventory.json)
    tests/fixtures/architecture_wire_inventory.json adds 449 lines. Consider splitting the PR.
  • medium — Very large file change (tests/fixtures/route_table.json)
    tests/fixtures/route_table.json adds 2945 lines. Consider splitting the PR.

Changed files

  • added: docs/development/ARCHITECTURE_FOUNDATION.md, scripts/architecture_contracts.py, tests/fixtures/architecture_wire_inventory.json, tests/fixtures/route_table.json, tests/test_architecture_contracts.py

CONTRIBUTING checklist

  • python scripts/verify_clean_repo.py
  • python -m compileall -q app/services app/launch.py scripts
  • cd ui && npm run build if the UI changed
  • No weights, CivitAI sidecars, or generated guides
  • Stays local-first (no required accounts / telemetry)

Posted by the repo PR review workflow. Re-runs on each push to the PR.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: WGP scanner skips dynamic imports
    • The WGP wall now flags importlib.import_module("wgp") and import("wgp") and names the existing first-party call in app/shared/api.py so the allowlist cannot stay green while that dependency remains or grows.

Create PR

Or push these changes by commenting:

@cursor push 3b18e861f5
Preview (3b18e861f5)
diff --git a/tests/test_architecture_contracts.py b/tests/test_architecture_contracts.py
--- a/tests/test_architecture_contracts.py
+++ b/tests/test_architecture_contracts.py
@@ -25,6 +25,7 @@
     ("app/services/model3d_service.py", "_active_profile", "import wgp"),
     ("app/services/model3d_service.py", "_minimax_api_key", "import wgp"),
     ("app/services/model3d_service.py", "_services", "import wgp"),
+    ("app/shared/api.py", "WanGPSession._ensure_runtime", "importlib.import_module('wgp')"),
     ("app/shared/magic_mask.py", "_ensure_sam3_assets", "import wgp"),
     ("app/shared/magic_mask.py", "_video_to_numpy", "from wgp import get_resampled_video"),
 }
@@ -40,6 +41,23 @@
 )
 
 
+def _is_dynamic_wgp_import(node: ast.AST) -> bool:
+    if not isinstance(node, ast.Call) or not node.args:
+        return False
+    name = node.args[0]
+    if not isinstance(name, ast.Constant) or name.value != "wgp":
+        return False
+    func = node.func
+    if isinstance(func, ast.Name) and func.id in {"import_module", "__import__"}:
+        return True
+    return (
+        isinstance(func, ast.Attribute)
+        and func.attr == "import_module"
+        and isinstance(func.value, ast.Name)
+        and func.value.id == "importlib"
+    )
+
+
 def _wgp_imports() -> set[tuple[str, str, str]]:
     found = set()
     for path in (ROOT / "app").rglob("*.py"):
@@ -54,6 +72,7 @@
         for node in ast.walk(tree):
             is_wgp = isinstance(node, ast.Import) and any(alias.name == "wgp" for alias in node.names)
             is_wgp = is_wgp or isinstance(node, ast.ImportFrom) and node.module == "wgp"
+            is_wgp = is_wgp or _is_dynamic_wgp_import(node)
             if not is_wgp:
                 continue
             scopes = []

You can send follow-ups to the cloud agent here.

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 0fe366b. Configure here.

Comment thread tests/test_architecture_contracts.py Outdated
for node in ast.walk(tree):
is_wgp = isinstance(node, ast.Import) and any(alias.name == "wgp" for alias in node.names)
is_wgp = is_wgp or isinstance(node, ast.ImportFrom) and node.module == "wgp"
if not is_wgp:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WGP scanner skips dynamic imports

Medium Severity

The WanGP wall only treats import wgp and from wgp import ... as imports, so the existing first-party importlib.import_module("wgp") call is never named. The allowlist can stay green while that dependency remains or while more dynamic imports are added.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 0fe366b. Configure here.

The first-party allowlist only scanned import/from statements, so
importlib.import_module("wgp") in WanGPSession._ensure_runtime stayed
invisible. Detect static loaders and record the existing site.

Co-authored-by: THEINAOG <IAnMove@users.noreply.github.com>
@IAnMove
IAnMove merged commit 9d2b935 into main Aug 31, 2026
4 checks passed
@IAnMove
IAnMove deleted the refactor/wizard-control-plane-foundation branch September 5, 2026 11:55
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