@arbiterforge/ca-pi 0.17.2 → 0.17.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 +2 -2
- package/package.json +1 -1
- package/plugins/ca-pi/CHANGELOG.md +18 -0
- package/plugins/ca-pi/extensions/codearbiter-child.js +2 -2
- package/plugins/ca-pi/extensions/codearbiter.js +21 -14
- package/plugins/ca-pi/helpers/artifacts/release.json +18 -18
- package/plugins/ca-pi/hooks/_githooks.py +24 -14
- package/plugins/ca-pi/hooks/_host.py +1 -1
- package/plugins/ca-pi/hooks/hostapi.py +1 -1
- package/plugins/ca-pi/includes/pi-host-notes.md +1 -1
- package/plugins/ca-pi/package.json +1 -1
- package/plugins/ca-pi/skills/ca-doctor/SKILL.md +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.25.
|
|
13
|
+
<img alt="version 2.25.3" src="https://img.shields.io/badge/version-2.25.3-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">
|
|
@@ -183,7 +183,7 @@ Replace `<version>` with the numeric suffix from the chosen tag while retaining
|
|
|
183
183
|
it is a partial install that cannot author typed HTML specs and plans; use the npm channel for
|
|
184
184
|
that.
|
|
185
185
|
|
|
186
|
-
Pi 1.0
|
|
186
|
+
Pi 1.1.0 is the supported host for this release line. Generated aliases use `/ca-*`;
|
|
187
187
|
`/skill:ca-*` is the host-native fallback. Every `ca-pi-v*` tag is also published to npm as
|
|
188
188
|
`npm:@arbiterforge/ca-pi` with provenance (ADR-0029); the pinned Git tag remains the reproducible
|
|
189
189
|
install. The [Pi runbook](./docs/pi-parity-testing.md) covers isolated install, trust, verification,
|
package/package.json
CHANGED
|
@@ -4,6 +4,24 @@ All notable changes to `ca-pi` are documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.17.4] - 2026-10-09
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Promote the verified Pi host window through exact Pi 1.1.0.
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- Accept Pi 1.1.0 execution timing fields and settlement outcomes without treating aborted child work as successful.
|
|
16
|
+
- Recognize Pi's renamed Azure provider while retaining parent-only provider credentials.
|
|
17
|
+
|
|
18
|
+
## [0.17.3] - 2026-10-09
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- Keep managed Git hooks working with a restricted PATH while preserving
|
|
23
|
+
trusted executable identities, cross-host path resolution and stale-registration checks.
|
|
24
|
+
|
|
7
25
|
## [0.17.2] - 2026-10-08
|
|
8
26
|
|
|
9
27
|
### Fixed
|
|
@@ -629,7 +629,7 @@ function resolvePythonCommand(platform = process.platform, probe = systemPythonP
|
|
|
629
629
|
}
|
|
630
630
|
|
|
631
631
|
// src/compatibility.ts
|
|
632
|
-
var SUPPORTED_PI_VERSIONS = /* @__PURE__ */ new Set(["1.0
|
|
632
|
+
var SUPPORTED_PI_VERSIONS = /* @__PURE__ */ new Set(["1.1.0"]);
|
|
633
633
|
var MINIMUM_NODE = [22, 19, 0];
|
|
634
634
|
var SEMVER_PREFIX = /^(\d+)\.(\d+)\.(\d+)(?:$|[-+])/u;
|
|
635
635
|
function atLeast(version, minimum) {
|
|
@@ -644,7 +644,7 @@ function atLeast(version, minimum) {
|
|
|
644
644
|
}
|
|
645
645
|
function compatibilityDirection(input) {
|
|
646
646
|
if (!SUPPORTED_PI_VERSIONS.has(input.piVersion)) {
|
|
647
|
-
return "codeArbiter requires Pi 1.0
|
|
647
|
+
return "codeArbiter requires Pi 1.1.0; install a supported Pi version and run /ca-doctor.";
|
|
648
648
|
}
|
|
649
649
|
if (!atLeast(input.nodeVersion, MINIMUM_NODE)) {
|
|
650
650
|
return "codeArbiter requires Node >=22.19.0 for Pi; upgrade Node and run /ca-doctor.";
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
var define_CODEARBITER_PI_PERMISSION_POLICY_SURFACES_default = { "ca-plan": "planning-write", codearbiter_background_bash: "background-launch" };
|
|
3
3
|
|
|
4
4
|
// <define:__CODEARBITER_PI_SKILL_EXPANSION_FINGERPRINTS__>
|
|
5
|
-
var define_CODEARBITER_PI_SKILL_EXPANSION_FINGERPRINTS_default = { "1.0
|
|
5
|
+
var define_CODEARBITER_PI_SKILL_EXPANSION_FINGERPRINTS_default = { "1.1.0": "12632f365440b07d5183cff871d889b796a3c711b6b49df20f95d9bc198d6c51" };
|
|
6
6
|
|
|
7
7
|
// <define:__CODEARBITER_PI_TOOL_CLASSES__>
|
|
8
8
|
var define_CODEARBITER_PI_TOOL_CLASSES_default = { bash: "EXEC", codearbiter_background_bash: "EXEC", codearbiter_dispatch: "EXEC", codearbiter_farm_preview: "EXEC", write: "WRITE", edit: "EDIT", read: "READ" };
|
|
@@ -16,7 +16,7 @@ import { fileURLToPath as fileURLToPath5, pathToFileURL as pathToFileURL2 } from
|
|
|
16
16
|
import { types as utilTypes9 } from "node:util";
|
|
17
17
|
|
|
18
18
|
// src/compatibility.ts
|
|
19
|
-
var SUPPORTED_PI_VERSIONS = /* @__PURE__ */ new Set(["1.0
|
|
19
|
+
var SUPPORTED_PI_VERSIONS = /* @__PURE__ */ new Set(["1.1.0"]);
|
|
20
20
|
var MINIMUM_NODE = [22, 19, 0];
|
|
21
21
|
var SEMVER_PREFIX = /^(\d+)\.(\d+)\.(\d+)(?:$|[-+])/u;
|
|
22
22
|
function atLeast(version, minimum) {
|
|
@@ -31,7 +31,7 @@ function atLeast(version, minimum) {
|
|
|
31
31
|
}
|
|
32
32
|
function compatibilityDirection(input) {
|
|
33
33
|
if (!SUPPORTED_PI_VERSIONS.has(input.piVersion)) {
|
|
34
|
-
return "codeArbiter requires Pi 1.0
|
|
34
|
+
return "codeArbiter requires Pi 1.1.0; install a supported Pi version and run /ca-doctor.";
|
|
35
35
|
}
|
|
36
36
|
if (!atLeast(input.nodeVersion, MINIMUM_NODE)) {
|
|
37
37
|
return "codeArbiter requires Node >=22.19.0 for Pi; upgrade Node and run /ca-doctor.";
|
|
@@ -6881,10 +6881,10 @@ async function collectPiDoctorInput(dependencies) {
|
|
|
6881
6881
|
var REMEDIATION = {
|
|
6882
6882
|
package: "Reinstall ca-pi from the approved pinned Git tag, then restart Pi.",
|
|
6883
6883
|
trust: "Run /trust in Pi, inspect the project, grant trust only if you accept it, then start a new session.",
|
|
6884
|
-
version: "Upgrade Pi to 1.0
|
|
6884
|
+
version: "Upgrade Pi to 1.1.0 and Node to >=22.19.0, then restart Pi.",
|
|
6885
6885
|
python: "Upgrade or install Python 3, then run /ca-doctor again.",
|
|
6886
6886
|
core: "Reinstall ca-pi to restore the generated shared core, then run /ca-doctor again.",
|
|
6887
|
-
commands: "Remove conflicting command owners or run Pi 1.0
|
|
6887
|
+
commands: "Remove conflicting command owners or run Pi 1.1.0, then restart Pi and run /ca-doctor.",
|
|
6888
6888
|
bridge: "Reinstall ca-pi and Python 3, then run /ca-doctor again.",
|
|
6889
6889
|
child: "Reinstall ca-pi if the hardened child artifact is missing or tampered, then run /ca-doctor again.",
|
|
6890
6890
|
"ambient-marker": "Remove CODEARBITER_SUBAGENT from the parent environment and restart Pi.",
|
|
@@ -6913,7 +6913,7 @@ function diagnosePi(input) {
|
|
|
6913
6913
|
const packageHealthy = input.package.declared && input.package.name === "@arbiterforge/ca-pi" && existsSync(input.package.root) && existsSync(input.package.extensionPath) && samePath2(input.package.extensionPath, expectedExtension) && canonicallyInside(input.package.extensionPath, input.package.root);
|
|
6914
6914
|
const trustHealthy = input.trust.inspected && (!input.trust.required || input.trust.projectTrusted);
|
|
6915
6915
|
const waitingForTrust = input.trust.required && !input.trust.projectTrusted;
|
|
6916
|
-
const versionHealthy = input.runtime.piVersion === "1.0
|
|
6916
|
+
const versionHealthy = input.runtime.piVersion === "1.1.0" && atLeast(input.runtime.nodeVersion, [22, 19, 0]);
|
|
6917
6917
|
const piBelowMinimum = !atLeast(input.runtime.piVersion, [0, 80, 5]);
|
|
6918
6918
|
const supportedExpansion = input.commands.expansionVerifiedVersions.includes(input.runtime.piVersion);
|
|
6919
6919
|
const expectedDoctorSkill = resolve9(input.package.root, "skills", "ca-doctor", "SKILL.md");
|
|
@@ -7034,7 +7034,7 @@ function diagnosePi(input) {
|
|
|
7034
7034
|
{
|
|
7035
7035
|
id: "active-dispatch",
|
|
7036
7036
|
state: "degraded",
|
|
7037
|
-
message: "Supported Pi 1.0
|
|
7037
|
+
message: "Supported Pi 1.1.0 public extension APIs cannot submit this deterministic self-test through the active dispatcher; the wrapper self-test does not exercise active dispatch.",
|
|
7038
7038
|
remediation: REMEDIATION["active-dispatch"]
|
|
7039
7039
|
}
|
|
7040
7040
|
];
|
|
@@ -7806,6 +7806,7 @@ var PI_PROVIDER_ENV = Object.freeze({
|
|
|
7806
7806
|
"amazon-bedrock": ["AWS_PROFILE", "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_BEARER_TOKEN_BEDROCK", "AWS_REGION"],
|
|
7807
7807
|
"ant-ling": ["ANT_LING_API_KEY"],
|
|
7808
7808
|
anthropic: ["ANTHROPIC_OAUTH_TOKEN", "ANTHROPIC_API_KEY"],
|
|
7809
|
+
azure: ["AZURE_OPENAI_API_KEY", "AZURE_OPENAI_BASE_URL", "AZURE_OPENAI_RESOURCE_NAME", "AZURE_OPENAI_API_VERSION", "AZURE_OPENAI_DEPLOYMENT_NAME_MAP"],
|
|
7809
7810
|
"azure-openai-responses": ["AZURE_OPENAI_API_KEY", "AZURE_OPENAI_BASE_URL", "AZURE_OPENAI_RESOURCE_NAME", "AZURE_OPENAI_API_VERSION", "AZURE_OPENAI_DEPLOYMENT_NAME_MAP"],
|
|
7810
7811
|
cerebras: ["CEREBRAS_API_KEY"],
|
|
7811
7812
|
"cloudflare-ai-gateway": ["CLOUDFLARE_API_KEY", "CLOUDFLARE_ACCOUNT_ID", "CLOUDFLARE_GATEWAY_ID"],
|
|
@@ -8351,16 +8352,16 @@ function validMessage(value) {
|
|
|
8351
8352
|
if (value.role === "assistant") {
|
|
8352
8353
|
return exactKeys4(
|
|
8353
8354
|
value,
|
|
8354
|
-
["role", "content", "api", "provider", "model", "responseModel", "responseId", "providerThinkingLevel", "thinkingLevel", "diagnostics", "usage", "stopReason", "errorMessage", "rawStopReason", "deferred", "endTurn", "timestamp"],
|
|
8355
|
+
["role", "content", "api", "provider", "model", "responseModel", "responseId", "providerThinkingLevel", "thinkingLevel", "diagnostics", "usage", "stopReason", "errorMessage", "rawStopReason", "deferred", "endTurn", "timestamp", "durationMs"],
|
|
8355
8356
|
["role", "content", "api", "provider", "model", "usage", "stopReason", "timestamp"]
|
|
8356
|
-
) && validContent(value.content, "assistant") && ["api", "provider", "model", "stopReason"].every((key) => typeof value[key] === "string") && (value.responseModel === void 0 || boundedString2(value.responseModel)) && (value.responseId === void 0 || boundedString2(value.responseId)) && (value.errorMessage === void 0 || boundedString2(value.errorMessage)) && (value.rawStopReason === void 0 || boundedString2(value.rawStopReason)) && (value.providerThinkingLevel === void 0 || boundedString2(value.providerThinkingLevel)) && (value.thinkingLevel === void 0 || boundedString2(value.thinkingLevel)) && (value.endTurn === void 0 || typeof value.endTurn === "boolean") && (value.deferred === void 0 || validDeferredHandle(value.deferred)) && (value.diagnostics === void 0 || Array.isArray(value.diagnostics) && value.diagnostics.length <= MAX_JSON_ARRAY && value.diagnostics.every(validDiagnostic)) && validUsage(value.usage) && typeof value.timestamp === "number" && Number.isFinite(value.timestamp);
|
|
8357
|
+
) && validContent(value.content, "assistant") && ["api", "provider", "model", "stopReason"].every((key) => typeof value[key] === "string") && (value.responseModel === void 0 || boundedString2(value.responseModel)) && (value.responseId === void 0 || boundedString2(value.responseId)) && (value.errorMessage === void 0 || boundedString2(value.errorMessage)) && (value.rawStopReason === void 0 || boundedString2(value.rawStopReason)) && (value.providerThinkingLevel === void 0 || boundedString2(value.providerThinkingLevel)) && (value.thinkingLevel === void 0 || boundedString2(value.thinkingLevel)) && (value.endTurn === void 0 || typeof value.endTurn === "boolean") && (value.durationMs === void 0 || typeof value.durationMs === "number" && Number.isFinite(value.durationMs) && value.durationMs >= 0) && (value.deferred === void 0 || validDeferredHandle(value.deferred)) && (value.diagnostics === void 0 || Array.isArray(value.diagnostics) && value.diagnostics.length <= MAX_JSON_ARRAY && value.diagnostics.every(validDiagnostic)) && validUsage(value.usage) && typeof value.timestamp === "number" && Number.isFinite(value.timestamp);
|
|
8357
8358
|
}
|
|
8358
8359
|
if (value.role === "toolResult") {
|
|
8359
8360
|
return exactKeys4(
|
|
8360
8361
|
value,
|
|
8361
|
-
["role", "toolCallId", "toolName", "content", "details", "isError", "usage", "nestedCalls", "timestamp"],
|
|
8362
|
+
["role", "toolCallId", "toolName", "content", "details", "isError", "usage", "nestedCalls", "timestamp", "durationMs"],
|
|
8362
8363
|
["role", "toolCallId", "toolName", "content", "isError", "timestamp"]
|
|
8363
|
-
) && typeof value.toolCallId === "string" && typeof value.toolName === "string" && validContent(value.content, "toolResult") && (value.details === void 0 || validOpaqueJson(value.details)) && (value.usage === void 0 || validUsage(value.usage)) && (value.nestedCalls === void 0 || validNestedCalls(value.nestedCalls)) && typeof value.isError === "boolean" && typeof value.timestamp === "number" && Number.isFinite(value.timestamp);
|
|
8364
|
+
) && typeof value.toolCallId === "string" && typeof value.toolName === "string" && validContent(value.content, "toolResult") && (value.details === void 0 || validOpaqueJson(value.details)) && (value.usage === void 0 || validUsage(value.usage)) && (value.nestedCalls === void 0 || validNestedCalls(value.nestedCalls)) && (value.durationMs === void 0 || typeof value.durationMs === "number" && Number.isFinite(value.durationMs) && value.durationMs >= 0) && typeof value.isError === "boolean" && typeof value.timestamp === "number" && Number.isFinite(value.timestamp);
|
|
8364
8365
|
}
|
|
8365
8366
|
return false;
|
|
8366
8367
|
}
|
|
@@ -8449,10 +8450,12 @@ function parseChildJsonLine(line) {
|
|
|
8449
8450
|
} else if (!exactKeys4(record2, ["type", "id", "command", "success", "error"]) || typeof record2.error !== "string") invalidProtocol();
|
|
8450
8451
|
break;
|
|
8451
8452
|
case "agent_start":
|
|
8452
|
-
case "agent_settled":
|
|
8453
8453
|
case "turn_start":
|
|
8454
8454
|
if (!exactKeys4(record2, ["type"])) invalidProtocol();
|
|
8455
8455
|
break;
|
|
8456
|
+
case "agent_settled":
|
|
8457
|
+
if (!exactKeys4(record2, ["type", "aborted"]) || typeof record2.aborted !== "boolean") invalidProtocol();
|
|
8458
|
+
break;
|
|
8456
8459
|
case "agent_end":
|
|
8457
8460
|
if (!exactKeys4(record2, ["type", "messages", "willRetry"]) || !Array.isArray(record2.messages) || record2.messages.length > MAX_JSON_ARRAY || !record2.messages.every(validMessage) || typeof record2.willRetry !== "boolean") invalidProtocol();
|
|
8458
8461
|
break;
|
|
@@ -8473,7 +8476,7 @@ function parseChildJsonLine(line) {
|
|
|
8473
8476
|
if (!exactKeys4(record2, ["type", "toolCallId", "toolName", "args", "partialResult", "parentToolCallId"], ["type", "toolCallId", "toolName", "args", "partialResult"]) || record2.parentToolCallId !== void 0 && !boundedString2(record2.parentToolCallId) || typeof record2.toolCallId !== "string" || typeof record2.toolName !== "string" || !validOpaqueJson(record2.args) || !validOpaqueJson(record2.partialResult)) invalidProtocol();
|
|
8474
8477
|
break;
|
|
8475
8478
|
case "tool_execution_end":
|
|
8476
|
-
if (!exactKeys4(record2, ["type", "toolCallId", "toolName", "result", "isError", "parentToolCallId"], ["type", "toolCallId", "toolName", "result", "isError"]) || record2.parentToolCallId !== void 0 && !boundedString2(record2.parentToolCallId) || typeof record2.toolCallId !== "string" || typeof record2.toolName !== "string" || !validOpaqueJson(record2.result) || typeof record2.isError !== "boolean") invalidProtocol();
|
|
8479
|
+
if (!exactKeys4(record2, ["type", "toolCallId", "toolName", "result", "isError", "parentToolCallId", "durationMs"], ["type", "toolCallId", "toolName", "result", "isError"]) || record2.parentToolCallId !== void 0 && !boundedString2(record2.parentToolCallId) || record2.durationMs !== void 0 && (typeof record2.durationMs !== "number" || !Number.isFinite(record2.durationMs) || record2.durationMs < 0) || typeof record2.toolCallId !== "string" || typeof record2.toolName !== "string" || !validOpaqueJson(record2.result) || typeof record2.isError !== "boolean") invalidProtocol();
|
|
8477
8480
|
break;
|
|
8478
8481
|
case "extension_error":
|
|
8479
8482
|
if (!exactKeys4(record2, ["type", "extensionPath", "event", "error"]) || typeof record2.extensionPath !== "string" || typeof record2.event !== "string" || typeof record2.error !== "string") invalidProtocol();
|
|
@@ -8773,6 +8776,10 @@ async function runPiChild(request, signal) {
|
|
|
8773
8776
|
finishFailure("protocol_error");
|
|
8774
8777
|
return;
|
|
8775
8778
|
}
|
|
8779
|
+
if (record2.aborted === true) {
|
|
8780
|
+
finishFailure("cancelled");
|
|
8781
|
+
return;
|
|
8782
|
+
}
|
|
8776
8783
|
phase = "complete";
|
|
8777
8784
|
endInput();
|
|
8778
8785
|
} else {
|
|
@@ -10598,7 +10605,7 @@ async function codeArbiterPi(pi) {
|
|
|
10598
10605
|
activeTools: pi.getActiveTools(),
|
|
10599
10606
|
allTools: pi.getAllTools(),
|
|
10600
10607
|
expansionFingerprints,
|
|
10601
|
-
childFingerprint: "
|
|
10608
|
+
childFingerprint: "98a945a0d55cc25f75a50bbe7c94cbea192b81f3db44fd9b3133d977a2973430"
|
|
10602
10609
|
});
|
|
10603
10610
|
const wrapperSelfTest = await runPiWrapperSelfTest({
|
|
10604
10611
|
enabled: enabledForDoctor,
|
|
@@ -37,11 +37,11 @@
|
|
|
37
37
|
},
|
|
38
38
|
"context_qualification": {
|
|
39
39
|
"darwin/amd64": {
|
|
40
|
-
"source_commit": "
|
|
40
|
+
"source_commit": "6a243348a0e74b0a50c37eccf4d61520129a5c1c",
|
|
41
41
|
"workflow": ".github/workflows/ci.yml",
|
|
42
|
-
"run_id": "
|
|
42
|
+
"run_id": "37938394077",
|
|
43
43
|
"binary_sha256": "433780fa59913512346069f9e1891e306a8bec41ed6fcc7cd26b50748d03ae06",
|
|
44
|
-
"observation_sha256": "
|
|
44
|
+
"observation_sha256": "017903dc1173484279e8029e5edee028cd81d1eb71c60e706b0476d7ea1d0e42",
|
|
45
45
|
"module_sha256": "421b4db5fa1afc9a8620c5538161d8b23f193d6a1042ad1c5aa004facdd77844",
|
|
46
46
|
"native_cases": [
|
|
47
47
|
"TestContextBoundedRender",
|
|
@@ -53,11 +53,11 @@
|
|
|
53
53
|
]
|
|
54
54
|
},
|
|
55
55
|
"darwin/arm64": {
|
|
56
|
-
"source_commit": "
|
|
56
|
+
"source_commit": "6a243348a0e74b0a50c37eccf4d61520129a5c1c",
|
|
57
57
|
"workflow": ".github/workflows/ci.yml",
|
|
58
|
-
"run_id": "
|
|
58
|
+
"run_id": "37938394077",
|
|
59
59
|
"binary_sha256": "b68192c7a1da2cd2f9031f71ab4c7e015673f060d6bfdfa3aa4b57d9f090bf34",
|
|
60
|
-
"observation_sha256": "
|
|
60
|
+
"observation_sha256": "28682b5ece3e695125587ff8578d22ce5ccd75f6643f626b64246bc7dd664716",
|
|
61
61
|
"module_sha256": "421b4db5fa1afc9a8620c5538161d8b23f193d6a1042ad1c5aa004facdd77844",
|
|
62
62
|
"native_cases": [
|
|
63
63
|
"TestContextBoundedRender",
|
|
@@ -69,11 +69,11 @@
|
|
|
69
69
|
]
|
|
70
70
|
},
|
|
71
71
|
"linux/amd64": {
|
|
72
|
-
"source_commit": "
|
|
72
|
+
"source_commit": "6a243348a0e74b0a50c37eccf4d61520129a5c1c",
|
|
73
73
|
"workflow": ".github/workflows/ci.yml",
|
|
74
|
-
"run_id": "
|
|
74
|
+
"run_id": "37938394077",
|
|
75
75
|
"binary_sha256": "09582eabdef3f828a12de21b85ccc7b52a188651c2a4f69f3f776a2e62c86036",
|
|
76
|
-
"observation_sha256": "
|
|
76
|
+
"observation_sha256": "0782dc40b8b03584b6f048204234fbf3896e0ee33ebfb52da4b72237d18679a6",
|
|
77
77
|
"module_sha256": "421b4db5fa1afc9a8620c5538161d8b23f193d6a1042ad1c5aa004facdd77844",
|
|
78
78
|
"native_cases": [
|
|
79
79
|
"TestContextBoundedRender",
|
|
@@ -85,11 +85,11 @@
|
|
|
85
85
|
]
|
|
86
86
|
},
|
|
87
87
|
"linux/arm64": {
|
|
88
|
-
"source_commit": "
|
|
88
|
+
"source_commit": "6a243348a0e74b0a50c37eccf4d61520129a5c1c",
|
|
89
89
|
"workflow": ".github/workflows/ci.yml",
|
|
90
|
-
"run_id": "
|
|
90
|
+
"run_id": "37938394077",
|
|
91
91
|
"binary_sha256": "f7699ce8f2f07200ea8508f21a6d369506443392aa8897d84e9d5e7dd6469770",
|
|
92
|
-
"observation_sha256": "
|
|
92
|
+
"observation_sha256": "451808d71946bed78727672d0c8ed94903eb9179a3907dd86248c1885eb7b094",
|
|
93
93
|
"module_sha256": "421b4db5fa1afc9a8620c5538161d8b23f193d6a1042ad1c5aa004facdd77844",
|
|
94
94
|
"native_cases": [
|
|
95
95
|
"TestContextBoundedRender",
|
|
@@ -101,11 +101,11 @@
|
|
|
101
101
|
]
|
|
102
102
|
},
|
|
103
103
|
"windows/amd64": {
|
|
104
|
-
"source_commit": "
|
|
104
|
+
"source_commit": "6a243348a0e74b0a50c37eccf4d61520129a5c1c",
|
|
105
105
|
"workflow": ".github/workflows/ci.yml",
|
|
106
|
-
"run_id": "
|
|
106
|
+
"run_id": "37938394077",
|
|
107
107
|
"binary_sha256": "9a0f186e2a1bcfd92c8f9db5cb0aa2f6dfb128dd6f0dad2708a78596f0364e16",
|
|
108
|
-
"observation_sha256": "
|
|
108
|
+
"observation_sha256": "336b9ea6f4b53b2aaa98cf5ee47f7d2792e2ece09eaafef8f37b0ae51c222275",
|
|
109
109
|
"module_sha256": "421b4db5fa1afc9a8620c5538161d8b23f193d6a1042ad1c5aa004facdd77844",
|
|
110
110
|
"native_cases": [
|
|
111
111
|
"TestContextBoundedRender",
|
|
@@ -117,11 +117,11 @@
|
|
|
117
117
|
]
|
|
118
118
|
},
|
|
119
119
|
"windows/arm64": {
|
|
120
|
-
"source_commit": "
|
|
120
|
+
"source_commit": "6a243348a0e74b0a50c37eccf4d61520129a5c1c",
|
|
121
121
|
"workflow": ".github/workflows/ci.yml",
|
|
122
|
-
"run_id": "
|
|
122
|
+
"run_id": "37938394077",
|
|
123
123
|
"binary_sha256": "3f1bc7d00f9488b4a4a9f21e5ca414fd5c97031ad7b1c2b52c02f5d7f2956e3a",
|
|
124
|
-
"observation_sha256": "
|
|
124
|
+
"observation_sha256": "817414c35d85c544d9554544af86fc14aa11f866f0df0f6fe28f64adda5bfe1a",
|
|
125
125
|
"module_sha256": "421b4db5fa1afc9a8620c5538161d8b23f193d6a1042ad1c5aa004facdd77844",
|
|
126
126
|
"native_cases": [
|
|
127
127
|
"TestContextBoundedRender",
|
|
@@ -349,13 +349,23 @@ def _resolve_live_dir(path):
|
|
|
349
349
|
# semantics like `_path_form_candidates` on POSIX -- embedded verbatim into
|
|
350
350
|
# every generated shim so the REAL git-hook execution path (not just Python
|
|
351
351
|
# diagnostics) resolves a foreign-but-translatable spelling instead of
|
|
352
|
-
# failing closed on it.
|
|
353
|
-
#
|
|
354
|
-
#
|
|
352
|
+
# failing closed on it. POSIX shell builtins only: the trusted-identity path
|
|
353
|
+
# must also work when PATH contains no trusted utilities (ADR-0015).
|
|
354
|
+
# Prints the resolved path and returns 0 on the
|
|
355
355
|
# first candidate that exists; returns 1 with nothing printed when NONE of
|
|
356
356
|
# the (as-is, plus up to two translated) candidates resolves -- callers must
|
|
357
357
|
# treat that as "does not exist," preserving ADR-0014's fail-closed contract.
|
|
358
|
+
_CX_DRIVE_CASE_SH = "".join(
|
|
359
|
+
f" {letter.lower()}|{letter}) DRL={letter.lower()}; DRU={letter} ;;\n"
|
|
360
|
+
for letter in "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
361
|
+
)
|
|
358
362
|
_CX_RESOLVE_SH = (
|
|
363
|
+
"_cx_drive_case() {\n"
|
|
364
|
+
' case "$1" in\n'
|
|
365
|
+
f"{_CX_DRIVE_CASE_SH}"
|
|
366
|
+
" *) return 1 ;;\n"
|
|
367
|
+
" esac\n"
|
|
368
|
+
"}\n"
|
|
359
369
|
"_cx_resolve() {\n"
|
|
360
370
|
" P=$1\n"
|
|
361
371
|
" K=-f\n"
|
|
@@ -364,17 +374,15 @@ _CX_RESOLVE_SH = (
|
|
|
364
374
|
" /mnt/[A-Za-z]/*)\n"
|
|
365
375
|
' [ "$K" "$P" ] && { printf \'%s\' "$P"; return 0; }\n'
|
|
366
376
|
' REST=${P#/mnt/?/}\n'
|
|
367
|
-
' DR=$
|
|
368
|
-
'
|
|
369
|
-
' DRU=$(printf \'%s\' "$DR" | tr \'a-z\' \'A-Z\')\n'
|
|
377
|
+
' DR=${P#/mnt/}; DR=${DR%%/*}\n'
|
|
378
|
+
' _cx_drive_case "$DR" || return 1\n'
|
|
370
379
|
' A1="/$DRL/$REST"; A2="$DRU:/$REST"\n'
|
|
371
380
|
" ;;\n"
|
|
372
381
|
" /[A-Za-z]/*)\n"
|
|
373
382
|
' [ "$K" "$P" ] && { printf \'%s\' "$P"; return 0; }\n'
|
|
374
383
|
' REST=${P#/?/}\n'
|
|
375
|
-
' DR=$
|
|
376
|
-
'
|
|
377
|
-
' DRU=$(printf \'%s\' "$DR" | tr \'a-z\' \'A-Z\')\n'
|
|
384
|
+
' DR=${P#/}; DR=${DR%%/*}\n'
|
|
385
|
+
' _cx_drive_case "$DR" || return 1\n'
|
|
378
386
|
' A1="/mnt/$DRL/$REST"; A2="$DRU:/$REST"\n'
|
|
379
387
|
" ;;\n"
|
|
380
388
|
" [A-Za-z]:/*)\n"
|
|
@@ -387,7 +395,8 @@ _CX_RESOLVE_SH = (
|
|
|
387
395
|
" # Git-Bash resolves this same spelling too, but via A1 (\"/<drive>/\n"
|
|
388
396
|
" # ...\"), which Git-Bash ALSO resolves -- so nothing is lost by\n"
|
|
389
397
|
" # withholding the raw as-is test for this one grammar.\n"
|
|
390
|
-
' DR=$
|
|
398
|
+
' DR=${P%%:*}\n'
|
|
399
|
+
' _cx_drive_case "$DR" || return 1\n'
|
|
391
400
|
" # ??: (two wildcards, literal colon) never matches a drive-letter\n"
|
|
392
401
|
" # path like C:/... (its 3rd char is / , not the required literal\n"
|
|
393
402
|
" # ':'), so it left REST completely unstripped -- a confirmed\n"
|
|
@@ -396,7 +405,7 @@ _CX_RESOLVE_SH = (
|
|
|
396
405
|
" # correct 3-char match for this branch's own case pattern.\n"
|
|
397
406
|
' REST=${P#?:/}\n'
|
|
398
407
|
' REST=${REST#/}\n'
|
|
399
|
-
' A1="/$
|
|
408
|
+
' A1="/$DRL/$REST"; A2="/mnt/$DRL/$REST"\n'
|
|
400
409
|
" ;;\n"
|
|
401
410
|
" *)\n"
|
|
402
411
|
' [ "$K" "$P" ] && { printf \'%s\' "$P"; return 0; }\n'
|
|
@@ -801,14 +810,15 @@ def _shim(dropin_dir, phase):
|
|
|
801
810
|
f"{_FRESHNESS_PY}"
|
|
802
811
|
"CODEARBITER_556_FRESHNESS\n"
|
|
803
812
|
")\n"
|
|
804
|
-
# Match
|
|
805
|
-
"
|
|
813
|
+
# Match whole LF/CRLF lines without executing a PATH-resolved utility.
|
|
814
|
+
"CR=$(printf '\\r')\n"
|
|
815
|
+
"NL='\n'\n"
|
|
806
816
|
"SEEN=0\n"
|
|
807
817
|
'for c in "$D"/*.path; do\n'
|
|
808
818
|
' [ -f "$c" ] || continue\n'
|
|
809
819
|
' N=${c##*/}\n'
|
|
810
820
|
' case "$N" in [0-9]*.[0-9]*.[0-9]*.path) continue ;; esac\n'
|
|
811
|
-
' case "
|
|
821
|
+
' case "$NL$SKIP$NL" in *"$NL${N%.path}$NL"*|*"$NL${N%.path}$CR$NL"*) continue ;; esac\n'
|
|
812
822
|
' IFS= read -r E < "$c" || continue\n'
|
|
813
823
|
' E=$(_cx_resolve "$E") || continue\n'
|
|
814
824
|
' SEEN=1\n'
|
|
@@ -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.17.
|
|
14
|
+
adapter_version = "0.17.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"
|
|
@@ -313,7 +313,7 @@ class Host:
|
|
|
313
313
|
|
|
314
314
|
name = "claude"
|
|
315
315
|
adapter_name = "ca"
|
|
316
|
-
adapter_version = "2.25.
|
|
316
|
+
adapter_version = "2.25.3"
|
|
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,
|
|
@@ -87,7 +87,7 @@ file maps those actions to Pi's extension API.
|
|
|
87
87
|
operator-launched Pi CLI, imported module, package root, and reported version.
|
|
88
88
|
It does not prove publisher authenticity. Verify the source separately with
|
|
89
89
|
`pi list` and `pi config`.
|
|
90
|
-
- The supported promotion target is exact Pi 1.0.
|
|
90
|
+
- The supported promotion target is exact Pi 1.1.0. The package is
|
|
91
91
|
published as `npm:@arbiterforge/ca-pi` on every `ca-pi-v*` tag (ADR-0029);
|
|
92
92
|
the pinned Git tag remains the reproducible install. A Pi-native embedded
|
|
93
93
|
farm worker is a future spike, not an installed dependency.
|
|
@@ -32,7 +32,7 @@ repository binary, mutate an artifact, or silently fall back to Markdown.
|
|
|
32
32
|
Pi bash wrapper. The exact shared-core `[H-03]` block is healthy and cannot stage files; execution
|
|
33
33
|
or a different block is unhealthy. This self-test does not traverse Pi's active dispatcher. Do not
|
|
34
34
|
rerun or respell it.
|
|
35
|
-
4. Its `active-dispatch` row remains degraded because supported Pi 1.0
|
|
35
|
+
4. Its `active-dispatch` row remains degraded because supported Pi 1.1.0 public extension
|
|
36
36
|
APIs cannot submit that deterministic call through the active dispatcher. PI-AC-28 remains blocked
|
|
37
37
|
until supported-version real-host promotion/CI evidence closes the gap.
|
|
38
38
|
5. Resolve Python once, run `<plugin-root>/hooks/doctor.py`, and present its mechanical report
|