TracePulse PLM Engine Core — control_plane (governance, autonomy, HITL, run lifecycle, trace propagation) + agent_runtime (selector, dispatcher, retry, escalation). US-CR.1 scaffold; behaviour lands in US-CR.0+. Internal one-way import contract: control_plane MUST NOT import from agent_runtime (mechanical enforcement in US-CR.2).
Project description
plm-engine-core
TracePulse PLM Engine Core package. Lives next to plm-shared in the
monorepo; shipped editable for Wave 1 (pip install -e ../plm-engine-core),
internal PyPI publication deferred to Wave 5.
US-CR.1 ships this package as empty scaffolding. Every other
US-CR.* story in FTR-607 lands its implementation inside the two
sub-packages declared here, on top of contracts published by
plm-shared (US-W1.0).
Internal layout
| Sub-package | Owns | Stories landing here |
|---|---|---|
control_plane/ |
governance, autonomy, HITL, run lifecycle, trace propagation | CR.0, CR.3, CR.4, CR.5, CR.6, CR.10, CR.13 |
agent_runtime/ |
selector, dispatcher, retry, escalation | CR.10, CR.11 |
The split implements target architecture invariant #5 — execution separated from expertise — and decision D-LOCKED-13. The physical repo split is deferred to V1.1; Wave 1 delivers the logical boundary.
One-way import contract
control_plane ─────► plm_shared.* (frozen contracts)
agent_runtime ─────► plm_shared.* (frozen contracts)
agent_runtime ─────► control_plane (asks for verdicts)
control_plane ──╳──► agent_runtime (FORBIDDEN)
plm_engine_core ─╳──► plm_accelerators (FORBIDDEN)
control_plane decides what is allowed; agent_runtime asks
how do I run this. Reversing the dependency (control_plane reading
runtime state) couples policy to execution and breaks the V1.1 repo
split. plm-engine-core MUST NOT import from the Workbench /
Accelerators package; reversing this absorption would dissolve
the platform / product-line boundary (anti-pattern #8).
Mechanical enforcement (US-CR.2 / Conv F sub-story 3): two
import-linter contracts in pyproject.toml fail CI on any
violation:
| Contract | Source | Forbidden |
|---|---|---|
control_plane-must-not-depend-on-agent_runtime |
plm_engine_core.control_plane |
plm_engine_core.agent_runtime |
plm_engine_core-must-not-depend-on-workbench |
plm_engine_core |
plm_accelerators |
if TYPE_CHECKING: imports across the boundary are blocked by
default (CR.2 AC-6) — TYPE_CHECKING leakage is the most common
way the boundary erodes silently. tests/ lives outside the
package and is naturally excluded.
The CR.1-era by-convention guard in tests/test_imports.py STAYS
alongside the mechanical contract. Both fire if either rule trips
— belt-and-braces protection if the linter contract has to be
relaxed for a transient reason.
Negative-fixture toggling test
A permanent sandbox lives at
plm_engine_core/control_plane/_lint_fixtures/violation_demo.py.
The tests/test_import_linter.py::test_negative_fixture_trips_*
tests (gated by RUN_LINTER_NEGATIVE=1) materialise a temporary
sibling file with an offending import, run lint-imports, assert
the contract trips with the right name + file:line, then delete
the temp file and verify the clean state passes again. Run with:
RUN_LINTER_NEGATIVE=1 pytest tests/test_import_linter.py -v
Exemption process
Genuine exceptions go through an ADR signed off by the
architecture team. ADRs live under
02_App/plm-engine-core/docs/adr/. Each ADR records
the contract relaxed, the scope of the relaxation
(typically a specific ignore_imports entry on one contract),
the rationale, and the cross-link to D-LOCKED-13 + invariant #5.
The contract / ignore_imports edit MUST cite the ADR file path
in a comment so a future reader finds the authority for the
exemption.
Known limitations
- Transitive imports via
plm-sharedare not caught (CR.2 §9 + Edge cases). A control_plane file importing a plm-shared helper that itself transitively imports agent_runtime is invisible to the contract. Intentional — limits blast radius of a single PR's contract scope. - Dynamic imports (
importlib, string-based) are not caught. Static analysis only. - The contracts are scoped to plm-engine-core. Cross-product-
line contracts (e.g.
agent_runtime → connectors,agent_runtime → workbench) land with Epic 6 / Epic 8.
with_system_identity allowlist (CR.2 Decision #24)
plm_engine_core.control_plane.identity.with_system_identity is a
context manager that binds an actor_kind="system" identity for
in-process callers without an inbound JWT (cron, BackgroundTask,
GC). It bypasses JWT validation by design and MUST NOT be invoked
from arbitrary call sites.
The path-based BL6 guardrail in
02_App/backend/scripts/architecture_guardrails.py
restricts the importer set. Initial allowlist:
plm_engine_core/control_plane/identity/system_identity.py— defining module.plm_engine_core/control_plane/identity/__init__.py— re-export site.plm_engine_core/cli/—plm-clifuture subcommands may bind a system identity for offline operations.tests/— fixtures may import freely.
Adding a new module to the allowlist requires an ADR.
Install (developer)
cd 02_App/backend
pip install -e ../plm-engine-core
The editable install puts plm_engine_core.* on the sys.path of the
backend venv. Like plm-shared, pip install MUST run from
02_App/backend/ because pip resolves -e ../plm-engine-core
relative to the invocation CWD.
Tests
cd 02_App/plm-engine-core
python -m pytest tests/ -v
The smoke test verifies:
- Both sub-packages import cleanly.
__all__placeholders match the documented public surface.- No
control_planemodule imports fromagent_runtime(one-way contract guard, AC-10). - No business logic has snuck in beyond
__init__.pyfiles (AC-9 scope-creep guard).
CI
.github/workflows/test.yml runs a plm-engine-core-tests job
mirroring plm-shared-tests — editable-install + pytest on every
push to main / FTR575-Codebase-Split and on every PR touching
02_App/**.
Status
- US-CR.1: scaffold (Conv E close
822c415). Ships placeholders only. - US-CR.0 (Wave 1 Conv E + Conv F):
IdentityMiddleware,Hs256JwtIdentityProvider,with_system_identity,audit_logmigration 0013, andplm-cli auth issue-tokenall land. 16/16 ACs covered; story closed Conv F (3/3 PRs). - US-CR.2 (Wave 1 Conv F): two import-linter Forbidden contracts +
permanent negative-fixture toggling test + BL6 path-based guardrail
for
with_system_identity+ ADR exemption process.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file plm_engine_core-0.1.0a0.tar.gz.
File metadata
- Download URL: plm_engine_core-0.1.0a0.tar.gz
- Upload date:
- Size: 151.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7001db94e4bbb63a84aabf762335ecddca9e8103e2141a6eda7c13583f312adb
|
|
| MD5 |
31abb00020ccb5bae0a5519caa0a7055
|
|
| BLAKE2b-256 |
7a19a78dc92c2065aaced8e1851f81603a072745eb7f6181b03e772a591e4683
|
File details
Details for the file plm_engine_core-0.1.0a0-py3-none-any.whl.
File metadata
- Download URL: plm_engine_core-0.1.0a0-py3-none-any.whl
- Upload date:
- Size: 119.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bb1aae50385430c0f539c34ed74099b35143243136b3193a97b4c53253cbcf17
|
|
| MD5 |
14ca72c05756486601607af8143aafe8
|
|
| BLAKE2b-256 |
bef3c2c4eced58d6b2431f9ce8b0696f266202a502ce8f514d04fd0eadfc5eb2
|