Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions .github/workflows/engineering-platform-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v5
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
with: {python-version: '3.12'}
with: {python-version: '3.14'}
- name: Validate committed offline projection
run: python3 docs/ai-development/validate_projection.py --profile engineering-platform --source-commit 6ec3b443c3ab3bdf76c626c2046d3778db570eb0 --extension-identity ENGINEERING_PLATFORM_DEVELOPMENT_EXTENSION
validation-profile:
Expand All @@ -56,6 +56,8 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v5
with: {fetch-depth: 0}
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
with: {python-version: '3.14'}
- id: profile
run: PYTHONPATH=src python3 -m engineering_platform.validation_profile --base "${{ github.event.pull_request.base.sha || github.event.before }}" --branch "${{ github.head_ref || github.ref_name }}" --github-output "$GITHUB_OUTPUT"
validate:
Expand All @@ -67,7 +69,7 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v5
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
with: {python-version: '3.12'}
with: {python-version: '3.14'}
- name: Build and install committed canonical Engineering Platform wheel
run: |
python3 -m pip install build coverage
Expand Down Expand Up @@ -169,7 +171,7 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v5
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
with: {python-version: '3.12'}
with: {python-version: '3.14'}
- name: Install Engineering Platform runtime
run: python3 -m pip install .
- name: Install browser validation dependencies
Expand Down Expand Up @@ -216,7 +218,7 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v5
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
with: {python-version: '3.12'}
with: {python-version: '3.14'}
- name: Verify standalone qualification evidence
run: |
python -m pip install build .
Expand Down
16 changes: 16 additions & 0 deletions docs/development/CONSOLIDATION_PARKING_2026_09_10.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,22 @@ of QR-LOCAL-VALIDATION-PASS-001 and SEC-001 is not inferred from code/tests.
Host sequencing, phase prompts and early-result rejection are not universal
capability-level prevention of every HTTP/credential remote-write route.

## Minimal strict-validation extraction for first-canary readiness

`STRICT_CURRENT_CONTROL_VALIDATION_SLICE = SOURCE_DELIVERED / QUALIFIED` for
the separately delivered minimal source increment. The normal Managed
first-publication gate now requires the current validated audit plus an exact
candidate-bound, repair-ordinal-bound persisted profile digest and explicit
terminal PASS receipts for every profile-owned required control. Missing,
stale, skipped, not-applicable, unavailable, prose-only, nonzero or malformed
receipts remain ineligible; Quality/Security PASS cannot compensate.

This extraction does not resume or qualify the parked publication programme:
`EP #175 = OPEN_DRAFT_PARKED_NOT_QUALIFIED`, unchanged at its retained head.
Its remaining candidate-adoption and duplicate-safe publication-recovery scope
is `PARKED_NON_BLOCKER_FOR_FIRST_CANARY`. No primary runtime/CENTRAL,
configuration, governance, installer, submission or canary state was changed.

## Parked decisions and documentary DAG

| Node | Disposition and retained future acceptance |
Expand Down
19 changes: 18 additions & 1 deletion docs/development/ENGINEERING_PLATFORM_ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ moved the canonical source projections forward to 2.3.2 without rewriting that
published identity. The observed Mac has one 2.3.1 server process/data root and
a distinct 2.3.0 PlatformIO PATH candidate. This is explicit-path investigation
evidence, not proof of Mac-wide uniqueness and not authorization to remove or
cut over either installation. CENTRAL schema 56, engineering-storage schema 41
cut over either installation. CENTRAL schema 56, engineering-storage schema 42
and repository-attachment schema 1.0 remain separate contracts.

| Increment | Owning repository | Bounded result | Dependencies / acceptance |
Expand Down Expand Up @@ -65,6 +65,23 @@ receipts remain product-specific. A production publication or an actual Mac
installation/update remains outside this source order until separately
authorized.

## First-canary strict current-control validation slice

`STRICT_CURRENT_CONTROL_VALIDATION_SLICE = SOURCE_DELIVERED / QUALIFIED`.
Normal Managed first-publication eligibility now consumes one append-only,
candidate-bound validation-profile identity for the current run-wide repair
ordinal. The identity covers the selected tier, profile version/reference and
selection source, exact required-control set and launcher bindings. Every
required control must have one current terminal receipt with `EXECUTED`,
`PASS`, exit code zero and valid start/end timestamps; provider summaries and
Quality/Security passes cannot replace that evidence.

This is only the minimal first-canary product-capability closure. It creates no
submission, configuration, grant, installation, release or canary run. PR #175
remains `OPEN_DRAFT_PARKED_NOT_QUALIFIED`; its candidate-adoption,
publication-recovery and remaining scope are
`PARKED_NON_BLOCKER_FOR_FIRST_CANARY` and were not changed or qualified here.

## Subagent orchestration and efficiency — retained audit and planned lane

`EP_SUBAGENT_ORCHESTRATION_AND_EFFICIENCY_V1` records the
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "engineering-platform-browser-validation",
"private": true,
"version": "2.3.2",
"version": "2.3.4",
"scripts": {
"test:engineering-dashboard": "PYTHONPATH=src python3 -m engineering_platform.dashboard_browser_validation",
"test:engineering-dashboard-logic": "node --test tests/engineering/dashboard_status_store.test.mjs tests/engineering/ui_localization_contract.test.mjs",
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "engineering-platform"
version = "2.3.2"
version = "2.3.4"
description = "Local-first Engineering Platform execution operations runtime"
readme = "README.md"
requires-python = ">=3.11"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"platform": {
"id": "engineering-platform",
"name": "Engineering Platform",
"version": "2.3.2",
"version": "2.3.4",
"generation": 2,
"documentation_namespace": "engineering-platform",
"capability_registry_version": 1
Expand Down
10 changes: 5 additions & 5 deletions src/engineering_platform/ENGINEERING_PLATFORM_VERSION.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"bootstrap_contract": "2026.12",
"checkpoint_format": 1,
"dashboard_version": "2.3.2",
"dashboard_version": "2.3.4",
"handoff_protocol": 1,
"memory_format": 2,
"minimum_codex_cli": "0.146.0",
"inbox_protocol": 1,
"platform_version": "2.3.2",
"platform_version": "2.3.4",
"report_format": 2,
"runner_version": "2.3.2",
"runner_version": "2.3.4",
"status_model": 1,
"storage_schema": 41,
"watcher_version": "2.3.2"
"storage_schema": 42,
"watcher_version": "2.3.4"
}
11 changes: 10 additions & 1 deletion src/engineering_platform/agent_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,12 +379,21 @@ def from_dict(cls, raw: object) -> "TransactionState":
raise StateError("checkpoint quality evidence is invalid or unsafe")
profile_fields = {"version", "digest", "candidate_sha"}
current_profile_fields = profile_fields | {"criteria_digest"}
validation_bound_profile_fields = current_profile_fields | {"validation_profile_digest"}
if state.assurance_profile is not None and (
not isinstance(state.assurance_profile, dict)
or set(state.assurance_profile) not in (profile_fields, current_profile_fields)
or set(state.assurance_profile) not in (
profile_fields, current_profile_fields, validation_bound_profile_fields,
)
or not all(isinstance(value, str) and value for value in state.assurance_profile.values())
or not re.fullmatch(r"sha256:[0-9a-f]{64}", state.assurance_profile["digest"])
or not re.fullmatch(r"[0-9a-f]{40}", state.assurance_profile["candidate_sha"])
or (
"validation_profile_digest" in state.assurance_profile
and not re.fullmatch(
r"sha256:[0-9a-f]{64}", state.assurance_profile["validation_profile_digest"],
)
)
):
raise StateError("checkpoint assurance profile is invalid")
review_fields = {"reviewer", "status", "candidate_sha", "profile_digest", "invocation_id", "findings"}
Expand Down
87 changes: 37 additions & 50 deletions src/engineering_platform/contracts/projection.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
EvidenceReference,
require_compatible_version,
)
from ..storage import EngineeringStorageError, database_path
from ..storage import EngineeringStorageError, database_path, load_validation_context
from ..validation_profile import strict_required_controls_pass


UNAVAILABLE = "UNAVAILABLE"
Expand Down Expand Up @@ -137,65 +138,51 @@ def _qualification_evidence(connection: sqlite3.Connection, run_id: str) -> tupl
"SELECT submission_id,fresh_submission,retry_parent_run_id,resume_parent_run_id,recorded_at "
"FROM execution_run_qualification_context WHERE run_id=?", (run_id,)
).fetchone()
profile = connection.execute(
"SELECT selected_validation_tier,validation_profile_version,required_validation_controls,recorded_at "
"FROM execution_validation_profiles WHERE run_id=?", (run_id,)
).fetchone()
controls = connection.execute(
"SELECT validation_id,category,required_for_profile,execution_status,result,observed_at,currentness "
"FROM execution_validation_control_results WHERE run_id=? ORDER BY id", (run_id,)
).fetchall()
commands = connection.execute(
"SELECT inv.validation_id,inv.category,inv.required_for_profile,'EXECUTED',"
"COALESCE(term.result,'UNAVAILABLE'),COALESCE(term.completed_at,inv.started_at),inv.currentness "
"FROM execution_validation_command_invocations inv LEFT JOIN execution_validation_command_terminals term "
"ON term.run_id=inv.run_id AND term.command_id=inv.command_id WHERE inv.run_id=? ORDER BY inv.started_at",
(run_id,),
).fetchall()
database = Path(str(connection.execute("PRAGMA database_list").fetchone()[2]))
validation = load_validation_context(Path("."), run_id, central_database=database)
except sqlite3.OperationalError:
return None, None
except EngineeringStorageError:
validation = None
lineage_projection = None if lineage is None else {
"submission_id": lineage[0], "fresh_submission": bool(lineage[1]),
"retry_parent": lineage[2], "resume_parent": lineage[3], "recorded_at": lineage[4],
}
if profile is None:
if validation is None:
return lineage_projection, None
try:
payload = json.loads(profile[2])
required = payload.get("validation_ids", [])
except (AttributeError, TypeError, json.JSONDecodeError):
return lineage_projection, None
if not isinstance(required, list) or not all(isinstance(item, str) for item in required):
return lineage_projection, None
current: dict[str, sqlite3.Row] = {}
conflicts: set[str] = set()
for row in (*controls, *commands):
validation_id = str(row[0])
existing = current.get(validation_id)
if existing is None or int(row[6]) > int(existing[6]):
current[validation_id] = row
elif int(row[6]) == int(existing[6]) and row[4] != existing[4]:
conflicts.add(validation_id)
def result_for(validation_id: str) -> object:
if validation_id in conflicts:
return "UNRESOLVED"
row = current.get(validation_id)
return row[4] if row is not None else None
results = [result_for(validation_id) for validation_id in required]
required_state = "FAIL" if any(result == "FAIL" for result in results) else (
"PASS" if results and all(result == "PASS" for result in results) else "UNRESOLVED"
required = validation["required_validation_controls"]
controls = validation["controls"]
candidate = validation.get("candidate_sha")
currentness = validation.get("currentness")
strict_pass = (
isinstance(candidate, str) and isinstance(currentness, int)
and strict_required_controls_pass(
validation, candidate_sha=candidate, currentness=currentness,
)
)
results = [controls.get(item, {}).get("result") for item in required]
required_state = (
"PASS" if strict_pass else "FAIL" if any(result == "FAIL" for result in results)
else "UNRESOLVED"
)
return lineage_projection, {
"selected_validation_tier": profile[0], "validation_profile_version": profile[1],
"profile_reference": payload.get("profile_reference", UNAVAILABLE),
"profile_selection_source": payload.get("profile_selection_source", UNAVAILABLE),
"required_validation_controls": required, "required_validation_state": required_state,
"control_bindings": payload.get("control_bindings", UNAVAILABLE),
"recorded_at": profile[3],
"selected_validation_tier": validation["selected_validation_tier"],
"validation_profile_version": validation["validation_profile_version"],
"profile_reference": validation["profile_reference"],
"profile_selection_source": validation["profile_selection_source"],
"profile_digest": validation.get("profile_digest") or UNAVAILABLE,
"candidate_sha": candidate or UNAVAILABLE,
"currentness": currentness if isinstance(currentness, int) else UNAVAILABLE,
"required_validation_controls": list(required), "required_validation_state": required_state,
"control_bindings": list(validation["control_bindings"]),
"recorded_at": validation["recorded_at"],
"controls": [
{"validation_id": validation_id, "category": row[1], "required_for_profile": bool(row[2]),
"execution_status": row[3], "result": result_for(validation_id), "observed_at": row[5]}
for validation_id, row in sorted(current.items())
{"validation_id": validation_id, "category": row.get("category", UNAVAILABLE),
"required_for_profile": row.get("required_for_profile", False),
"execution_status": row.get("execution_status", "UNRESOLVED"),
"result": row.get("result", "UNRESOLVED"),
"observed_at": row.get("observed_at", UNAVAILABLE)}
for validation_id, row in sorted(controls.items())
],
}

Expand Down
Loading
Loading