Save The Tree implementation and acceptance work in progress
Preserve production code, regression fixtures, audio assets and provenance, test infrastructure, and the original-completion plan and progress ledger. Final game and Windows acceptance remain pending; excluded local artifacts and native experiments are not part of this snapshot.
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
"""Bind atomic conditions to current static leads without promoting them to PASS.
|
||||
|
||||
Old group evidence supplies search leads only. Presence and unchanged bytes are
|
||||
not proof of normal operation, complete content, or accepted release behavior.
|
||||
"""
|
||||
from datetime import datetime
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
import re
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[4]
|
||||
PLAN = ROOT / "docs/plans/original-completion-2026-10-02"
|
||||
|
||||
|
||||
def sha(path):
|
||||
return hashlib.sha256(path.read_bytes()).hexdigest() if path.is_file() else None
|
||||
|
||||
|
||||
def main():
|
||||
atomic = json.loads((PLAN / "atomic_requirements.json").read_text())
|
||||
groups = {r["id"]: r for r in json.loads((ROOT / "docs/traceability/original/requirements.json").read_text())}
|
||||
baseline = json.loads((ROOT / "artifacts/facility-need-pricing-production-scale-adoption-2026-10-01-r01/after.json").read_text())
|
||||
definitions = {}
|
||||
for path in sorted((ROOT / "data/facilities").rglob("*.tres")):
|
||||
match = re.search(r'^id = &"([^"]+)"$', path.read_text(), re.MULTILINE)
|
||||
if match:
|
||||
definitions[match.group(1)] = path
|
||||
catalog = (ROOT / "scripts/data/facility_catalog.gd").read_text()
|
||||
characters = {r["id"] for r in json.loads((ROOT / "data/characters/mvp_unique_characters.json").read_text())["entries"]}
|
||||
locators = {}
|
||||
rows = []
|
||||
|
||||
def locate(name, symbol=None):
|
||||
key = (name, symbol)
|
||||
if key not in locators:
|
||||
path = ROOT / name
|
||||
entry = {"path": name, "exists": path.is_file(), "sha256": sha(path),
|
||||
"matches_retained_baseline": sha(path) == baseline.get(name) if name in baseline else None,
|
||||
"semantic_acceptance": "not_verified"}
|
||||
if symbol and path.is_file():
|
||||
lines = [i for i, line in enumerate(path.read_text().splitlines(), 1) if symbol in line]
|
||||
entry.update(symbol=symbol, current_matching_lines=lines, symbol_present=bool(lines))
|
||||
locators[key] = entry
|
||||
return locators[key]
|
||||
|
||||
for requirement in atomic["requirements"]:
|
||||
source_refs, test_refs = {}, set()
|
||||
for group_id in requirement["source_group_ids"]:
|
||||
group = groups[group_id]
|
||||
for ref in group.get("source_evidence", []):
|
||||
source_refs[(ref["path"], ref.get("symbol"))] = locate(ref["path"], ref.get("symbol"))
|
||||
test_refs.update(group.get("related_component_tests", []))
|
||||
item = {"requirement_id": requirement["id"], "source_group_ids": requirement["source_group_ids"],
|
||||
"primary_package": requirement["primary_package"], "planned_normal_entry": requirement["normal_entry"],
|
||||
"normal_entry_verified": False, "static_source_leads": list(source_refs.values()),
|
||||
"component_test_leads": [locate(t) for t in sorted(test_refs)],
|
||||
"save_contract_leads": [locate("scripts/core/save_service.gd"), locate("scripts/core/simulation_snapshot.gd"), locate("autoload/simulation_runtime.gd")],
|
||||
"boundary_evidence": "group tests require condition-specific review",
|
||||
"implementation_state": "not_reaudited_at_all_required_views", "acceptance_state": "unverified",
|
||||
"reviewer": "root static provenance audit"}
|
||||
if requirement["id"].startswith("AR.facility."):
|
||||
facility_id = requirement["id"].split(".")[2]
|
||||
path = definitions.get(facility_id)
|
||||
if path:
|
||||
name = str(path.relative_to(ROOT))
|
||||
item["definition"] = dict(locate(name), catalog_literal_present=("res://" + name) in catalog,
|
||||
source_value_approval="requires condition-specific review")
|
||||
field = requirement["id"].split(".")[3]
|
||||
aliases = {"footprint": "footprint", "layer": "layer", "staff_min": "staff_min", "staff_max": "staff_max",
|
||||
"customer_capacity": "customer_capacity", "service_attribute": "service_attribute", "service_price": "base_price",
|
||||
"upkeep_gold": "maintenance_gold", "upkeep_mana": "maintenance_mana"}
|
||||
if field in aliases:
|
||||
prefix = aliases[field] + " = "
|
||||
values = [(i, line[len(prefix):]) for i, line in enumerate(path.read_text().splitlines(), 1) if line.startswith(prefix)]
|
||||
item["implementation_field"] = {"field": aliases[field], "explicit_lines": values,
|
||||
"state": "explicit_implementation_not_yet_source_approved" if values else "inherited_default_not_explicit_approval"}
|
||||
else:
|
||||
item["definition"] = {"state": "missing_definition", "canonical_audit_id": facility_id}
|
||||
if requirement["id"].startswith("AR.heroine."):
|
||||
person_id = "heroine_" + requirement["id"].split(".")[2]
|
||||
item["character_catalog"] = dict(locate("data/characters/mvp_unique_characters.json"),
|
||||
canonical_audit_id=person_id, entry_present=person_id in characters,
|
||||
effect_or_route_verified=False)
|
||||
if requirement["id"].startswith(("AR.asset.", "AR.art.")):
|
||||
item["finished_asset_acceptance"] = {"state": "missing_acceptance", "audit": "assets_platform_audit.json",
|
||||
"fallback_counts_as_complete": False}
|
||||
rows.append(item)
|
||||
report = {"scope": "current static bindings and missing definitions; no group-to-atom PASS promotion",
|
||||
"audited_at_jst": datetime.now(ZoneInfo("Asia/Tokyo")).isoformat(), "atomic_register_sha256": sha(PLAN / "atomic_requirements.json"),
|
||||
"known_condition_denominator": len(atomic["denominator_ids"]), "rows": rows,
|
||||
"unique_source_locators": len(locators), "whole_atom_acceptance_claimed": False,
|
||||
"complete_runtime_ui_save_review": False}
|
||||
(PLAN / "current_evidence_links.json").write_text(json.dumps(report, ensure_ascii=False, indent=2) + "\n")
|
||||
print(json.dumps({k:v for k,v in report.items() if k != "rows"}, ensure_ascii=False))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user