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
4 changes: 3 additions & 1 deletion curllm_core/autonomy.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,13 @@ def run_command(spec: dict, repository: Path) -> dict:
if ok and spec.get("oracle", "exit") == "json":
try:
result = json.loads(raw)
status = result.get("status") if isinstance(result, dict) else None
# A zero exit code does not prove the application's semantic result.
ok = (isinstance(result, dict) and result.get("success") is True
and not result.get("error") and not result.get("errors")
and not result.get("failed")
and result.get("status") not in {"failed", "error"})
and (status is None or (isinstance(status, str)
and status not in {"failed", "error"})))
except (ValueError, UnicodeError):
ok = False
code = "passed" if ok else "semantic_failed"
Expand Down
15 changes: 15 additions & 0 deletions project/ticket-007/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Malformed probe status

- **Owner**: agent:codex
- **Status**: IN_PROGRESS
- **Workflow state**: PUBLICATION
- **Workstream**: application

SESSION_EXECUTION_AUTHORIZATION: continuous improvement, tests, repairs and deployment authorized by user on 2026-10-06; STARTER-019 records reproduced malformed JSON failure after frozen PR12. Preserve that publication and fix in this bounded slice.

## Acceptance criteria

- [x] AC-01: Invalid JSON status types become semantic failure; monitor cycle continues.
- [x] AC-02: Native gate and autonomy regressions pass.

Validation: four new adverse-result regressions failed before repair; 30 autonomy tests passed after repair (8.81s). Native gate passed without errors/warnings.
84 changes: 84 additions & 0 deletions project/ticket-007/intent.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
{
"schema": "new-project.intent/v3",
"ticket": "ticket-007",
"summary": "Classify malformed probe status without interrupting autonomy",
"workstream": "application",
"classification": {
"kind": "BUG",
"priority": "P1",
"origin": "requested"
},
"allowedPaths": [
"project/ticket-007/**",
"TODO.md",
"project/TICKETS.md",
"curllm_core/autonomy.py",
"tests/test_autonomy.py"
],
"forbiddenPaths": [
"project/ticket-*/user-*.md"
],
"stacks": [],
"dependsOn": [
"ticket-006"
],
"conflictsWith": [],
"integrationTicket": null,
"delivery": {
"acceptedBaseSha": "473dcf782d67452a81da879830fde9927a4630b1",
"targetBranch": "main",
"outcome": "Publish malformed-result regression fix before continuous monitor deployment (STARTER-019).",
"nonGoals": [
"No self-authorized source changes or review bypass",
"No edits to reference repositories",
"No interaction with user browser pages"
],
"complexity": "XS",
"estimatedMinutes": 8,
"budgets": {
"maxImplementationFiles": 2,
"maxAffectedComponents": 1,
"maxPublicInterfaceChanges": 0,
"maxRuntimeDependencies": 0
},
"architecture": {
"status": "accepted",
"decision": "Validate JSON status type before semantic evaluation; malformed application results are failures, not monitor exceptions.",
"components": [
{
"name": "autonomy-runtime",
"paths": [
"curllm_core/autonomy.py",
"tests/test_autonomy.py"
]
}
],
"responsibilityChanges": false,
"interfaceChanges": [],
"dataChanges": [],
"ui": {
"impact": "none",
"states": [],
"evidence": []
},
"rollback": "Revert malformed-result guard."
},
"runtimeDependencies": [],
"validation": [
{
"criterion": "AC-01",
"commands": [
"python -m pytest tests/test_autonomy.py -q"
],
"evidence": "Malformed list, object, number and boolean status returns semantic_failed; monitor lifecycle remains functional."
},
{
"criterion": "AC-02",
"commands": [
"bash project/governance-check.sh --actor agent"
],
"evidence": "Native gate passes."
}
]
}
}
4 changes: 3 additions & 1 deletion tests/test_autonomy.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,9 @@ def test_concurrent_cycle_cannot_run_probe(tmp_path):


@pytest.mark.parametrize("output", ['{"success":false}', '{"success":true,"errors":["bad"]}',
'{"success":true,"failed":1}', '{"status":"ok"}', 'not json'])
'{"success":true,"failed":1}', '{"status":"ok"}', 'not json',
'{"success":true,"status":[]}', '{"success":true,"status":{}}',
'{"success":true,"status":0}', '{"success":true,"status":false}'])
def test_semantic_failure_with_zero_exit(output, tmp_path):
spec = {"argv": [sys.executable, "-c", f"print({output!r})"], "oracle": "json"}
result = run_command(spec, tmp_path)
Expand Down
Loading