engineering-platform 2.3.93__tar.gz → 2.3.94__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/PKG-INFO +1 -1
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/pyproject.toml +1 -1
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/ENGINEERING_PLATFORM_CONFIG.json +1 -1
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/ENGINEERING_PLATFORM_VERSION.json +4 -4
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/agent_state.py +33 -1
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/assets/dashboard.css +4 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/assets/dashboard.js +116 -36
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/assets/dashboard_locales.mjs +10 -5
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/capability_review.py +104 -3
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/dashboard_state.py +8 -7
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/execution_executor.py +64 -20
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/execution_host.py +82 -33
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/execution_reporting.py +18 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/live_status.py +11 -11
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/platform_version.py +1 -1
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/qualification_runtime.py +15 -2
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/templates/workspace-config.json +1 -1
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform.egg-info/PKG-INFO +1 -1
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/README.md +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/setup.cfg +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/__init__.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/__main__.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/agent_trust.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/assets/dashboard_status_store.mjs +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/assets/dashboard_translation.mjs +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/assets/operations-console/apple-touch-icon-dark.png +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/assets/operations-console/apple-touch-icon-light.png +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/assets/operations-console/icon-dark.png +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/assets/operations-console/icon-light.png +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/assets/operations-console/icon-transparent.png +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/assets/operations-console/manifest.webmanifest +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/assurance_scope.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/capability_preflight.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/central_data_transfer.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/central_database.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/central_operational_reset.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/central_store_migration.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/codex_capacity.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/codex_chat.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/codex_observability.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/component_lock.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/component_logging.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/console_presentation.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/console_route_ownership.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/contracts/__init__.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/contracts/ep_consumer.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/contracts/models.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/contracts/projection.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/dashboard_browser_validation.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/dashboard_supervisor.swift +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/dashboard_translation.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/dependabot_producer.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/development_profile.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/drift_diagnostics.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/emergency_recovery.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/engineering_memory.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/ep_consumer_credentials.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/evidence_projection.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/execution_activity.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/execution_context.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/execution_errors.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/execution_evidence.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/execution_finalization.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/execution_host_evidence.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/execution_lease.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/execution_lifecycle.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/execution_models.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/execution_readiness.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/execution_repository.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/execution_timeout_policy.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/execution_timing.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/execution_transaction.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/external_producer_binding.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/file_inbox.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/forensic_attribution.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/forensic_attribution_v2.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/forensic_delta.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/golden_scenario.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/historical_dashboard_configuration.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/host_admin.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/host_preflight.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/installation_relocation.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/installation_update_activation.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/installation_update_admission.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/installation_update_backup.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/installation_update_composition.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/installation_update_executor.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/installation_update_migration.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/installation_update_operation.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/installation_update_plan.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/installation_update_preparation.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/investigation_ledger.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/legacy_inbox_migration.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/legacy_installation_adoption.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/lifecycle_worker.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/local_api.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/local_api_keychain.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/local_repository_binding.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/managed_autonomy.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/managed_codex_runtime.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/managed_workspace_readiness.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/merge_delegation.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/operational_installation.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/operational_installation_lock.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/operational_installation_record.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/owner_credential_recovery.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/parity_context.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/parity_lifecycle_dispatcher.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/platform_admin.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/platform_api.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/platform_bootstrap.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/platform_components.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/pr_check_repair.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/pr_evidence_backfill.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/producer.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/product_installation_readback.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/project_agent.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/project_agent_service.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/project_topology.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/prompt_history.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/provider_context.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/provider_context_benchmark.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/provider_context_scope.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/provider_interruption.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/provider_process_identity.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/provider_readiness.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/provider_recovery.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/provider_usage.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/providers.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/qualification.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/recommendation_handoff.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/reconciliation_adoption.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/release_operation.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/report_analysis.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/repository_attachment.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/repository_handoff.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/resources.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/reviewer_evidence.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/revision_binding.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/schemas/producer-readback-v1.2.schema.json +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/schemas/producer-readback-v1.3.schema.json +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/schemas/producer-readback-v1.schema.json +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/schemas/repository-attachment.schema.json +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/server.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/server_console_services.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/server_relay.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/server_service.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/status_model.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/status_reconciliation.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/storage.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/submission_cli.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/submission_intake.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/submission_service.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/system_installation_topology.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/system_server_service.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/telemetry.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/telemetry_contract.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/telemetry_export.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/telemetry_metrics.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/terminal_evidence_reconciliation.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/validation_identity.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/validation_profile.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/version_preparation_delivery.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/workspace_preflight.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/worktree_provenance.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/worktree_tooling.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform.egg-info/SOURCES.txt +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform.egg-info/dependency_links.txt +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform.egg-info/entry_points.txt +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform.egg-info/top_level.txt +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/tests/test_adaptive_action_sizing_design.py +0 -0
- {engineering_platform-2.3.93 → engineering_platform-2.3.94}/tests/test_role_task_model_policy_design.py +0 -0
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"bootstrap_contract": "2026.12",
|
|
3
3
|
"checkpoint_format": 1,
|
|
4
|
-
"dashboard_version": "2.3.
|
|
4
|
+
"dashboard_version": "2.3.94",
|
|
5
5
|
"handoff_protocol": 1,
|
|
6
6
|
"memory_format": 2,
|
|
7
7
|
"minimum_codex_cli": "0.146.0",
|
|
8
8
|
"inbox_protocol": 1,
|
|
9
|
-
"platform_version": "2.3.
|
|
9
|
+
"platform_version": "2.3.94",
|
|
10
10
|
"report_format": 2,
|
|
11
|
-
"runner_version": "2.3.
|
|
11
|
+
"runner_version": "2.3.94",
|
|
12
12
|
"status_model": 1,
|
|
13
13
|
"storage_schema": 45,
|
|
14
|
-
"watcher_version": "2.3.
|
|
14
|
+
"watcher_version": "2.3.94"
|
|
15
15
|
}
|
{engineering_platform-2.3.93 → engineering_platform-2.3.94}/src/engineering_platform/agent_state.py
RENAMED
|
@@ -458,13 +458,16 @@ class TransactionState:
|
|
|
458
458
|
raise StateError("checkpoint assurance profile is invalid")
|
|
459
459
|
review_fields = {"reviewer", "status", "candidate_sha", "profile_digest", "invocation_id", "findings"}
|
|
460
460
|
current_review_fields = review_fields | {"contract_version", "started_at", "completed_at"}
|
|
461
|
+
integral_review_fields = current_review_fields | {"coverage", "finding_dispositions"}
|
|
461
462
|
finding_fields = {"id", "fingerprint", "category", "criterion", "observation", "severity", "confidence", "blocking", "disposition"}
|
|
462
463
|
current_finding_fields = finding_fields | {"evidence_ref"}
|
|
464
|
+
coverage_fields = {"surface", "status", "evidence_ref"}
|
|
465
|
+
finding_disposition_fields = {"finding_id", "disposition", "evidence_ref"}
|
|
463
466
|
if (
|
|
464
467
|
not isinstance(state.assurance_reviews, tuple)
|
|
465
468
|
or len(state.assurance_reviews) > 16
|
|
466
469
|
or any(
|
|
467
|
-
not isinstance(review, dict) or set(review) not in (review_fields, current_review_fields)
|
|
470
|
+
not isinstance(review, dict) or set(review) not in (review_fields, current_review_fields, integral_review_fields)
|
|
468
471
|
or review.get("reviewer") not in {"quality", "security"}
|
|
469
472
|
or review.get("status") not in {"PASS", "FAIL", "UNRESOLVED"}
|
|
470
473
|
or not isinstance(review.get("candidate_sha"), str) or not re.fullmatch(r"[0-9a-f]{40}", review["candidate_sha"])
|
|
@@ -486,6 +489,35 @@ class TransactionState:
|
|
|
486
489
|
or not isinstance(review.get("started_at"), str)
|
|
487
490
|
or not isinstance(review.get("completed_at"), str)
|
|
488
491
|
))
|
|
492
|
+
or (set(review) == integral_review_fields and (
|
|
493
|
+
review.get("contract_version") != "2.0"
|
|
494
|
+
or not isinstance(review.get("started_at"), str)
|
|
495
|
+
or not isinstance(review.get("completed_at"), str)
|
|
496
|
+
or not isinstance(review.get("coverage"), list)
|
|
497
|
+
or not 1 <= len(review["coverage"]) <= 16
|
|
498
|
+
or any(
|
|
499
|
+
not isinstance(item, dict) or set(item) != coverage_fields
|
|
500
|
+
or item.get("status") not in {"REVIEWED", "NOT_APPLICABLE"}
|
|
501
|
+
or any(
|
|
502
|
+
not isinstance(value, str) or not value or len(value) > 240
|
|
503
|
+
or value != redact_diagnostic(value, limit=240)
|
|
504
|
+
for value in item.values()
|
|
505
|
+
)
|
|
506
|
+
for item in review["coverage"]
|
|
507
|
+
)
|
|
508
|
+
or not isinstance(review.get("finding_dispositions"), list)
|
|
509
|
+
or len(review["finding_dispositions"]) > 64
|
|
510
|
+
or any(
|
|
511
|
+
not isinstance(item, dict) or set(item) != finding_disposition_fields
|
|
512
|
+
or item.get("disposition") not in {"RESOLVED", "OPEN"}
|
|
513
|
+
or any(
|
|
514
|
+
not isinstance(value, str) or not value or len(value) > 240
|
|
515
|
+
or value != redact_diagnostic(value, limit=240)
|
|
516
|
+
for value in item.values()
|
|
517
|
+
)
|
|
518
|
+
for item in review["finding_dispositions"]
|
|
519
|
+
)
|
|
520
|
+
))
|
|
489
521
|
for review in state.assurance_reviews
|
|
490
522
|
)
|
|
491
523
|
):
|
|
@@ -280,6 +280,8 @@ html[data-theme="light"] :is(#rateLimitReset,#codexCliUpdate){background:#e8fff5
|
|
|
280
280
|
.prompt-detail-provider-review{display:grid;gap:18px;grid-column:1/-1;grid-template-columns:minmax(0,1fr) minmax(320px,.78fr)}@media (max-width:760px){.prompt-detail-provider-review{grid-template-columns:1fr}}
|
|
281
281
|
.prompt-detail-provider-review-stack{display:grid;gap:18px;grid-column:1/-1}.prompt-detail-provider-review>.prompt-detail-card{align-self:stretch;box-sizing:border-box}.prompt-detail-card--commit-timeline{display:flex;flex-direction:column;min-height:0}.prompt-detail-commit-timeline__list{align-content:start;display:grid;flex:1;gap:10px;list-style:none;margin:0;max-height:none;min-height:0;overflow:auto;padding:0 8px 0 0;scrollbar-gutter:stable}.prompt-detail-commit-timeline__item{border-top:1px solid color-mix(in srgb,var(--category-color) 38%,transparent);display:grid;gap:3px;padding-top:10px}.prompt-detail-commit-timeline__item:first-child{border-top:0;padding-top:0}.prompt-detail-commit-timeline__meta{color:var(--dashboard-modal-muted);font-size:12px;line-height:1.35}.prompt-detail-commit-timeline__item code{font-size:12px;overflow-wrap:normal;white-space:nowrap}.prompt-detail-commit-timeline__item>span{font-size:13px;line-height:1.4;overflow-wrap:anywhere}
|
|
282
282
|
.prompt-detail-card--evidence pre,.prompt-detail-card--reviewers pre,.prompt-detail-card--assurance-reviews pre{font-family:inherit}
|
|
283
|
+
.reviewer-agent__status--failed{background:#ff6b6b;box-shadow:0 0 8px #ff6b6b66;color:#351313;font:800 14px/1 system-ui;height:16px;width:16px}
|
|
284
|
+
.prompt-detail-reviewer{border-top:1px solid color-mix(in srgb,var(--category-color) 45%,transparent);display:grid;gap:7px;padding-top:14px}.prompt-detail-reviewer:first-of-type{border-top:0;padding-top:0}.prompt-detail-reviewer h4{color:var(--category-color);font-size:16px;margin:0 0 4px}.prompt-detail-reviewer>.field{margin:2px 0 0}.prompt-detail-reviewer__status{align-items:center;display:inline-flex;gap:8px}.prompt-detail-reviewer__status-icon{align-items:center;border-radius:50%;display:inline-flex;flex:0 0 18px;font:800 12px/1 system-ui;height:18px;justify-content:center}.prompt-detail-reviewer__status-icon--completed{background:#51d88a;box-shadow:0 0 8px #51d88a66;color:#11261d}.prompt-detail-reviewer__status-icon--failed{background:#ff6b6b;box-shadow:0 0 8px #ff6b6b66;color:#351313}.prompt-detail-reviewer__status-icon--neutral{background:#9a9aa3;color:#202027}
|
|
283
285
|
.prompt-detail-commit-timeline__phase{border-top:1px solid color-mix(in srgb,var(--category-color) 52%,transparent);list-style:none;padding:13px 0 0}.prompt-detail-commit-timeline__phase:first-child{border-top:0;padding-top:0}.prompt-detail-commit-timeline__phase h4{color:var(--category-color);font-size:12px;letter-spacing:.04em;margin:0 0 9px;text-transform:uppercase}.prompt-detail-commit-timeline__phase-entries{display:grid;gap:10px;list-style:none;margin:0;padding:0 0 2px}.prompt-detail-commit-timeline__phase-entries .prompt-detail-commit-timeline__item{border-top:0;padding-top:0}
|
|
284
286
|
.prompt-detail-commit-timeline__phase{--commit-kind-color:#8dc7ff;border-left:3px solid var(--commit-kind-color);padding-left:10px}.prompt-detail-commit-timeline__phase--implementation{--commit-kind-color:#65c5d9}.prompt-detail-commit-timeline__phase--validation{--commit-kind-color:#65d9a3}.prompt-detail-commit-timeline__phase--quality{--commit-kind-color:#c29aff}.prompt-detail-commit-timeline__phase--repair{--commit-kind-color:#f4c34f}.prompt-detail-commit-timeline__phase--finalization{--commit-kind-color:#ff99a7}.prompt-detail-commit-timeline__phase--implementation_merge,.prompt-detail-commit-timeline__phase--finalization_merge,.prompt-detail-commit-timeline__phase--reconciliation_merge{--commit-kind-color:#f3d36a}.prompt-detail-commit-timeline__phase--reconciliation{--commit-kind-color:#73d6b0}.prompt-detail-commit-timeline__phase h4{align-items:center;color:var(--commit-kind-color);display:flex;gap:7px}.prompt-detail-commit-timeline__kind{border:1px solid currentColor;border-radius:999px;font-size:10px;line-height:1;padding:4px 6px}.prompt-detail-commit-timeline__phase-name{color:var(--dashboard-modal-muted);font-size:11px;font-weight:500;letter-spacing:0;text-transform:none;white-space:nowrap}
|
|
285
287
|
|
|
@@ -1335,3 +1337,5 @@ html[data-theme="light"] :is(.dashboard-status-banner--provider-auth_required .p
|
|
|
1335
1337
|
}
|
|
1336
1338
|
.telemetry-note{color:var(--dashboard-muted,#b9b6c0);font-size:12px;line-height:1.45;margin:0 0 10px}.telemetry-run-detail{border-top:1px solid color-mix(in srgb,var(--category-color,#fb7185) 45%,transparent);display:grid;gap:16px;margin-top:16px;padding-top:16px}.telemetry-run-detail h4{color:var(--category-color,#fb7185);font-size:14px;margin:14px 0 8px}.telemetry-scope-switcher{display:flex;flex-wrap:wrap;gap:8px}.telemetry-scope-switcher button{background:var(--dashboard-expanded-content-surface,#24242d);border:1px solid color-mix(in srgb,var(--category-color,#fb7185) 72%,transparent);border-radius:7px;color:inherit;cursor:pointer;font:400 12px/1.2 system-ui;min-height:32px;padding:5px 9px}.telemetry-scope-switcher button:hover{background:color-mix(in srgb,var(--category-color,#fb7185) 14%,var(--dashboard-expanded-content-surface,#24242d));border-color:var(--category-color,#fb7185)}.telemetry-scope-switcher button[aria-selected="true"]{background:color-mix(in srgb,var(--category-color,#fb7185) 24%,var(--dashboard-expanded-content-surface,#24242d));border-color:var(--category-color,#fb7185);box-shadow:inset 3px 0 0 var(--category-color,#fb7185)}.telemetry-scope-switcher button:focus:not(:focus-visible){box-shadow:none!important;outline:0!important}.telemetry-scope-switcher button[aria-selected="true"]:focus:not(:focus-visible){box-shadow:inset 3px 0 0 var(--category-color,#fb7185)!important}.telemetry-timeline{display:grid;gap:5px;list-style:none;margin:0;padding:0}.telemetry-timeline li{border-left:2px solid color-mix(in srgb,var(--category-color,#fb7185) 60%,transparent);margin-left:calc(var(--timeline-depth,0) * 14px);padding:6px 8px;word-break:break-word}@media(max-width:620px){.telemetry-detail-modal__content .technical-grid{grid-template-columns:minmax(0,1fr)}.telemetry-scope-switcher{position:sticky;top:0;background:var(--dashboard-expanded-content-surface,#24242d);padding-block:6px;z-index:2}.telemetry-timeline li{margin-left:min(calc(var(--timeline-depth,0) * 9px),45px)}}
|
|
1337
1339
|
.telemetry-timeline-axis{color:var(--dashboard-muted,#b9b6c0);display:flex;font:11px ui-monospace,monospace;justify-content:space-between;margin:4px 8px}.telemetry-timeline__label{font-size:12px;line-height:1.35}.telemetry-timeline__track{background:color-mix(in srgb,var(--category-color,#fb7185) 10%,transparent);border:1px solid color-mix(in srgb,var(--category-color,#fb7185) 24%,transparent);border-radius:4px;height:14px;margin:5px 0;overflow:hidden;position:relative}.telemetry-timeline__bar{background:var(--category-color,#fb7185);border-radius:3px;display:block;height:100%;min-width:2px;position:absolute}.telemetry-timeline__bar:focus-visible{outline:3px solid var(--house-style);outline-offset:2px}.telemetry-timeline__bar--unpositioned{background:repeating-linear-gradient(135deg,var(--category-color,#fb7185) 0 4px,transparent 4px 8px);inset:0;width:100%}.telemetry-timeline__identity{color:var(--dashboard-muted,#b9b6c0);display:block;font-size:10px;overflow-wrap:anywhere}.telemetry-export{min-width:38px}@media(max-width:620px){.telemetry-timeline-axis{margin-inline:0}.telemetry-timeline__identity{font-size:9px}.telemetry-actions{flex-wrap:wrap}}
|
|
1340
|
+
/* Status markers inside lifecycle assurance evidence mirror the main status language. */
|
|
1341
|
+
.lifecycle-detail-modal__assurance-heading{align-items:center;display:inline-flex;gap:8px}.lifecycle-detail-modal__assurance-status{align-items:center;border-radius:50%;display:inline-flex;flex:0 0 18px;font:800 12px/1 system-ui;height:18px;justify-content:center;width:18px!important}.lifecycle-detail-modal__assurance-status--passed{background:#51d88a;box-shadow:0 0 8px #51d88a66;color:#11261d!important}.lifecycle-detail-modal__assurance-status--failed{background:#ff6b6b;box-shadow:0 0 8px #ff6b6b66;color:#351313!important}.lifecycle-detail-modal__assurance-status--neutral{background:#9a9aa3;color:#202027!important}
|
|
@@ -831,12 +831,12 @@ function reviewerPresentationState(status = {}) {
|
|
|
831
831
|
}
|
|
832
832
|
function activeReviewerAgents(items, executionStatus = {}) {
|
|
833
833
|
const reviewActive = String(executionStatus?.current_phase || "").toUpperCase() === "CAPABILITY_REVIEW";
|
|
834
|
-
// A later phase may retain
|
|
835
|
-
//
|
|
836
|
-
//
|
|
837
|
-
const
|
|
838
|
-
&& items.every((agent) => String(agent?.status || "").toLowerCase()
|
|
839
|
-
const agents = (reviewActive ||
|
|
834
|
+
// A later phase may retain a wholly terminal review as compact historical
|
|
835
|
+
// evidence. Running or incomplete projections stay phase-scoped so they can
|
|
836
|
+
// never look like live reviewer work.
|
|
837
|
+
const terminalReview = Array.isArray(items) && items.length > 0
|
|
838
|
+
&& items.every((agent) => ["completed", "failed"].includes(String(agent?.status || "").toLowerCase()));
|
|
839
|
+
const agents = (reviewActive || terminalReview) && Array.isArray(items) ? items : [];
|
|
840
840
|
let card = $("activeReviewerAgents");
|
|
841
841
|
if (!card) {
|
|
842
842
|
card = document.createElement("section");
|
|
@@ -871,19 +871,23 @@ function activeReviewerAgents(items, executionStatus = {}) {
|
|
|
871
871
|
indicator = document.createElement("span"), rawStatus = String(agent?.status || "").toLowerCase(),
|
|
872
872
|
status = rawStatus === "running" && presentation !== "active" ? presentation : rawStatus;
|
|
873
873
|
const isRunning = status === "running";
|
|
874
|
-
const isCompleted = ["completed", "uitgevoerd"].includes(status);
|
|
874
|
+
const isCompleted = ["completed", "uitgevoerd"].includes(status), isFailed = status === "failed";
|
|
875
875
|
row.className = "reviewer-agent";
|
|
876
876
|
header.className = "reviewer-agent__header";
|
|
877
877
|
name.className = "reviewer-agent__name";
|
|
878
878
|
meta.className = "reviewer-agent__meta";
|
|
879
879
|
name.textContent = reviewerLabel(agent.reviewer);
|
|
880
880
|
meta.textContent = `${reviewerCapabilityLabel(agent.capability || "ENGINEERING")} · ${reviewerStatusLabel(status || "selected")}`;
|
|
881
|
-
if (isRunning || isCompleted) {
|
|
882
|
-
|
|
881
|
+
if (isRunning || isCompleted || isFailed) {
|
|
882
|
+
const tone = isRunning ? "running" : isFailed ? "failed" : "completed";
|
|
883
|
+
indicator.className = `reviewer-agent__status reviewer-agent__status--${tone}`;
|
|
883
884
|
indicator.setAttribute("role", "status");
|
|
884
|
-
indicator.setAttribute("aria-label", isRunning
|
|
885
|
+
indicator.setAttribute("aria-label", isRunning
|
|
886
|
+
? t("ui.reviewer_status_running")
|
|
887
|
+
: isFailed ? reviewerStatusLabel("failed") : t("ui.reviewer_status_completed"));
|
|
885
888
|
indicator.setAttribute("title", indicator.getAttribute("aria-label"));
|
|
886
889
|
if (isCompleted) indicator.textContent = "✓";
|
|
890
|
+
if (isFailed) indicator.textContent = "×";
|
|
887
891
|
}
|
|
888
892
|
header.append(name, indicator);
|
|
889
893
|
row.append(header, meta);
|
|
@@ -2143,12 +2147,31 @@ function lifecycleAssuranceEvidence(step) {
|
|
|
2143
2147
|
for (const review of reviews) {
|
|
2144
2148
|
if (!review || typeof review !== "object") continue;
|
|
2145
2149
|
const findings = Array.isArray(review.findings) ? review.findings : [];
|
|
2146
|
-
const item = document.createElement("li")
|
|
2147
|
-
|
|
2148
|
-
|
|
2150
|
+
const item = document.createElement("li"), heading = document.createElement("strong"),
|
|
2151
|
+
statusIcon = document.createElement("span"), status = String(review.status || "UNRESOLVED"),
|
|
2152
|
+
normalizedStatus = status.toUpperCase();
|
|
2153
|
+
const role = String(review.reviewer || "");
|
|
2154
|
+
const passed = normalizedStatus === "PASS", failed = ["FAIL", "FAILED", "UNRESOLVED"].includes(normalizedStatus);
|
|
2155
|
+
heading.className = "lifecycle-detail-modal__assurance-heading";
|
|
2156
|
+
statusIcon.className = "lifecycle-detail-modal__assurance-status lifecycle-detail-modal__assurance-status--"
|
|
2157
|
+
+ (passed ? "passed" : failed ? "failed" : "neutral");
|
|
2158
|
+
statusIcon.setAttribute("aria-hidden", "true");
|
|
2159
|
+
statusIcon.textContent = passed ? "✓" : failed ? "×" : "•";
|
|
2160
|
+
heading.append(statusIcon, Object.assign(document.createElement("span"), {
|
|
2161
|
+
textContent: `${reviewerLabel(role, role)} · ${assuranceStatusLabel(status, status)}`,
|
|
2162
|
+
}));
|
|
2163
|
+
item.append(heading);
|
|
2149
2164
|
const summary = findings.map((finding) => String(finding?.observation || "").trim()).filter(Boolean).join("; ");
|
|
2150
2165
|
const summaryElement = Object.assign(document.createElement("span"), { textContent: summary || t("lifecycle.assurance_no_findings") });
|
|
2151
2166
|
item.append(summaryElement);
|
|
2167
|
+
const coverage = Array.isArray(review.coverage) ? review.coverage : [];
|
|
2168
|
+
const dispositions = Array.isArray(review.finding_dispositions) ? review.finding_dispositions : [];
|
|
2169
|
+
if (coverage.length || dispositions.length) item.append(Object.assign(document.createElement("span"), {
|
|
2170
|
+
className: "estimate-meta",
|
|
2171
|
+
textContent: t("lifecycle.assurance_integral_evidence", {
|
|
2172
|
+
coverage: coverage.length, dispositions: dispositions.length,
|
|
2173
|
+
}),
|
|
2174
|
+
}));
|
|
2152
2175
|
if (summary) dynamicRows.push({ source: summary, element: summaryElement });
|
|
2153
2176
|
list.append(item);
|
|
2154
2177
|
}
|
|
@@ -2200,20 +2223,46 @@ function lifecycleCapabilityEvidence(step) {
|
|
|
2200
2223
|
section.append(list);
|
|
2201
2224
|
return section;
|
|
2202
2225
|
}
|
|
2203
|
-
function
|
|
2204
|
-
const
|
|
2226
|
+
function lifecyclePullRequestField(label, pullRequest, repository) {
|
|
2227
|
+
const field = lifecycleDetailField(label, `#${pullRequest}`);
|
|
2228
|
+
const repositoryIdentity = String(repository || "").trim();
|
|
2229
|
+
if (!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(repositoryIdentity)) return field;
|
|
2230
|
+
const link = document.createElement("a");
|
|
2231
|
+
link.className = "prompt-detail-pr-link";
|
|
2232
|
+
link.href = `https://github.com/${repositoryIdentity.split("/").map(encodeURIComponent).join("/")}/pull/${pullRequest}`;
|
|
2233
|
+
link.target = "_blank";
|
|
2234
|
+
link.rel = "noopener noreferrer";
|
|
2235
|
+
link.textContent = `#${pullRequest} ↗`;
|
|
2236
|
+
link.setAttribute("aria-label", `${label} #${pullRequest}`);
|
|
2237
|
+
field.lastElementChild.replaceWith(link);
|
|
2238
|
+
return field;
|
|
2239
|
+
}
|
|
2240
|
+
function lifecycleDeliveryEvidence(step) {
|
|
2241
|
+
const evidence = step?.delivery_evidence || step?.implementation_evidence;
|
|
2205
2242
|
if (!evidence || typeof evidence !== "object") return null;
|
|
2243
|
+
const role = String(evidence.role || "implementation").toLowerCase();
|
|
2244
|
+
const titles = {
|
|
2245
|
+
implementation: "lifecycle.detail_implementation_evidence",
|
|
2246
|
+
finalization: "lifecycle.detail_finalization_evidence",
|
|
2247
|
+
reconciliation: "lifecycle.detail_reconciliation_evidence",
|
|
2248
|
+
};
|
|
2249
|
+
const pullRequestLabels = {
|
|
2250
|
+
implementation: "detail.implementation_pull_request",
|
|
2251
|
+
finalization: "detail.finalization_pull_request",
|
|
2252
|
+
reconciliation: "detail.reconciliation_pull_request",
|
|
2253
|
+
};
|
|
2206
2254
|
const fields = [];
|
|
2207
2255
|
if (evidence.branch) fields.push(lifecycleDetailField(t("workspace.current_branch"), String(evidence.branch)));
|
|
2208
2256
|
if (evidence.candidate_sha) fields.push(lifecycleDetailField(t("detail.candidate_sha"), String(evidence.candidate_sha)));
|
|
2209
2257
|
if (Number.isInteger(evidence.pull_request) && evidence.pull_request > 0) {
|
|
2210
|
-
|
|
2258
|
+
const label = t(pullRequestLabels[role] || pullRequestLabels.implementation);
|
|
2259
|
+
fields.push(lifecyclePullRequestField(label, evidence.pull_request, evidence.repository));
|
|
2211
2260
|
}
|
|
2212
2261
|
if (!fields.length) return null;
|
|
2213
2262
|
const section = document.createElement("section");
|
|
2214
2263
|
section.className = "lifecycle-detail-modal__implementation-evidence";
|
|
2215
2264
|
section.append(
|
|
2216
|
-
Object.assign(document.createElement("h3"), { textContent: t(
|
|
2265
|
+
Object.assign(document.createElement("h3"), { textContent: t(titles[role] || titles.implementation) }),
|
|
2217
2266
|
Object.assign(document.createElement("div"), { className: "technical-grid" }),
|
|
2218
2267
|
);
|
|
2219
2268
|
section.lastElementChild.append(...fields);
|
|
@@ -2346,8 +2395,8 @@ function openLifecycleDetail(step, trigger, { presentationOnly = false } = {}) {
|
|
|
2346
2395
|
if (capabilityEvidence) content.append(capabilityEvidence);
|
|
2347
2396
|
const assuranceEvidence = lifecycleAssuranceEvidence(step);
|
|
2348
2397
|
if (assuranceEvidence) content.append(assuranceEvidence);
|
|
2349
|
-
const
|
|
2350
|
-
if (
|
|
2398
|
+
const deliveryEvidence = lifecycleDeliveryEvidence(step);
|
|
2399
|
+
if (deliveryEvidence) content.append(deliveryEvidence);
|
|
2351
2400
|
const repairEvidence = lifecycleRepairEvidence(step);
|
|
2352
2401
|
if (repairEvidence) content.append(repairEvidence);
|
|
2353
2402
|
if (!modal.open) modal.showModal();
|
|
@@ -2364,15 +2413,24 @@ function lifecycleStepWithEvidence(step, context = {}) {
|
|
|
2364
2413
|
: Array.isArray(context.reviewers) ? context.reviewers : [];
|
|
2365
2414
|
if (reviewers.length) enriched.reviewer_evidence = reviewers;
|
|
2366
2415
|
}
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2416
|
+
const deliverySteps = {
|
|
2417
|
+
EXECUTE_AGENT: { role: "implementation", candidate: "implementation_candidate_sha", branch: "implementation_branch", pullRequest: "implementation_pr" },
|
|
2418
|
+
FINALIZE_AGENT: { role: "finalization", candidate: "finalization_candidate_sha", branch: "finalization_branch", pullRequest: "finalization_pr" },
|
|
2419
|
+
RECONCILE_AGENT: { role: "reconciliation", candidate: "reconciliation_candidate_sha", branch: "reconciliation_branch", pullRequest: "reconciliation_pr" },
|
|
2420
|
+
};
|
|
2421
|
+
const delivery = deliverySteps[id];
|
|
2422
|
+
if (delivery) {
|
|
2423
|
+
const candidate = String(context[delivery.candidate] || "").trim();
|
|
2424
|
+
const branch = String(context[delivery.branch] || "").trim();
|
|
2425
|
+
const pullRequest = Number(context[delivery.pullRequest]);
|
|
2426
|
+
const repository = String(context.github_repository || context.target_repository || "").trim();
|
|
2371
2427
|
const evidence = {};
|
|
2428
|
+
evidence.role = delivery.role;
|
|
2372
2429
|
if (/^[0-9a-f]{40}$/.test(candidate)) evidence.candidate_sha = candidate;
|
|
2373
2430
|
if (branch) evidence.branch = branch;
|
|
2374
2431
|
if (Number.isInteger(pullRequest) && pullRequest > 0) evidence.pull_request = pullRequest;
|
|
2375
|
-
if (
|
|
2432
|
+
if (/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(repository)) evidence.repository = repository;
|
|
2433
|
+
if (Object.keys(evidence).length > 1) enriched.delivery_evidence = evidence;
|
|
2376
2434
|
}
|
|
2377
2435
|
return enriched;
|
|
2378
2436
|
}
|
|
@@ -8543,19 +8601,41 @@ function promptDetailRecommendationHandoff(handoff) {
|
|
|
8543
8601
|
}
|
|
8544
8602
|
function promptDetailReviewersSection(reviewers, { wide = true } = {}) {
|
|
8545
8603
|
if (!reviewers.length) return null;
|
|
8546
|
-
const fields = reviewers.map((reviewer) =>
|
|
8547
|
-
|
|
8548
|
-
|
|
8549
|
-
|
|
8550
|
-
|
|
8551
|
-
|
|
8552
|
-
|
|
8553
|
-
|
|
8554
|
-
|
|
8604
|
+
const fields = reviewers.map((reviewer) => {
|
|
8605
|
+
const rawStatus = String(reviewer.status || "completed").toLowerCase();
|
|
8606
|
+
const failed = rawStatus === "failed", completed = ["completed", "uitgevoerd"].includes(rawStatus);
|
|
8607
|
+
const field = document.createElement("article"), heading = document.createElement("h4"),
|
|
8608
|
+
statusLabel = document.createElement("span"), statusRow = document.createElement("span"),
|
|
8609
|
+
indicator = document.createElement("span"), statusText = document.createElement("span");
|
|
8610
|
+
field.className = "field prompt-detail-reviewer";
|
|
8611
|
+
heading.textContent = reviewerLabel(reviewer.reviewer, t("detail.specialist_review"));
|
|
8612
|
+
statusLabel.className = "label";
|
|
8613
|
+
statusLabel.textContent = t("detail.prompt_status");
|
|
8614
|
+
statusRow.className = "prompt-detail-reviewer__status";
|
|
8615
|
+
indicator.className = "prompt-detail-reviewer__status-icon prompt-detail-reviewer__status-icon--"
|
|
8616
|
+
+ (failed ? "failed" : completed ? "completed" : "neutral");
|
|
8617
|
+
indicator.setAttribute("aria-hidden", "true");
|
|
8618
|
+
indicator.textContent = failed ? "×" : completed ? "✓" : "•";
|
|
8619
|
+
statusText.className = "prompt-detail-reviewer__status-text";
|
|
8620
|
+
statusText.textContent = reviewerCapabilityLabel(reviewer.capability || "ENGINEERING")
|
|
8621
|
+
+ " · " + reviewerStatusLabel(rawStatus);
|
|
8622
|
+
statusRow.append(indicator, statusText);
|
|
8623
|
+
field.append(
|
|
8624
|
+
heading,
|
|
8625
|
+
statusLabel,
|
|
8626
|
+
statusRow,
|
|
8627
|
+
detailField(
|
|
8628
|
+
t("detail.selected_because"),
|
|
8555
8629
|
String(reviewer.selected_because || t("detail.not_recorded")),
|
|
8556
|
-
|
|
8557
|
-
|
|
8558
|
-
|
|
8630
|
+
true,
|
|
8631
|
+
),
|
|
8632
|
+
detailField(
|
|
8633
|
+
t("detail.accepted_recommendations"),
|
|
8634
|
+
String(Number(reviewer.accepted_recommendations) || 0),
|
|
8635
|
+
),
|
|
8636
|
+
);
|
|
8637
|
+
return field;
|
|
8638
|
+
});
|
|
8559
8639
|
return promptDetailCard(t("detail.specialist_reviews"), fields, wide, "prompt-detail-card--reviewers");
|
|
8560
8640
|
}
|
|
8561
8641
|
function promptDetailAssuranceReviewsSection(reviews) {
|
|
@@ -4273,8 +4273,13 @@ Object.assign(DASHBOARD_MESSAGES.es, {
|
|
|
4273
4273
|
// A repair step can be entered before a pull request exists and shares its
|
|
4274
4274
|
// bounded budget across local validation, assurance, hosted checks and
|
|
4275
4275
|
// finalization. Keep the flow label generic; detail evidence names the cause.
|
|
4276
|
-
Object.assign(DASHBOARD_MESSAGES.en, {"lifecycle.step.repair_agent":"Repair round","lifecycle.detail_repair_evidence":"Completed repair rounds","lifecycle.detail_implementation_evidence":"Implementation result","lifecycle.detail_validation_pass":"Validation pass {iteration}","detail.initial_observation":"Initial observation","detail.rejected_recommendations":"Rejected recommendations"});
|
|
4277
|
-
Object.assign(DASHBOARD_MESSAGES.nl, {"lifecycle.step.repair_agent":"Herstelronde","lifecycle.detail_repair_evidence":"Uitgevoerde herstelrondes","lifecycle.detail_implementation_evidence":"Implementatieresultaat","lifecycle.detail_validation_pass":"Validatiepass {iteration}","detail.initial_observation":"Initiële bevinding","detail.rejected_recommendations":"Afgewezen aanbevelingen"});
|
|
4278
|
-
Object.assign(DASHBOARD_MESSAGES.de, {"lifecycle.step.repair_agent":"Reparaturrunde","lifecycle.detail_repair_evidence":"Abgeschlossene Reparaturrunden","lifecycle.detail_implementation_evidence":"Implementierungsergebnis","lifecycle.detail_validation_pass":"Validierungsdurchlauf {iteration}","detail.initial_observation":"Erste Beobachtung","detail.rejected_recommendations":"Abgelehnte Empfehlungen"});
|
|
4279
|
-
Object.assign(DASHBOARD_MESSAGES.fr, {"lifecycle.step.repair_agent":"Cycle de réparation","lifecycle.detail_repair_evidence":"Cycles de réparation terminés","lifecycle.detail_implementation_evidence":"Résultat de l’implémentation","lifecycle.detail_validation_pass":"Passe de validation {iteration}","detail.initial_observation":"Observation initiale","detail.rejected_recommendations":"Recommandations rejetées"});
|
|
4280
|
-
Object.assign(DASHBOARD_MESSAGES.es, {"lifecycle.step.repair_agent":"Ronda de reparación","lifecycle.detail_repair_evidence":"Rondas de reparación completadas","lifecycle.detail_implementation_evidence":"Resultado de la implementación","lifecycle.detail_validation_pass":"Pasada de validación {iteration}","detail.initial_observation":"Observación inicial","detail.rejected_recommendations":"Recomendaciones rechazadas"});
|
|
4276
|
+
Object.assign(DASHBOARD_MESSAGES.en, {"lifecycle.step.repair_agent":"Repair round","lifecycle.detail_repair_evidence":"Completed repair rounds","lifecycle.detail_implementation_evidence":"Implementation result","lifecycle.detail_finalization_evidence":"Finalization result","lifecycle.detail_reconciliation_evidence":"Reconciliation result","lifecycle.detail_validation_pass":"Validation pass {iteration}","detail.initial_observation":"Initial observation","detail.rejected_recommendations":"Rejected recommendations"});
|
|
4277
|
+
Object.assign(DASHBOARD_MESSAGES.nl, {"lifecycle.step.repair_agent":"Herstelronde","lifecycle.detail_repair_evidence":"Uitgevoerde herstelrondes","lifecycle.detail_implementation_evidence":"Implementatieresultaat","lifecycle.detail_finalization_evidence":"Finalisatieresultaat","lifecycle.detail_reconciliation_evidence":"Reconciliatieresultaat","lifecycle.detail_validation_pass":"Validatiepass {iteration}","detail.initial_observation":"Initiële bevinding","detail.rejected_recommendations":"Afgewezen aanbevelingen"});
|
|
4278
|
+
Object.assign(DASHBOARD_MESSAGES.de, {"lifecycle.step.repair_agent":"Reparaturrunde","lifecycle.detail_repair_evidence":"Abgeschlossene Reparaturrunden","lifecycle.detail_implementation_evidence":"Implementierungsergebnis","lifecycle.detail_finalization_evidence":"Finalisierungsergebnis","lifecycle.detail_reconciliation_evidence":"Abstimmungsergebnis","lifecycle.detail_validation_pass":"Validierungsdurchlauf {iteration}","detail.initial_observation":"Erste Beobachtung","detail.rejected_recommendations":"Abgelehnte Empfehlungen"});
|
|
4279
|
+
Object.assign(DASHBOARD_MESSAGES.fr, {"lifecycle.step.repair_agent":"Cycle de réparation","lifecycle.detail_repair_evidence":"Cycles de réparation terminés","lifecycle.detail_implementation_evidence":"Résultat de l’implémentation","lifecycle.detail_finalization_evidence":"Résultat de la finalisation","lifecycle.detail_reconciliation_evidence":"Résultat de la réconciliation","lifecycle.detail_validation_pass":"Passe de validation {iteration}","detail.initial_observation":"Observation initiale","detail.rejected_recommendations":"Recommandations rejetées"});
|
|
4280
|
+
Object.assign(DASHBOARD_MESSAGES.es, {"lifecycle.step.repair_agent":"Ronda de reparación","lifecycle.detail_repair_evidence":"Rondas de reparación completadas","lifecycle.detail_implementation_evidence":"Resultado de la implementación","lifecycle.detail_finalization_evidence":"Resultado de la finalización","lifecycle.detail_reconciliation_evidence":"Resultado de la conciliación","lifecycle.detail_validation_pass":"Pasada de validación {iteration}","detail.initial_observation":"Observación inicial","detail.rejected_recommendations":"Recomendaciones rechazadas"});
|
|
4281
|
+
Object.assign(DASHBOARD_MESSAGES.en, {"lifecycle.assurance_integral_evidence":"Impact surfaces reviewed: {coverage} · Prior findings reassessed: {dispositions}"});
|
|
4282
|
+
Object.assign(DASHBOARD_MESSAGES.nl, {"lifecycle.assurance_integral_evidence":"Impactvlakken beoordeeld: {coverage} · Eerdere bevindingen herbeoordeeld: {dispositions}"});
|
|
4283
|
+
Object.assign(DASHBOARD_MESSAGES.de, {"lifecycle.assurance_integral_evidence":"Geprüfte Auswirkungsbereiche: {coverage} · Frühere Befunde erneut bewertet: {dispositions}"});
|
|
4284
|
+
Object.assign(DASHBOARD_MESSAGES.fr, {"lifecycle.assurance_integral_evidence":"Surfaces d’impact examinées : {coverage} · Constats antérieurs réévalués : {dispositions}"});
|
|
4285
|
+
Object.assign(DASHBOARD_MESSAGES.es, {"lifecycle.assurance_integral_evidence":"Superficies de impacto revisadas: {coverage} · Hallazgos anteriores reevaluados: {dispositions}"});
|
|
@@ -44,10 +44,47 @@ REVIEWER_LABELS = {
|
|
|
44
44
|
"documentation": "Documentation Reviewer",
|
|
45
45
|
"finalization": "Finalization Reviewer",
|
|
46
46
|
}
|
|
47
|
-
|
|
47
|
+
ADVISORY_REVIEW_OUTPUT_CONTRACT_VERSION = "1.0"
|
|
48
|
+
MANDATORY_REVIEW_OUTPUT_CONTRACT_VERSION = "2.0"
|
|
48
49
|
MANDATORY_FINDING_FIELDS = frozenset({
|
|
49
50
|
"id", "observation", "category", "criterion", "severity", "confidence", "evidence_ref",
|
|
50
51
|
})
|
|
52
|
+
MANDATORY_COVERAGE_FIELDS = frozenset({"surface", "status", "evidence_ref"})
|
|
53
|
+
MANDATORY_DISPOSITION_FIELDS = frozenset({"finding_id", "disposition", "evidence_ref"})
|
|
54
|
+
MANDATORY_COVERAGE_SURFACES = {
|
|
55
|
+
"IMPLEMENTATION": {
|
|
56
|
+
"quality": (
|
|
57
|
+
"approved_criteria", "full_candidate_diff", "callers_and_consumers",
|
|
58
|
+
"service_lifecycle", "maintenance_recovery_cleanup", "persistence_concurrency",
|
|
59
|
+
"transport_schema_compatibility", "regression_validation",
|
|
60
|
+
),
|
|
61
|
+
"security": (
|
|
62
|
+
"approved_criteria", "full_candidate_diff", "trust_authentication",
|
|
63
|
+
"data_integrity_concurrency", "maintenance_recovery_cleanup",
|
|
64
|
+
"failure_redaction", "availability_resource_bounds", "security_validation",
|
|
65
|
+
),
|
|
66
|
+
},
|
|
67
|
+
"FINALIZATION": {
|
|
68
|
+
"quality": (
|
|
69
|
+
"delivery_role_scope", "full_candidate_diff", "record_consistency",
|
|
70
|
+
"lifecycle_state_claims", "regression_validation",
|
|
71
|
+
),
|
|
72
|
+
"security": (
|
|
73
|
+
"delivery_role_scope", "full_candidate_diff", "authority_scope",
|
|
74
|
+
"sensitive_data", "lifecycle_state_claims", "security_validation",
|
|
75
|
+
),
|
|
76
|
+
},
|
|
77
|
+
"RECONCILIATION": {
|
|
78
|
+
"quality": (
|
|
79
|
+
"delivery_role_scope", "full_candidate_diff", "record_consistency",
|
|
80
|
+
"lifecycle_state_claims", "regression_validation",
|
|
81
|
+
),
|
|
82
|
+
"security": (
|
|
83
|
+
"delivery_role_scope", "full_candidate_diff", "authority_scope",
|
|
84
|
+
"sensitive_data", "lifecycle_state_claims", "security_validation",
|
|
85
|
+
),
|
|
86
|
+
},
|
|
87
|
+
}
|
|
51
88
|
PRODUCT_MATCHERS = {
|
|
52
89
|
"apple_platform": (("apps/apple/", "engineering-platform-app", "swiftui", "watchos", "macos", "ios"), "Apple platform capability"),
|
|
53
90
|
"windows_platform": (("apps/windows/", "engineering-platform-windows", "maui", "windows packaging"), "Windows platform capability"),
|
|
@@ -77,13 +114,15 @@ class ReviewerResult:
|
|
|
77
114
|
# In-process deterministic/test adapters construct this typed result only
|
|
78
115
|
# after choosing the mandatory contract. Raw provider JSON is still
|
|
79
116
|
# required to carry this field by ``CodexCliClient.review``.
|
|
80
|
-
contract_version: str | None =
|
|
117
|
+
contract_version: str | None = ADVISORY_REVIEW_OUTPUT_CONTRACT_VERSION
|
|
81
118
|
failed: bool = False
|
|
82
119
|
usage: dict[str, object] = field(default_factory=dict)
|
|
83
120
|
runtime_metadata: dict[str, object] = field(default_factory=dict)
|
|
84
121
|
churn: dict[str, object] = field(default_factory=dict)
|
|
85
122
|
duration_seconds: float | None = None
|
|
86
123
|
usage_snapshots: tuple[dict[str, int], ...] = ()
|
|
124
|
+
coverage: tuple[dict[str, str], ...] = ()
|
|
125
|
+
finding_dispositions: tuple[dict[str, str], ...] = ()
|
|
87
126
|
|
|
88
127
|
|
|
89
128
|
class ReviewerClient(Protocol):
|
|
@@ -164,6 +203,8 @@ def run_reviews(
|
|
|
164
203
|
result.churn,
|
|
165
204
|
result.duration_seconds,
|
|
166
205
|
result.usage_snapshots,
|
|
206
|
+
tuple(dict(item) for item in result.coverage if isinstance(item, dict)),
|
|
207
|
+
tuple(dict(item) for item in result.finding_dispositions if isinstance(item, dict)),
|
|
167
208
|
)
|
|
168
209
|
except Exception: # Reviewer failure is advisory and cannot block the transaction.
|
|
169
210
|
result = ReviewerResult(selection.reviewer, "Reviewer failed; primary review continues.", failed=True)
|
|
@@ -192,7 +233,8 @@ def mandatory_findings(result: ReviewerResult) -> tuple[dict[str, str], ...] | N
|
|
|
192
233
|
"""Return validated mandatory output, never advice-shaped pseudo-evidence."""
|
|
193
234
|
if result.failed or result.contract_version != MANDATORY_REVIEW_OUTPUT_CONTRACT_VERSION:
|
|
194
235
|
return None
|
|
195
|
-
if
|
|
236
|
+
finding_limit = 12 if result.reviewer in {"quality", "security"} else 64
|
|
237
|
+
if not isinstance(result.findings, tuple) or len(result.findings) > finding_limit:
|
|
196
238
|
return None
|
|
197
239
|
normalized: list[dict[str, str]] = []
|
|
198
240
|
seen: set[str] = set()
|
|
@@ -210,6 +252,65 @@ def mandatory_findings(result: ReviewerResult) -> tuple[dict[str, str], ...] | N
|
|
|
210
252
|
return tuple(normalized)
|
|
211
253
|
|
|
212
254
|
|
|
255
|
+
def mandatory_coverage_surfaces(reviewer: str, delivery_role: str) -> tuple[str, ...]:
|
|
256
|
+
"""Return the host-owned complete impact checklist for one assurance role."""
|
|
257
|
+
return MANDATORY_COVERAGE_SURFACES.get(delivery_role, {}).get(reviewer, ())
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
def mandatory_assessment(
|
|
261
|
+
result: ReviewerResult,
|
|
262
|
+
*,
|
|
263
|
+
delivery_role: str,
|
|
264
|
+
prior_finding_ids: tuple[str, ...],
|
|
265
|
+
) -> tuple[tuple[dict[str, str], ...], tuple[dict[str, str], ...], tuple[dict[str, str], ...]] | None:
|
|
266
|
+
"""Validate complete impact coverage and explicit prior-finding closure.
|
|
267
|
+
|
|
268
|
+
A syntactically valid list of findings is insufficient for mandatory
|
|
269
|
+
assurance. Each reviewer must cover every host-owned impact surface and
|
|
270
|
+
explicitly reassess every still-open finding previously raised by that
|
|
271
|
+
same independent role.
|
|
272
|
+
"""
|
|
273
|
+
findings = mandatory_findings(result)
|
|
274
|
+
required_surfaces = mandatory_coverage_surfaces(result.reviewer, delivery_role)
|
|
275
|
+
if findings is None or not required_surfaces:
|
|
276
|
+
return None
|
|
277
|
+
coverage = result.coverage
|
|
278
|
+
dispositions = result.finding_dispositions
|
|
279
|
+
if (
|
|
280
|
+
not isinstance(coverage, tuple)
|
|
281
|
+
or len(coverage) != len(required_surfaces)
|
|
282
|
+
or any(not isinstance(item, dict) or set(item) != MANDATORY_COVERAGE_FIELDS for item in coverage)
|
|
283
|
+
or any(
|
|
284
|
+
item["surface"] not in required_surfaces
|
|
285
|
+
or item["status"] not in {"REVIEWED", "NOT_APPLICABLE"}
|
|
286
|
+
or not isinstance(item["evidence_ref"], str) or not item["evidence_ref"].strip()
|
|
287
|
+
or len(item["evidence_ref"]) > 240
|
|
288
|
+
for item in coverage
|
|
289
|
+
)
|
|
290
|
+
or {item["surface"] for item in coverage} != set(required_surfaces)
|
|
291
|
+
):
|
|
292
|
+
return None
|
|
293
|
+
if (
|
|
294
|
+
not isinstance(dispositions, tuple)
|
|
295
|
+
or len(dispositions) != len(prior_finding_ids)
|
|
296
|
+
or any(not isinstance(item, dict) or set(item) != MANDATORY_DISPOSITION_FIELDS for item in dispositions)
|
|
297
|
+
or any(
|
|
298
|
+
item["finding_id"] not in prior_finding_ids
|
|
299
|
+
or item["disposition"] not in {"RESOLVED", "OPEN"}
|
|
300
|
+
or not isinstance(item["evidence_ref"], str) or not item["evidence_ref"].strip()
|
|
301
|
+
or len(item["evidence_ref"]) > 240
|
|
302
|
+
for item in dispositions
|
|
303
|
+
)
|
|
304
|
+
or {item["finding_id"] for item in dispositions} != set(prior_finding_ids)
|
|
305
|
+
):
|
|
306
|
+
return None
|
|
307
|
+
return (
|
|
308
|
+
findings,
|
|
309
|
+
tuple({key: redact_diagnostic(value, limit=240) for key, value in item.items()} for item in coverage),
|
|
310
|
+
tuple({key: redact_diagnostic(value, limit=240) for key, value in item.items()} for item in dispositions),
|
|
311
|
+
)
|
|
312
|
+
|
|
313
|
+
|
|
213
314
|
def records_for_storage(selections: tuple[ReviewerSelection, ...], results: tuple[ReviewerResult, ...]) -> tuple[dict[str, object], ...]:
|
|
214
315
|
by_reviewer = {result.reviewer: result for result in results}
|
|
215
316
|
records: list[dict[str, object]] = []
|
|
@@ -29,14 +29,15 @@ RunJsonReader = Callable[[Path, str | None], bytes]
|
|
|
29
29
|
TERMINAL_PHASES = frozenset({"COMPLETE", "BLOCKED", "FAILED"})
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
def
|
|
33
|
-
"""Expose
|
|
32
|
+
def _terminal_reviewer_agents(value: object) -> list[dict[str, object]]:
|
|
33
|
+
"""Expose a wholly terminal review beyond its live phase."""
|
|
34
34
|
if not isinstance(value, list):
|
|
35
35
|
return []
|
|
36
36
|
reviewers = [item for item in value if isinstance(item, dict)]
|
|
37
37
|
if not reviewers or len(reviewers) != len(value):
|
|
38
38
|
return []
|
|
39
|
-
|
|
39
|
+
terminal = {"completed", "failed"}
|
|
40
|
+
return reviewers if all(item.get("status") in terminal for item in reviewers) else []
|
|
40
41
|
|
|
41
42
|
|
|
42
43
|
def _run_workspace_preflight(root: Path, run_id: object) -> dict[str, object]:
|
|
@@ -417,13 +418,13 @@ def status(root: Path) -> bytes:
|
|
|
417
418
|
"candidate_sha": live.get("candidate_sha"),
|
|
418
419
|
"repair_iteration": live.get("repair_iteration"),
|
|
419
420
|
"workspace_preflight": run_workspace_preflight,
|
|
420
|
-
# Only a wholly
|
|
421
|
-
#
|
|
422
|
-
#
|
|
421
|
+
# Only a wholly terminal specialist review survives its live
|
|
422
|
+
# phase as historical evidence for this active run. A running
|
|
423
|
+
# or malformed reviewer projection remains hidden.
|
|
423
424
|
"reviewer_agents": (
|
|
424
425
|
live.get("reviewer_agents", [])
|
|
425
426
|
if live.get("phase") == "CAPABILITY_REVIEW"
|
|
426
|
-
else
|
|
427
|
+
else _terminal_reviewer_agents(live.get("reviewer_agents"))
|
|
427
428
|
),
|
|
428
429
|
"runtime_metadata": live.get("runtime_metadata", {}),
|
|
429
430
|
"workspace_progress": live.get("workspace_progress"),
|