@arbiterforge/ca-pi 0.18.2 → 0.18.4
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/README.md +1 -1
- package/package.json +1 -1
- package/plugins/ca-pi/CHANGELOG.md +12 -0
- package/plugins/ca-pi/helpers/artifacts/ca-artifact-darwin-amd64 +0 -0
- package/plugins/ca-pi/helpers/artifacts/ca-artifact-darwin-arm64 +0 -0
- package/plugins/ca-pi/helpers/artifacts/ca-artifact-linux-amd64 +0 -0
- package/plugins/ca-pi/helpers/artifacts/ca-artifact-linux-arm64 +0 -0
- package/plugins/ca-pi/helpers/artifacts/ca-artifact-windows-amd64.exe +0 -0
- package/plugins/ca-pi/helpers/artifacts/ca-artifact-windows-arm64.exe +0 -0
- package/plugins/ca-pi/helpers/artifacts/release.json +36 -36
- package/plugins/ca-pi/hooks/_artifactauthoritylib.py +69 -26
- package/plugins/ca-pi/hooks/_host.py +1 -1
- package/plugins/ca-pi/hooks/_reconciliationlib.py +3 -1
- package/plugins/ca-pi/hooks/artifact-authority.py +3 -6
- package/plugins/ca-pi/hooks/hostapi.py +1 -1
- package/plugins/ca-pi/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ and durable project context. You decide. codeArbiter enforces.
|
|
|
10
10
|
<img alt="Claude Code plugin" src="https://img.shields.io/badge/Claude_Code-plugin-d97757">
|
|
11
11
|
<img alt="Codex plugin" src="https://img.shields.io/badge/OpenAI_Codex-plugin-10a37f">
|
|
12
12
|
<img alt="Pi Feature Forge preview" src="https://img.shields.io/badge/ca--pi-Feature_Forge_preview-d97757">
|
|
13
|
-
<img alt="version 2.26.
|
|
13
|
+
<img alt="version 2.26.4" src="https://img.shields.io/badge/version-2.26.4-2b7489">
|
|
14
14
|
<img alt="core lanes" src="https://img.shields.io/badge/core_lanes-18-555">
|
|
15
15
|
<img alt="skills" src="https://img.shields.io/badge/skills-22-555">
|
|
16
16
|
<img alt="agents" src="https://img.shields.io/badge/agents-20-555">
|
package/package.json
CHANGED
|
@@ -4,6 +4,18 @@ All notable changes to `ca-pi` are documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.18.4] - 2026-10-13
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Fix task reconciliation for Unicode text while preserving armed requests and prompt-route integrity.
|
|
12
|
+
|
|
13
|
+
## [0.18.3] - 2026-10-13
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- Synchronize the shared authority adapter with the Codex runtime compatibility repair while preserving Pi's existing host contract.
|
|
18
|
+
|
|
7
19
|
## [0.18.2] - 2026-10-12
|
|
8
20
|
|
|
9
21
|
### Fixed
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -6,43 +6,43 @@
|
|
|
6
6
|
"binaries": {
|
|
7
7
|
"darwin/amd64": {
|
|
8
8
|
"file": "ca-artifact-darwin-amd64",
|
|
9
|
-
"sha256": "
|
|
9
|
+
"sha256": "42f302c05c66b22294bff0bdacbd28d5373ddd64b447f087a4532cd99f0a1b6c",
|
|
10
10
|
"native_tested": true
|
|
11
11
|
},
|
|
12
12
|
"darwin/arm64": {
|
|
13
13
|
"file": "ca-artifact-darwin-arm64",
|
|
14
|
-
"sha256": "
|
|
14
|
+
"sha256": "adf818a92d6d45db8d13a4ec685b2e2e14ddd19d0978c3d820541c45ed5cd4d9",
|
|
15
15
|
"native_tested": true
|
|
16
16
|
},
|
|
17
17
|
"linux/amd64": {
|
|
18
18
|
"file": "ca-artifact-linux-amd64",
|
|
19
|
-
"sha256": "
|
|
19
|
+
"sha256": "8090a552d8a40bd3d37075eb81005d4e2bc4cdefac3ecb04cef8d72ef00f64d5",
|
|
20
20
|
"native_tested": true
|
|
21
21
|
},
|
|
22
22
|
"linux/arm64": {
|
|
23
23
|
"file": "ca-artifact-linux-arm64",
|
|
24
|
-
"sha256": "
|
|
24
|
+
"sha256": "0e65ced478bc490e80d6ab5323d307ceffdf42830709563cd6740ef5f35fb069",
|
|
25
25
|
"native_tested": true
|
|
26
26
|
},
|
|
27
27
|
"windows/amd64": {
|
|
28
28
|
"file": "ca-artifact-windows-amd64.exe",
|
|
29
|
-
"sha256": "
|
|
29
|
+
"sha256": "687e362c216634b531371b4238d129a5f09df716d8cf73b6123f20d4c40c9d36",
|
|
30
30
|
"native_tested": true
|
|
31
31
|
},
|
|
32
32
|
"windows/arm64": {
|
|
33
33
|
"file": "ca-artifact-windows-arm64.exe",
|
|
34
|
-
"sha256": "
|
|
34
|
+
"sha256": "bc4920311a4e3768439b9c35bd0aca77f1ab964011d7812dd8932fc7360527a0",
|
|
35
35
|
"native_tested": true
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
38
|
"context_qualification": {
|
|
39
39
|
"darwin/amd64": {
|
|
40
|
-
"source_commit": "
|
|
40
|
+
"source_commit": "045c0812888f20f4c843677cfb37b802e2084770",
|
|
41
41
|
"workflow": ".github/workflows/ci.yml",
|
|
42
|
-
"run_id": "
|
|
43
|
-
"binary_sha256": "
|
|
44
|
-
"observation_sha256": "
|
|
45
|
-
"module_sha256": "
|
|
42
|
+
"run_id": "38575955363",
|
|
43
|
+
"binary_sha256": "42f302c05c66b22294bff0bdacbd28d5373ddd64b447f087a4532cd99f0a1b6c",
|
|
44
|
+
"observation_sha256": "e03881ae6e4baf8095597869933ae43dd90b4e1c97bd56dbd83ec57535f6ad7f",
|
|
45
|
+
"module_sha256": "e482ad7b0c9264711828ac8404c624517b893981b45712d70ead0fb0ef3b5522",
|
|
46
46
|
"native_cases": [
|
|
47
47
|
"TestContextBoundedRender",
|
|
48
48
|
"TestContextDocumentContract",
|
|
@@ -53,12 +53,12 @@
|
|
|
53
53
|
]
|
|
54
54
|
},
|
|
55
55
|
"darwin/arm64": {
|
|
56
|
-
"source_commit": "
|
|
56
|
+
"source_commit": "045c0812888f20f4c843677cfb37b802e2084770",
|
|
57
57
|
"workflow": ".github/workflows/ci.yml",
|
|
58
|
-
"run_id": "
|
|
59
|
-
"binary_sha256": "
|
|
60
|
-
"observation_sha256": "
|
|
61
|
-
"module_sha256": "
|
|
58
|
+
"run_id": "38575955363",
|
|
59
|
+
"binary_sha256": "adf818a92d6d45db8d13a4ec685b2e2e14ddd19d0978c3d820541c45ed5cd4d9",
|
|
60
|
+
"observation_sha256": "053780b4155a329003e9d8402a90be022ac1750e5f1420ea46a5079931464fd6",
|
|
61
|
+
"module_sha256": "e482ad7b0c9264711828ac8404c624517b893981b45712d70ead0fb0ef3b5522",
|
|
62
62
|
"native_cases": [
|
|
63
63
|
"TestContextBoundedRender",
|
|
64
64
|
"TestContextDocumentContract",
|
|
@@ -69,12 +69,12 @@
|
|
|
69
69
|
]
|
|
70
70
|
},
|
|
71
71
|
"linux/amd64": {
|
|
72
|
-
"source_commit": "
|
|
72
|
+
"source_commit": "045c0812888f20f4c843677cfb37b802e2084770",
|
|
73
73
|
"workflow": ".github/workflows/ci.yml",
|
|
74
|
-
"run_id": "
|
|
75
|
-
"binary_sha256": "
|
|
76
|
-
"observation_sha256": "
|
|
77
|
-
"module_sha256": "
|
|
74
|
+
"run_id": "38575955363",
|
|
75
|
+
"binary_sha256": "8090a552d8a40bd3d37075eb81005d4e2bc4cdefac3ecb04cef8d72ef00f64d5",
|
|
76
|
+
"observation_sha256": "e83da7b877c8e37761b826b6a45bee44e009066a66c18309d2f854ed0d94096b",
|
|
77
|
+
"module_sha256": "e482ad7b0c9264711828ac8404c624517b893981b45712d70ead0fb0ef3b5522",
|
|
78
78
|
"native_cases": [
|
|
79
79
|
"TestContextBoundedRender",
|
|
80
80
|
"TestContextDocumentContract",
|
|
@@ -85,12 +85,12 @@
|
|
|
85
85
|
]
|
|
86
86
|
},
|
|
87
87
|
"linux/arm64": {
|
|
88
|
-
"source_commit": "
|
|
88
|
+
"source_commit": "045c0812888f20f4c843677cfb37b802e2084770",
|
|
89
89
|
"workflow": ".github/workflows/ci.yml",
|
|
90
|
-
"run_id": "
|
|
91
|
-
"binary_sha256": "
|
|
92
|
-
"observation_sha256": "
|
|
93
|
-
"module_sha256": "
|
|
90
|
+
"run_id": "38575955363",
|
|
91
|
+
"binary_sha256": "0e65ced478bc490e80d6ab5323d307ceffdf42830709563cd6740ef5f35fb069",
|
|
92
|
+
"observation_sha256": "dbaace14fca6456b29dbb71360fe9d2f0ab73738bad9c09486f0964358958a07",
|
|
93
|
+
"module_sha256": "e482ad7b0c9264711828ac8404c624517b893981b45712d70ead0fb0ef3b5522",
|
|
94
94
|
"native_cases": [
|
|
95
95
|
"TestContextBoundedRender",
|
|
96
96
|
"TestContextDocumentContract",
|
|
@@ -101,12 +101,12 @@
|
|
|
101
101
|
]
|
|
102
102
|
},
|
|
103
103
|
"windows/amd64": {
|
|
104
|
-
"source_commit": "
|
|
104
|
+
"source_commit": "045c0812888f20f4c843677cfb37b802e2084770",
|
|
105
105
|
"workflow": ".github/workflows/ci.yml",
|
|
106
|
-
"run_id": "
|
|
107
|
-
"binary_sha256": "
|
|
108
|
-
"observation_sha256": "
|
|
109
|
-
"module_sha256": "
|
|
106
|
+
"run_id": "38575955363",
|
|
107
|
+
"binary_sha256": "687e362c216634b531371b4238d129a5f09df716d8cf73b6123f20d4c40c9d36",
|
|
108
|
+
"observation_sha256": "575df189640f478ffdbc593f4a070c4e407b0f50b7787d20632eb3586bc16cee",
|
|
109
|
+
"module_sha256": "e482ad7b0c9264711828ac8404c624517b893981b45712d70ead0fb0ef3b5522",
|
|
110
110
|
"native_cases": [
|
|
111
111
|
"TestContextBoundedRender",
|
|
112
112
|
"TestContextDocumentContract",
|
|
@@ -117,12 +117,12 @@
|
|
|
117
117
|
]
|
|
118
118
|
},
|
|
119
119
|
"windows/arm64": {
|
|
120
|
-
"source_commit": "
|
|
120
|
+
"source_commit": "045c0812888f20f4c843677cfb37b802e2084770",
|
|
121
121
|
"workflow": ".github/workflows/ci.yml",
|
|
122
|
-
"run_id": "
|
|
123
|
-
"binary_sha256": "
|
|
124
|
-
"observation_sha256": "
|
|
125
|
-
"module_sha256": "
|
|
122
|
+
"run_id": "38575955363",
|
|
123
|
+
"binary_sha256": "bc4920311a4e3768439b9c35bd0aca77f1ab964011d7812dd8932fc7360527a0",
|
|
124
|
+
"observation_sha256": "1b6574772d1e93c2cd59ff43d519e343d44926312cf4d90b840207b0a625d3f9",
|
|
125
|
+
"module_sha256": "e482ad7b0c9264711828ac8404c624517b893981b45712d70ead0fb0ef3b5522",
|
|
126
126
|
"native_cases": [
|
|
127
127
|
"TestContextBoundedRender",
|
|
128
128
|
"TestContextDocumentContract",
|
|
@@ -117,7 +117,11 @@ CLAUDE_REVIEW_PROFILE = "claude-review/0.1.0"
|
|
|
117
117
|
CODEX_REVIEW_PROFILE = "codex-review/0.1.0"
|
|
118
118
|
CODEX_NATIVE_V1 = "codex-native-v1/0.145.0"
|
|
119
119
|
CODEX_NATIVE_V2 = "codex-native-v2/0.162.0-alpha.2"
|
|
120
|
-
|
|
120
|
+
# This version identifies our evidence protocol, never the host release.
|
|
121
|
+
CODEX_NATIVE_PROTOCOL = "codex-native-collaboration/1.0.0"
|
|
122
|
+
CODEX_COLLABORATION_PROFILES = frozenset({CODEX_NATIVE_V2, CODEX_NATIVE_PROTOCOL})
|
|
123
|
+
CODEX_NATIVE_PROFILES = frozenset({CODEX_NATIVE_V1, *CODEX_COLLABORATION_PROFILES})
|
|
124
|
+
CODEX_RUNTIME_RE = re.compile(r"[0-9]+(?:\.[0-9]+){2}(?:[-+][0-9A-Za-z.+-]+)?", re.ASCII)
|
|
121
125
|
CODEX_UUID_RE = re.compile(r"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}")
|
|
122
126
|
CODEX_AGENT_PATH_RE = re.compile(r"/root(?:/[a-z0-9_]+)*")
|
|
123
127
|
CODEX_STEERING_TOOLS = frozenset({
|
|
@@ -1179,7 +1183,7 @@ def _reject_overlapping_authority(session_id: str, turn_id: str) -> None:
|
|
|
1179
1183
|
launch = request.get("launch") or {}
|
|
1180
1184
|
if (
|
|
1181
1185
|
request["state"] in {"LAUNCHING", "RUNNING"}
|
|
1182
|
-
and request.get("codex_review_profile")
|
|
1186
|
+
and request.get("codex_review_profile") not in CODEX_COLLABORATION_PROFILES
|
|
1183
1187
|
and launch.get("parent_session_id") == session_id
|
|
1184
1188
|
and launch.get("parent_turn_id") == turn_id
|
|
1185
1189
|
):
|
|
@@ -1500,8 +1504,8 @@ def _dispatch_prompt(request: dict[str, Any], *, legacy_inline: bool = False) ->
|
|
|
1500
1504
|
"these settings do not provide an OS sandbox.\n"
|
|
1501
1505
|
if request.get("codex_review_profile") == CODEX_NATIVE_V1 else ""
|
|
1502
1506
|
)
|
|
1503
|
-
if request.get("codex_review_profile")
|
|
1504
|
-
profile = (f"Native review profile: {
|
|
1507
|
+
if request.get("codex_review_profile") in CODEX_COLLABORATION_PROFILES:
|
|
1508
|
+
profile = (f"Native review profile: {request['codex_review_profile']}. This review was dispatched through "
|
|
1505
1509
|
"collaboration.spawn_agent with default role and fork_turns=none. Read-only conduct "
|
|
1506
1510
|
"is cooperative; these settings do not provide an OS sandbox.\n")
|
|
1507
1511
|
completion = ""
|
|
@@ -1600,7 +1604,7 @@ def arm_request(
|
|
|
1600
1604
|
if host == "claude" and reviewer_model not in CLAUDE_REVIEWER_MODELS:
|
|
1601
1605
|
raise AuthorityError("INVALID_AUTHORITY_REQUEST", "reviewer model is unsupported")
|
|
1602
1606
|
if codex_review_profile is not None and (
|
|
1603
|
-
codex_review_profile not in {"native-v1", "native-v2"} or host != "codex" or activity not in REVIEW_ACTIVITIES
|
|
1607
|
+
codex_review_profile not in {"native", "native-v1", "native-v2"} or host != "codex" or activity not in REVIEW_ACTIVITIES
|
|
1604
1608
|
):
|
|
1605
1609
|
raise AuthorityError("INVALID_AUTHORITY_REQUEST", "Codex review profile is unsupported")
|
|
1606
1610
|
completion_selection = None
|
|
@@ -1652,7 +1656,9 @@ def arm_request(
|
|
|
1652
1656
|
if activity == "verification":
|
|
1653
1657
|
seed_value["context_storage"] = CONTEXT_STORAGE
|
|
1654
1658
|
if codex_review_profile is not None:
|
|
1655
|
-
seed_value["codex_review_profile"] =
|
|
1659
|
+
seed_value["codex_review_profile"] = {
|
|
1660
|
+
"native": CODEX_NATIVE_PROTOCOL, "native-v1": CODEX_NATIVE_V1, "native-v2": CODEX_NATIVE_V2,
|
|
1661
|
+
}[codex_review_profile]
|
|
1656
1662
|
if completion_selection is not None:
|
|
1657
1663
|
seed_value["context_storage"] = CONTEXT_STORAGE
|
|
1658
1664
|
seed = _canonical(seed_value)
|
|
@@ -3043,6 +3049,16 @@ def _codex_v2_activity(event: dict[str, Any], request: dict[str, Any]) -> dict[s
|
|
|
3043
3049
|
raise AuthorityError("UNSUPPORTED_HOST_SEAM", "native activity for exact call is missing or ambiguous")
|
|
3044
3050
|
activity = matches[0]
|
|
3045
3051
|
item = activity["item"]
|
|
3052
|
+
if request.get("codex_review_profile") == CODEX_NATIVE_PROTOCOL:
|
|
3053
|
+
# Host records may gain non-authoritative fields. Retained evidence is
|
|
3054
|
+
# closed; required joins, bounds and duplicate-key rejection stay strict.
|
|
3055
|
+
activity = {key: activity[key] for key in (
|
|
3056
|
+
"type", "thread_id", "turn_id", "item", "started_at_ms", "completed_at_ms",
|
|
3057
|
+
) if key in activity}
|
|
3058
|
+
item = {key: item[key] for key in (
|
|
3059
|
+
"type", "id", "kind", "agent_thread_id", "agent_path",
|
|
3060
|
+
) if key in item}
|
|
3061
|
+
activity["item"] = item
|
|
3046
3062
|
if (set(activity) != {"type", "thread_id", "turn_id", "item", "started_at_ms", "completed_at_ms"}
|
|
3047
3063
|
or set(item) != {"type", "id", "kind", "agent_thread_id", "agent_path"}
|
|
3048
3064
|
or activity["thread_id"] != anchor["parent_thread_id"] or activity["turn_id"] != launch["parent_turn_id"]
|
|
@@ -3054,6 +3070,10 @@ def _codex_v2_activity(event: dict[str, Any], request: dict[str, Any]) -> dict[s
|
|
|
3054
3070
|
return activity
|
|
3055
3071
|
|
|
3056
3072
|
|
|
3073
|
+
def _codex_runtime_identity(value: Any) -> bool:
|
|
3074
|
+
return isinstance(value, str) and len(value) <= 128 and CODEX_RUNTIME_RE.fullmatch(value) is not None
|
|
3075
|
+
|
|
3076
|
+
|
|
3057
3077
|
def _codex_v2_child(event: dict[str, Any]) -> dict[str, Any] | None:
|
|
3058
3078
|
# Historical V1 lifecycle fixtures/hosts need no native rollout metadata.
|
|
3059
3079
|
if event.get("transcript_path") is None:
|
|
@@ -3065,16 +3085,26 @@ def _codex_v2_child(event: dict[str, Any]) -> dict[str, Any] | None:
|
|
|
3065
3085
|
# A V1 Start did not promise native metadata. V2 binding below requires
|
|
3066
3086
|
# qualified metadata; missing/unsafe bytes still cannot pass V2.
|
|
3067
3087
|
return None
|
|
3068
|
-
|
|
3088
|
+
# Runtime identity is provenance; compatibility comes from the concrete
|
|
3089
|
+
# launch/activity/lifecycle protocol, not a release allowlist.
|
|
3090
|
+
if (not _codex_runtime_identity(meta.get("cli_version"))
|
|
3091
|
+
or not {"id", "parent_thread_id", "session_id", "agent_path"} <= set(meta)):
|
|
3092
|
+
# V1 metadata lacks collaboration fields. Its own lifecycle contract
|
|
3093
|
+
# remains sufficient; collaboration requests require this evidence at bind.
|
|
3094
|
+
return None
|
|
3095
|
+
try:
|
|
3096
|
+
identity = {"cli_version": meta["cli_version"], "thread_id": _codex_uuid(meta.get("id")),
|
|
3097
|
+
"parent_thread_id": _codex_uuid(meta.get("parent_thread_id")),
|
|
3098
|
+
"session_id": _host_id(meta.get("session_id"), "session_id"),
|
|
3099
|
+
"agent_path": meta.get("agent_path"), "metadata_sha256": _digest(raw)}
|
|
3100
|
+
except AuthorityError:
|
|
3101
|
+
# Optional metadata cannot impose collaboration prerequisites on V1.
|
|
3102
|
+
# A collaboration request will reject this absence at profile binding.
|
|
3069
3103
|
return None
|
|
3070
|
-
identity = {"cli_version": meta["cli_version"], "thread_id": _codex_uuid(meta.get("id")),
|
|
3071
|
-
"parent_thread_id": _codex_uuid(meta.get("parent_thread_id")),
|
|
3072
|
-
"session_id": _host_id(meta.get("session_id"), "session_id"),
|
|
3073
|
-
"agent_path": meta.get("agent_path"), "metadata_sha256": _digest(raw)}
|
|
3074
3104
|
if (identity["thread_id"] != event["agent_id"] or identity["session_id"] != event.get("session_id")
|
|
3075
3105
|
or not isinstance(identity["agent_path"], str)
|
|
3076
3106
|
or CODEX_AGENT_PATH_RE.fullmatch(identity["agent_path"]) is None):
|
|
3077
|
-
|
|
3107
|
+
return None
|
|
3078
3108
|
return identity
|
|
3079
3109
|
|
|
3080
3110
|
|
|
@@ -3085,7 +3115,11 @@ def _codex_v2_bind_child(request: dict[str, Any], child: dict[str, Any]) -> None
|
|
|
3085
3115
|
or identity.get("thread_id") != launch["agent_id"]
|
|
3086
3116
|
or identity.get("session_id") != launch["parent_session_id"]
|
|
3087
3117
|
or identity.get("agent_path") != launch["task_name"]):
|
|
3088
|
-
raise AuthorityError("UNSUPPORTED_HOST_SEAM", "native
|
|
3118
|
+
raise AuthorityError("UNSUPPORTED_HOST_SEAM", "native collaboration requires child metadata bound to the exact parent/session/path/UUID")
|
|
3119
|
+
# Only new protocol requests admit differing runtime provenance.
|
|
3120
|
+
if (request.get("codex_review_profile") == CODEX_NATIVE_V2
|
|
3121
|
+
and identity.get("cli_version") != "0.162.0-alpha.2"):
|
|
3122
|
+
raise AuthorityError("UNSUPPORTED_HOST_SEAM", "historical native-v2 request requires its original runtime; arm a new native protocol request")
|
|
3089
3123
|
launch["native_child"] = identity
|
|
3090
3124
|
|
|
3091
3125
|
|
|
@@ -3173,7 +3207,7 @@ def _read_codex_child(path: Path, agent_id: str, session_id: str) -> dict[str, A
|
|
|
3173
3207
|
identity = value["native_v2"]
|
|
3174
3208
|
if (not isinstance(identity, dict) or set(identity) != {
|
|
3175
3209
|
"cli_version", "thread_id", "parent_thread_id", "session_id", "agent_path", "metadata_sha256"}
|
|
3176
|
-
or identity.get("cli_version")
|
|
3210
|
+
or not _codex_runtime_identity(identity.get("cli_version"))
|
|
3177
3211
|
or identity.get("thread_id") != agent_id or identity.get("session_id") != value["session_id"]
|
|
3178
3212
|
or not isinstance(identity.get("parent_thread_id"), str)
|
|
3179
3213
|
or CODEX_UUID_RE.fullmatch(identity["parent_thread_id"]) is None
|
|
@@ -3224,7 +3258,7 @@ def _codex_native_post(event: dict[str, Any], root: Path, request: dict[str, Any
|
|
|
3224
3258
|
|
|
3225
3259
|
|
|
3226
3260
|
def _codex_native_post_join(event: dict[str, Any], root: Path, request: dict[str, Any]) -> dict[str, Any]:
|
|
3227
|
-
expected_tool = "collaborationspawn_agent" if request.get("codex_review_profile")
|
|
3261
|
+
expected_tool = "collaborationspawn_agent" if request.get("codex_review_profile") in CODEX_COLLABORATION_PROFILES else "spawn_agent"
|
|
3228
3262
|
if event.get("tool_name") != expected_tool:
|
|
3229
3263
|
raise AuthorityError("UNSUPPORTED_HOST_SEAM", "native review PostToolUse tool differs from its launch profile")
|
|
3230
3264
|
if _canonical(event.get("tool_input")) != _canonical(request["launch_envelope"]):
|
|
@@ -3238,13 +3272,22 @@ def _codex_native_post_join(event: dict[str, Any], root: Path, request: dict[str
|
|
|
3238
3272
|
except ValueError as exc:
|
|
3239
3273
|
raise AuthorityError("UNSUPPORTED_HOST_SEAM", "native-v1 spawn result is not strict JSON") from exc
|
|
3240
3274
|
activity = None
|
|
3241
|
-
if request.get("codex_review_profile")
|
|
3242
|
-
|
|
3275
|
+
if request.get("codex_review_profile") in CODEX_COLLABORATION_PROFILES:
|
|
3276
|
+
stable = request.get("codex_review_profile") == CODEX_NATIVE_PROTOCOL
|
|
3277
|
+
if (not isinstance(response, dict)
|
|
3278
|
+
or not stable and set(response) not in ({"task_name"}, {"task_name", "nickname"})
|
|
3243
3279
|
or response.get("task_name") != request["codex_native_trace"]["agent_path"]
|
|
3244
3280
|
or ("nickname" in response and (not isinstance(response["nickname"], str) or len(response["nickname"]) > 256))):
|
|
3245
|
-
raise AuthorityError("UNSUPPORTED_HOST_SEAM", "native
|
|
3281
|
+
raise AuthorityError("UNSUPPORTED_HOST_SEAM", "native collaboration spawn result fields or canonical task path differ")
|
|
3246
3282
|
activity = _codex_v2_activity(event, request)
|
|
3247
3283
|
agent_id = _codex_uuid(activity["item"]["agent_thread_id"])
|
|
3284
|
+
if stable:
|
|
3285
|
+
# Extra display metadata is inert, but an optional host identity
|
|
3286
|
+
# must agree with the independently observed native activity.
|
|
3287
|
+
identities = {"agent_id": agent_id, "thread_id": agent_id,
|
|
3288
|
+
"parent_thread_id": request["launch"]["parent_thread_id"]}
|
|
3289
|
+
if any(key in response and response[key] != expected for key, expected in identities.items()):
|
|
3290
|
+
raise AuthorityError("UNSUPPORTED_HOST_SEAM", "native spawn result identity conflicts with its activity")
|
|
3248
3291
|
elif (not isinstance(response, dict) or set(response) != {"agent_id", "nickname"}
|
|
3249
3292
|
or (response["nickname"] is not None and (
|
|
3250
3293
|
not isinstance(response["nickname"], str) or len(response["nickname"]) > 256))):
|
|
@@ -3269,7 +3312,7 @@ def _codex_native_post_join(event: dict[str, Any], root: Path, request: dict[str
|
|
|
3269
3312
|
if activity is not None:
|
|
3270
3313
|
launch.update(native_activity=activity, native_activity_sha256=_engine_digest(activity))
|
|
3271
3314
|
if child["start"] is not None:
|
|
3272
|
-
if request.get("codex_review_profile")
|
|
3315
|
+
if request.get("codex_review_profile") in CODEX_COLLABORATION_PROFILES:
|
|
3273
3316
|
_codex_v2_bind_child(request, child)
|
|
3274
3317
|
launch.update(child_turn_id=child["start"]["turn_id"], agent_type="default")
|
|
3275
3318
|
request["state"] = "RUNNING"
|
|
@@ -3363,7 +3406,7 @@ def _codex_native_lifecycle_join(event: dict[str, Any]) -> dict[str, Any] | None
|
|
|
3363
3406
|
if name == "SubagentStart":
|
|
3364
3407
|
if request["state"] != "LAUNCHING":
|
|
3365
3408
|
_codex_native_refuse(root, request, "native reviewer start was repeated")
|
|
3366
|
-
if request.get("codex_review_profile")
|
|
3409
|
+
if request.get("codex_review_profile") in CODEX_COLLABORATION_PROFILES:
|
|
3367
3410
|
_codex_v2_bind_child(request, child)
|
|
3368
3411
|
launch.update(child_turn_id=event["turn_id"], agent_type="default")
|
|
3369
3412
|
request["state"] = "RUNNING"
|
|
@@ -3419,7 +3462,7 @@ def _codex_native_steering(event: dict[str, Any]) -> None:
|
|
|
3419
3462
|
_write_codex_child(path, child)
|
|
3420
3463
|
for root, request in _registered_requests(strict=True):
|
|
3421
3464
|
launch = request.get("launch") or {}
|
|
3422
|
-
if (request.get("codex_review_profile")
|
|
3465
|
+
if (request.get("codex_review_profile") not in CODEX_COLLABORATION_PROFILES
|
|
3423
3466
|
or request["state"] not in {"LAUNCHING", "RUNNING"}
|
|
3424
3467
|
or launch.get("parent_session_id") != event.get("session_id")):
|
|
3425
3468
|
continue
|
|
@@ -3470,11 +3513,11 @@ def observe_codex_hook(root: str | Path, event: dict[str, Any]) -> dict[str, Any
|
|
|
3470
3513
|
message = tool_input.get("message") if isinstance(tool_input, dict) else None
|
|
3471
3514
|
if isinstance(message, str) and message.startswith("[CODEARBITER_AUTHORITY_REQUEST:"):
|
|
3472
3515
|
_, candidate = _registered_request(_request_id_from_prompt(message))
|
|
3473
|
-
if candidate.get("codex_review_profile")
|
|
3516
|
+
if candidate.get("codex_review_profile") not in CODEX_COLLABORATION_PROFILES:
|
|
3474
3517
|
raise AuthorityError(
|
|
3475
3518
|
"UNSUPPORTED_HOST_SEAM",
|
|
3476
|
-
"
|
|
3477
|
-
"
|
|
3519
|
+
"collaboration review requires a fresh native protocol request with direct activity UUID binding; "
|
|
3520
|
+
"historical requests cannot be relabelled",
|
|
3478
3521
|
)
|
|
3479
3522
|
else:
|
|
3480
3523
|
turn_id = _host_id(event.get("turn_id"), "turn_id")
|
|
@@ -3508,7 +3551,7 @@ def observe_codex_hook(root: str | Path, event: dict[str, Any]) -> dict[str, Any
|
|
|
3508
3551
|
raise AuthorityError("UNSUPPORTED_HOST_SEAM", "review request is not launchable")
|
|
3509
3552
|
if _canonical(tool_input) != _canonical(request.get("launch_envelope")):
|
|
3510
3553
|
raise AuthorityError("UNSUPPORTED_HOST_SEAM", "review launch envelope was changed")
|
|
3511
|
-
is_v2 = request.get("codex_review_profile")
|
|
3554
|
+
is_v2 = request.get("codex_review_profile") in CODEX_COLLABORATION_PROFILES
|
|
3512
3555
|
if is_v2 != (event["tool_name"] == "collaborationspawn_agent"):
|
|
3513
3556
|
raise AuthorityError("UNSUPPORTED_HOST_SEAM", "native review profile differs from launch tool")
|
|
3514
3557
|
_require_frozen_context(root, request)
|
|
@@ -3536,7 +3579,7 @@ def observe_codex_hook(root: str | Path, event: dict[str, Any]) -> dict[str, Any
|
|
|
3536
3579
|
elif is_v2:
|
|
3537
3580
|
anchor = _codex_v2_trace_anchor(event, tool_input["task_name"])
|
|
3538
3581
|
request["codex_native_trace"] = anchor
|
|
3539
|
-
request["launch"].update(codex_review_profile=
|
|
3582
|
+
request["launch"].update(codex_review_profile=request["codex_review_profile"], child_turn_id=None,
|
|
3540
3583
|
parent_thread_id=anchor["parent_thread_id"], task_name=anchor["agent_path"], fork_turns="none")
|
|
3541
3584
|
else:
|
|
3542
3585
|
request["launch"].update(task_name=tool_input["task_name"], fork_turns=tool_input["fork_turns"])
|
|
@@ -11,7 +11,7 @@ import hostapi # noqa: E402
|
|
|
11
11
|
class PiHost(hostapi.Host):
|
|
12
12
|
name = "pi"
|
|
13
13
|
adapter_name = "@arbiterforge/ca-pi"
|
|
14
|
-
adapter_version = "0.18.
|
|
14
|
+
adapter_version = "0.18.4"
|
|
15
15
|
update_target = "ca-pi"
|
|
16
16
|
update_tag_prefix = "ca-pi-v"
|
|
17
17
|
update_command = "pi update npm:@arbiterforge/ca-pi"
|
|
@@ -498,7 +498,9 @@ def _consume_reconciliation_unlocked(
|
|
|
498
498
|
raise ReconciliationError("reconciliation target changed after arming")
|
|
499
499
|
payload = {"input_sha256": pending["input_sha256"], "assessment": pending["assessment"]}
|
|
500
500
|
if pending["operation"] == "task-reconcile":
|
|
501
|
-
|
|
501
|
+
# Marker/route integrity retains its legacy serialization; authority
|
|
502
|
+
# binds the rechecked record to the engine's canonical JSON digest.
|
|
503
|
+
payload.update(task_sha256=_artifactauthoritylib._engine_digest(record), target_state=pending["target_state"])
|
|
502
504
|
event = {
|
|
503
505
|
"kind": "reconciliation",
|
|
504
506
|
"authority_kind": "user_workflow",
|
|
@@ -52,8 +52,8 @@ def main(argv=None) -> int:
|
|
|
52
52
|
default="opus", help="Claude reviewer model pinned into the launch envelope",
|
|
53
53
|
)
|
|
54
54
|
arm.add_argument(
|
|
55
|
-
"--codex-review-profile", choices=("native-v1", "native-v2"), default=None,
|
|
56
|
-
help="
|
|
55
|
+
"--codex-review-profile", choices=("native", "native-v1", "native-v2"), default=None,
|
|
56
|
+
help="Codex reviews default to the collaboration evidence protocol; legacy profiles are explicit",
|
|
57
57
|
)
|
|
58
58
|
context_arm = sub.add_parser("arm-context")
|
|
59
59
|
context_arm.add_argument("--root", required=True)
|
|
@@ -92,10 +92,7 @@ def main(argv=None) -> int:
|
|
|
92
92
|
)
|
|
93
93
|
if (host == "codex" and args.activity in _artifactauthoritylib.REVIEW_ACTIVITIES
|
|
94
94
|
and args.codex_review_profile is None):
|
|
95
|
-
|
|
96
|
-
"UNSUPPORTED_HOST_SEAM",
|
|
97
|
-
"Codex review requires an explicit native-v1 or native-v2 profile after live interface qualification",
|
|
98
|
-
)
|
|
95
|
+
args.codex_review_profile = "native"
|
|
99
96
|
result = _artifactauthoritylib.arm_request(
|
|
100
97
|
root, client, args.artifact_id, args.record_id, args.activity,
|
|
101
98
|
workspace_roots=workspaces or None, host=host,
|
|
@@ -313,7 +313,7 @@ class Host:
|
|
|
313
313
|
|
|
314
314
|
name = "claude"
|
|
315
315
|
adapter_name = "ca"
|
|
316
|
-
adapter_version = "2.26.
|
|
316
|
+
adapter_version = "2.26.4"
|
|
317
317
|
|
|
318
318
|
# Update-notifier descriptor. Each independently versioned host overrides
|
|
319
319
|
# these three values in its per-plugin _host.py. Keeping the target,
|