@hunter-harness/workflow-harness 0.2.26 → 0.2.28
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.
- package/harness/bundles/general/claude-code/.harness-build.json +1 -1
- package/harness/bundles/general/claude-code/harness-archive/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-archive/templates/render-summary.mjs +25 -6
- package/harness/bundles/general/claude-code/harness-archive/templates/summary-data-template.json +44 -0
- package/harness/bundles/general/claude-code/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-knowledge-ingest/scripts/harness_knowledge.py +493 -74
- package/harness/bundles/general/claude-code/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-plan/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-review/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-run/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-submit/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/harness-sync/SKILL.md +8 -4
- package/harness/bundles/general/claude-code/harness-sync/reference.md +28 -0
- package/harness/bundles/general/claude-code/harness-test/SKILL.md +1 -1
- package/harness/bundles/general/claude-code/scripts/harness_archive.py +2147 -189
- package/harness/bundles/general/claude-code/scripts/harness_change.py +8 -3
- package/harness/bundles/general/claude-code/scripts/harness_events.py +57 -9
- package/harness/bundles/general/claude-code/scripts/harness_gate.py +530 -8
- package/harness/bundles/general/claude-code/scripts/harness_integration.py +263 -6
- package/harness/bundles/general/claude-code/scripts/harness_phase.py +758 -1
- package/harness/bundles/general/claude-code/scripts/harness_plan_finalize.py +74 -0
- package/harness/bundles/general/claude-code/scripts/harness_retry.py +175 -0
- package/harness/bundles/general/claude-code/scripts/harness_test_guard.py +702 -22
- package/harness/bundles/general/codebuddy/.harness-build.json +1 -1
- package/harness/bundles/general/codebuddy/harness-archive/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-archive/templates/render-summary.mjs +25 -6
- package/harness/bundles/general/codebuddy/harness-archive/templates/summary-data-template.json +44 -0
- package/harness/bundles/general/codebuddy/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge.py +493 -74
- package/harness/bundles/general/codebuddy/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-plan/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-review/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-run/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-submit/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/harness-sync/SKILL.md +8 -4
- package/harness/bundles/general/codebuddy/harness-sync/reference.md +28 -0
- package/harness/bundles/general/codebuddy/harness-test/SKILL.md +1 -1
- package/harness/bundles/general/codebuddy/scripts/harness_archive.py +2147 -189
- package/harness/bundles/general/codebuddy/scripts/harness_change.py +8 -3
- package/harness/bundles/general/codebuddy/scripts/harness_events.py +57 -9
- package/harness/bundles/general/codebuddy/scripts/harness_gate.py +530 -8
- package/harness/bundles/general/codebuddy/scripts/harness_integration.py +263 -6
- package/harness/bundles/general/codebuddy/scripts/harness_phase.py +758 -1
- package/harness/bundles/general/codebuddy/scripts/harness_plan_finalize.py +74 -0
- package/harness/bundles/general/codebuddy/scripts/harness_retry.py +175 -0
- package/harness/bundles/general/codebuddy/scripts/harness_test_guard.py +702 -22
- package/harness/bundles/general/codex/.harness-build.json +1 -1
- package/harness/bundles/general/codex/harness-archive/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-archive/templates/render-summary.mjs +25 -6
- package/harness/bundles/general/codex/harness-archive/templates/summary-data-template.json +44 -0
- package/harness/bundles/general/codex/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-knowledge-ingest/scripts/harness_knowledge.py +493 -74
- package/harness/bundles/general/codex/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-plan/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-review/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-run/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-submit/SKILL.md +1 -1
- package/harness/bundles/general/codex/harness-sync/SKILL.md +8 -4
- package/harness/bundles/general/codex/harness-sync/reference.md +28 -0
- package/harness/bundles/general/codex/harness-test/SKILL.md +1 -1
- package/harness/bundles/general/codex/scripts/harness_archive.py +2147 -189
- package/harness/bundles/general/codex/scripts/harness_change.py +8 -3
- package/harness/bundles/general/codex/scripts/harness_events.py +57 -9
- package/harness/bundles/general/codex/scripts/harness_gate.py +530 -8
- package/harness/bundles/general/codex/scripts/harness_integration.py +263 -6
- package/harness/bundles/general/codex/scripts/harness_phase.py +758 -1
- package/harness/bundles/general/codex/scripts/harness_plan_finalize.py +74 -0
- package/harness/bundles/general/codex/scripts/harness_retry.py +175 -0
- package/harness/bundles/general/codex/scripts/harness_test_guard.py +702 -22
- package/harness/bundles/general/cursor/.harness-build.json +1 -1
- package/harness/bundles/general/cursor/harness-archive/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-archive/templates/render-summary.mjs +25 -6
- package/harness/bundles/general/cursor/harness-archive/templates/summary-data-template.json +44 -0
- package/harness/bundles/general/cursor/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-knowledge-ingest/scripts/harness_knowledge.py +493 -74
- package/harness/bundles/general/cursor/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-plan/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-review/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-run/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-submit/SKILL.md +1 -1
- package/harness/bundles/general/cursor/harness-sync/SKILL.md +8 -4
- package/harness/bundles/general/cursor/harness-sync/reference.md +28 -0
- package/harness/bundles/general/cursor/harness-test/SKILL.md +1 -1
- package/harness/bundles/general/cursor/scripts/harness_archive.py +2147 -189
- package/harness/bundles/general/cursor/scripts/harness_change.py +8 -3
- package/harness/bundles/general/cursor/scripts/harness_events.py +57 -9
- package/harness/bundles/general/cursor/scripts/harness_gate.py +530 -8
- package/harness/bundles/general/cursor/scripts/harness_integration.py +263 -6
- package/harness/bundles/general/cursor/scripts/harness_phase.py +758 -1
- package/harness/bundles/general/cursor/scripts/harness_plan_finalize.py +74 -0
- package/harness/bundles/general/cursor/scripts/harness_retry.py +175 -0
- package/harness/bundles/general/cursor/scripts/harness_test_guard.py +702 -22
- package/harness/bundles/java/claude-code/.harness-build.json +1 -1
- package/harness/bundles/java/claude-code/harness-apidoc/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-archive/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-archive/templates/render-summary.mjs +25 -6
- package/harness/bundles/java/claude-code/harness-archive/templates/summary-data-template.json +44 -0
- package/harness/bundles/java/claude-code/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-knowledge-ingest/scripts/harness_knowledge.py +493 -74
- package/harness/bundles/java/claude-code/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-package/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-plan/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-review/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-run/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-submit/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/harness-sync/SKILL.md +8 -4
- package/harness/bundles/java/claude-code/harness-sync/reference.md +28 -0
- package/harness/bundles/java/claude-code/harness-test/SKILL.md +1 -1
- package/harness/bundles/java/claude-code/scripts/harness_archive.py +2147 -189
- package/harness/bundles/java/claude-code/scripts/harness_change.py +8 -3
- package/harness/bundles/java/claude-code/scripts/harness_events.py +57 -9
- package/harness/bundles/java/claude-code/scripts/harness_gate.py +530 -8
- package/harness/bundles/java/claude-code/scripts/harness_integration.py +263 -6
- package/harness/bundles/java/claude-code/scripts/harness_phase.py +758 -1
- package/harness/bundles/java/claude-code/scripts/harness_plan_finalize.py +74 -0
- package/harness/bundles/java/claude-code/scripts/harness_retry.py +175 -0
- package/harness/bundles/java/claude-code/scripts/harness_test_guard.py +702 -22
- package/harness/bundles/java/codebuddy/.harness-build.json +1 -1
- package/harness/bundles/java/codebuddy/harness-apidoc/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-archive/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-archive/templates/render-summary.mjs +25 -6
- package/harness/bundles/java/codebuddy/harness-archive/templates/summary-data-template.json +44 -0
- package/harness/bundles/java/codebuddy/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge.py +493 -74
- package/harness/bundles/java/codebuddy/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-package/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-plan/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-review/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-run/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-submit/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/harness-sync/SKILL.md +8 -4
- package/harness/bundles/java/codebuddy/harness-sync/reference.md +28 -0
- package/harness/bundles/java/codebuddy/harness-test/SKILL.md +1 -1
- package/harness/bundles/java/codebuddy/scripts/harness_archive.py +2147 -189
- package/harness/bundles/java/codebuddy/scripts/harness_change.py +8 -3
- package/harness/bundles/java/codebuddy/scripts/harness_events.py +57 -9
- package/harness/bundles/java/codebuddy/scripts/harness_gate.py +530 -8
- package/harness/bundles/java/codebuddy/scripts/harness_integration.py +263 -6
- package/harness/bundles/java/codebuddy/scripts/harness_phase.py +758 -1
- package/harness/bundles/java/codebuddy/scripts/harness_plan_finalize.py +74 -0
- package/harness/bundles/java/codebuddy/scripts/harness_retry.py +175 -0
- package/harness/bundles/java/codebuddy/scripts/harness_test_guard.py +702 -22
- package/harness/bundles/java/codex/.harness-build.json +1 -1
- package/harness/bundles/java/codex/harness-apidoc/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-archive/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-archive/templates/render-summary.mjs +25 -6
- package/harness/bundles/java/codex/harness-archive/templates/summary-data-template.json +44 -0
- package/harness/bundles/java/codex/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-knowledge-ingest/scripts/harness_knowledge.py +493 -74
- package/harness/bundles/java/codex/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-package/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-plan/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-review/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-run/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-submit/SKILL.md +1 -1
- package/harness/bundles/java/codex/harness-sync/SKILL.md +8 -4
- package/harness/bundles/java/codex/harness-sync/reference.md +28 -0
- package/harness/bundles/java/codex/harness-test/SKILL.md +1 -1
- package/harness/bundles/java/codex/scripts/harness_archive.py +2147 -189
- package/harness/bundles/java/codex/scripts/harness_change.py +8 -3
- package/harness/bundles/java/codex/scripts/harness_events.py +57 -9
- package/harness/bundles/java/codex/scripts/harness_gate.py +530 -8
- package/harness/bundles/java/codex/scripts/harness_integration.py +263 -6
- package/harness/bundles/java/codex/scripts/harness_phase.py +758 -1
- package/harness/bundles/java/codex/scripts/harness_plan_finalize.py +74 -0
- package/harness/bundles/java/codex/scripts/harness_retry.py +175 -0
- package/harness/bundles/java/codex/scripts/harness_test_guard.py +702 -22
- package/harness/bundles/java/cursor/.harness-build.json +1 -1
- package/harness/bundles/java/cursor/harness-apidoc/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-archive/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-archive/templates/render-summary.mjs +25 -6
- package/harness/bundles/java/cursor/harness-archive/templates/summary-data-template.json +44 -0
- package/harness/bundles/java/cursor/harness-codebase-map/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-knowledge-ingest/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-knowledge-ingest/scripts/harness_knowledge.py +493 -74
- package/harness/bundles/java/cursor/harness-knowledge-query/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-package/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-plan/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-review/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-run/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-submit/SKILL.md +1 -1
- package/harness/bundles/java/cursor/harness-sync/SKILL.md +8 -4
- package/harness/bundles/java/cursor/harness-sync/reference.md +28 -0
- package/harness/bundles/java/cursor/harness-test/SKILL.md +1 -1
- package/harness/bundles/java/cursor/scripts/harness_archive.py +2147 -189
- package/harness/bundles/java/cursor/scripts/harness_change.py +8 -3
- package/harness/bundles/java/cursor/scripts/harness_events.py +57 -9
- package/harness/bundles/java/cursor/scripts/harness_gate.py +530 -8
- package/harness/bundles/java/cursor/scripts/harness_integration.py +263 -6
- package/harness/bundles/java/cursor/scripts/harness_phase.py +758 -1
- package/harness/bundles/java/cursor/scripts/harness_plan_finalize.py +74 -0
- package/harness/bundles/java/cursor/scripts/harness_retry.py +175 -0
- package/harness/bundles/java/cursor/scripts/harness_test_guard.py +702 -22
- package/harness/manifests/general/claude-code.json +28 -24
- package/harness/manifests/general/codebuddy.json +28 -24
- package/harness/manifests/general/codex.json +28 -24
- package/harness/manifests/general/cursor.json +28 -24
- package/harness/manifests/java/claude-code.json +30 -26
- package/harness/manifests/java/codebuddy.json +30 -26
- package/harness/manifests/java/codex.json +30 -26
- package/harness/manifests/java/cursor.json +30 -26
- package/hunter-workflow-family.json +2 -2
- package/package.json +1 -1
|
@@ -232,8 +232,13 @@ def read_concurrency_mode(project_root: Path) -> str:
|
|
|
232
232
|
``isolated-multi-active`` (allows multiple active Changes but all
|
|
233
233
|
Change-scoped commands require ``--change``).
|
|
234
234
|
"""
|
|
235
|
-
|
|
236
|
-
|
|
235
|
+
configs = [
|
|
236
|
+
project_root / ".harness" / "config" / "harness.json",
|
|
237
|
+
project_root / ".harness" / "config.json",
|
|
238
|
+
]
|
|
239
|
+
for cfg in configs:
|
|
240
|
+
if not cfg.is_file():
|
|
241
|
+
continue
|
|
237
242
|
try:
|
|
238
243
|
data = json.loads(cfg.read_text(encoding="utf-8"))
|
|
239
244
|
if isinstance(data, dict):
|
|
@@ -244,7 +249,7 @@ def read_concurrency_mode(project_root: Path) -> str:
|
|
|
244
249
|
}:
|
|
245
250
|
return mode
|
|
246
251
|
except (OSError, json.JSONDecodeError):
|
|
247
|
-
|
|
252
|
+
continue
|
|
248
253
|
return "single-active"
|
|
249
254
|
|
|
250
255
|
|
|
@@ -883,6 +883,15 @@ def split_phase_attempts(phase_events: list[dict[str, Any]]) -> list[dict[str, A
|
|
|
883
883
|
attempts: list[dict[str, Any]] = []
|
|
884
884
|
current: dict[str, Any] | None = None
|
|
885
885
|
next_attempt = 1
|
|
886
|
+
pre_start_metadata_types = {
|
|
887
|
+
"correction",
|
|
888
|
+
"decision",
|
|
889
|
+
"environment.wait",
|
|
890
|
+
"env.wait",
|
|
891
|
+
"external.wait",
|
|
892
|
+
"issue",
|
|
893
|
+
"ci.wait",
|
|
894
|
+
}
|
|
886
895
|
for event in phase_events:
|
|
887
896
|
if event.get("type") == "phase.start":
|
|
888
897
|
if current is not None:
|
|
@@ -900,6 +909,11 @@ def split_phase_attempts(phase_events: list[dict[str, Any]]) -> list[dict[str, A
|
|
|
900
909
|
if prior_type == "phase.end":
|
|
901
910
|
attempts[-1]["warnings"].append("event recorded after phase.end")
|
|
902
911
|
continue
|
|
912
|
+
if event.get("type") in pre_start_metadata_types:
|
|
913
|
+
# Decisions and diagnostics may be emitted while selecting or
|
|
914
|
+
# recovering a phase. They describe workflow context, not an
|
|
915
|
+
# execution attempt, so they must not manufacture an orphan.
|
|
916
|
+
continue
|
|
903
917
|
raw_attempt = event.get("attempt")
|
|
904
918
|
attempt = raw_attempt if isinstance(raw_attempt, int) and raw_attempt > 0 else next_attempt
|
|
905
919
|
next_attempt = max(next_attempt, attempt + 1)
|
|
@@ -974,26 +988,40 @@ def _seal_timestamp_for_attempt(
|
|
|
974
988
|
cutoff_ts: str | None,
|
|
975
989
|
next_attempt_start: Any = None,
|
|
976
990
|
) -> tuple[Any, str | None]:
|
|
977
|
-
"""Pick
|
|
991
|
+
"""Pick a typed terminal and seal time for an unclosed attempt."""
|
|
978
992
|
recovery_ts = None
|
|
993
|
+
explicit_terminal: tuple[Any, str] | None = None
|
|
979
994
|
for event in events_in:
|
|
980
|
-
|
|
995
|
+
event_type = str(event.get("type") or "").lower()
|
|
996
|
+
if event_type in {
|
|
981
997
|
"recovery",
|
|
982
998
|
"phase.recovery",
|
|
983
999
|
"attempt.recovery",
|
|
984
1000
|
}:
|
|
985
1001
|
recovery_ts = event.get("timestamp") or recovery_ts
|
|
1002
|
+
terminal = {
|
|
1003
|
+
"attempt.abandoned": "ABANDONED",
|
|
1004
|
+
"phase.abandoned": "ABANDONED",
|
|
1005
|
+
"attempt.interrupted": "INTERRUPTED",
|
|
1006
|
+
"phase.interrupted": "INTERRUPTED",
|
|
1007
|
+
"attempt.orphaned": "ORPHANED",
|
|
1008
|
+
"phase.orphaned": "ORPHANED",
|
|
1009
|
+
}.get(event_type)
|
|
1010
|
+
if terminal and event.get("timestamp"):
|
|
1011
|
+
explicit_terminal = (event.get("timestamp"), terminal)
|
|
1012
|
+
if explicit_terminal is not None:
|
|
1013
|
+
return explicit_terminal
|
|
986
1014
|
if next_attempt_start:
|
|
987
|
-
return next_attempt_start, "
|
|
1015
|
+
return next_attempt_start, "RECOVERED"
|
|
988
1016
|
if recovery_ts:
|
|
989
|
-
return recovery_ts, "
|
|
1017
|
+
return recovery_ts, "RECOVERED"
|
|
990
1018
|
if cutoff_ts:
|
|
991
|
-
return cutoff_ts, "
|
|
1019
|
+
return cutoff_ts, "INCOMPLETE_AT_CUTOFF"
|
|
992
1020
|
# Fall back to last event timestamp so wall clock is not silently dropped.
|
|
993
1021
|
for event in reversed(events_in):
|
|
994
1022
|
if event.get("timestamp"):
|
|
995
|
-
return event.get("timestamp"), "
|
|
996
|
-
return None, "
|
|
1023
|
+
return event.get("timestamp"), "INTERRUPTED"
|
|
1024
|
+
return None, "ORPHANED"
|
|
997
1025
|
|
|
998
1026
|
|
|
999
1027
|
def attempt_invocations(
|
|
@@ -1013,6 +1041,7 @@ def attempt_invocations(
|
|
|
1013
1041
|
start_ts = None
|
|
1014
1042
|
end_ts = None
|
|
1015
1043
|
status = None
|
|
1044
|
+
terminal_status = None
|
|
1016
1045
|
closed_by_end = False
|
|
1017
1046
|
for event in events_in:
|
|
1018
1047
|
if event.get("type") == "phase.start" and start_ts is None:
|
|
@@ -1021,7 +1050,9 @@ def attempt_invocations(
|
|
|
1021
1050
|
end_ts = event.get("timestamp")
|
|
1022
1051
|
if "status" in event:
|
|
1023
1052
|
status = event.get("status")
|
|
1053
|
+
terminal_status = str(event.get("status") or "").upper() or None
|
|
1024
1054
|
closed_by_end = True
|
|
1055
|
+
missing_start = start_ts is None
|
|
1025
1056
|
sealed_incomplete = False
|
|
1026
1057
|
if not closed_by_end:
|
|
1027
1058
|
next_start = None
|
|
@@ -1038,7 +1069,12 @@ def attempt_invocations(
|
|
|
1038
1069
|
if seal_ts is not None:
|
|
1039
1070
|
end_ts = seal_ts
|
|
1040
1071
|
status = seal_status
|
|
1072
|
+
terminal_status = seal_status
|
|
1041
1073
|
sealed_incomplete = True
|
|
1074
|
+
elif missing_start:
|
|
1075
|
+
terminal_status = "ORPHANED"
|
|
1076
|
+
status = "ORPHANED"
|
|
1077
|
+
sealed_incomplete = True
|
|
1042
1078
|
duration = None
|
|
1043
1079
|
if start_ts and end_ts:
|
|
1044
1080
|
duration = duration_ms_between(start_ts, end_ts)
|
|
@@ -1048,9 +1084,13 @@ def attempt_invocations(
|
|
|
1048
1084
|
{
|
|
1049
1085
|
"attempt": attempt.get("attempt"),
|
|
1050
1086
|
"status": status,
|
|
1087
|
+
"terminalStatus": terminal_status,
|
|
1088
|
+
"startedAt": start_ts,
|
|
1089
|
+
"endedAt": end_ts,
|
|
1051
1090
|
"durationMs": duration,
|
|
1052
1091
|
"activeEligible": active_eligible,
|
|
1053
1092
|
"sealedIncomplete": sealed_incomplete,
|
|
1093
|
+
"warnings": list(attempt.get("warnings") or []),
|
|
1054
1094
|
}
|
|
1055
1095
|
)
|
|
1056
1096
|
return invocations
|
|
@@ -1066,7 +1106,13 @@ def phase_final_state(phase_events: list[dict[str, Any]]) -> dict[str, Any]:
|
|
|
1066
1106
|
"attempt": latest.get("attempt"),
|
|
1067
1107
|
"status": latest.get("status"),
|
|
1068
1108
|
"durationMs": latest.get("durationMs"),
|
|
1069
|
-
"closed": latest.get("
|
|
1109
|
+
"closed": latest.get("terminalStatus") not in {
|
|
1110
|
+
None,
|
|
1111
|
+
"INCOMPLETE",
|
|
1112
|
+
"INCOMPLETE_AT_CUTOFF",
|
|
1113
|
+
"ORPHANED",
|
|
1114
|
+
"INTERRUPTED",
|
|
1115
|
+
},
|
|
1070
1116
|
}
|
|
1071
1117
|
|
|
1072
1118
|
|
|
@@ -1100,7 +1146,8 @@ def canonical_phase_timing(
|
|
|
1100
1146
|
unclosed = sum(
|
|
1101
1147
|
1
|
|
1102
1148
|
for invocation in invocations
|
|
1103
|
-
if invocation.get("
|
|
1149
|
+
if invocation.get("terminalStatus")
|
|
1150
|
+
in {"INCOMPLETE", "INCOMPLETE_AT_CUTOFF", "ORPHANED", "INTERRUPTED"}
|
|
1104
1151
|
)
|
|
1105
1152
|
return {
|
|
1106
1153
|
"activeExecutionMs": active,
|
|
@@ -1108,6 +1155,7 @@ def canonical_phase_timing(
|
|
|
1108
1155
|
"lateEventCount": late["lateEventCount"],
|
|
1109
1156
|
"lateEventSpanMs": late["lateEventSpanMs"],
|
|
1110
1157
|
"unclosedAttemptCount": unclosed,
|
|
1158
|
+
"attempts": invocations,
|
|
1111
1159
|
}
|
|
1112
1160
|
|
|
1113
1161
|
|