docs(milestone): complete v1.15 — Nova Rebrand (tag v1.15.4)
P5 final-review-ship complete: dual-read fallback removed (REQ-164) — core/env.py NOVA-only, .env.secrets load paths NOVA-only (G-106 retired), nova_tagging.py hard-fails any acdl:* tag, legacy ACDL_* Gitea secrets deleted, ACDL_LIFECYCLE_MODE/ACDL_LOCAL_TIER/ACDL_HITL_* exports removed from scripts, SNS subject → Nova SoD halt (P1-2), bootstrap scripts NOVA-only. Review: 2 P0 auto-fixed (duplicate delenv), P1-1/P1-2 resolved, doc-drift fixed. Audit: tags v1.15.0-4 exist; traceability REQ-155..164 all complete; ARCHITECTURE naming table matches codebase. 615 pytest PASS; run_ci.sh 3-stage PASS. NOVA_MIGRATION.md marked COMPLETE. ---ci--- project: acdl phase: 5 milestone: v1.15 status: complete phase_role: final requirements: covered: [REQ-155, REQ-156, REQ-157, REQ-158, REQ-159, REQ-160, REQ-161, REQ-162, REQ-163, REQ-164] partial: [] ---/ci---
This commit is contained in:
+14
-31
@@ -1,19 +1,14 @@
|
||||
"""Dual-read environment helper (D-108, REQ-159, G-106).
|
||||
"""Environment helper (D-108, REQ-159, REQ-164).
|
||||
|
||||
During the Nova rebrand transition window (P2–P4), every `NOVA_*`
|
||||
environment variable is the preferred source, with the legacy `ACDL_*`
|
||||
name as the fallback. This keeps deployments from breaking while the
|
||||
keys are rotated across `.env`, `.env.secrets`, Gitea repo secrets, and
|
||||
operator-managed process environments.
|
||||
During the Nova rebrand transition window (P2–P4), `get_env` read
|
||||
`NOVA_*` preferred with the legacy `ACDL_*` name as the fallback. **P5
|
||||
(REQ-164) removed the fallback** — `get_env` now reads `NOVA_*` only.
|
||||
|
||||
`get_env(name, default=None)` resolves `NOVA_<name>` first, then falls
|
||||
back to `ACDL_<name>`, then returns `default` if neither is set.
|
||||
|
||||
This helper is removed (NOVA-only) in P5 (REQ-164). Direct-read paths
|
||||
that bypass this helper (the `.env.secrets` shell export in
|
||||
`scripts/run_platform.sh` and the Python parser in
|
||||
`core/regression_verify.py`) mirror this contract inline per the G-106
|
||||
binding — see those sites for the dual-read shell/Python forms.
|
||||
`get_env(name, default=None)` resolves `NOVA_<name>`, then returns
|
||||
`default` if unset. Direct-read paths that bypass this helper (the
|
||||
`.env.secrets` shell export in `scripts/run_platform.sh` and the Python
|
||||
parser in `core/regression_verify.py`) were updated to NOVA-only in P5
|
||||
(the G-106 dual-read contract was retired with the fallback).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -25,24 +20,12 @@ __all__ = ["get_env"]
|
||||
|
||||
|
||||
def get_env(name: str, default: Optional[str] = None) -> Optional[str]:
|
||||
"""Resolve a config value with a NOVA-preferred / ACDL-fallback read.
|
||||
"""Resolve a config value from the `NOVA_*` environment.
|
||||
|
||||
`name` is the bare key WITHOUT the prefix (e.g. ``"AWS_ACCOUNT_ID"``).
|
||||
The lookup order is:
|
||||
|
||||
1. ``NOVA_<name>`` (preferred)
|
||||
2. ``ACDL_<name>`` (legacy fallback, removed in P5)
|
||||
3. ``default``
|
||||
|
||||
Returns the first value that is present and non-empty, or ``default``
|
||||
if neither env var is set. An explicitly-set empty string is treated
|
||||
as "unset" so an operator cannot accidentally shadow the fallback
|
||||
with a blank NOVA key.
|
||||
Returns ``NOVA_<name>`` if set and non-empty, else ``default``.
|
||||
"""
|
||||
nova_val = os.environ.get(f"NOVA_{name}")
|
||||
if nova_val:
|
||||
return nova_val
|
||||
acdl_val = os.environ.get(f"ACDL_{name}")
|
||||
if acdl_val:
|
||||
return acdl_val
|
||||
val = os.environ.get(f"NOVA_{name}")
|
||||
if val:
|
||||
return val
|
||||
return default
|
||||
@@ -502,6 +502,6 @@ if __name__ == "__main__":
|
||||
# Set both so the dual-read in is_local_tier() finds NOVA_* (preferred);
|
||||
# the ACDL_* alias stays for any unmigrated reader until P5.
|
||||
os.environ["NOVA_LOCAL_TIER"] = "1"
|
||||
os.environ["ACDL_LOCAL_TIER"] = "1" # legacy alias (dual-read fallback), removed in P5
|
||||
# P5 (REQ-164): ACDL_LOCAL_TIER legacy alias removed (NOVA_* only)
|
||||
result = run_local_e2e(contract)
|
||||
print(json.dumps(result, indent=2))
|
||||
@@ -315,13 +315,10 @@ def _load_aws_env() -> Dict[str, str]:
|
||||
continue
|
||||
if "=" in line:
|
||||
k, v = line.split("=", 1)
|
||||
# G-106 binding: dual-read NOVA_* first, ACDL_* fallback.
|
||||
# The .env.secrets keys are renamed to NOVA_* in P2; the
|
||||
# ACDL_* fallback covers operators who haven't rotated
|
||||
# their local .env.secrets yet. Removed in P5.
|
||||
if k == "NOVA_AWS_ACCESS_KEY_ID" or k == "ACDL_AWS_ACCESS_KEY_ID":
|
||||
# P5 (REQ-164): dual-read fallback removed — NOVA_* only.
|
||||
if k == "NOVA_AWS_ACCESS_KEY_ID":
|
||||
env["AWS_ACCESS_KEY_ID"] = v
|
||||
elif k == "NOVA_AWS_SECRET_ACCESS_KEY" or k == "ACDL_AWS_SECRET_ACCESS_KEY":
|
||||
elif k == "NOVA_AWS_SECRET_ACCESS_KEY":
|
||||
env["AWS_SECRET_ACCESS_KEY"] = v
|
||||
elif k == "AWS_DEFAULT_REGION":
|
||||
env["AWS_DEFAULT_REGION"] = v
|
||||
|
||||
@@ -74,7 +74,7 @@ def route_halt_artifact(contract_id: str, violation_reason: str,
|
||||
sns.publish(
|
||||
TopicArn=topic_arn,
|
||||
Message=json.dumps(halt_payload),
|
||||
Subject="ACDL SoD halt",
|
||||
Subject="Nova SoD halt",
|
||||
)
|
||||
print(f"[halt-artifact] SNS published contract={contract_id} "
|
||||
f"topic={topic_arn}", flush=True)
|
||||
|
||||
Reference in New Issue
Block a user