Issue #934 APTL-To-LilRAE Rename Boundary Preflight¶
This note fixes the architecture boundary for the rename audit. It does not perform the audit, rename a runtime identity, or define a delivery sequence. The issue's 2026-09-05 review disposition is the current contract; the older acceptance text remains useful for identifying the incorrect model.
Identity decision¶
- APTL and LilRAE are one product before and after a rename. They are not peer backends, nested products, a host and plugin, or separate user experiences.
- TechVault is a scenario pack. Its topology, vulnerable applications, seeded content, selected integrations, and verification policy remain pack-specific, but they do not form an APTL product or an "experience layer" on LilRAE.
- RAES remains the separate owner of portable scenario/runtime semantics, and
OpenRAE/env-packsremains the owner of the pack format and current TechVault pack bytes. Neither is renamed by this issue. - Terms such as core, optional integration, participant tooling, research apparatus, web UI, and appliance delivery may describe dependency or packaging boundaries. They must not be promoted into product identities.
- A remaining
aptlliteral is a technical compatibility identity only when the inventory says so. Its existence is not evidence that APTL and LilRAE coexist.
No new ADR should preserve the rejected model. Proposed ADR-054 through ADR-058 and their #962 disposition entries are editable proposals: correct the false statements in those records directly. Keep ADR numbers stable. If an ADR filename is retained for incoming-link compatibility after its title changes, record that path explicitly as a legacy locator rather than treating its words as architecture.
Baseline and useful history¶
The #962 review is an incumbent input, not a current complete inventory. Its
tracked-file-inventory.tsv covers 1,467 paths at the recorded review
baseline. At preflight commit d48d2b7e, the repository has 1,505 tracked
paths: 38 current paths are absent from that TSV and no TSV path has
disappeared. Most of the delta is the review/ADR material itself plus the
post-baseline orchestration-authority split. Closure evidence must name its
source commit and reconcile this delta; it must not silently relabel the old
ledger as a current snapshot.
History anchors that explain the present boundaries include:
00fe44bd/ #660: bundled the tracked lab tree into the installable wheel;ced66dcc/ #846: the ACES-to-RAES namespace migration and public-import precedent;7b21cdbd/ #890: the TechVault realization contract and verifier seam;4dcf07bd/ #908: consumption of TechVault through the env-pack;ebb4db29/ #927: the pack/backend serving-interaction seam; andc1497e42,2f8d282c, andd48d2b7e/ #971: creation, correction, and integration of the #962 readiness review.
Use repository Git history as the history record. Do not duplicate known-false prose merely to preserve it: Git already does that. Signed, sealed, content-addressed, or externally published evidence bytes are different and remain immutable.
Inventory contract¶
Keep the #962 tracked-path and ADR-disposition ledgers as named inputs. The rename audit needs one complementary identity-disposition ledger, not another copy of every tracked path. One row represents one independently versioned or retired identity surface; multiple occurrences of the same contract belong in that row.
Each row must carry these facts:
| Field | Required meaning |
|---|---|
| Surface and kind | A stable row id and one kind such as product prose, repository, distribution, import root, CLI, config/env, backend target, plugin, telemetry, persisted schema, state path, native resource, image, static route, scenario pack, or historical record |
| Current identity and locations | Exact case-sensitive literal plus all owning source/config/doc locations; a glob or generated occurrence report may supplement, not replace, named owners |
| Semantic owner | LilRAE product, TechVault pack, RAES, env-packs, external service, repository governance, or immutable historical evidence |
| History | Introduction/change commit or an explicit reason history is immaterial |
| Disposition | Correct now, retain technical identity, rename later, version with reader, historical immutable, retire after parity, externally owned, or blocked on coordination |
| Compatibility boundary | The single reader, shim, accessor, entry-point group, or resolver that contains compatibility; empty when no compatibility is allowed |
| Retirement evidence | Released replacement, consumer/import proof, data-reader window, parity proof, migration guidance, and removal condition as applicable |
| Coordination owner | #970, #880, OpenRAE/lilrae#3, another named issue, or this audit; never an unowned “later” |
The kind field is the extensibility seam. A later repository move, CLI alias,
or schema generation can add a row without adding brand-specific columns or
changing the meaning of existing rows. Reconciliation succeeds when every
candidate has a disposition and every location agrees with its canonical row;
it does not require zero APTL strings.
The current #962 categories experience-mcp, experience-plugin,
split-core-experience, and rules referring to “experience docs/modules” are
not acceptable final semantic owners. Replace their conceptual meaning with
scenario-pack integration, optional product capability, research apparatus,
or another concrete technical owner. Do not mechanically replace every use of
the ordinary word “experience”; classify what the sentence asserts.
Canonical incumbents to reuse¶
| Concern | Existing owner and guardrail |
|---|---|
| Repository-wide coverage | git ls-files, the #962 tracked-file TSV, its baseline commit, and an explicit current delta. Generated site/, local runs/, caches, and untracked state are not source inventory. |
| Current prose and decisions | README, current docs/navigation, code comments, package descriptions, ADR-054 through ADR-058, migration-inventory.md, adr-disposition.md, and backlog-disposition.md. Correct false claims in place; do not add a superseding identity ADR. |
| Product distribution/import/CLI | pyproject.toml owns aptl-labs, src/aptl, aptl, and aptl-misp-suricata-sync; release-please-config.json, .release-please-manifest.json, release workflows, and hatch_build.py consume those exact identities. This audit inventories them and does not create lilrae aliases. |
| RAES imports | The pinned RAES packages and tests/test_raes_namespace_cutover.py are the incumbent dependency/import policy. Extend that AST-based check when public replacements exist; do not add a second import scanner or compatibility package. |
| Config and environment | Strict nested AptlConfig/load_config(), ScenarioSourceConfig, EnvVars, dotenv hydration, placeholder checks, host-port binding, WebAuthSettings, and ServiceConfig.from_env() own Python-side aptl.json/environment input. mcp/aptl-mcp-common/src/config.ts owns the shared docker-lab-config.json/dotenv loader for every MCP. Its LabConfig interface is compile-time only and its current runtime checks are shallow; do not mistake that interface for a shape gate or fork validation into each MCP. A brand alias must never bypass extra="forbid", the common MCP loader, or create two sources of truth. |
| Pack acquisition and identity | ScenarioBundle, ScenarioSourceKind, PackIdentity, env-packs public validation, ScenarioCatalog, and RAES parsing/planning are the only pack/source shape. TechVault remains an ordinary exact pack identity, version, and digest. |
| Plugins | aptl.scenario_verifiers and aptl.pack_backend_interactions, their compatibility metadata, installed distribution provenance, and fail-closed discovery are the only plugin seams. The current verifier's empty content-digest list is a known compatibility gap, not an exact-match precedent. Installed entry points are trusted executable code, not a product layer or sandbox. |
| Persistence | Versioned aptl.*/aptl-* schema ids, .aptl, run stores, archive sealing, provenance/correlation, appliance records, and core/archival/legacy_manifest.py are data contracts. Preserve bytes and centralize any later compatibility read. |
| Errors and observability | RAES Diagnostic, LabResult, StartupDiagnostic, existing domain errors, aptl.utils.redaction.redact, and get_logger() remain the vocabularies. A rename does not justify duplicate exception trees, log pipelines, or response envelopes. |
| Runtime/native identity | BackendIdentity, the serialized RAES target, Compose deployment.project_name, labels, container/network/image names, MCP server ids, and telemetry attributes are operational contracts. Names do not establish ownership, and this audit does not mutate them. |
| Workflow and quality | .ground-control.yaml, .gc/plan-rules.md, .pre-commit-config.yaml, .github/workflows/checks.yml, and .github/workflows/release-please.yml remain canonical. Reuse pytest, strict MkDocs, Vale, the RAES static/live gates, all MCP consumer builds, installed-wheel checks, locked dependency exports, and release provenance rather than adding a rename-only workflow. |
The current public-import audit must explicitly record four private RAES uses:
raes._source.ArtifactIdentity,
raes_processor.compiler.addresses._node_address in two runtime modules, and
raes_runtime.control_plane_store._snapshot_payload. It must also record the
older-package ImportError fallback for
BACKEND_SUPPORTED_CONTRACT_IDS in raes_manifest.py. These are migration
blockers or compatibility decisions for the owning work, not invitations to
copy upstream code, use dynamic imports, or swallow import failure here.
Security and cross-cutting passage¶
The intended #934 change is documentation, inventory, and reconciliation evidence. It adds no runtime input or side effect. That narrow design passes the cross-cutting layers as follows:
| Layer | Required passage |
|---|---|
| Audit input and secret boundary | Inspect repository-tracked paths and Git history only. Do not inspect generated .env, .aptl, runs, credentials, private keys, local caches, or user secret stores. Inventory variable/key names, never values. |
| Auth surface | Add no API, web, websocket, MCP tool, listener, or auth alias. verify_token, WebAuthSettings, BFF Host/CSRF/session checks, request limits, and terminal tickets remain unchanged. |
| Config and shape validation | Change no config key, parser, default, or environment binding. Current literals remain subject to strict AptlConfig, EnvVars, WebAuthSettings, ServiceConfig, host-port, scenario-catalog, RAES/env-pack, plugin-metadata, and Pydantic shape gates, plus the common MCP config loader. The MCP LabConfig interface supplies no runtime validation beyond that loader's checks. A ledger disposition cannot authorize a runtime alias. |
| Filesystem and pack ingress | Add no path resolver. Existing no-follow containment in pathsafe/ScenarioBundle, env-pack validation, and project-root checks remain authoritative. A renamed path string in prose cannot become an accepted pack or host path. |
| OS/process exposure | Add no executable, shell call, Docker/Compose action, environment export, port, socket, or process argument. In particular, do not put credentials or private paths in argv to support a compatibility shim. |
| Error envelopes and logs | Preserve error codes, redacted/bounded diagnostics, generic HTTP authentication failures, logger hierarchy, and telemetry attribute contracts. Terminology edits must not expose raw validation input, paths, stderr, plugin exceptions, or secrets. |
| Persistence and export | Do not rewrite archives, signatures, digests, run records, .aptl state, appliance manifests, or exported bundles. A later writer rename requires a schema version plus one bounded legacy reader; aliases must not make ambiguous records valid. |
| Supply chain and plugin trust | Change no distribution, dependency, entry-point group, or package lookup. Any later identity cut must update locked metadata, wheel/import tests, SBOM and vulnerability workflows together and retain exact plugin compatibility/provenance checks. |
Static-path retirement boundary¶
The old static path is not one file. It includes the explicit
project-tree source in ScenarioSourceConfig/ScenarioSourceKind,
project_tree_bundle(), root docker-compose.yml lookup in the Compose
realization/profile paths, mixed/legacy realization, named profile fallbacks,
and broad wheel bundling/materialization through _asset_manifest.py,
hatch_build.py, core/assets.py, and cli/lab_init.py.
Retirement is coordinated with #880 and #970 and is allowed only when the same
released, digest-identified pack path proves acquisition, admission,
realization, observation, reset, teardown, and installed-wheel behavior; user
data has a named reader/migration policy; and no current config, CLI, test, or
packaging route silently selects the static path. Absence of
docker-compose.yml must not itself change authority. Unsupported legacy input
fails with the existing bounded diagnostics; it must not fall back to nearby
TechVault bytes or a second lifecycle.
Gotchas and anti-patterns¶
- Do not use a blanket APTL-to-LilRAE replacement. A prose brand, PyPI distribution, Python package, CLI, config filename, env key, schema id, logger, container, repository URL, and historical byte string have different compatibility contracts.
- Do not create a LilRAE wrapper around APTL, dual active backends, mirrored
lilraeDTO/config/schema/error hierarchies, or a second lifecycle for a tiny pack. - Do not call TechVault a product, experience, platform layer, runtime, or retained APTL surface. Optional MCPs/verifiers are integrations selected for a scenario pack, not evidence of another product boundary.
- Do not preserve false current prose under “historical” labels when Git already preserves it. Conversely, never rewrite sealed or content-addressed evidence merely to modernize branding.
- Do not treat the #962 owner category as proof of import safety, scenario independence, data compatibility, or current-file coverage.
- Do not rename plugin groups or backend target strings without an exact producer/consumer inventory. Do not allow config, pack data, or CLI strings to choose Python imports.
- Do not add permissive config aliases, catch broad import/parse errors, accept both schema sections, use last-one-wins behavior, or silently fall back to an old static path.
- Do not treat the MCP
LabConfiginterface as runtime validation or add per-server rename parsers. Any later config cut belongs in the shared loader, with fail-closed shape checks and every dependent MCP rebuilt. - Do not treat an empty verifier content-digest list as proven compatibility; it is an existing gap that later plugin qualification must close.
- Do not move lifecycle responsibilities while correcting terminology. Record
mixed ownership for #970; this issue does not decompose
core/lab.py. - Do not infer that a temporary
aptltechnical identifier denotes a separate architecture. Its ledger disposition is the authority.
Non-goals and implementation boundary¶
This audit does not choose the final repository, PyPI distribution, Python import root, CLI, config/env, backend target, plugin group, telemetry namespace, schema id, state directory, Compose project, container/image, or release identity. It does not ship compatibility aliases, migrate user data, retire the static Compose/project-tree path, move TechVault again, decompose the lifecycle, change RAES/env-packs contracts, alter auth/secret/error/logging behavior, or qualify a release. Those identities receive explicit dispositions and named owners so later work can change them without recreating the false product model.