forgexa-cli 1.77.0__tar.gz → 1.77.1__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.
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/PKG-INFO +1 -1
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/forgexa_cli/__init__.py +1 -1
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/forgexa_cli/agent_core.py +18 -1
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/forgexa_cli/daemon.py +12 -6
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/forgexa_cli.egg-info/PKG-INFO +1 -1
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/pyproject.toml +1 -1
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/README.md +0 -0
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/forgexa_cli/_build_config.py +0 -0
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/forgexa_cli/_local_bind.py +0 -0
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/forgexa_cli/autoupgrade.py +0 -0
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/forgexa_cli/aws_evidence.py +0 -0
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/forgexa_cli/aws_logs_evidence.py +0 -0
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/forgexa_cli/main.py +0 -0
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/forgexa_cli/py.typed +0 -0
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/forgexa_cli/runtime_evidence.py +0 -0
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/forgexa_cli/zcode_protocol.py +0 -0
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/forgexa_cli.egg-info/SOURCES.txt +0 -0
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/forgexa_cli.egg-info/dependency_links.txt +0 -0
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/forgexa_cli.egg-info/entry_points.txt +0 -0
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/forgexa_cli.egg-info/requires.txt +0 -0
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/forgexa_cli.egg-info/top_level.txt +0 -0
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/setup.cfg +0 -0
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/tests/test_auth_and_runtime_commands.py +0 -0
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/tests/test_autoupgrade.py +0 -0
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/tests/test_check_command.py +0 -0
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/tests/test_expiry_warnings_and_revoke.py +0 -0
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/tests/test_local_bind_commands.py +0 -0
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/tests/test_runtime_credentials.py +0 -0
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/tests/test_session_credentials.py +0 -0
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/tests/test_silent_install.py +0 -0
- {forgexa_cli-1.77.0 → forgexa_cli-1.77.1}/tests/test_upgrade_observability.py +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""forgexa-cli — Forgexa command-line client."""
|
|
2
|
-
__version__ = "1.77.
|
|
2
|
+
__version__ = "1.77.1"
|
|
@@ -67,6 +67,15 @@ except ImportError:
|
|
|
67
67
|
logger = logging.getLogger("agent_core")
|
|
68
68
|
|
|
69
69
|
|
|
70
|
+
def is_implementation_testing_task(node_type: str, input_data: dict) -> bool:
|
|
71
|
+
"""Retain the testing responsibility of a phase-remediation wrapper."""
|
|
72
|
+
fix_context = input_data.get("fix_context")
|
|
73
|
+
return node_type == "testing" or (
|
|
74
|
+
node_type == "fix" and input_data.get("task") == "phase_remediation_fix"
|
|
75
|
+
and isinstance(fix_context, dict) and fix_context.get("failed_node_type") == "testing"
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
|
|
70
79
|
def missing_planned_task_files(task_input: dict, changed_files: list[str]) -> list[str]:
|
|
71
80
|
"""Find planned files without delivery evidence, including grouped sub-tasks."""
|
|
72
81
|
def normalize_path(value: object) -> str | None:
|
|
@@ -166,7 +175,7 @@ def assess_implementation_audit(contract: dict, report: object) -> dict:
|
|
|
166
175
|
"audit_id": contract.get("audit_id"), "report_valid": False,
|
|
167
176
|
"node_complete": False, "status": "incomplete", "issues": issues,
|
|
168
177
|
"findings": findings, "followup_task_ids": [], "report": report,
|
|
169
|
-
"revision_requests": [],
|
|
178
|
+
"revision_requests": [], "blocking_reasons": [],
|
|
170
179
|
}
|
|
171
180
|
if (
|
|
172
181
|
not isinstance(contract.get("audit_id"), str) or not contract["audit_id"]
|
|
@@ -226,6 +235,10 @@ def assess_implementation_audit(contract: dict, report: object) -> dict:
|
|
|
226
235
|
issues.append("Implementation audit has invalid acceptance criterion or task references")
|
|
227
236
|
continue
|
|
228
237
|
checked_criteria.add(index)
|
|
238
|
+
if len(related) > 1:
|
|
239
|
+
unresolved_contributors = [task_id for task_id in related if checked.get(task_id) != "covered"]
|
|
240
|
+
if unresolved_contributors:
|
|
241
|
+
related = unresolved_contributors
|
|
229
242
|
if status != "covered":
|
|
230
243
|
description = row.get("description")
|
|
231
244
|
paths = row.get("files") or []
|
|
@@ -266,6 +279,10 @@ def assess_implementation_audit(contract: dict, report: object) -> dict:
|
|
|
266
279
|
not issues and checked.get(subject) == "covered"
|
|
267
280
|
and not any(finding["task_id"] == subject for finding in findings)
|
|
268
281
|
)
|
|
282
|
+
result["blocking_reasons"] = list(dict.fromkeys(
|
|
283
|
+
f"Approved task '{subject}' is {finding['status']}: {finding['description']}"
|
|
284
|
+
for finding in findings if finding["task_id"] == subject
|
|
285
|
+
))
|
|
269
286
|
result["followup_task_ids"] = sorted({finding["task_id"] for finding in findings})
|
|
270
287
|
result["status"] = "complete" if not issues and not findings else "incomplete"
|
|
271
288
|
if result["report_valid"] and result["revision_requests"]:
|
|
@@ -1234,7 +1234,7 @@ except (ImportError, ModuleNotFoundError):
|
|
|
1234
1234
|
# DAEMON_VERSION is the protocol/logic version of the daemon code.
|
|
1235
1235
|
# Kept in sync with pyproject.toml version via bump-version.sh.
|
|
1236
1236
|
# CLIENT_TYPE identifies which packaging/distribution this daemon runs in.
|
|
1237
|
-
DAEMON_VERSION = "1.77.
|
|
1237
|
+
DAEMON_VERSION = "1.77.1"
|
|
1238
1238
|
|
|
1239
1239
|
|
|
1240
1240
|
def _detect_client_type() -> str:
|
|
@@ -13875,6 +13875,8 @@ class RuntimeDaemon:
|
|
|
13875
13875
|
issues: list[str] = []
|
|
13876
13876
|
node_type = task.node_type
|
|
13877
13877
|
input_data = task.input_data or {}
|
|
13878
|
+
if agent_core.is_implementation_testing_task(node_type, input_data):
|
|
13879
|
+
node_type = "testing"
|
|
13878
13880
|
req_type = input_data.get("requirement_type", "feature")
|
|
13879
13881
|
verification_work_item = bool(input_data.get("verification_work_item"))
|
|
13880
13882
|
|
|
@@ -13895,7 +13897,9 @@ class RuntimeDaemon:
|
|
|
13895
13897
|
result.error = "Approved analysis and task plan require revision before implementation can continue"
|
|
13896
13898
|
issues.append(result.error)
|
|
13897
13899
|
elif not audit_result["report_valid"] or not audit_result["node_complete"]:
|
|
13898
|
-
issues.extend(audit_result["issues"] or ["
|
|
13900
|
+
issues.extend(audit_result["issues"] or audit_result["blocking_reasons"] or [
|
|
13901
|
+
"The selected approved task still has implementation gaps",
|
|
13902
|
+
])
|
|
13899
13903
|
|
|
13900
13904
|
if node_type == "coding" or (
|
|
13901
13905
|
node_type == "fix" and input_data.get("task") == "phase_remediation_fix"
|
|
@@ -15880,7 +15884,7 @@ class RuntimeDaemon:
|
|
|
15880
15884
|
])
|
|
15881
15885
|
|
|
15882
15886
|
if (
|
|
15883
|
-
task.node_type
|
|
15887
|
+
agent_core.is_implementation_testing_task(task.node_type, task.input_data or {})
|
|
15884
15888
|
and all(
|
|
15885
15889
|
issue.startswith("Uncovered acceptance criteria in coverage-matrix.json:")
|
|
15886
15890
|
for issue in issues
|
|
@@ -16003,7 +16007,7 @@ class RuntimeDaemon:
|
|
|
16003
16007
|
*[f"[daemon] {issue}" for issue in remaining],
|
|
16004
16008
|
])
|
|
16005
16009
|
if (
|
|
16006
|
-
task.node_type
|
|
16010
|
+
agent_core.is_implementation_testing_task(task.node_type, task.input_data or {})
|
|
16007
16011
|
and all(
|
|
16008
16012
|
issue.startswith("Uncovered acceptance criteria in coverage-matrix.json:")
|
|
16009
16013
|
for issue in remaining
|
|
@@ -16162,7 +16166,7 @@ class RuntimeDaemon:
|
|
|
16162
16166
|
result.metrics["validation_issue_categories"] = sorted(
|
|
16163
16167
|
{_categorize_validation_issue(str(issue)) for issue in issues}
|
|
16164
16168
|
)
|
|
16165
|
-
if task.node_type
|
|
16169
|
+
if not agent_core.is_implementation_testing_task(task.node_type, task.input_data or {}):
|
|
16166
16170
|
return
|
|
16167
16171
|
input_data = task.input_data or {}
|
|
16168
16172
|
context = input_data.get("context") or {}
|
|
@@ -17616,7 +17620,9 @@ class RuntimeDaemon:
|
|
|
17616
17620
|
before_sha: str,
|
|
17617
17621
|
) -> None:
|
|
17618
17622
|
"""Bind generated testing artifacts to the committed testing attempt."""
|
|
17619
|
-
if task.workspace_resolution != "cloud_worktree" or
|
|
17623
|
+
if task.workspace_resolution != "cloud_worktree" or not agent_core.is_implementation_testing_task(
|
|
17624
|
+
task.node_type, task.input_data or {},
|
|
17625
|
+
):
|
|
17620
17626
|
return
|
|
17621
17627
|
|
|
17622
17628
|
after_sha = str((result.git or {}).get("commit_sha") or "").strip()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|