feat(runner): add pinned Kimi Code native runtime (#18028)

Add the pinned Kimi Code runtime, native instruction and model admission, scoped credentials, and pending-candidate recovery contracts. Retain current master release attestations and provider-pack compatibility.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip authored and GitHub committed 2026-10-30 21:58:12 -05:00
1 parent 909e29dd07
commit b866fa4bdc
111 files changed
+7180 -249

No files matched your search

+8
View File
@@ -48,3 +48,11 @@ packages/grok-acp/bin
# Images build their pinned Copilot assets instead of copying host binaries.
/packages/paperclip-runner/provider-assets/
/server/provider-assets/
!packages/paperclip-runner/test/fixtures/kimi-profile-v*-identity.json
!packages/paperclip-runner/test/fixtures/grok-profile-v*-identity.json
!packages/paperclip-runner/test/fixtures/copilot-profile-v*-identity.json
!packages/paperclip-runner/test-fixtures/pi-acp/profile-v34-identity.json
@@ -12,6 +12,10 @@ import {
} from "./paperclip-runner-permissions.js";
describe("Paperclip Runner permission defaults", () => {
it("keeps Kimi Code pending with an explicit runtime credential", () => {
expect(PAPERCLIP_RUNNER_ACPX_PROFILES.find(profile => profile.value === "kimi"))
.toMatchObject({ qualified: false, credentialEnvironment: ["KIMI_API_KEY"] });
});
it("marks Pi and Copilot qualified with their provider credential bindings", () => {
expect(PAPERCLIP_RUNNER_ACPX_PROFILES.find(profile => profile.value === "pi"))
.toMatchObject({ qualified: true, credentialEnvironment: expect.arrayContaining(["OPENROUTER_API_KEY", "OPENAI_API_KEY", "ANTHROPIC_API_KEY", "GEMINI_API_KEY"]) });
@@ -253,6 +253,7 @@ export const PAPERCLIP_RUNNER_ACPX_PROFILES = Object.freeze([
{ value: "cursor", label: "Cursor", qualified: true, credentialEnvironment: ["CURSOR_API_KEY", "CURSOR_AUTH_TOKEN"] },
{ value: "copilot", label: "GitHub Copilot", qualified: true, credentialEnvironment: ["COPILOT_GITHUB_TOKEN"] },
{ value: "pi", label: "Pi", qualified: true, credentialEnvironment: ["OPENROUTER_API_KEY", "OPENAI_API_KEY", "ANTHROPIC_API_KEY", "GEMINI_API_KEY"] },
{ value: "kimi", label: "Kimi Code", qualified: false, credentialEnvironment: ["KIMI_API_KEY"] },
{ value: "antigravity", label: "Google Antigravity", qualified: false, credentialEnvironment: ["GEMINI_API_KEY"] },
] as const);
+28
View File
@@ -981,6 +981,34 @@ while daemon work might still be running. The socket and its parent must be priv
canonical paths owned by the same account. Local stdio assignment requires Unix;
other platforms retain the HTTP path.
## Kimi Code candidate
Kimi Code uses the pinned `@moonshot-ai/kimi-code@2.3.3` distribution through
ACPX. Candidate support is pending local and Daytona Product E2E qualification.
The installation targets are macOS ARM64 and Linux x64. Platform startup,
authenticated driver checks, and product acceptance are separate evidence levels.
Run `paperclipai runtime setup kimi` on the execution host to install its complete
verified runtime. Setup downloads public pinned dependencies without model calls
or provider credentials. An invalid existing installation fails without ambient
Kimi fallback. Bind a company secret as `KIMI_API_KEY` and select an exact model.
This release uses the global Code endpoint at `https://api.kimi.ai/coding/v1`.
Model suggestions are empty; a compatible typed model is decided by the provider.
The account needs Kimi Code entitlement. Runtime Test verifies installation and
queries the authenticated Code model catalog for the exact selected model. It
sends no model prompt; an actual task verifies inference and tool execution.
The ordinary hiring path stays hidden while qualification is pending. Existing
legacy Kimi agents retain their runtime and history. Managed Kimi connections,
ambient login borrowing, other regions/platforms, steering, native child work,
and per-run token/dollar accounting are outside this release. Read-only Kimi work
uses scoped Paperclip tools; native filesystem and shell tools are denied.
The provider-owned patch binds native instructions, preserves permission arguments,
and removes provider auth from tool subprocesses. See the
[protocol dossier](src/providers/kimi/README.md) and
[release ledger](../../doc/plans/2026-10-28-kimi-code-runner-integration.md) for
current evidence and limits.
## ACPX controller replacement regression tests
`src/control-plane/acpx-controller-recovery.test.ts` runs the production Rust
@@ -67,6 +67,16 @@
"agentRuntimeVersion": "0.160.0",
"commandDigest": "sha256:443491f4e814501a5dc47347e4510e84faeec9c9382e2d4e53bfe69386d5aabc",
"requiresProviderPolicy": false
},
"kimi": {
"agentProfileVersion": 16,
"agentServerPackage": "@moonshot-ai/kimi-code",
"agentServerVersion": "2.3.3",
"agentRuntimePackage": null,
"agentRuntimeVersion": null,
"commandDigest": "sha256:0c1e6ce460407ec973a37a2d192d665fcde744e2b9875c791c90308afbf4c52b",
"requiresProviderPolicy": true,
"qualificationStatus": "pending"
}
}
}
@@ -80,7 +80,7 @@ Each provider declares how in `ACPX_RELEASE_ATTESTATIONS`
| --- | --- | --- |
| `installed-command` | Claude, Codex | the upstream package's launch command, hashed at installation |
| `launcher` | Grok | the SHA-256 of the launcher shipped verbatim |
| `closure` | Copilot, Pi | upstream versions and the complete platform closure pins |
| `closure` | Copilot, Pi, Kimi | upstream versions and the complete platform closure pins |
| `declaration` | Cursor, Antigravity | a checked-in release declaration, as canonical JSON |
`generate:acpx-profiles` writes the computed digests and `check:acpx-profiles`
@@ -127,6 +127,11 @@ An administrator-owned read-only Runner can therefore use a user-writable cache,
but this provides weaker protection against that same user than hashing every
executable on each admission. Removing the cache restores full hashing.
Kimi keeps revision 16 from its pending candidate history. Its release
attestation replaces the earlier source-bound digest without advancing that
revision. Historical candidate records stay readable, while exact current
digest admission refuses their old launch identities. Kimi remains pending.
## External controller checkpoints
The optional controller persistence callback stores recovery control state, not
+1 -1
View File
@@ -85,7 +85,7 @@
"typecheck:browser": "tsc -p tsconfig.browser.json --noEmit",
"test": "pnpm run test:typescript && pnpm run test:rust",
"test:typescript": "pnpm run test:typescript:prep && vitest run",
"test:typescript:prep": "pnpm run ensure:eval-build-deps && pnpm run build:rust && node ../../scripts/ci-profile/node-test.mjs test/protocol-contract.test.mjs test/acpx-sidecar-contract.test.mjs test/acpx-codex-package-contract.test.mjs test/acpx-model-selection-package-contract.test.mjs test/acpx-message-boundaries-package-contract.test.mjs test/acpx-rich-extensions-package-contract.test.mjs test/acpx-pi-receipt-package-contract.test.mjs test/acpx-response-delivery-package-contract.test.mjs scripts/candidate-provider-pack.test.mjs scripts/materialize-pi-distribution.test.mjs scripts/cursor-provisioner-layout.test.mjs scripts/release-provider-pack.test.mjs scripts/acpx-release-attestations.test.mjs scripts/provider-pack-runtime-tree.test.mjs scripts/aws-agentcore-provisioning.test.mjs scripts/build-verified-provider-entrypoints.test.mjs scripts/local-provider-smoke-environment.test.mjs scripts/materialize-opencode-binary.test.mjs scripts/installed-package-pack.test.mjs scripts/runner-runtime-dependency-roots.test.mjs scripts/runner-package-executable.test.mjs scripts/stage-runner-binary.test.mjs scripts/build-inputs.test.mjs scripts/contracts/contract-fingerprints.test.mjs scripts/provider-pack-executable-shims.test.mjs scripts/controlled-evals/controller.test.mjs scripts/controlled-evals/portable.test.mjs && node --test scripts/build-copilot-distribution.test.mjs scripts/copilot-inner-distribution.test.mjs scripts/copilot-smoke-resources.test.mjs scripts/discover-copilot-acp.test.mjs scripts/materialize-copilot-binary.test.mjs scripts/install-copilot-assets.test.mjs scripts/probe-copilot-acp.test.mjs scripts/qualify-copilot-acp.test.mjs test/acpx-message-boundaries-package-contract.test.mjs",
"test:typescript:prep": "pnpm run ensure:eval-build-deps && pnpm run build:rust && node ../../scripts/ci-profile/node-test.mjs test/protocol-contract.test.mjs test/acpx-sidecar-contract.test.mjs test/acpx-codex-package-contract.test.mjs test/acpx-model-selection-package-contract.test.mjs test/acpx-message-boundaries-package-contract.test.mjs test/acpx-rich-extensions-package-contract.test.mjs test/acpx-pi-receipt-package-contract.test.mjs test/acpx-response-delivery-package-contract.test.mjs scripts/candidate-provider-pack.test.mjs scripts/materialize-pi-distribution.test.mjs scripts/cursor-provisioner-layout.test.mjs scripts/release-provider-pack.test.mjs scripts/acpx-release-attestations.test.mjs scripts/provider-pack-runtime-tree.test.mjs scripts/aws-agentcore-provisioning.test.mjs scripts/build-verified-provider-entrypoints.test.mjs scripts/local-provider-smoke-environment.test.mjs scripts/materialize-opencode-binary.test.mjs scripts/materialize-kimi-distribution.test.mjs scripts/provision-kimi-package.test.mjs scripts/kimi-metadata-probe.test.mjs scripts/patch-kimi-runtime.test.mjs test/kimi-installed-runtime.test.mjs scripts/installed-package-pack.test.mjs scripts/runner-runtime-dependency-roots.test.mjs scripts/runner-package-executable.test.mjs scripts/stage-runner-binary.test.mjs scripts/build-inputs.test.mjs scripts/contracts/contract-fingerprints.test.mjs scripts/provider-pack-executable-shims.test.mjs scripts/controlled-evals/controller.test.mjs scripts/controlled-evals/portable.test.mjs && node --test scripts/build-copilot-distribution.test.mjs scripts/copilot-inner-distribution.test.mjs scripts/copilot-smoke-resources.test.mjs scripts/discover-copilot-acp.test.mjs scripts/materialize-copilot-binary.test.mjs scripts/install-copilot-assets.test.mjs scripts/probe-copilot-acp.test.mjs scripts/qualify-copilot-acp.test.mjs test/acpx-message-boundaries-package-contract.test.mjs",
"test:typescript:vitest": "node ./scripts/run-pr-vitest-lane.mjs",
"test:rust": "cargo test --release --manifest-path runner/Cargo.toml --locked --workspace",
"test:codex": "cargo test --manifest-path runner/Cargo.toml --locked -p paperclip-runner-core --test codex_provider",
@@ -3,7 +3,7 @@ use std::time::{SystemTime, UNIX_EPOCH};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use crate::generated_acpx_profiles::acpx_release_profile;
use crate::generated_acpx_profiles::{acpx_release_profile, kimi_native_closure};
use crate::local_runner::LocalRunnerError;
use crate::stable_identity::{is_stable_id, DURABLE_STABLE_ID_CHARS, SHORT_STABLE_ID_CHARS};
@@ -63,15 +63,41 @@ impl AcpxCandidateAdmission {
}
fn validate_at(&self, now: u64, os: &str, architecture: &str) -> Result<(), LocalRunnerError> {
let profile = acpx_release_profile("antigravity").ok_or_else(invalid)?;
let manifest: Value = serde_json::from_str(DISTRIBUTIONS).map_err(|_| invalid())?;
let closure = manifest
.pointer("/platforms/darwin-arm64/closureSha256")
.and_then(Value::as_str)
.ok_or_else(invalid)?;
let profile = acpx_release_profile(&self.agent).ok_or_else(invalid)?;
let (closure, host_matches) = match self.agent.as_str() {
"antigravity" => {
let manifest: Value = serde_json::from_str(DISTRIBUTIONS).map_err(|_| invalid())?;
let closure = manifest
.pointer("/platforms/darwin-arm64/closureSha256")
.and_then(Value::as_str)
.ok_or_else(invalid)?
.to_owned();
(
closure,
self.platform == "darwin"
&& self.architecture == "arm64"
&& os == "macos"
&& architecture == "aarch64",
)
}
"kimi" if profile.qualification_pending => {
let closure =
kimi_native_closure(&self.platform, &self.architecture).ok_or_else(invalid)?;
let host_matches = matches!(
(
self.platform.as_str(),
self.architecture.as_str(),
os,
architecture
),
("darwin", "arm64", "macos", "aarch64") | ("linux", "x64", "linux", "x86_64")
);
(closure.to_owned(), host_matches)
}
_ => return Err(invalid()),
};
if self.schema != SCHEMA
|| !is_stable_id(&self.company_id, DURABLE_STABLE_ID_CHARS)
|| self.agent != "antigravity"
|| self.model.trim().is_empty()
|| self.model != self.model.trim()
|| self.model.len() > 512
@@ -79,10 +105,7 @@ impl AcpxCandidateAdmission {
|| matches!(self.model.to_ascii_lowercase().as_str(), "auto" | "default")
|| self.profile_digest != profile.command_digest
|| self.native_closure_digest != format!("sha256:{closure}")
|| self.platform != "darwin"
|| self.architecture != "arm64"
|| os != "macos"
|| architecture != "aarch64"
|| !host_matches
|| self.expires_at > MAX_JSON_SAFE_INTEGER
|| self.expires_at <= now
|| self.expires_at > now.saturating_add(MAX_LIFETIME_MS)
@@ -94,6 +117,27 @@ impl AcpxCandidateAdmission {
Ok(())
}
pub fn validate_next_run(
&self,
next: &Self,
agent: &str,
model: &str,
run_id: &str,
normalized_session_id: &str,
) -> Result<(), LocalRunnerError> {
if self.agent != "kimi" || self.run_id == next.run_id {
return Err(invalid());
}
self.validate()?;
next.validate_binding(agent, model, run_id, normalized_session_id)?;
let mut rebound = next.clone();
rebound.run_id = self.run_id.clone();
if &rebound != self {
return Err(invalid());
}
Ok(())
}
pub fn validate_binding(
&self,
agent: &str,
@@ -208,4 +252,163 @@ mod tests {
let error = AcpxCandidateAdmission::parse_json("private malformed input").unwrap_err();
assert!(!error.to_string().contains("private"));
}
fn kimi_admission(platform: &str, architecture: &str) -> AcpxCandidateAdmission {
AcpxCandidateAdmission {
agent: "kimi".to_owned(),
model: "kimi-for-coding".to_owned(),
profile_digest: acpx_release_profile("kimi")
.unwrap()
.command_digest
.to_owned(),
native_closure_digest: format!(
"sha256:{}",
kimi_native_closure(platform, architecture).unwrap()
),
platform: platform.to_owned(),
architecture: architecture.to_owned(),
..test_admission("kimi-run", "kimi-session")
}
}
#[test]
fn kimi_candidate_requires_exact_two_platform_closures_scope_and_time() {
for (platform, architecture, os, host_arch) in [
("darwin", "arm64", "macos", "aarch64"),
("linux", "x64", "linux", "x86_64"),
] {
let candidate = kimi_admission(platform, architecture);
let now = candidate.expires_at - 1;
candidate.validate_at(now, os, host_arch).unwrap();
for (wrong_os, wrong_arch) in [
("windows", "x86_64"),
("linux", "aarch64"),
("macos", "x86_64"),
] {
assert!(candidate.validate_at(now, wrong_os, wrong_arch).is_err());
}
let (other_os, other_arch) = if os == "macos" {
("linux", "x86_64")
} else {
("macos", "aarch64")
};
assert!(candidate.validate_at(now, other_os, other_arch).is_err());
assert!(candidate
.validate_at(candidate.expires_at, os, host_arch)
.is_err());
assert!(candidate
.validate_at(candidate.expires_at - MAX_LIFETIME_MS - 1, os, host_arch)
.is_err());
for (field, value) in [
("companyId", json!("bad company")),
("agent", json!("copilot")),
("model", json!("default")),
("profileDigest", json!("sha256:wrong")),
("nativeClosureDigest", json!("sha256:wrong")),
("platform", json!("windows")),
("architecture", json!("s390x")),
("runId", json!("bad/run")),
("normalizedSessionId", json!("bad/session")),
] {
let mut changed = serde_json::to_value(&candidate).unwrap();
changed[field] = value;
let changed: AcpxCandidateAdmission = serde_json::from_value(changed).unwrap();
assert!(changed.validate_at(now, os, host_arch).is_err(), "{field}");
}
}
}
#[test]
#[cfg(any(
all(target_os = "macos", target_arch = "aarch64"),
all(target_os = "linux", target_arch = "x86_64")
))]
fn kimi_next_run_rebinds_only_the_authenticated_run_identity() {
let (platform, architecture) = if cfg!(target_os = "macos") {
("darwin", "arm64")
} else {
("linux", "x64")
};
let current = kimi_admission(platform, architecture);
let mut next = current.clone();
next.run_id = "kimi-next-run".to_owned();
current
.validate_next_run(
&next,
"kimi",
"kimi-for-coding",
"kimi-next-run",
"kimi-session",
)
.unwrap();
assert!(current
.validate_next_run(
&current,
"kimi",
"kimi-for-coding",
"kimi-run",
"kimi-session"
)
.is_err());
for (field, change) in [
("companyId", json!("another-company")),
("model", json!("another-model")),
("profileDigest", json!("sha256:wrong")),
("nativeClosureDigest", json!("sha256:wrong")),
("normalizedSessionId", json!("another-session")),
("expiresAt", json!(next.expires_at + 1)),
] {
let mut value = serde_json::to_value(&next).unwrap();
value[field] = change;
let changed = serde_json::from_value(value).unwrap();
assert!(current
.validate_next_run(
&changed,
"kimi",
"kimi-for-coding",
"kimi-next-run",
"kimi-session"
)
.is_err());
}
assert!(current
.validate_next_run(
&next,
"kimi",
"kimi-for-coding",
"foreign-run",
"kimi-session"
)
.is_err());
assert!(current
.validate_next_run(
&next,
"kimi",
"kimi-for-coding",
"kimi-next-run",
"foreign-session"
)
.is_err());
let mut expired = current.clone();
expired.expires_at = 0;
assert!(expired
.validate_next_run(
&next,
"kimi",
"kimi-for-coding",
"kimi-next-run",
"kimi-session"
)
.is_err());
let antigravity = test_admission("run-1", "session-1");
assert!(antigravity
.validate_next_run(
&next,
"kimi",
"kimi-for-coding",
"kimi-next-run",
"kimi-session"
)
.is_err());
}
}
@@ -927,6 +927,35 @@ impl AcpxCommandExecutor {
.canonical_digest()
}
fn restore_launch_profile_digest(
&self,
state: &AcpxDurableState,
) -> Result<String, DurableRunnerError> {
let Some(profile) = self.launch_profile.as_ref() else {
return self.launch_profile_digest();
};
let Some(current) = profile.candidate_admission.as_ref().filter(|grant| {
grant.agent == "kimi" && state.descriptor.run_id != self.context.run_id
}) else {
return profile.canonical_digest();
};
let mut prior = profile.clone();
prior.candidate_admission.as_mut().unwrap().run_id = state.descriptor.run_id.clone();
prior
.candidate_admission
.as_ref()
.unwrap()
.validate_next_run(
current,
&state.descriptor.agent,
&state.descriptor.model,
&self.context.run_id,
&self.context.normalized_session_id,
)
.map_err(|error| DurableRunnerError::invalid(error.to_string()))?;
prior.canonical_digest()
}
fn restore(&mut self) -> Result<(), DurableRunnerError> {
self.ensure_persistence_healthy()?;
if self.restore_checked {
@@ -958,7 +987,10 @@ impl AcpxCommandExecutor {
)))
}
};
if self.candidate_admission().is_some() {
if self
.candidate_admission()
.is_some_and(|admission| admission.agent == "antigravity")
{
return Err(DurableRunnerError::invalid(
"ACPX candidate cannot adopt a prior durable runner activation",
));
@@ -983,7 +1015,7 @@ impl AcpxCommandExecutor {
let state: AcpxDurableState = serde_json::from_slice(&bytes).map_err(|error| {
DurableRunnerError::invalid(format!("ACPX provider state is malformed: {error}"))
})?;
let launch_profile_digest = self.launch_profile_digest()?;
let launch_profile_digest = self.restore_launch_profile_digest(&state)?;
state.validate(&self.context, &launch_profile_digest)?;
self.state = Some(state);
self.restore_session_if_needed()
@@ -1218,7 +1250,10 @@ impl AcpxCommandExecutor {
}
fn attach_run(&mut self, payload: &Value) -> Result<(), DurableRunnerError> {
if self.candidate_admission().is_some() {
if self
.candidate_admission()
.is_some_and(|admission| admission.agent == "antigravity")
{
return Err(DurableRunnerError::invalid(
"ACPX candidate cannot rotate or adopt a live runner authority",
));
@@ -1258,6 +1293,62 @@ impl AcpxCommandExecutor {
attachment_context.run_id = run_id.to_owned();
}
descriptor.validate(&attachment_context)?;
let cold_candidate_attachment = self
.candidate_admission()
.is_some_and(|grant| grant.agent == "kimi")
&& payload.get("paperclipNextAuthority").is_none()
&& self
.state
.as_ref()
.is_some_and(|state| state.descriptor.run_id != self.context.run_id);
let next_candidate = if let Some(admission) = self
.candidate_admission()
.filter(|admission| admission.agent == "kimi")
{
if cold_candidate_attachment {
let state = self.state.as_ref().unwrap();
let digest = self.restore_launch_profile_digest(state)?;
state.validate(&self.context, &digest)?;
admission
.validate_binding(
&descriptor.agent,
&descriptor.model,
&self.context.run_id,
&self.context.normalized_session_id,
)
.map_err(|error| DurableRunnerError::invalid(error.to_string()))?;
Some(admission.clone())
} else {
let proposed: crate::acpx_candidate_admission::AcpxCandidateAdmission =
serde_json::from_value(
payload
.pointer("/paperclipNextAuthority/candidateAdmission")
.cloned()
.ok_or_else(|| {
DurableRunnerError::invalid(
"Kimi run.attach requires exact trusted candidate admission",
)
})?,
)
.map_err(|_| {
DurableRunnerError::invalid(
"Kimi run.attach candidate admission is invalid",
)
})?;
admission
.validate_next_run(
&proposed,
&descriptor.agent,
&descriptor.model,
&descriptor.run_id,
&descriptor.normalized_session_id,
)
.map_err(|error| DurableRunnerError::invalid(error.to_string()))?;
Some(proposed)
}
} else {
None
};
let tool_set = authorized_tool_set(payload)?;
let state = self
.state
@@ -1327,16 +1418,30 @@ impl AcpxCommandExecutor {
})?;
}
self.session = None;
let state = self
if let Some(admission) = next_candidate {
self.launch_profile
.as_mut()
.expect("candidate launch profile remains available")
.candidate_admission = Some(admission);
}
let launch_profile_digest = self.launch_profile_digest()?;
let mut state = self
.state
.as_mut()
.expect("ACPX state remains available while attaching a run");
.as_ref()
.expect("ACPX state remains available while attaching a run")
.clone();
state.launch_profile_digest = launch_profile_digest;
state.descriptor = descriptor;
state.tool_set = tool_set;
state.semantic_result = None;
state.pending_events.clear();
state.lifecycle = "suspended".to_owned();
self.save_state()
if cold_candidate_attachment {
self.commit_staged_state(state)
} else {
self.state = Some(state);
self.save_state()
}
}
fn open_session(&mut self) -> Result<CommandExecution, DurableRunnerError> {
@@ -2032,7 +2137,10 @@ impl AcpxCommandExecutor {
}
fn suspend(&mut self) -> Result<CommandExecution, DurableRunnerError> {
if self.candidate_admission().is_some() {
if self
.candidate_admission()
.is_some_and(|admission| admission.agent == "antigravity")
{
return self.close_session("candidate runner.suspend retires the owned process");
}
if self
@@ -2270,7 +2378,9 @@ fn goal_terminal_disposition<'a>(
impl CommandExecutor for AcpxCommandExecutor {
fn execute(&mut self, command: &Command) -> Result<CommandExecution, DurableRunnerError> {
self.restore()?;
if self.candidate_admission().is_some()
if self
.candidate_admission()
.is_some_and(|admission| admission.agent == "antigravity")
&& command.command_type == "run.attach"
&& command.payload.get("paperclipNextAuthority").is_some()
{
@@ -2346,6 +2456,12 @@ impl CommandExecutor for AcpxCommandExecutor {
self.context.normalized_session_id = config.normalized_session_id.clone();
self.context.turn_id = config.turn_id.clone();
self.context.item_id = config.item_id.clone();
if self
.candidate_admission()
.is_some_and(|admission| admission.agent == "kimi")
{
self.launch_profile = config.acpx_launch_profile.clone();
}
}
fn poll_events(&mut self) -> Result<Vec<PolledEvent>, DurableRunnerError> {
@@ -4824,4 +4940,510 @@ mod tests {
drop(listeners.pop());
(candidates, listeners)
}
#[test]
#[cfg(any(
all(target_os = "macos", target_arch = "aarch64"),
all(target_os = "linux", target_arch = "x86_64")
))]
fn kimi_candidate_attachment_atomically_rebinds_exact_grant_and_profile_digest() {
let directory = temporary_directory("kimi-candidate-attachment");
let mut grant = crate::acpx_candidate_admission::test_admission("run-1", "session-1");
grant.agent = "kimi".to_owned();
grant.model = "explicit-test-model".to_owned();
grant.profile_digest = acpx_release_profile("kimi")
.unwrap()
.command_digest
.to_owned();
grant.platform = if cfg!(target_os = "macos") {
"darwin"
} else {
"linux"
}
.to_owned();
grant.architecture = if cfg!(target_os = "macos") {
"arm64"
} else {
"x64"
}
.to_owned();
grant.native_closure_digest = format!(
"sha256:{}",
crate::generated_acpx_profiles::kimi_native_closure(
&grant.platform,
&grant.architecture
)
.unwrap()
);
let command = directory.join("owned-sidecar");
write_artifact(&command, b"#!/bin/sh\nexit 1\n", true);
let profile = AcpxLaunchProfile {
candidate_admission: Some(grant.clone()),
authority_digest: format!("sha256:{}", "d".repeat(64)),
command: command.clone(),
args: vec![],
artifacts: vec![artifact(&command)],
};
let runtime = directory.join("runtime");
let workspace = directory.join("workspace");
fs::create_dir_all(&runtime).unwrap();
fs::create_dir_all(&workspace).unwrap();
fs::set_permissions(&runtime, fs::Permissions::from_mode(0o700)).unwrap();
fs::set_permissions(&workspace, fs::Permissions::from_mode(0o700)).unwrap();
let mut value = descriptor("kimi");
value["runtimeDirectory"] = json!(runtime);
value["cwd"] = json!(workspace);
value["sidecarCommand"] = json!(command);
value["sidecarArgs"] = json!([]);
let desc: AcpxProviderDescriptor = serde_json::from_value(value.clone()).unwrap();
let identity = AcpxProviderSessionIdentity {
kind: "acpx".to_owned(),
normalized_session_id: "session-1".to_owned(),
acpx_record_id: "record-1".to_owned(),
backend_session_id: "backend-1".to_owned(),
agent_session_id: "agent-1".to_owned(),
profile_digest: desc.command_digest.clone(),
workspace_digest: format!("sha256:{}", "a".repeat(64)),
requested_model: desc.model.clone(),
effective_model: desc.model.clone(),
permission_mode: Some(desc.permission_mode),
mode: None,
pi_thinking_level: None,
claude_effort: None,
grok_effort: None,
grok_disable_web_search: None,
provider_lifetime_fence_candidates: [60_001, 60_002, 60_003],
};
let operations = Vec::new();
let tools = AuthorizedToolSet {
schema: TOOL_SET_SCHEMA.to_owned(),
schema_version: 1,
catalog_digest: authorized_tool_catalog_digest(&operations).unwrap(),
operations,
};
let previous_digest = profile.canonical_digest().unwrap();
let mut state = AcpxDurableState::new(desc, tools, previous_digest.clone());
state.lifecycle = "suspended".to_owned();
state.identity = Some(identity);
let config = test_config(&directory, Some(profile));
let mut executor = AcpxCommandExecutor::with_runner_config(&directory, &config);
executor.state = Some(state);
executor.save_state().unwrap();
let before = fs::read(executor.state_path()).unwrap();
let mut next = grant.clone();
next.run_id = "run-2".to_owned();
let mut provider = value;
provider["runId"] = json!("run-2");
let payload = json!({"provider":provider,"paperclipNextAuthority":{
"identity":{"runId":"run-2","normalizedSessionId":"session-1"},"candidateAdmission":next
}});
for (field, changed) in [
("companyId", json!("foreign")),
("model", json!("wrong")),
("expiresAt", json!(grant.expires_at + 1)),
("runId", json!("unbound")),
] {
let mut invalid = payload.clone();
invalid["paperclipNextAuthority"]["candidateAdmission"][field] = changed;
assert!(executor.attach_run(&invalid).is_err(), "{field}");
assert_eq!(fs::read(executor.state_path()).unwrap(), before);
}
assert!(executor.attach_run(&json!({"provider":provider})).is_err());
executor.attach_run(&payload).unwrap();
let updated = executor.state.as_ref().unwrap();
assert_eq!(updated.descriptor.run_id, "run-2");
assert_eq!(executor.context.run_id, "run-1");
let profile = executor.launch_profile.as_ref().unwrap();
assert_eq!(profile.candidate_admission.as_ref().unwrap(), &next);
assert_ne!(updated.launch_profile_digest, previous_digest);
assert_eq!(
updated.launch_profile_digest,
profile.canonical_digest().unwrap()
);
let launch = updated
.descriptor
.session_config(
updated.tool_set.clone(),
updated.identity.clone(),
Some(profile),
)
.unwrap();
assert_eq!(launch.candidate_admission.as_ref().unwrap(), &next);
let saved: AcpxDurableState =
serde_json::from_slice(&fs::read(executor.state_path()).unwrap()).unwrap();
assert_eq!(saved.descriptor.run_id, "run-2");
assert_eq!(saved.launch_profile_digest, updated.launch_profile_digest);
assert!(executor.session.is_none());
fs::remove_dir_all(directory).unwrap();
}
#[cfg(any(
all(target_os = "macos", target_arch = "aarch64"),
all(target_os = "linux", target_arch = "x86_64")
))]
fn kimi_cold_restore_fixture(
label: &str,
) -> (PathBuf, DurableRunnerConfig, Value, Vec<u8>, PathBuf) {
let directory = temporary_directory(label);
let mut grant = crate::acpx_candidate_admission::test_admission("run-1", "session-1");
grant.agent = "kimi".to_owned();
grant.model = "explicit-test-model".to_owned();
grant.profile_digest = acpx_release_profile("kimi")
.unwrap()
.command_digest
.to_owned();
grant.platform = if cfg!(target_os = "macos") {
"darwin"
} else {
"linux"
}
.to_owned();
grant.architecture = if cfg!(target_os = "macos") {
"arm64"
} else {
"x64"
}
.to_owned();
grant.native_closure_digest = format!(
"sha256:{}",
crate::generated_acpx_profiles::kimi_native_closure(
&grant.platform,
&grant.architecture
)
.unwrap()
);
let command = directory.join("owned-sidecar");
let sentinel = directory.join("provider-opened");
write_artifact(
&command,
format!("#!/bin/sh\ntouch '{}'\nexit 1\n", sentinel.display()).as_bytes(),
true,
);
let profile = AcpxLaunchProfile {
candidate_admission: Some(grant.clone()),
authority_digest: format!("sha256:{}", "d".repeat(64)),
command: command.clone(),
args: vec![],
artifacts: vec![artifact(&command)],
};
let runtime = directory.join("runtime");
let workspace = directory.join("workspace");
fs::create_dir_all(&runtime).unwrap();
fs::create_dir_all(&workspace).unwrap();
fs::set_permissions(&runtime, fs::Permissions::from_mode(0o700)).unwrap();
fs::set_permissions(&workspace, fs::Permissions::from_mode(0o700)).unwrap();
let mut value = descriptor("kimi");
value["runtimeDirectory"] = json!(runtime);
value["cwd"] = json!(workspace);
value["sidecarCommand"] = json!(command);
value["sidecarArgs"] = json!([]);
let desc: AcpxProviderDescriptor = serde_json::from_value(value.clone()).unwrap();
let identity = AcpxProviderSessionIdentity {
kind: "acpx".to_owned(),
normalized_session_id: "session-1".to_owned(),
acpx_record_id: "record-1".to_owned(),
backend_session_id: "backend-1".to_owned(),
agent_session_id: "agent-1".to_owned(),
profile_digest: desc.command_digest.clone(),
workspace_digest: format!("sha256:{}", "a".repeat(64)),
requested_model: desc.model.clone(),
effective_model: desc.model.clone(),
permission_mode: Some(desc.permission_mode),
mode: None,
pi_thinking_level: None,
claude_effort: None,
grok_effort: None,
grok_disable_web_search: None,
provider_lifetime_fence_candidates: [60_001, 60_002, 60_003],
};
let operations = Vec::new();
let tools = AuthorizedToolSet {
schema: TOOL_SET_SCHEMA.to_owned(),
schema_version: 1,
catalog_digest: authorized_tool_catalog_digest(&operations).unwrap(),
operations,
};
let previous_digest = profile.canonical_digest().unwrap();
let mut state = AcpxDurableState::new(desc, tools, previous_digest.clone());
state.lifecycle = "suspended".to_owned();
state.identity = Some(identity);
let config = test_config(&directory, Some(profile));
let mut executor = AcpxCommandExecutor::with_runner_config(&directory, &config);
executor.state = Some(state);
executor.save_state().unwrap();
let before = fs::read(executor.state_path()).unwrap();
let mut next_config = config.clone();
next_config.run_id = "run-2".to_owned();
next_config.turn_id = "turn-2".to_owned();
next_config.item_id = "item-2".to_owned();
let next_grant = next_config
.acpx_launch_profile
.as_mut()
.unwrap()
.candidate_admission
.as_mut()
.unwrap();
next_grant.run_id = "run-2".to_owned();
next_config.validate().unwrap();
let mut next_provider = value;
next_provider["runId"] = json!("run-2");
(
directory,
next_config,
json!({"provider": next_provider}),
before,
sentinel,
)
}
fn cold_attach_command(payload: Value) -> Command {
Command {
schema: "paperclip.prp.command.v1".into(),
command_id: "cold-attach".into(),
controller_seq: 1,
command_type: "run.attach".into(),
issued_at: "2026-10-30T00:00:00.000Z".into(),
deadline_at: None,
precondition: None,
payload,
}
}
#[test]
#[cfg(any(
all(target_os = "macos", target_arch = "aarch64"),
all(target_os = "linux", target_arch = "x86_64")
))]
fn kimi_candidate_governed_wait_cold_restore_uses_authenticated_next_startup() {
let (directory, next_config, payload, before, sentinel) =
kimi_cold_restore_fixture("kimi-candidate-cold-governed-wait");
let mut recovered = AcpxCommandExecutor::with_runner_config(&directory, &next_config);
recovered.restore().expect("authorized cold Kimi restore must retain the settled prior session until authenticated attachment");
assert!(recovered.session.is_none());
assert!(recovered.poll_events().unwrap().is_empty());
assert!(!sentinel.exists());
recovered.attach_run(&payload)
.expect("cold replacement uses its already authenticated startup authority, not a second warm next-authority grant");
let saved: AcpxDurableState =
serde_json::from_slice(&fs::read(recovered.state_path()).unwrap()).unwrap();
assert_eq!(saved.descriptor.run_id, "run-2");
assert_eq!(
saved.launch_profile_digest,
next_config
.acpx_launch_profile
.as_ref()
.unwrap()
.canonical_digest()
.unwrap()
);
assert!(recovered.session.is_none());
assert!(!sentinel.exists());
assert_ne!(fs::read(recovered.state_path()).unwrap(), before);
fs::remove_dir_all(directory).unwrap();
}
#[test]
#[cfg(any(
all(target_os = "macos", target_arch = "aarch64"),
all(target_os = "linux", target_arch = "x86_64")
))]
fn kimi_candidate_cold_restore_rejects_changed_startup_authority_before_provider_open() {
for field in [
"company",
"model",
"expiry",
"expired",
"profile",
"closure",
"platform",
"architecture",
"session",
"grant_run",
"context_run",
"authority",
"command",
"args",
"artifact",
"missing_grant",
"saved_digest",
] {
let (directory, mut config, payload, before, sentinel) =
kimi_cold_restore_fixture("kimi-candidate-cold-reject");
match field {
"context_run" => config.run_id = "foreign-run".into(),
"missing_grant" => {
config
.acpx_launch_profile
.as_mut()
.unwrap()
.candidate_admission = None
}
"saved_digest" => {
let mut state: AcpxDurableState = serde_json::from_slice(&before).unwrap();
state.launch_profile_digest = format!("sha256:{}", "0".repeat(64));
fs::write(
directory.join("acpx-provider-state.json"),
serde_json::to_vec(&state).unwrap(),
)
.unwrap();
}
_ => {
let profile = config.acpx_launch_profile.as_mut().unwrap();
let grant = profile.candidate_admission.as_mut().unwrap();
match field {
"company" => grant.company_id = "foreign-company".into(),
"model" => grant.model = "foreign-model".into(),
"expiry" => grant.expires_at += 1,
"expired" => grant.expires_at = 1,
"profile" => grant.profile_digest = format!("sha256:{}", "0".repeat(64)),
"closure" => {
grant.native_closure_digest = format!("sha256:{}", "0".repeat(64))
}
"platform" => grant.platform = "foreign-platform".into(),
"architecture" => grant.architecture = "foreign-architecture".into(),
"session" => grant.normalized_session_id = "foreign-session".into(),
"grant_run" => grant.run_id = "foreign-run".into(),
"authority" => {
profile.authority_digest = format!("sha256:{}", "0".repeat(64))
}
"command" => profile.command = directory.join("foreign-command"),
"args" => profile.args.push("foreign-argument".into()),
"artifact" => {
profile.artifacts[0].sha256 = format!("sha256:{}", "0".repeat(64))
}
_ => unreachable!(),
}
}
}
let mut recovered = AcpxCommandExecutor::with_runner_config(&directory, &config);
let retained = fs::read(recovered.state_path()).unwrap();
assert!(
recovered.execute(&cold_attach_command(payload)).is_err(),
"{field}"
);
assert!(recovered.session.is_none(), "{field}");
assert!(!sentinel.exists(), "{field}");
assert_eq!(
fs::read(recovered.state_path()).unwrap(),
retained,
"{field}"
);
fs::remove_dir_all(directory).unwrap();
}
}
#[test]
#[cfg(any(
all(target_os = "macos", target_arch = "aarch64"),
all(target_os = "linux", target_arch = "x86_64")
))]
fn kimi_candidate_cold_attach_rejects_unsettled_or_changed_session_before_provider_open() {
for field in [
"run",
"session",
"model",
"workspace",
"active_turn",
"pending_event",
"exit_unconfirmed",
"identity",
"closed",
] {
let (directory, config, mut payload, before, sentinel) =
kimi_cold_restore_fixture("kimi-candidate-cold-binding");
let mut recovered = AcpxCommandExecutor::with_runner_config(&directory, &config);
match field {
"run" => payload["provider"]["runId"] = json!("foreign-run"),
"session" => payload["provider"]["normalizedSessionId"] = json!("foreign-session"),
"model" => payload["provider"]["model"] = json!("foreign-model"),
"workspace" => {
payload["provider"]["cwd"] = json!(directory.join("foreign-workspace"))
}
_ => {
let mut state: AcpxDurableState = serde_json::from_slice(&before).unwrap();
match field {
"active_turn" => state.active_turn_id = Some("active-turn".into()),
"pending_event" => {
state
.push(NormalizedProviderEvent {
event_type: "runtime_request.created".into(),
priority: EventPriority::P0,
payload: json!({"request":pending_input_request("input-1")}),
})
.unwrap();
}
"exit_unconfirmed" => state.provider_exit_unconfirmed = true,
"identity" => state.identity = None,
"closed" => state.lifecycle = "closed".into(),
_ => unreachable!(),
}
fs::write(recovered.state_path(), serde_json::to_vec(&state).unwrap()).unwrap();
}
}
let retained = fs::read(recovered.state_path()).unwrap();
assert!(
recovered.execute(&cold_attach_command(payload)).is_err(),
"{field}"
);
assert!(recovered.session.is_none(), "{field}");
assert!(!sentinel.exists(), "{field}");
assert_eq!(
fs::read(recovered.state_path()).unwrap(),
retained,
"{field}"
);
fs::remove_dir_all(directory).unwrap();
}
}
#[test]
#[cfg(any(
all(target_os = "macos", target_arch = "aarch64"),
all(target_os = "linux", target_arch = "x86_64")
))]
fn kimi_candidate_cold_attach_post_rename_failure_quarantines_public_execution() {
let (directory, config, payload, before, sentinel) =
kimi_cold_restore_fixture("kimi-candidate-cold-write-failure");
let mut recovered = AcpxCommandExecutor::with_runner_config(&directory, &config);
recovered.restore().unwrap();
let previous_state = recovered.state.clone();
recovered.fail_after_state_rename = true;
let command = cold_attach_command(payload);
let error = recovered.execute(&command).unwrap_err();
assert!(error
.to_string()
.contains("injected post-rename sync failure"));
assert_eq!(recovered.state, previous_state);
assert!(recovered.session.is_none());
assert!(!sentinel.exists());
let disk = fs::read(recovered.state_path()).unwrap();
assert_ne!(disk, before);
let saved: AcpxDurableState = serde_json::from_slice(&disk).unwrap();
assert_eq!(saved.descriptor.run_id, "run-2");
assert_eq!(
saved.launch_profile_digest,
config
.acpx_launch_profile
.as_ref()
.unwrap()
.canonical_digest()
.unwrap()
);
recovered.fail_after_state_rename = false;
for result in [
recovered.retained_events().map(|_| ()),
recovered.poll_events().map(|_| ()),
recovered.acknowledge_events(0),
recovered.restore(),
recovered.save_state(),
recovered.shutdown(),
] {
assert_eq!(result.unwrap_err().to_string(), error.to_string());
}
assert_eq!(
recovered.execute(&command).unwrap_err().to_string(),
error.to_string()
);
assert_eq!(fs::read(recovered.state_path()).unwrap(), disk);
assert!(!sentinel.exists());
fs::remove_dir_all(directory).unwrap();
}
}
@@ -11,7 +11,7 @@ pub(crate) enum RunAttachmentPolicy {
pub(crate) fn run_attachment_policy(agent: &str) -> RunAttachmentPolicy {
match agent {
"cursor" | "copilot" | "pi" => RunAttachmentPolicy::AuthenticatedRunGrants,
"cursor" | "copilot" | "pi" | "kimi" => RunAttachmentPolicy::AuthenticatedRunGrants,
"claude" => RunAttachmentPolicy::AuthenticatedAssetPaths,
_ => RunAttachmentPolicy::ImmutableInstructions,
}
@@ -109,8 +109,8 @@ pub struct AcpxProviderState {
plan_revision: u64,
assistant_text: String,
assistant_message_id: Option<String>,
pi_assistant_message: Option<String>,
pi_assistant_message_ids: BTreeSet<String>,
native_assistant_message: Option<String>,
native_assistant_message_ids: BTreeSet<String>,
pending_tools: BTreeMap<String, AcpxPendingTool>,
pending_tool_input_bytes: usize,
pending_permissions: BTreeMap<String, (usize, Value)>,
@@ -128,8 +128,8 @@ impl AcpxProviderState {
plan_revision: 0,
assistant_text: String::new(),
assistant_message_id: None,
pi_assistant_message: None,
pi_assistant_message_ids: BTreeSet::new(),
native_assistant_message: None,
native_assistant_message_ids: BTreeSet::new(),
pending_tools: BTreeMap::new(),
pending_tool_input_bytes: 0,
pending_permissions: BTreeMap::new(),
@@ -222,8 +222,8 @@ impl AcpxProviderState {
self.plan_revision = 0;
self.assistant_text.clear();
self.assistant_message_id = None;
self.pi_assistant_message = None;
self.pi_assistant_message_ids.clear();
self.native_assistant_message = None;
self.native_assistant_message_ids.clear();
self.semantic_result = None;
self.attempted_turn_controls.clear();
Ok(())
@@ -371,9 +371,9 @@ impl AcpxProviderState {
}])
}
AcpxEventPayload::TurnTerminal { status, error } => {
if status == AcpxTurnStatus::Completed && self.pi_assistant_message.is_some() {
if status == AcpxTurnStatus::Completed && self.native_assistant_message.is_some() {
return Err(LocalRunnerError::invalid(
"Pi assistant message ended without its native boundary",
"ACP assistant message ended without its native boundary",
));
}
let turn_id = event
@@ -394,8 +394,8 @@ impl AcpxProviderState {
self.assistant_text.clear();
}
self.assistant_message_id = None;
self.pi_assistant_message = None;
self.pi_assistant_message_ids.clear();
self.native_assistant_message = None;
self.native_assistant_message_ids.clear();
events.push(AcpxProviderStateEvent::TurnTerminal {
turn_id,
status,
@@ -518,6 +518,10 @@ impl AcpxProviderState {
};
if kind == AcpxRuntimeEventKind::TextDelta
&& payload.get("piMessageHistory").and_then(Value::as_bool) != Some(true)
&& payload
.get("assistantMessageHistory")
.and_then(Value::as_bool)
!= Some(true)
{
let provider_message_id = payload
.get("messageId")
@@ -534,55 +538,67 @@ impl AcpxProviderState {
.and_then(Value::as_str)
.unwrap_or_default();
let mut native_boundary_clears = false;
if let Some(boundary) = payload.get("piMessageBoundary") {
if payload.get("assistantMessageBoundary").is_some()
&& payload.get("piMessageBoundary").is_some()
{
return Err(LocalRunnerError::invalid(
"ACP assistant boundary has ambiguous representations",
));
}
if let Some(boundary) = payload
.get("assistantMessageBoundary")
.or_else(|| payload.get("piMessageBoundary"))
{
let phase = boundary.get("phase").and_then(Value::as_str);
let reason = boundary.get("stopReason").and_then(Value::as_str);
if !raw_text.is_empty() || provider_message_id.is_none() {
return Err(LocalRunnerError::invalid(
"Pi assistant boundary contains invalid content or identity",
"ACP assistant boundary contains invalid content or identity",
));
}
match phase {
Some("start") if self.pi_assistant_message.is_none() && reason.is_none() => {
if self.pi_assistant_message_ids.len() >= 4096
Some("start")
if self.native_assistant_message.is_none() && reason.is_none() =>
{
if self.native_assistant_message_ids.len() >= 4096
|| !self
.pi_assistant_message_ids
.native_assistant_message_ids
.insert(provider_message_id.clone().unwrap())
{
return Err(LocalRunnerError::invalid(
"Pi assistant identity is duplicated or exceeds its bound",
"ACP assistant identity is duplicated or exceeds its bound",
));
}
self.pi_assistant_message = provider_message_id.clone();
self.native_assistant_message = provider_message_id.clone();
native_boundary_clears = true;
}
Some("end")
if self.pi_assistant_message.is_some()
&& self.pi_assistant_message == provider_message_id =>
if self.native_assistant_message.is_some()
&& self.native_assistant_message == provider_message_id =>
{
if !matches!(
reason,
Some("stop" | "length" | "toolUse" | "error" | "aborted")
) {
return Err(LocalRunnerError::invalid(
"Pi assistant stop reason is invalid",
"ACP assistant stop reason is invalid",
));
}
self.pi_assistant_message = None;
self.native_assistant_message = None;
native_boundary_clears = !matches!(reason, Some("stop" | "length"));
}
_ => {
return Err(LocalRunnerError::invalid(
"Pi assistant boundaries are out of order",
"ACP assistant boundaries are out of order",
))
}
}
} else if !self.pi_assistant_message_ids.is_empty()
&& (self.pi_assistant_message.is_none()
|| self.pi_assistant_message != provider_message_id)
} else if !self.native_assistant_message_ids.is_empty()
&& (self.native_assistant_message.is_none()
|| self.native_assistant_message != provider_message_id)
{
return Err(LocalRunnerError::invalid(
"Pi assistant delta has no matching native message",
"ACP assistant delta has no matching native message",
));
}
// ACP can produce more than one assistant message in a turn. All
@@ -216,6 +216,7 @@ impl AcpxSidecarTransport {
"pi" => &[],
"cursor" => &["CURSOR_API_KEY", "CURSOR_AUTH_TOKEN"],
"copilot" => &["COPILOT_GITHUB_TOKEN"],
"kimi" => &["KIMI_API_KEY"],
"antigravity" => &[
"GEMINI_API_KEY",
"PAPERCLIP_ACPX_ANTIGRAVITY_AUTH_JSON_SECRET",
@@ -254,7 +255,7 @@ impl AcpxSidecarTransport {
"PAPERCLIP_ACPX_PROVIDER_PACKAGE_ROOT",
"PAPERCLIP_ACPX_PROVIDER_PACKAGE_MANIFEST",
];
if matches!(agent, "pi" | "cursor" | "copilot" | "antigravity") {
if matches!(agent, "pi" | "cursor" | "copilot" | "kimi" | "antigravity") {
// Credential values alone are not proof of an explicit task binding.
// The sidecar checks this controller-minted provider/session marker.
keys.push("PAPERCLIP_ACPX_CREDENTIAL_BINDING");
@@ -52,6 +52,7 @@ const RESERVED: &[&str] = &[
"GITHUB_ENTERPRISE_TOKEN",
"GITHUB_TOKEN",
"HOME",
"KIMI_API_KEY",
"NODE_OPTIONS",
"NODE_PATH",
"OPENAI_API_KEY",
@@ -209,6 +210,7 @@ mod tests {
"[\"PAPERCLIP_RUNTIME_NOTIFICATION_CONTEXT\"]",
"[\"PAPERCLIP_RUNTIME_NOTIFICATION_HELPER\"]",
"[\"OPENAI_API_KEY\"]",
"[\"KIMI_API_KEY\"]",
"[\"LD_PRELOAD\"]",
"[\"bad=name\"]",
"[\"CUSTOM\",\"CUSTOM\"]",
@@ -226,6 +228,14 @@ mod tests {
assert_eq!(command.get_envs().count(), 0);
}
let mut command = Command::new("unused");
assert!(apply_configured_environment(&mut command, |key| match key {
MARKER => Some("[\"KIMI_API_KEY\"]".into()),
"KIMI_API_KEY" => Some("selected-code-key".into()),
_ => None,
})
.is_err());
assert_eq!(command.get_envs().count(), 0);
let mut command = Command::new("unused");
assert!(
apply_configured_environment(&mut command, |key| Some(if key == MARKER {
"[\"CUSTOM\"]".into()
@@ -199,7 +199,6 @@ pub(crate) fn next_authority_config(
next.normalized_session_id = read_identity("normalizedSessionId")?;
next.turn_id = read_identity("turnId")?;
next.item_id = read_identity("itemId")?;
next.validate()?;
if next.runner_instance_id != current.runner_instance_id
|| next.environment_lease_id != current.environment_lease_id
|| next.normalized_session_id != current.normalized_session_id
@@ -209,6 +208,47 @@ pub(crate) fn next_authority_config(
"run.attach authority changed an immutable session binding",
));
}
if let Some(admission) = current
.acpx_launch_profile
.as_ref()
.and_then(|profile| profile.candidate_admission.as_ref())
{
if admission.agent == "kimi" {
let proposed: crate::acpx_candidate_admission::AcpxCandidateAdmission =
serde_json::from_value(boundary.get("candidateAdmission").cloned().ok_or_else(
|| {
DurableRunnerError::invalid(
"Kimi authority rotation requires exact trusted candidate admission",
)
},
)?)
.map_err(|_| {
DurableRunnerError::invalid("Kimi authority rotation admission is invalid")
})?;
admission
.validate_next_run(
&proposed,
"kimi",
&admission.model,
&next.run_id,
&next.normalized_session_id,
)
.map_err(|error| DurableRunnerError::invalid(error.to_string()))?;
next.acpx_launch_profile
.as_mut()
.unwrap()
.candidate_admission = Some(proposed);
} else if boundary.get("candidateAdmission").is_some() {
return Err(DurableRunnerError::invalid(
"candidate authority rotation is not admitted",
));
}
} else if boundary.get("candidateAdmission").is_some() {
return Err(DurableRunnerError::invalid(
"authority rotation cannot create candidate admission",
));
}
next.validate()?;
Ok(Some(next))
}
@@ -5104,4 +5144,129 @@ mod tests {
assert_eq!(executor.calls, 1);
fs::remove_dir_all(directory).unwrap();
}
#[test]
#[cfg(any(
all(target_os = "macos", target_arch = "aarch64"),
all(target_os = "linux", target_arch = "x86_64")
))]
fn kimi_candidate_handoff_binds_the_existing_authenticated_next_authority() {
let directory =
std::env::temp_dir().join(format!("kimi-grant-handoff-{}", std::process::id()));
let mut current = config(directory);
let mut grant = crate::acpx_candidate_admission::test_admission(
"run_1",
&current.normalized_session_id,
);
grant.agent = "kimi".to_owned();
grant.profile_digest = crate::generated_acpx_profiles::acpx_release_profile("kimi")
.unwrap()
.command_digest
.to_owned();
grant.platform = if cfg!(target_os = "macos") {
"darwin"
} else {
"linux"
}
.to_owned();
grant.architecture = if cfg!(target_os = "macos") {
"arm64"
} else {
"x64"
}
.to_owned();
grant.native_closure_digest = format!(
"sha256:{}",
crate::generated_acpx_profiles::kimi_native_closure(
&grant.platform,
&grant.architecture
)
.unwrap()
);
current.acpx_launch_profile = Some(crate::durable::AcpxLaunchProfile {
authority_digest: format!("sha256:{}", "a".repeat(64)),
command: PathBuf::from("/fixture/node"),
args: vec!["/fixture/sidecar.cjs".to_owned()],
artifacts: vec![crate::durable::QualifiedLaunchArtifact {
path: PathBuf::from("/fixture/node"),
sha256: format!("sha256:{}", "b".repeat(64)),
}],
candidate_admission: Some(grant.clone()),
});
current.validate().unwrap();
let mut next_grant = grant.clone();
next_grant.run_id = "run_2".to_owned();
let mut attach = command("run.attach");
attach.payload = json!({"paperclipNextAuthority":{
"identity":{"runnerInstanceId":current.runner_instance_id,"environmentLeaseId":current.environment_lease_id,
"runId":"run_2","normalizedSessionId":current.normalized_session_id,"turnId":"turn_2","itemId":"item_2"},
"connection":{"mode":"external"},"candidateAdmission":next_grant
}});
let next = next_authority_config(&attach, &current).unwrap().unwrap();
let actual = next
.acpx_launch_profile
.as_ref()
.unwrap()
.candidate_admission
.as_ref()
.unwrap();
assert_eq!(actual, &next_grant);
assert_eq!(
current
.acpx_launch_profile
.as_ref()
.unwrap()
.candidate_admission
.as_ref()
.unwrap(),
&grant
);
assert_eq!(next.runner_instance_id, current.runner_instance_id);
assert_eq!(next.environment_lease_id, current.environment_lease_id);
assert_eq!(next.normalized_session_id, current.normalized_session_id);
for (field, value) in [
("companyId", json!("foreign-company")),
("agent", json!("antigravity")),
("model", json!("different-model")),
("profileDigest", json!(format!("sha256:{}", "f".repeat(64)))),
(
"nativeClosureDigest",
json!(format!("sha256:{}", "e".repeat(64))),
),
("expiresAt", json!(grant.expires_at + 1)),
("runId", json!("unbound-run")),
("normalizedSessionId", json!("foreign-session")),
] {
let mut changed = attach.clone();
changed.payload["paperclipNextAuthority"]["candidateAdmission"][field] = value;
assert!(
next_authority_config(&changed, &current).is_err(),
"{field}"
);
}
for field in [
"runnerInstanceId",
"environmentLeaseId",
"normalizedSessionId",
] {
let mut changed = attach.clone();
changed.payload["paperclipNextAuthority"]["identity"][field] = json!("foreign");
assert!(
next_authority_config(&changed, &current).is_err(),
"{field}"
);
}
let mut missing = attach.clone();
missing.payload["paperclipNextAuthority"]
.as_object_mut()
.unwrap()
.remove("candidateAdmission");
assert!(next_authority_config(&missing, &current).is_err());
let mut no_prior = current.clone();
no_prior
.acpx_launch_profile
.as_mut()
.unwrap()
.candidate_admission = None;
assert!(next_authority_config(&attach, &no_prior).is_err());
}
}
@@ -13,6 +13,18 @@ pub(crate) struct AcpxReleaseProfile {
pub qualification_pending: bool,
}
pub(crate) fn kimi_native_closure(platform: &str, architecture: &str) -> Option<&'static str> {
match (platform, architecture) {
("darwin", "arm64") => {
Some("6038325abd0431c30097ff1f572a9b29816e1b4da372d8cb86b2ca5d18ea34e7")
}
("linux", "x64") => {
Some("105d8394adbbc76a953a12cc51b5288eb940ad693291e584f6cdc6407213164d")
}
_ => None,
}
}
pub(crate) fn acpx_release_profile(agent: &str) -> Option<AcpxReleaseProfile> {
Some(match agent {
"antigravity" => AcpxReleaseProfile {
@@ -85,6 +97,16 @@ pub(crate) fn acpx_release_profile(agent: &str) -> Option<AcpxReleaseProfile> {
requires_provider_policy: false,
qualification_pending: false,
},
"kimi" => AcpxReleaseProfile {
agent_server_package: "@moonshot-ai/kimi-code",
agent_server_version: "2.3.3",
agent_runtime_package: None,
agent_runtime_version: None,
command_digest:
"sha256:0c1e6ce460407ec973a37a2d192d665fcde744e2b9875c791c90308afbf4c52b",
requires_provider_policy: true,
qualification_pending: true,
},
_ => return None,
})
}
@@ -138,7 +138,12 @@ impl NativeProviderCommandExecutor {
.config
.acpx_launch_profile
.as_ref()
.is_some_and(|profile| profile.candidate_admission.is_some())
.is_some_and(|profile| {
profile
.candidate_admission
.as_ref()
.is_some_and(|admission| admission.agent == "antigravity")
})
&& [
CODEX_PROVIDER_STATE_FILE,
ACPX_PROVIDER_STATE_FILE,
@@ -176,92 +176,103 @@ fn promotes_only_the_latest_provider_message_as_the_terminal_reply() {
}
#[test]
fn pi_native_boundaries_keep_progress_but_never_promote_tool_narration_or_history() {
for final_reason in ["stop", "length", "toolUse", "error", "aborted", "empty"] {
let mut state = AcpxProviderState::new("run-1").unwrap();
state.begin_turn("turn-1").unwrap();
let mut messages = vec![
json!({"type":"text_delta","messageId":"history","text":"Earlier session answer","piMessageHistory":true}),
json!({"type":"text_delta","messageId":"first","text":"","piMessageBoundary":{"phase":"start"}}),
json!({"type":"text_delta","messageId":"first","text":"Calling finish."}),
json!({"type":"text_delta","messageId":"first","text":"","piMessageBoundary":{"phase":"end","stopReason":"toolUse"}}),
json!({"type":"text_delta","messageId":"last","text":"","piMessageBoundary":{"phase":"start"}}),
];
if final_reason != "empty" {
messages.push(json!({"type":"text_delta","messageId":"last","text":"EXACT_MARKER"}));
}
messages.push(json!({"type":"text_delta","messageId":"last","text":"","piMessageBoundary":{"phase":"end","stopReason":if final_reason == "empty" { "stop" } else { final_reason }}}));
let count = messages.len() as u64;
for (index, payload) in messages.into_iter().enumerate() {
state
fn native_boundaries_keep_progress_but_never_promote_tool_narration_or_history() {
for (boundary_field, history_field) in [
("piMessageBoundary", "piMessageHistory"),
("assistantMessageBoundary", "assistantMessageHistory"),
] {
for final_reason in ["stop", "length", "toolUse", "error", "aborted", "empty"] {
let mut state = AcpxProviderState::new("run-1").unwrap();
state.begin_turn("turn-1").unwrap();
let mut messages = vec![
json!({"type":"text_delta","messageId":"history","text":"Earlier session answer",(history_field):true}),
json!({"type":"text_delta","messageId":"first","text":"",(boundary_field):{"phase":"start"}}),
json!({"type":"text_delta","messageId":"first","text":"Calling finish."}),
json!({"type":"text_delta","messageId":"first","text":"",(boundary_field):{"phase":"end","stopReason":"toolUse"}}),
json!({"type":"text_delta","messageId":"last","text":"",(boundary_field):{"phase":"start"}}),
];
if final_reason != "empty" {
messages
.push(json!({"type":"text_delta","messageId":"last","text":"EXACT_MARKER"}));
}
messages.push(json!({"type":"text_delta","messageId":"last","text":"",(boundary_field):{"phase":"end","stopReason":if final_reason == "empty" { "stop" } else { final_reason }}}));
let count = messages.len() as u64;
for (index, payload) in messages.into_iter().enumerate() {
state
.accept_event(&event(
index as u64 + 1,
GeneratedAcpxSidecarEventType::RuntimeEvent,
Some("turn-1"),
payload,
))
.unwrap();
}
let terminal = state
.accept_event(&event(
index as u64 + 1,
GeneratedAcpxSidecarEventType::RuntimeEvent,
count + 1,
GeneratedAcpxSidecarEventType::RuntimeTurnTerminal,
Some("turn-1"),
payload,
json!({"status":"completed"}),
))
.unwrap();
}
let terminal = state
.accept_event(&event(
count + 1,
GeneratedAcpxSidecarEventType::RuntimeTurnTerminal,
Some("turn-1"),
json!({"status":"completed"}),
))
.unwrap();
let replies: Vec<_> = terminal
.iter()
.filter_map(|entry| {
if let AcpxProviderStateEvent::AssistantMessage { text, .. } = entry {
Some(text.as_str())
let replies: Vec<_> = terminal
.iter()
.filter_map(|entry| {
if let AcpxProviderStateEvent::AssistantMessage { text, .. } = entry {
Some(text.as_str())
} else {
None
}
})
.collect();
assert_eq!(
replies,
if matches!(final_reason, "stop" | "length") {
vec!["EXACT_MARKER"]
} else {
None
vec![]
}
})
.collect();
assert_eq!(
replies,
if matches!(final_reason, "stop" | "length") {
vec!["EXACT_MARKER"]
} else {
vec![]
}
);
);
}
}
}
#[test]
fn pi_native_boundary_order_and_terminal_completeness_fail_closed() {
for malformed in [
json!({"type":"text_delta","messageId":"first","text":"","piMessageBoundary":{"phase":"start"}}),
json!({"type":"text_delta","messageId":"other","text":"","piMessageBoundary":{"phase":"end","stopReason":"stop"}}),
json!({"type":"text_delta","messageId":"first","text":"","piMessageBoundary":{"phase":"end","stopReason":"invented"}}),
json!({"type":"text_delta","messageId":"other","text":"Out of order"}),
fn native_boundary_order_and_terminal_completeness_fail_closed() {
for (boundary_field, _history_field) in [
("piMessageBoundary", "piMessageHistory"),
("assistantMessageBoundary", "assistantMessageHistory"),
] {
for malformed in [
json!({"type":"text_delta","messageId":"first","text":"",(boundary_field):{"phase":"start"}}),
json!({"type":"text_delta","messageId":"other","text":"",(boundary_field):{"phase":"end","stopReason":"stop"}}),
json!({"type":"text_delta","messageId":"first","text":"",(boundary_field):{"phase":"end","stopReason":"invented"}}),
json!({"type":"text_delta","messageId":"other","text":"Out of order"}),
] {
let mut state = AcpxProviderState::new("run-1").unwrap();
state.begin_turn("turn-1").unwrap();
state.accept_event(&event(1, GeneratedAcpxSidecarEventType::RuntimeEvent, Some("turn-1"), json!({"type":"text_delta","messageId":"first","text":"",(boundary_field):{"phase":"start"}}))).unwrap();
assert!(state
.accept_event(&event(
2,
GeneratedAcpxSidecarEventType::RuntimeEvent,
Some("turn-1"),
malformed
))
.is_err());
}
let mut state = AcpxProviderState::new("run-1").unwrap();
state.begin_turn("turn-1").unwrap();
state.accept_event(&event(1, GeneratedAcpxSidecarEventType::RuntimeEvent, Some("turn-1"), json!({"type":"text_delta","messageId":"first","text":"","piMessageBoundary":{"phase":"start"}}))).unwrap();
state.accept_event(&event(1, GeneratedAcpxSidecarEventType::RuntimeEvent, Some("turn-1"), json!({"type":"text_delta","messageId":"first","text":"",(boundary_field):{"phase":"start"}}))).unwrap();
assert!(state
.accept_event(&event(
2,
GeneratedAcpxSidecarEventType::RuntimeEvent,
GeneratedAcpxSidecarEventType::RuntimeTurnTerminal,
Some("turn-1"),
malformed
json!({"status":"completed"})
))
.is_err());
}
let mut state = AcpxProviderState::new("run-1").unwrap();
state.begin_turn("turn-1").unwrap();
state.accept_event(&event(1, GeneratedAcpxSidecarEventType::RuntimeEvent, Some("turn-1"), json!({"type":"text_delta","messageId":"first","text":"","piMessageBoundary":{"phase":"start"}}))).unwrap();
assert!(state
.accept_event(&event(
2,
GeneratedAcpxSidecarEventType::RuntimeTurnTerminal,
Some("turn-1"),
json!({"status":"completed"})
))
.is_err());
}
#[test]
@@ -28,6 +28,10 @@ export const ACPX_RELEASE_ATTESTATIONS = Object.freeze({
nodeVersion: ["pi-node-pins.ts", "PI_NODE_VERSION"],
closure: ["pi-closure-pins.ts", "PI_DISTRIBUTION_CLOSURE_SHA256"],
} },
kimi: { kind: "closure", pins: {
nodeVersion: ["kimi-closure-pins.ts", "KIMI_NODE_VERSION"],
closure: ["kimi-closure-pins.ts", "KIMI_DISTRIBUTION_CLOSURE_SHA256"],
} },
cursor: { kind: "declaration", path: "cursor-contract.json", digestField: "commandDigest" },
antigravity: { kind: "declaration", path: "antigravity-distributions.json" },
});
@@ -16,6 +16,7 @@ const packageFiles = [
"scripts/acpx-release-attestations.mjs", "scripts/generate-acpx-profiles.mjs",
"src/providers/grok/launcher.cjs", "src/drivers/acpx/copilot-closure-pins.ts",
"src/drivers/acpx/pi-closure-pins.ts", "src/drivers/acpx/pi-node-pins.ts",
"src/drivers/acpx/kimi-closure-pins.ts",
"src/drivers/acpx/generated-profiles.ts", "runner/crates/runner-core/src/generated_acpx_profiles.rs",
];
@@ -37,7 +38,7 @@ const generate = (root, ...args) => spawnSync(process.execPath, [join(root, "scr
test("every profile declares how its digest attests the upstream release", async () => {
assert.deepEqual(Object.keys(ACPX_RELEASE_ATTESTATIONS).sort(), Object.keys(manifest.profiles).sort());
assert.deepEqual(COMPUTED.sort(), ["antigravity", "copilot", "cursor", "grok", "pi"]);
assert.deepEqual(COMPUTED.sort(), ["antigravity", "copilot", "cursor", "grok", "kimi", "pi"]);
for (const agent of COMPUTED) {
assert.equal(manifest.profiles[agent].commandDigest, (await acpxReleaseAttestation(agent, packageRoot)).commandDigest, agent);
}
@@ -66,10 +67,11 @@ test("a relocated copy of the provider inputs computes the same attestations", a
});
test("the attestations bind no Paperclip source beyond the Grok launcher", async () => {
for (const agent of ["copilot", "pi"]) {
for (const agent of ["copilot", "pi", "kimi"]) {
const { declaration } = await acpxReleaseAttestation(agent, packageRoot);
assert.deepEqual(Object.keys(declaration).filter(key => /source/iu.test(key)), [], agent);
assert.deepEqual(Object.keys(declaration.closure).sort(), ["darwin-arm64", "darwin-x64", "linux-x64"]);
assert.deepEqual(Object.keys(declaration.closure).sort(), agent === "kimi"
? ["darwin-arm64", "linux-x64"] : ["darwin-arm64", "darwin-x64", "linux-x64"]);
}
});
@@ -86,6 +88,10 @@ for (const [name, agents, edit] of [
const path = join(root, "src/drivers/acpx/pi-closure-pins.ts");
writeFileSync(path, readFileSync(path, "utf8").replace(/"linux-x64": "[a-f0-9]{64}"/u, `"linux-x64": "${"0".repeat(64)}"`));
}],
["a Kimi platform closure", ["kimi"], root => {
const path = join(root, "src/drivers/acpx/kimi-closure-pins.ts");
writeFileSync(path, readFileSync(path, "utf8").replace(/"linux-x64": "[a-f0-9]{64}"/u, `"linux-x64": "${"0".repeat(64)}"`));
}],
["the Grok launcher bytes", ["grok"], root => {
const path = join(root, "src/providers/grok/launcher.cjs");
writeFileSync(path, `${readFileSync(path, "utf8")}\n// changed\n`);
@@ -8,6 +8,12 @@ import { build } from "esbuild";
const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
export const verifiedProviderEntrypoints = Object.freeze([
Object.freeze({
name: "kimi-metadata-probe",
source: resolve(packageRoot, "src/cli/kimi-metadata-probe.ts"),
output: resolve(packageRoot, "dist/cli/kimi-metadata-probe.js"),
verifiedOutput: resolve(packageRoot, "dist/cli/kimi-metadata-probe.cjs"),
}),
Object.freeze({
name: "provision-antigravity",
source: resolve(packageRoot, "scripts/provision-antigravity.mjs"),
@@ -80,6 +86,7 @@ export async function bundleVerifiedProviderEntrypoints({ write = true } = {}) {
platform: "node",
format,
target: "node24",
absWorkingDir: entrypoint.name === "kimi-metadata-probe" ? packageRoot : undefined,
packages: "bundle",
splitting: false,
sourcemap: false,
@@ -116,6 +123,7 @@ export async function bundleVerifiedProviderEntrypoints({ write = true } = {}) {
results.push({ entrypoint, result, verifiedResult });
}
await bundlePiProvisioner({ write });
await bundleKimiProvisioner({ write });
return results;
}
@@ -146,6 +154,28 @@ export async function bundlePiProvisioner({ write = true, outputRoot = resolve(p
return result;
}
export async function bundleKimiProvisioner({ write = true, outputRoot = resolve(packageRoot, "dist/cli") } = {}) {
const entrypoint = { name: "provision-kimi", source: resolve(packageRoot, "scripts/provision-kimi.mjs") };
const result = await build({
entryPoints: [entrypoint.source], outfile: resolve(outputRoot, "provision-kimi.cjs"),
bundle: true, platform: "node", format: "cjs", target: "node24", packages: "bundle",
splitting: false, sourcemap: false, legalComments: "none", metafile: true,
treeShaking: true, write, logLevel: "silent",
banner: { js: 'const __paperclipVerifiedEntrypointUrl = require("node:url").pathToFileURL(__filename).href;' },
define: { "import.meta.dirname": "__dirname", "import.meta.url": "__paperclipVerifiedEntrypointUrl" },
});
assertSelfContainedBundle(entrypoint, result);
if (write) {
const inputs = resolve(outputRoot, "kimi-provision-inputs");
await mkdir(inputs, { recursive: true });
for (const [source, name] of [
["scripts/kimi-distribution/package.json", "package.json"],
["scripts/kimi-distribution/package-lock.json", "package-lock.json"],
]) await cp(resolve(packageRoot, source), resolve(inputs, name));
}
return result;
}
const invokedPath = process.argv[1]
? pathToFileURL(resolve(process.argv[1])).href
: null;
@@ -41,6 +41,11 @@ test("written provider entrypoints satisfy qualified launch permissions", async
// Package-layout regression runs in the existing verified-entrypoint test lane.
import "./provision-pi-package.test.mjs";
import "./materialize-kimi-distribution.test.mjs";
import "./provision-kimi-package.test.mjs";
import "./patch-kimi-runtime.test.mjs";
import "./kimi-metadata-probe.test.mjs";
import "./antigravity-provisioner-layout.test.mjs";
import "./materialize-antigravity-distribution.test.mjs";
import "./probe-antigravity-metadata.test.mjs";
@@ -1,7 +1,7 @@
import { materializePiDistribution } from "./materialize-pi-distribution.mjs";
import profiles from "../acpx-profiles.json" with { type: "json" };
import { materializePinnedCursorDistribution } from "./materialize-cursor-distribution.mjs";
const CANDIDATES = new Set(["cursor", "copilot", "pi"]);
const CANDIDATES = new Set(["cursor", "copilot", "pi", "kimi"]);
/** Only materialized providers enter the serialized manifest and its digest. */
export function providerPackManifestFields(providers, candidates) {
@@ -34,6 +34,11 @@ export function parseProviderPackArguments(args) {
/** Closed source-owned builder registry; provider branches add their exact pins. */
export async function materializeCandidateProviderPack({ provider, outputRoot }) {
if (!CANDIDATES.has(provider)) throw new Error("Unknown candidate provider");
if (provider === "kimi") {
const { materializeKimiDistribution } = await import("./materialize-kimi-distribution.mjs");
const result = await materializeKimiDistribution({ outputRoot });
return { version: result.version, profileDigest: profiles.profiles.kimi.commandDigest, closureDigest: result.closureDigest };
}
if (provider === "pi") return materializePiDistribution({ outputRoot });
if (provider === "copilot") {
const { buildPinnedCopilotDistribution } = await import("./build-copilot-distribution.mjs");
@@ -43,6 +43,27 @@ test("provider manifest digest survives disk JSON on supported and unsupported t
test("candidate options stay explicit and supported native assets are included by default", () => {
assert.deepEqual(parseProviderPackArguments(["--", "/pack"]), { output: "/pack", candidates: [] });
assert.deepEqual(parseProviderPackArguments(["/pack", "--candidate-providers=pi,cursor"]), { output: "/pack", candidates: ["pi", "cursor"] });
assert.deepEqual(parseProviderPackArguments(["/pack", "--candidate-providers=kimi"]), { output: "/pack", candidates: ["kimi"] });
});
test("Kimi stays explicit, pending and separate from released provider inventory", () => {
const kimi = { version: "2.3.3", qualification: "pending", profileDigest: "sha256:profile", closureDigest: "sha256:closure" };
for (const [platform, architecture] of [["darwin", "arm64"], ["linux", "x64"]]) {
assert.equal(providerPackProviders(platform, architecture, []).includes("kimi"), false);
assert.equal(providerPackProviders(platform, architecture, ["kimi"]).includes("kimi"), true);
}
const fields = providerPackManifestFields({ kimi }, ["kimi"]);
assert.equal(fields.providers?.kimi, undefined);
assert.equal(fields.candidateProviders.kimi, kimi);
assert.equal(providerPackManifestFields({ kimi }, []).candidateProviders?.kimi, undefined);
assert.equal(digest(JSON.parse(JSON.stringify(fields))), digest(fields));
});
test("Kimi's candidate builder rejects invalid paths before any public download", async t => {
let requests = 0;
t.mock.method(globalThis, "fetch", async () => { requests++; throw new Error("Unexpected Kimi download"); });
await assert.rejects(materializeCandidateProviderPack({ provider: "kimi", outputRoot: "relative-kimi-output" }), /Kimi distribution output must be absolute/);
assert.equal(requests, 0);
});
test("normal packs include Cursor and Copilot on their three pinned targets without breaking other hosts", () => {
for (const [platform, architecture] of [["darwin", "arm64"], ["darwin", "x64"], ["linux", "x64"]]) {
@@ -1,3 +1,4 @@
import { KIMI_DISTRIBUTION_CLOSURE_SHA256 } from "../src/drivers/acpx/kimi-closure-pins.ts";
import assert from "node:assert/strict";
import { readFile, writeFile } from "node:fs/promises";
import { fileURLToPath } from "node:url";
@@ -90,6 +91,13 @@ pub(crate) struct AcpxReleaseProfile {
pub qualification_pending: bool,
}
pub(crate) fn kimi_native_closure(platform: &str, architecture: &str) -> Option<&'static str> {
match (platform, architecture) {
${Object.entries(KIMI_DISTRIBUTION_CLOSURE_SHA256).map(([target, digest]) => { const [platform, architecture] = target.split("-"); return ` (${quote(platform)}, ${quote(architecture)}) => {\n Some(${quote(digest)})\n }`; }).join("\n")}
_ => None,
}
}
pub(crate) fn acpx_release_profile(agent: &str) -> Option<AcpxReleaseProfile> {
Some(match agent {
${entries.map(([agent, p]) => ` ${quote(agent)} => AcpxReleaseProfile {
@@ -0,0 +1,606 @@
{
"name": "paperclip-kimi-runtime-distribution",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "paperclip-kimi-runtime-distribution",
"version": "1.0.0",
"dependencies": {
"@moonshot-ai/kimi-code": "2.3.3"
},
"engines": {
"node": ">=24.11.0"
}
},
"node_modules/@mariozechner/clipboard": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/@mariozechner/clipboard/-/clipboard-0.3.9.tgz",
"integrity": "sha512-ABnA53mdfkGZwOFUdZNv2S0CWGO/EIuPj8Vv9xmBFmSYg/qFc7ihO6q5FcQjvoE67kZpWkEc4AhD6B/os04yuA==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">= 10"
},
"optionalDependencies": {
"@mariozechner/clipboard-darwin-arm64": "0.3.9",
"@mariozechner/clipboard-darwin-universal": "0.3.9",
"@mariozechner/clipboard-darwin-x64": "0.3.9",
"@mariozechner/clipboard-linux-arm64-gnu": "0.3.9",
"@mariozechner/clipboard-linux-arm64-musl": "0.3.9",
"@mariozechner/clipboard-linux-riscv64-gnu": "0.3.9",
"@mariozechner/clipboard-linux-x64-gnu": "0.3.9",
"@mariozechner/clipboard-linux-x64-musl": "0.3.9",
"@mariozechner/clipboard-win32-arm64-msvc": "0.3.9",
"@mariozechner/clipboard-win32-x64-msvc": "0.3.9"
}
},
"node_modules/@mariozechner/clipboard-darwin-arm64": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/@mariozechner/clipboard-darwin-arm64/-/clipboard-darwin-arm64-0.3.9.tgz",
"integrity": "sha512-BfgV7vCEWZwJwZJw03r6bP5+tf0iI/ANuQYCxi9RNn7FrWB3yzGuMKCrNLRl6V761vXRdL8+OqZ0wd4TqlsNOQ==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@mariozechner/clipboard-darwin-universal": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/@mariozechner/clipboard-darwin-universal/-/clipboard-darwin-universal-0.3.9.tgz",
"integrity": "sha512-BGGR4iA9Z2shAjI65eI5xtyb3LYNlDW9X3gxKxDbqtbnREohsrqznov6zpKoIrsRWpzlYVEdKphS7ksJ0/ndSQ==",
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@mariozechner/clipboard-darwin-x64": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/@mariozechner/clipboard-darwin-x64/-/clipboard-darwin-x64-0.3.9.tgz",
"integrity": "sha512-4kURmCbS6nt8uYhtmWpUcJWyPHfmAr5dTpXD1nO3pIfa+TSQ9DbrGOYCKH+aEFW47XhQ4Vp8ZTszie+wfFvDKg==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@mariozechner/clipboard-linux-arm64-gnu": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/@mariozechner/clipboard-linux-arm64-gnu/-/clipboard-linux-arm64-gnu-0.3.9.tgz",
"integrity": "sha512-g59OkUGP2DDfCOIKypHeYgv2M55u/cKvXa5dSxFbEJ34XvIQMdcVmpKCkGUro3ZgefXiGVdwguvTMQGpHWzIXw==",
"cpu": [
"arm64"
],
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@mariozechner/clipboard-linux-arm64-musl": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/@mariozechner/clipboard-linux-arm64-musl/-/clipboard-linux-arm64-musl-0.3.9.tgz",
"integrity": "sha512-AGuJdgKsmJdm4Pych7kv3sqe591ERRaAHW3xjLooiFzn8J+PxUyof++7YZrB5Y5tpnTO+K18Og3taj2NpluCRQ==",
"cpu": [
"arm64"
],
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@mariozechner/clipboard-linux-riscv64-gnu": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/@mariozechner/clipboard-linux-riscv64-gnu/-/clipboard-linux-riscv64-gnu-0.3.9.tgz",
"integrity": "sha512-DXBEAiuMpk7dhS1a9NzNxVAFi1vaKoPu7rQNgY8LIDLGrK3lnIp3nT10DUum+PKVJoJppIP+NAA8IZe4DMNDPw==",
"cpu": [
"riscv64"
],
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@mariozechner/clipboard-linux-x64-gnu": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/@mariozechner/clipboard-linux-x64-gnu/-/clipboard-linux-x64-gnu-0.3.9.tgz",
"integrity": "sha512-WORrMLd6EpElEME7JRKfSaY34nW1P5LbdgK5YNCS1ncG2LqmITsSMEJ8nh2mpvxb3TxqbOOKgY7k9eMJYlW9Mw==",
"cpu": [
"x64"
],
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@mariozechner/clipboard-linux-x64-musl": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/@mariozechner/clipboard-linux-x64-musl/-/clipboard-linux-x64-musl-0.3.9.tgz",
"integrity": "sha512-/DHn+1DrfL6oRaPPWXaOKvonFFrni666fxd+zFqiQEfvBH0tsHVWjq9iqBk0oDp0qaPA72lIMy5BptxISBEhZQ==",
"cpu": [
"x64"
],
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@mariozechner/clipboard-win32-arm64-msvc": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/@mariozechner/clipboard-win32-arm64-msvc/-/clipboard-win32-arm64-msvc-0.3.9.tgz",
"integrity": "sha512-O5FHD3ErkMwMhNzAfu3ggy0ug4z7btZuoQgwwxlzPrwV2bxlD6WDpqBY4NCgICAgZdDKdp+loUEKVAVt8aYnhQ==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@mariozechner/clipboard-win32-x64-msvc": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/@mariozechner/clipboard-win32-x64-msvc/-/clipboard-win32-x64-msvc-0.3.9.tgz",
"integrity": "sha512-ihQC3EufqEY81vhXBgVBtK4prL+wc62zJsSvxrgz7K1hsdt6OObz6v9p3Rn1OG3GJksTTKMJF0u/guMISHPhSA==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@moonshot-ai/kimi-code": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/@moonshot-ai/kimi-code/-/kimi-code-2.3.3.tgz",
"integrity": "sha512-3V8bycucf9KgPRH27S8De2u0ip84/Ry3FpNn6gi5z9JmoEHt9vxiYHHZqiMdyDf5nPm4bv+YKGwKEQL4oYpRTw==",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
"chokidar": "^4.0.3",
"qrcode": "^1.5.4",
"ws": "^8.18.0"
},
"bin": {
"kimi": "dist/main.mjs"
},
"engines": {
"node": ">=22.19.0"
},
"optionalDependencies": {
"@mariozechner/clipboard": "^0.3.9",
"node-pty": "^1.1.0"
}
},
"node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"license": "MIT",
"dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/chokidar": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
"license": "MIT",
"dependencies": {
"readdirp": "^4.0.1"
},
"engines": {
"node": ">= 14.16.0"
},
"funding": {
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/cliui": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
"license": "ISC",
"dependencies": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0",
"wrap-ansi": "^6.2.0"
}
},
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"license": "MIT"
},
"node_modules/decamelize": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
"integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/dijkstrajs": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz",
"integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==",
"license": "MIT"
},
"node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"license": "MIT"
},
"node_modules/find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"license": "MIT",
"dependencies": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"license": "ISC",
"engines": {
"node": "6.* || 8.* || >= 10.*"
}
},
"node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"license": "MIT",
"dependencies": {
"p-locate": "^4.1.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/node-addon-api": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
"integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
"license": "MIT",
"optional": true
},
"node_modules/node-pty": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/node-pty/-/node-pty-1.1.0.tgz",
"integrity": "sha512-20JqtutY6JPXTUnL0ij1uad7Qe1baT46lyolh2sSENDd4sTzKZ4nmAFkeAARDKwmlLjPx6XKRlwRUxwjOy+lUg==",
"hasInstallScript": true,
"license": "MIT",
"optional": true,
"dependencies": {
"node-addon-api": "^7.1.0"
}
},
"node_modules/p-limit": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"license": "MIT",
"dependencies": {
"p-try": "^2.0.0"
},
"engines": {
"node": ">=6"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/p-locate": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"license": "MIT",
"dependencies": {
"p-limit": "^2.2.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/pngjs": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz",
"integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==",
"license": "MIT",
"engines": {
"node": ">=10.13.0"
}
},
"node_modules/qrcode": {
"version": "1.5.4",
"resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.4.tgz",
"integrity": "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==",
"license": "MIT",
"dependencies": {
"dijkstrajs": "^1.0.1",
"pngjs": "^5.0.0",
"yargs": "^15.3.1"
},
"bin": {
"qrcode": "bin/qrcode"
},
"engines": {
"node": ">=10.13.0"
}
},
"node_modules/readdirp": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
"integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
"license": "MIT",
"engines": {
"node": ">= 14.18.0"
},
"funding": {
"type": "individual",
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/require-main-filename": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
"license": "ISC"
},
"node_modules/set-blocking": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
"license": "ISC"
},
"node_modules/string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"license": "MIT",
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/which-module": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz",
"integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==",
"license": "ISC"
},
"node_modules/wrap-ansi": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/ws": {
"version": "8.22.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.22.0.tgz",
"integrity": "sha512-Ydggc987+RO0AnWtZ/7Wq9FtNvcrL1b/RO0ud9mWjUPgDrsAAwQSF51sm2hm1XofbU/4jkpGEsLFsZZxU+1DOg==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/y18n": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
"license": "ISC"
},
"node_modules/yargs": {
"version": "15.4.1",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
"license": "MIT",
"dependencies": {
"cliui": "^6.0.0",
"decamelize": "^1.2.0",
"find-up": "^4.1.0",
"get-caller-file": "^2.0.1",
"require-directory": "^2.1.1",
"require-main-filename": "^2.0.0",
"set-blocking": "^2.0.0",
"string-width": "^4.2.0",
"which-module": "^2.0.0",
"y18n": "^4.0.0",
"yargs-parser": "^18.1.2"
},
"engines": {
"node": ">=8"
}
},
"node_modules/yargs-parser": {
"version": "18.1.3",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
"license": "ISC",
"dependencies": {
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
},
"engines": {
"node": ">=6"
}
}
}
}
@@ -0,0 +1,11 @@
{
"name": "paperclip-kimi-runtime-distribution",
"version": "1.0.0",
"private": true,
"dependencies": {
"@moonshot-ai/kimi-code": "2.3.3"
},
"engines": {
"node": ">=24.11.0"
}
}
@@ -0,0 +1,34 @@
export const KIMI_INSTRUCTION_RUNTIME_SOURCE = [
"function createKimiInstructionRuntime(raw, { createHash, byteLength }) {",
" const schema = \"paperclip.kimi.instructions.v1\";",
" const fail = () => { throw new Error(\"Kimi instruction binding is missing or invalid\"); };",
" if (typeof raw !== \"string\" || byteLength(raw) > 200_000) fail();",
" let value;",
" try { value = JSON.parse(raw); } catch { fail(); }",
" if (!value || typeof value !== \"object\" || Array.isArray(value)",
" || Object.keys(value).sort().join(\",\") !== \"byteLength,content,digest,schema\"",
" || value.schema !== schema || typeof value.content !== \"string\"",
" || value.content.includes(\"\\0\") || !value.content.isWellFormed()",
" || byteLength(value.content) > 32_768 || value.byteLength !== byteLength(value.content)",
" || typeof value.digest !== \"string\") fail();",
" const digest = text => `sha256:${createHash(\"sha256\").update(text, \"utf8\").digest(\"hex\")}`;",
" const content = value.content;",
" if (value.digest !== digest(content)) fail();",
" const suffix = content.length === 0 ? \"\" : `\\n\\n${content}`;",
" const append = base => {",
" if (typeof base !== \"string\" || byteLength(base) > 2_097_152) fail();",
" return suffix.length === 0 || base.endsWith(suffix) ? base : `${base}${suffix}`;",
" };",
" return Object.freeze({",
" append,",
" receipt(sessionId, effectivePrompt) {",
" if (typeof sessionId !== \"string\" || !sessionId.trim() || append(effectivePrompt) !== effectivePrompt) fail();",
" return Object.freeze({ schema, sessionId, digest: value.digest,",
" byteLength: byteLength(content), effectiveDigest: digest(effectivePrompt),",
" effectiveByteLength: byteLength(effectivePrompt) });",
" },",
" });",
"}",
].join("\n");
export const createKimiInstructionRuntime = new Function(`return (${KIMI_INSTRUCTION_RUNTIME_SOURCE});`)();
@@ -0,0 +1,112 @@
import assert from "node:assert/strict";
import { spawnSync } from "node:child_process";
import { createHash } from "node:crypto";
import { mkdtemp, mkdir, readFile, realpath, rm, stat, symlink, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { dirname, join, resolve } from "node:path";
import test from "node:test";
import { fileURLToPath, pathToFileURL } from "node:url";
import { build } from "esbuild";
import { bundleVerifiedProviderEntrypoints } from "./build-verified-provider-entrypoints.mjs";
const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
const sha = bytes => `sha256:${createHash("sha256").update(bytes).digest("hex")}`;
test("Kimi metadata CLI is self-contained and rejects incomplete assets without inheriting credentials or making requests", { timeout: 20_000 }, async t => {
const root = await realpath(await mkdtemp(join(tmpdir(), "paperclip-kimi-metadata-cli-")));
t.after(() => rm(root, { recursive: true, force: true }));
const bundles = await bundleVerifiedProviderEntrypoints({ write: false });
const bundle = bundles.find(value => value.entrypoint.name === "kimi-metadata-probe");
assert.ok(bundle, "The ordinary provider pack build must include the metadata CLI");
const bytes = bundle.verifiedResult.outputFiles[0].contents;
const relocatedBuild = spawnSync(process.execPath, ["--input-type=module", "-e", `
import { createHash } from "node:crypto";
import { bundleVerifiedProviderEntrypoints } from ${JSON.stringify(new URL("./build-verified-provider-entrypoints.mjs", import.meta.url).href)};
const bundles = await bundleVerifiedProviderEntrypoints({ write: false });
const bytes = bundles.find(value => value.entrypoint.name === "kimi-metadata-probe").verifiedResult.outputFiles[0].contents;
process.stdout.write("sha256:" + createHash("sha256").update(bytes).digest("hex"));
`], { cwd: root, env: { PATH: "/usr/bin:/bin" }, encoding: "utf8", timeout: 10_000 });
assert.ifError(relocatedBuild.error);
assert.equal(relocatedBuild.status, 0, relocatedBuild.stderr);
assert.equal(relocatedBuild.stdout, sha(bytes), "Metadata CLI admission bytes must be independent of the build cwd");
const entry = join(root, "kimi-metadata-probe.cjs");
await writeFile(entry, bytes);
assert.doesNotMatch(Buffer.from(bytes).toString(), /\bimport\.meta\b/);
for (const output of Object.values(bundle.verifiedResult.metafile.outputs)) {
for (const dependency of output.imports) assert.match(dependency.path, /^node:/);
}
const manifest = join(root, "package.json");
await writeFile(manifest, '{"name":"@paperclipai/paperclip-runner","type":"module"}');
const preload = join(root, "deny-external-work.cjs");
await writeFile(preload, `
const assert = require("node:assert/strict");
process.nextTick(() => {
for (const name of ["KIMI_API_KEY", "PAPERCLIP_KIMI_PROBE_MODEL", "KIMI_MODEL_DEFAULT", "HOME", "HTTPS_PROXY", "NODE_OPTIONS", "NODE_PATH", "ANTHROPIC_API_KEY", "PAPERCLIP_ACPX_CANDIDATE_ADMISSION"]) {
assert.equal(process.env[name], undefined, name);
}
assert.equal(process.env.PAPERCLIP_ACPX_PROVIDER_PACKAGE_ROOT, ${JSON.stringify(root)});
});
const fail = () => { throw Error("UNEXPECTED_NETWORK_OR_CHILD"); };
globalThis.fetch = fail;
for (const name of ["node:net", "node:tls", "node:http", "node:https"]) {
const dependency = require(name);
for (const key of ["connect", "createConnection", "request", "get"]) if (key in dependency) dependency[key] = fail;
}
const child = require("node:child_process");
for (const key of ["spawn", "exec", "execFile"]) child[key] = fail;
`);
const pinnedNode = join(packageRoot, "provider-assets/kimi", `${process.platform}-${process.arch}`, "runtime/node/bin/node");
const node = await stat(pinnedNode).then(() => pinnedNode, () => process.execPath);
const profile = JSON.parse(await readFile(join(packageRoot, "acpx-profiles.json"), "utf8")).profiles.kimi;
const { KIMI_DISTRIBUTION_CLOSURE_SHA256 } = await import(new URL("../src/drivers/acpx/kimi-closure-pins.ts", import.meta.url));
const admission = { schema: "paperclip.acpx-candidate-admission.v1", companyId: "metadata-cli-company", agent: "kimi", model: "selected-model",
profileDigest: profile.commandDigest, nativeClosureDigest: `sha256:${KIMI_DISTRIBUTION_CLOSURE_SHA256[`${process.platform}-${process.arch}`]}`,
platform: process.platform, architecture: process.arch, expiresAt: Date.now() + 60_000,
runId: "metadata-operation", normalizedSessionId: "metadata-session" };
const child = spawnSync(node, ["--require", preload, entry], {
env: { KIMI_API_KEY: "selected-secret-canary", PAPERCLIP_KIMI_PROBE_MODEL: "selected-model",
PAPERCLIP_ACPX_CANDIDATE_ADMISSION: JSON.stringify(admission),
PAPERCLIP_ACPX_PROVIDER_PACKAGE_ROOT: root, PAPERCLIP_ACPX_PROVIDER_PACKAGE_MANIFEST: manifest,
KIMI_MODEL_DEFAULT: "unselected-model", HOME: "/private/unselected-home", HTTPS_PROXY: "http://127.0.0.1:9",
ANTHROPIC_API_KEY: "unselected-secret-canary", NODE_OPTIONS: "", NODE_PATH: "/unselected-module-path" },
encoding: "utf8", timeout: 10_000,
});
assert.ifError(child.error);
assert.equal(child.status, 1);
assert.equal(child.signal, null);
assert.doesNotMatch(child.stdout + child.stderr, /UNEXPECTED_NETWORK_OR_CHILD|selected-secret-canary|unselected-secret-canary/);
assert.deepEqual(JSON.parse(child.stdout), { schema: "paperclip.kimi.metadata.v1", status: "failed",
code: "KIMI_INSTALLATION_INVALID", message: process.versions.node === "24.21.0" || node === pinnedNode
? "Install the current verified Kimi Code runtime in this execution environment."
: "Kimi metadata verification requires the pinned Node runtime.", promptSent: false });
const unqualified = spawnSync(node, ["--require", preload, entry], {
env: { KIMI_API_KEY: "selected-secret-canary", PAPERCLIP_KIMI_PROBE_MODEL: "selected-model",
PAPERCLIP_ACPX_PROVIDER_PACKAGE_ROOT: root, PAPERCLIP_ACPX_PROVIDER_PACKAGE_MANIFEST: manifest },
encoding: "utf8", timeout: 10_000,
});
assert.ifError(unqualified.error); assert.equal(unqualified.status, 1);
if (process.versions.node === "24.21.0" || node === pinnedNode) {
assert.equal(JSON.parse(unqualified.stdout).code, "KIMI_QUALIFICATION_REQUIRED");
}
assert.doesNotMatch(unqualified.stdout + unqualified.stderr, /UNEXPECTED_NETWORK_OR_CHILD|selected-secret-canary/);
for (const layout of ["runner", "server"]) {
const packageDirectory = join(root, layout);
const outputRoot = layout === "server" ? join(packageDirectory, "dist/vendor/paperclip-runner") : join(packageDirectory, "dist");
const helper = join(outputRoot, "drivers/acpx/kimi-metadata-probe.js");
const cli = join(outputRoot, "cli/kimi-metadata-probe.cjs");
await mkdir(dirname(cli), { recursive: true });
await writeFile(join(packageDirectory, "package.json"), '{"type":"module"}');
await writeFile(cli, bytes);
await build({ entryPoints: [join(packageRoot, "src/drivers/acpx/kimi-metadata-probe.ts")], outfile: helper,
bundle: true, platform: "node", format: "esm", target: "node24", logLevel: "silent" });
const api = await import(pathToFileURL(helper).href);
assert.equal(await api.kimiMetadataProbeDigest(), sha(bytes), `${layout} fixed artifact`);
await writeFile(cli, "different artifact bytes");
assert.equal(await api.kimiMetadataProbeDigest(), sha("different artifact bytes"), `${layout} digest is fresh`);
await rm(cli);
await symlink(entry, cli);
await assert.rejects(api.kimiMetadataProbeDigest(), /ELOOP|symbolic/i);
}
});
@@ -0,0 +1,119 @@
import assert from "node:assert/strict";
import { once } from "node:events";
import { mkdir, mkdtemp, readFile, realpath, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join, resolve } from "node:path";
import { pathToFileURL } from "node:url";
export async function smokeKimiProviderPack(directory) {
const pack = await realpath(resolve(directory));
const manifest = JSON.parse(await readFile(join(pack, "provider-pack.json"), "utf8"));
assert.equal(manifest.schema, "paperclip-runner/remote-provider-pack/v1");
assert.equal(manifest.payload.target.platform, process.platform);
assert.equal(manifest.payload.target.architecture, process.arch);
if (process.env.PAPERCLIP_EXPECTED_SOURCE_REVISION) assert.equal(manifest.payload.runnerSourceRevision, process.env.PAPERCLIP_EXPECTED_SOURCE_REVISION);
const candidate = manifest.payload.candidateProviders?.kimi;
assert.equal(candidate?.qualification, "pending");
assert.equal(candidate.version, "2.3.3");
assert.equal(candidate.path, `provider-assets/kimi/${process.platform}-${process.arch}`);
assert.equal(manifest.payload.providers?.kimi, undefined);
const load = path => import(pathToFileURL(join(pack, "dist/drivers/acpx", path)));
const [{ verifyKimiInstallation }, { QUALIFIED_ACPX_PROFILES }, { kimiManagedConfiguration }, { kimiInstructionBinding }, { KIMI_DISTRIBUTION_CLOSURE_SHA256 }] = await Promise.all([
load("kimi-installation.js"), load("qualified-profiles.js"), load("kimi-config.js"), load("kimi-instructions.js"), load("kimi-closure-pins.js"),
]);
assert.equal(candidate.profileDigest, QUALIFIED_ACPX_PROFILES.kimi.commandDigest);
assert.equal(candidate.closureDigest, `sha256:${KIMI_DISTRIBUTION_CLOSURE_SHA256[`${process.platform}-${process.arch}`]}`);
const keys = ["PAPERCLIP_ACPX_PROVIDER_PACKAGE_ROOT", "PAPERCLIP_ACPX_PROVIDER_PACKAGE_MANIFEST"];
const previous = keys.map(key => process.env[key]);
process.env[keys[0]] = pack; process.env[keys[1]] = join(pack, "package.json");
const root = await realpath(await mkdtemp(join(tmpdir(), "paperclip-kimi-pack-smoke-")));
const home = join(root, "home"), workspace = join(root, "workspace");
await mkdir(home); await mkdir(workspace);
const model = "kimi-for-coding";
const binding = kimiInstructionBinding("Do not call a model during this installed-package smoke. Exact suffix: café.\n");
await writeFile(join(home, "config.toml"), kimiManagedConfiguration(model), { mode: 0o600 });
const active = new Set(); let sequence = 0;
try {
const installation = await verifyKimiInstallation(QUALIFIED_ACPX_PROFILES.kimi);
const connect = async () => {
const lease = await installation.openCommand();
const child = lease.spawn([], { cwd: workspace, stdio: "pipe", env: {
PATH: "/usr/bin:/bin", LANG: "C.UTF-8", KIMI_CODE_HOME: home,
KIMI_CODE_NO_AUTO_UPDATE: "1", KIMI_API_KEY: "paperclip-offline-placeholder",
PAPERCLIP_KIMI_INSTRUCTIONS: binding.payload, CI: "1", NO_COLOR: "1", TERM: "dumb",
} });
const closed = once(child, "close"), pending = new Map();
let buffer = "", bytes = 0;
const fail = error => { for (const request of pending.values()) request.reject(error); pending.clear(); };
child.on("error", fail); child.on("close", () => fail(new Error("Kimi exited with a pending ACP request")));
child.stderr.resume();
child.stdout.on("data", chunk => {
bytes += chunk.length;
if (bytes > 1024 * 1024) { fail(new Error("Kimi ACP output exceeded its package smoke bound")); return; }
buffer += chunk.toString("utf8");
let newline;
while ((newline = buffer.indexOf("\n")) >= 0) {
const line = buffer.slice(0, newline); buffer = buffer.slice(newline + 1);
if (!line.trim()) continue;
let value;
try { value = JSON.parse(line); } catch { fail(new Error("Kimi emitted malformed ACP JSON")); return; }
const request = pending.get(value.id);
if (request && value.method === undefined) {
pending.delete(value.id);
if (value.error) request.reject(new Error(`Kimi rejected ACP request (${value.error.code})`));
else request.resolve(value.result);
}
}
});
const request = (method, params) => new Promise((accept, reject) => {
const id = sequence++;
const timeout = setTimeout(() => { pending.delete(id); reject(new Error(`Kimi ${method} timed out`)); }, 15_000);
const settle = callback => value => { clearTimeout(timeout); callback(value); };
pending.set(id, { resolve: settle(accept), reject: settle(reject) });
child.stdin.write(`${JSON.stringify({ jsonrpc: "2.0", id, method, params })}\n`);
});
let closing;
const close = () => closing ??= (async () => {
const started = Date.now(); child.stdin.end();
const term = setTimeout(() => child.kill("SIGTERM"), 4_000), kill = setTimeout(() => child.kill("SIGKILL"), 5_000);
try {
const [code, signal] = await closed;
assert.equal(code, 0, "Kimi did not exit cleanly after EOF"); assert.equal(signal, null);
return Date.now() - started;
} finally { clearTimeout(term); clearTimeout(kill); await lease.close(); active.delete(close); }
})();
active.add(close);
const initialized = await request("initialize", { protocolVersion: 1, clientCapabilities: {}, clientInfo: { name: "paperclip-provider-pack-smoke", version: "1" } });
assert.equal(initialized.agentInfo?.version, "2.3.3");
return { request, close };
};
const assertBinding = (result, sessionId) => {
const ack = result._meta?.paperclipKimiInstructions;
assert.equal(ack?.sessionId, sessionId); assert.equal(ack.digest, binding.digest); assert.equal(ack.byteLength, binding.byteLength);
assert.match(ack.effectiveDigest, /^sha256:[a-f0-9]{64}$/);
};
const first = await connect();
const created = await first.request("session/new", { cwd: workspace, mcpServers: [] });
assertBinding(created, created.sessionId);
const selected = await first.request("session/set_config_option", { sessionId: created.sessionId, configId: "model", value: model });
assert.equal(selected.configOptions.find(option => option.id === "model").currentValue, model);
const createExitMs = await first.close();
const second = await connect();
const loaded = await second.request("session/load", { sessionId: created.sessionId, cwd: workspace, mcpServers: [] });
assertBinding(loaded, created.sessionId);
assert.equal(loaded.configOptions.find(option => option.id === "model").currentValue, model);
const loadExitMs = await second.close();
return { schema: "paperclip.kimi-provider-pack-smoke.v1", sourceRevision: manifest.payload.runnerSourceRevision, providerPackDigest: manifest.digest,
platform: process.platform, architecture: process.arch, runtimeVersion: "2.3.3", profileDigest: candidate.profileDigest, closureDigest: candidate.closureDigest,
createAcknowledged: true, loadAcknowledged: true, model, createExitMs, loadExitMs, providerPrompts: 0, providerCredentials: false,
qualification: "installed runtime only; no model entitlement or task completion" };
} finally {
try { await Promise.all([...active].map(close => close())); }
finally { keys.forEach((key, index) => { if (previous[index] === undefined) delete process.env[key]; else process.env[key] = previous[index]; }); await rm(root, { recursive: true, force: true }); }
}
}
if (process.argv[1] && import.meta.url === pathToFileURL(resolve(process.argv[1])).href) {
if (process.argv.length !== 3) throw new Error("Usage: node scripts/kimi-provider-pack-smoke.mjs /absolute/installed-provider-pack");
smokeKimiProviderPack(process.argv[2]).then(result => console.log(JSON.stringify(result))).catch(error => { console.error(error.message); process.exitCode = 1; });
}
@@ -0,0 +1,182 @@
import { execFile } from "node:child_process";
import { createHash } from "node:crypto";
import { chmod, copyFile, lstat, mkdir, mkdtemp, readFile, readdir, realpath, rename, rm, unlink, writeFile } from "node:fs/promises";
import { dirname, isAbsolute, join, resolve } from "node:path";
import { fileURLToPath, pathToFileURL } from "node:url";
import { promisify } from "node:util";
import { KIMI_DISTRIBUTION_CLOSURE_SHA256, KIMI_DISTRIBUTION_LOCK_SHA256, KIMI_NODE_DISTRIBUTIONS, KIMI_NODE_VERSION, KIMI_RUNTIME_VERSION } from "../src/drivers/acpx/kimi-closure-pins.ts";
import { inventoryKimiRuntimeFiles, kimiRuntimeClosureDigest } from "../src/drivers/acpx/kimi-runtime-files.ts";
import { patchKimiRuntime } from "./patch-kimi-runtime.mjs";
const run = promisify(execFile);
const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
const repositoryRoot = resolve(packageRoot, "../..");
const hash = bytes => createHash("sha256").update(bytes).digest("hex");
export const KIMI_DISTRIBUTION_ENTRYPOINT = "node_modules/@moonshot-ai/kimi-code/dist/main.mjs";
export async function runKimiBuildCommand(command, args, options, checkCancelled = () => {}, signal) {
checkCancelled(); signal?.throwIfAborted();
const pending = run(command, args, { ...options, signal, killSignal: "SIGKILL" });
const closed = new Promise(resolve => pending.child.once("close", resolve));
try {
const result = await pending;
checkCancelled(); signal?.throwIfAborted();
return result;
} finally { await closed; }
}
export function kimiDistributionInstallCommand() {
return ["ci", "--ignore-scripts", "--omit=optional", "--omit=dev", "--no-audit", "--no-fund", "--registry=https://registry.npmjs.org", "--userconfig=.npmrc", "--globalconfig=.npmrc-global"];
}
export function kimiDistributionEnvironment(source = process.env) {
return Object.fromEntries(["PATH", "LANG", "LC_ALL", "HTTPS_PROXY", "HTTP_PROXY", "NO_PROXY", "https_proxy", "http_proxy", "no_proxy", "SSL_CERT_FILE", "SSL_CERT_DIR", "NODE_EXTRA_CA_CERTS"].flatMap(key => typeof source[key] === "string" ? [[key, source[key]]] : []));
}
export async function verifyLockedKimiPackageGraph(root, lock) {
if (lock.lockfileVersion !== 3 || !lock.packages || lock.packages[""]?.dependencies?.["@moonshot-ai/kimi-code"] !== KIMI_RUNTIME_VERSION) throw new Error("Kimi distribution lock is invalid");
let packages = 0;
for (const [path, entry] of Object.entries(lock.packages)) {
if (!path) continue;
if (!path.startsWith("node_modules/") || /[\\\u0000-\u001f\u007f]/.test(path) || path.split("/").some(part => !part || part === "." || part === "..") || entry.link || typeof entry.version !== "string" || !/^https:\/\/registry\.npmjs\.org\//.test(entry.resolved ?? "") || !/^sha512-[A-Za-z0-9+/]+=*$/.test(entry.integrity ?? "")) throw new Error("Kimi distribution lock contains an unpinned package");
if (entry.optional === true) {
try { await lstat(join(root, path)); } catch (error) { if (error.code === "ENOENT") continue; throw error; }
throw new Error("Kimi headless distribution unexpectedly installed an optional TUI dependency");
}
const file = join(root, path, "package.json");
if (await realpath(file) !== file || !(await lstat(file)).isFile()) throw new Error("Kimi distribution package metadata is not a regular file");
const actual = JSON.parse(await readFile(file, "utf8"));
if (actual.version !== entry.version) throw new Error(`Kimi distribution package differs from its lock: ${path}`);
packages++;
}
return packages;
}
export function assertKimiNodeSystemDependencies(listing, platform) {
for (const line of listing.split("\n").map(value => value.trim()).filter(Boolean)) {
if (platform === "darwin") {
if (line.endsWith(":")) continue;
if (!line.startsWith("/usr/lib/") && !line.startsWith("/System/Library/")) throw new Error("Kimi Node depends on an unbundled library");
} else if (!line.startsWith("linux-vdso.so.") && !/^(?:[^\s]+ => )?\/(?:usr\/)?lib(?:64)?\//.test(line)) throw new Error("Kimi Node depends on an unbundled library");
}
}
async function nodeDistribution(staging, target, archivePath, environment, runOwned, signal) {
const pin = KIMI_NODE_DISTRIBUTIONS[target];
if (!pin) throw new Error(`Kimi distribution target is unsupported: ${target}`);
let bytes;
if (archivePath) bytes = await readFile(archivePath);
else {
const timeout = AbortSignal.timeout(60_000);
const response = await fetch(`https://nodejs.org/dist/v${KIMI_NODE_VERSION}/node-v${KIMI_NODE_VERSION}-${target}.tar.gz`, { redirect: "error", signal: signal ? AbortSignal.any([signal, timeout]) : timeout });
if (!response.ok || !response.body) throw new Error("Pinned Kimi Node download failed");
const chunks = []; let length = 0;
for await (const chunk of response.body) {
length += chunk.length;
if (length > 128 * 1024 * 1024) throw new Error("Kimi Node archive exceeds its bound");
chunks.push(Buffer.from(chunk));
}
bytes = Buffer.concat(chunks);
}
if (bytes.length > 128 * 1024 * 1024 || hash(bytes) !== pin.archiveSha256) throw new Error("Kimi Node archive does not match its release pin");
const archive = join(staging, `${target}.tar.gz`); await writeFile(archive, bytes);
const output = join(staging, `node-${target}`); await mkdir(output);
await runOwned("tar", ["-xzf", archive, "-C", output, "--strip-components=1", `node-v${KIMI_NODE_VERSION}-${target}/bin/node`, `node-v${KIMI_NODE_VERSION}-${target}/lib/node_modules/npm`], { env: environment, timeout: 30_000 });
const executable = join(output, "bin/node");
if (hash(await readFile(executable)) !== pin.executableSha256 || (await lstat(executable)).size !== pin.executableSize) throw new Error("Kimi Node executable does not match its target pin");
const npm = join(output, "lib/node_modules/npm/bin/npm-cli.js");
if (JSON.parse(await readFile(join(output, "lib/node_modules/npm/package.json"), "utf8")).version !== "11.19.0") throw new Error("Kimi Node archive has an unexpected npm version");
return { executable, npm };
}
async function removePackageManagerLinks(root) {
const visit = async directory => {
for (const name of await readdir(directory)) {
const path = join(directory, name), stat = await lstat(path);
if (stat.isSymbolicLink()) {
if (dirname(path).endsWith("/node_modules/.bin")) await unlink(path);
else throw new Error("Kimi package payload contains an unsupported symbolic link");
} else if (stat.isDirectory()) await visit(path);
else if (!stat.isFile()) throw new Error("Kimi package payload contains a non-file resource");
}
};
await visit(root);
await rm(join(root, "node_modules/.package-lock.json"), { force: true });
}
export async function buildKimiDistribution({ outputRoot, target = `${process.platform}-${process.arch}`, lockDirectory = join(packageRoot, "scripts/kimi-distribution"), nodeArchives = {}, checkCancelled = () => {}, signal }) {
checkCancelled(); signal?.throwIfAborted();
if (typeof outputRoot !== "string" || !isAbsolute(outputRoot)) throw new Error("Kimi distribution output must be absolute");
const output = resolve(outputRoot);
if (["/", packageRoot, repositoryRoot].includes(output)) throw new Error("Refusing unsafe Kimi distribution output");
if (!Object.hasOwn(KIMI_NODE_DISTRIBUTIONS, target)) throw new Error("Kimi distribution target is unsupported");
const host = `${process.platform}-${process.arch}`;
if (!Object.hasOwn(KIMI_NODE_DISTRIBUTIONS, host)) throw new Error("Kimi distribution build host is unsupported");
try { await lstat(output); throw new Error("Kimi distribution output already exists"); } catch (error) { if (error.code !== "ENOENT") throw error; }
const lockBytes = await readFile(join(lockDirectory, "package-lock.json"));
if (hash(lockBytes) !== KIMI_DISTRIBUTION_LOCK_SHA256) throw new Error("Kimi distribution lock differs from its source pin");
await mkdir(dirname(output), { recursive: true });
const staging = await mkdtemp(join(await realpath(dirname(output)), ".paperclip-kimi-distribution-"));
const environment = kimiDistributionEnvironment();
const runOwned = (command, args, options) => runKimiBuildCommand(command, args, options, checkCancelled, signal);
const runtime = join(staging, "runtime");
try {
const buildHome = join(staging, "build-home"); await mkdir(buildHome); environment.HOME = buildHome;
const installedNode = await nodeDistribution(staging, target, nodeArchives[target], environment, runOwned, signal);
const buildNode = host === target ? installedNode : await nodeDistribution(staging, host, nodeArchives[host], environment, runOwned, signal);
if ((await runOwned(buildNode.executable, ["--version"], { env: {}, timeout: 10_000 })).stdout.trim() !== `v${KIMI_NODE_VERSION}`) throw new Error("Kimi distribution build Node cannot execute");
await mkdir(runtime);
for (const name of ["package.json", "package-lock.json"]) await copyFile(join(lockDirectory, name), join(runtime, name));
await writeFile(join(runtime, ".npmrc"), "registry=https://registry.npmjs.org/\nignore-scripts=true\naudit=false\nfund=false\n");
await writeFile(join(runtime, ".npmrc-global"), "");
await runOwned(buildNode.executable, [buildNode.npm, ...kimiDistributionInstallCommand()], { cwd: runtime, env: environment, timeout: 300_000, maxBuffer: 4 * 1024 * 1024 });
if (!(await readFile(join(runtime, "package-lock.json"))).equals(lockBytes)) throw new Error("Kimi installation changed its committed lock");
const packageCount = await verifyLockedKimiPackageGraph(runtime, JSON.parse(lockBytes.toString("utf8")));
const patch = await patchKimiRuntime(join(runtime, KIMI_DISTRIBUTION_ENTRYPOINT));
await mkdir(join(runtime, "node/bin"), { recursive: true });
await copyFile(installedNode.executable, join(runtime, "node/bin/node")); await chmod(join(runtime, "node/bin/node"), 0o755);
if (host === target) {
const listing = process.platform === "darwin"
? await runOwned("/usr/bin/otool", ["-L", join(runtime, "node/bin/node")], { env: {}, timeout: 10_000 })
: await runOwned("ldd", [join(runtime, "node/bin/node")], { env: { PATH: "/usr/bin:/bin" }, timeout: 10_000 });
assertKimiNodeSystemDependencies(listing.stdout, process.platform);
if ((await runOwned(join(runtime, "node/bin/node"), ["--version"], { env: {}, timeout: 10_000 })).stdout.trim() !== `v${KIMI_NODE_VERSION}`) throw new Error("Kimi Node cannot execute after relocation");
}
await removePackageManagerLinks(runtime);
const entries = await inventoryKimiRuntimeFiles(runtime);
const closure = kimiRuntimeClosureDigest(entries);
const metadata = { schema: "paperclip.kimi-distribution.v1", version: KIMI_RUNTIME_VERSION, target, nodeVersion: KIMI_NODE_VERSION, runtimeRoot: "runtime", entrypoint: KIMI_DISTRIBUTION_ENTRYPOINT, lockSha256: KIMI_DISTRIBUTION_LOCK_SHA256, patch, packageCount, nativeClosureSha256: closure };
await writeFile(join(staging, "native-closure.json"), `${JSON.stringify({ entries })}\n`);
await writeFile(join(staging, "kimi-distribution.json"), `${JSON.stringify(metadata, null, 2)}\n`);
for (const name of await readdir(staging)) if (!["runtime", "native-closure.json", "kimi-distribution.json"].includes(name)) await rm(join(staging, name), { recursive: true, force: true });
checkCancelled();
await rename(staging, output);
return { outputRoot: output, runtimeRoot: join(output, "runtime"), version: KIMI_RUNTIME_VERSION, closureDigest: `sha256:${closure}`, metadata };
} catch (error) { await rm(staging, { recursive: true, force: true }); throw error; }
}
export async function materializeKimiDistribution(options) {
if (typeof options.outputRoot !== "string" || !isAbsolute(options.outputRoot)) throw new Error("Kimi distribution output must be absolute");
const output = resolve(options.outputRoot);
if (["/", packageRoot, repositoryRoot].includes(output)) throw new Error("Refusing unsafe Kimi distribution output");
const target = options.target ?? `${process.platform}-${process.arch}`;
if (!Object.hasOwn(KIMI_DISTRIBUTION_CLOSURE_SHA256, target)) throw new Error("Kimi distribution target is unsupported");
try { await lstat(output); throw new Error("Kimi distribution output already exists"); } catch (error) { if (error.code !== "ENOENT") throw error; }
await mkdir(dirname(output), { recursive: true });
const parent = await realpath(dirname(output));
const temporary = await mkdtemp(join(parent, ".paperclip-kimi-admission-"));
const candidate = join(temporary, "candidate");
try {
const result = await buildKimiDistribution({ ...options, outputRoot: candidate });
if (result.metadata.nativeClosureSha256 !== KIMI_DISTRIBUTION_CLOSURE_SHA256[target]) throw new Error("Kimi native closure differs from its trusted target pin");
try { await lstat(options.outputRoot); throw new Error("Kimi distribution output already exists"); } catch (error) { if (error.code !== "ENOENT") throw error; }
await rename(candidate, options.outputRoot);
return { ...result, outputRoot: options.outputRoot, runtimeRoot: join(options.outputRoot, "runtime") };
} finally { await rm(temporary, { recursive: true, force: true }); }
}
if (import.meta.url.endsWith("/materialize-kimi-distribution.mjs") && process.argv[1] && pathToFileURL(resolve(process.argv[1])).href === import.meta.url) {
const args = process.argv.slice(2);
if (args.length !== 1) throw new Error("Usage: node scripts/materialize-kimi-distribution.mjs /absolute/output-directory");
materializeKimiDistribution({ outputRoot: args[0] }).then(result => console.log(JSON.stringify(result))).catch(error => { console.error(error.message); process.exitCode = 1; });
}
@@ -0,0 +1,121 @@
import assert from "node:assert/strict";
import { createHash } from "node:crypto";
import { chmod, link, mkdir, mkdtemp, readFile, readdir, realpath, rm, symlink, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { dirname, join } from "node:path";
import test from "node:test";
import { setTimeout as delay } from "node:timers/promises";
import { assertKimiNodeSystemDependencies, buildKimiDistribution, kimiDistributionEnvironment, kimiDistributionInstallCommand, materializeKimiDistribution, runKimiBuildCommand, verifyLockedKimiPackageGraph } from "./materialize-kimi-distribution.mjs";
import { KIMI_DISTRIBUTION_LOCK_SHA256, KIMI_NODE_DISTRIBUTIONS } from "../src/drivers/acpx/kimi-closure-pins.ts";
import { inventoryKimiRuntimeFiles, kimiRuntimeClosureDigest } from "../src/drivers/acpx/kimi-runtime-files.ts";
async function fixture(t) {
const root = await realpath(await mkdtemp(join(tmpdir(), "paperclip-kimi-distribution-test-")));
t.after(() => rm(root, { recursive: true, force: true }));
const write = async (path, content) => { const file = join(root, path); await mkdir(dirname(file), { recursive: true }); await writeFile(file, content); };
return { root, write };
}
test("Kimi's portable graph pins public integrity and excludes lifecycle and optional TUI dependencies", async () => {
const bytes = await readFile(new URL("./kimi-distribution/package-lock.json", import.meta.url));
assert.equal(createHash("sha256").update(bytes).digest("hex"), KIMI_DISTRIBUTION_LOCK_SHA256);
const lock = JSON.parse(bytes.toString("utf8"));
const pkg = JSON.parse(await readFile(new URL("./kimi-distribution/package.json", import.meta.url), "utf8"));
assert.deepEqual(pkg.dependencies, { "@moonshot-ai/kimi-code": "2.3.3" });
assert.deepEqual(lock.packages[""].dependencies, pkg.dependencies);
assert.equal(lock.packages["node_modules/@moonshot-ai/kimi-code"].integrity, "sha512-3V8bycucf9KgPRH27S8De2u0ip84/Ry3FpNn6gi5z9JmoEHt9vxiYHHZqiMdyDf5nPm4bv+YKGwKEQL4oYpRTw==");
assert.equal(kimiDistributionInstallCommand()[0], "ci");
assert.ok(kimiDistributionInstallCommand().includes("--ignore-scripts"));
assert.ok(kimiDistributionInstallCommand().includes("--omit=optional"));
assert.ok(kimiDistributionInstallCommand().includes("--registry=https://registry.npmjs.org"));
assert.deepEqual(Object.keys(KIMI_NODE_DISTRIBUTIONS).sort(), ["darwin-arm64", "linux-x64"]);
});
test("distribution build admits network settings without provider keys or Node injection", () => {
const network = { PATH: "/usr/bin:/bin", LANG: "C.UTF-8", HTTPS_PROXY: "http://proxy.invalid", NODE_EXTRA_CA_CERTS: "/public/ca.pem" };
assert.deepEqual(kimiDistributionEnvironment({ ...network, HOME: "/private/home", KIMI_MODEL_API_KEY: "canary-secret", NPM_TOKEN: "canary-secret", NODE_OPTIONS: "--require /foreign.js", NODE_PATH: "/foreign", NODE_TLS_REJECT_UNAUTHORIZED: "0" }), network);
});
test("setup cancellation physically stops an in-flight owned child", { timeout: 5_000 }, async t => {
const { root } = await fixture(t), pidFile = join(root, "pid");
const controller = new AbortController();
const result = runKimiBuildCommand(process.execPath, ["-e", "require('node:fs').writeFileSync(process.argv[1],String(process.pid));setInterval(()=>{},1000)", pidFile], { env: {}, timeout: 3_000 }, undefined, controller.signal).then(() => null, error => error);
let pid;
try {
for (let attempt = 0; attempt < 100; attempt++) {
try { pid = Number(await readFile(pidFile, "utf8")); break; }
catch (error) { if (error.code !== "ENOENT") throw error; await delay(10); }
}
assert.ok(Number.isSafeInteger(pid) && pid > 0, "The real child did not start");
controller.abort();
assert.equal((await result).code, "ABORT_ERR");
assert.throws(() => process.kill(pid, 0), error => error.code === "ESRCH");
} finally { controller.abort(); await result; }
});
test("setup cancellation aborts the pending download and removes its staging tree", { timeout: 5_000 }, async t => {
const { root } = await fixture(t), controller = new AbortController();
let started;
const downloading = new Promise(resolve => { started = resolve; });
t.mock.method(globalThis, "fetch", (_url, options) => new Promise((_resolve, reject) => {
started(); options.signal.addEventListener("abort", () => reject(options.signal.reason), { once: true });
}));
const result = buildKimiDistribution({ outputRoot: join(root, "output"), signal: controller.signal });
await downloading; controller.abort();
await assert.rejects(result, error => error.name === "AbortError");
assert.deepEqual(await readdir(root), []);
});
test("the installed graph rejects version drift and optional packages", async t => {
const { root, write } = await fixture(t);
const entry = { version: "2.3.3", resolved: "https://registry.npmjs.org/@moonshot-ai/kimi-code/-/kimi-code-2.3.3.tgz", integrity: "sha512-YWJjZA==" };
const lock = { lockfileVersion: 3, packages: { "": { dependencies: { "@moonshot-ai/kimi-code": "2.3.3" } }, "node_modules/@moonshot-ai/kimi-code": entry, "node_modules/optional-native": { ...entry, optional: true } } };
await write("node_modules/@moonshot-ai/kimi-code/package.json", '{"version":"2.3.3"}');
assert.equal(await verifyLockedKimiPackageGraph(root, lock), 1);
await write("node_modules/@moonshot-ai/kimi-code/package.json", '{"version":"2.3.4"}');
await assert.rejects(verifyLockedKimiPackageGraph(root, lock), /differs from its lock/);
await write("node_modules/@moonshot-ai/kimi-code/package.json", '{"version":"2.3.3"}');
await write("node_modules/optional-native/package.json", '{"version":"2.3.3"}');
await assert.rejects(verifyLockedKimiPackageGraph(root, lock), /optional TUI dependency/);
});
test("inventory binds native assets, workers, permissions and bytes in stable path order", async t => {
const { root, write } = await fixture(t);
await write("node_modules/provider/worker.mjs", "worker");
await write("node_modules/provider/native/addon.node", Buffer.from([0, 1, 2, 3]));
await write("node/bin/node", "node");
const first = await inventoryKimiRuntimeFiles(root);
assert.deepEqual(first.map(entry => entry.path), ["node/bin/node", "node_modules/provider/native/addon.node", "node_modules/provider/worker.mjs"]);
const digest = kimiRuntimeClosureDigest(first);
await write("node_modules/provider/worker.mjs", "worker changed");
assert.notEqual(kimiRuntimeClosureDigest(await inventoryKimiRuntimeFiles(root)), digest);
await chmod(join(root, "node/bin/node"), 0o755);
assert.equal((await inventoryKimiRuntimeFiles(root))[0].executable, true);
});
test("inventory rejects external links, hardlinks and special files", async t => {
const { root, write } = await fixture(t);
await write("original", "content");
await symlink("/outside", join(root, "escape"));
await assert.rejects(inventoryKimiRuntimeFiles(root), /symbolic link/);
await rm(join(root, "escape"));
await link(join(root, "original"), join(root, "alias"));
await assert.rejects(inventoryKimiRuntimeFiles(root), /invalid file/);
});
test("setup refuses relative, root, unsupported and existing outputs before network work", async t => {
const { root } = await fixture(t);
for (const operation of [buildKimiDistribution, materializeKimiDistribution]) {
await assert.rejects(operation({ outputRoot: "relative" }), /must be absolute/);
await assert.rejects(operation({ outputRoot: "/" }), /unsafe/);
await assert.rejects(operation({ outputRoot: join(root, "output"), target: "linux-arm64" }), /unsupported/);
await assert.rejects(operation({ outputRoot: root }), /already exists/);
}
});
test("the bundled Node may depend only on platform system libraries", () => {
assert.doesNotThrow(() => assertKimiNodeSystemDependencies("node:\n /usr/lib/libSystem.B.dylib (version 0)\n", "darwin"));
assert.throws(() => assertKimiNodeSystemDependencies("node:\n /opt/homebrew/lib/libnode.dylib (version 0)\n", "darwin"), /unbundled/);
assert.doesNotThrow(() => assertKimiNodeSystemDependencies("linux-vdso.so.1 (0x0)\nlibc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x0)\n/lib64/ld-linux-x86-64.so.2 (0x0)\n", "linux"));
assert.throws(() => assertKimiNodeSystemDependencies("libcustom.so => /opt/private/libcustom.so (0x0)\n", "linux"), /unbundled/);
});
@@ -0,0 +1,160 @@
import { createHash } from "node:crypto";
import { readFile, writeFile } from "node:fs/promises";
import { pathToFileURL } from "node:url";
import { KIMI_INSTRUCTION_RUNTIME_SOURCE } from "./kimi-instructions-runtime.mjs";
export const KIMI_RUNTIME_PATCH = Object.freeze({
version: "paperclip-kimi-2.3.3-instructions-v6",
vendorSha256: "f18b711e22947d473175126d0c2da437d641187963a3bc300d66e183060703e3",
patchedSha256: "79980aa95c54f325a05cbdf883f74443705db28f3e412a1b5ae22929d939eb66",
});
const sha256 = value => createHash("sha256").update(value).digest("hex");
export function replaceKimiPatchAnchor(source, before, after) {
if (source.split(before).length !== 2) throw new Error("Kimi runtime patch requires exactly one source anchor");
return source.replace(before, () => after);
}
export function patchKimiRuntimeSource(input) {
if (sha256(input) !== KIMI_RUNTIME_PATCH.vendorSha256) throw new Error("Kimi runtime patch input digest mismatch");
let source = input;
const replace = (before, after) => { source = replaceKimiPatchAnchor(source, before, after); };
replace("#!/usr/bin/env node\n", `#!/usr/bin/env node
import { createHash as paperclipKimiCreateHash } from "node:crypto";
let paperclipKimiInstructionSnapshot;
function paperclipKimiInstructionState() {
if (paperclipKimiInstructionSnapshot) return paperclipKimiInstructionSnapshot;
const raw = process.env.PAPERCLIP_KIMI_INSTRUCTIONS;
delete process.env.PAPERCLIP_KIMI_INSTRUCTIONS;
return paperclipKimiInstructionSnapshot = (${KIMI_INSTRUCTION_RUNTIME_SOURCE})(raw, {
createHash: paperclipKimiCreateHash, byteLength: value => Buffer.byteLength(value, "utf8")
});
}
function paperclipKimiChildEnvironment(overrides) {
const environment = { ...process.env, ...overrides };
delete environment.KIMI_API_KEY;
delete environment.PAPERCLIP_KIMI_INSTRUCTIONS;
return environment;
}
`);
replace('function buildEnv(overrides) {\n\tif (overrides === void 0) return;\n\treturn {\n\t\t...process.env,\n\t\t...overrides\n\t};\n}',
'function buildEnv(overrides) {\n\treturn paperclipKimiChildEnvironment(overrides);\n}');
replace('env: globalThis.process.env', 'env: paperclipKimiChildEnvironment()');
replace('\t\tbindTerminalCapability(terminal) {\n\t\t\tthis._terminalEnabled = terminal === true;\n\t\t}',
'\t\tbindTerminalCapability(terminal) {\n\t\t\tthis._terminalEnabled = false;\n\t\t}');
replace("\t\tget systemPrompt() {\n\t\t\treturn this.profileState.systemPrompt;\n\t\t}",
"\t\tget systemPrompt() {\n\t\t\treturn paperclipKimiInstructionState().append(this.profileState.systemPrompt);\n\t\t}");
replace("async function runAcpServerWithStream(stream, opts = {}) {\n",
"async function runAcpServerWithStream(stream, opts = {}) {\n\tpaperclipKimiInstructionState();\n");
replace('\t\tmerged() {\n\t\t\treturn {\n\t\t\t\t...Object.fromEntries(this.pluginServers),\n\t\t\t\t...Object.fromEntries(this.fileServers)\n\t\t\t};\n\t\t}',
'\t\tmerged() {\n\t\t\treturn {};\n\t\t}');
replace('\tawait pushFirstExisting$1(roots, USER_GENERIC_DIRS$1, osHomeDir, "user");', '');
replace('async function projectRoots(workDir, options = {}) {\n', 'async function projectRoots(workDir, options = {}) {\n\treturn [];\n');
replace('async function projectAgentRoots(fs, workDir, warn) {\n', 'async function projectAgentRoots(fs, workDir, warn) {\n\treturn [];\n');
replace('async function userAgentRoots(fs, homeDir, osHomeDir, warn) {\n', 'async function userAgentRoots(fs, homeDir, osHomeDir, warn) {\n\treturn [];\n');
replace('this.byEvent = indexHooks([...configured ?? [], ...pluginHooks]);', 'this.byEvent = new Map();');
replace('\t\tasync evaluate(context) {\n\t\t\tfor (const policy of this.policies) {',
'\t\tasync evaluate(context) {\n\t\t\treturn { policyName: "paperclip-runner", result: { kind: "ask" } };\n\t\t\tfor (const policy of this.policies) {');
replace('if (req.display.kind !== "plan_review") return CANONICAL_OPTIONS;',
'if (req.display.kind !== "plan_review") return CANONICAL_OPTIONS.filter(option => option.kind !== "allow_always");');
replace('\t\t\t\ttoolName: name,\n\t\t\t\taction,\n\t\t\t\tdisplay\n\t\t\t};\n\t\t\tconst approvalContext = {',
'\t\t\t\ttoolName: name,\n\t\t\t\ttoolInput: context.args,\n\t\t\t\taction,\n\t\t\t\tdisplay\n\t\t\t};\n\t\t\tconst approvalContext = {');
replace('\t\ttitle: req.toolName,\n\t\tcontent\n', '\t\ttitle: req.toolName,\n\t\tkind: inferToolKind(req.toolName),\n\t\trawInput: req.toolInput,\n\t\tcontent\n');
const bindRuntime = '\t\t\thandle.accessor.get(IAgentLifecycleService).handleOf(agentContext.agentId).accessor.get(IAgentRuntimeBindingService).switch(runtimeId);';
replace(bindRuntime, `${bindRuntime}
\t\t\tconst paperclipProfile = handle.accessor.get(IAgentLifecycleService).handleOf(agentContext.agentId).accessor.get(IAgentProfileService);
\t\t\treturn paperclipKimiInstructionState().receipt(sessionId, paperclipProfile.getSystemPrompt());`);
replace("\t\t\tawait this.bindSessionRuntime?.(sessionId);\n",
"\t\t\tconst paperclipReceipt = await this.bindSessionRuntime?.(sessionId);\n\t\t\tif (!paperclipReceipt || paperclipReceipt.sessionId !== sessionId) throw new Error(\"Kimi native instruction receipt is missing\");\n\t\t\tthis.paperclipInstructionReceipts ??= new Map();\n\t\t\tthis.paperclipInstructionReceipts.set(sessionId, paperclipReceipt);\n");
replace("\t\t\t\t...await this.activateSession(meta.id)\n",
"\t\t\t\t...await this.activateSession(meta.id),\n\t\t\t\t_meta: { paperclipKimiInstructions: this.paperclipInstructionReceipts.get(meta.id) }\n");
const lifecycleState = "\t\t\t\tconfigOptions: await acpSession.configOptions(),\n\t\t\t\tmodes: acpSession.modeState()\n\t\t\t};\n\t\t}\n\t\tasync ";
replace(`${lifecycleState}resumeSession(params)`,
`${lifecycleState.replace("modes: acpSession.modeState()", "modes: acpSession.modeState(),\n\t\t\t\t_meta: { paperclipKimiInstructions: this.paperclipInstructionReceipts.get(params.sessionId) }")}resumeSession(params)`);
replace(`${lifecycleState}listSessions(params)`,
`${lifecycleState.replace("modes: acpSession.modeState()", "modes: acpSession.modeState(),\n\t\t\t\t_meta: { paperclipKimiInstructions: this.paperclipInstructionReceipts.get(params.sessionId) }")}listSessions(params)`);
replace('\t\t\t\tdriver.resolve({ stopReason: turnEndReasonToStopReason(event.reason, error) });',
'\t\t\t\tif (event.reason === "failed") {\n\t\t\t\t\tdriver.reject(RequestError$1.internalError({ schema: "paperclip.kimi.provider-error.v1", kind: "provider_failed" }, "Kimi provider turn failed"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tdriver.resolve({ stopReason: turnEndReasonToStopReason(event.reason, error) });');
const stepSchema = 'object({ type: string(), turnId: number$1().int().nonnegative(), step: number$1().int().positive(), stepId: string().min(1).max(256).optional(), finishReason: string().max(32).optional(), reason: string().max(32).optional() })';
replace('\tagentEvents = {\n\t\t"turn.started": {', `\tagentEvents = {
\t\t"turn.step.started": { kind: "stream", name: "events", type: "turn.step.started", schema: ${stepSchema} },
\t\t"turn.step.completed": { kind: "stream", name: "events", type: "turn.step.completed", schema: ${stepSchema} },
\t\t"turn.step.interrupted": { kind: "stream", name: "events", type: "turn.step.interrupted", schema: ${stepSchema} },
\t\t"turn.started": {`);
replace('\t\t\tthis.subscriptions.push(events.on("assistant.delta", (event) => {', `\t\t\tthis.subscriptions.push(
\t\t\t\tevents.on("turn.step.started", event => this.dispatchTurnEvent(event.turnId, () => this.paperclipKimiStep(event, "start"))),
\t\t\t\tevents.on("turn.step.completed", event => this.dispatchTurnEvent(event.turnId, () => this.paperclipKimiStep(event, "end"))),
\t\t\t\tevents.on("turn.step.interrupted", event => this.dispatchTurnEvent(event.turnId, () => this.paperclipKimiStep(event, "interrupted"))),
\t\t\t\tevents.on("assistant.delta", (event) => {`);
replace('\t\tonAssistantDelta(event) {\n\t\t\tif (this.driverFor(event.turnId) === void 0) return;\n\t\t\tthis.emit(assistantDeltaToSessionUpdate(this.sessionId, event));\n\t\t}', `\t\tpaperclipKimiMessageFailure(driver) {
\t\t\tthis.settleDriver(driver, () => driver.reject(RequestError$1.internalError({ schema: "paperclip.kimi.provider-error.v1", kind: "message_boundary_invalid" }, "Kimi native message boundary is invalid")));
\t\t}
\t\tpaperclipKimiChunk(driver, text, kind, thought = false) {
\t\t\tthis.emit({ sessionId: this.sessionId, update: {
\t\t\t\tsessionUpdate: thought ? "agent_thought_chunk" : "agent_message_chunk",
\t\t\t\tmessageId: driver.paperclipKimiMessage.id, content: { type: "text", text },
\t\t\t\t_meta: { origin: "kimi-native-assistant", source: "kimi-turn-step-v1", kind }
\t\t\t} });
\t\t}
\t\tpaperclipKimiStep(event, phase) {
\t\t\tconst driver = this.driverFor(event.turnId);
\t\t\tif (driver === void 0) return;
\t\t\tconst current = driver.paperclipKimiMessage;
\t\t\tif (!Number.isSafeInteger(event.step) || event.step < 1 || !Number.isSafeInteger(event.turnId) || event.turnId < 0) return this.paperclipKimiMessageFailure(driver);
\t\t\tif (phase === "start") {
\t\t\t\tif (current?.active || typeof event.stepId !== "string" || !/^[A-Za-z0-9_-]{1,256}$/.test(event.stepId) || current && event.step <= current.step) return this.paperclipKimiMessageFailure(driver);
\t\t\t\tdriver.paperclipKimiMessageIds ??= new Set();
\t\t\t\tconst id = "kimi-message-" + paperclipKimiCreateHash("sha256").update(JSON.stringify([this.sessionId, event.turnId, event.stepId])).digest("hex");
\t\t\t\tif (driver.paperclipKimiMessageIds.size >= 4096 || driver.paperclipKimiMessageIds.has(id)) return this.paperclipKimiMessageFailure(driver);
\t\t\t\tdriver.paperclipKimiMessageIds.add(id);
\t\t\t\tdriver.paperclipKimiMessage = { id, step: event.step, stepId: event.stepId, active: true };
\t\t\t\tthis.paperclipKimiChunk(driver, "", "start");
\t\t\t\treturn;
\t\t\t}
\t\t\tif (!current || current.step !== event.step || event.stepId !== void 0 && event.stepId !== current.stepId) return this.paperclipKimiMessageFailure(driver);
\t\t\tconst reason = phase === "interrupted" ? event.reason : event.finishReason;
\t\t\tconst reasons = phase === "interrupted" ? ["aborted", "max_steps", "error"] : ["end_turn", "max_tokens", "tool_use", "filtered", "paused", "other"];
\t\t\tif (!reasons.includes(reason)) return this.paperclipKimiMessageFailure(driver);
\t\t\tif (!current.active) {
\t\t\t\tif (phase === "interrupted") return;
\t\t\t\treturn this.paperclipKimiMessageFailure(driver);
\t\t\t}
\t\t\tthis.paperclipKimiChunk(driver, "", "end:" + reason);
\t\t\tcurrent.active = false;
\t\t}
\t\tonAssistantDelta(event) {
\t\t\tconst driver = this.driverFor(event.turnId);
\t\t\tif (driver === void 0) return;
\t\t\tif (!driver.paperclipKimiMessage?.active || typeof event.delta !== "string") return this.paperclipKimiMessageFailure(driver);
\t\t\tthis.paperclipKimiChunk(driver, event.delta, "delta");
\t\t}`);
replace('\t\tonThinkingDelta(event) {\n\t\t\tif (this.driverFor(event.turnId) === void 0) return;\n\t\t\tthis.emit(thinkingDeltaToSessionUpdate(this.sessionId, event));\n\t\t}', `\t\tonThinkingDelta(event) {
\t\t\tconst driver = this.driverFor(event.turnId);
\t\t\tif (driver === void 0) return;
\t\t\tif (!driver.paperclipKimiMessage?.active || typeof event.delta !== "string") return this.paperclipKimiMessageFailure(driver);
\t\t\tthis.paperclipKimiChunk(driver, event.delta, "delta", true);
\t\t}`);
return source;
}
export async function patchKimiRuntime(path) {
const input = await readFile(path, "utf8");
const digest = sha256(input);
if (digest === KIMI_RUNTIME_PATCH.patchedSha256) return { ...KIMI_RUNTIME_PATCH };
const patched = patchKimiRuntimeSource(input);
if (sha256(patched) !== KIMI_RUNTIME_PATCH.patchedSha256) throw new Error("Kimi runtime patch output digest mismatch");
await writeFile(path, patched);
return { ...KIMI_RUNTIME_PATCH };
}
if (import.meta.url?.endsWith("/patch-kimi-runtime.mjs") && process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
const path = process.argv[2];
if (!path || process.argv.length !== 3) throw new Error("Usage: node patch-kimi-runtime.mjs <dist/main.mjs>");
patchKimiRuntime(path).then(result => {
process.stdout.write(`${JSON.stringify(result)}\n`);
}).catch(error => {
process.stderr.write(`${error instanceof Error ? error.message : "Kimi runtime patch failed"}\n`);
process.exitCode = 1;
});
}
@@ -0,0 +1,576 @@
import assert from "node:assert/strict";
import { createHash } from "node:crypto";
import { access, mkdir, mkdtemp, readFile, realpath, rm, writeFile } from "node:fs/promises";
import { createServer } from "node:http";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { fileURLToPath, pathToFileURL } from "node:url";
import test from "node:test";
import { runInNewContext } from "node:vm";
import { createKimiInstructionRuntime } from "./kimi-instructions-runtime.mjs";
import { KIMI_RUNTIME_PATCH, patchKimiRuntime, patchKimiRuntimeSource, replaceKimiPatchAnchor } from "./patch-kimi-runtime.mjs";
const sha = text => createHash("sha256").update(text, "utf8").digest("hex");
const binding = content => JSON.stringify({ schema: "paperclip.kimi.instructions.v1", content,
digest: `sha256:${sha(content)}`, byteLength: Buffer.byteLength(content) });
const runtime = raw => createKimiInstructionRuntime(raw, { createHash, byteLength: text => Buffer.byteLength(text, "utf8") });
test("native instruction binding preserves exact literals and rejects false readback", () => {
const content = "\nGovernance: résumé 日本語 ${cwd} ${base_prompt}\n\n";
const state = runtime(binding(content));
const native = "Original native system prompt";
const effective = `${native}\n\n${content}`;
assert.equal(state.append(native), effective);
assert.equal(state.append(effective), effective);
const receipt = state.receipt("native-session", effective);
assert.deepEqual(receipt, { schema: "paperclip.kimi.instructions.v1", sessionId: "native-session",
digest: `sha256:${sha(content)}`, byteLength: Buffer.byteLength(content),
effectiveDigest: `sha256:${sha(effective)}`, effectiveByteLength: Buffer.byteLength(effective) });
assert.throws(() => state.receipt("native-session", native), /binding/);
assert.throws(() => state.receipt("", effective), /binding/);
assert.throws(() => state.append("x".repeat(2_097_153)), /binding/);
assert.ok(Object.isFrozen(receipt));
});
test("explicit empty instructions retain the native prompt and acknowledge zero bytes", () => {
const state = runtime(binding(""));
assert.equal(state.append("native"), "native");
assert.equal(state.receipt("s", "native").byteLength, 0);
});
test("malformed, changed, oversized, and ill-formed instruction bindings fail closed", () => {
const valid = JSON.parse(binding("test"));
for (const raw of [undefined, "{", "[]", "null", " ".repeat(200_001),
binding("x\0y"), binding("x".repeat(32_769)), binding("\ud800"),
JSON.stringify({ ...valid, byteLength: 1 }), JSON.stringify({ ...valid, digest: "sha256:" + "0".repeat(64) }),
JSON.stringify({ ...valid, extra: true }), JSON.stringify({ schema: valid.schema, content: "test", digest: valid.digest })]) {
assert.throws(() => runtime(raw), /binding/);
}
});
test("patch rejects unknown source and ambiguous anchors before writing", async () => {
assert.throws(() => patchKimiRuntimeSource("unverified runtime"), /input digest/);
assert.throws(() => replaceKimiPatchAnchor("absent", "needle", "replacement"), /exactly one/);
assert.throws(() => replaceKimiPatchAnchor("needle needle", "needle", "replacement"), /exactly one/);
const root = await mkdtemp(join(tmpdir(), "kimi-patch-test-"));
const path = join(root, "main.mjs");
try {
await writeFile(path, "unverified runtime");
await assert.rejects(patchKimiRuntime(path), /input digest/);
assert.equal(await readFile(path, "utf8"), "unverified runtime");
} finally { await rm(root, { recursive: true, force: true }); }
});
function segment(source, start, end) {
const first = source.indexOf(start);
assert.ok(first >= 0, `Missing native start: ${start}`);
const last = source.indexOf(end, first + start.length);
assert.ok(last > first, `Missing native end: ${end}`);
return source.slice(first, last);
}
test("pinned native package binds new/load and rejects failed turns", {
skip: !process.env.PAPERCLIP_KIMI_VENDOR_MAIN,
}, async () => {
const input = await readFile(process.env.PAPERCLIP_KIMI_VENDOR_MAIN, "utf8");
const patched = patchKimiRuntimeSource(input);
assert.equal(sha(patched), KIMI_RUNTIME_PATCH.patchedSha256);
const { build } = await import("esbuild");
const bundledRoot = await mkdtemp(join(tmpdir(), "kimi-bundled-patch-test-"));
try {
const bundledPath = join(bundledRoot, "patch-kimi-runtime.bundle.cjs");
await build({ entryPoints: [fileURLToPath(new URL("./patch-kimi-runtime.mjs", import.meta.url))],
outfile: bundledPath, bundle: true, platform: "node", format: "cjs", target: "node24", logLevel: "silent",
define: { "import.meta.url": JSON.stringify(pathToFileURL(bundledPath).href) } });
const bundled = (await import(pathToFileURL(bundledPath))).default;
assert.equal(sha(bundled.patchKimiRuntimeSource(input)), KIMI_RUNTIME_PATCH.patchedSha256,
"installed bundled patcher produces exactly the same pinned native bytes");
} finally { await rm(bundledRoot, { recursive: true, force: true }); }
const content = " Exact ${cwd} instructions\n日本語\n";
const env = { PAPERCLIP_KIMI_INSTRUCTIONS: binding(content) };
const helper = segment(patched, "let paperclipKimiInstructionSnapshot;", "import { fileURLToPath");
const context = { process: { env }, Buffer, paperclipKimiCreateHash: createHash };
const state = runInNewContext(`${helper};paperclipKimiInstructionState()`, context);
assert.equal(env.PAPERCLIP_KIMI_INSTRUCTIONS, undefined);
env.PAPERCLIP_KIMI_INSTRUCTIONS = binding("replacement");
assert.equal(runInNewContext("paperclipKimiInstructionState()", context), state);
env.KIMI_API_KEY = "fake-provider-key";
env.PAPERCLIP_TASK_SCOPED = "assigned-task-value";
const childEnvironment = segment(patched, "function buildEnv(overrides) {", "function waitForSpawn(child)");
const buildEnvironment = runInNewContext(`${childEnvironment};buildEnv`, context);
for (const overrides of [undefined, { KIMI_API_KEY: "override-key", PAPERCLIP_KIMI_INSTRUCTIONS: "private", EXTRA: "assigned" }]) {
const child = buildEnvironment(overrides);
assert.equal(child.KIMI_API_KEY, undefined);
assert.equal(child.PAPERCLIP_KIMI_INSTRUCTIONS, undefined);
assert.equal(child.PAPERCLIP_TASK_SCOPED, "assigned-task-value");
assert.equal(child.EXTRA, overrides?.EXTRA);
}
assert.equal(env.KIMI_API_KEY, "fake-provider-key");
const terminalBinding = segment(patched, "\t\tbindTerminalCapability(terminal) {", "\n\t\tget terminalEnabled()");
const bindTerminal = runInNewContext(`({${terminalBinding}}).bindTerminalCapability`);
const terminalHolder = {};
bindTerminal.call(terminalHolder, true);
assert.equal(terminalHolder._terminalEnabled, false);
const getter = segment(patched, "\t\tget systemPrompt() {", "\t\tget thinkingLevel()");
const native = runInNewContext(`({profileState:{systemPrompt:"native"},${getter}})`, context);
assert.equal(native.systemPrompt, `native\n\n${content}`);
assert.equal(native.profileState.systemPrompt, "native");
const receipt = state.receipt("s", native.systemPrompt);
const baseline = segment(patched, "\t\tmerged() {\n\t\t\treturn {};", "\n\t\tasync watchConfigFiles()");
const merged = runInNewContext(`({${baseline}}).merged`, context);
assert.deepEqual(Object.keys(merged.call(new Proxy({}, { get: () => assert.fail("ambient MCP was read") }))), []);
const policy = segment(patched, '\t\tasync evaluate(context) {\n\t\t\treturn { policyName: "paperclip-runner"', '\n\t};');
const evaluate = runInNewContext(`({${policy}}).evaluate`, context);
assert.equal((await evaluate.call(new Proxy({}, { get: () => assert.fail("native heuristic was read") }), {})).result.kind, "ask");
const userRoots = segment(patched, "async function userRoots(homeDir, osHomeDir, options = {}) {", "async function projectRoots(");
const discovered = [];
const roots = await runInNewContext(`(${userRoots})`, { USER_BRAND_DIRS$1: ["skills"],
pushBrandGroup: async (_roots, _dirs, home) => { discovered.push(home); },
pushFirstExisting$1: () => assert.fail("global skills were read") })("/owned-kimi", "/ambient-home");
assert.deepEqual(discovered, ["/owned-kimi"]);
assert.equal(roots.length, 0);
const host = { klient: { session: () => ({ agent: () => ({}) }) },
bindDefaultModel: async () => {}, bindSessionRuntime: async () => undefined };
const wire = segment(patched, "\t\tasync wireSession(sessionId) {", "\n\t\t/**");
await assert.rejects(runInNewContext(`({${wire}}).wireSession`, context).call(host, "s"), /native instruction receipt/);
const admitted = { ensureAuthed: async () => {}, klient: { global: { sessions: { create: async () => ({ id: "s" }) } } },
activateSession: async () => ({}), paperclipInstructionReceipts: new Map([["s", receipt]]) };
const create = segment(patched, "\t\tasync newSession(params) {", "\n\t\t/**");
const createContext = { ...context, acpMcpServersToConfigRecord: value => value };
const created = await runInNewContext(`({${create}}).newSession`, createContext).call(admitted, { cwd: "/workspace", mcpServers: [] });
assert.equal(created._meta.paperclipKimiInstructions, receipt);
for (const [name, next] of [["loadSession", "resumeSession"], ["resumeSession", "listSessions"]]) {
const method = segment(patched, `\t\tasync ${name}(params) {`, `\t\tasync ${next}(params)`);
const response = await runInNewContext(`({${method}}).${name}`, createContext).call({ ...admitted,
warnIgnoredAdditionalDirs() {}, scheduleAvailableCommandsUpdate() {},
resumeAcpSession: async () => ({ replayHistory: async () => {}, configOptions: async () => [], modeState: () => ({}) }) },
{ sessionId: "s", mcpServers: [] });
assert.equal(response._meta.paperclipKimiInstructions, receipt);
}
const terminal = segment(patched, "\t\tonTurnEnded(event) {", "\n\t\t/**");
const rejection = [];
const RequestError = { authRequired: () => ({ kind: "auth" }), internalError: data => data };
const end = runInNewContext(`({${terminal}}).onTurnEnded`, { RequestError$1: RequestError,
isAuthError: error => error?.code === "provider.auth_error", turnEndReasonToStopReason: () => "end_turn" });
for (const code of ["provider.auth_error", "provider.server_error"]) {
end.call({ driverFor: () => ({ reject: error => rejection.push(error), resolve: () => assert.fail("failed turn resolved") }),
settleDriver: (_driver, action) => action(), emitUsageUpdate() {} }, { turnId: 1, reason: "failed", error: { code } });
}
assert.equal(rejection[0].kind, "auth");
assert.equal(rejection[1].kind, "provider_failed");
const infer = segment(patched, "function inferToolKind(name) {", "\n/**");
const approval = segment(patched, "function buildPermissionToolCallUpdate(req) {", "\n/**");
const permission = runInNewContext(`${infer}\n${approval}\nbuildPermissionToolCallUpdate`, {
displayBlockToAcpContent: () => null, acpToolCallId: (turn, id) => `${turn}:${id}`,
});
for (const [toolName, kind] of [["Write", "edit"], ["Edit", "edit"], ["Read", "read"], ["Bash", "execute"], ["mcp__paperclip__read_workspace_file", "other"]]) {
const args = { path: "/workspace/exact.txt", content: "body" };
const request = permission({ toolName, toolInput: args, toolCallId: "native-tool", turnId: 1, display: {}, action: "test" });
assert.equal(request.kind, kind);
assert.equal(request.rawInput, args);
assert.equal(request.toolCallId, "1:native-tool");
}
});
test("native step identity separates identical commentary/final text and retains empty boundaries", {
skip: !process.env.PAPERCLIP_KIMI_VENDOR_MAIN,
}, async () => {
const patched = patchKimiRuntimeSource(await readFile(process.env.PAPERCLIP_KIMI_VENDOR_MAIN, "utf8"));
const methods = segment(patched, "\t\tpaperclipKimiMessageFailure(driver) {", "\n\t\tonToolCallStarted(event)");
const host = () => {
const events = [], rejected = [];
const driver = { reject: value => rejected.push(value) };
const session = runInNewContext(`new class {${methods}}`, { paperclipKimiCreateHash: createHash,
RequestError$1: { internalError: value => value } });
Object.assign(session, { sessionId: "native-session", emit: value => events.push(value),
driverFor: turnId => turnId === 7 && !driver.settled ? driver : undefined,
settleDriver: (value, action) => { value.settled = true; action(); } });
return { session, events, rejected, driver };
};
const h = host();
h.session.paperclipKimiStep({ turnId: 7, step: 1, stepId: "native-step-uuid-one" }, "start");
h.session.onAssistantDelta({ turnId: 7, delta: "SAME café" });
h.session.onThinkingDelta({ turnId: 7, delta: "reasoning" });
h.session.paperclipKimiStep({ turnId: 7, step: 1, stepId: "native-step-uuid-one", finishReason: "tool_use" }, "end");
h.session.paperclipKimiStep({ turnId: 7, step: 2, stepId: "native-step-uuid-two" }, "start");
h.session.onAssistantDelta({ turnId: 7, delta: "SAME café" });
h.session.paperclipKimiStep({ turnId: 7, step: 2, stepId: "native-step-uuid-two", finishReason: "end_turn" }, "end");
h.session.paperclipKimiStep({ turnId: 7, step: 3, stepId: "native-step-uuid-empty" }, "start");
h.session.paperclipKimiStep({ turnId: 7, step: 3, stepId: "native-step-uuid-empty", finishReason: "end_turn" }, "end");
const chunks = h.events.map(event => event.update);
assert.equal(h.rejected.length, 0);
assert.deepEqual(chunks.map(chunk => chunk._meta.kind), ["start", "delta", "delta", "end:tool_use", "start", "delta", "end:end_turn", "start", "end:end_turn"]);
assert.equal(chunks[0].messageId, `kimi-message-${sha(JSON.stringify(["native-session", 7, "native-step-uuid-one"]))}`);
assert.equal(new Set(chunks.map(chunk => chunk.messageId)).size, 3);
assert.equal(chunks[2].sessionUpdate, "agent_thought_chunk");
assert.ok(chunks.every(chunk => chunk._meta.origin === "kimi-native-assistant" && chunk._meta.source === "kimi-turn-step-v1"));
assert.ok(chunks.filter(chunk => chunk._meta.kind !== "delta").every(chunk => chunk.content.text === ""));
h.session.onAssistantDelta({ turnId: 8, delta: "foreign turn" });
assert.equal(h.events.length, 9);
for (const mutate of [
value => value.session.onAssistantDelta({ turnId: 7, delta: "orphan" }),
value => { value.session.paperclipKimiStep({ turnId: 7, step: 1, stepId: "uuid" }, "start"); value.session.paperclipKimiStep({ turnId: 7, step: 2, stepId: "other" }, "start"); },
value => { value.session.paperclipKimiStep({ turnId: 7, step: 1, stepId: "uuid" }, "start"); value.session.paperclipKimiStep({ turnId: 7, step: 1, stepId: "foreign", finishReason: "end_turn" }, "end"); },
value => { value.session.paperclipKimiStep({ turnId: 7, step: 1, stepId: "uuid" }, "start"); value.session.paperclipKimiStep({ turnId: 7, step: 1, stepId: "uuid", finishReason: "invented" }, "end"); },
value => { value.session.paperclipKimiStep({ turnId: 7, step: 1, stepId: "uuid" }, "start"); value.session.paperclipKimiStep({ turnId: 7, step: 1, reason: "aborted" }, "interrupted"); value.session.paperclipKimiStep({ turnId: 7, step: 2, stepId: "uuid" }, "start"); },
]) {
const invalid = host(); mutate(invalid);
assert.equal(invalid.rejected.length, 1);
assert.equal(invalid.rejected[0].kind, "message_boundary_invalid");
const count = invalid.events.length;
invalid.session.onAssistantDelta({ turnId: 7, delta: "late after failure" });
assert.equal(invalid.events.length, count);
}
});
test("real pinned Kimi and ACPX exchange instructions/tools/denial/errors with a simulated local model service", {
skip: process.env.PAPERCLIP_TEST_KIMI_MODEL_PEER !== "1",
timeout: 60_000,
}, async t => {
const packageRoot = await realpath(fileURLToPath(new URL("../", import.meta.url)));
const assets = join(packageRoot, "provider-assets/kimi", `${process.platform}-${process.arch}`);
try { await access(join(assets, "native-closure.json")); }
catch (error) {
if (error.code !== "ENOENT") throw error;
t.skip("Install the pinned Kimi runtime with paperclipai runtime setup kimi first");
return;
}
const { tsImport } = await import("tsx/esm/api");
const [{ verifyKimiInstallation }, { QUALIFIED_ACPX_PROFILES }, { kimiManagedConfiguration }, instructionModule, { createKimiMessageProjection }, { normalizeAcpxPermission }] = await Promise.all([
tsImport("../src/drivers/acpx/kimi-installation.ts", import.meta.url),
tsImport("../src/drivers/acpx/qualified-profiles.ts", import.meta.url),
tsImport("../src/drivers/acpx/kimi-config.ts", import.meta.url),
tsImport("../src/drivers/acpx/kimi-instructions.ts", import.meta.url),
tsImport("../src/drivers/acpx/kimi-message-boundary.ts", import.meta.url),
tsImport("../src/drivers/acpx/acp-permission-adapter.ts", import.meta.url),
]);
const { createAcpRuntime, createFileSessionStore } = await import(pathToFileURL(join(packageRoot, "node_modules/acpx/dist/runtime.js")));
const root = await realpath(await mkdtemp(join(tmpdir(), "kimi-simulated-model-peer-")));
const home = join(root, "home"), workspace = join(root, "workspace");
await mkdir(home); await mkdir(workspace);
const instructions = "\nExact governance café 日本語 ${cwd} ${base_prompt}\nKeep the final LF.\n";
const selectedModel = "kimi-for-coding";
const binding = instructionModule.kimiInstructionBinding(instructions);
const argumentsObject = { payload: "café 🧪\n${literal}", nested: { count: 0, empty: {}, flag: false } };
const toolReceipt = sha(JSON.stringify(argumentsObject));
const deniedPath = join(workspace, "denied-peer.txt");
const bashArguments = { command: 'if test -n "${KIMI_API_KEY+x}"; then printf "PROVIDER_KEY_PRESENT"; exit 1; fi; if test -n "${PAPERCLIP_KIMI_INSTRUCTIONS+x}"; then printf "PRIVATE_BINDING_PRESENT"; exit 1; fi; if test "$PAPERCLIP_TASK_SCOPED" != "assigned-task-canary"; then printf "TASK_VARIABLE_MISSING"; exit 1; fi; printf "KIMI_CHILD_CREDENTIAL_FENCE_OK"', timeout: 5 };
const modelRequests = [], mcpCalls = [], permissions = [], deliveries = [], nativeMessages = [], owners = [];
let scenario = "echo", modelStep = 0, peerFailure, permissionGate;
const complete = (response, chunks) => {
response.writeHead(200, { "content-type": "text/event-stream" });
const bytes = Buffer.from(chunks.map(chunk => `data: ${JSON.stringify({ id: "simulated-peer", ...chunk })}\n\n`).join("") + "data: [DONE]\n\n");
const index = bytes.indexOf(Buffer.from("é"));
if (index >= 0) { response.write(bytes.subarray(0, index + 1)); response.end(bytes.subarray(index + 1)); }
else response.end(bytes);
};
const server = createServer(async (request, response) => {
try {
if (request.method !== "POST") { response.writeHead(405); response.end(); return; }
let body = "";
for await (const chunk of request) { body += chunk; assert.ok(Buffer.byteLength(body) < 2_097_152); }
const value = JSON.parse(body);
if (request.url === "/v1/chat/completions") {
assert.equal(request.headers.authorization, "Bearer simulated-peer-not-a-credential");
assert.equal(value.model, selectedModel);
const system = value.messages.find(message => message.role === "system")?.content;
assert.equal(typeof system, "string");
assert.ok(system.endsWith(`\n\n${instructions}`), "exact literal instructions reached native HTTP request");
const ack = nativeMessages.map(entry => entry.message.result?._meta?.paperclipKimiInstructions).filter(Boolean).at(-1);
assert.equal(ack?.digest, binding.digest);
assert.equal(ack?.effectiveDigest, `sha256:${sha(system)}`, "native instruction receipt matches the full actual model-request prompt");
modelRequests.push({ scenario, value });
assert.ok(modelRequests.length <= 9, "bounded simulated model requests");
modelStep++;
if (scenario === "error") {
response.writeHead(418, { "content-type": "application/json" });
response.end(JSON.stringify({ error: { type: "simulated_provider_error", message: "private-peer-error-canary" } }));
return;
}
if (modelStep === 1) {
const tools = scenario === "echo"
? [{ id: "peer-echo", name: "mcp__peer__echo_peer", args: argumentsObject }, { id: "peer-empty", name: "mcp__peer__empty_peer", args: {} }]
: scenario === "bash" ? [{ id: "peer-bash", name: "Bash", args: bashArguments }]
: [{ id: `peer-${scenario}`, name: "Write", args: { path: permissionGate?.path ?? deniedPath, content: "must never be written" } }];
for (const tool of tools) assert.ok(value.tools.some(declared => declared.function?.name === tool.name), `native request discloses ${tool.name}`);
complete(response, [
{ choices: [{ index: 0, delta: { content: "Before tool café." } }] },
{ choices: [{ index: 0, delta: { tool_calls: tools.map((tool, index) => ({ index, id: tool.id, type: "function", function: { name: tool.name, arguments: JSON.stringify(tool.args).slice(0, 1) } })) } }] },
...tools.map((tool, index) => ({ choices: [{ index: 0, delta: { tool_calls: [{ index, function: { arguments: JSON.stringify(tool.args).slice(1) } }] } }] })),
{ choices: [{ index: 0, delta: {}, finish_reason: "tool_calls" }] },
]);
} else {
const result = value.messages.find(message => message.role === "tool" && message.tool_call_id === `peer-${scenario}`);
assert.ok(result, "the exact native tool result returned to the model");
if (scenario === "echo") {
assert.ok(JSON.stringify(result).includes(toolReceipt), `MCP receiver result reached the next native request: ${JSON.stringify({ result, mcpCalls: mcpCalls.length, permissions })}`);
assert.ok(value.messages.some(message => message.role === "tool" && message.tool_call_id === "peer-empty" && JSON.stringify(message).includes("EMPTY_TOOL_ACCEPTED")), "zero-argument MCP result returned to the native model");
}
else if (scenario === "bash") assert.match(result.content, /^(?:Wall time: [0-9.]+ seconds\n)?KIMI_CHILD_CREDENTIAL_FENCE_OK\n?$/, "native Bash excluded provider/private credentials and retained the assigned task variable");
else assert.match(JSON.stringify(result), /denied|rejected|approval/i);
complete(response, [{ choices: [{ index: 0, delta: { content: scenario === "echo" ? "PEER_ECHO_OK café" : scenario === "bash" ? "PEER_BASH_OK" : "PEER_DENIED_OK" } }] },
{ choices: [{ index: 0, delta: {}, finish_reason: "stop" }], usage: { prompt_tokens: 12, completion_tokens: 3, total_tokens: 15 } }]);
}
return;
}
assert.equal(request.url, "/mcp");
if (value.id === undefined) { response.writeHead(202); response.end(); return; }
if (value.method === "tools/call") {
assert.ok(["echo_peer", "empty_peer"].includes(value.params.name));
assert.deepEqual(value.params.arguments, value.params.name === "echo_peer" ? argumentsObject : {});
mcpCalls.push(value.params);
}
const result = value.method === "initialize"
? { protocolVersion: value.params.protocolVersion, capabilities: { tools: {} }, serverInfo: { name: "simulated-peer", version: "1" } }
: value.method === "tools/list" ? { tools: [{ name: "echo_peer", description: "Echo the supplied JSON through the controlled peer.",
inputSchema: { type: "object", properties: { payload: { type: "string" }, nested: { type: "object", additionalProperties: true } }, required: ["payload", "nested"] } },
{ name: "empty_peer", description: "Return a receipt from an empty object argument.", inputSchema: { type: "object", properties: {}, additionalProperties: false } }] }
: { content: [{ type: "text", text: value.params.name === "empty_peer" ? "EMPTY_TOOL_ACCEPTED" : JSON.stringify({ echoed: argumentsObject, receipt: toolReceipt }) }] };
response.writeHead(200, { "content-type": "application/json" });
response.end(JSON.stringify({ jsonrpc: "2.0", id: value.id, result }));
} catch (error) {
peerFailure ??= error;
if (!response.headersSent) response.writeHead(400, { "content-type": "application/json" });
response.end(JSON.stringify({ error: { type: "peer_assertion_failed", message: "simulated peer assertion failed" } }));
}
});
const keys = ["PAPERCLIP_ACPX_PROVIDER_PACKAGE_ROOT", "PAPERCLIP_ACPX_PROVIDER_PACKAGE_MANIFEST"];
const previous = keys.map(key => process.env[key]);
const closeOwner = async owner => {
if (owner.closed) return;
owner.closed = true;
const started = Date.now();
const terminate = setTimeout(() => { for (const child of owner.children) if (child.exitCode === null && child.signalCode === null) child.kill("SIGTERM"); }, 2_000);
const kill = setTimeout(() => { for (const child of owner.children) if (child.exitCode === null && child.signalCode === null) child.kill("SIGKILL"); }, 3_000);
try {
if (owner.handle) await owner.runtime.close({ handle: owner.handle, reason: "simulated peer cleanup" });
} finally {
try {
await Promise.all(owner.completions);
assert.ok(Date.now() - started < 5_000, "native process cleanup is bounded");
} finally { clearTimeout(terminate); clearTimeout(kill); await owner.lease.close(); }
}
};
try {
await new Promise((resolve, reject) => { server.once("error", reject); server.listen(0, "127.0.0.1", resolve); });
const endpoint = `http://127.0.0.1:${server.address().port}`;
const config = kimiManagedConfiguration(selectedModel).replace(/^base_url = .+$/m, `base_url = ${JSON.stringify(`${endpoint}/v1`)}`)
+ "\n[loop_control]\nmax_attempts_per_step = 1\n";
await writeFile(join(home, "config.toml"), config, { mode: 0o600 });
process.env[keys[0]] = packageRoot; process.env[keys[1]] = join(packageRoot, "package.json");
const installation = await verifyKimiInstallation(QUALIFIED_ACPX_PROFILES.kimi);
const store = createFileSessionStore({ stateDir: join(root, "acpx-state") });
const spawnNative = (lease, owner) => {
const child = lease.spawn([], { cwd: workspace, stdio: "pipe", env: { PATH: "/usr/bin:/bin", HOME: home,
LANG: "C.UTF-8", CI: "1", NO_COLOR: "1", TERM: "dumb", KIMI_CODE_HOME: home,
KIMI_API_KEY: "simulated-peer-not-a-credential", KIMI_CODE_NO_AUTO_UPDATE: "1", KIMI_DISABLE_TELEMETRY: "1",
KIMI_CODE_WATCH: "0", KIMI_DISABLE_CRON: "1", PAPERCLIP_KIMI_INSTRUCTIONS: binding.payload,
PAPERCLIP_TASK_SCOPED: "assigned-task-canary" } });
owner.children.push(child);
owner.completions.push(new Promise((resolve, reject) => { child.once("close", resolve); child.once("error", reject); }));
return child;
};
const connect = async (resumeSessionId, sessionKey = "scripted-kimi-peer") => {
const lease = await installation.openCommand();
const admission = instructionModule.createKimiInstructionAdmission(instructions);
const owner = { lease, children: [], completions: [], handle: undefined, runtime: undefined, closed: false };
owners.push(owner);
owner.runtime = createAcpRuntime({ cwd: workspace, sessionStore: store,
agentRegistry: { resolve: () => "paperclip-verified-kimi-command", list: () => ["kimi"] },
mcpServers: [{ type: "http", name: "peer", url: `${endpoint}/mcp`, headers: [] }],
permissionMode: "approve-all", permissionPolicy: { defaultAction: "escalate" }, timeoutMs: 15_000,
protocolGuardFactory: () => admission.createGuard(),
onAcpMessage: (direction, message) => nativeMessages.push({ owner, direction, message }),
onPermissionRequest: async (request, context) => {
permissions.push(request.raw);
assert.ok(context.responseDelivery instanceof Promise);
assert.ok(request.raw.options.every(option => option.kind !== "allow_always"));
const normalized = normalizeAcpxPermission(request, { provider: "kimi", workingDirectory: workspace });
if (request.raw.toolCall.title === "Write") {
assert.equal(request.raw.toolCall.kind, "edit", "native approval carries the actual tool's canonical kind");
const path = request.raw.toolCall.rawInput.path;
assert.equal(normalized.title, `Change file: ${path.slice(workspace.length + 1)}`);
assert.equal(normalized.kind, "edit");
assert.deepEqual(normalized.choices.map(choice => choice.key), ["accept", "decline", "cancel"]);
for (const workingDirectory of [undefined, home]) {
const unsafe = normalizeAcpxPermission(request, { provider: "kimi", workingDirectory });
assert.equal(unsafe.title, "File change requested; target unavailable. Deny or cancel this request.");
assert.deepEqual(unsafe.choices.map(choice => choice.key), ["decline", "cancel"]);
assert.throws(() => unsafe.resolve({ action: "accept" }), /not an offered choice/);
}
}
if (permissionGate) {
assert.equal(request.raw.toolCall.title, "Write");
assert.deepEqual(request.raw.toolCall.rawInput, { path: permissionGate.path, content: "must never be written" });
permissionGate.context = context;
permissionGate.delivery = context.responseDelivery.then(() => "delivered", () => "suppressed");
permissionGate.requestId = nativeMessages.findLast(entry => entry.owner === owner && entry.direction === "inbound"
&& entry.message.method === "session/request_permission"
&& entry.message.params.toolCall.rawInput?.path === permissionGate.path)?.message.id;
assert.ok(permissionGate.requestId !== undefined);
permissionGate.markSeen();
return permissionGate.decision;
}
deliveries.push(context.responseDelivery);
if (request.raw.toolCall.title === "Write") {
assert.deepEqual(request.raw.toolCall.rawInput, { path: deniedPath, content: "must never be written" });
await assert.rejects(access(deniedPath), { code: "ENOENT" });
return { outcome: "reject_once" };
}
if (request.raw.toolCall.title === "Bash") {
assert.deepEqual(request.raw.toolCall.rawInput, bashArguments);
return { outcome: "allow_once" };
}
assert.ok(["mcp__peer__echo_peer", "mcp__peer__empty_peer"].includes(request.raw.toolCall.title));
assert.deepEqual(request.raw.toolCall.rawInput, request.raw.toolCall.title === "mcp__peer__echo_peer" ? argumentsObject : {});
return { outcome: "allow_once" };
},
spawnAgent: () => spawnNative(lease, owner),
});
owner.handle = await owner.runtime.ensureSession({ sessionKey, agent: "kimi", mode: "persistent", cwd: workspace,
...(resumeSessionId ? { resumeSessionId } : {}),
sessionOptions: { model: selectedModel } });
return owner;
};
const prompt = async (owner, name) => {
scenario = name; modelStep = 0;
const turn = owner.runtime.startTurn({ handle: owner.handle, mode: "prompt", text: `Controlled ${name} boundary.`, requestId: `peer-${name}` });
const events = [];
const drained = (async () => { for await (const event of turn.events) events.push(event); })();
const result = await turn.result;
await drained;
if (peerFailure) throw peerFailure;
if (name !== "error") {
const chunks = events.filter(event => event.type === "text_delta" && event.stream === "output");
assert.deepEqual(chunks.map(event => event.meta?.kind), ["start", "delta", "end:tool_use", "start", "delta", "end:end_turn"]);
assert.ok(chunks.every(event => /^kimi-message-[a-f0-9]{64}$/.test(event.messageId)
&& event.meta.origin === "kimi-native-assistant" && event.meta.source === "kimi-turn-step-v1"));
assert.equal(new Set(chunks.map(event => event.messageId)).size, 2);
assert.equal(chunks[0].messageId, chunks[2].messageId);
assert.equal(chunks[3].messageId, chunks[5].messageId);
assert.notEqual(chunks[0].messageId, chunks[3].messageId);
assert.equal(chunks[1].text, "Before tool café.");
assert.ok(chunks.filter(event => event.meta.kind !== "delta").every(event => event.text === ""));
const projection = createKimiMessageProjection();
const projected = events.map(event => projection.normalize(event));
projection.settle();
assert.deepEqual(projected.filter(event => event.assistantMessageBoundary).map(event => event.assistantMessageBoundary), [
{ phase: "start" }, { phase: "end", stopReason: "toolUse" },
{ phase: "start" }, { phase: "end", stopReason: "stop" },
]);
}
return { result, events };
};
const first = await connect();
const echoed = await prompt(first, "echo");
assert.equal(echoed.result.status, "completed");
assert.equal(mcpCalls.length, 2);
assert.ok(echoed.events.some(event => event.type === "text_delta" && event.text.includes("PEER_ECHO_OK")));
const shell = await prompt(first, "bash");
assert.equal(shell.result.status, "completed");
assert.ok(shell.events.some(event => event.type === "text_delta" && event.text.includes("PEER_BASH_OK")));
assert.ok(nativeMessages.some(entry => entry.direction === "outbound" && entry.message.method === "initialize" && entry.message.params.clientCapabilities.terminal === true), "actual ACPX offered its mandatory client terminal");
assert.ok(!nativeMessages.some(entry => entry.direction === "inbound" && entry.message.method === "terminal/create"), "Kimi kept Bash in its native fenced process service despite ACPX client terminal capability");
await closeOwner(first);
const second = await connect(first.handle.backendSessionId);
const denied = await prompt(second, "deny");
assert.equal(denied.result.status, "completed");
await assert.rejects(access(deniedPath), { code: "ENOENT" });
const failed = await prompt(second, "error");
assert.equal(failed.result.status, "failed");
assert.match(JSON.stringify(failed.result), /Kimi provider turn failed/);
assert.ok(!JSON.stringify(failed.result).includes("private-peer-error-canary"));
assert.ok(nativeMessages.some(entry => entry.direction === "outbound" && ["session/load", "session/resume"].includes(entry.message.method)), "ACPX restored the native session before the second model turn");
assert.ok(permissions.some(request => request.toolCall.title === "Write"));
assert.equal(permissions.length, 4);
await Promise.all(deliveries);
assert.equal(modelRequests.length, 7);
await closeOwner(second);
assert.ok(owners.every(owner => owner.children.every(child => child.exitCode !== null || child.signalCode !== null)));
await assert.rejects(access(deniedPath), { code: "ENOENT" });
t.diagnostic("SIMULATED provider service; real pinned Kimi 2.3.3 + ACPX manager: 7 native model requests with provider auth intact, exact create/resume instruction suffix, native UUID start/end separates pre-tool commentary from final text despite reused model response IDs, actual provider projection yields toolUse/stop boundaries, two MCP JSON/result round trips including terminal {}, native Bash excludes provider/private credentials and retains an assigned task variable, rejected Write with no file, typed provider failure, owned process closure; zero external model calls");
if (process.env.PAPERCLIP_TEST_KIMI_LIFECYCLE_PEER === "1") {
const { readProcessTable, observeDescendantProcessTree } = await tsImport("../../../tests/runner-e2e/process-tree.ts", import.meta.url);
const bounded = async (promise, label, milliseconds = 5_000) => {
let timer;
try {
return await Promise.race([promise, new Promise((_, reject) => {
timer = setTimeout(() => reject(new Error(`${label} exceeded its bound`)), milliseconds);
})]);
} finally { clearTimeout(timer); }
};
const nativeWorker = async owner => {
assert.equal(owner.children.length, 1);
const rootPid = owner.children[0].pid;
const table = await readProcessTable();
assert.ok(table);
const tree = observeDescendantProcessTree(table, rootPid);
const candidates = tree.members.filter(member => member.depth === 1);
assert.equal(candidates.length, 1, `one native Kimi worker belongs directly to the verified command root: ${JSON.stringify(tree.members.map(member => ({ depth: member.depth, kind: member.process.kind })))}`);
const rootProcess = table.find(row => row.pid === rootPid);
const worker = candidates[0].process;
assert.ok(rootProcess && worker.pid > 1 && worker.pid !== rootPid && worker.pid !== process.pid);
const fresh = await readProcessTable();
assert.ok(fresh?.some(row => row.pid === rootPid && row.started === rootProcess.started && row.processGroupId === rootProcess.processGroupId));
assert.ok(fresh?.some(row => row.pid === worker.pid && row.started === worker.started
&& row.parentPid === rootPid && row.processGroupId === worker.processGroupId));
return worker;
};
const assertRetired = async worker => {
const deadline = Date.now() + 5_000;
while (Date.now() < deadline) {
const table = await readProcessTable();
assert.ok(table);
if (!table.some(row => row.pid === worker.pid && row.started === worker.started)) return;
await new Promise(resolve => setTimeout(resolve, 25));
}
assert.fail("the observed native worker survived owned cleanup");
};
for (const boundary of ["stop", "loss"]) {
const path = join(workspace, `${boundary}-must-not-exist.txt`);
let markSeen, decide;
const seen = new Promise(resolve => { markSeen = resolve; });
const decision = new Promise(resolve => { decide = resolve; });
permissionGate = { path, markSeen, decision, decide };
const owner = await connect(undefined, `scripted-kimi-peer-${boundary}`);
scenario = boundary; modelStep = 0;
const turn = owner.runtime.startTurn({ handle: owner.handle, mode: "prompt", text: `Controlled pending permission ${boundary}.`, requestId: `peer-${boundary}` });
const drained = (async () => { for await (const _event of turn.events) {} })();
try {
await bounded(seen, `${boundary} native permission observation`);
await assert.rejects(access(path), { code: "ENOENT" });
const worker = await nativeWorker(owner);
if (boundary === "stop") await bounded(turn.cancel({ reason: "controlled pending permission Stop" }), "native Stop");
else process.kill(worker.pid, "SIGKILL");
const result = await bounded(turn.result, `${boundary} terminal result`);
await bounded(drained, `${boundary} event drain`);
if (peerFailure) throw peerFailure;
assert.equal(result.status, boundary === "stop" ? "cancelled" : "failed");
if (boundary === "loss") assert.equal(typeof result.error?.code, "string");
assert.equal(permissionGate.context.signal.aborted, true, "pending host callback was revoked at settlement");
const countAtSettlement = modelRequests.length;
permissionGate.decide({ outcome: "allow_once" });
assert.equal(await bounded(permissionGate.delivery, `${boundary} stale permission suppression`), "suppressed");
await new Promise(resolve => setTimeout(resolve, 100));
assert.equal(modelRequests.length, countAtSettlement, "a stale callback cannot restart provider inference");
assert.ok(!nativeMessages.some(entry => entry.owner === owner && entry.direction === "outbound" && entry.message.id === permissionGate.requestId && entry.message.result?.outcome?.outcome === "selected"), "no stale allow response crossed the provider connection");
await assert.rejects(access(path), { code: "ENOENT" });
await closeOwner(owner);
await assertRetired(worker);
await assert.rejects(access(path), { code: "ENOENT" });
} finally { permissionGate.decide({ outcome: "reject_once" }); permissionGate = undefined; }
}
assert.equal(modelRequests.length, 9);
assert.equal(permissions.length, 6);
t.diagnostic("SIMULATED provider service; pending native Write permission Stop and exact observed native-worker SIGKILL both revoked host callbacks, suppressed stale allow responses, produced no file/model continuation, settled typed results and retired owned native processes; zero external model calls");
}
} finally {
try { await Promise.all(owners.map(closeOwner)); }
finally {
server.closeAllConnections();
await new Promise(resolve => server.close(resolve));
keys.forEach((key, index) => { if (previous[index] === undefined) delete process.env[key]; else process.env[key] = previous[index]; });
await rm(root, { recursive: true, force: true });
}
}
});
@@ -0,0 +1,111 @@
import assert from "node:assert/strict";
import { execFile, spawn, spawnSync } from "node:child_process";
import { createHash } from "node:crypto";
import { once } from "node:events";
import { mkdtemp, mkdir, readFile, readdir, realpath, rm, symlink, writeFile } from "node:fs/promises";
import { createRequire } from "node:module";
import { tmpdir } from "node:os";
import { dirname, join, resolve } from "node:path";
import test from "node:test";
import { setTimeout as delay } from "node:timers/promises";
import { promisify } from "node:util";
import { bundleKimiProvisioner } from "./build-verified-provider-entrypoints.mjs";
import { KIMI_DISTRIBUTION_CLOSURE_SHA256 } from "../src/drivers/acpx/kimi-closure-pins.ts";
const run = promisify(execFile);
test("installed Kimi setup is self-contained, rejects corrupt assets and cancels pending downloads", { timeout: 10_000 }, async t => {
const root = await realpath(await mkdtemp(join(tmpdir(), "paperclip-kimi-public-layout-")));
t.after(() => rm(root, { recursive: true, force: true }));
const pkg = join(root, "package"), cli = join(pkg, "dist/vendor/paperclip-runner/cli");
await mkdir(cli, { recursive: true });
await writeFile(join(pkg, "package.json"), '{"name":"@paperclipai/server","type":"module"}');
await writeFile(join(pkg, "dist/index.js"), 'throw Error("server must not start");');
await writeFile(join(cli, "acpx-runtime-sidecar.cjs"), "// installed layout fixture");
const entry = join(cli, "provision-kimi.cjs");
const packageRoot = resolve(dirname(new URL(import.meta.url).pathname), "..");
const result = await bundleKimiProvisioner({ outputRoot: cli });
for (const output of Object.values(result.metafile.outputs)) for (const dependency of output.imports) assert.match(dependency.path, /^node:/);
assert.deepEqual((await readdir(join(cli, "kimi-provision-inputs"))).sort(), ["package-lock.json", "package.json"]);
for (const name of ["package-lock.json", "package.json"]) assert.deepEqual(await readFile(join(cli, "kimi-provision-inputs", name)), await readFile(join(packageRoot, "scripts/kimi-distribution", name)));
const setup = createRequire(import.meta.url)(entry);
const layout = await setup.provisionKimiPackageRoot(entry);
assert.equal(layout.root, pkg);
assert.equal(layout.assetRoot, join(pkg, "dist/vendor/paperclip-runner"));
const linked = join(cli, "linked.cjs"); await symlink(entry, linked);
await assert.rejects(setup.provisionKimiPackageRoot(linked), /installed entrypoint/);
assert.deepEqual(setup.provisionEnvironment({ PATH: "/usr/bin:/bin", HTTPS_PROXY: "http://127.0.0.1:9", KIMI_MODEL_API_KEY: "sensitive-canary", HOME: "/private/home", NODE_OPTIONS: "--require /foreign", NODE_PATH: "/foreign", NPM_TOKEN: "sensitive-canary" }), { PATH: "/usr/bin:/bin", LANG: "C.UTF-8", HTTPS_PROXY: "http://127.0.0.1:9" });
const target = `${process.platform}-${process.arch}`;
const parent = join(layout.assetRoot, "provider-assets/kimi");
await mkdir(join(parent, target, "runtime"), { recursive: true });
const deny = join(root, "deny.cjs");
await writeFile(deny, `process.nextTick(()=>{const assert=require('node:assert/strict');for(const key of ['KIMI_MODEL_API_KEY','NPM_TOKEN','HOME','NODE_OPTIONS','NODE_PATH'])assert.equal(process.env[key],undefined,key)});const fail=()=>{throw Error('UNEXPECTED_NETWORK_OR_CHILD')};globalThis.fetch=fail;for(const m of ['node:net','node:tls','node:http','node:https']){const x=require(m);for(const key of ['connect','createConnection','request','get'])if(key in x)x[key]=fail}const c=require('node:child_process');for(const key of ['spawn','execFile','exec'])c[key]=fail;`);
const child = spawnSync(process.execPath, ["--require", deny, entry], { env: { PATH: "/usr/bin:/bin", KIMI_MODEL_API_KEY: "sensitive-canary", NPM_TOKEN: "sensitive-canary", HOME: "/private/home", NODE_OPTIONS: "", NODE_PATH: "/foreign" }, encoding: "utf8", timeout: 10_000 });
assert.ifError(child.error); assert.equal(child.status, 1); assert.match(child.stderr, /Kimi setup failed/);
assert.doesNotMatch(child.stderr + child.stdout, /UNEXPECTED_NETWORK_OR_CHILD|sensitive-canary/);
assert.deepEqual(await readdir(parent), [target]);
assert.equal(JSON.parse(await readFile(join(pkg, "package.json"), "utf8")).name, "@paperclipai/server");
await rm(join(parent, target), { recursive: true });
const ready = join(root, "download-ready"), aborted = join(root, "download-aborted");
const preload = join(root, "pending-download.cjs");
await writeFile(preload, `globalThis.fetch=(_url,{signal})=>new Promise((_resolve,reject)=>{const pending=setInterval(()=>{},1000);require('node:fs').writeFileSync(${JSON.stringify(ready)},'ready');signal.addEventListener('abort',()=>{clearInterval(pending);require('node:fs').writeFileSync(${JSON.stringify(aborted)},'aborted');reject(signal.reason)},{once:true})});`);
const cancelled = spawn(process.execPath, ["--require", preload, entry], { env: { PATH: "/usr/bin:/bin" }, stdio: ["ignore", "ignore", "pipe"] });
const closed = once(cancelled, "close");
let stderr = ""; cancelled.stderr.on("data", chunk => { stderr = (stderr + chunk).slice(-4096); });
const kill = setTimeout(() => cancelled.kill("SIGKILL"), 5_000);
try {
for (let attempt = 0; attempt < 100; attempt++) {
try { await readFile(ready); break; }
catch (error) { if (error.code !== "ENOENT") throw error; await delay(10); }
}
assert.equal(await readFile(ready, "utf8"), "ready");
cancelled.kill("SIGTERM");
const [code, signal] = await closed;
assert.equal(code, 1); assert.equal(signal, null);
assert.match(stderr, /Kimi setup failed/);
assert.equal(await readFile(aborted, "utf8"), "aborted");
assert.deepEqual(await readdir(parent), []);
} finally { clearTimeout(kill); if (cancelled.exitCode === null && cancelled.signalCode === null) { cancelled.kill("SIGKILL"); await closed; } }
});
test("fresh archived installed provisioner downloads the exact closure, reuses it offline and rejects tampering", {
skip: process.env.PAPERCLIP_TEST_KIMI_PUBLIC_SETUP !== "1" && "Set PAPERCLIP_TEST_KIMI_PUBLIC_SETUP=1 for public registry downloads; no model calls or provider credentials",
timeout: 180_000,
}, async t => {
const root = await realpath(await mkdtemp(join(tmpdir(), "paperclip-kimi-public-setup-")));
t.after(() => rm(root, { recursive: true, force: true }));
const packed = join(root, "packed"), pkg = join(packed, "package"), cli = join(pkg, "dist/vendor/paperclip-runner/cli");
await mkdir(cli, { recursive: true });
await writeFile(join(pkg, "package.json"), '{"name":"@paperclipai/server","type":"module"}');
await writeFile(join(pkg, "dist/index.js"), 'throw Error("server must not start");');
await writeFile(join(cli, "acpx-runtime-sidecar.cjs"), "// installed layout fixture");
await bundleKimiProvisioner({ outputRoot: cli });
const archive = join(root, "setup.tgz"), installed = join(root, "installed");
await run("tar", ["-czf", archive, "-C", packed, "package"], { timeout: 10_000 });
await mkdir(installed);
await run("tar", ["-xzf", archive, "-C", installed], { timeout: 10_000 });
const entry = join(installed, "package/dist/vendor/paperclip-runner/cli/provision-kimi.cjs");
const api = createRequire(import.meta.url)(entry);
const environment = api.provisionEnvironment(process.env);
const fresh = await run(process.execPath, ["--use-env-proxy", entry], { env: { ...environment, KIMI_API_KEY: "sensitive-canary", NPM_TOKEN: "sensitive-canary", HOME: "/private/foreign-home" }, timeout: 120_000, maxBuffer: 1024 * 1024 });
assert.doesNotMatch(fresh.stdout + fresh.stderr, /sensitive-canary/);
const receipt = JSON.parse(fresh.stdout.trim());
assert.equal(receipt.status, "installed_verified");
const target = `${process.platform}-${process.arch}`;
const assets = join(installed, "package/dist/vendor/paperclip-runner/provider-assets/kimi", target);
const metadata = JSON.parse(await readFile(join(assets, "kimi-distribution.json"), "utf8"));
assert.equal(metadata.nativeClosureSha256, KIMI_DISTRIBUTION_CLOSURE_SHA256[target]);
const offline = { ...environment, HTTPS_PROXY: "http://127.0.0.1:9", HTTP_PROXY: "http://127.0.0.1:9", https_proxy: "http://127.0.0.1:9", http_proxy: "http://127.0.0.1:9", NO_PROXY: "", no_proxy: "" };
const reused = await run(process.execPath, ["--use-env-proxy", entry], { env: offline, timeout: 20_000, maxBuffer: 1024 * 1024 });
assert.equal(JSON.parse(reused.stdout.trim()).status, "verified_existing");
const worker = join(assets, "runtime/node_modules/@moonshot-ai/kimi-code/dist/search-worker.mjs");
const changed = Buffer.concat([await readFile(worker), Buffer.from("\n// integrity test\n")]);
await writeFile(worker, changed);
await assert.rejects(run(process.execPath, ["--use-env-proxy", entry], { env: offline, timeout: 20_000, maxBuffer: 1024 * 1024 }), error => {
assert.match(error.stderr, /Kimi setup failed/);
assert.doesNotMatch(error.stderr, /download|ECONNREFUSED/i);
return true;
});
assert.deepEqual(await readFile(worker), changed, "Invalid existing assets must not be silently replaced");
t.diagnostic(JSON.stringify({ target, closure: metadata.nativeClosureSha256, patch: metadata.patch.version, provisionerSha256: createHash("sha256").update(await readFile(entry)).digest("hex"), freshInstalled: true, offlineReuse: true, tamperRejected: true, modelPrompts: 0, scope: "self-contained public-layout setup component; full Paperclip tarball is a separate proof" }));
});
@@ -0,0 +1,120 @@
#!/usr/bin/env node
import { constants } from "node:fs";
import { lstat, mkdir, mkdtemp, open, readdir, realpath, rename, rm, unlink, writeFile } from "node:fs/promises";
import { basename, dirname, join, resolve } from "node:path";
import { fileURLToPath, pathToFileURL } from "node:url";
import { materializeKimiDistribution, kimiDistributionEnvironment } from "./materialize-kimi-distribution.mjs";
import { KIMI_DISTRIBUTION_CLOSURE_SHA256 } from "../src/drivers/acpx/kimi-closure-pins.ts";
import { verifyKimiInstallation } from "../src/drivers/acpx/kimi-installation.ts";
import { QUALIFIED_ACPX_PROFILES } from "../src/drivers/acpx/qualified-profiles.ts";
export function provisionEnvironment(source = process.env) {
return { ...kimiDistributionEnvironment(source), LANG: "C.UTF-8", PATH: source.PATH ?? "/usr/bin:/bin" };
}
export async function provisionKimiPackageRoot(entrypoint) {
const canonical = await realpath(entrypoint);
if (canonical !== resolve(entrypoint) || basename(canonical) !== "provision-kimi.cjs" || !(await lstat(canonical)).isFile()) throw new Error("Kimi setup requires its installed entrypoint");
const cli = dirname(canonical);
const vendored = cli.endsWith("/dist/vendor/paperclip-runner/cli");
if (!vendored && !cli.endsWith("/dist/cli")) throw new Error("Kimi setup requires the installed runner or server layout");
const root = resolve(cli, vendored ? "../../../.." : "../..");
const manifest = join(root, "package.json");
const file = await open(manifest, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
try {
const before = await file.stat({ bigint: true });
if (!before.isFile() || before.nlink !== 1n || before.size < 1n || before.size > 64n * 1024n) throw new Error("Kimi setup package manifest is invalid");
const bytes = await file.readFile(), after = await file.stat({ bigint: true }), named = await lstat(manifest, { bigint: true });
if (bytes.length !== Number(before.size) || before.dev !== after.dev || before.ino !== after.ino || before.size !== after.size || before.mtimeNs !== after.mtimeNs || before.ctimeNs !== after.ctimeNs || named.dev !== before.dev || named.ino !== before.ino || named.isSymbolicLink()) throw new Error("Kimi setup package manifest changed");
if (JSON.parse(bytes.toString("utf8")).name !== (vendored ? "@paperclipai/server" : "@paperclipai/paperclip-runner")) throw new Error("Kimi setup package identity does not match its layout");
} finally { await file.close(); }
return { root, manifest, cli, assetRoot: vendored ? resolve(cli, "..") : root };
}
async function verifyInstallation(root, manifest) {
const keys = ["PAPERCLIP_ACPX_PROVIDER_PACKAGE_ROOT", "PAPERCLIP_ACPX_PROVIDER_PACKAGE_MANIFEST"], previous = keys.map(key => process.env[key]);
process.env[keys[0]] = root; process.env[keys[1]] = manifest;
try {
const installation = await verifyKimiInstallation(QUALIFIED_ACPX_PROFILES.kimi);
const lease = await installation.openCommand();
await lease.close();
} finally { keys.forEach((key, index) => { if (previous[index] === undefined) delete process.env[key]; else process.env[key] = previous[index]; }); }
}
async function absent(path) { try { await lstat(path); return false; } catch (error) { if (error.code === "ENOENT") return true; throw error; } }
async function containedDirectory(root, path) {
await mkdir(path, { recursive: true, mode: 0o700 });
if (await realpath(path) !== path || !(await lstat(path)).isDirectory() || !path.startsWith(root + "/")) throw new Error("Kimi setup asset directory escapes its package");
}
export async function provisionKimi(entrypoint, checkCancelled = () => {}, signal) {
checkCancelled(); signal?.throwIfAborted();
const target = `${process.platform}-${process.arch}`;
if (!Object.hasOwn(KIMI_DISTRIBUTION_CLOSURE_SHA256, target)) throw new Error(`Kimi is not supported on ${target}`);
const { root, manifest, cli, assetRoot } = await provisionKimiPackageRoot(entrypoint);
const assets = join(assetRoot, "provider-assets"), parent = join(assets, "kimi");
await containedDirectory(root, assets); await containedDirectory(root, parent);
const lockPath = join(parent, `.setup-${target}.lock`);
const lock = await open(lockPath, constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY | constants.O_NOFOLLOW, 0o600);
let lockIdentity, temporary, temporaryIdentity, published, committed = false;
const output = join(parent, target);
try {
lockIdentity = await lock.stat({ bigint: true });
checkCancelled();
if (!(await absent(output))) {
await verifyInstallation(root, manifest);
return { status: "verified_existing", target, profileDigest: QUALIFIED_ACPX_PROFILES.kimi.commandDigest };
}
temporary = await mkdtemp(join(parent, ".setup-private-")); temporaryIdentity = await lstat(temporary, { bigint: true });
const stagingRoot = join(temporary, "package"); await mkdir(stagingRoot, { mode: 0o700 });
await writeFile(join(stagingRoot, "package.json"), JSON.stringify({ name: "@paperclipai/paperclip-runner" }), { flag: "wx", mode: 0o600 });
const stagedOutput = join(stagingRoot, "provider-assets/kimi", target);
await materializeKimiDistribution({ outputRoot: stagedOutput, lockDirectory: join(cli, "kimi-provision-inputs"), checkCancelled, signal });
await verifyInstallation(stagingRoot, join(stagingRoot, "package.json"));
if (!(await absent(output))) throw new Error("Kimi setup destination appeared during installation; refusing replacement");
checkCancelled();
await mkdir(output, { mode: 0o700 }); published = await lstat(output, { bigint: true });
for (const name of await readdir(stagedOutput)) {
const named = await lstat(output, { bigint: true });
if (named.dev !== published.dev || named.ino !== published.ino || named.isSymbolicLink()) throw new Error("Kimi setup output ownership changed during publication");
await rename(join(stagedOutput, name), join(output, name));
}
await verifyInstallation(root, manifest);
checkCancelled(); committed = true;
return { status: "installed_verified", target, profileDigest: QUALIFIED_ACPX_PROFILES.kimi.commandDigest };
} finally {
const cleanup = [];
if (published && !committed) cleanup.push((async () => {
const named = await lstat(output, { bigint: true });
if (named.dev !== published.dev || named.ino !== published.ino || named.isSymbolicLink()) throw new Error("Kimi setup output ownership changed; refusing cleanup");
await rm(output, { recursive: true });
})());
if (temporary) cleanup.push((async () => {
const named = await lstat(temporary, { bigint: true });
if (!temporaryIdentity || named.dev !== temporaryIdentity.dev || named.ino !== temporaryIdentity.ino || named.isSymbolicLink()) throw new Error("Kimi setup staging ownership changed; refusing cleanup");
await rm(temporary, { recursive: true });
})());
cleanup.push((async () => {
try {
lockIdentity ??= await lock.stat({ bigint: true }); const named = await lstat(lockPath, { bigint: true });
if (named.dev !== lockIdentity.dev || named.ino !== lockIdentity.ino) throw new Error("Kimi setup lock ownership changed; refusing cleanup");
await unlink(lockPath);
} finally { await lock.close(); }
})());
const results = await Promise.allSettled(cleanup), failed = results.filter(result => result.status === "rejected");
if (failed.length) throw new AggregateError(failed.map(result => result.reason), "Kimi setup cleanup failed; inspect the package before retrying");
}
}
if (process.argv[1] && pathToFileURL(resolve(process.argv[1])).href === import.meta.url) {
if (process.argv.length !== 2) throw new Error("Usage: paperclipai runtime setup kimi (explicit host installation; no model calls)");
const environment = provisionEnvironment();
for (const key of Object.keys(process.env)) delete process.env[key]; Object.assign(process.env, environment);
const controller = new AbortController();
const cancel = () => controller.abort();
process.on("SIGINT", cancel); process.on("SIGTERM", cancel);
const deadline = setTimeout(cancel, 900_000); deadline.unref();
provisionKimi(fileURLToPath(import.meta.url), () => { if (controller.signal.aborted) throw new Error("Kimi setup cancelled; no installation was admitted"); }, controller.signal).finally(() => {
clearTimeout(deadline); process.off("SIGINT", cancel); process.off("SIGTERM", cancel);
}).then(result => console.log(JSON.stringify(result))).catch(error => { console.error(`Kimi setup failed: ${error.message}`); process.exitCode = 1; });
}
@@ -1,4 +1,5 @@
import { bindAcpxCandidateAdmission } from "../drivers/acpx/candidate-admission.js";
import { KIMI_DISTRIBUTION_CLOSURE_SHA256 } from "../drivers/acpx/kimi-closure-pins.js";
import { ANTIGRAVITY_DISTRIBUTION_PINS } from "../drivers/acpx/generated-profiles.js";
import { canonicalNativeRuntimeContextDigest } from "../contracts/runtime-context.js";
import { acpxProfileActivity } from "../drivers/acpx/profile-activity.js";
@@ -15,6 +16,7 @@ import { spawn, type ChildProcessWithoutNullStreams } from "node:child_process";
import { readFileSync } from "node:fs";
import { fileURLToPath } from "node:url";
import { createAcpxSidecarHostEnvironment, createSanitizedAcpxSpawnInput } from "../drivers/acpx/environment.js";
import { createKimiMessageProjection } from "../drivers/acpx/kimi-message-boundary.js";
import { afterEach, describe, expect, it, vi } from "vitest";
@@ -563,6 +565,31 @@ describe("qualified ACPX runtime sidecar", () => {
expect(wire.writes).toEqual([]); expect(wire.sequence()).toBe(0);
});
it("preserves validated native assistant boundaries without exposing Kimi provenance metadata", () => {
const source = readFileSync(fileURLToPath(new URL("./acpx-runtime-sidecar.ts", import.meta.url)), "utf8");
const start = source.indexOf(' if (event.type === "text_delta") {', source.indexOf("function sanitizeRuntimeEvent"));
const end = source.indexOf(' if (event.type === "status") {', start);
const sanitize = new Function("boundedOptionalText", "stableProviderIdentity", `return event => {${source.slice(start, end)} return null;}`)(
(value: string) => value, (value: string) => `stable-${value}`,
);
const projection = createKimiMessageProjection<{ type: string; text: string; stream: string; messageId: string; meta: Record<string, string> }>();
const event = (kind: string, text = "", stream = "output") => ({ type: "text_delta", text, stream,
messageId: `kimi-message-${"a".repeat(64)}`,
meta: { origin: "kimi-native-assistant", source: "kimi-turn-step-v1", kind, secret: "PRIVATE_PROVENANCE" } });
const frames = [sanitize(projection.normalize(event("start"))),
sanitize(projection.normalize(event("delta", "Working."))),
sanitize(projection.normalize(event("delta", "Private reasoning", "thought"))),
sanitize(projection.normalize(event("end:tool_use")))];
expect(frames[0]).toMatchObject({ text: "", assistantMessageBoundary: { phase: "start" } });
expect(frames[1]).toMatchObject({ type: "text_delta", text: "Working." });
expect(frames[2]).toMatchObject({ type: "thinking" });
expect(frames[3]).toMatchObject({ text: "", assistantMessageBoundary: { phase: "end", stopReason: "toolUse" } });
expect(new Set(frames.map(frame => frame.messageId)).size).toBe(1);
expect(JSON.stringify(frames)).not.toContain("PRIVATE_PROVENANCE");
expect(JSON.stringify(frames)).not.toContain("kimi-native-assistant");
projection.settle();
});
it("passes only validated Pi native boundaries and history through the real text sanitizer", () => {
const source = readFileSync(fileURLToPath(new URL("./acpx-runtime-sidecar.ts", import.meta.url)), "utf8");
const start = source.indexOf(' if (event.type === "text_delta") {', source.indexOf("function sanitizeRuntimeEvent"));
@@ -1258,17 +1285,56 @@ describe("qualified ACPX runtime sidecar", () => {
});
it.each([
["cursor", "explicit-cursor-model"],
["copilot", "explicit-copilot-model"],
] as const)("initializes the declared %s profile with its current admission status", async (agent, model) => {
["cursor", "explicit-cursor-model", "qualified"],
["copilot", "explicit-copilot-model", "pending"],
["kimi", "explicit-kimi-model", resolveQualifiedAcpxProfile("kimi", "explicit-kimi-model").qualificationStatus === "pending" ? "pending" : "qualified"],
] as const)("initializes the declared %s profile with its current admission status", async (agent, model, qualification) => {
const sidecar = startSidecar();
const profile = resolveQualifiedAcpxProfile(agent, model);
sidecar.write(initializeRequest(1, agent, model));
const frame = await sidecar.next((value) => value.id === 1);
expect(ACPX_CAPABILITY_PROFILES[agent].qualification).toBe(qualification);
if (agent === "kimi" && profile.qualificationStatus === "pending") {
expect(frame).toMatchObject({ id: 1, ok: false,
error: { message: expect.stringContaining("qualification is pending"), retryable: false } });
return;
}
expect(frame).toMatchObject({ id: 1, ok: true });
const result = frame.result as Record<string, unknown>;
expect(result.profile).toEqual(resolveQualifiedAcpxProfile(agent, model));
expect(result.profile).toEqual(profile);
expect(result.profile).toMatchObject({ reportedModelId: model });
expect(ACPX_CAPABILITY_PROFILES[agent].qualification).toBe(agent === "cursor" ? "qualified" : "pending");
});
it.each([
["darwin", "arm64"], ["linux", "x64"],
] as const)("binds Kimi startup to its declared %s/%s host and session before provider launch", async (platform, architecture) => {
const sidecar = startSidecar(), model = "explicit-kimi-model";
const profile = resolveQualifiedAcpxProfile("kimi", model);
const request = initializeRequest(1, "kimi", model);
if (profile.qualificationStatus !== "pending") {
sidecar.write(request);
expect(await sidecar.next(frame => frame.id === 1)).toMatchObject({ ok: true, result: { profile } });
return;
}
const target = `${platform}-${architecture}` as "darwin-arm64" | "linux-x64";
const candidateAdmission = bindAcpxCandidateAdmission({ schema: "paperclip.acpx-candidate-admission.v1",
companyId: "company-kimi-candidate", agent: "kimi", model, profileDigest: profile.commandDigest,
nativeClosureDigest: `sha256:${KIMI_DISTRIBUTION_CLOSURE_SHA256[target]}`,
platform, architecture, expiresAt: Date.now() + 60_000,
}, { runId: "run-kimi-candidate", normalizedSessionId: "session-kimi-candidate" });
sidecar.write({ ...request, params: { ...request.params, candidateAdmission } });
const frame = await sidecar.next(value => value.id === 1);
if (process.platform !== platform || process.arch !== architecture) {
expect(frame).toMatchObject({ ok: false, error: { message: expect.stringContaining("candidate admission"), retryable: false } });
return;
}
expect(frame).toMatchObject({ ok: true, result: { profile } });
expect((frame.result as Record<string, unknown>).profile).toMatchObject({ reportedModelId: model });
sidecar.write({ protocolVersion: ACPX_SIDECAR_PROTOCOL_VERSION, id: 2, command: "session.open", params: {
runtimeDirectory: "/unused", workingDirectory: "/unused", normalizedSessionId: "other-kimi-session", agent: "kimi", model,
candidateAdmission, permissionMode: "deny-all", permissionModePinned: true, providerPolicy: { readOnly: true }, systemInstructions: "", tools: [],
} });
expect(await sidecar.next(value => value.id === 2)).toMatchObject({ ok: false, error: { message: expect.stringContaining("candidate admission") } });
});
it("refuses pending Antigravity bootstrap before any native process opens", async () => {
@@ -1312,7 +1378,7 @@ describe("qualified ACPX runtime sidecar", () => {
ok: false,
error: {
code: "acpx_sidecar_command_failed",
message: "ACPX agent must be claude, codex, grok, cursor, copilot, pi, or antigravity",
message: "ACPX agent must be claude, codex, grok, cursor, copilot, kimi, pi, or antigravity",
retryable: false,
},
});
@@ -1338,7 +1404,7 @@ function initializeRequest(
id: number,
agent: string,
model = "gpt-5.6-sol",
): Record<string, unknown> {
) {
return {
protocolVersion: ACPX_SIDECAR_PROTOCOL_VERSION,
id,
@@ -27,6 +27,7 @@ import { acpxProfileClientCapabilities, bindAcpxExtensionTurn, validateAcpxRichE
import type { PaperclipQuestionSet } from "../contracts/question-set.js";
import { createAcpxToolEventNormalizer, createGrokMessageNormalizer } from "../provider-events.js";
import { createPiMessageProjection, type PiProjectedMessageEvent } from "../drivers/acpx/pi-message-projection.js";
import { createKimiMessageProjection, type KimiProjectedMessageEvent } from "../drivers/acpx/kimi-message-boundary.js";
import { parseNativeRuntimeContext } from "../contracts/runtime-context.js";
import {
PRP_BLOCK_TOOL_NAME,
@@ -667,7 +668,8 @@ async function pumpTurn(
// the sidecar boundary, matching the in-process ACPX driver path.
const normalizeToolEvent = createAcpxToolEventNormalizer<AcpRuntimeEvent>();
const piMessages = initializedAgent === "pi" ? createPiMessageProjection<AcpRuntimeEvent>() : null;
const normalizeMessage = piMessages ? piMessages.normalize : initializedAgent === "grok"
const kimiMessages = initializedAgent === "kimi" ? createKimiMessageProjection<AcpRuntimeEvent>() : null;
const normalizeMessage = kimiMessages ? kimiMessages.normalize : piMessages ? piMessages.normalize : initializedAgent === "grok"
? createGrokMessageNormalizer<AcpRuntimeEvent>() : (event: AcpRuntimeEvent) => event;
for await (const event of runtimeTurn.events) {
toolEvidence?.tool(event);
@@ -680,7 +682,7 @@ async function pumpTurn(
);
}
const result = await runtimeTurn.result;
if (result.status === "completed") piMessages?.settle();
if (result.status === "completed") { piMessages?.settle(); kimiMessages?.settle(); }
await drainExtensions();
try {
const usageAfter = await readSidecarHostStatusWithin(activeHost);
@@ -1037,7 +1039,7 @@ function boundRuntimeEventForNormalization(
} as BoundedRuntimeToolEvent;
}
function sanitizeRuntimeEvent(event: PiProjectedMessageEvent<AcpRuntimeEvent>): Record<string, unknown> {
function sanitizeRuntimeEvent(event: PiProjectedMessageEvent<AcpRuntimeEvent> & KimiProjectedMessageEvent<AcpRuntimeEvent>): Record<string, unknown> {
const runtimeType = text(record(event).type);
if (runtimeType === "plan") {
return {
@@ -1053,6 +1055,8 @@ function sanitizeRuntimeEvent(event: PiProjectedMessageEvent<AcpRuntimeEvent>):
tag: event.tag ?? null,
...(event.piMessageBoundary ? { piMessageBoundary: event.piMessageBoundary } : {}),
...(event.piMessageHistory ? { piMessageHistory: true } : {}),
...(event.assistantMessageBoundary ? { assistantMessageBoundary: event.assistantMessageBoundary } : {}),
...(event.assistantMessageHistory ? { assistantMessageHistory: true } : {}),
messageId:
typeof event.messageId === "string" && event.messageId.length > 0
? stableProviderIdentity(event.messageId, "message")
@@ -1478,8 +1482,8 @@ function requireHost(
}
function requireQualifiedAgent(value: unknown, model?: string, candidateAdmission?: AcpxCandidateStartupAdmission): QualifiedAcpxAgent {
if (value !== "grok" && value !== "codex" && value !== "claude" && value !== "pi" && value !== "cursor" && value !== "copilot" && value !== "antigravity") {
throw new Error("ACPX agent must be claude, codex, grok, cursor, copilot, pi, or antigravity");
if (value !== "grok" && value !== "codex" && value !== "claude" && value !== "pi" && value !== "cursor" && value !== "copilot" && value !== "kimi" && value !== "antigravity") {
throw new Error("ACPX agent must be claude, codex, grok, cursor, copilot, kimi, pi, or antigravity");
}
if (candidateAdmission) assertAcpxExecutionAdmission(resolveQualifiedAcpxProfile(value, model ?? ""), candidateAdmission);
else assertAcpxProfileReleased(value);
@@ -0,0 +1,30 @@
#!/usr/bin/env node
import { parseAcpxCandidateStartupAdmission, type AcpxCandidateStartupAdmission } from "../drivers/acpx/candidate-admission.js";
import { probeKimiMetadata } from "../drivers/acpx/kimi-metadata-probe.js";
import { KIMI_NODE_VERSION } from "../drivers/acpx/kimi-closure-pins.js";
async function main() {
const model = process.env.PAPERCLIP_KIMI_PROBE_MODEL ?? "", apiKey = process.env.KIMI_API_KEY ?? "";
const encodedAdmission = process.env.PAPERCLIP_ACPX_CANDIDATE_ADMISSION;
const bindings = { PAPERCLIP_ACPX_PROVIDER_PACKAGE_ROOT: process.env.PAPERCLIP_ACPX_PROVIDER_PACKAGE_ROOT,
PAPERCLIP_ACPX_PROVIDER_PACKAGE_MANIFEST: process.env.PAPERCLIP_ACPX_PROVIDER_PACKAGE_MANIFEST };
for (const name of Object.keys(process.env)) delete process.env[name];
for (const [name, value] of Object.entries(bindings)) if (value !== undefined) process.env[name] = value;
let candidateAdmission: AcpxCandidateStartupAdmission | undefined;
if (encodedAdmission !== undefined) {
if (Buffer.byteLength(encodedAdmission) > 4096) throw new Error("Invalid metadata admission");
candidateAdmission = parseAcpxCandidateStartupAdmission(JSON.parse(encodedAdmission), { agent: "kimi", model });
}
const result = process.versions.node !== KIMI_NODE_VERSION
? { schema: "paperclip.kimi.metadata.v1", status: "failed", code: "KIMI_INSTALLATION_INVALID",
message: "Kimi metadata verification requires the pinned Node runtime.", promptSent: false }
: await probeKimiMetadata(model, apiKey, candidateAdmission);
process.stdout.write(`${JSON.stringify(result)}\n`);
if (result.status !== "verified") process.exitCode = 1;
}
void main().catch(() => {
process.stdout.write(`${JSON.stringify({ schema: "paperclip.kimi.metadata.v1", status: "failed", code: "KIMI_REQUEST_FAILED",
message: "Kimi Code metadata verification failed.", promptSent: false })}\n`);
process.exitCode = 1;
});
@@ -72,6 +72,23 @@ describe("configured environment authority", () => {
expect(projected.PAPERCLIP_API_KEY).toBeUndefined();
});
it("reserves Kimi credentials for the selected provider instead of the generic task projection", async () => {
const { createSanitizedAcpxSpawnInput } = await import("./drivers/acpx/environment.js");
const projected = configuredEnvironmentProjection({ KIMI_API_KEY: "selected-kimi-secret", CUSTOM_FLAG: "allowed" });
expect(projected.KIMI_API_KEY).toBeUndefined();
expect(JSON.parse(projected[CONFIGURED_ENVIRONMENT_KEYS]!)).toEqual(["CUSTOM_FLAG"]);
expect(() => configuredEnvironment({ [CONFIGURED_ENVIRONMENT_KEYS]: '["KIMI_API_KEY"]', KIMI_API_KEY: "selected-kimi-secret" }))
.toThrow("Invalid configured environment projection");
const selected = { ...projected, KIMI_API_KEY: "selected-kimi-secret" };
expect(createSanitizedCodexEnvironment(selected).KIMI_API_KEY).toBeUndefined();
for (const agent of ["claude", "codex", "grok", "cursor", "copilot"] as const) {
expect(createSanitizedAcpxSpawnInput(selected, agent).env.KIMI_API_KEY).toBeUndefined();
}
expect(createSanitizedAcpxSpawnInput(selected, "kimi").env).toMatchObject({ KIMI_API_KEY: "selected-kimi-secret", CUSTOM_FLAG: "allowed" });
// Pi already supports this credential through its explicit SDK allowlist.
expect(createSanitizedAcpxSpawnInput(selected, "pi").env.KIMI_API_KEY).toBe("selected-kimi-secret");
});
it("does not accept an ambient projection in the provider or shell policy", () => {
vi.stubEnv(CONFIGURED_ENVIRONMENT_KEYS, JSON.stringify(["PAPERCLIP_PAGE_AWS_SECRET_ACCESS_KEY"]));
vi.stubEnv("PAPERCLIP_PAGE_AWS_SECRET_ACCESS_KEY", "ambient-secret");
@@ -81,7 +98,7 @@ describe("configured environment authority", () => {
} finally { vi.unstubAllEnvs(); }
});
it.each(["not-json", "[1]", '["NODE_OPTIONS"]', '["PAPERCLIP_API_KEY"]', '["PAPERCLIP_RUNNER_BOOTSTRAP_TICKET"]', '["OPENAI_API_KEY"]', '["LD_PRELOAD"]', '["bad=name"]', '["CUSTOM","CUSTOM"]', '["MISSING"]'])
it.each(["not-json", "[1]", '["NODE_OPTIONS"]', '["PAPERCLIP_API_KEY"]', '["PAPERCLIP_RUNNER_BOOTSTRAP_TICKET"]', '["OPENAI_API_KEY"]', '["KIMI_API_KEY"]', '["LD_PRELOAD"]', '["bad=name"]', '["CUSTOM","CUSTOM"]', '["MISSING"]'])
("rejects malformed or reserved projection %s", raw => {
expect(() => configuredEnvironment({ [CONFIGURED_ENVIRONMENT_KEYS]: raw })).toThrow("Invalid configured environment");
});
@@ -30,7 +30,7 @@ const RESERVED_KEYS = new Set([
"PYTHONPATH", "PYTHONHOME", "RUBYOPT", "RUBYLIB", "PERL5OPT", "PERL5LIB", "BASH_ENV", "ENV", "ZDOTDIR", "GH_CONFIG_DIR",
"OPENAI_API_KEY", "CODEX_API_KEY", "ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN", "CLAUDE_CODE_OAUTH_TOKEN",
"AWS_BEARER_TOKEN_BEDROCK", "OPENROUTER_API_KEY", "XAI_API_KEY", "CURSOR_API_KEY", "CURSOR_AUTH_TOKEN",
"COPILOT_GITHUB_TOKEN", "GH_TOKEN", "GITHUB_TOKEN", "GH_ENTERPRISE_TOKEN", "GITHUB_ENTERPRISE_TOKEN", "PAPERCLIP_GIT_TOKEN",
"COPILOT_GITHUB_TOKEN", "KIMI_API_KEY", "GH_TOKEN", "GITHUB_TOKEN", "GH_ENTERPRISE_TOKEN", "GITHUB_ENTERPRISE_TOKEN", "PAPERCLIP_GIT_TOKEN",
]);
function eligibleKey(key: string): boolean {
@@ -2,7 +2,7 @@ import { resolveGrokDisableWebSearch } from "../drivers/acpx/grok-web-search.js"
import { resolveGrokEffort } from "../drivers/acpx/grok-effort.js";
import { resolveClaudeEffort } from "../drivers/acpx/claude-effort.js";
import type { DotBindingSnapshot, MuseBindingSnapshot, ExternalBotProviderKind } from "./external-provider.js";
import { QUALIFIED_ACPX_VERSION } from "../drivers/acpx/generated-profiles.js";
import { QUALIFIED_ACPX_VERSION, QUALIFIED_ACPX_PROFILE_DATA } from "../drivers/acpx/generated-profiles.js";
import { isSupportedAcpxProfileVersion, type AcpxProfileVersion } from "../drivers/acpx/profile-compatibility.js";
import { isProviderMode } from "./provider-mode.js";
import { createHash } from "node:crypto";
@@ -93,7 +93,11 @@ export interface NativeAwsAgentCoreProfileSnapshot {
eventExpiryDays: 90;
}
export type NativeAcpxAgent = "pi" | "claude" | "codex" | "grok" | "cursor" | "copilot" | "antigravity";
export type NativeAcpxAgent = keyof typeof QUALIFIED_ACPX_PROFILE_DATA;
function isNativeAcpxAgent(value: unknown): value is NativeAcpxAgent {
return typeof value === "string" && Object.hasOwn(QUALIFIED_ACPX_PROFILE_DATA, value);
}
export type NativeCodexApprovalPolicy = "never" | "on-request" | "untrusted";
export type NativeOpenCodePermissionMode = "allow" | "ask" | "deny";
export type NativeAcpxPermissionMode = "approve-all" | "approve-paperclip" | "approve-reads" | "deny-all";
@@ -709,8 +713,8 @@ export function parseNativeExecutionInput(value: unknown): NativeExecutionInput
if (providerModel === null) {
throw new NativeExecutionInputError("input.provider.model is required for acpx");
}
if (provider.agent !== "pi" && provider.agent !== "claude" && provider.agent !== "codex" && provider.agent !== "grok" && provider.agent !== "cursor" && provider.agent !== "copilot" && provider.agent !== "antigravity") {
throw new NativeExecutionInputError("input.provider.agent must be pi, claude, codex, grok, cursor, copilot, or antigravity");
if (!isNativeAcpxAgent(provider.agent)) {
throw new NativeExecutionInputError("input.provider.agent must name a registered ACPX profile");
}
if (isV4) {
if (provider.permissionMode !== "approve-all" && provider.permissionMode !== "approve-paperclip" && provider.permissionMode !== "approve-reads" && provider.permissionMode !== "deny-all") {
@@ -0,0 +1,46 @@
import { redactPaperclipSemanticValue } from "../../semantic-tools/redaction.js";
import { safeAcpxLocations } from "./safe-locations.js";
import { lstatSync, realpathSync } from "node:fs";
import { basename, dirname, isAbsolute, join } from "node:path";
const record = (value: unknown): Record<string, unknown> =>
value !== null && typeof value === "object" && !Array.isArray(value) ? value as Record<string, unknown> : {};
function aliasedLocation(path: string, cwd: string): string | undefined {
if (!isAbsolute(path)) return;
try {
const canonicalCwd = realpathSync(cwd);
let canonicalPath: string;
try {
lstatSync(path);
canonicalPath = realpathSync(path);
} catch (error) {
if ((error as NodeJS.ErrnoException).code !== "ENOENT") return;
try { lstatSync(path); return; } catch (missing) {
if ((missing as NodeJS.ErrnoException).code !== "ENOENT") return;
}
canonicalPath = join(realpathSync(dirname(path)), basename(path));
}
return safeAcpxLocations([{ path: canonicalPath }], canonicalCwd, "edit")[0]?.path as string | undefined;
} catch { return; }
}
export function safeAcpxEditTarget(value: unknown, workingDirectory: string | undefined): string | undefined {
const call = record(value);
if (call.kind !== "edit" || !workingDirectory) return;
const input = record(call.rawInput);
if (call.locations !== undefined && !Array.isArray(call.locations)) return;
if (Array.isArray(call.locations) && (call.locations.length > 16 || call.locations.some(x => typeof record(x).path !== "string"))) return;
const paths = [input.path, input.fileName, ...(Array.isArray(call.locations) ? call.locations.map(x => record(x).path) : [])].filter(x => x !== undefined);
if (!paths.length || paths.some(x => typeof x !== "string" || !x || x.trim() !== x || x.length > 2048 || /[\\\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/u.test(x))) return;
const safe = paths.flatMap(path => {
const locations = safeAcpxLocations([{ path }], workingDirectory, call.kind, call.title);
if (locations.length) return locations;
const aliased = aliasedLocation(path as string, workingDirectory);
return aliased ? [{ path: aliased }] : [];
});
const names = safe.map(x => x.path).filter((x): x is string => typeof x === "string" && x.length <= 1024 && x.trim() === x && !x.includes(":"));
if (names.length !== paths.length || new Set(names).size !== 1) return;
const target = names[0];
return target && redactPaperclipSemanticValue(target) === target ? target : undefined;
}
@@ -13,7 +13,7 @@ function request(kinds = ["allow_once", "allow_always", "reject_once"]): AcpPerm
} } as AcpPermissionRequest;
}
describe("ACP permission normalization", () => {
it.each([undefined, "codex", "claude", "pi", "copilot"])("preserves existing %s native identity behavior", provider => {
it.each([undefined, "codex", "claude", "pi", "copilot", "kimi"])("preserves existing %s native identity behavior", provider => {
const native = request(); native.raw.toolCall.toolCallId = "native\u0000tool";
expect(normalizeAcpxPermission(native, { provider }).toolCallId).toBe("native\u0000tool");
});
@@ -93,6 +93,42 @@ describe("ACP permission normalization", () => {
});
});
describe("Kimi canonical file permission context", () => {
const context = { provider: "kimi", workingDirectory: "/fixture/workspace", allowAlwaysScope: "session" as const };
function write(call: Record<string, unknown> = {}) {
const value = request();
Object.assign(value.raw.toolCall, { toolCallId: "kimi-write-native-id", kind: "edit", title: "Write", rawInput: { path: "/fixture/workspace/nested/result.txt", content: "PRIVATE_KIMI_CONTENT" }, locations: [{ path: "nested/result.txt" }], ...call });
return value;
}
it("shows the native Write target and preserves its exact operation and decision identity", () => {
const normalized = normalizeAcpxPermission(write(), context);
expect(normalized.title).toBe("Change file: nested/result.txt");
expect(normalized.toolCallId).toBe("kimi-write-native-id");
expect(JSON.stringify(normalized)).not.toContain("PRIVATE_KIMI_CONTENT");
expect(normalized.resolve({ action: "accept" })).toEqual({ outcome: "allow_once" });
expect(normalized.resolve({ action: "accept_for_session" })).toEqual({ outcome: "allow_always" });
expect(normalized.resolve({ action: "decline" })).toEqual({ outcome: "reject_once" });
});
it.each([
{ name: "unknown", rawInput: {}, locations: [] },
{ name: "conflicting", rawInput: { path: "one.txt" }, locations: [{ path: "two.txt" }] },
{ name: "outside", rawInput: { path: "/outside/result.txt" }, locations: [] },
])("offers only denial or cancellation for a $name Write target", ({ rawInput, locations }) => {
const normalized = normalizeAcpxPermission(write({ rawInput, locations }), context);
expect(normalized.title).toContain("target unavailable");
expect(normalized.toolCallId).toBe("kimi-write-native-id");
expect(normalized.choices.map(choice => choice.key)).toEqual(["decline", "cancel"]);
expect(normalized.resolve({ action: "decline" })).toEqual({ outcome: "reject_once" });
expect(normalized.resolve({ action: "cancel" })).toEqual({ outcome: "cancel" });
for (const action of ["accept", "accept_for_session"] as const) expect(() => normalized.resolve({ action })).toThrow("not an offered choice");
});
it("requires a bound workspace before allowing a native Write", () => {
const normalized = normalizeAcpxPermission(write(), { provider: "kimi" });
expect(normalized.choices.map(choice => choice.key)).toEqual(["decline", "cancel"]);
expect(() => normalized.resolve({ action: "accept" })).toThrow("not an offered choice");
});
});
describe("Copilot canonical file permission context", () => {
const context = { provider: "copilot", workingDirectory: "/fixture/workspace", allowAlwaysScope: "session" as const };
@@ -4,7 +4,7 @@ import { cursorToolIdentity } from "./cursor-plan-tool-identity.js";
import { safeCopilotEditTarget } from "./copilot-permission-context.js";
import { safeAcpxEditTarget } from "./acp-edit-context.js";
export type AcpxPermissionAction = "accept" | "accept_for_session" | "decline" | "cancel";
export interface NormalizedAcpxPermission {
@@ -39,8 +39,8 @@ export function normalizeAcpxPermission(request: AcpPermissionRequest, options:
|| (options.provider === "cursor" && !call.toolCallId.trim())) {
throw new Error("ACP permission request omitted its tool identity");
}
const needsEditContext = options.provider === "copilot" && call.kind === "edit";
const target = needsEditContext ? safeCopilotEditTarget(call, options.workingDirectory) : undefined;
const needsEditContext = (options.provider === "copilot" || options.provider === "kimi") && call.kind === "edit";
const target = needsEditContext ? safeAcpxEditTarget(call, options.workingDirectory) : undefined;
const bindings = new Map<AcpxPermissionAction, AcpPermissionDecision["outcome"]>();
const choices: NormalizedAcpxPermission["choices"] = [];
for (const [key, kind, label] of [
@@ -1,4 +1,5 @@
import { afterEach, describe, expect, it, vi } from "vitest";
import { KIMI_DISTRIBUTION_CLOSURE_SHA256 } from "./kimi-closure-pins.js";
import { ANTIGRAVITY_DISTRIBUTION_PINS } from "./generated-profiles.js";
import { assertAcpxProfileReleased, resolveQualifiedAcpxProfile } from "./qualified-profiles.js";
import { assertAcpxExecutionAdmission, bindAcpxCandidateAdmission, parseAcpxCandidateAdmission, parseAcpxCandidateStartupAdmission, type AcpxCandidateAdmission } from "./candidate-admission.js";
@@ -95,3 +96,59 @@ describe("candidate installation remains cryptographically verified", () => {
expect(openRuntime).not.toHaveBeenCalled();
});
});
describe("trusted Kimi candidate admission", () => {
const kimiExpected = { companyId: "company-kimi", agent: "kimi", model: "kimi-for-coding" };
const kimiCandidate = (target: "darwin-arm64" | "linux-x64"): AcpxCandidateAdmission => ({
schema: "paperclip.acpx-candidate-admission.v1", ...kimiExpected, agent: "kimi",
profileDigest: resolveQualifiedAcpxProfile("kimi", kimiExpected.model).commandDigest,
nativeClosureDigest: `sha256:${KIMI_DISTRIBUTION_CLOSURE_SHA256[target]}`,
platform: target === "darwin-arm64" ? "darwin" : "linux",
architecture: target === "darwin-arm64" ? "arm64" : "x64", expiresAt: now + 60_000,
});
it.each(["darwin-arm64", "linux-x64"] as const)("binds only the current pending Kimi profile and exact %s closure", target => {
expect(resolveQualifiedAcpxProfile("kimi", kimiExpected.model)).toMatchObject({ agentProfileVersion: 16, qualificationStatus: "pending" });
expect(parseAcpxCandidateAdmission(kimiCandidate(target), kimiExpected, now)).toEqual(kimiCandidate(target));
expect(() => assertAcpxProfileReleased("kimi")).toThrow("qualification is pending");
expect(() => assertAcpxExecutionAdmission(resolveQualifiedAcpxProfile("kimi", kimiExpected.model))).toThrow("qualification is pending");
const other = target === "darwin-arm64" ? "linux-x64" : "darwin-arm64";
for (const change of [
{ companyId: "foreign-company" }, { agent: "antigravity" }, { model: "another-model" },
{ model: "auto" }, { model: "default" }, { model: " kimi-for-coding" },
{ profileDigest: `sha256:${"0".repeat(64)}` },
{ nativeClosureDigest: `sha256:${KIMI_DISTRIBUTION_CLOSURE_SHA256[other]}` },
{ platform: "linux", architecture: "arm64" }, { platform: "darwin", architecture: "x64" },
{ expiresAt: now }, { expiresAt: now + 86_400_001 }, { expiresAt: "1800000060000" },
{ unknown: true }, { runId: "injected-run" },
]) expect(() => parseAcpxCandidateAdmission({ ...kimiCandidate(target), ...change }, kimiExpected, now)).toThrow(expect.objectContaining({ code: "ACPX_CANDIDATE_ADMISSION_INVALID" }));
});
it.each(["darwin-arm64", "linux-x64"] as const)("requires the exact actual host and startup identity for %s", target => {
const startup = bindAcpxCandidateAdmission({ ...kimiCandidate(target), expiresAt: Date.now() + 60_000 },
{ runId: "kimi-run", normalizedSessionId: "kimi-session" });
const profile = resolveQualifiedAcpxProfile("kimi", kimiExpected.model);
const platform = Object.getOwnPropertyDescriptor(process, "platform")!;
const architecture = Object.getOwnPropertyDescriptor(process, "arch")!;
try {
Object.defineProperty(process, "platform", { ...platform, value: startup.platform });
Object.defineProperty(process, "arch", { ...architecture, value: startup.architecture });
expect(() => assertAcpxExecutionAdmission(profile, startup)).not.toThrow();
for (const identity of [{ runId: "foreign-run" }, { normalizedSessionId: "foreign-session" }, { model: "foreign-model" }]) {
expect(() => parseAcpxCandidateStartupAdmission(startup, { ...kimiExpected, runId: "kimi-run", normalizedSessionId: "kimi-session", ...identity })).toThrow();
}
expect(() => assertAcpxExecutionAdmission({ ...profile, commandDigest: `sha256:${"f".repeat(64)}` }, startup)).toThrow();
expect(() => parseAcpxCandidateStartupAdmission(startup, kimiExpected, startup.expiresAt)).toThrow();
for (const [os, arch] of [["win32", "x64"], ["linux", "arm64"], ["darwin", "x64"],
target === "darwin-arm64" ? ["linux", "x64"] : ["darwin", "arm64"]]) {
Object.defineProperty(process, "platform", { ...platform, value: os });
Object.defineProperty(process, "arch", { ...architecture, value: arch });
expect(() => assertAcpxExecutionAdmission(profile, startup)).toThrow();
}
} finally {
Object.defineProperty(process, "platform", platform);
Object.defineProperty(process, "arch", architecture);
}
});
});
@@ -1,3 +1,4 @@
import { KIMI_DISTRIBUTION_CLOSURE_SHA256 } from "./kimi-closure-pins.js";
import { ANTIGRAVITY_DISTRIBUTION_PINS } from "./generated-profiles.js";
import { QUALIFIED_ACPX_PROFILES, assertAcpxProfileReleased, type QualifiedAcpxProfile } from "./qualified-profiles.js";
@@ -5,12 +6,12 @@ import { QUALIFIED_ACPX_PROFILES, assertAcpxProfileReleased, type QualifiedAcpxP
export interface AcpxCandidateAdmission {
schema: "paperclip.acpx-candidate-admission.v1";
companyId: string;
agent: "antigravity";
agent: "antigravity" | "kimi";
model: string;
profileDigest: string;
nativeClosureDigest: string;
platform: "darwin";
architecture: "arm64";
platform: "darwin" | "linux";
architecture: "arm64" | "x64";
expiresAt: number;
}
@@ -31,16 +32,23 @@ export function parseAcpxCandidateAdmission(
): AcpxCandidateAdmission {
if (value === null || typeof value !== "object" || Array.isArray(value)) return invalid();
const entry = value as Record<string, unknown>;
const profile = entry.agent === "antigravity" ? QUALIFIED_ACPX_PROFILES.antigravity
: entry.agent === "kimi" ? QUALIFIED_ACPX_PROFILES.kimi : undefined;
const target = `${entry.platform}-${entry.architecture}`;
const closure = entry.agent === "antigravity" && target === "darwin-arm64"
? ANTIGRAVITY_DISTRIBUTION_PINS["darwin-arm64"].closureSha256
: entry.agent === "kimi" && (target === "darwin-arm64" || target === "linux-x64")
? KIMI_DISTRIBUTION_CLOSURE_SHA256[target] : undefined;
if (!Number.isSafeInteger(now) || now < 0 || Object.keys(entry).length !== BASE_FIELDS.length || Object.keys(entry).some(key => !BASE_FIELDS.includes(key))
|| entry.schema !== "paperclip.acpx-candidate-admission.v1"
|| !stableId(entry.companyId) || entry.companyId !== expected.companyId
|| entry.agent !== "antigravity" || entry.agent !== expected.agent
|| !profile || entry.agent !== expected.agent
|| entry.agent === "kimi" && profile.qualificationStatus !== "pending"
|| typeof entry.model !== "string" || entry.model !== expected.model || !entry.model.trim()
|| entry.model !== entry.model.trim() || Buffer.byteLength(entry.model) > 512 || /[\u0000-\u001f\u007f]/.test(entry.model)
|| ["auto", "default"].includes(entry.model.toLowerCase())
|| entry.profileDigest !== QUALIFIED_ACPX_PROFILES.antigravity.commandDigest
|| entry.nativeClosureDigest !== `sha256:${ANTIGRAVITY_DISTRIBUTION_PINS["darwin-arm64"].closureSha256}`
|| entry.platform !== "darwin" || entry.architecture !== "arm64"
|| entry.profileDigest !== profile.commandDigest
|| !closure || entry.nativeClosureDigest !== `sha256:${closure}`
|| !Number.isSafeInteger(entry.expiresAt) || Number(entry.expiresAt) <= now
|| Number(entry.expiresAt) > now + 24 * 60 * 60 * 1000) return invalid();
return { ...entry } as unknown as AcpxCandidateAdmission;
@@ -74,7 +82,7 @@ export function parseAcpxCandidateStartupAdmission(
/** This exception is deliberately absent from direct driver/config admission. */
export function assertAcpxExecutionAdmission(profile: QualifiedAcpxProfile, candidate?: AcpxCandidateStartupAdmission): void {
if (candidate === undefined) return assertAcpxProfileReleased(profile.agent);
if (process.platform !== "darwin" || process.arch !== "arm64") return invalid();
parseAcpxCandidateStartupAdmission(candidate, { agent: profile.agent, model: profile.qualificationModel });
if (candidate.platform !== process.platform || candidate.architecture !== process.arch) return invalid();
if (profile.commandDigest !== candidate.profileDigest) return invalid();
}
@@ -62,6 +62,12 @@ export const ACPX_CAPABILITY_PROFILES: Readonly<Record<QualifiedAcpxAgent, AcpxC
artifacts: "references-pending", extensionRequests: [],
extensionNotifications: ["github.com/copilot/sessionEvent"],
},
kimi: {
displayName: "Kimi Code", qualification: "pending", models: "explicit-provider-verified",
permissions: "interactive", questions: "semantic-only", plans: "semantic-only", tools: "authenticated-mcp",
recovery: "unverified", usage: "unverified", steering: "unsupported", followUp: "controller-queue",
artifacts: "policy_disabled", extensionRequests: [], extensionNotifications: [],
},
pi: {
displayName: "Pi", qualification: "qualified", models: "explicit-provider-verified",
permissions: "interactive", questions: "form", plans: "semantic-only", tools: "owned-extension",
@@ -4,6 +4,7 @@ import { createHash } from "node:crypto";
import { cursorToolIdentity } from "./cursor-plan-tool-identity.js";
import { describe, expect, it, vi } from "vitest";
import { AcpxProviderProcessLostError } from "./codex-runtime-adapter.js";
import { QUALIFIED_ACPX_PROFILES } from "./qualified-profiles.js";
import type { AcpRuntimeEvent } from "acpx/runtime";
@@ -209,6 +210,44 @@ describe("Codex ACPX harness driver", () => {
await session.close({ reason: "native attribution verified" });
});
it.runIf(QUALIFIED_ACPX_PROFILES.kimi.qualificationStatus === "pending")("rejects pending Kimi before opening a direct runtime host", () => {
const openHost = vi.fn();
expect(() => driverFixture({ agent: "kimi", model: "kimi-for-coding", providerPolicy: { readOnly: true } }, { openHost }))
.toThrow(expect.objectContaining({ code: "ACPX_PROFILE_QUALIFICATION_PENDING", retryable: false }));
expect(openHost).not.toHaveBeenCalled();
});
it.skipIf(QUALIFIED_ACPX_PROFILES.kimi.qualificationStatus === "pending").each(["exact-final", "tool-only", "empty-final", "missing-end", "cancelled", "filtered", "paused", "max-tokens"])("qualified Kimi direct-driver step boundaries separate commentary from the actual final response: %s", async scenario => {
const id = (n: number) => `kimi-message-${String(n).padStart(64, "0")}`;
const chunk = (n: number, kind: string, text = "", stream: "output" | "thought" = "output"): AcpRuntimeEvent => ({
type: "text_delta", text, stream, messageId: id(n), meta: { origin: "kimi-native-assistant", source: "kimi-turn-step-v1", kind },
});
const runtimeEvents = [chunk(1, "start"), chunk(1, "delta", "Calling finish."), chunk(1, "end:tool_use")];
if (scenario !== "tool-only") {
runtimeEvents.push(chunk(2, "start"), chunk(2, "delta", "private thought", "thought"));
if (scenario !== "empty-final") runtimeEvents.push(chunk(2, "delta", "EXACT_"), chunk(2, "delta", "MARKER"));
if (scenario !== "missing-end" && scenario !== "cancelled") runtimeEvents.push(chunk(2,
`end:${scenario === "filtered" || scenario === "paused" ? scenario : scenario === "max-tokens" ? "max_tokens" : "end_turn"}`));
}
const fixture = driverFixture({ agent: "kimi", model: "kimi-for-coding", providerPolicy: { readOnly: true } }, { runtimeEvents });
const session = await fixture.driver.openSession({ runId: "run-kimi-boundaries", normalizedSessionId: "session-1", workingDirectory: "/workspace" });
const { turnId } = await session.startTurn({ message: { text: "Answer exactly" } });
fixture.finishTurn({ status: scenario === "cancelled" ? "cancelled" : "completed" });
const events = await collectUntil(session.events(), scenario === "missing-end" ? "turn.failed" : scenario === "cancelled" ? "turn.interrupted" : "turn.completed");
const progress = events.find(event => event.eventType === "item.delta" && event.payload.text === "Calling finish.")!;
expect(progress).toBeDefined();
expect(progress.itemId).toBe(`${turnId}:assistant-message:${id(1)}`);
const commentary = events.filter(event => event.eventType === "item.completed" && event.payload.kind === "agentMessage" && event.payload.channel === "commentary");
expect(commentary.filter(event => event.payload.text === "Calling finish.")).toHaveLength(1);
expect(commentary[0]!.itemId).toBe(progress.itemId);
const final = events.filter(event => event.eventType === "item.completed" && event.payload.kind === "agentMessage" && event.payload.channel === "final");
expect(final.map(event => event.payload.text)).toEqual(["exact-final", "max-tokens"].includes(scenario) ? ["EXACT_MARKER"] : []);
if (final.length) expect(final[0]!.itemId).toBe(`${turnId}:assistant-message:${id(2)}`);
expect(events.filter(event => event.payload.kind === "agentMessage").some(event => event.payload.text === "private thought")).toBe(false);
expect(events.filter(event => event.eventType === "item.delta" && event.payload.text === "").length).toBeGreaterThanOrEqual(2);
await session.close({ reason: "Kimi native final attribution verified" });
});
it("delivers negotiated steering and follow-up distinctly, once, for the active turn", async () => {
const fixture = driverFixture({ agent: "pi", model: "openrouter/deepseek/deepseek-v4-flash-0731", providerPolicy: { readOnly: true } }, { runtimeEvents: [] });
fixture.host.steeringCapability.mockReturnValue({ steering: true, queuedFollowUp: true });
@@ -5,6 +5,7 @@ import { acpxProfileActivity, type AcpxActivityAdapter, type AcpxToolEvidence }
import { requireAcpxResponseDelivery } from "./response-delivery.js";
import { createPiMessageProjection, piBoundaryClearsFinal, type PiProjectedMessageEvent } from "./pi-message-projection.js";
import { createKimiMessageProjection, kimiMessageBoundaryClears, type KimiProjectedMessageEvent } from "./kimi-message-boundary.js";
import { acpxProfileClientCapabilities, bindAcpxExtensionTurn, validateAcpxRichEvent, createAcpxProfileExtensionAdapter, type AcpxExtensionInput } from "./profile-extensions.js";
import { createHash, randomBytes } from "node:crypto";
@@ -290,7 +291,7 @@ export class CodexAcpxDriver implements HarnessDriver {
dependencies: CodexAcpxDriverDependencies = {},
) {
assertAcpxProfileReleased(options.agent ?? "codex");
if (["pi", "cursor", "copilot"].includes(options.agent ?? "codex") && typeof options.providerPolicy?.readOnly !== "boolean") {
if (["pi", "cursor", "copilot", "kimi"].includes(options.agent ?? "codex") && typeof options.providerPolicy?.readOnly !== "boolean") {
throw new Error("ACP candidate requires an explicit provider read-only policy");
}
this.#options = {
@@ -330,7 +331,7 @@ export class CodexAcpxDriver implements HarnessDriver {
},
capabilities: {
...descriptor.capabilities,
resume: true,
resume: descriptor.capabilities.resume,
runtimeRequestResolution: true,
runtimeRequestHandoff: true,
unsupported: descriptor.capabilities.unsupported,
@@ -1481,7 +1482,8 @@ class CodexAcpxSession implements HarnessSession {
const normalizeToolEvent =
createAcpxToolEventNormalizer<AcpRuntimeEvent>();
const piMessages = this.#agent === "pi" ? createPiMessageProjection<AcpRuntimeEvent>() : null;
const normalizeMessage = piMessages ? piMessages.normalize : this.#agent === "grok"
const kimiMessages = this.#agent === "kimi" ? createKimiMessageProjection<AcpRuntimeEvent>() : null;
const normalizeMessage = piMessages ? piMessages.normalize : kimiMessages ? kimiMessages.normalize : this.#agent === "grok"
? createGrokMessageNormalizer<AcpRuntimeEvent>() : (event: AcpRuntimeEvent) => event;
for await (const event of turn.events) {
toolEvidence?.tool(event);
@@ -1490,7 +1492,7 @@ class CodexAcpxSession implements HarnessSession {
this.#mapRuntimeEvent(normalizeMessage(normalizeToolEvent(projected)), turnId, ++index);
}
const result = await turn.result;
if (result.status === "completed") piMessages?.settle();
if (result.status === "completed") { piMessages?.settle(); kimiMessages?.settle(); }
await drainExtensions();
const usageAfter = await readUsageStatus(this.#host);
// Diagnostic projection failures cannot replace the provider's terminal result.
@@ -1676,12 +1678,12 @@ class CodexAcpxSession implements HarnessSession {
}
#assistantItemId(turnId: string, messageId: string | null): string {
if (this.#agent !== "copilot") return `${turnId}:assistant-message`;
if (this.#agent !== "copilot" && this.#agent !== "kimi") return `${turnId}:assistant-message`;
return messageId ? `${turnId}:assistant-message:${messageId}` : `${turnId}:assistant-activity`;
}
#mapRuntimeEvent(
event: PiProjectedMessageEvent<AcpRuntimeEvent>,
event: PiProjectedMessageEvent<KimiProjectedMessageEvent<AcpRuntimeEvent>>,
turnId: string,
index: number,
): void {
@@ -1691,10 +1693,15 @@ class CodexAcpxSession implements HarnessSession {
const isReasoning =
event.stream === "thought" || event.tag === "agent_thought_chunk";
const messageId = typeof event.messageId === "string" && event.messageId ? event.messageId : null;
let kimiCommentary: { text: string; itemId: string } | undefined;
// The pinned Copilot mapper supplies actual native identity, including
// empty starts. Unidentified session info/warnings remain activity only.
if (!isReasoning && !event.piMessageHistory && (this.#agent !== "copilot" || messageId)) {
if (piBoundaryClearsFinal(event)) this.#assistantText = "";
if (!isReasoning && !event.piMessageHistory && !event.assistantMessageHistory && (this.#agent !== "copilot" || messageId)) {
const kimiClears = this.#agent === "kimi" && kimiMessageBoundaryClears(event);
if (kimiClears && this.#assistantText) {
kimiCommentary = { text: this.#assistantText, itemId: this.#assistantItemId(turnId, this.#assistantMessageId) };
}
if (piBoundaryClearsFinal(event) || kimiClears) this.#assistantText = "";
if (messageId && this.#assistantMessageId && messageId !== this.#assistantMessageId) {
if (this.#agent === "copilot" && this.#assistantText) {
this.#emit("item.completed", { kind: "agentMessage", channel: "commentary", text: this.#assistantText },
@@ -1722,6 +1729,8 @@ class CodexAcpxSession implements HarnessSession {
: this.#assistantItemId(turnId, messageId),
},
);
if (kimiCommentary) this.#emit("item.completed", { kind: "agentMessage", channel: "commentary", text: kimiCommentary.text },
{ turnId, itemId: kimiCommentary.itemId });
}
if (event.type === "status" && event.tag === "usage_update") {
this.#usage = boundedRecord({
@@ -1,3 +1,6 @@
import { admitAcpxSessionContext } from "./session-context-admission.js";
import { createKimiInstructionAdmission } from "./kimi-instructions.js";
import { kimiReadOnlyPermissionAllowed } from "./kimi-config.js";
import { resolveGrokDisableWebSearch } from "./grok-web-search.js";
import { resolveGrokEffort, createGrokEffortAdmission } from "./grok-effort.js";
import { resolveClaudeEffort, createClaudeEffortAdmission } from "./claude-effort.js";
@@ -37,7 +40,6 @@ import { AcpxApprovalRequiredError, decideAcpxPermission } from "./permission-po
import { ACPX_CAPABILITY_PROFILES } from "./capability-profiles.js";
import { createCursorInstructionAdmission } from "./cursor-instructions.js";
import { createAntigravityAdmission } from "./antigravity-admission.js";
import { admitAcpxSessionContext } from "./session-context-admission.js";
import { createAcpxModeBinding } from "./provider-mode.js";
import { assertCopilotPromptPolicy, createCopilotProtocolGuard } from "./copilot-policy.js";
@@ -326,17 +328,19 @@ export async function openQualifiedAcpxRuntime(
const grokDisableWebSearch = resolveGrokDisableWebSearch(options.profile.agent, options.grokDisableWebSearch);
const effortAdmission = selectedClaudeEffort ? createClaudeEffortAdmission(selectedClaudeEffort)
: selectedGrokEffort ? createGrokEffortAdmission(selectedGrokEffort, options.profile.reportedModelId) : undefined;
const cursorInstructions = options.profile.agent === "cursor"
const instructionAdmission = options.profile.agent === "kimi"
? createKimiInstructionAdmission(options.systemInstructions)
: options.profile.agent === "cursor"
? createCursorInstructionAdmission(options.systemInstructions)
: null;
const antigravityAdmission = options.profile.agent === "antigravity"
? createAntigravityAdmission(options.systemInstructions, options.profile.reportedModelId)
: null;
const contextAdmission = cursorInstructions ?? antigravityAdmission;
const contextAdmission = instructionAdmission ?? antigravityAdmission;
const runtimeOptions: GoalAwareAcpRuntimeOptions = {
cwd: options.cwd,
...(cursorInstructions || modeBinding ? { protocolGuardFactory: () => {
const instructions = cursorInstructions?.createGuard();
...(instructionAdmission || modeBinding ? { protocolGuardFactory: () => {
const instructions = instructionAdmission?.createGuard();
const mode = modeBinding?.createGuard();
return (direction: "inbound" | "outbound", message: unknown) => { instructions?.(direction, message); mode?.(direction, message); };
} } : {}),
@@ -412,6 +416,8 @@ export async function openQualifiedAcpxRuntime(
}
if ((permissionBoundary.hasAdmittedTurn && !extensionBoundary.active)
|| extensionBoundary.active?.signal.aborted || context.signal.aborted) return { outcome: "cancel" };
if (options.profile.agent === "kimi" && options.readOnly === true
&& !kimiReadOnlyPermissionAllowed(request, runnerOwnedMcpServerNames)) return { outcome: "reject_once" };
const disposition = decideAcpxPermission(
options.profile.agent,
options.permissionMode,
@@ -532,7 +538,7 @@ export async function openQualifiedAcpxRuntime(
// Its supported exact-model control forces session/load and the
// current instruction acknowledgement before host admission.
if (!runtime.setConfigOption) {
throw new Error("ACP context admission requires exact model configuration");
throw new Error("Cold instruction admission requires exact model configuration");
}
await runtime.setConfigOption({
handle: ensuredHandle, key: "model", value: options.profile.reportedModelId,
@@ -1,52 +1,2 @@
import { redactPaperclipSemanticValue } from "../../semantic-tools/redaction.js";
import { safeAcpxLocations } from "./safe-locations.js";
import { lstatSync, realpathSync } from "node:fs";
import { basename, dirname, isAbsolute, join } from "node:path";
export const COPILOT_PERMISSION_CONTEXT_CONTRACT = "copilot-edit-permission-context-v1";
const record = (value: unknown): Record<string, unknown> =>
value !== null && typeof value === "object" && !Array.isArray(value) ? value as Record<string, unknown> : {};
/** Native providers can spell an absolute workspace path through a host alias
* (macOS /tmp and /private/tmp). Attest the real entry, or its existing parent
* for a new file, before converting it to a display target. */
function aliasedLocation(path: string, cwd: string): string | undefined {
if (!isAbsolute(path)) return;
try {
const canonicalCwd = realpathSync(cwd);
let canonicalPath: string;
try {
lstatSync(path);
canonicalPath = realpathSync(path);
} catch (error) {
if ((error as NodeJS.ErrnoException).code !== "ENOENT") return;
// A dangling symlink must not become an apparently safe create target.
try { lstatSync(path); return; } catch (missing) {
if ((missing as NodeJS.ErrnoException).code !== "ENOENT") return;
}
canonicalPath = join(realpathSync(dirname(path)), basename(path));
}
return safeAcpxLocations([{ path: canonicalPath }], canonicalCwd, "edit")[0]?.path as string | undefined;
} catch { return; }
}
/** Display context only; this does not authorize filesystem access. */
export function safeCopilotEditTarget(value: unknown, workingDirectory: string | undefined): string | undefined {
const call = record(value);
if (call.kind !== "edit" || !workingDirectory) return;
const input = record(call.rawInput);
if (call.locations !== undefined && !Array.isArray(call.locations)) return;
if (Array.isArray(call.locations) && (call.locations.length > 16 || call.locations.some(x => typeof record(x).path !== "string"))) return;
const paths = [input.path, input.fileName, ...(Array.isArray(call.locations) ? call.locations.map(x => record(x).path) : [])].filter(x => x !== undefined);
if (!paths.length || paths.some(x => typeof x !== "string" || !x || x.trim() !== x || x.length > 2048 || /[\\\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/u.test(x))) return;
const safe = paths.flatMap(path => {
const locations = safeAcpxLocations([{ path }], workingDirectory, call.kind, call.title);
if (locations.length) return locations;
const aliased = aliasedLocation(path as string, workingDirectory);
return aliased ? [{ path: aliased }] : [];
});
const names = safe.map(x => x.path).filter((x): x is string => typeof x === "string" && x.length <= 1024 && x.trim() === x && !x.includes(":"));
if (names.length !== paths.length || new Set(names).size !== 1) return;
const target = names[0];
return target && redactPaperclipSemanticValue(target) === target ? target : undefined;
}
export { safeAcpxEditTarget as safeCopilotEditTarget } from "./acp-edit-context.js";
@@ -16,7 +16,7 @@ import {
import { ACPX_CAPABILITY_PROFILES } from "./capability-profiles.js";
const ACPX_AGENTS = ["claude", "codex", "grok", "pi", "cursor", "copilot", "antigravity"] as const;
const ACPX_AGENTS = ["claude", "codex", "grok", "pi", "cursor", "copilot", "kimi", "antigravity"] as const;
const ACPX_PERMISSION_MODES = [
"approve-all",
"approve-paperclip",
@@ -113,7 +113,7 @@ export function validateAcpxDriverConfig(
return invalid(
"agent",
"invalid_agent",
"ACPX agent must be claude, codex, grok, cursor, copilot, pi, or antigravity.",
"ACPX agent must be claude, codex, grok, cursor, copilot, kimi, pi, or antigravity.",
);
}
if (ACPX_CAPABILITY_PROFILES[agent].qualification !== "qualified") {
@@ -44,9 +44,9 @@ describe("ACPX launch environment", () => {
expect(launch.ACPX_CLAUDE_INCLUDE_USER_SETTINGS).toBeUndefined();
expect(environment.CLAUDE_CONFIG_DIR).toBe(configured);
});
it("retains Runner notification discovery while denying task-supplied overrides", () => {
it.each(["claude", "kimi"] as const)("retains %s Runner notification discovery while denying task-supplied overrides", agent => {
for (const key of ["PAPERCLIP_RUNTIME_NOTIFICATION_CONTEXT", "PAPERCLIP_RUNTIME_NOTIFICATION_HELPER"]) {
expect(createSanitizedAcpxSpawnInput({ [key]: "/private/runner/context" }, "claude").env[key]).toBe("/private/runner/context");
expect(createSanitizedAcpxSpawnInput({ [key]: "/private/runner/context" }, agent).env[key]).toBe("/private/runner/context");
expect(configuredEnvironmentProjection({ [key]: "/caller/override" })).not.toHaveProperty(key);
}
});
@@ -137,7 +137,9 @@ describe("ACPX launch environment", () => {
it.each([
["pi", "OPENROUTER_API_KEY"], ["cursor", "CURSOR_API_KEY"],
["cursor", "CURSOR_AUTH_TOKEN"], ["copilot", "COPILOT_GITHUB_TOKEN"], ["antigravity", "GEMINI_API_KEY"],
["cursor", "CURSOR_AUTH_TOKEN"], ["copilot", "COPILOT_GITHUB_TOKEN"],
["kimi", "KIMI_API_KEY"],
["antigravity", "GEMINI_API_KEY"],
] as const)("requires an explicit %s credential binding for %s", (agent, name) => {
vi.stubEnv(name, "ambient-secret");
expect(createSanitizedAcpxSpawnInput(undefined, agent).env[name]).toBeUndefined();
@@ -157,9 +159,33 @@ describe("ACPX launch environment", () => {
expect(createSanitizedAcpxSpawnInput(source, "pi").env).toEqual({ COPILOT_GITHUB_TOKEN: "copilot-key" });
});
it("strips configured Kimi model redirects and home overrides while retaining selected task and MCP values", () => {
const overrides = {
KIMI_MODEL_NAME: "__kimi_env_model__", KIMI_MODEL_API_KEY: "unselected-model-key",
KIMI_MODEL_BASE_URL: "https://unselected.invalid/v1", KIMI_MODEL_PROVIDER_TYPE: "openai_legacy",
KIMI_MODEL_FUTURE_OVERRIDE: "cannot-bypass-the-prefix-check", KIMI_SECONDARY_MODEL: "other-model",
KIMI_CODE_HOME: "/unselected/home",
};
const source = { ...configuredEnvironmentProjection({ ...overrides, CUSTOM_SETTING: "allowed" }),
KIMI_API_KEY: "selected-code-key", PAPERCLIP_NATIVE_MCP_NAME: "assigned",
PAPERCLIP_NATIVE_MCP_URL: "https://assigned.example/mcp", PAPERCLIP_NATIVE_MCP_TOKEN: "controller-only" };
const binding = createAcpxCredentialBinding(source, "kimi", "session-1")!;
const sidecar = createAcpxSidecarHostEnvironment({ ...source, [ACPX_CREDENTIAL_BINDING_ENV]: binding }, "kimi", "session-1");
for (const environment of [sidecar, createSanitizedAcpxSpawnInput(source, "kimi").env,
createSanitizedAcpxSpawnInput(sidecar, "kimi").env]) {
for (const name of Object.keys(overrides)) expect(environment).not.toHaveProperty(name);
expect(environment).toMatchObject({ KIMI_API_KEY: "selected-code-key", CUSTOM_SETTING: "allowed",
PAPERCLIP_NATIVE_MCP_NAME: "assigned", PAPERCLIP_NATIVE_MCP_URL: "https://assigned.example/mcp" });
expect(JSON.parse(environment[CONFIGURED_ENVIRONMENT_KEYS]!)).toEqual(["CUSTOM_SETTING"]);
}
expect(createSanitizedAcpxSpawnInput(source, "kimi").env).not.toHaveProperty("PAPERCLIP_NATIVE_MCP_TOKEN");
});
it.each([
["pi", "OPENROUTER_API_KEY"], ["cursor", "CURSOR_API_KEY"],
["cursor", "CURSOR_AUTH_TOKEN"], ["copilot", "COPILOT_GITHUB_TOKEN"], ["antigravity", "GEMINI_API_KEY"],
["cursor", "CURSOR_AUTH_TOKEN"], ["copilot", "COPILOT_GITHUB_TOKEN"],
["kimi", "KIMI_API_KEY"],
["antigravity", "GEMINI_API_KEY"],
] as const)("admits only session-bound %s sidecar credentials for %s", (agent, name) => {
const source = { [name]: "task-secret" };
const binding = createAcpxCredentialBinding(source, agent, "session-1");
@@ -10,6 +10,7 @@ export const ACPX_CREDENTIAL_BINDING_ENV = "PAPERCLIP_ACPX_CREDENTIAL_BINDING";
export const ACPX_CREDENTIAL_NAMES: Readonly<Record<QualifiedAcpxAgent, readonly string[]>> = {
antigravity: ["GEMINI_API_KEY", "PAPERCLIP_ACPX_ANTIGRAVITY_AUTH_JSON_SECRET"],
grok: ["XAI_API_KEY"],
kimi: ["KIMI_API_KEY"],
pi: PI_CREDENTIAL_NAMES,
cursor: ["CURSOR_API_KEY", "CURSOR_AUTH_TOKEN"],
copilot: ["COPILOT_GITHUB_TOKEN"],
@@ -27,7 +28,17 @@ function removePiIamCredentials(environment: NodeJS.ProcessEnv): void {
}
}
const isCandidate = (agent: QualifiedAcpxAgent) => agent === "pi" || agent === "cursor" || agent === "copilot" || agent === "antigravity";
function removeKimiRuntimeOverrides(environment: NodeJS.ProcessEnv): void {
const isOverride = (name: string) => /^KIMI_MODEL_/.test(name.toUpperCase())
|| ["KIMI_SECONDARY_MODEL", "KIMI_CODE_HOME"].includes(name.toUpperCase());
const names = configuredEnvironmentKeys(environment);
for (const name of Object.keys(environment)) if (isOverride(name)) delete environment[name];
if (environment[CONFIGURED_ENVIRONMENT_KEYS] !== undefined) {
environment[CONFIGURED_ENVIRONMENT_KEYS] = JSON.stringify(names.filter(name => !isOverride(name)));
}
}
const isCandidate = (agent: QualifiedAcpxAgent) => agent === "pi" || agent === "cursor" || agent === "copilot" || agent === "kimi" || agent === "antigravity";
/** Mint only at the controller's explicit task-environment boundary, never by copying a marker. */
export function createAcpxCredentialBinding(
@@ -79,6 +90,7 @@ export function createAcpxSidecarHostEnvironment(
}
}
if (agent === "pi") removePiIamCredentials(result);
if (agent === "kimi") removeKimiRuntimeOverrides(result);
if (agent === "antigravity") sanitizeAntigravityEnvironment(result);
return result;
}
@@ -164,6 +176,7 @@ export function createSanitizedAcpxSpawnInput(
result[key] = value;
}
if (agent === "pi") removePiIamCredentials(result);
if (agent === "kimi") removeKimiRuntimeOverrides(result);
if (agent === "antigravity") sanitizeAntigravityEnvironment(result);
// The controller-to-sidecar document is staged under a lifetime fence. The
// native child receives the private token file, never its launch document.
@@ -95,6 +95,20 @@ export const QUALIFIED_ACPX_PROFILE_DATA = {
"agentRuntimeVersion": "0.160.0",
"commandDigest": "sha256:443491f4e814501a5dc47347e4510e84faeec9c9382e2d4e53bfe69386d5aabc",
"permissionPolicy": "interactive"
},
"kimi": {
"driverKind": "acpx_runtime",
"protocolVersion": 1,
"acpxVersion": "0.13.1",
"agent": "kimi",
"agentProfileVersion": 16,
"agentServerPackage": "@moonshot-ai/kimi-code",
"agentServerVersion": "2.3.3",
"agentRuntimePackage": null,
"agentRuntimeVersion": null,
"commandDigest": "sha256:0c1e6ce460407ec973a37a2d192d665fcde744e2b9875c791c90308afbf4c52b",
"qualificationStatus": "pending",
"permissionPolicy": "interactive"
}
} as const;
@@ -0,0 +1,12 @@
export const KIMI_RUNTIME_VERSION = "2.3.3" as const;
export const KIMI_NODE_VERSION = "24.21.0" as const;
export const KIMI_DISTRIBUTION_LOCK_SHA256 = "87f854ddd7f92254ccd8596b85962684ec176f92e93863771843bf416825f16b";
export const KIMI_NODE_DISTRIBUTIONS = Object.freeze({
"darwin-arm64": Object.freeze({ archiveSha256: "bed7eea5325e1108f32ce5228ddd6a5f0f08a499ee42aa7442aea583702f6057", executableSha256: "e4b5a3af0e05c75de2eae013904145f40fe7fc2a6e6f17510128bf45cca4e79b", executableSize: 122129232 }),
"linux-x64": Object.freeze({ archiveSha256: "6e1db87ef58b8819e5d5402eff1536491b18edd8eb7bee5ef7897876e88dc5ff", executableSha256: "7fde7b8afa198da66257f42ee2001d874c7355631e6d1579a5fb5ef1f246df4c", executableSize: 126595440 }),
});
export const KIMI_DISTRIBUTION_CLOSURE_SHA256 = Object.freeze({
"darwin-arm64": "6038325abd0431c30097ff1f572a9b29816e1b4da372d8cb86b2ca5d18ea34e7",
"linux-x64": "105d8394adbbc76a953a12cc51b5288eb940ad693291e584f6cdc6407213164d",
});
@@ -0,0 +1,44 @@
export function kimiManagedConfiguration(model: string): string {
if (!model.trim() || model.includes("\0") || Buffer.byteLength(model) > 512) throw new Error("Kimi Code requires a bounded explicit model ID");
const quote = JSON.stringify;
return [
`default_model = ${quote(model)}`,
"telemetry = false",
"builtin_product_skills = false",
"merge_all_available_skills = false",
"hooks = []",
"[providers.paperclip]",
'type = "kimi"',
'base_url = "https://api.kimi.ai/coding/v1"',
'api_key_env = "KIMI_API_KEY"',
`[models.${quote(model)}]`,
'provider = "paperclip"',
`model = ${quote(model)}`,
"max_context_size = 262144",
'capabilities = ["tool_use"]',
"[tools]",
'disabled = ["Agent", "AgentSwarm", "TaskList", "TaskOutput", "TaskStop", "CronCreate", "CronList", "CronDelete", "CreateGoal", "GetGoal", "SetGoalBudget", "UpdateGoal", "AskUserQuestion", "EnterPlanMode", "ExitPlanMode"]',
"[background]",
"keep_alive_on_exit = false",
"bash_auto_background_on_timeout = false",
"[watch]",
"enabled = false",
"",
].join("\n");
}
export function kimiReadOnlyPermissionAllowed(request: unknown, runnerOwnedMcpServerNames: ReadonlySet<string>): boolean {
if (!request || typeof request !== "object") return false;
const raw = (request as { raw?: unknown }).raw;
if (!raw || typeof raw !== "object") return false;
const call = (raw as { toolCall?: unknown }).toolCall;
if (!call || typeof call !== "object") return false;
const title = (call as { title?: unknown }).title;
const input = (call as { rawInput?: unknown }).rawInput;
if (typeof title !== "string" || !input || typeof input !== "object" || Array.isArray(input)) return false;
for (const name of runnerOwnedMcpServerNames) {
const prefix = `mcp__${name}__`;
if (title.startsWith(prefix) && title.length > prefix.length) return true;
}
return false;
}
@@ -0,0 +1,110 @@
import { createHash } from "node:crypto";
import { readFileSync } from "node:fs";
import { mkdir, mkdtemp, realpath, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import { assertKimiInstallationProfile, verifyKimiInstallation } from "./kimi-installation.js";
import { QUALIFIED_ACPX_PROFILES } from "./qualified-profiles.js";
import { isSupportedAcpxProfileVersion } from "./profile-compatibility.js";
const roots: string[] = [];
const previous = new Map<string, string | undefined>();
function environment(key: string, value: string) {
if (!previous.has(key)) previous.set(key, process.env[key]);
process.env[key] = value;
}
afterEach(async () => {
for (const [key, value] of previous) { if (value === undefined) delete process.env[key]; else process.env[key] = value; }
previous.clear();
await Promise.all(roots.splice(0).map(root => rm(root, { recursive: true, force: true })));
});
describe("Kimi installed runtime admission", () => {
it("rejects caller-selected package/version/command changes before filesystem resolution", () => {
const profile = QUALIFIED_ACPX_PROFILES.kimi;
expect(() => assertKimiInstallationProfile(profile)).not.toThrow();
for (const alteration of [{ agentServerVersion: "latest" }, { agentServerPackage: "foreign" }, { commandDigest: `sha256:${"f".repeat(64)}` }, { agentProfileVersion: profile.agentProfileVersion + 1 }]) {
expect(() => assertKimiInstallationProfile({ ...profile, ...alteration })).toThrow(/trusted declaration/);
}
});
it("retains pending profile 10 while binding the merged entrypoint builder in profile 11", () => {
const bytes = readFileSync(new URL("../../../test/fixtures/kimi-profile-v10-identity.json", import.meta.url));
expect(createHash("sha256").update(bytes).digest("hex")).toBe("b859f4aefcc36fc5e75b3aeeb02135ca9f7acc84866c856a3939effdd13cb358");
const prior = JSON.parse(bytes.toString("utf8"));
const current = JSON.parse(readFileSync(new URL("../../../test/fixtures/kimi-profile-v11-identity.json", import.meta.url), "utf8"));
expect(Object.keys(current.declaration.sources).filter(key => current.declaration.sources[key] !== prior.declaration.sources[key])).toEqual([
"scripts/build-verified-provider-entrypoints.mjs",
]);
expect(() => assertKimiInstallationProfile({ ...QUALIFIED_ACPX_PROFILES.kimi,
agentProfileVersion: 10, commandDigest: prior.commandDigest })).toThrow(/trusted declaration/);
});
it("preserves historical profile 11 while binding the reconciled authority and event boundaries in 13", () => {
const bytes = readFileSync(new URL("../../../test/fixtures/kimi-profile-v11-identity.json", import.meta.url));
expect(createHash("sha256").update(bytes).digest("hex")).toBe("17b3db5659cfbaa4d3f5dddd8a97ffeab38353795aa4dbfa6c6fe1520f415ab1");
const prior = JSON.parse(bytes.toString("utf8"));
const current = JSON.parse(readFileSync(new URL("../../../test/fixtures/kimi-profile-v13-identity.json", import.meta.url), "utf8"));
expect(prior.declaration.agentProfileVersion).toBe(11);
expect(Object.keys(prior.declaration.sources)).toHaveLength(31);
expect(current.declaration.agentProfileVersion).toBe(13);
expect(Object.keys(current.declaration.sources)).toHaveLength(55);
expect(Object.hasOwn(current.declaration.sources, "src/drivers/acpx/candidate-admission.ts")).toBe(true);
expect(Object.hasOwn(current.declaration.sources, "runner/crates/runner-core/src/provider_events.rs")).toBe(true);
expect(isSupportedAcpxProfileVersion("kimi", 11)).toBe(true);
expect(() => assertKimiInstallationProfile({ ...QUALIFIED_ACPX_PROFILES.kimi,
agentProfileVersion: 11, commandDigest: prior.commandDigest })).toThrow(/trusted declaration/);
});
it("decodes pending14 history without installing it as the repaired pending15 runtime", () => {
const bytes = readFileSync(new URL("../../../test/fixtures/kimi-profile-v14-identity.json", import.meta.url));
expect(createHash("sha256").update(bytes).digest("hex")).toBe("13ce8e301e6b7d622f4b3ffdca7981e18538e7a5ca2f1b2208ec466259469e7b");
const prior = JSON.parse(bytes.toString("utf8"));
const current = JSON.parse(readFileSync(new URL("../../../test/fixtures/kimi-profile-v15-identity.json", import.meta.url), "utf8"));
expect(current.declaration.agentProfileVersion).toBe(15);
expect(Object.keys(current.declaration.sources)).toHaveLength(55);
expect(Object.keys(current.declaration.sources).filter(key => current.declaration.sources[key] !== prior.declaration.sources[key])).toEqual([
"runner/crates/runner-core/src/acpx_provider_backend.rs",
]);
expect(isSupportedAcpxProfileVersion("kimi", 14)).toBe(true);
expect(() => assertKimiInstallationProfile({ ...QUALIFIED_ACPX_PROFILES.kimi,
agentProfileVersion: 14, commandDigest: prior.commandDigest })).toThrow(/trusted declaration/);
expect(() => assertKimiInstallationProfile(QUALIFIED_ACPX_PROFILES.kimi)).not.toThrow();
});
it("decodes pending15 history without installing it as merged pending16", () => {
const bytes = readFileSync(new URL("../../../test/fixtures/kimi-profile-v15-identity.json", import.meta.url));
expect(createHash("sha256").update(bytes).digest("hex")).toBe("5221f6f9f64c02ca7ee68b185e08ed46b1c82a13037b001854065b9fad28ff87");
const prior = JSON.parse(bytes.toString("utf8"));
const current = JSON.parse(readFileSync(new URL("../../../test/fixtures/kimi-profile-v16-identity.json", import.meta.url), "utf8"));
expect(current.declaration.agentProfileVersion).toBe(16);
expect(current.declaration.qualificationStatus).toBe("pending");
expect(Object.keys(current.declaration.sources)).toHaveLength(58);
expect(isSupportedAcpxProfileVersion("kimi", 15)).toBe(true);
expect(() => assertKimiInstallationProfile({ ...QUALIFIED_ACPX_PROFILES.kimi,
agentProfileVersion: 15, commandDigest: prior.commandDigest })).toThrow(/trusted declaration/);
expect(() => assertKimiInstallationProfile(QUALIFIED_ACPX_PROFILES.kimi)).not.toThrow();
});
it("decodes the old pending revision while refusing its source-bound launch digest", () => {
const historical = JSON.parse(readFileSync(new URL("../../../test/fixtures/kimi-profile-v16-identity.json", import.meta.url), "utf8"));
expect(isSupportedAcpxProfileVersion("kimi", historical.declaration.agentProfileVersion)).toBe(true);
expect(QUALIFIED_ACPX_PROFILES.kimi.agentProfileVersion).toBe(historical.declaration.agentProfileVersion);
expect(QUALIFIED_ACPX_PROFILES.kimi.commandDigest).not.toBe(historical.commandDigest);
expect(() => assertKimiInstallationProfile({ ...QUALIFIED_ACPX_PROFILES.kimi,
commandDigest: historical.commandDigest })).toThrow(/trusted declaration/);
});
it("gives the normal setup command and never falls back to ambient kimi when assets are missing", async () => {
const root = await realpath(await mkdtemp(join(tmpdir(), "paperclip-kimi-installation-test-"))); roots.push(root);
await writeFile(join(root, "package.json"), '{"name":"@paperclipai/paperclip-runner"}');
environment("PAPERCLIP_ACPX_PROVIDER_PACKAGE_ROOT", root);
environment("PAPERCLIP_ACPX_PROVIDER_PACKAGE_MANIFEST", join(root, "package.json"));
await expect(verifyKimiInstallation(QUALIFIED_ACPX_PROFILES.kimi)).rejects.toThrow(/paperclipai runtime setup kimi/);
const assets = join(root, "provider-assets/kimi", `${process.platform}-${process.arch}`);
await mkdir(join(assets, "runtime"), { recursive: true });
await writeFile(join(assets, "kimi-distribution.json"), JSON.stringify({ schema: "paperclip.kimi-distribution.v1", nativeClosureSha256: "f".repeat(64) }));
await expect(verifyKimiInstallation(QUALIFIED_ACPX_PROFILES.kimi)).rejects.toThrow(/source-owned pin/);
});
});
@@ -0,0 +1,71 @@
import { constants } from "node:fs";
import { lstat, open, realpath } from "node:fs/promises";
import { join } from "node:path";
import { verifyNativeAcpxInstallation, type VerifiedAcpxInstallation } from "./installation-integrity.js";
import { KIMI_DISTRIBUTION_CLOSURE_SHA256, KIMI_DISTRIBUTION_LOCK_SHA256, KIMI_NODE_VERSION, KIMI_RUNTIME_VERSION } from "./kimi-closure-pins.js";
import { resolveRunnerProviderAssetsRoot } from "./provider-assets-root.js";
import { QUALIFIED_ACPX_PROFILES, type AcpxReleaseProfile } from "./qualified-profiles.js";
export function assertKimiInstallationProfile(profile: AcpxReleaseProfile): void {
const trusted = QUALIFIED_ACPX_PROFILES.kimi;
for (const key of ["agent", "driverKind", "protocolVersion", "acpxVersion", "agentProfileVersion", "agentServerPackage", "agentServerVersion", "agentRuntimePackage", "agentRuntimeVersion", "commandDigest", "permissionPolicy"] as const) {
if (profile[key] !== trusted[key]) throw new Error("Kimi distribution profile differs from its trusted declaration");
}
if (profile.agentServerPackage !== "@moonshot-ai/kimi-code" || profile.agentServerVersion !== KIMI_RUNTIME_VERSION || profile.permissionPolicy !== "interactive") throw new Error("Kimi distribution profile has an unsupported runtime");
}
async function readMetadata(path: string): Promise<Record<string, unknown>> {
const file = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
try {
const before = await file.stat({ bigint: true });
if (!before.isFile() || before.nlink !== 1n || before.size < 1n || before.size > 64n * 1024n) throw new Error("Kimi distribution metadata is not a bounded regular file");
const bytes = await file.readFile();
const after = await file.stat({ bigint: true });
const named = await lstat(path, { bigint: true });
if (bytes.length !== Number(before.size) || before.dev !== after.dev || before.ino !== after.ino || before.size !== after.size || before.mtimeNs !== after.mtimeNs || before.ctimeNs !== after.ctimeNs || named.dev !== before.dev || named.ino !== before.ino || named.isSymbolicLink()) throw new Error("Kimi distribution metadata changed while read");
const value: unknown = JSON.parse(bytes.toString("utf8"));
if (value === null || typeof value !== "object" || Array.isArray(value)) throw new Error("Kimi distribution metadata is invalid");
return value as Record<string, unknown>;
} finally { await file.close(); }
}
export async function verifyKimiInstallation(profile: AcpxReleaseProfile): Promise<VerifiedAcpxInstallation> {
assertKimiInstallationProfile(profile);
const target = `${process.platform}-${process.arch}`;
if (!Object.hasOwn(KIMI_DISTRIBUTION_CLOSURE_SHA256, target)) throw new Error(`Kimi runtime target is unsupported: ${target}`);
const expectedClosureSha256 = KIMI_DISTRIBUTION_CLOSURE_SHA256[target as keyof typeof KIMI_DISTRIBUTION_CLOSURE_SHA256];
const assets = join(resolveRunnerProviderAssetsRoot(import.meta.url, "kimi"), target);
const distributionRoot = join(assets, "runtime");
const assertDirectories = async (): Promise<void> => {
for (const path of [assets, distributionRoot]) {
const stat = await lstat(path);
if (!stat.isDirectory() || stat.isSymbolicLink() || await realpath(path) !== path) throw new Error("Kimi runtime escaped its fixed asset directory");
}
};
try { await assertDirectories(); }
catch (error) {
if ((error as NodeJS.ErrnoException).code === "ENOENT") throw new Error("Kimi runtime is not installed on this host; run paperclipai runtime setup kimi before selecting Kimi Code");
throw error;
}
const metadata = await readMetadata(join(assets, "kimi-distribution.json"));
const entrypoint = "node_modules/@moonshot-ai/kimi-code/dist/main.mjs";
if (metadata.schema !== "paperclip.kimi-distribution.v1" || metadata.version !== KIMI_RUNTIME_VERSION || metadata.target !== target || metadata.nodeVersion !== KIMI_NODE_VERSION || metadata.runtimeRoot !== "runtime" || metadata.entrypoint !== entrypoint || metadata.lockSha256 !== KIMI_DISTRIBUTION_LOCK_SHA256 || metadata.nativeClosureSha256 !== expectedClosureSha256) throw new Error("Kimi distribution metadata differs from its source-owned pin");
const native = await verifyNativeAcpxInstallation({
distributionRoot,
manifestPath: join(assets, "native-closure.json"),
expectedClosureSha256,
executable: "node/bin/node",
entrypoint,
fixedArguments: ["acp"],
});
return Object.freeze({
commandDigest: profile.commandDigest,
agentServerPackageJsonPath: join(distributionRoot, "node_modules/@moonshot-ai/kimi-code/package.json"),
agentRuntimePackageJsonPath: null,
async openCommand(options?: { signal?: AbortSignal }) {
options?.signal?.throwIfAborted();
await assertDirectories();
return native.openCommand(options);
},
});
}
@@ -0,0 +1,70 @@
import { describe, expect, it } from "vitest";
import { createKimiInstructionAdmission, kimiInstructionBinding } from "./kimi-instructions.js";
import { kimiManagedConfiguration, kimiReadOnlyPermissionAllowed } from "./kimi-config.js";
function acknowledgment(content: string, sessionId = "native-1") {
return { schema: "paperclip.kimi.instructions.v1", ...kimiInstructionBinding(content), sessionId,
effectiveDigest: `sha256:${"a".repeat(64)}`, effectiveByteLength: 500 };
}
describe("Kimi native instruction admission", () => {
it("keeps human questions and plans on the qualified semantic tool path", () => {
const config = kimiManagedConfiguration("caller-model");
for (const name of ["AskUserQuestion", "EnterPlanMode", "ExitPlanMode", "Agent", "AgentSwarm"]) {
expect(config).toContain(JSON.stringify(name));
}
});
it("admits exact UTF-8 instructions only after the correlated native reply, including ID zero", () => {
const content = "Follow café instructions 🥔\n";
const admission = createKimiInstructionAdmission(content);
const guard = admission.createGuard();
guard("outbound", { id: 0, method: "session/new", params: {} });
guard("inbound", { id: 4, result: { sessionId: "native-1", _meta: { paperclipKimiInstructions: acknowledgment(content) } } });
expect(admission.assertReady).toThrow("did not acknowledge");
guard("inbound", { id: 0, result: { sessionId: "native-1", _meta: { paperclipKimiInstructions: acknowledgment(content) } } });
expect(admission.assertReady).not.toThrow();
guard("outbound", { id: 1, method: "session/prompt", params: { sessionId: "native-1" } });
});
it.each(["missing", "content", "session", "length", "effective"])("rejects %s proof before a prompt", kind => {
const admission = createKimiInstructionAdmission("rules");
const guard = admission.createGuard();
guard("outbound", { id: "load", method: "session/load", params: { sessionId: "native-1" } });
const ack = acknowledgment("rules");
if (kind === "content") ack.digest = kimiInstructionBinding("different").digest;
if (kind === "session") ack.sessionId = "other";
if (kind === "length") ack.byteLength += 1;
if (kind === "effective") ack.effectiveDigest = "unknown";
expect(() => guard("inbound", { id: "load", result: { _meta: kind === "missing" ? {} : { paperclipKimiInstructions: ack } } })).toThrow("mismatched");
expect(() => guard("outbound", { id: 2, method: "session/prompt", params: { sessionId: "native-1" } })).toThrow();
});
it("revokes the old connection and requires proof again after load", () => {
const admission = createKimiInstructionAdmission("");
const old = admission.createGuard();
old("outbound", { id: 1, method: "session/new", params: {} });
old("inbound", { id: 1, result: { sessionId: "native-1", _meta: { paperclipKimiInstructions: acknowledgment("") } } });
const current = admission.createGuard();
expect(() => old("outbound", { method: "session/prompt" })).toThrow("replaced");
current("outbound", { id: 2, method: "session/load", params: { sessionId: "native-1" } });
expect(admission.assertReady).toThrow();
current("inbound", { id: 2, result: { _meta: { paperclipKimiInstructions: acknowledgment("") } } });
expect(admission.assertReady).not.toThrow();
expect(() => current("outbound", { method: "session/prompt", params: { sessionId: "other" } })).toThrow("unacknowledged");
});
it("bounds exact byte content rather than JavaScript character count", () => {
expect(() => kimiInstructionBinding("🧪".repeat(8193))).toThrow("bounded");
expect(() => kimiInstructionBinding("bad\0input")).toThrow("NUL");
});
it("keeps read-only authority separate from native tool labels and auto-approval", () => {
const owned = new Set(["paperclip"]);
for (const title of ["Write", "Edit", "Bash", "Read", "mcp__other__read", "mcp__paperclip__"]) {
expect(kimiReadOnlyPermissionAllowed({ inferredKind: "read", raw: { toolCall: { title, rawInput: {} } } }, owned)).toBe(false);
}
expect(kimiReadOnlyPermissionAllowed({ raw: { toolCall: { title: "mcp__paperclip__get_task_context", rawInput: {} } } }, owned)).toBe(true);
expect(kimiReadOnlyPermissionAllowed({ raw: { toolCall: { title: "mcp__paperclip__get_task_context" } } }, owned)).toBe(false);
expect(kimiReadOnlyPermissionAllowed({ raw: { toolCall: { title: "mcp__paperclip__get_task_context", rawInput: [] } } }, owned)).toBe(false);
});
});
@@ -0,0 +1,71 @@
import { createHash } from "node:crypto";
const SCHEMA = "paperclip.kimi.instructions.v1";
const MAX_BYTES = 32 * 1024;
export function kimiInstructionBinding(content: string) {
if (typeof content !== "string" || content.includes("\0") || Buffer.from(content).toString("utf8") !== content || Buffer.byteLength(content) > MAX_BYTES) {
throw new Error("Kimi Code instructions exceed their bounded size or contain NUL");
}
const digest = `sha256:${createHash("sha256").update(content).digest("hex")}`;
const byteLength = Buffer.byteLength(content);
return { payload: JSON.stringify({ schema: SCHEMA, content, digest, byteLength }), digest, byteLength };
}
function record(value: unknown): Record<string, unknown> {
return value !== null && typeof value === "object" && !Array.isArray(value) ? value as Record<string, unknown> : {};
}
export function createKimiInstructionAdmission(content: string) {
const expected = kimiInstructionBinding(content);
let current: { sessionId: string | null; error: Error | null } | null = null;
const failure = (message: string) => new Error(`Kimi Code instruction admission failed: ${message}`);
const assertReady = () => {
if (current?.error) throw current.error;
if (!current?.sessionId) throw failure("provider did not acknowledge the composed instructions");
};
return {
assertReady,
createGuard() {
const state = { sessionId: null as string | null, error: null as Error | null };
current = state;
const pending = new Map<string | number, { method: string; sessionId: unknown }>();
return (direction: "inbound" | "outbound", value: unknown): void => {
if (current !== state) throw failure("connection authority was replaced");
if (state.error) throw state.error;
const message = record(value);
try {
if (direction === "outbound") {
if (["session/new", "session/load", "session/resume"].includes(String(message.method))) {
if ((typeof message.id !== "string" && typeof message.id !== "number") || pending.size !== 0) throw failure("session admission request is ambiguous");
state.sessionId = null;
pending.set(message.id, { method: String(message.method), sessionId: record(message.params).sessionId });
} else if (message.method === "session/prompt") {
assertReady();
if (record(message.params).sessionId !== state.sessionId) throw failure("prompt belongs to an unacknowledged session");
}
return;
}
if (message.method !== undefined || (typeof message.id !== "string" && typeof message.id !== "number")) return;
const request = pending.get(message.id);
if (!request) return;
pending.delete(message.id);
if (message.error !== undefined) return;
const result = record(message.result);
const ack = record(record(result._meta).paperclipKimiInstructions);
const sessionId = request.method === "session/new" ? result.sessionId : request.sessionId;
if (ack.schema !== SCHEMA || ack.digest !== expected.digest || ack.byteLength !== expected.byteLength
|| typeof sessionId !== "string" || !sessionId.trim() || ack.sessionId !== sessionId
|| typeof ack.effectiveDigest !== "string" || !/^sha256:[a-f0-9]{64}$/.test(ack.effectiveDigest)
|| !Number.isSafeInteger(ack.effectiveByteLength) || (ack.effectiveByteLength as number) < expected.byteLength) {
throw failure("native instruction acknowledgment is missing or mismatched");
}
state.sessionId = sessionId;
} catch (error) {
state.error = error instanceof Error ? error : failure("invalid acknowledgment");
throw state.error;
}
};
},
};
}
@@ -0,0 +1,70 @@
import { describe, expect, it } from "vitest";
import { createKimiMessageProjection, kimiMessageBoundaryClears } from "./kimi-message-boundary.js";
const id = (n: number) => `kimi-message-${String(n).padStart(64, "0")}`;
const chunk = (n: number, kind: string, text = "", stream = "output") => ({ type: "text_delta", messageId: id(n), text, stream,
meta: { origin: "kimi-native-assistant", source: "kimi-turn-step-v1", kind } });
function project(events: ReturnType<typeof chunk>[]) {
const projection = createKimiMessageProjection<ReturnType<typeof chunk>>();
const progress: string[] = []; let final = "";
for (const raw of events) {
const event = projection.normalize(raw);
if (kimiMessageBoundaryClears(event)) final = "";
if (event.stream === "output") { final += event.text; progress.push(event.text); }
}
projection.settle(); return { final, progress };
}
describe("Kimi native message boundaries", () => {
it("preserves separate native steps while finalizing only the actual end-turn answer", () => {
const projection = createKimiMessageProjection<ReturnType<typeof chunk>>();
const started = projection.normalize(chunk(1, "start"));
expect(started).toMatchObject({ messageId: id(1), text: "", assistantMessageBoundary: { phase: "start" } });
expect(projection.normalize(chunk(1, "delta", "I will call the tool."))).toMatchObject({ messageId: id(1), text: "I will call the tool." });
expect(projection.normalize(chunk(1, "end:tool_use"))).toMatchObject({ messageId: id(1), text: "", assistantMessageBoundary: { phase: "end", stopReason: "toolUse" } });
projection.normalize(chunk(2, "start"));
expect(projection.normalize(chunk(2, "delta", "private reasoning", "thought"))).toMatchObject({ messageId: id(2), stream: "thought" });
projection.normalize(chunk(2, "delta", "EXACT_MARKER"));
expect(projection.normalize(chunk(2, "end:end_turn"))).toMatchObject({ messageId: id(2), assistantMessageBoundary: { phase: "end", stopReason: "stop" } });
projection.settle();
const result = project([chunk(1, "start"), chunk(1, "delta", "I will call the tool."), chunk(1, "end:tool_use"),
chunk(2, "start"), chunk(2, "delta", "private reasoning", "thought"), chunk(2, "delta", "EXACT_"), chunk(2, "delta", "MARKER"), chunk(2, "end:end_turn")]);
expect(result.final).toBe("EXACT_MARKER");
expect(result.progress).toContain("I will call the tool.");
expect(result.progress).not.toContain("private reasoning");
});
it.each([
["end_turn", "stop"], ["max_tokens", "length"], ["tool_use", "toolUse"], ["error", "error"],
["filtered", "error"], ["other", "error"], ["aborted", "aborted"], ["paused", "aborted"], ["max_steps", "aborted"],
])("maps the actual native %s reason to closed canonical %s", (native, canonical) => {
const projection = createKimiMessageProjection<ReturnType<typeof chunk>>();
projection.normalize(chunk(1, "start"));
expect(projection.normalize(chunk(1, `end:${native}`)).assistantMessageBoundary).toEqual({ phase: "end", stopReason: canonical });
projection.settle();
expect(project([chunk(1, "start"), chunk(1, "delta", "native output"), chunk(1, `end:${native}`)]).final)
.toBe(["end_turn", "max_tokens"].includes(native) ? "native output" : "");
});
it("retains empty final boundaries and permits notice-only turns without inventing an answer", () => {
expect(project([chunk(1, "start"), chunk(1, "delta", "old answer"), chunk(1, "end:end_turn"), chunk(2, "start"), chunk(2, "end:end_turn")]).final).toBe("");
const projection = createKimiMessageProjection<{ type: string }>();
expect(projection.normalize({ type: "status" })).toEqual({ type: "status" }); projection.settle();
});
it.each([
[chunk(1, "delta", "missing start")], [chunk(1, "end:end_turn")], [chunk(1, "start"), chunk(1, "start")],
[chunk(1, "start"), chunk(2, "delta", "wrong id")], [chunk(1, "start"), chunk(2, "end:end_turn")],
[chunk(1, "start"), chunk(1, "end:invented")], [chunk(1, "start"), chunk(1, "end:constructor")],
[chunk(1, "start"), chunk(1, "end:end_turn"), chunk(1, "start")], [chunk(1, "start", "nonempty boundary")],
[chunk(1, "start", "", "thought")], [chunk(1, "start"), chunk(1, "end:end_turn", "nonempty end")], [chunk(1, "start")],
[{ ...chunk(1, "start"), messageId: "fabricated-id" }], [{ ...chunk(1, "start"), meta: { origin: "forged", source: "kimi-turn-step-v1", kind: "start" } }],
[{ ...chunk(1, "start"), meta: { origin: "kimi-native-assistant", source: "unversioned", kind: "start" } }],
[{ ...chunk(1, "start"), assistantMessageBoundary: { phase: "start" } }],
])("fails closed for missing, reused or forged native provenance %#", (...events) => {
expect(() => project(events)).toThrow("provenance");
});
it("poisons a malformed stream instead of accepting a later valid-looking boundary", () => {
const projection = createKimiMessageProjection<ReturnType<typeof chunk>>();
expect(() => projection.normalize(chunk(1, "delta", "orphan"))).toThrow("provenance");
expect(() => projection.normalize(chunk(2, "start"))).toThrow("provenance");
expect(() => projection.settle()).toThrow("provenance");
});
});
@@ -0,0 +1,47 @@
type RuntimeMessageEvent = { type: string; text?: string; stream?: string; messageId?: string; meta?: Record<string, unknown> };
export interface KimiMessageBoundary { phase: "start" | "end"; stopReason?: "stop" | "length" | "toolUse" | "error" | "aborted" }
export type KimiProjectedMessageEvent<T> = T & { assistantMessageBoundary?: KimiMessageBoundary; assistantMessageHistory?: true };
const STOP_REASONS: Readonly<Record<string, KimiMessageBoundary["stopReason"]>> = Object.freeze({
end_turn: "stop", max_tokens: "length", tool_use: "toolUse", error: "error", filtered: "error", other: "error",
aborted: "aborted", paused: "aborted", max_steps: "aborted",
});
export function createKimiMessageProjection<T extends RuntimeMessageEvent>() {
let active: string | null = null;
const seen = new Set<string>();
let poisoned = false;
const fail = (): never => { poisoned = true; throw new Error("Kimi native message provenance is invalid or incomplete"); };
return {
normalize(event: T): KimiProjectedMessageEvent<T> {
if (poisoned) return fail();
if ("assistantMessageBoundary" in event || "assistantMessageHistory" in event) return fail();
if (event.type !== "text_delta") return event;
const { messageId, meta } = event;
if (typeof messageId !== "string" || !/^kimi-message-[a-f0-9]{64}$/.test(messageId)
|| meta?.origin !== "kimi-native-assistant" || meta.source !== "kimi-turn-step-v1"
|| typeof event.text !== "string" || (event.stream !== "output" && event.stream !== "thought")) return fail();
if (meta.kind === "delta") {
if (active !== messageId) return fail();
return event;
}
if (event.text !== "" || event.stream !== "output") return fail();
if (meta.kind === "start") {
if (active || seen.has(messageId) || seen.size >= 4096) return fail();
seen.add(messageId); active = messageId;
return { ...event, assistantMessageBoundary: { phase: "start" } };
}
if (active !== messageId || typeof meta.kind !== "string" || !meta.kind.startsWith("end:")) return fail();
const reason = meta.kind.slice(4);
if (!Object.hasOwn(STOP_REASONS, reason)) return fail();
active = null;
return { ...event, assistantMessageBoundary: { phase: "end", stopReason: STOP_REASONS[reason] } };
},
settle(): void { if (poisoned || active) fail(); },
};
}
export function kimiMessageBoundaryClears(event: { assistantMessageBoundary?: KimiMessageBoundary }): boolean {
const boundary = event.assistantMessageBoundary;
return boundary?.phase === "start" || (boundary?.phase === "end" && !["stop", "length"].includes(boundary.stopReason ?? ""));
}
@@ -0,0 +1,141 @@
import { bindAcpxCandidateAdmission, type AcpxCandidateAdmission } from "./candidate-admission.js";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { KIMI_DISTRIBUTION_CLOSURE_SHA256, KIMI_NODE_DISTRIBUTIONS, KIMI_NODE_VERSION, KIMI_RUNTIME_VERSION } from "./kimi-closure-pins.js";
import { KimiMetadataProbeError } from "./kimi-models.js";
import { QUALIFIED_ACPX_PROFILES } from "./qualified-profiles.js";
const mocks = vi.hoisted(() => ({ installation: vi.fn(), open: vi.fn(), close: vi.fn(), metadata: vi.fn() }));
vi.mock("./kimi-installation.js", () => ({ verifyKimiInstallation: mocks.installation }));
vi.mock("./kimi-models.js", async original => ({ ...await original<object>(), probeKimiModels: mocks.metadata }));
import { kimiMetadataProbeNodeDigest, probeKimiMetadata, validateKimiMetadata } from "./kimi-metadata-probe.js";
const model = "selected-model";
const apiKey = "selected-secret-canary";
const target = `${process.platform}-${process.arch}` as keyof typeof KIMI_DISTRIBUTION_CLOSURE_SHA256;
const admission = () => bindAcpxCandidateAdmission({ schema: "paperclip.acpx-candidate-admission.v1", companyId: "metadata-company", agent: "kimi", model,
profileDigest: QUALIFIED_ACPX_PROFILES.kimi.commandDigest,
nativeClosureDigest: `sha256:${KIMI_DISTRIBUTION_CLOSURE_SHA256[target]}`,
platform: process.platform, architecture: process.arch, expiresAt: Date.now() + 60_000 } as AcpxCandidateAdmission,
{ runId: "metadata-operation", normalizedSessionId: "metadata-session" });
const receipt = () => ({ schema: "paperclip.kimi.metadata.v1", status: "verified", version: KIMI_RUNTIME_VERSION,
nodeVersion: KIMI_NODE_VERSION, profileDigest: QUALIFIED_ACPX_PROFILES.kimi.commandDigest, target,
closureDigest: `sha256:${KIMI_DISTRIBUTION_CLOSURE_SHA256[target]}`, model, contextLength: 1048576, promptSent: false });
beforeEach(() => {
vi.resetAllMocks();
mocks.installation.mockResolvedValue({ openCommand: mocks.open });
mocks.open.mockResolvedValue({ close: mocks.close });
mocks.close.mockResolvedValue(undefined);
mocks.metadata.mockResolvedValue({ model, contextLength: 1048576 });
});
afterEach(() => { vi.unstubAllEnvs(); });
describe("Kimi setup metadata admission", () => {
it("verifies and closes the complete installation before authenticating the exact selected model", async () => {
const order: string[] = [];
mocks.open.mockImplementation(async () => { order.push("verify-closure"); return { close: mocks.close }; });
mocks.close.mockImplementation(async () => { order.push("cleanup"); });
mocks.metadata.mockImplementation(async () => { order.push("authenticate"); return { model, contextLength: 1048576 }; });
vi.stubEnv("KIMI_API_KEY", "unselected-ambient-secret");
vi.stubEnv("KIMI_MODEL_DEFAULT", "unselected-model");
await expect(probeKimiMetadata(model, apiKey, admission())).resolves.toEqual(receipt());
expect(order).toEqual(["verify-closure", "cleanup", "authenticate"]);
expect(mocks.installation).toHaveBeenCalledWith(expect.objectContaining({
agent: "kimi", commandDigest: QUALIFIED_ACPX_PROFILES.kimi.commandDigest,
qualificationModel: model, reportedModelId: model,
}));
expect(mocks.metadata).toHaveBeenCalledExactlyOnceWith(model, apiKey);
});
it.each(["metadata", "closure", "cleanup"])("rejects %s installation failure before authenticating", async stage => {
const error = new Error(`private runtime failure ${apiKey}`);
if (stage === "metadata") mocks.installation.mockRejectedValue(error);
if (stage === "closure") mocks.open.mockRejectedValue(error);
if (stage === "cleanup") mocks.close.mockRejectedValue(error);
const result = await probeKimiMetadata(model, apiKey, admission());
expect(result).toMatchObject({ status: "failed", code: "KIMI_INSTALLATION_INVALID", promptSent: false });
expect(JSON.stringify(result)).not.toContain(apiKey);
expect(mocks.metadata).not.toHaveBeenCalled();
});
it("refuses pending metadata work without exact trusted startup authority before files or HTTP", async () => {
expect(await probeKimiMetadata(model, apiKey)).toMatchObject({ status: "failed", code: "KIMI_QUALIFICATION_REQUIRED", promptSent: false });
const valid = admission();
for (const altered of [{ ...valid, model: "other-model" }, { ...valid, agent: "antigravity" },
{ ...valid, expiresAt: 0 }, { ...valid, profileDigest: `sha256:${"f".repeat(64)}` },
{ ...valid, nativeClosureDigest: `sha256:${"e".repeat(64)}` }, { ...valid, extra: true }]) {
expect(await probeKimiMetadata(model, apiKey, altered as typeof valid)).toMatchObject({ code: "KIMI_QUALIFICATION_REQUIRED" });
}
expect(mocks.installation).not.toHaveBeenCalled(); expect(mocks.metadata).not.toHaveBeenCalled();
});
it("requires no operator grant after canonical release metadata admits Kimi", async () => {
vi.resetModules();
vi.doMock("./generated-profiles.js", async original => {
const data = await original<typeof import("./generated-profiles.js")>();
const current = structuredClone(data.QUALIFIED_ACPX_PROFILE_DATA);
const released = { ...current.kimi } as Record<string, unknown>;
delete released.qualificationStatus;
return { ...data, QUALIFIED_ACPX_PROFILE_DATA: { ...current, kimi: released } };
});
try {
const released = await import("./kimi-metadata-probe.js");
expect(await released.probeKimiMetadata(model, apiKey)).toMatchObject({ status: "verified", model, promptSent: false });
expect(mocks.metadata).toHaveBeenCalledExactlyOnceWith(model, apiKey);
} finally { vi.doUnmock("./generated-profiles.js"); vi.resetModules(); }
});
it("requires an explicit bounded credential and exact model before installation or HTTP work", async () => {
vi.stubEnv("KIMI_API_KEY", apiKey);
for (const invalid of ["", " ", "key\nheader", "key\rheader", "key\0header", "x".repeat(16385)]) {
expect(await probeKimiMetadata(model, invalid)).toMatchObject({ code: "KIMI_AUTH_REQUIRED" });
}
for (const invalid of ["", " ", "model\0value", "x".repeat(513), "\ud800"]) {
expect(await probeKimiMetadata(invalid, apiKey)).toMatchObject({ code: "KIMI_MODEL_UNAVAILABLE" });
}
expect(mocks.installation).not.toHaveBeenCalled();
expect(mocks.metadata).not.toHaveBeenCalled();
});
it.each(["KIMI_AUTH_REJECTED", "KIMI_MODEL_UNAVAILABLE", "KIMI_METADATA_TIMEOUT", "KIMI_METADATA_INVALID", "KIMI_PROVIDER_ERROR"] as const)("preserves the canonical %s failure without provider text", async code => {
mocks.metadata.mockRejectedValue(new KimiMetadataProbeError(code));
expect(await probeKimiMetadata(model, apiKey, admission())).toMatchObject({ status: "failed", code, promptSent: false });
mocks.metadata.mockRejectedValue(new Error(`provider failure ${apiKey}`));
const result = await probeKimiMetadata(model, apiKey, admission());
expect(result).toMatchObject({ status: "failed", code: "KIMI_REQUEST_FAILED", promptSent: false });
expect(JSON.stringify(result)).not.toContain(apiKey);
});
});
describe("untrusted Kimi metadata receipts", () => {
it("accepts only the current source identity and exact selected model", () => {
expect(validateKimiMetadata(receipt(), model)).toEqual(receipt());
expect(kimiMetadataProbeNodeDigest()).toBe(`sha256:${KIMI_NODE_DISTRIBUTIONS["linux-x64"].executableSha256}`);
expect(validateKimiMetadata(receipt(), "different-model")).toMatchObject({ code: "KIMI_MODEL_UNAVAILABLE" });
});
it.each([
{ version: "latest" }, { nodeVersion: "24.0.0" }, { profileDigest: `sha256:${"0".repeat(64)}` },
{ closureDigest: `sha256:${"0".repeat(64)}` }, { target: "linux-arm64" },
])("rejects an incompatible installation %#", alteration => {
expect(validateKimiMetadata({ ...receipt(), ...alteration }, model)).toMatchObject({
status: "failed", code: "KIMI_INSTALLATION_INVALID", promptSent: false,
});
});
it.each([null, [], {}, { ...receipt(), promptSent: true }, { ...receipt(), injected: true },
{ ...receipt(), schema: "other" }, { schema: "paperclip.kimi.metadata.v1", status: "failed", code: "invented", promptSent: false },
])("rejects malformed or open receipt contracts %#", value => {
expect(validateKimiMetadata(value, model)).toMatchObject({ status: "failed", code: "KIMI_REQUEST_FAILED" });
});
it.each([0, -1, 1.5, "1048576", Number.MAX_SAFE_INTEGER + 1, undefined])("rejects invalid context length %s", contextLength => {
expect(validateKimiMetadata({ ...receipt(), contextLength }, model)).toMatchObject({ code: "KIMI_METADATA_INVALID" });
});
it("replaces remote failure messages with canonical text", () => {
const result = validateKimiMetadata({ schema: "paperclip.kimi.metadata.v1", status: "failed", code: "KIMI_AUTH_REJECTED", message: apiKey, promptSent: false }, model);
expect(result).toMatchObject({ code: "KIMI_AUTH_REJECTED", promptSent: false });
expect(JSON.stringify(result)).not.toContain(apiKey);
});
});
@@ -0,0 +1,94 @@
import { assertAcpxExecutionAdmission, type AcpxCandidateStartupAdmission } from "./candidate-admission.js";
import { createHash } from "node:crypto";
import { constants } from "node:fs";
import { lstat, open } from "node:fs/promises";
import { fileURLToPath } from "node:url";
import { KIMI_DISTRIBUTION_CLOSURE_SHA256, KIMI_NODE_DISTRIBUTIONS, KIMI_NODE_VERSION, KIMI_RUNTIME_VERSION } from "./kimi-closure-pins.js";
import { verifyKimiInstallation } from "./kimi-installation.js";
import { KimiMetadataProbeError, probeKimiModels, type KimiMetadataProbeErrorCode } from "./kimi-models.js";
import { resolveQualifiedAcpxProfile, QUALIFIED_ACPX_PROFILES } from "./qualified-profiles.js";
const SCHEMA = "paperclip.kimi.metadata.v1";
const providerCodes = ["KIMI_AUTH_REQUIRED", "KIMI_AUTH_REJECTED", "KIMI_MODEL_UNAVAILABLE", "KIMI_METADATA_TIMEOUT", "KIMI_METADATA_INVALID", "KIMI_PROVIDER_ERROR"] as const;
type FailureCode = KimiMetadataProbeErrorCode | "KIMI_INSTALLATION_INVALID" | "KIMI_REQUEST_FAILED" | "KIMI_QUALIFICATION_REQUIRED";
export type KimiMetadataResult = {
schema: typeof SCHEMA; status: "verified"; version: typeof KIMI_RUNTIME_VERSION;
nodeVersion: typeof KIMI_NODE_VERSION; profileDigest: string; target: string;
closureDigest: string; model: string; contextLength: number; promptSent: false;
} | { schema: typeof SCHEMA; status: "failed"; code: FailureCode; message: string; promptSent: false };
function failed(code: FailureCode): Extract<KimiMetadataResult, { status: "failed" }> {
const message = code === "KIMI_QUALIFICATION_REQUIRED"
? "Kimi Code qualification is pending; metadata verification requires trusted operator admission."
: code === "KIMI_INSTALLATION_INVALID"
? "Install the current verified Kimi Code runtime in this execution environment."
: code === "KIMI_REQUEST_FAILED" ? "Kimi Code metadata verification failed."
: new KimiMetadataProbeError(code).message;
return { schema: SCHEMA, status: "failed", code, message, promptSent: false };
}
export async function probeKimiMetadata(model: string, apiKey: string, candidateAdmission?: AcpxCandidateStartupAdmission): Promise<KimiMetadataResult> {
if (typeof apiKey !== "string" || !apiKey.trim() || /[\0\r\n]/.test(apiKey) || Buffer.byteLength(apiKey) > 16 * 1024) return failed("KIMI_AUTH_REQUIRED");
if (typeof model !== "string" || !model.trim() || model.includes("\0") || Buffer.byteLength(model) > 512 || Buffer.from(model).toString("utf8") !== model) return failed("KIMI_MODEL_UNAVAILABLE");
const target = `${process.platform}-${process.arch}`;
if (!Object.hasOwn(KIMI_DISTRIBUTION_CLOSURE_SHA256, target)) return failed("KIMI_INSTALLATION_INVALID");
const profile = resolveQualifiedAcpxProfile("kimi", model);
try { assertAcpxExecutionAdmission(profile, candidateAdmission); }
catch { return failed("KIMI_QUALIFICATION_REQUIRED"); }
try {
const installation = await verifyKimiInstallation(profile);
const lease = await installation.openCommand();
await lease.close();
} catch { return failed("KIMI_INSTALLATION_INVALID"); }
try {
const metadata = await probeKimiModels(model, apiKey);
return { schema: SCHEMA, status: "verified", version: KIMI_RUNTIME_VERSION, nodeVersion: KIMI_NODE_VERSION,
profileDigest: QUALIFIED_ACPX_PROFILES.kimi.commandDigest, target,
closureDigest: `sha256:${KIMI_DISTRIBUTION_CLOSURE_SHA256[target as keyof typeof KIMI_DISTRIBUTION_CLOSURE_SHA256]}`,
model: metadata.model, contextLength: metadata.contextLength, promptSent: false };
} catch (error) { return failed(error instanceof KimiMetadataProbeError ? error.code : "KIMI_REQUEST_FAILED"); }
}
export function validateKimiMetadata(value: unknown, model: string): KimiMetadataResult {
if (!value || typeof value !== "object" || Array.isArray(value)) return failed("KIMI_REQUEST_FAILED");
const row = value as Record<string, unknown>;
if (row.schema !== SCHEMA || row.promptSent !== false) return failed("KIMI_REQUEST_FAILED");
if (row.status === "failed") {
if (Object.keys(row).some(key => !["schema", "status", "code", "message", "promptSent"].includes(key))
|| typeof row.code !== "string" || ![...providerCodes, "KIMI_INSTALLATION_INVALID", "KIMI_REQUEST_FAILED", "KIMI_QUALIFICATION_REQUIRED"].includes(row.code)) return failed("KIMI_REQUEST_FAILED");
return failed(row.code as FailureCode);
}
if (row.status !== "verified" || Object.keys(row).some(key => !["schema", "status", "version", "nodeVersion", "profileDigest", "target", "closureDigest", "model", "contextLength", "promptSent"].includes(key))) return failed("KIMI_REQUEST_FAILED");
if (row.version !== KIMI_RUNTIME_VERSION || row.nodeVersion !== KIMI_NODE_VERSION
|| row.profileDigest !== QUALIFIED_ACPX_PROFILES.kimi.commandDigest || typeof row.target !== "string"
|| !Object.hasOwn(KIMI_DISTRIBUTION_CLOSURE_SHA256, row.target)
|| row.closureDigest !== `sha256:${KIMI_DISTRIBUTION_CLOSURE_SHA256[row.target as keyof typeof KIMI_DISTRIBUTION_CLOSURE_SHA256]}`) return failed("KIMI_INSTALLATION_INVALID");
if (row.model !== model) return failed("KIMI_MODEL_UNAVAILABLE");
if (!Number.isSafeInteger(row.contextLength) || (row.contextLength as number) <= 0) return failed("KIMI_METADATA_INVALID");
return row as Extract<KimiMetadataResult, { status: "verified" }>;
}
export function kimiMetadataProbeNodeDigest(): string {
return `sha256:${KIMI_NODE_DISTRIBUTIONS["linux-x64"].executableSha256}`;
}
export async function kimiMetadataProbeDigest(): Promise<string> {
const url = new URL(import.meta.url);
const relative = /\/dist\/vendor\/paperclip-runner\/drivers\/acpx\/kimi-metadata-probe\.js$/.test(url.pathname)
? "../../cli/kimi-metadata-probe.cjs"
: /\/(?:src|dist)\/drivers\/acpx\/kimi-metadata-probe\.(?:ts|js)$/.test(url.pathname)
? "../../../dist/cli/kimi-metadata-probe.cjs" : null;
if (url.protocol !== "file:" || url.search || url.hash || relative === null) throw new Error("Kimi metadata probe requires its fixed build layout");
const path = fileURLToPath(new URL(relative, url));
const file = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
try {
const before = await file.stat({ bigint: true });
if (!before.isFile() || before.size < 1n || before.size > 4n * 1024n * 1024n) throw new Error("Kimi metadata probe artifact is invalid");
const bytes = await file.readFile();
const after = await file.stat({ bigint: true }), named = await lstat(path, { bigint: true });
if (bytes.length !== Number(before.size) || before.dev !== after.dev || before.ino !== after.ino
|| before.mtimeNs !== after.mtimeNs || before.ctimeNs !== after.ctimeNs || before.size !== after.size
|| named.dev !== before.dev || named.ino !== before.ino || named.isSymbolicLink()) throw new Error("Kimi metadata probe artifact changed during admission");
return `sha256:${createHash("sha256").update(bytes).digest("hex")}`;
} finally { await file.close(); }
}
@@ -0,0 +1,143 @@
import { afterEach, describe, expect, it, vi } from "vitest";
import { KimiMetadataProbeError, probeKimiModels } from "./kimi-models.js";
const model = "kimi-for-coding";
const key = "selected-key-canary";
const payload = { data: [{ id: "別のモデル", limit: { context: 262144 } }, { id: model, limit: { context: 1048576 } }] };
const response = (value: unknown) => new Response(JSON.stringify(value), { headers: { "content-type": "application/json" } });
const dependency = (value: Response) => ({ fetch: vi.fn<typeof fetch>().mockResolvedValue(value) });
afterEach(() => { vi.useRealTimers(); vi.unstubAllEnvs(); });
describe("Kimi Code authenticated model metadata", () => {
it("uses only the selected key, pinned endpoint and official client identity without inference", async () => {
vi.stubEnv("KIMI_API_KEY", "ambient-unselected-key");
vi.stubEnv("KIMI_CODE_BASE_URL", "https://unselected.example");
const bytes = Buffer.from(JSON.stringify(payload));
const split = bytes.indexOf(Buffer.from("別")) + 1;
const deps = dependency(new Response(new ReadableStream({ start(controller) {
controller.enqueue(bytes.subarray(0, split)); controller.enqueue(bytes.subarray(split)); controller.close();
} })));
await expect(probeKimiModels(model, key, deps)).resolves.toEqual({
code: "kimi_metadata_verified", model, contextLength: 1048576,
message: expect.stringContaining("No model prompt was sent"),
});
expect(deps.fetch).toHaveBeenCalledTimes(1);
const [url, init] = deps.fetch.mock.calls[0]!;
expect(url).toBe("https://api.kimi.ai/coding/v1/models");
expect(init).toMatchObject({ method: "GET", redirect: "error", headers: {
Authorization: `Bearer ${key}`, Accept: "application/json", "User-Agent": "KimiCLI/2.3.3",
} });
expect(init?.body).toBeUndefined();
expect(init?.signal).toBeInstanceOf(AbortSignal);
});
it("rejects absent credentials before fetching and never falls back to ambient login", async () => {
vi.stubEnv("KIMI_API_KEY", key);
const deps = dependency(response(payload));
for (const invalid of ["", " ", "x\ny", "x\ry", "x\0y", "x".repeat(16385)]) {
await expect(probeKimiModels(model, invalid, deps)).rejects.toMatchObject({ code: "KIMI_AUTH_REQUIRED" });
}
expect(deps.fetch).not.toHaveBeenCalled();
});
it.each([401, 402, 403])("preserves typed HTTP %i credential/access rejection without reading its body", async status => {
const cancel = vi.fn();
const body = new ReadableStream({ cancel });
const getReader = vi.spyOn(body, "getReader");
const deps = dependency(new Response(body, { status }));
await expect(probeKimiModels(model, key, deps)).rejects.toMatchObject({
name: "KimiMetadataProbeError", code: "KIMI_AUTH_REJECTED", status,
});
expect(getReader).not.toHaveBeenCalled();
expect(cancel).toHaveBeenCalled();
});
it("requires the exact selected model without aliases or fallback", async () => {
for (const selected of ["KIMI-FOR-CODING", "kimi-for-coding ", "unlisted", "", "x\0y", "x".repeat(513)]) {
await expect(probeKimiModels(selected, key, dependency(response(payload))))
.rejects.toMatchObject({ code: "KIMI_MODEL_UNAVAILABLE" });
}
});
it.each([
null, [], {}, { data: {} }, { data: [null] }, { data: [{ id: "", limit: { context: 1 } }] },
{ data: [{ id: model }] }, { data: [{ id: model, limit: { context: 0 } }] },
{ data: [{ id: model, limit: { context: -1 } }] }, { data: [{ id: model, limit: { context: 1.2 } }] },
{ data: [{ id: model, limit: { context: true } }] }, { data: [{ id: model, limit: { context: "" } }] },
{ data: [{ id: model, limit: { context: Number.MAX_SAFE_INTEGER + 1 } }] },
{ data: [{ id: model, limit: { context: 1 } }, { id: model, limit: { context: 2 } }] },
])("rejects invalid or ambiguous metadata %#", async value => {
await expect(probeKimiModels(model, key, dependency(response(value)))).rejects.toMatchObject({ code: "KIMI_METADATA_INVALID" });
});
it("accepts the native numeric-string context representation", async () => {
await expect(probeKimiModels(model, key, dependency(response({ data: [{ id: model, limit: { context: "1048576" } }] }))))
.resolves.toMatchObject({ contextLength: 1048576 });
});
it("bounds streamed bytes even when Content-Length is missing or false", async () => {
for (const headers of [{}, { "content-length": "10" }]) {
const cancel = vi.fn();
const deps = dependency(new Response(new ReadableStream({ start(controller) {
controller.enqueue(new Uint8Array(256 * 1024)); controller.enqueue(new Uint8Array(1));
}, cancel }), { headers }));
await expect(probeKimiModels(model, key, deps)).rejects.toMatchObject({ code: "KIMI_METADATA_INVALID" });
expect(deps.fetch.mock.calls[0]?.[1]?.signal?.aborted).toBe(true);
expect(cancel).toHaveBeenCalled();
}
});
it("rejects oversized declared bodies before consuming them", async () => {
const cancel = vi.fn();
const deps = dependency(new Response(new ReadableStream({ cancel }), { headers: { "content-length": "262145" } }));
await expect(probeKimiModels(model, key, deps)).rejects.toMatchObject({ code: "KIMI_METADATA_INVALID" });
expect(cancel).toHaveBeenCalled();
});
it.each([new Uint8Array([0xff]), Buffer.from("invalid JSON")])("rejects invalid UTF-8 or JSON %#", async bytes => {
await expect(probeKimiModels(model, key, dependency(new Response(bytes))))
.rejects.toMatchObject({ code: "KIMI_METADATA_INVALID" });
});
it("aborts an outstanding request at the fixed eight-second deadline", async () => {
vi.useFakeTimers();
let signal: AbortSignal | undefined;
const aborted = vi.fn();
const deps = { fetch: vi.fn<typeof fetch>((_url, init) => new Promise((_, reject) => {
signal = init?.signal ?? undefined;
signal?.addEventListener("abort", () => { aborted(); reject(new Error(`request failure ${key}`)); });
})) };
const rejected = expect(probeKimiModels(model, key, deps)).rejects.toMatchObject({ code: "KIMI_METADATA_TIMEOUT" });
await vi.advanceTimersByTimeAsync(7999);
expect(aborted).not.toHaveBeenCalled();
await vi.advanceTimersByTimeAsync(1);
await rejected;
expect(signal?.aborted).toBe(true);
expect(aborted).toHaveBeenCalledTimes(1);
});
it("keeps the deadline active after headers and cancels a stalled response body", async () => {
vi.useFakeTimers();
const cancel = vi.fn();
const deps = dependency(new Response(new ReadableStream({ cancel })));
const rejected = expect(probeKimiModels(model, key, deps)).rejects.toMatchObject({ code: "KIMI_METADATA_TIMEOUT" });
await vi.advanceTimersByTimeAsync(8000);
await rejected;
expect(deps.fetch.mock.calls[0]?.[1]?.signal?.aborted).toBe(true);
expect(cancel).toHaveBeenCalled();
});
it("sanitizes provider responses and transport exceptions", async () => {
for (const deps of [dependency(new Response(`private response ${key}`, { status: 500 })),
{ fetch: vi.fn<typeof fetch>().mockRejectedValue(new Error(`private request ${key}`)) }]) {
let failure: unknown;
try { await probeKimiModels(model, key, deps); } catch (error) { failure = error; }
expect(failure).toBeInstanceOf(KimiMetadataProbeError);
expect(failure).toMatchObject({ code: "KIMI_PROVIDER_ERROR" });
expect(JSON.stringify(failure)).not.toContain(key);
expect(String(failure)).not.toContain(key);
expect(failure).not.toHaveProperty("cause");
}
});
});
@@ -0,0 +1,140 @@
const MODELS_URL = "https://api.kimi.ai/coding/v1/models";
const USER_AGENT = "KimiCLI/2.3.3";
const MAX_BYTES = 256 * 1024;
const TIMEOUT_MS = 8_000;
export type KimiMetadataProbeErrorCode =
| "KIMI_AUTH_REQUIRED"
| "KIMI_AUTH_REJECTED"
| "KIMI_MODEL_UNAVAILABLE"
| "KIMI_METADATA_TIMEOUT"
| "KIMI_METADATA_INVALID"
| "KIMI_PROVIDER_ERROR";
const messages: Record<KimiMetadataProbeErrorCode, string> = {
KIMI_AUTH_REQUIRED: "Bind a valid company secret to KIMI_API_KEY.",
KIMI_AUTH_REJECTED: "Kimi Code rejected the selected credential or account access. Check the credential and Code membership.",
KIMI_MODEL_UNAVAILABLE: "The exact selected model is unavailable in the authenticated Kimi Code catalog.",
KIMI_METADATA_TIMEOUT: "Kimi Code model verification timed out.",
KIMI_METADATA_INVALID: "Kimi Code returned invalid model metadata.",
KIMI_PROVIDER_ERROR: "Kimi Code model verification failed. Try again when the provider is available.",
};
export class KimiMetadataProbeError extends Error {
readonly code: KimiMetadataProbeErrorCode;
readonly status?: number;
constructor(code: KimiMetadataProbeErrorCode, status?: number) {
super(messages[code]);
this.name = "KimiMetadataProbeError";
this.code = code;
this.status = status;
}
}
export interface KimiVerifiedModelMetadata {
code: "kimi_metadata_verified";
model: string;
contextLength: number;
message: string;
}
function record(value: unknown): Record<string, unknown> | undefined {
return value !== null && typeof value === "object" && !Array.isArray(value) ? value as Record<string, unknown> : undefined;
}
function selectedModel(payload: unknown, requestedModel: string): number {
const data = record(payload)?.data;
if (!Array.isArray(data)) throw new KimiMetadataProbeError("KIMI_METADATA_INVALID");
const ids = new Set<string>();
let contextLength: number | undefined;
for (const value of data) {
const row = record(value);
const id = row?.id;
const context = record(row?.limit)?.context;
const parsed = typeof context === "number" || (typeof context === "string" && /^[0-9]+$/.test(context)) ? Number(context) : NaN;
if (typeof id !== "string" || !id.trim() || ids.has(id) || !Number.isSafeInteger(parsed) || parsed <= 0) {
throw new KimiMetadataProbeError("KIMI_METADATA_INVALID");
}
ids.add(id);
if (id === requestedModel) contextLength = parsed;
}
if (contextLength === undefined) throw new KimiMetadataProbeError("KIMI_MODEL_UNAVAILABLE");
return contextLength;
}
export async function probeKimiModels(
model: string,
apiKey: string,
testDependencies?: { fetch: typeof globalThis.fetch },
): Promise<KimiVerifiedModelMetadata> {
if (typeof apiKey !== "string" || !apiKey.trim() || Buffer.byteLength(apiKey) > 16 * 1024 || /[\0\r\n]/.test(apiKey)) {
throw new KimiMetadataProbeError("KIMI_AUTH_REQUIRED");
}
if (typeof model !== "string" || !model.trim() || Buffer.byteLength(model) > 512 || model.includes("\0")
|| Buffer.from(model).toString("utf8") !== model) throw new KimiMetadataProbeError("KIMI_MODEL_UNAVAILABLE");
const controller = new AbortController();
const timeoutError = new KimiMetadataProbeError("KIMI_METADATA_TIMEOUT");
let reader: ReadableStreamDefaultReader<Uint8Array> | undefined;
let response: Response | undefined;
let rejectAbort!: (reason: unknown) => void;
const aborted = new Promise<never>((_, reject) => { rejectAbort = reject; });
const onAbort = () => {
rejectAbort(timeoutError);
void reader?.cancel().catch(() => {});
};
controller.signal.addEventListener("abort", onAbort, { once: true });
const timer = setTimeout(() => controller.abort(), TIMEOUT_MS);
try {
const request = Promise.resolve().then(() => (testDependencies?.fetch ?? globalThis.fetch)(MODELS_URL, {
method: "GET", redirect: "error", signal: controller.signal,
headers: { Authorization: `Bearer ${apiKey}`, Accept: "application/json", "User-Agent": USER_AGENT },
})).then(value => {
if (controller.signal.aborted) {
void value.body?.cancel().catch(() => {});
throw timeoutError;
}
return value;
});
response = await Promise.race([request, aborted]);
if (!response.ok) throw new KimiMetadataProbeError(
[401, 402, 403].includes(response.status) ? "KIMI_AUTH_REJECTED" : "KIMI_PROVIDER_ERROR", response.status,
);
const declaredLength = response.headers.get("content-length");
if (declaredLength !== null && (!/^[0-9]+$/.test(declaredLength) || Number(declaredLength) > MAX_BYTES)) {
controller.abort();
throw new KimiMetadataProbeError("KIMI_METADATA_INVALID");
}
if (!response.body) throw new KimiMetadataProbeError("KIMI_METADATA_INVALID");
reader = response.body.getReader();
const chunks: Uint8Array[] = [];
let bytes = 0;
for (;;) {
const chunk = await Promise.race([reader.read(), aborted]);
if (controller.signal.aborted) throw timeoutError;
if (chunk.done) break;
bytes += chunk.value.byteLength;
if (bytes > MAX_BYTES) {
controller.abort();
throw new KimiMetadataProbeError("KIMI_METADATA_INVALID");
}
chunks.push(chunk.value);
}
let payload: unknown;
try { payload = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(Buffer.concat(chunks, bytes))); }
catch { throw new KimiMetadataProbeError("KIMI_METADATA_INVALID"); }
const contextLength = selectedModel(payload, model);
return { code: "kimi_metadata_verified", model, contextLength,
message: "Kimi Code accepted the selected credential and listed the exact selected model. No model prompt was sent; inference and remaining quota were not tested." };
} catch (error) {
if (error instanceof KimiMetadataProbeError) throw error;
throw new KimiMetadataProbeError(controller.signal.aborted ? "KIMI_METADATA_TIMEOUT" : "KIMI_PROVIDER_ERROR");
} finally {
clearTimeout(timer);
controller.signal.removeEventListener("abort", onAbort);
if (reader) {
void reader.cancel().catch(() => {});
try { reader.releaseLock(); } catch {}
} else { void response?.body?.cancel().catch(() => {}); }
}
}
@@ -0,0 +1,60 @@
import { createHash } from "node:crypto";
import { constants } from "node:fs";
import { lstat, open, readdir, realpath } from "node:fs/promises";
import { join } from "node:path";
export interface KimiRuntimeFile { path: string; sha256: string; size: number; executable: boolean }
const MAX_FILES = 30_000;
const MAX_FILE_BYTES = 384 * 1024 * 1024;
const MAX_TREE_BYTES = 1024 * 1024 * 1024;
const HASH_CONCURRENCY = 16;
const safePath = (path: string) => !/[\u0000-\u001f\u007f\\]/.test(path) && path.split("/").every(part => part !== "" && part !== "." && part !== "..");
export function kimiRuntimeClosureDigest(entries: readonly KimiRuntimeFile[]): string {
return createHash("sha256").update(JSON.stringify(entries)).digest("hex");
}
export async function inventoryKimiRuntimeFiles(root: string): Promise<KimiRuntimeFile[]> {
if (await realpath(root) !== root || !(await lstat(root)).isDirectory()) throw new Error("Kimi runtime root is not a physical directory");
const files: { path: string; size: number; executable: boolean }[] = [];
let total = 0;
const visit = async (directory: string, prefix = ""): Promise<void> => {
for (const name of (await readdir(directory)).sort()) {
const path = prefix ? `${prefix}/${name}` : name;
if (!safePath(path) || path.startsWith(".paperclip-") || path === "manifest.json") throw new Error("Kimi runtime contains an invalid path");
const absolute = join(directory, name);
const stat = await lstat(absolute);
if (stat.isSymbolicLink() || await realpath(absolute) !== absolute) throw new Error("Kimi runtime contains a symbolic link");
if (stat.isDirectory()) await visit(absolute, path);
else {
if (!stat.isFile() || stat.nlink !== 1 || stat.size > MAX_FILE_BYTES) throw new Error("Kimi runtime contains an invalid file");
total += stat.size;
if (files.length >= MAX_FILES || total > MAX_TREE_BYTES) throw new Error("Kimi runtime inventory exceeds its bound");
files.push({ path, size: stat.size, executable: Boolean(stat.mode & 0o111) });
}
}
};
await visit(root);
files.sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
const entries: KimiRuntimeFile[] = [];
for (let index = 0; index < files.length; index += HASH_CONCURRENCY) {
const batch = await Promise.allSettled(files.slice(index, index + HASH_CONCURRENCY).map(async entry => {
const path = join(root, entry.path);
const file = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
try {
const before = await file.stat({ bigint: true });
if (!before.isFile() || before.nlink !== 1n || before.size !== BigInt(entry.size) || Boolean(before.mode & 0o111n) !== entry.executable) throw new Error("Kimi runtime file changed before inventory");
const digest = createHash("sha256");
for await (const chunk of file.createReadStream({ autoClose: false })) digest.update(chunk);
const after = await file.stat({ bigint: true });
const named = await lstat(path, { bigint: true });
if (before.dev !== after.dev || before.ino !== after.ino || before.size !== after.size || before.mtimeNs !== after.mtimeNs || before.ctimeNs !== after.ctimeNs || named.dev !== before.dev || named.ino !== before.ino || named.isSymbolicLink()) throw new Error("Kimi runtime file changed during inventory");
return { path: entry.path, sha256: digest.digest("hex"), size: entry.size, executable: entry.executable };
} finally { await file.close(); }
}));
const failed = batch.find(result => result.status === "rejected");
if (failed?.status === "rejected") throw failed.reason;
for (const result of batch) if (result.status === "fulfilled") entries.push(result.value);
}
return entries;
}
@@ -7,6 +7,8 @@ import { isSupportedAcpxProfileVersion } from "./profile-compatibility.js";
// at 1. Update this table, with the reason, only for a deliberate reset.
const PROFILE_VERSIONS: Readonly<Record<string, number>> = {
antigravity: 1, claude: 1, codex: 1, copilot: 92, cursor: 17, grok: 20, pi: 37,
// Retain the existing pending Kimi revision; only its release attestation changes.
kimi: 16,
};
describe("ACPX profile versions", () => {
@@ -28,7 +30,7 @@ describe("historical ACPX profile decoding", () => {
}
});
it("does not decode a revision newer than the current one", () => {
for (const agent of ["copilot", "grok", "pi", "cursor", "antigravity"] as const) {
for (const agent of ["copilot", "grok", "pi", "cursor", "antigravity", "kimi"] as const) {
expect(isSupportedAcpxProfileVersion(agent, QUALIFIED_ACPX_PROFILE_DATA[agent].agentProfileVersion + 1)).toBe(false);
}
});
@@ -1,3 +1,4 @@
import { verifyKimiInstallation } from "./kimi-installation.js";
import { assertAcpxExecutionAdmission, type AcpxCandidateStartupAdmission } from "./candidate-admission.js";
import { assertCopilotCredentials, classifyCopilotFailure } from "./copilot-profile.js";
import { verifyCopilotInstallation } from "./copilot-installation.js";
@@ -12,6 +13,7 @@ import { verifyQualifiedAcpxInstallation, type VerifiedAcpxInstallation } from "
export async function verifyAcpxProfileInstallation(profile: QualifiedAcpxProfile, candidateAdmission?: AcpxCandidateStartupAdmission): Promise<VerifiedAcpxInstallation> {
assertAcpxExecutionAdmission(profile, candidateAdmission);
if (profile.agent === "antigravity") return verifyAntigravityInstallation(profile, candidateAdmission);
if (profile.agent === "kimi") return verifyKimiInstallation(profile);
if (profile.agent === "pi") return verifyPiInstallation(profile);
if (profile.agent === "copilot") return verifyCopilotInstallation(profile);
if (profile.agent === "cursor") {
@@ -35,6 +37,9 @@ export async function assertAcpxProfileWorkspace(agent: QualifiedAcpxAgent, work
/** Called with the sanitized launch environment, never ambient process.env. */
export function assertAcpxProfileEnvironment(agent: QualifiedAcpxAgent, environment: Readonly<NodeJS.ProcessEnv>): void {
if (agent === "copilot") assertCopilotCredentials(environment);
if (agent === "kimi" && !environment.KIMI_API_KEY?.trim()) {
throw Object.assign(new Error("Kimi Code credentials are missing. Bind a company secret to KIMI_API_KEY in the agent environment."), { code: "KIMI_CREDENTIALS_MISSING", retryable: false });
}
if (agent === "antigravity" && !environment.GEMINI_API_KEY?.trim() && !environment.PAPERCLIP_ACPX_ANTIGRAVITY_AUTH_JSON_SECRET?.trim()) {
throw Object.assign(new Error("Google Antigravity requires an explicitly bound Google runtime connection. Connect a Google account or Gemini API key before starting a task."), { code: "ANTIGRAVITY_CREDENTIALS_MISSING", retryable: false });
}
@@ -77,3 +82,8 @@ export async function probeAcpxPiInstallation(model: string): Promise<void> {
const installation = await verifyAcpxProfileInstallation(resolveQualifiedAcpxProfile("pi", model));
await (await installation.openCommand()).close();
}
export async function probeAcpxKimiInstallation(model: string): Promise<void> {
const installation = await verifyAcpxProfileInstallation(resolveQualifiedAcpxProfile("kimi", model));
await (await installation.openCommand()).close();
}
@@ -2,7 +2,7 @@ import { constants, closeSync, fstatSync, lstatSync, openSync, readFileSync, rea
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
import { fileURLToPath } from "node:url";
type NativeProvider = "cursor" | "copilot" | "pi" | "antigravity";
type NativeProvider = "cursor" | "copilot" | "pi" | "kimi" | "antigravity";
const RUNNER_PACKAGE_NAME = "@paperclipai/paperclip-runner";
const SERVER_PACKAGE_NAME = "@paperclipai/server";
function assertServerVendorLayout(root: string): void {
@@ -17,7 +17,7 @@ function assertServerVendorLayout(root: string): void {
/** Resolve only runner-owned package assets, including descriptor-loaded sidecars. */
export function resolveRunnerProviderAssetsRoot(moduleUrl: string, provider: NativeProvider): string {
if (!["cursor", "copilot", "pi", "antigravity"].includes(provider)) throw new Error("Unknown native ACP provider assets");
if (!["cursor", "copilot", "pi", "kimi", "antigravity"].includes(provider)) throw new Error("Unknown native ACP provider assets");
const boundRoot = process.env.PAPERCLIP_ACPX_PROVIDER_PACKAGE_ROOT;
const boundManifest = process.env.PAPERCLIP_ACPX_PROVIDER_PACKAGE_MANIFEST;
let packageRoot: string;
@@ -173,6 +173,7 @@ export interface AcpxRuntimePortOpenOptions {
stateDirectory: string;
providerSessionKey: string;
permissionMode: NativeAcpxPermissionMode;
readOnly?: boolean;
mode?: string;
piThinkingLevel?: PiThinkingLevel;
claudeEffort?: "low" | "medium" | "high" | "xhigh" | "max";
@@ -394,7 +395,7 @@ export class AcpxRuntimeHost {
grokEffort: resolveGrokEffort(options.agent, options.grokEffort),
grokDisableWebSearch: resolveGrokDisableWebSearch(options.agent, options.grokDisableWebSearch),
...(preconfigured || preparedHome ? { homeBinding: preconfiguredHomeEnvironment(options.environment) } : {}),
...(["cursor", "copilot", "pi"].includes(options.agent) && options.providerPolicy !== undefined
...(["cursor", "copilot", "pi", "kimi"].includes(options.agent) && options.providerPolicy !== undefined
? { providerPolicy: options.providerPolicy } : {}),
}),
dependencies.retainAdmissionCleanup,
@@ -558,7 +559,7 @@ export class AcpxRuntimeHost {
// agent and run. Environment/config values cannot widen the grant. Each
// resumed process receives the newly registered copy; collection already
// requires verified provider shutdown in the native executor.
const agentFiles = ["cursor", "copilot", "pi"].includes(options.agent)
const agentFiles = ["cursor", "copilot", "pi", "kimi"].includes(options.agent)
? bindAcpxAgentFiles(options.runtimeContext, [sandbox.root,
...(installation.agentServerPackageJsonPath === null ? [] : [dirname(installation.agentServerPackageJsonPath)]),
]) : null;
@@ -601,7 +602,7 @@ export class AcpxRuntimeHost {
PAPERCLIP_PI_READ_ROOTS: JSON.stringify([...(options.providerPolicy?.readRoots ?? []), ...skills.readRoots]),
});
}
if (!preconfigured && !preparedHome && (options.agent === "claude" || options.agent === "grok")) {
if (!preconfigured && !preparedHome && (options.agent === "claude" || options.agent === "grok" || options.agent === "kimi")) {
// The lifetime lease proves the previous provider has stopped. Refresh
// the assigned snapshot before every launch, including durable resume;
// Claude discovers user skills beneath its isolated CLAUDE_CONFIG_DIR.
@@ -666,6 +667,7 @@ export class AcpxRuntimeHost {
providerSessionKey: binding.profileSessionKey,
restoringSession: options.expectedIdentity !== undefined,
permissionMode: binding.permissionMode,
readOnly: options.providerPolicy?.readOnly,
mode: binding.mode,
piThinkingLevel: binding.piThinkingLevel,
claudeEffort: binding.claudeEffort,
@@ -1,3 +1,5 @@
import { kimiManagedConfiguration } from "./kimi-config.js";
import { kimiInstructionBinding } from "./kimi-instructions.js";
import { AGENT_OBSERVABILITY_ENV_KEYS, codexObservabilityToml } from "../agent-observability.js";
import { piProviderConfiguration } from "./pi-provider-config.js";
import { configuredEnvironmentKeys } from "../../configured-environment.js";
@@ -421,6 +423,9 @@ export async function prepareAcpxRuntimeSandbox(input: {
workspaceRecordPath,
`${input.binding.workspacePath}\n`,
);
if (input.agent === "kimi") {
await writePrivateFile(join(agentHomeDirectory, "config.toml"), kimiManagedConfiguration(input.binding.requestedModel));
}
if (input.agent === "pi") {
const configuration = piProviderConfiguration(input.environment);
if (configuration) await writePrivateFile(join(agentHomeDirectory, "models.json"), configuration.json);
@@ -533,6 +538,7 @@ export async function prepareAcpxRuntimeSandbox(input: {
XDG_CACHE_HOME: cacheDirectory,
PAPERCLIP_ACPX_PROFILE: input.agent,
PAPERCLIP_ACPX_ISOLATED_CONTEXT: "1",
...(input.agent === "kimi" ? { KIMI_CODE_HOME: agentHomeDirectory, PAPERCLIP_KIMI_INSTRUCTIONS: kimiInstructionBinding(policy.systemInstructions).payload } : {}),
...(input.agent === "antigravity" ? { GEMINI_HOME: agentHomeDirectory, AGY_ACP_FORCE_FILE_STORAGE: "1" } : {}),
...(input.agent === "grok" ? { GROK_HOME: agentHomeDirectory, NO_BROWSER: "1", GROK_DISABLE_AUTOUPDATER: "1" } : {}),
...(input.agent === "pi"
+2 -1
View File
@@ -1,6 +1,7 @@
export * from "./configured-environment.js";
export * from "./catalog/index.js";
export { CURSOR_DISTRIBUTION_PINS } from "./drivers/acpx/generated-profiles.js";
export { KIMI_DISTRIBUTION_CLOSURE_SHA256 } from "./drivers/acpx/kimi-closure-pins.js";
export * from "./contracts/control-plane-port.js";
export * from "./contracts/completion-result.js";
export * from "./contracts/codex.js";
@@ -101,7 +102,7 @@ export * as acceptedCapabilitySemanticTools from "./semantic-tools/index.js";
export * from "./compatibility.js";
export { probeAcpxClaudeInstallation, probeAcpxGrokInstallation } from "./drivers/acpx/installation-integrity.js";
export { probeAcpxPiInstallation } from "./drivers/acpx/profile-installation.js";
export { probeAcpxPiInstallation, probeAcpxKimiInstallation } from "./drivers/acpx/profile-installation.js";
export { PROVIDER_PACK_COMPATIBILITY, bundledRemoteProviderPackManifestPath, bundledRemoteRunnerBinary } from "./live/bundled-remote-provider-pack.js";
export { RunnerdMuseDriver, describeRunnerdMuseDriver, type RunnerdMuseDriverOptions } from "./drivers/muse/runnerd-muse-driver.js";
+3 -1
View File
@@ -9,6 +9,8 @@ export * from "./linux-process-start.js";
export { probeAcpxClaudeInstallation, probeAcpxGrokInstallation } from "../drivers/acpx/installation-integrity.js";
export { probeCopilotMetadata, validateCopilotMetadata, type CopilotMetadataResult } from "../drivers/copilot-metadata-probe.js";
export { probeAcpxCursorInstallation, probeAcpxPiInstallation } from "../drivers/acpx/profile-installation.js";
export { probeAcpxCursorInstallation, probeAcpxPiInstallation, probeAcpxKimiInstallation } from "../drivers/acpx/profile-installation.js";
export { probeKimiModels, KimiMetadataProbeError, type KimiVerifiedModelMetadata } from "../drivers/acpx/kimi-models.js";
export { probeKimiMetadata, validateKimiMetadata, kimiMetadataProbeDigest, kimiMetadataProbeNodeDigest, type KimiMetadataResult } from "../drivers/acpx/kimi-metadata-probe.js";
export { bundledRemoteProviderPackManifestPath, bundledRemoteRunnerBinary } from "./bundled-remote-provider-pack.js";
@@ -0,0 +1,37 @@
import { mkdtemp, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { describe, expect, it } from "vitest";
import { type AcpxCandidateAdmission } from "../drivers/acpx/candidate-admission.js";
import { KIMI_DISTRIBUTION_CLOSURE_SHA256 } from "../drivers/acpx/kimi-closure-pins.js";
import { resolveQualifiedAcpxProfile } from "../drivers/acpx/qualified-profiles.js";
import { createRunnerdCodexTransport } from "./runnerd-codex-transport.js";
const candidate = (remote = false): AcpxCandidateAdmission => ({ schema: "paperclip.acpx-candidate-admission.v1", companyId: "company-kimi", agent: "kimi", model: "kimi-for-coding",
profileDigest: resolveQualifiedAcpxProfile("kimi", "kimi-for-coding").commandDigest,
nativeClosureDigest: `sha256:${KIMI_DISTRIBUTION_CLOSURE_SHA256[remote ? "linux-x64" : "darwin-arm64"]}`,
platform: remote ? "linux" : "darwin", architecture: remote ? "x64" : "arm64", expiresAt: Date.now() + 60_000 });
describe("Kimi trusted qualification startup", () => {
it("retains exact provider and isolated home authority for a valid Kimi grant", async () => {
const root = await mkdtemp(join(tmpdir(), "kimi-candidate-startup-"));
try {
const options = { provider: "acpx" as const, acpxAgent: "kimi" as const, stateDirectory: root, acpxCandidateAdmission: candidate() };
for (const changes of [{ provider: "codex" as const }, { provider: "opencode" as const }, { homeMode: "preconfigured" as const },
{ acpxAgent: "copilot" as const }, { acpxCandidateAdmission: { ...candidate(), profileDigest: `sha256:${"f".repeat(64)}` } }]) {
expect(() => createRunnerdCodexTransport({ ...options, ...changes })).toThrow();
}
expect(() => createRunnerdCodexTransport({ ...options, acpxCandidateAdmission: undefined })).toThrow("evaluation opt-in");
} finally { await rm(root, { recursive: true, force: true }); }
});
it.each([false, true])("keeps ordinary Kimi warm transport capability under target-bound authority: remote=%s", async remote => {
const root = await mkdtemp(join(tmpdir(), "kimi-candidate-warm-"));
try {
const owner = createRunnerdCodexTransport({ provider: "acpx", acpxAgent: "kimi", stateDirectory: root,
acpxCandidateAdmission: candidate(remote), lifecyclePolicy: { mode: "warm", idleTimeoutMs: 1000 },
...(remote ? { runnerFilesystemRoot: "/owned-runner" } : {}) });
await owner.transport.close();
} finally { await rm(root, { recursive: true, force: true }); }
});
});
@@ -1245,7 +1245,7 @@ export interface CapabilityRunnerdCodexTransportOptions extends RunnerExecutionD
opencodePermissionMode?: NativeOpenCodePermissionMode;
acpxAgent?: QualifiedAcpxAgent;
/** Explicit evaluation-only candidate selection, never derived from persisted session input. */
acpxCandidateProfile?: "pi" | "cursor" | "copilot";
acpxCandidateProfile?: "pi" | "cursor" | "copilot" | "kimi";
/** Server/operator authority; never derived from persisted agent or provider input. */
acpxCandidateAdmission?: AcpxCandidateAdmission;
acpxPermissionMode?: NativeAcpxPermissionMode;
@@ -3097,7 +3097,7 @@ function acpxProviderPackageAuthority(
// Native provider closures belong to the runner package itself. Their asset
// guard requires the bound manifest directly inside that same package root;
// the workspace dependency root used by JS providers is a different owner.
if (agent === "copilot" || agent === "pi" || agent === "antigravity") {
if (agent === "copilot" || agent === "pi" || agent === "kimi" || agent === "antigravity") {
return {
root: sidecarPackageRoot,
manifest: resolve(sidecarPackageRoot, "package.json"),
@@ -3146,7 +3146,7 @@ function acpxRunnerLaunchProfile(
`sha256:${createHash("sha256").update(readFileSync(path)).digest("hex")}`;
let candidateAdmission: AcpxCandidateStartupAdmission | undefined;
if (options.acpxCandidateAdmission) {
if (!identity || options.runnerFilesystemRoot) throw new Error("ACPX candidate requires an actual local startup identity");
if (!identity || options.acpxCandidateAdmission.agent === "antigravity" && options.runnerFilesystemRoot) throw new Error("ACPX candidate requires an actual authorized startup identity");
candidateAdmission = bindAcpxCandidateAdmission(options.acpxCandidateAdmission, identity);
}
if (!options.runnerFilesystemRoot) {
@@ -3200,6 +3200,7 @@ function acpxRunnerLaunchProfile(
);
}
return {
...(candidateAdmission ? { candidateAdmission } : {}),
authorityDigest,
command,
commandSha256,
@@ -3392,7 +3393,7 @@ function createCapabilityRunnerdProviderEnvironmentBase(input: {
PAPERCLIP_ACPX_PROVIDER_PACKAGE_ROOT: providerPackageAuthority.root,
PAPERCLIP_ACPX_PROVIDER_PACKAGE_MANIFEST:
providerPackageAuthority.manifest,
...(!input.options.acpxCandidateAdmission && input.options.providerRecoveryPolicy ===
...(input.options.acpxCandidateAdmission?.agent !== "antigravity" && input.options.providerRecoveryPolicy ===
"allow_replacement_after_governed_wait"
? {
PAPERCLIP_ACPX_PROVIDER_RECOVERY_POLICY:
@@ -3685,18 +3686,21 @@ class DurablePrpCodexTransport implements CodexAppServerTransport {
}
if (options.acpxCandidateAdmission !== undefined) {
const candidate = options.acpxCandidateAdmission;
if (options.provider !== "acpx") {
throw new Error("ACPX candidate admission requires the exact ACPX provider");
}
const admitted = parseAcpxCandidateAdmission(candidate, { companyId: candidate.companyId, agent: options.acpxAgent ?? "", model: candidate.model });
this.options = { ...this.options, acpxCandidateAdmission: Object.freeze(admitted), providerRecoveryPolicy: "same_session_only" };
this.prepareConversationResume = params => this.#prepareCandidateConversationResume(params);
if (options.provider !== "acpx" || process.platform !== "darwin" || process.arch !== "arm64"
this.options = { ...this.options, acpxCandidateAdmission: Object.freeze(admitted), ...(candidate.agent === "antigravity" ? { providerRecoveryPolicy: "same_session_only" as const } : {}) };
if (candidate.agent === "antigravity") this.prepareConversationResume = params => this.#prepareCandidateConversationResume(params);
if (candidate.agent === "antigravity" && (options.provider !== "acpx" || process.platform !== "darwin" || process.arch !== "arm64"
|| options.runnerFilesystemRoot || options.prepareLaunch || options.runnerProcessLauncher
|| options.homeMode === "preconfigured" || options.lifecyclePolicy?.mode === "warm"
|| options.adoptExistingRunner || options.resumeActiveTurnId
) {
)) {
throw new Error("ACPX candidate admission supports only a fresh local isolated per-turn execution");
}
}
if (options.acpxCandidateAdmission && options.resumeProviderSession) {
if (options.acpxCandidateAdmission?.agent === "antigravity" && options.resumeProviderSession) {
const prior = options.resumeProviderSession;
const identity = record(prior.providerIdentity);
if (!prior.driverSessionId?.trim() || !prior.providerSessionId?.trim()
@@ -3709,7 +3713,7 @@ class DurablePrpCodexTransport implements CodexAppServerTransport {
if (options.provider === "acpx" && options.acpxAgent !== undefined
&& ACPX_CAPABILITY_PROFILES[options.acpxAgent].qualification === "pending"
&& options.acpxCandidateProfile !== options.acpxAgent
&& !(options.acpxAgent === "antigravity" && options.acpxCandidateAdmission)) {
&& !(options.acpxCandidateAdmission?.agent === options.acpxAgent)) {
throw new Error("The candidate ACPX profile requires explicit evaluation opt-in");
}
this.#failureSignal = new Promise<never>((_resolve, reject) => {
@@ -4268,7 +4272,10 @@ class DurablePrpCodexTransport implements CodexAppServerTransport {
this.#runAttachTemplate = structuredClone(runAttachTemplate);
const payload = {
...runAttachTemplate,
paperclipNextAuthority: { identity: desired, connection },
paperclipNextAuthority: { identity: desired, connection,
...(this.options.acpxCandidateAdmission?.agent === "kimi"
? { candidateAdmission: bindAcpxCandidateAdmission(this.options.acpxCandidateAdmission, desired) } : {}),
},
};
core.queueCommand("run.attach", payload, commandId, true);
// ACPX run attachment checkpoints the old sidecar and starts a fresh
@@ -5385,7 +5392,7 @@ class DurablePrpCodexTransport implements CodexAppServerTransport {
}
async #resumeWork(): Promise<void> {
if (this.options.acpxCandidateAdmission) throw new Error("ACPX candidate durable runner recovery is not admitted");
if (this.options.acpxCandidateAdmission?.agent === "antigravity") throw new Error("ACPX candidate durable runner recovery is not admitted");
const desiredIdentity = this.options.prpIdentity;
if (desiredIdentity === undefined) {
throw new Error("PRP provider resume state is unavailable");
@@ -0,0 +1,285 @@
# Kimi Code native boundary
Research date: 2026-10-28. These are source observations and deterministic
package checks. They are not authenticated Product E2E qualification.
The maintained runtime is **`@moonshot-ai/kimi-code@2.3.3`**, release commit
[`ec495f0`](https://github.com/MoonshotAI/kimi-code/releases/tag/%40moonshot-ai%2Fkimi-code%402.3.3).
It is a Node.js/TypeScript application distributed both as a packaged native
executable and an npm package. The Python
[`MoonshotAI/kimi-cli`](https://github.com/MoonshotAI/kimi-cli) repository was
archived on September 23, 2026. Its Wire 1.10 documentation does not describe
the maintained runtime's public interface. The new npm bundle is inspectable
JavaScript; its internal ACP/core/Klient packages are private workspace packages.
## Selected transport and instruction delivery
[`kimi acp`](https://github.com/MoonshotAI/kimi-code/blob/ec495f0/docs/en/reference/kimi-acp.md)
speaks stdio JSON-RPC ACP. The maintained alternative is the REST/WebSocket
[`kimi web`](https://github.com/MoonshotAI/kimi-code/blob/ec495f0/docs/en/reference/server-api.md)
server. ACP reuses the existing Runner integration and avoids owning a second
HTTP-server lifecycle.
Native `AcpServer.newSession` accepts the workspace, extra directories and MCP
servers; load/resume accept current ephemeral MCP configuration. It does not
accept system instructions. The ACP CLI only consumes its login/region flags;
ordinary `--agent-file` does not establish ACP instruction admission.
The owned patch in `scripts/patch-kimi-runtime.mjs` verifies the entire official
npm `dist/main.mjs` SHA-256 before matching each unique source anchor. The
materializer verifies the complete patched output hash. The embedded helper
uses a single canonical owned source string so the raw patcher and installed
esbuild provisioner produce identical native bytes. The patch reads one
bounded process-owned `PAPERCLIP_KIMI_INSTRUCTIONS` JSON snapshot, validates its
content digest and byte length, then removes that variable from the environment
inherited by tools. Exact literal bytes are appended after native profile
composition through `AgentProfileService.systemPrompt`.
The native requester uses `getSystemPrompt()` in `captureTurnRequestConfig`
and `createModelRequest`; compaction uses the same getter. A restored or
recomposed profile therefore still receives the current literal suffix.
At the ACP native-runtime binding callback, the live main-agent scope reads
its effective `getSystemPrompt()`. Only that readback produces the session
receipt returned by new/load/resume. The receipt carries the bound-content
digest/length and the effective native prompt digest/length. Runner must match
the response to the active request and connection before sending a prompt.
The receipt proves delivery; an authenticated behavior case remains required.
Relevant source: [`profileService.ts`](https://github.com/MoonshotAI/kimi-code/blob/ec495f0/packages/agent-core-v2/src/agent/profile/profileService.ts),
[`llmRequesterService.ts`](https://github.com/MoonshotAI/kimi-code/blob/ec495f0/packages/agent-core-v2/src/agent/llmRequester/llmRequesterService.ts),
[`server.ts`](https://github.com/MoonshotAI/kimi-code/blob/ec495f0/packages/acp-server/src/server.ts),
[`start.ts`](https://github.com/MoonshotAI/kimi-code/blob/ec495f0/packages/acp-server/src/start.ts).
## Capability and loss inventory
| Native capability | ACP boundary and release implication |
| --- | --- |
| Model selection | `session/set_config_option` with `configId: model` returns current `configOptions`; `session/set_model` returns `{}` and emits a config update. Require the exact model acknowledgment before a prompt. Model aliases and provider-native model IDs are separate config fields. |
| Thinking | Config option exposes declared effort values or on/off; unsupported values fail. It must be tested for the selected account/model before advertising it. |
| Tools | Start, streaming arguments, full input, result/error and file diffs are projected. Native `tool.progress` only projects status text; stdout/stderr/progress/custom updates are dropped. |
| Reasoning | Thinking deltas become ACP thought chunks. Apply the existing Runner reasoning visibility policy. |
| Assistant messages | Upstream ACP emits text without the native step identity, merging progress and final messages. Patch v5 forwards actual main-agent step UUID/start/end facts with their native finish reason. The provider projection preserves separate messages, clears tool-use progress from final selection, and rejects incomplete provenance. |
| Children | ACP subscribes only to the main agent. Native child activity, identity and usage are not preserved. Disable native delegation for the initial supported release. |
| Questions | `elicitation.form` carries all questions and multi-selection. Permission fallback drops every question after the first, converts multi-selection to single-selection, and cannot represent Other/free text. Do not advertise native questions from fallback parsing; semantic Paperclip questions require their own live continuation proof. |
| Plans | Todos become ACP plan updates. `ExitPlanMode` approvals use the permission channel and plan-specific options. Native plan review, feedback and post-accept behavior need separate qualification. |
| Permission | Native normal mode has auto-approval heuristics and prior approval rules. The managed patch asks Runner for every tool operation, includes the actual `toolInput` as `rawInput`, removes session-wide approval choices, and disables ambient hooks/MCP/profiles. |
| Usage | ACP's `usage_update.used` is current context occupancy and `size` is model capacity. It is not per-turn input/output usage or cost; cost is omitted. Internal Klient has richer token counters, but the selected ACP path does not publish them. Do not turn these context values into charges or a dollar-budget guarantee. |
| Failures | Upstream ACP maps non-auth failed turns to `end_turn`. The managed patch preserves typed auth failure and rejects every other native failed turn on the prompt RPC. |
| Continuity | New/load/resume/list/fork/close/delete are implemented. Load replays history; resume skips replay. A cold restore accepts fresh ephemeral MCP config; loading an already-live session ignores replacement MCP configuration. Reopen after a configuration change requires a new owned process. |
| Stop and shutdown | Native cancel is turn-addressed and handles launch races. ACP close cancels/disposes the session. Connection EOF starts a flush/dispose path. These implementations do not prove bounded process-tree cleanup; test spontaneous child/process loss and forced termination independently. |
| Steering | Native Klient and REST have steering/queued prompts. ACP has no steering method. Sending a second prompt does not prove same-turn steering. |
| Media | ACP advertises image and text embedded-resource support; blob resources are dropped and audio is unsupported. End-to-end Runner forwarding still needs its own proof. |
Source: [`session.ts`](https://github.com/MoonshotAI/kimi-code/blob/ec495f0/packages/acp-server/src/session.ts),
[`events-map.ts`](https://github.com/MoonshotAI/kimi-code/blob/ec495f0/packages/acp-server/src/events-map.ts),
[`interaction-bridge.ts`](https://github.com/MoonshotAI/kimi-code/blob/ec495f0/packages/acp-server/src/interaction-bridge.ts),
[`question.ts`](https://github.com/MoonshotAI/kimi-code/blob/ec495f0/packages/acp-server/src/question.ts),
[`approval.ts`](https://github.com/MoonshotAI/kimi-code/blob/ec495f0/packages/acp-server/src/approval.ts).
## Configuration and authority
An empty isolated `KIMI_CODE_HOME` does **not** make an ambient `KIMI_API_KEY`
usable automatically. A provider must explicitly declare `api_key_env`.
Use the selected provider endpoint and a configured model alias whose `model`
is the caller's exact native model ID. `max_context_size` is required by the
native schema; it is configuration metadata, not entitlement evidence.
Strip unselected `KIMI_MODEL_*` variables, which can synthesize a competing
provider/model. Do not import ambient OAuth credentials, MCP grants or hooks.
The managed patch keeps user skills only under the owned Kimi home and drops
project/global skill directories. It empties ambient workspace MCP baseline
while leaving ACP session MCP separate. Root configuration must disable
native delegation, cron/background task tools and automatic backgrounding;
keep-alive-on-exit stays off. Removing TaskList/TaskOutput/TaskStop makes native
`Bash.allowBackground()` false and causes explicit background requests to fail.
Native `HostProcessService.buildEnv()` otherwise inherits the complete provider
environment, including `KIMI_API_KEY`; Bash supplies only noninteractive
overrides. The patch always builds an explicit child environment and removes
`KIMI_API_KEY` and `PAPERCLIP_KIMI_INSTRUCTIONS` after merging overrides. The
native PTY path uses the same filter. Assigned task variables remain available;
the provider process retains its key for model authentication. This is a child
environment boundary, not an operating-system sandbox for arbitrary native
filesystem or shell tools. Read-only work must use the controller's scoped
semantic tools.
Patch v4 also ignores the ACP client's terminal capability. Otherwise native
`AcpProcessService` sends Bash to ACPX's separate terminal process, bypassing
the provider-owned environment filter and dropping configured task variables.
Keeping the existing native local process service makes the filter apply on
the actual Runner execution path. The controlled-peer check requires ACPX to
advertise its normal terminal capability while observing zero `terminal/create`
requests from Kimi.
Native OAuth resolves the access token into the same `{ apiKey }` credential
as an explicit API-key provider. A selected unexpired access token can bound
a finite test, but that explicit binding has no OAuth refresh behavior. Never
copy refresh tokens into qualification homes or describe this as managed
OAuth support.
The setup Test can verify Code metadata without inference through
`probeKimiModels(model, apiKey)`. It sends one GET to the fixed global
`https://api.kimi.ai/coding/v1/models` endpoint, using the explicitly selected
key and pinned `KimiCLI/2.3.3` user agent. Native Kimi uses this endpoint for
both OAuth and API-key providers and treats HTTP 401/402/403 as credential or
membership-access failures. The probe requires a valid model catalog with the
exact caller-selected ID and positive context metadata. It never substitutes a
model or imports an ambient credential. Redirects are rejected, streamed JSON
is capped at 256 KiB, and the eight-second deadline aborts both the request and
response body. Errors contain fixed messages and typed codes, not provider
response text or credential values.
A successful metadata probe establishes catalog authentication and exact model
listing. It does not establish successful inference, remaining quota, usage or
charges. The native ACP catalog alone cannot establish authentication because
it projects local configuration. Normal model and instruction admission still
applies before a task prompt.
Source: [`overrides.md`](https://github.com/MoonshotAI/kimi-code/blob/ec495f0/docs/en/configuration/overrides.md),
[`config-files.md`](https://github.com/MoonshotAI/kimi-code/blob/ec495f0/docs/en/configuration/config-files.md),
[`credentials.ts`](https://github.com/MoonshotAI/kimi-code/blob/ec495f0/packages/agent-core-v2/src/human/credentials/credentials.ts),
[`bashTool.ts`](https://github.com/MoonshotAI/kimi-code/blob/ec495f0/packages/agent-core-v2/src/agent/tools/os/bash/bashTool.ts),
[`hostProcessService.ts`](https://github.com/MoonshotAI/kimi-code/blob/ec495f0/packages/agent-core-v2/src/os/backends/node-local/hostProcessService.ts),
[`hostTerminalService.ts`](https://github.com/MoonshotAI/kimi-code/blob/ec495f0/packages/agent-core-v2/src/os/backends/node-local/hostTerminalService.ts),
[`acpConnection.ts`](https://github.com/MoonshotAI/kimi-code/blob/ec495f0/packages/acp-server/src/acp-fs/acpConnection.ts),
[`acpTerminalRunner.ts`](https://github.com/MoonshotAI/kimi-code/blob/ec495f0/packages/acp-server/src/acp-terminal/acpTerminalRunner.ts),
[`managed-kimi-code.ts`](https://github.com/MoonshotAI/kimi-code/blob/ec495f0/packages/oauth/src/managed-kimi-code.ts),
[`refreshProviderModels.ts`](https://github.com/MoonshotAI/kimi-code/blob/ec495f0/packages/oauth/src/refreshProviderModels.ts).
## Reproducible boundary check
From a clean verified npm installation, provide its unmodified `dist/main.mjs`
to the package contract cell:
```sh
PAPERCLIP_KIMI_VENDOR_MAIN=/absolute/path/to/dist/main.mjs \
node --test packages/paperclip-runner/scripts/patch-kimi-runtime.test.mjs
```
This executes the actual pinned getter and ACP lifecycle/error methods with
engine/transport dependencies doubled. It verifies literal Unicode/whitespace,
explicit empty content, native readback, create/load/resume receipts, missing
receipts, ambient-source isolation, host permission delegation, malformed
bindings, child environment filtering, esbuild bundle reproducibility and
terminal failure mapping. It performs no inference and does not
replace installed-package, authenticated semantic-tool, browser persistence,
warm recovery or physical-cleanup acceptance.
## Controlled model-service regression
After installing the fixed runtime assets, a second opt-in cell runs the real
pinned Kimi command through the real ACPX manager against a loopback-only,
scripted OpenAI-compatible service and MCP receiver:
```sh
PAPERCLIP_TEST_KIMI_MODEL_PEER=1 \
node --test packages/paperclip-runner/scripts/patch-kimi-runtime.test.mjs
```
The test changes only its private native test configuration below the production
boundary. It does not add an endpoint override to production configuration, use
a provider credential, or call an external model. It captures exact instruction
bytes at the native HTTP request, fragmented/interleaved MCP JSON including a
terminal `{}`, accepted tool results in the next model request, Write denial
before any file effect, a native Bash credential fence, typed provider failure,
new/resume admission and bounded owned-process closure. The production patch
keeps Bash in the provider's own local process service even when ACPX advertises
client terminals. ACPX prefers `session/resume` when advertised; the
installed-runtime metadata smoke checks `session/load` separately.
The first controlled-peer attempt against patch v1 failed: the native blocking
approval payload omitted `toolInput`, although a sibling native event carried
it. The ACP callback therefore lost `rawInput`, and the strict host rejected
the operation before the MCP receiver ran. That failure is retained as the
reason for patch v2: add the original arguments at native `approvalRequest`
construction before the interaction kernel, then preserve them at the ACP edge.
An empty object remains a complete valid argument. A passing simulated service
cell remains protocol-boundary evidence and does not qualify model behavior,
account entitlement, browser journeys or Daytona delivery.
The v2 controlled-peer cell passed on 2026-10-28 against the verified
`darwin-arm64` closure through the actual pinned ACPX manager: five simulated
model requests, two accepted MCP receiver calls including `{}`, one denied
Write with independent before/after file-absence checks, typed failed-turn
settlement and two closed native processes. Both initial and resumed native
acknowledgments matched the SHA-256 of the complete system prompt observed at
the HTTP request. Permission response-delivery receipts settled. This cell
uses fake credentials and records zero external model calls.
The v3 Bash regression exposed the ACP client-terminal bypass: native filter
unit checks passed, but normal ACPX terminal execution lost the assigned task
variable and did not exercise that filter. V4 therefore forces the native local process path.
The extended cell checks both key/private-variable absence and task-variable
presence in real Bash, while every native model HTTP request must retain the
fake provider authorization. Earlier v2 evidence remains valid for its narrower
instruction/MCP/denial/error scope; the credential fence requires v4 evidence.
The final v4 native runtime passed the seven-request controlled-peer cell on
2026-10-28. ACPX advertised its normal client-terminal capability, Kimi sent zero
`terminal/create` requests, and native Bash returned its success marker only
after verifying both private variables were absent and an assigned task variable
was retained. All seven model requests still carried the fake provider key.
The exact native SHA-256 was
`cfd11b57b3d75419539bd16f237d73d9ca896d45ae41bbfed8c71beab4daaee9`;
the verified macOS closure was
`c05a0cd0686a4988fed6cb3c69ca1d9845ea233c53b391a84bc442241cef551b`.
Enable the additional pending-work lifecycle checks with:
```sh
PAPERCLIP_TEST_KIMI_MODEL_PEER=1 PAPERCLIP_TEST_KIMI_LIFECYCLE_PEER=1 \
node --test --test-name-pattern='simulated local model service' \
packages/paperclip-runner/scripts/patch-kimi-runtime.test.mjs
```
The extended nine-request cell also passed on 2026-10-28. Both cases held a real
native Write approval before any file effect. Stop settled as cancelled. For
spontaneous provider loss, the test observed the unique native worker beneath
its verified command root and revalidated its parent, process start and group
before sending SIGKILL to that worker. It settled as a typed failure. Both cases
aborted the waiting host callback, suppressed a subsequently supplied stale
`allow_once` response on that exact connection, and produced no file or further
model request. The test independently checked file absence after settlement and
cleanup, and observed physical worker retirement within five seconds. Four
owned native processes closed across the complete cell. These remain simulated
service proofs; they do not qualify authenticated behavior, browser journeys or
Daytona delivery.
## Message-boundary regression
The first completed local Product attempt on 2026-10-28 exposed an upstream
ACP framing loss. Campaign `local-2026-10-28T13-43-42-062Z` reached an accepted
completion report and durable Done state, but the displayed final comment
concatenated a pre-tool progress message with the final answer. The attempt
remains failed; completion state alone is insufficient user-facing acceptance.
The engine already emits `TurnStepStarted` and `TurnStepCompleted` with the
real model-step UUID and normalized finish reason. The owned v5 patch registers
those existing events in Klient's agent event hub and subscribes through the
same active-turn dispatch gate as text deltas. Each message ID hashes the
native session, turn and step UUID. Empty start/end chunks carry bounded
provenance; text and reasoning deltas use the same identity. Public interrupted
step events close only the matching active step. No text inspection or tool
notification creates a message boundary. Restored history remains outside the
active prompt event stream.
Source: [`loopService.ts`](https://github.com/MoonshotAI/kimi-code/blob/ec495f0/packages/agent-core-v2/src/agent/loop/loopService.ts),
[`turnEvents.ts`](https://github.com/MoonshotAI/kimi-code/blob/ec495f0/packages/agent-core-v2/src/agent/loop/turnEvents.ts),
[`Klient events.ts`](https://github.com/MoonshotAI/kimi-code/blob/ec495f0/packages/klient/src/contract/agent/events.ts).
The v5 nine-request controlled-peer check passed in 13.4 seconds on 2026-10-28
against native SHA-256
`9ea2cf23ed4a7386de7f01147d5f7c83719568d814b9d6e1d5ebb43ca3067d86`
and verified macOS closure
`429433e76fc8889b2262b3d0739bc955e80d958da4a9aa378653d6690030c2ef`.
Each ordinary simulated turn emitted a pre-tool message ending in `tool_use`
and a separate UUID for the final message ending in `end_turn`, even though
the scripted HTTP service deliberately reused its response ID. Actual ACPX
normalization retained every empty boundary. The real provider projection
validated the native provenance and returned canonical `toolUse` and `stop`
boundaries. The same check repeated instruction admission, MCP arguments and
results, the child credential fence, denial without effects, typed failure,
pending permission Stop, exact native-worker loss, stale-answer suppression
and bounded physical cleanup. Four owned native processes retired; there were
zero external model calls. This does not replace the failed Product attempt
or prove its browser journey passed after the fix.
@@ -0,0 +1,52 @@
{
"commandDigest": "sha256:00ce5ecc7f0e904811b70584b936c673182c1029b500e8d4823f44ae3cd755e2",
"declaration": {
"schema": "paperclip.acpx_profile_declaration.v1",
"agent": "pi",
"agentProfileVersion": 35,
"acpxVersion": "0.13.1",
"agentServerVersion": "0.0.33",
"agentRuntimeVersion": "1.0.0",
"nodeVersion": "24.21.0",
"closure": {
"darwin-arm64": "282022db10150c6632b3444df421342e7d534bdf5d5fb1097a2e79d0625a2bcf",
"darwin-x64": "64e251e19009f755c0b04f73ce2138246faab71a961b0f13d75ebfcc34bef12e",
"linux-x64": "713b1fdff42fb56a1518bdc084f181d70bee8ebadc3e4b1d76321ed9108c8410"
},
"wrapperSha256": "9d129b3d38772e93e97080aa6c4e574ac5df4e47ce5bc331a484a9fbf8188b36",
"helperSha256": "41e0490b617da0d60e0c8ec58ef311236f945129d99f816cff6897f78da7f91d",
"extensionSha256": "f5818573a355702388072b28926897db546a5cf346b5171f646582ce5f9102a4",
"agentFilesBinding": "registered-runtime-context-v1",
"nativeQuestions": "select-confirm-input-editor-v4-root-field-types",
"pathPolicy": "sdk-normalization-v1",
"mcpToolNames": "provider-safe-exact-source-v1",
"acpxPatchSha256": "1e7dae8c83bf8620f53f2bea13c175eeff95e7e955783f6f529bb1dcbdcdb6d2",
"nativeAssistantMessages": "pi1-rpc-deltas-v3-bound-message-and-tool-receipts",
"nativeNotices": "session-extension-v2-bounded-runtime-failure",
"messageProjectionSha256": "17d1e91b948dfa6a56e1905645add52b502041ad843c8d50a13b07956f22aadd",
"noticeProjectionSha256": "014485adc690998e395d334ea3ae67f72be6060a2fc78a1185df7b8d1da28fbf",
"sharedRuntimeContract": "paperclip.acpx-runtime-contract.v1",
"nativeInputDisposition": "queued-only-v1",
"cacheWarming": "disabled-owned-decision-v1",
"thinkingLevel": {
"supported": [
"off",
"low",
"high",
"max"
],
"newConfigurationDefault": "low",
"admission": "explicit-native-effective-before-prompt-v1",
"recovery": "mode-bound-v1"
},
"modelSelection": "caller-selected-native-verified-v1",
"providerConfigurationSourceSha256": "75a9a13f13f224dc092bd8ebf49e8747162172943761e44476c8eb18d80c52d4",
"credentialEnvironmentSourceSha256": "a6733e28a9468b744e1e72f1af0c2236e17372e51a9a3ba254a406e085591d2d",
"runtimeSandboxSourceSha256": "d631dc7a3554c5eb4ed47bef966007245a133862277c96011b1fe1639135f59d",
"recoveryIdentitySourceSha256": "f74d061cc07b0c7ca04df62ca991d940a733d9ef6594b3362451769fc10030b8",
"nativeCancellation": "acknowledged-cancelled-terminal-preserves-usage-v1",
"dependencySecurityPatchSha256": "5273a195b952f233336122842faaf650193c04f36b9359d20d4d63079b0ce814",
"openRouterAttributionSourceSha256": "1211191529d6073b733b311c3d69cada4973eede0f3e540c46e261f78e0b90f9",
"preparedHarnessHomeSourceSha256": "bb286f7ddc6e9597c56d46bf7ff6e3b556c5b680d7e147fd46518724432b083e"
}
}
@@ -0,0 +1,52 @@
{
"commandDigest": "sha256:5186e5acd48dd5f951ee62656be9e266d05e880127fb1d8d6f26161e444770af",
"declaration": {
"schema": "paperclip.acpx_profile_declaration.v1",
"agent": "pi",
"agentProfileVersion": 36,
"acpxVersion": "0.13.1",
"agentServerVersion": "0.0.33",
"agentRuntimeVersion": "1.0.0",
"nodeVersion": "24.21.0",
"closure": {
"darwin-arm64": "282022db10150c6632b3444df421342e7d534bdf5d5fb1097a2e79d0625a2bcf",
"darwin-x64": "64e251e19009f755c0b04f73ce2138246faab71a961b0f13d75ebfcc34bef12e",
"linux-x64": "713b1fdff42fb56a1518bdc084f181d70bee8ebadc3e4b1d76321ed9108c8410"
},
"wrapperSha256": "9d129b3d38772e93e97080aa6c4e574ac5df4e47ce5bc331a484a9fbf8188b36",
"helperSha256": "41e0490b617da0d60e0c8ec58ef311236f945129d99f816cff6897f78da7f91d",
"extensionSha256": "f5818573a355702388072b28926897db546a5cf346b5171f646582ce5f9102a4",
"agentFilesBinding": "registered-runtime-context-v1",
"nativeQuestions": "select-confirm-input-editor-v4-root-field-types",
"pathPolicy": "sdk-normalization-v1",
"mcpToolNames": "provider-safe-exact-source-v1",
"acpxPatchSha256": "1e7dae8c83bf8620f53f2bea13c175eeff95e7e955783f6f529bb1dcbdcdb6d2",
"nativeAssistantMessages": "pi1-rpc-deltas-v3-bound-message-and-tool-receipts",
"nativeNotices": "session-extension-v2-bounded-runtime-failure",
"messageProjectionSha256": "17d1e91b948dfa6a56e1905645add52b502041ad843c8d50a13b07956f22aadd",
"noticeProjectionSha256": "014485adc690998e395d334ea3ae67f72be6060a2fc78a1185df7b8d1da28fbf",
"sharedRuntimeContract": "paperclip.acpx-runtime-contract.v1",
"nativeInputDisposition": "queued-only-v1",
"cacheWarming": "disabled-owned-decision-v1",
"thinkingLevel": {
"supported": [
"off",
"low",
"high",
"max"
],
"newConfigurationDefault": "low",
"admission": "explicit-native-effective-before-prompt-v1",
"recovery": "mode-bound-v1"
},
"modelSelection": "caller-selected-native-verified-v1",
"providerConfigurationSourceSha256": "75a9a13f13f224dc092bd8ebf49e8747162172943761e44476c8eb18d80c52d4",
"credentialEnvironmentSourceSha256": "9ace39a71ba287838c1b9c56bed141248e805fd017eb8490770c3b579567e55b",
"runtimeSandboxSourceSha256": "86dcc0abbbe2e32f88febbbab22f662d8490d438a9e9cb5df04589fdf66ebd88",
"recoveryIdentitySourceSha256": "f74d061cc07b0c7ca04df62ca991d940a733d9ef6594b3362451769fc10030b8",
"nativeCancellation": "acknowledged-cancelled-terminal-preserves-usage-v1",
"dependencySecurityPatchSha256": "5273a195b952f233336122842faaf650193c04f36b9359d20d4d63079b0ce814",
"openRouterAttributionSourceSha256": "1211191529d6073b733b311c3d69cada4973eede0f3e540c46e261f78e0b90f9",
"preparedHarnessHomeSourceSha256": "bb286f7ddc6e9597c56d46bf7ff6e3b556c5b680d7e147fd46518724432b083e"
}
}
@@ -0,0 +1,89 @@
{
"commandDigest": "sha256:e0eddf258e824bb0cd7e0ec0a12dc5b8eeff72262e176249b5e6e7d5ea977caf",
"declaration": {
"schema": "paperclip.acpx_profile_declaration.v1",
"agent": "copilot",
"agentProfileVersion": 82,
"acpxVersion": "0.13.1",
"agentServerVersion": "1.0.88",
"protocolPolicyRevision": "copilot-agent-manual-v1",
"acpxPatchSha256": "1e7dae8c83bf8620f53f2bea13c175eeff95e7e955783f6f529bb1dcbdcdb6d2",
"policySha256": "a4be69be43db84052560420a3ca546a665c9165573c24d543eb33d144ba138a3",
"distributionSourceSha256": "c0a65e247fc47b263bd369a3d5ab505c4b323d4e6493be8a9ecbeb0e9dbb9107",
"agentFilesBinding": "registered-runtime-context-v1",
"systemInstructionDelivery": "COPILOT_HOME/copilot-instructions.md:replace-under-lifetime-lease-before-launch:v1",
"sharedRuntimeContract": "paperclip.acpx-runtime-contract.v1",
"innerDistributionSourceSha256": "9bb08347eed01f1ab44e065c8b06ead9be3a25973d6e6329dc4c0a099096279a",
"upstreamAppSha256": "7b48282a19b5b0814a0c96ad5e3a125173d792cc55f9525b2effea962f6063c0",
"patchedAppSha256": "61f8eebe0c30cc03b311c6818b2acb158a6d16ca58c8bfac5ebd42db095c2679",
"messageIdentityContract": "copilot-native-message-id-v1",
"ownedDistributionDelivery": "COPILOT_CLI_DIST_DIR:lease-owned-guarded-inner-distribution:v1",
"permissionContextContract": "copilot-edit-permission-context-v1",
"permissionContextSourceSha256": "14791781934eb8d91c2a304e257fdb8c7825ae3a40c2bd44fd149c7492470852",
"permissionAdapterSourceSha256": "444482de2abb23d9c9c39a3a93bc9b27af241db56f8329e9935bb5b603c08ae0",
"permissionLocationsSourceSha256": "f39a81da395b6e23aa2a1a45572a28846e5e81bfd3d764d9a456f74a79c752e9",
"permissionRedactionSourceSha256": "ad6770c69269087951790e2e87e22ac088e3d432769adf17ebc865ed512e6c4f",
"permissionClassifierSourceSha256": "1161eabd82e26133e3b3db3ab567f65d52808b03f176e93497e02c8330349fb4",
"semanticToolReceiptContract": "paperclip.semantic_tool_receipt.v2",
"semanticReceiptSourceSha256": "b2795726b2234a663fec1a6ca11f0551ae69882fe9e82aa39686e952d036e791",
"semanticBridgeSourceSha256": "8764b8c9032fdc7d1415b01e75a9fc57c550e7a5e11da4bed7d9100082872ae5",
"toolEvidenceSourceSha256": "6eef5039afc75bb851eaf9cd82a6f099e4bd398ca2deb59dd66f5b2a81a7a706",
"semanticNormalizedInputContract": "validated-forwarded-input-commit-v1",
"semanticSidecarSourceSha256": "152ec3e5066695c7a28b56cb9b4d5fbd30500c8e7beee54efb9a33fc8a532c9d",
"semanticDirectDriverSourceSha256": "9ee8f25f1ebcd44af15f12a46e5735980083672cd317f44cd10cf2e77699e352",
"semanticValidationSourceSha256": "02fbb92681c78c5de5d2f1aae25aabc25a0e5df6b0ff4baccac652192a8da975",
"semanticNormalizationSourceSha256": "8b628b82e8eacc91cdcc6fdca2210ba4cf282f01e9c6f74e95ff271655b5047e",
"semanticCompletionContractSourceSha256": "f49398b682a5623812f5d3c33d6bb9a749008e47cc0ed969072041615f66df59",
"semanticValidatorsSourceSha256": "b20ec8ee6e7165117233ce4421a975bb9d3f276220ce31655c0b9a717cb2d9cb",
"semanticSchemaBundleSourceSha256": "81ef98ca7b34896a0f76390ac7af3dd8ef7609fe6f38d54bd6a69373d50fe40b",
"semanticSidecarProtocolSourceSha256": "26dd0cfbef8b2b401de6b7862a4af7f243fb703e23678a1a5ed8fa68d4784d42",
"semanticSidecarReceiptCommitContract": "correlated-tool-resolve-v1",
"displayEventSourceSha256": "d72f9a6035c247bc6a42c067c05753076c54322c4b58984e93922f3325dc6877",
"displayProjectionSourceSha256": "75952606b26dd93bbc582c1f0a4424487377272ea745fb3a27ceae031fd5dc7e",
"configuredEnvironmentSourceSha256": "a872e5b939c496955615ce87889ad27eb1ba2a9d8fc25e6bb74e03b1c2293feb",
"configuredEnvironmentRustSourceSha256": "fef93985d703f6b484e58746df5c93d60cb95c085fbf5de1af557913358e900d",
"profileActivitySourceSha256": "4fdb6b0f9125fd8372ba6f27945fa5c8a3d3b2ec891df544092e3dc7a75d5282",
"profileExtensionsSourceSha256": "a80ddc95eb4505095bfdbbf85c758199949ab20be9c84b34c77f762eb7180571",
"profileInstallationSourceSha256": "4af2280930d6382ff4acef6a09515050991746d8ad5358705f536227d548555f",
"attachmentPolicySourceSha256": "e07e2dbc1fdb6895165f2433d1e9627e37cb3d3ad94a8c9601b4b9cafbc44b17",
"singleReadEvidenceSourceSha256": "4069393405089bde613cecec04f5123c426594811da4c668bd96f0e7e283550f",
"nativeSessionRuntimeSourceSha256": "1fe6fa9e6b96d84d70432b85a57c473f833606d4a521563d5022b4d3c41576ce",
"nativeRuntimeContextSourceSha256": "71607f80dbb8dc5cc6c123d0b8f3995d6c5407277695a8c82cbedc90fb8f4842",
"nativeRuntimePromptsSourceSha256": "fff5755dba9b7dce8a5f10ff6ac6d5ed06b92ed079ce1e0a44ac72f2ce7869c1",
"nativeSessionContractSourceSha256": "22a8c96ce41ba4f03e976fc37f0cc7c5d05cee99fa789941da31ee1dab440b90",
"harnessSessionContractSourceSha256": "baba1a210b863518f01e0c875606ed37f9467c433222251438578bd999bc43b5",
"harnessBackendSourceSha256": "dc827e281ae6731545b166ee4d709a4f67f594a556dcbe63c70fe8f1aca26249",
"harnessSessionSourceSha256": "81361733e86b56dd5a66415aefc6f72e69be24acc8d3417370154ebb7fef6e94",
"transportContractSourceSha256": "03fca93d36a89b0cc0917335e293ad097fdf04356d21b307827bb0ea4c13f523",
"nativeBackendSourceSha256": "7495d9898d22dca1ebf6336361d332bafefc4498f6e49f1135025fad846c8586",
"nativeBackendFactorySourceSha256": "7e431c926b76d53c4c08e3a4105353dcd34bd940f6588a1a68f79631f6feeb44",
"nativeInstructionsSourceSha256": "82ac6e5f7275b4ef79fb166c7330efc504e80cab3d7e9081e4e40a8b570bc50b",
"providerLaunchSourceSha256": "c744235b3067ea75973523f78f1e13399337bc155f1775af694e34782d5c9bef",
"launchPreparationStoreSourceSha256": "ff6025568bbc0aa6ce545772d73dfca2d3da226740bd3a7b386b069e76cff296",
"runtimeRequestBridgeSourceSha256": "55aec95e7c7f204454cbd2961e4ee7e7507851da99f0ced899b61154333ae927",
"runtimeRequestFacadeSourceSha256": "d0ed28e0c5ddad34db8f437e704c8a755eb0b47f27e08e44185f66d1d2205295",
"runtimeRequestNotificationSourceSha256": "6196c6175f11c69295dc00fc773201f4fdeca26c500653870253c43b81e65211",
"guardedInstallationSourceSha256": "56a177d3e702914818dca4ca50e061f0d25f988bfc4c0582c36ce23c1696d82f",
"nativeExecutionSourceSha256": "927b98c90f482cd10ce66fe6730ecd91eb3854935fe6f454b4898da726c0fd69",
"profileCompatibilitySourceSha256": "addf190c6b561d48cbc013ba08326e9d922e49e6adc3fa4460d1fb733b06f6bb",
"installationSourceSha256": "a1c7c6f103b898216973e77ffbac0ef7572e250aa574d1a4065270e9dfa0dc2d",
"assetOwnershipSourceSha256": "b4e8c5b4e2c1757bcbf2049b5cb013723876168c00c24c28048fc80c7ca16ace",
"assetInstallerSourceSha256": "d3bd9514e5920d0cc3567aa50487fb534c57a6f66b8da0d3f22c5f6e499c841f",
"credentialBindingSourceSha256": "a6733e28a9468b744e1e72f1af0c2236e17372e51a9a3ba254a406e085591d2d",
"admissionDiagnosticsSourceSha256": "df8f1aa4f2d1bc63b2635bdd09cb8165c8b7681ddcc2618435c7c08ca90475af",
"grokAdmissionSourceSha256": "f1e46cf2e1e36b7704bd797b678e3db8db2003f97bdb9d827cfa3d7662698777",
"sidecarErrorSourceSha256": "17948ad74350dc487ab20d24a0fb89daf0b426b98396454fff0e3856e922d82c",
"profileSourceSha256": "f5538b3dbefa7634a332b87d5ededcefb56aa7e5790cede1c7a0d948a548a456",
"metadataProbeSourceSha256": "be4c8416edd27061109bc1f33d0c26071b4facbb3f651beaae6b3c0275cce727",
"nativeEditContextSourceSha256": "7be0bd911bc6bb3587e57d25ab5e75a961801ad0c58f06e713dd64cfe17a3c43",
"permissionToolIdentitySourceSha256": "770b47305e571a81f344883057d0e4a482a1cd59ac77d045836593a8e739deb1",
"semanticContinuationSourceSha256": "c9cc0fd516b3df92a6655f56ee9bef37615a889c371e2e137d8ac5c1176de811",
"preparedHarnessHomeSourceSha256": "bb286f7ddc6e9597c56d46bf7ff6e3b556c5b680d7e147fd46518724432b083e",
"runtimeHostSourceSha256": "981a18aad23e34c3c675123d1dd0a920748821bad88885bb1a2e1a060c870921",
"runtimeAdapterSourceSha256": "601cbfe4e2811f771a3a59bf23fdbb05e33a04901af987f2ff96a8acf56374a3",
"runtimeSandboxSourceSha256": "d631dc7a3554c5eb4ed47bef966007245a133862277c96011b1fe1639135f59d",
"cancellationSourceSha256": "a07d1a9e982dec0ae130c1ad1efa5bc75c6a39e013b730ba3ee45256f09ceeca",
"agentFilesSourceSha256": "fb32f6badc13dfa22f231479509b631b2f0eba0c99b1ab9f3cd5c0c601aa03ba",
"nativeDistributionSourceSha256": "aed327c389e957483a503cb1bb8b247ee7cd7ff4b528fb4567c39bcb4577690b"
}
}
@@ -0,0 +1,89 @@
{
"commandDigest": "sha256:4cecc2ba4bc9674fbc6f585d81934789a98b75a36f074dfe2b40391ae9ef8a19",
"declaration": {
"schema": "paperclip.acpx_profile_declaration.v1",
"agent": "copilot",
"agentProfileVersion": 83,
"acpxVersion": "0.13.1",
"agentServerVersion": "1.0.88",
"protocolPolicyRevision": "copilot-agent-manual-v1",
"acpxPatchSha256": "1e7dae8c83bf8620f53f2bea13c175eeff95e7e955783f6f529bb1dcbdcdb6d2",
"policySha256": "a4be69be43db84052560420a3ca546a665c9165573c24d543eb33d144ba138a3",
"distributionSourceSha256": "c0a65e247fc47b263bd369a3d5ab505c4b323d4e6493be8a9ecbeb0e9dbb9107",
"agentFilesBinding": "registered-runtime-context-v1",
"systemInstructionDelivery": "COPILOT_HOME/copilot-instructions.md:replace-under-lifetime-lease-before-launch:v1",
"sharedRuntimeContract": "paperclip.acpx-runtime-contract.v1",
"innerDistributionSourceSha256": "9bb08347eed01f1ab44e065c8b06ead9be3a25973d6e6329dc4c0a099096279a",
"upstreamAppSha256": "7b48282a19b5b0814a0c96ad5e3a125173d792cc55f9525b2effea962f6063c0",
"patchedAppSha256": "61f8eebe0c30cc03b311c6818b2acb158a6d16ca58c8bfac5ebd42db095c2679",
"messageIdentityContract": "copilot-native-message-id-v1",
"ownedDistributionDelivery": "COPILOT_CLI_DIST_DIR:lease-owned-guarded-inner-distribution:v1",
"permissionContextContract": "copilot-edit-permission-context-v1",
"permissionContextSourceSha256": "14791781934eb8d91c2a304e257fdb8c7825ae3a40c2bd44fd149c7492470852",
"permissionAdapterSourceSha256": "444482de2abb23d9c9c39a3a93bc9b27af241db56f8329e9935bb5b603c08ae0",
"permissionLocationsSourceSha256": "f39a81da395b6e23aa2a1a45572a28846e5e81bfd3d764d9a456f74a79c752e9",
"permissionRedactionSourceSha256": "ad6770c69269087951790e2e87e22ac088e3d432769adf17ebc865ed512e6c4f",
"permissionClassifierSourceSha256": "1161eabd82e26133e3b3db3ab567f65d52808b03f176e93497e02c8330349fb4",
"semanticToolReceiptContract": "paperclip.semantic_tool_receipt.v2",
"semanticReceiptSourceSha256": "b2795726b2234a663fec1a6ca11f0551ae69882fe9e82aa39686e952d036e791",
"semanticBridgeSourceSha256": "8764b8c9032fdc7d1415b01e75a9fc57c550e7a5e11da4bed7d9100082872ae5",
"toolEvidenceSourceSha256": "6eef5039afc75bb851eaf9cd82a6f099e4bd398ca2deb59dd66f5b2a81a7a706",
"semanticNormalizedInputContract": "validated-forwarded-input-commit-v1",
"semanticSidecarSourceSha256": "152ec3e5066695c7a28b56cb9b4d5fbd30500c8e7beee54efb9a33fc8a532c9d",
"semanticDirectDriverSourceSha256": "9ee8f25f1ebcd44af15f12a46e5735980083672cd317f44cd10cf2e77699e352",
"semanticValidationSourceSha256": "02fbb92681c78c5de5d2f1aae25aabc25a0e5df6b0ff4baccac652192a8da975",
"semanticNormalizationSourceSha256": "8b628b82e8eacc91cdcc6fdca2210ba4cf282f01e9c6f74e95ff271655b5047e",
"semanticCompletionContractSourceSha256": "f49398b682a5623812f5d3c33d6bb9a749008e47cc0ed969072041615f66df59",
"semanticValidatorsSourceSha256": "b20ec8ee6e7165117233ce4421a975bb9d3f276220ce31655c0b9a717cb2d9cb",
"semanticSchemaBundleSourceSha256": "81ef98ca7b34896a0f76390ac7af3dd8ef7609fe6f38d54bd6a69373d50fe40b",
"semanticSidecarProtocolSourceSha256": "26dd0cfbef8b2b401de6b7862a4af7f243fb703e23678a1a5ed8fa68d4784d42",
"semanticSidecarReceiptCommitContract": "correlated-tool-resolve-v1",
"displayEventSourceSha256": "d72f9a6035c247bc6a42c067c05753076c54322c4b58984e93922f3325dc6877",
"displayProjectionSourceSha256": "75952606b26dd93bbc582c1f0a4424487377272ea745fb3a27ceae031fd5dc7e",
"configuredEnvironmentSourceSha256": "a872e5b939c496955615ce87889ad27eb1ba2a9d8fc25e6bb74e03b1c2293feb",
"configuredEnvironmentRustSourceSha256": "fef93985d703f6b484e58746df5c93d60cb95c085fbf5de1af557913358e900d",
"profileActivitySourceSha256": "4fdb6b0f9125fd8372ba6f27945fa5c8a3d3b2ec891df544092e3dc7a75d5282",
"profileExtensionsSourceSha256": "a80ddc95eb4505095bfdbbf85c758199949ab20be9c84b34c77f762eb7180571",
"profileInstallationSourceSha256": "4af2280930d6382ff4acef6a09515050991746d8ad5358705f536227d548555f",
"attachmentPolicySourceSha256": "e07e2dbc1fdb6895165f2433d1e9627e37cb3d3ad94a8c9601b4b9cafbc44b17",
"singleReadEvidenceSourceSha256": "4069393405089bde613cecec04f5123c426594811da4c668bd96f0e7e283550f",
"nativeSessionRuntimeSourceSha256": "1fe6fa9e6b96d84d70432b85a57c473f833606d4a521563d5022b4d3c41576ce",
"nativeRuntimeContextSourceSha256": "71607f80dbb8dc5cc6c123d0b8f3995d6c5407277695a8c82cbedc90fb8f4842",
"nativeRuntimePromptsSourceSha256": "fff5755dba9b7dce8a5f10ff6ac6d5ed06b92ed079ce1e0a44ac72f2ce7869c1",
"nativeSessionContractSourceSha256": "22a8c96ce41ba4f03e976fc37f0cc7c5d05cee99fa789941da31ee1dab440b90",
"harnessSessionContractSourceSha256": "baba1a210b863518f01e0c875606ed37f9467c433222251438578bd999bc43b5",
"harnessBackendSourceSha256": "dc827e281ae6731545b166ee4d709a4f67f594a556dcbe63c70fe8f1aca26249",
"harnessSessionSourceSha256": "81361733e86b56dd5a66415aefc6f72e69be24acc8d3417370154ebb7fef6e94",
"transportContractSourceSha256": "03fca93d36a89b0cc0917335e293ad097fdf04356d21b307827bb0ea4c13f523",
"nativeBackendSourceSha256": "7495d9898d22dca1ebf6336361d332bafefc4498f6e49f1135025fad846c8586",
"nativeBackendFactorySourceSha256": "7e431c926b76d53c4c08e3a4105353dcd34bd940f6588a1a68f79631f6feeb44",
"nativeInstructionsSourceSha256": "82ac6e5f7275b4ef79fb166c7330efc504e80cab3d7e9081e4e40a8b570bc50b",
"providerLaunchSourceSha256": "c744235b3067ea75973523f78f1e13399337bc155f1775af694e34782d5c9bef",
"launchPreparationStoreSourceSha256": "ff6025568bbc0aa6ce545772d73dfca2d3da226740bd3a7b386b069e76cff296",
"runtimeRequestBridgeSourceSha256": "55aec95e7c7f204454cbd2961e4ee7e7507851da99f0ced899b61154333ae927",
"runtimeRequestFacadeSourceSha256": "d0ed28e0c5ddad34db8f437e704c8a755eb0b47f27e08e44185f66d1d2205295",
"runtimeRequestNotificationSourceSha256": "6196c6175f11c69295dc00fc773201f4fdeca26c500653870253c43b81e65211",
"guardedInstallationSourceSha256": "56a177d3e702914818dca4ca50e061f0d25f988bfc4c0582c36ce23c1696d82f",
"nativeExecutionSourceSha256": "927b98c90f482cd10ce66fe6730ecd91eb3854935fe6f454b4898da726c0fd69",
"profileCompatibilitySourceSha256": "68f12855fc4f51f31b79ee48851204cd8424449df3b7f33147813aaa21959e83",
"installationSourceSha256": "a1c7c6f103b898216973e77ffbac0ef7572e250aa574d1a4065270e9dfa0dc2d",
"assetOwnershipSourceSha256": "b4e8c5b4e2c1757bcbf2049b5cb013723876168c00c24c28048fc80c7ca16ace",
"assetInstallerSourceSha256": "d3bd9514e5920d0cc3567aa50487fb534c57a6f66b8da0d3f22c5f6e499c841f",
"credentialBindingSourceSha256": "a6733e28a9468b744e1e72f1af0c2236e17372e51a9a3ba254a406e085591d2d",
"admissionDiagnosticsSourceSha256": "df8f1aa4f2d1bc63b2635bdd09cb8165c8b7681ddcc2618435c7c08ca90475af",
"grokAdmissionSourceSha256": "f1e46cf2e1e36b7704bd797b678e3db8db2003f97bdb9d827cfa3d7662698777",
"sidecarErrorSourceSha256": "17948ad74350dc487ab20d24a0fb89daf0b426b98396454fff0e3856e922d82c",
"profileSourceSha256": "f5538b3dbefa7634a332b87d5ededcefb56aa7e5790cede1c7a0d948a548a456",
"metadataProbeSourceSha256": "be4c8416edd27061109bc1f33d0c26071b4facbb3f651beaae6b3c0275cce727",
"nativeEditContextSourceSha256": "7be0bd911bc6bb3587e57d25ab5e75a961801ad0c58f06e713dd64cfe17a3c43",
"permissionToolIdentitySourceSha256": "770b47305e571a81f344883057d0e4a482a1cd59ac77d045836593a8e739deb1",
"semanticContinuationSourceSha256": "c9cc0fd516b3df92a6655f56ee9bef37615a889c371e2e137d8ac5c1176de811",
"preparedHarnessHomeSourceSha256": "bb286f7ddc6e9597c56d46bf7ff6e3b556c5b680d7e147fd46518724432b083e",
"runtimeHostSourceSha256": "981a18aad23e34c3c675123d1dd0a920748821bad88885bb1a2e1a060c870921",
"runtimeAdapterSourceSha256": "601cbfe4e2811f771a3a59bf23fdbb05e33a04901af987f2ff96a8acf56374a3",
"runtimeSandboxSourceSha256": "d631dc7a3554c5eb4ed47bef966007245a133862277c96011b1fe1639135f59d",
"cancellationSourceSha256": "a07d1a9e982dec0ae130c1ad1efa5bc75c6a39e013b730ba3ee45256f09ceeca",
"agentFilesSourceSha256": "fb32f6badc13dfa22f231479509b631b2f0eba0c99b1ab9f3cd5c0c601aa03ba",
"nativeDistributionSourceSha256": "aed327c389e957483a503cb1bb8b247ee7cd7ff4b528fb4567c39bcb4577690b"
}
}
@@ -0,0 +1,89 @@
{
"commandDigest": "sha256:0c3328c3fecbe730fa0c4d5239f1084eada804bcb140e16bb41efa0e5a4c4380",
"declaration": {
"schema": "paperclip.acpx_profile_declaration.v1",
"agent": "copilot",
"agentProfileVersion": 88,
"acpxVersion": "0.13.1",
"agentServerVersion": "1.0.88",
"protocolPolicyRevision": "copilot-agent-manual-v1",
"acpxPatchSha256": "1e7dae8c83bf8620f53f2bea13c175eeff95e7e955783f6f529bb1dcbdcdb6d2",
"policySha256": "a4be69be43db84052560420a3ca546a665c9165573c24d543eb33d144ba138a3",
"distributionSourceSha256": "c0a65e247fc47b263bd369a3d5ab505c4b323d4e6493be8a9ecbeb0e9dbb9107",
"agentFilesBinding": "registered-runtime-context-v1",
"systemInstructionDelivery": "COPILOT_HOME/copilot-instructions.md:replace-under-lifetime-lease-before-launch:v1",
"sharedRuntimeContract": "paperclip.acpx-runtime-contract.v1",
"innerDistributionSourceSha256": "9bb08347eed01f1ab44e065c8b06ead9be3a25973d6e6329dc4c0a099096279a",
"upstreamAppSha256": "7b48282a19b5b0814a0c96ad5e3a125173d792cc55f9525b2effea962f6063c0",
"patchedAppSha256": "61f8eebe0c30cc03b311c6818b2acb158a6d16ca58c8bfac5ebd42db095c2679",
"messageIdentityContract": "copilot-native-message-id-v1",
"ownedDistributionDelivery": "COPILOT_CLI_DIST_DIR:lease-owned-guarded-inner-distribution:v1",
"permissionContextContract": "copilot-edit-permission-context-v1",
"permissionContextSourceSha256": "14791781934eb8d91c2a304e257fdb8c7825ae3a40c2bd44fd149c7492470852",
"permissionAdapterSourceSha256": "444482de2abb23d9c9c39a3a93bc9b27af241db56f8329e9935bb5b603c08ae0",
"permissionLocationsSourceSha256": "f39a81da395b6e23aa2a1a45572a28846e5e81bfd3d764d9a456f74a79c752e9",
"permissionRedactionSourceSha256": "ad6770c69269087951790e2e87e22ac088e3d432769adf17ebc865ed512e6c4f",
"permissionClassifierSourceSha256": "1161eabd82e26133e3b3db3ab567f65d52808b03f176e93497e02c8330349fb4",
"semanticToolReceiptContract": "paperclip.semantic_tool_receipt.v2",
"semanticReceiptSourceSha256": "b2795726b2234a663fec1a6ca11f0551ae69882fe9e82aa39686e952d036e791",
"semanticBridgeSourceSha256": "8764b8c9032fdc7d1415b01e75a9fc57c550e7a5e11da4bed7d9100082872ae5",
"toolEvidenceSourceSha256": "6eef5039afc75bb851eaf9cd82a6f099e4bd398ca2deb59dd66f5b2a81a7a706",
"semanticNormalizedInputContract": "validated-forwarded-input-commit-v1",
"semanticSidecarSourceSha256": "6816fe12cdd274746b5241b75823b3c347b245f3cc03cdbe70f05ec1a0250663",
"semanticDirectDriverSourceSha256": "d11dea41590394225d622c2f4b4141ede0445fdb529fec1d6ce3fe749f354234",
"semanticValidationSourceSha256": "02fbb92681c78c5de5d2f1aae25aabc25a0e5df6b0ff4baccac652192a8da975",
"semanticNormalizationSourceSha256": "8b628b82e8eacc91cdcc6fdca2210ba4cf282f01e9c6f74e95ff271655b5047e",
"semanticCompletionContractSourceSha256": "f49398b682a5623812f5d3c33d6bb9a749008e47cc0ed969072041615f66df59",
"semanticValidatorsSourceSha256": "b20ec8ee6e7165117233ce4421a975bb9d3f276220ce31655c0b9a717cb2d9cb",
"semanticSchemaBundleSourceSha256": "81ef98ca7b34896a0f76390ac7af3dd8ef7609fe6f38d54bd6a69373d50fe40b",
"semanticSidecarProtocolSourceSha256": "26b6b21dad582810d00f46e947e682a9615ee9761c487f6315970d6d014c05ab",
"semanticSidecarReceiptCommitContract": "correlated-tool-resolve-v1",
"displayEventSourceSha256": "d72f9a6035c247bc6a42c067c05753076c54322c4b58984e93922f3325dc6877",
"displayProjectionSourceSha256": "75952606b26dd93bbc582c1f0a4424487377272ea745fb3a27ceae031fd5dc7e",
"configuredEnvironmentSourceSha256": "a872e5b939c496955615ce87889ad27eb1ba2a9d8fc25e6bb74e03b1c2293feb",
"configuredEnvironmentRustSourceSha256": "fef93985d703f6b484e58746df5c93d60cb95c085fbf5de1af557913358e900d",
"profileActivitySourceSha256": "4fdb6b0f9125fd8372ba6f27945fa5c8a3d3b2ec891df544092e3dc7a75d5282",
"profileExtensionsSourceSha256": "a80ddc95eb4505095bfdbbf85c758199949ab20be9c84b34c77f762eb7180571",
"profileInstallationSourceSha256": "d229b6afef695991313acdf490991136d40d638359665e0c48afb675af94f863",
"attachmentPolicySourceSha256": "e07e2dbc1fdb6895165f2433d1e9627e37cb3d3ad94a8c9601b4b9cafbc44b17",
"singleReadEvidenceSourceSha256": "4069393405089bde613cecec04f5123c426594811da4c668bd96f0e7e283550f",
"nativeSessionRuntimeSourceSha256": "cbcefbceb0b2a24b0909cbb8361df6b8853b4f50b21d66328bc483951a8246ea",
"nativeRuntimeContextSourceSha256": "71607f80dbb8dc5cc6c123d0b8f3995d6c5407277695a8c82cbedc90fb8f4842",
"nativeRuntimePromptsSourceSha256": "fff5755dba9b7dce8a5f10ff6ac6d5ed06b92ed079ce1e0a44ac72f2ce7869c1",
"nativeSessionContractSourceSha256": "22a8c96ce41ba4f03e976fc37f0cc7c5d05cee99fa789941da31ee1dab440b90",
"harnessSessionContractSourceSha256": "baba1a210b863518f01e0c875606ed37f9467c433222251438578bd999bc43b5",
"harnessBackendSourceSha256": "dc827e281ae6731545b166ee4d709a4f67f594a556dcbe63c70fe8f1aca26249",
"harnessSessionSourceSha256": "bb9bb3daac53ce5955ddf8f56839c7a57ae60c74ea3cdd08895ab6912fcf7851",
"transportContractSourceSha256": "06f06c53ecae304f72034ffb2f659ff087c82a70ed4994daf21a9d2edaf56e4e",
"nativeBackendSourceSha256": "7495d9898d22dca1ebf6336361d332bafefc4498f6e49f1135025fad846c8586",
"nativeBackendFactorySourceSha256": "7e431c926b76d53c4c08e3a4105353dcd34bd940f6588a1a68f79631f6feeb44",
"nativeInstructionsSourceSha256": "82ac6e5f7275b4ef79fb166c7330efc504e80cab3d7e9081e4e40a8b570bc50b",
"providerLaunchSourceSha256": "c744235b3067ea75973523f78f1e13399337bc155f1775af694e34782d5c9bef",
"launchPreparationStoreSourceSha256": "ff6025568bbc0aa6ce545772d73dfca2d3da226740bd3a7b386b069e76cff296",
"runtimeRequestBridgeSourceSha256": "1554851fd4b32561e8575b8ad72a28528172dfc0372a014d11f02668991d5e49",
"runtimeRequestFacadeSourceSha256": "23361d25e660ef7919bfb54f21727b899e7d6f8865307604ee15eca7488afeaa",
"runtimeRequestNotificationSourceSha256": "6196c6175f11c69295dc00fc773201f4fdeca26c500653870253c43b81e65211",
"guardedInstallationSourceSha256": "64b137e3ef695e7d03013ea2b6c8830171e0a73e0bf2e73d55e9ced57a47bcf6",
"nativeExecutionSourceSha256": "927b98c90f482cd10ce66fe6730ecd91eb3854935fe6f454b4898da726c0fd69",
"profileCompatibilitySourceSha256": "3937581ffc20b248bb24e2e7109e8adb1035a750d1713994988986d3572a84bc",
"installationSourceSha256": "a1c7c6f103b898216973e77ffbac0ef7572e250aa574d1a4065270e9dfa0dc2d",
"assetOwnershipSourceSha256": "36064b48d889c41070091a75c1645b7c8caa987a7ed1810a931dc378ddbb1356",
"assetInstallerSourceSha256": "d3bd9514e5920d0cc3567aa50487fb534c57a6f66b8da0d3f22c5f6e499c841f",
"credentialBindingSourceSha256": "9ace39a71ba287838c1b9c56bed141248e805fd017eb8490770c3b579567e55b",
"admissionDiagnosticsSourceSha256": "df8f1aa4f2d1bc63b2635bdd09cb8165c8b7681ddcc2618435c7c08ca90475af",
"grokAdmissionSourceSha256": "f1e46cf2e1e36b7704bd797b678e3db8db2003f97bdb9d827cfa3d7662698777",
"sidecarErrorSourceSha256": "17948ad74350dc487ab20d24a0fb89daf0b426b98396454fff0e3856e922d82c",
"profileSourceSha256": "f5538b3dbefa7634a332b87d5ededcefb56aa7e5790cede1c7a0d948a548a456",
"metadataProbeSourceSha256": "be4c8416edd27061109bc1f33d0c26071b4facbb3f651beaae6b3c0275cce727",
"nativeEditContextSourceSha256": "7be0bd911bc6bb3587e57d25ab5e75a961801ad0c58f06e713dd64cfe17a3c43",
"permissionToolIdentitySourceSha256": "770b47305e571a81f344883057d0e4a482a1cd59ac77d045836593a8e739deb1",
"semanticContinuationSourceSha256": "c9cc0fd516b3df92a6655f56ee9bef37615a889c371e2e137d8ac5c1176de811",
"preparedHarnessHomeSourceSha256": "bb286f7ddc6e9597c56d46bf7ff6e3b556c5b680d7e147fd46518724432b083e",
"runtimeHostSourceSha256": "f44e5555b722553ab7ea1c982d355b1694d3c5fe1cdf19b9868e4bfbaa587b72",
"runtimeAdapterSourceSha256": "c676b83d9dbef86d781069a8b25e160615b288177729974267fe0c2da25afb71",
"runtimeSandboxSourceSha256": "86dcc0abbbe2e32f88febbbab22f662d8490d438a9e9cb5df04589fdf66ebd88",
"cancellationSourceSha256": "a07d1a9e982dec0ae130c1ad1efa5bc75c6a39e013b730ba3ee45256f09ceeca",
"agentFilesSourceSha256": "fb32f6badc13dfa22f231479509b631b2f0eba0c99b1ab9f3cd5c0c601aa03ba",
"nativeDistributionSourceSha256": "aed327c389e957483a503cb1bb8b247ee7cd7ff4b528fb4567c39bcb4577690b"
}
}
@@ -0,0 +1,89 @@
{
"commandDigest": "sha256:995381b2cec7a0faf3f5cefbe2421eae7936a2bfa50bb153645f57341f968db3",
"declaration": {
"schema": "paperclip.acpx_profile_declaration.v1",
"agent": "copilot",
"agentProfileVersion": 89,
"acpxVersion": "0.13.1",
"agentServerVersion": "1.0.88",
"protocolPolicyRevision": "copilot-agent-manual-v1",
"acpxPatchSha256": "1e7dae8c83bf8620f53f2bea13c175eeff95e7e955783f6f529bb1dcbdcdb6d2",
"policySha256": "a4be69be43db84052560420a3ca546a665c9165573c24d543eb33d144ba138a3",
"distributionSourceSha256": "c0a65e247fc47b263bd369a3d5ab505c4b323d4e6493be8a9ecbeb0e9dbb9107",
"agentFilesBinding": "registered-runtime-context-v1",
"systemInstructionDelivery": "COPILOT_HOME/copilot-instructions.md:replace-under-lifetime-lease-before-launch:v1",
"sharedRuntimeContract": "paperclip.acpx-runtime-contract.v1",
"innerDistributionSourceSha256": "9bb08347eed01f1ab44e065c8b06ead9be3a25973d6e6329dc4c0a099096279a",
"upstreamAppSha256": "7b48282a19b5b0814a0c96ad5e3a125173d792cc55f9525b2effea962f6063c0",
"patchedAppSha256": "61f8eebe0c30cc03b311c6818b2acb158a6d16ca58c8bfac5ebd42db095c2679",
"messageIdentityContract": "copilot-native-message-id-v1",
"ownedDistributionDelivery": "COPILOT_CLI_DIST_DIR:lease-owned-guarded-inner-distribution:v1",
"permissionContextContract": "copilot-edit-permission-context-v1",
"permissionContextSourceSha256": "14791781934eb8d91c2a304e257fdb8c7825ae3a40c2bd44fd149c7492470852",
"permissionAdapterSourceSha256": "444482de2abb23d9c9c39a3a93bc9b27af241db56f8329e9935bb5b603c08ae0",
"permissionLocationsSourceSha256": "f39a81da395b6e23aa2a1a45572a28846e5e81bfd3d764d9a456f74a79c752e9",
"permissionRedactionSourceSha256": "ad6770c69269087951790e2e87e22ac088e3d432769adf17ebc865ed512e6c4f",
"permissionClassifierSourceSha256": "1161eabd82e26133e3b3db3ab567f65d52808b03f176e93497e02c8330349fb4",
"semanticToolReceiptContract": "paperclip.semantic_tool_receipt.v2",
"semanticReceiptSourceSha256": "b2795726b2234a663fec1a6ca11f0551ae69882fe9e82aa39686e952d036e791",
"semanticBridgeSourceSha256": "8764b8c9032fdc7d1415b01e75a9fc57c550e7a5e11da4bed7d9100082872ae5",
"toolEvidenceSourceSha256": "6eef5039afc75bb851eaf9cd82a6f099e4bd398ca2deb59dd66f5b2a81a7a706",
"semanticNormalizedInputContract": "validated-forwarded-input-commit-v1",
"semanticSidecarSourceSha256": "6816fe12cdd274746b5241b75823b3c347b245f3cc03cdbe70f05ec1a0250663",
"semanticDirectDriverSourceSha256": "d11dea41590394225d622c2f4b4141ede0445fdb529fec1d6ce3fe749f354234",
"semanticValidationSourceSha256": "02fbb92681c78c5de5d2f1aae25aabc25a0e5df6b0ff4baccac652192a8da975",
"semanticNormalizationSourceSha256": "8b628b82e8eacc91cdcc6fdca2210ba4cf282f01e9c6f74e95ff271655b5047e",
"semanticCompletionContractSourceSha256": "f49398b682a5623812f5d3c33d6bb9a749008e47cc0ed969072041615f66df59",
"semanticValidatorsSourceSha256": "b20ec8ee6e7165117233ce4421a975bb9d3f276220ce31655c0b9a717cb2d9cb",
"semanticSchemaBundleSourceSha256": "81ef98ca7b34896a0f76390ac7af3dd8ef7609fe6f38d54bd6a69373d50fe40b",
"semanticSidecarProtocolSourceSha256": "26b6b21dad582810d00f46e947e682a9615ee9761c487f6315970d6d014c05ab",
"semanticSidecarReceiptCommitContract": "correlated-tool-resolve-v1",
"displayEventSourceSha256": "d72f9a6035c247bc6a42c067c05753076c54322c4b58984e93922f3325dc6877",
"displayProjectionSourceSha256": "75952606b26dd93bbc582c1f0a4424487377272ea745fb3a27ceae031fd5dc7e",
"configuredEnvironmentSourceSha256": "a872e5b939c496955615ce87889ad27eb1ba2a9d8fc25e6bb74e03b1c2293feb",
"configuredEnvironmentRustSourceSha256": "fef93985d703f6b484e58746df5c93d60cb95c085fbf5de1af557913358e900d",
"profileActivitySourceSha256": "4fdb6b0f9125fd8372ba6f27945fa5c8a3d3b2ec891df544092e3dc7a75d5282",
"profileExtensionsSourceSha256": "a80ddc95eb4505095bfdbbf85c758199949ab20be9c84b34c77f762eb7180571",
"profileInstallationSourceSha256": "d229b6afef695991313acdf490991136d40d638359665e0c48afb675af94f863",
"attachmentPolicySourceSha256": "e07e2dbc1fdb6895165f2433d1e9627e37cb3d3ad94a8c9601b4b9cafbc44b17",
"singleReadEvidenceSourceSha256": "4069393405089bde613cecec04f5123c426594811da4c668bd96f0e7e283550f",
"nativeSessionRuntimeSourceSha256": "cbcefbceb0b2a24b0909cbb8361df6b8853b4f50b21d66328bc483951a8246ea",
"nativeRuntimeContextSourceSha256": "71607f80dbb8dc5cc6c123d0b8f3995d6c5407277695a8c82cbedc90fb8f4842",
"nativeRuntimePromptsSourceSha256": "fff5755dba9b7dce8a5f10ff6ac6d5ed06b92ed079ce1e0a44ac72f2ce7869c1",
"nativeSessionContractSourceSha256": "22a8c96ce41ba4f03e976fc37f0cc7c5d05cee99fa789941da31ee1dab440b90",
"harnessSessionContractSourceSha256": "baba1a210b863518f01e0c875606ed37f9467c433222251438578bd999bc43b5",
"harnessBackendSourceSha256": "dc827e281ae6731545b166ee4d709a4f67f594a556dcbe63c70fe8f1aca26249",
"harnessSessionSourceSha256": "bb9bb3daac53ce5955ddf8f56839c7a57ae60c74ea3cdd08895ab6912fcf7851",
"transportContractSourceSha256": "06f06c53ecae304f72034ffb2f659ff087c82a70ed4994daf21a9d2edaf56e4e",
"nativeBackendSourceSha256": "7495d9898d22dca1ebf6336361d332bafefc4498f6e49f1135025fad846c8586",
"nativeBackendFactorySourceSha256": "7e431c926b76d53c4c08e3a4105353dcd34bd940f6588a1a68f79631f6feeb44",
"nativeInstructionsSourceSha256": "82ac6e5f7275b4ef79fb166c7330efc504e80cab3d7e9081e4e40a8b570bc50b",
"providerLaunchSourceSha256": "c744235b3067ea75973523f78f1e13399337bc155f1775af694e34782d5c9bef",
"launchPreparationStoreSourceSha256": "ff6025568bbc0aa6ce545772d73dfca2d3da226740bd3a7b386b069e76cff296",
"runtimeRequestBridgeSourceSha256": "1554851fd4b32561e8575b8ad72a28528172dfc0372a014d11f02668991d5e49",
"runtimeRequestFacadeSourceSha256": "23361d25e660ef7919bfb54f21727b899e7d6f8865307604ee15eca7488afeaa",
"runtimeRequestNotificationSourceSha256": "6196c6175f11c69295dc00fc773201f4fdeca26c500653870253c43b81e65211",
"guardedInstallationSourceSha256": "64b137e3ef695e7d03013ea2b6c8830171e0a73e0bf2e73d55e9ced57a47bcf6",
"nativeExecutionSourceSha256": "927b98c90f482cd10ce66fe6730ecd91eb3854935fe6f454b4898da726c0fd69",
"profileCompatibilitySourceSha256": "6332462e69b990dcba4104389e76ba4198ba284242dc1b963aedfdc5dba93f31",
"installationSourceSha256": "a1c7c6f103b898216973e77ffbac0ef7572e250aa574d1a4065270e9dfa0dc2d",
"assetOwnershipSourceSha256": "36064b48d889c41070091a75c1645b7c8caa987a7ed1810a931dc378ddbb1356",
"assetInstallerSourceSha256": "d3bd9514e5920d0cc3567aa50487fb534c57a6f66b8da0d3f22c5f6e499c841f",
"credentialBindingSourceSha256": "9ace39a71ba287838c1b9c56bed141248e805fd017eb8490770c3b579567e55b",
"admissionDiagnosticsSourceSha256": "df8f1aa4f2d1bc63b2635bdd09cb8165c8b7681ddcc2618435c7c08ca90475af",
"grokAdmissionSourceSha256": "f1e46cf2e1e36b7704bd797b678e3db8db2003f97bdb9d827cfa3d7662698777",
"sidecarErrorSourceSha256": "17948ad74350dc487ab20d24a0fb89daf0b426b98396454fff0e3856e922d82c",
"profileSourceSha256": "f5538b3dbefa7634a332b87d5ededcefb56aa7e5790cede1c7a0d948a548a456",
"metadataProbeSourceSha256": "be4c8416edd27061109bc1f33d0c26071b4facbb3f651beaae6b3c0275cce727",
"nativeEditContextSourceSha256": "7be0bd911bc6bb3587e57d25ab5e75a961801ad0c58f06e713dd64cfe17a3c43",
"permissionToolIdentitySourceSha256": "770b47305e571a81f344883057d0e4a482a1cd59ac77d045836593a8e739deb1",
"semanticContinuationSourceSha256": "c9cc0fd516b3df92a6655f56ee9bef37615a889c371e2e137d8ac5c1176de811",
"preparedHarnessHomeSourceSha256": "bb286f7ddc6e9597c56d46bf7ff6e3b556c5b680d7e147fd46518724432b083e",
"runtimeHostSourceSha256": "f44e5555b722553ab7ea1c982d355b1694d3c5fe1cdf19b9868e4bfbaa587b72",
"runtimeAdapterSourceSha256": "c676b83d9dbef86d781069a8b25e160615b288177729974267fe0c2da25afb71",
"runtimeSandboxSourceSha256": "86dcc0abbbe2e32f88febbbab22f662d8490d438a9e9cb5df04589fdf66ebd88",
"cancellationSourceSha256": "a07d1a9e982dec0ae130c1ad1efa5bc75c6a39e013b730ba3ee45256f09ceeca",
"agentFilesSourceSha256": "fb32f6badc13dfa22f231479509b631b2f0eba0c99b1ab9f3cd5c0c601aa03ba",
"nativeDistributionSourceSha256": "aed327c389e957483a503cb1bb8b247ee7cd7ff4b528fb4567c39bcb4577690b"
}
}
@@ -0,0 +1,89 @@
{
"commandDigest": "sha256:8922d3d41dae0a7b7f7e2de69d50b272b58283232fefb22ffdb6c9b34fa26a6b",
"declaration": {
"schema": "paperclip.acpx_profile_declaration.v1",
"agent": "copilot",
"agentProfileVersion": 90,
"acpxVersion": "0.13.1",
"agentServerVersion": "1.0.88",
"protocolPolicyRevision": "copilot-agent-manual-v1",
"acpxPatchSha256": "1e7dae8c83bf8620f53f2bea13c175eeff95e7e955783f6f529bb1dcbdcdb6d2",
"policySha256": "a4be69be43db84052560420a3ca546a665c9165573c24d543eb33d144ba138a3",
"distributionSourceSha256": "c0a65e247fc47b263bd369a3d5ab505c4b323d4e6493be8a9ecbeb0e9dbb9107",
"agentFilesBinding": "registered-runtime-context-v1",
"systemInstructionDelivery": "COPILOT_HOME/copilot-instructions.md:replace-under-lifetime-lease-before-launch:v1",
"sharedRuntimeContract": "paperclip.acpx-runtime-contract.v1",
"innerDistributionSourceSha256": "9bb08347eed01f1ab44e065c8b06ead9be3a25973d6e6329dc4c0a099096279a",
"upstreamAppSha256": "7b48282a19b5b0814a0c96ad5e3a125173d792cc55f9525b2effea962f6063c0",
"patchedAppSha256": "61f8eebe0c30cc03b311c6818b2acb158a6d16ca58c8bfac5ebd42db095c2679",
"messageIdentityContract": "copilot-native-message-id-v1",
"ownedDistributionDelivery": "COPILOT_CLI_DIST_DIR:lease-owned-guarded-inner-distribution:v1",
"permissionContextContract": "copilot-edit-permission-context-v1",
"permissionContextSourceSha256": "14791781934eb8d91c2a304e257fdb8c7825ae3a40c2bd44fd149c7492470852",
"permissionAdapterSourceSha256": "444482de2abb23d9c9c39a3a93bc9b27af241db56f8329e9935bb5b603c08ae0",
"permissionLocationsSourceSha256": "f39a81da395b6e23aa2a1a45572a28846e5e81bfd3d764d9a456f74a79c752e9",
"permissionRedactionSourceSha256": "ad6770c69269087951790e2e87e22ac088e3d432769adf17ebc865ed512e6c4f",
"permissionClassifierSourceSha256": "1161eabd82e26133e3b3db3ab567f65d52808b03f176e93497e02c8330349fb4",
"semanticToolReceiptContract": "paperclip.semantic_tool_receipt.v2",
"semanticReceiptSourceSha256": "b2795726b2234a663fec1a6ca11f0551ae69882fe9e82aa39686e952d036e791",
"semanticBridgeSourceSha256": "8764b8c9032fdc7d1415b01e75a9fc57c550e7a5e11da4bed7d9100082872ae5",
"toolEvidenceSourceSha256": "6eef5039afc75bb851eaf9cd82a6f099e4bd398ca2deb59dd66f5b2a81a7a706",
"semanticNormalizedInputContract": "validated-forwarded-input-commit-v1",
"semanticSidecarSourceSha256": "6816fe12cdd274746b5241b75823b3c347b245f3cc03cdbe70f05ec1a0250663",
"semanticDirectDriverSourceSha256": "d11dea41590394225d622c2f4b4141ede0445fdb529fec1d6ce3fe749f354234",
"semanticValidationSourceSha256": "02fbb92681c78c5de5d2f1aae25aabc25a0e5df6b0ff4baccac652192a8da975",
"semanticNormalizationSourceSha256": "8b628b82e8eacc91cdcc6fdca2210ba4cf282f01e9c6f74e95ff271655b5047e",
"semanticCompletionContractSourceSha256": "f49398b682a5623812f5d3c33d6bb9a749008e47cc0ed969072041615f66df59",
"semanticValidatorsSourceSha256": "b20ec8ee6e7165117233ce4421a975bb9d3f276220ce31655c0b9a717cb2d9cb",
"semanticSchemaBundleSourceSha256": "81ef98ca7b34896a0f76390ac7af3dd8ef7609fe6f38d54bd6a69373d50fe40b",
"semanticSidecarProtocolSourceSha256": "26b6b21dad582810d00f46e947e682a9615ee9761c487f6315970d6d014c05ab",
"semanticSidecarReceiptCommitContract": "correlated-tool-resolve-v1",
"displayEventSourceSha256": "d72f9a6035c247bc6a42c067c05753076c54322c4b58984e93922f3325dc6877",
"displayProjectionSourceSha256": "75952606b26dd93bbc582c1f0a4424487377272ea745fb3a27ceae031fd5dc7e",
"configuredEnvironmentSourceSha256": "a872e5b939c496955615ce87889ad27eb1ba2a9d8fc25e6bb74e03b1c2293feb",
"configuredEnvironmentRustSourceSha256": "fef93985d703f6b484e58746df5c93d60cb95c085fbf5de1af557913358e900d",
"profileActivitySourceSha256": "4fdb6b0f9125fd8372ba6f27945fa5c8a3d3b2ec891df544092e3dc7a75d5282",
"profileExtensionsSourceSha256": "a80ddc95eb4505095bfdbbf85c758199949ab20be9c84b34c77f762eb7180571",
"profileInstallationSourceSha256": "d229b6afef695991313acdf490991136d40d638359665e0c48afb675af94f863",
"attachmentPolicySourceSha256": "e07e2dbc1fdb6895165f2433d1e9627e37cb3d3ad94a8c9601b4b9cafbc44b17",
"singleReadEvidenceSourceSha256": "4069393405089bde613cecec04f5123c426594811da4c668bd96f0e7e283550f",
"nativeSessionRuntimeSourceSha256": "cbcefbceb0b2a24b0909cbb8361df6b8853b4f50b21d66328bc483951a8246ea",
"nativeRuntimeContextSourceSha256": "71607f80dbb8dc5cc6c123d0b8f3995d6c5407277695a8c82cbedc90fb8f4842",
"nativeRuntimePromptsSourceSha256": "fff5755dba9b7dce8a5f10ff6ac6d5ed06b92ed079ce1e0a44ac72f2ce7869c1",
"nativeSessionContractSourceSha256": "22a8c96ce41ba4f03e976fc37f0cc7c5d05cee99fa789941da31ee1dab440b90",
"harnessSessionContractSourceSha256": "baba1a210b863518f01e0c875606ed37f9467c433222251438578bd999bc43b5",
"harnessBackendSourceSha256": "dc827e281ae6731545b166ee4d709a4f67f594a556dcbe63c70fe8f1aca26249",
"harnessSessionSourceSha256": "bb9bb3daac53ce5955ddf8f56839c7a57ae60c74ea3cdd08895ab6912fcf7851",
"transportContractSourceSha256": "06f06c53ecae304f72034ffb2f659ff087c82a70ed4994daf21a9d2edaf56e4e",
"nativeBackendSourceSha256": "7495d9898d22dca1ebf6336361d332bafefc4498f6e49f1135025fad846c8586",
"nativeBackendFactorySourceSha256": "7e431c926b76d53c4c08e3a4105353dcd34bd940f6588a1a68f79631f6feeb44",
"nativeInstructionsSourceSha256": "82ac6e5f7275b4ef79fb166c7330efc504e80cab3d7e9081e4e40a8b570bc50b",
"providerLaunchSourceSha256": "c744235b3067ea75973523f78f1e13399337bc155f1775af694e34782d5c9bef",
"launchPreparationStoreSourceSha256": "ff6025568bbc0aa6ce545772d73dfca2d3da226740bd3a7b386b069e76cff296",
"runtimeRequestBridgeSourceSha256": "1554851fd4b32561e8575b8ad72a28528172dfc0372a014d11f02668991d5e49",
"runtimeRequestFacadeSourceSha256": "23361d25e660ef7919bfb54f21727b899e7d6f8865307604ee15eca7488afeaa",
"runtimeRequestNotificationSourceSha256": "6196c6175f11c69295dc00fc773201f4fdeca26c500653870253c43b81e65211",
"guardedInstallationSourceSha256": "64b137e3ef695e7d03013ea2b6c8830171e0a73e0bf2e73d55e9ced57a47bcf6",
"nativeExecutionSourceSha256": "927b98c90f482cd10ce66fe6730ecd91eb3854935fe6f454b4898da726c0fd69",
"profileCompatibilitySourceSha256": "09eac296f1f511678ffa057b9bcc0de5321902a9607eeec0177cd1957f22d735",
"installationSourceSha256": "a1c7c6f103b898216973e77ffbac0ef7572e250aa574d1a4065270e9dfa0dc2d",
"assetOwnershipSourceSha256": "36064b48d889c41070091a75c1645b7c8caa987a7ed1810a931dc378ddbb1356",
"assetInstallerSourceSha256": "d3bd9514e5920d0cc3567aa50487fb534c57a6f66b8da0d3f22c5f6e499c841f",
"credentialBindingSourceSha256": "9ace39a71ba287838c1b9c56bed141248e805fd017eb8490770c3b579567e55b",
"admissionDiagnosticsSourceSha256": "df8f1aa4f2d1bc63b2635bdd09cb8165c8b7681ddcc2618435c7c08ca90475af",
"grokAdmissionSourceSha256": "f1e46cf2e1e36b7704bd797b678e3db8db2003f97bdb9d827cfa3d7662698777",
"sidecarErrorSourceSha256": "17948ad74350dc487ab20d24a0fb89daf0b426b98396454fff0e3856e922d82c",
"profileSourceSha256": "f5538b3dbefa7634a332b87d5ededcefb56aa7e5790cede1c7a0d948a548a456",
"metadataProbeSourceSha256": "be4c8416edd27061109bc1f33d0c26071b4facbb3f651beaae6b3c0275cce727",
"nativeEditContextSourceSha256": "7be0bd911bc6bb3587e57d25ab5e75a961801ad0c58f06e713dd64cfe17a3c43",
"permissionToolIdentitySourceSha256": "770b47305e571a81f344883057d0e4a482a1cd59ac77d045836593a8e739deb1",
"semanticContinuationSourceSha256": "c9cc0fd516b3df92a6655f56ee9bef37615a889c371e2e137d8ac5c1176de811",
"preparedHarnessHomeSourceSha256": "bb286f7ddc6e9597c56d46bf7ff6e3b556c5b680d7e147fd46518724432b083e",
"runtimeHostSourceSha256": "f44e5555b722553ab7ea1c982d355b1694d3c5fe1cdf19b9868e4bfbaa587b72",
"runtimeAdapterSourceSha256": "c676b83d9dbef86d781069a8b25e160615b288177729974267fe0c2da25afb71",
"runtimeSandboxSourceSha256": "86dcc0abbbe2e32f88febbbab22f662d8490d438a9e9cb5df04589fdf66ebd88",
"cancellationSourceSha256": "a07d1a9e982dec0ae130c1ad1efa5bc75c6a39e013b730ba3ee45256f09ceeca",
"agentFilesSourceSha256": "fb32f6badc13dfa22f231479509b631b2f0eba0c99b1ab9f3cd5c0c601aa03ba",
"nativeDistributionSourceSha256": "aed327c389e957483a503cb1bb8b247ee7cd7ff4b528fb4567c39bcb4577690b"
}
}
@@ -0,0 +1,90 @@
{
"commandDigest": "sha256:75ae0628c140e51b466b898a394032849d6eca5272279fa7782192a6d316a75d",
"declaration": {
"schema": "paperclip.acpx_profile_declaration.v1",
"agent": "copilot",
"agentProfileVersion": 91,
"acpxVersion": "0.13.1",
"agentServerVersion": "1.0.88",
"protocolPolicyRevision": "copilot-agent-manual-v1",
"acpxPatchSha256": "1e7dae8c83bf8620f53f2bea13c175eeff95e7e955783f6f529bb1dcbdcdb6d2",
"policySha256": "a4be69be43db84052560420a3ca546a665c9165573c24d543eb33d144ba138a3",
"distributionSourceSha256": "c0a65e247fc47b263bd369a3d5ab505c4b323d4e6493be8a9ecbeb0e9dbb9107",
"agentFilesBinding": "registered-runtime-context-v1",
"systemInstructionDelivery": "COPILOT_HOME/copilot-instructions.md:replace-under-lifetime-lease-before-launch:v1",
"sharedRuntimeContract": "paperclip.acpx-runtime-contract.v1",
"innerDistributionSourceSha256": "9bb08347eed01f1ab44e065c8b06ead9be3a25973d6e6329dc4c0a099096279a",
"upstreamAppSha256": "7b48282a19b5b0814a0c96ad5e3a125173d792cc55f9525b2effea962f6063c0",
"patchedAppSha256": "61f8eebe0c30cc03b311c6818b2acb158a6d16ca58c8bfac5ebd42db095c2679",
"messageIdentityContract": "copilot-native-message-id-v1",
"ownedDistributionDelivery": "COPILOT_CLI_DIST_DIR:lease-owned-guarded-inner-distribution:v1",
"permissionContextContract": "copilot-edit-permission-context-v1",
"permissionContextSourceSha256": "14791781934eb8d91c2a304e257fdb8c7825ae3a40c2bd44fd149c7492470852",
"permissionAdapterSourceSha256": "444482de2abb23d9c9c39a3a93bc9b27af241db56f8329e9935bb5b603c08ae0",
"permissionLocationsSourceSha256": "f39a81da395b6e23aa2a1a45572a28846e5e81bfd3d764d9a456f74a79c752e9",
"permissionRedactionSourceSha256": "ad6770c69269087951790e2e87e22ac088e3d432769adf17ebc865ed512e6c4f",
"permissionClassifierSourceSha256": "b60e4b924e827e122860d2a4cc13b465ba748ee521620887c88f3c58c0df6081",
"semanticToolReceiptContract": "paperclip.semantic_tool_receipt.v2",
"semanticReceiptSourceSha256": "b2795726b2234a663fec1a6ca11f0551ae69882fe9e82aa39686e952d036e791",
"semanticBridgeSourceSha256": "8764b8c9032fdc7d1415b01e75a9fc57c550e7a5e11da4bed7d9100082872ae5",
"toolEvidenceSourceSha256": "6eef5039afc75bb851eaf9cd82a6f099e4bd398ca2deb59dd66f5b2a81a7a706",
"semanticNormalizedInputContract": "validated-forwarded-input-commit-v1",
"semanticSidecarSourceSha256": "477a05847187159f9c6f07bf90f1c0c1d432a9eb6fdb15d5620daf54443dafd8",
"semanticDirectDriverSourceSha256": "d11dea41590394225d622c2f4b4141ede0445fdb529fec1d6ce3fe749f354234",
"semanticValidationSourceSha256": "02fbb92681c78c5de5d2f1aae25aabc25a0e5df6b0ff4baccac652192a8da975",
"semanticNormalizationSourceSha256": "8b628b82e8eacc91cdcc6fdca2210ba4cf282f01e9c6f74e95ff271655b5047e",
"semanticCompletionContractSourceSha256": "f49398b682a5623812f5d3c33d6bb9a749008e47cc0ed969072041615f66df59",
"semanticValidatorsSourceSha256": "b20ec8ee6e7165117233ce4421a975bb9d3f276220ce31655c0b9a717cb2d9cb",
"semanticSchemaBundleSourceSha256": "81ef98ca7b34896a0f76390ac7af3dd8ef7609fe6f38d54bd6a69373d50fe40b",
"semanticSidecarProtocolSourceSha256": "26b6b21dad582810d00f46e947e682a9615ee9761c487f6315970d6d014c05ab",
"semanticSidecarReceiptCommitContract": "correlated-tool-resolve-v1",
"displayEventSourceSha256": "d72f9a6035c247bc6a42c067c05753076c54322c4b58984e93922f3325dc6877",
"displayProjectionSourceSha256": "75952606b26dd93bbc582c1f0a4424487377272ea745fb3a27ceae031fd5dc7e",
"configuredEnvironmentSourceSha256": "a872e5b939c496955615ce87889ad27eb1ba2a9d8fc25e6bb74e03b1c2293feb",
"configuredEnvironmentRustSourceSha256": "fef93985d703f6b484e58746df5c93d60cb95c085fbf5de1af557913358e900d",
"profileActivitySourceSha256": "4fdb6b0f9125fd8372ba6f27945fa5c8a3d3b2ec891df544092e3dc7a75d5282",
"profileExtensionsSourceSha256": "a80ddc95eb4505095bfdbbf85c758199949ab20be9c84b34c77f762eb7180571",
"profileInstallationSourceSha256": "d229b6afef695991313acdf490991136d40d638359665e0c48afb675af94f863",
"attachmentPolicySourceSha256": "e07e2dbc1fdb6895165f2433d1e9627e37cb3d3ad94a8c9601b4b9cafbc44b17",
"singleReadEvidenceSourceSha256": "4069393405089bde613cecec04f5123c426594811da4c668bd96f0e7e283550f",
"nativeSessionRuntimeSourceSha256": "cbcefbceb0b2a24b0909cbb8361df6b8853b4f50b21d66328bc483951a8246ea",
"nativeRuntimeContextSourceSha256": "152d7187ce1dc91a15377d368776555c9897d6e018b65f0f59a92dcdbd6497d9",
"nativeRuntimeContextFieldsSourceSha256": "069f4bc3c4dc95888f30d3fea331adb0ee0a164d09f4f70ec9c132f24f69c7dd",
"nativeRuntimePromptsSourceSha256": "fff5755dba9b7dce8a5f10ff6ac6d5ed06b92ed079ce1e0a44ac72f2ce7869c1",
"nativeSessionContractSourceSha256": "22a8c96ce41ba4f03e976fc37f0cc7c5d05cee99fa789941da31ee1dab440b90",
"harnessSessionContractSourceSha256": "baba1a210b863518f01e0c875606ed37f9467c433222251438578bd999bc43b5",
"harnessBackendSourceSha256": "dc827e281ae6731545b166ee4d709a4f67f594a556dcbe63c70fe8f1aca26249",
"harnessSessionSourceSha256": "bb9bb3daac53ce5955ddf8f56839c7a57ae60c74ea3cdd08895ab6912fcf7851",
"transportContractSourceSha256": "06f06c53ecae304f72034ffb2f659ff087c82a70ed4994daf21a9d2edaf56e4e",
"nativeBackendSourceSha256": "7495d9898d22dca1ebf6336361d332bafefc4498f6e49f1135025fad846c8586",
"nativeBackendFactorySourceSha256": "7e431c926b76d53c4c08e3a4105353dcd34bd940f6588a1a68f79631f6feeb44",
"nativeInstructionsSourceSha256": "82ac6e5f7275b4ef79fb166c7330efc504e80cab3d7e9081e4e40a8b570bc50b",
"providerLaunchSourceSha256": "c744235b3067ea75973523f78f1e13399337bc155f1775af694e34782d5c9bef",
"launchPreparationStoreSourceSha256": "ff6025568bbc0aa6ce545772d73dfca2d3da226740bd3a7b386b069e76cff296",
"runtimeRequestBridgeSourceSha256": "1554851fd4b32561e8575b8ad72a28528172dfc0372a014d11f02668991d5e49",
"runtimeRequestFacadeSourceSha256": "23361d25e660ef7919bfb54f21727b899e7d6f8865307604ee15eca7488afeaa",
"runtimeRequestNotificationSourceSha256": "6196c6175f11c69295dc00fc773201f4fdeca26c500653870253c43b81e65211",
"guardedInstallationSourceSha256": "64b137e3ef695e7d03013ea2b6c8830171e0a73e0bf2e73d55e9ced57a47bcf6",
"nativeExecutionSourceSha256": "927b98c90f482cd10ce66fe6730ecd91eb3854935fe6f454b4898da726c0fd69",
"profileCompatibilitySourceSha256": "aaa189a1e8b921887a5d83c7576617a5b46ceb77d43ed7ec0466653eb29fc37c",
"installationSourceSha256": "a1c7c6f103b898216973e77ffbac0ef7572e250aa574d1a4065270e9dfa0dc2d",
"assetOwnershipSourceSha256": "36064b48d889c41070091a75c1645b7c8caa987a7ed1810a931dc378ddbb1356",
"assetInstallerSourceSha256": "d3bd9514e5920d0cc3567aa50487fb534c57a6f66b8da0d3f22c5f6e499c841f",
"credentialBindingSourceSha256": "9ace39a71ba287838c1b9c56bed141248e805fd017eb8490770c3b579567e55b",
"admissionDiagnosticsSourceSha256": "df8f1aa4f2d1bc63b2635bdd09cb8165c8b7681ddcc2618435c7c08ca90475af",
"grokAdmissionSourceSha256": "f1e46cf2e1e36b7704bd797b678e3db8db2003f97bdb9d827cfa3d7662698777",
"sidecarErrorSourceSha256": "17948ad74350dc487ab20d24a0fb89daf0b426b98396454fff0e3856e922d82c",
"profileSourceSha256": "f5538b3dbefa7634a332b87d5ededcefb56aa7e5790cede1c7a0d948a548a456",
"metadataProbeSourceSha256": "be4c8416edd27061109bc1f33d0c26071b4facbb3f651beaae6b3c0275cce727",
"nativeEditContextSourceSha256": "7be0bd911bc6bb3587e57d25ab5e75a961801ad0c58f06e713dd64cfe17a3c43",
"permissionToolIdentitySourceSha256": "770b47305e571a81f344883057d0e4a482a1cd59ac77d045836593a8e739deb1",
"semanticContinuationSourceSha256": "c9cc0fd516b3df92a6655f56ee9bef37615a889c371e2e137d8ac5c1176de811",
"preparedHarnessHomeSourceSha256": "bb286f7ddc6e9597c56d46bf7ff6e3b556c5b680d7e147fd46518724432b083e",
"runtimeHostSourceSha256": "f44e5555b722553ab7ea1c982d355b1694d3c5fe1cdf19b9868e4bfbaa587b72",
"runtimeAdapterSourceSha256": "c676b83d9dbef86d781069a8b25e160615b288177729974267fe0c2da25afb71",
"runtimeSandboxSourceSha256": "86dcc0abbbe2e32f88febbbab22f662d8490d438a9e9cb5df04589fdf66ebd88",
"cancellationSourceSha256": "a07d1a9e982dec0ae130c1ad1efa5bc75c6a39e013b730ba3ee45256f09ceeca",
"agentFilesSourceSha256": "fb32f6badc13dfa22f231479509b631b2f0eba0c99b1ab9f3cd5c0c601aa03ba",
"nativeDistributionSourceSha256": "aed327c389e957483a503cb1bb8b247ee7cd7ff4b528fb4567c39bcb4577690b"
}
}
@@ -0,0 +1,35 @@
{
"commandDigest": "sha256:c4beba5aff2708dbab58b00da718e112dc29b91159a4f9cf449104a5ef141a40",
"sourceDigest": "sha256:e61fd575a05d284ba10ef17122adabccd08169ae0d06004a365198a603014b1e",
"declaration": {
"schema": "paperclip.grok-profile-identity.v1",
"agent": "grok",
"agentProfileVersion": 13,
"agentServerPackage": "builtin:grok-acp",
"agentServerVersion": "1",
"agentRuntimePackage": "native:grok",
"agentRuntimeVersion": "1.0.13",
"requiresProviderPolicy": false,
"acpxVersion": "0.13.1",
"sources": {
"patches/acpx@0.13.1.patch": "sha256:1e7dae8c83bf8620f53f2bea13c175eeff95e7e955783f6f529bb1dcbdcdb6d2",
"packages/paperclip-runner/src/cli/acpx-runtime-sidecar.ts": "sha256:152ec3e5066695c7a28b56cb9b4d5fbd30500c8e7beee54efb9a33fc8a532c9d",
"packages/paperclip-runner/src/cli/acpx-sidecar-input.ts": "sha256:17948ad74350dc487ab20d24a0fb89daf0b426b98396454fff0e3856e922d82c",
"packages/paperclip-runner/src/drivers/acpx/admission-diagnostics.ts": "sha256:df8f1aa4f2d1bc63b2635bdd09cb8165c8b7681ddcc2618435c7c08ca90475af",
"packages/paperclip-runner/src/drivers/acpx/grok-effort.ts": "sha256:f1e46cf2e1e36b7704bd797b678e3db8db2003f97bdb9d827cfa3d7662698777",
"packages/paperclip-runner/src/drivers/acpx/grok-web-search.ts": "sha256:754b5ca2345c045421f6007f34999508d996e1cea035f0f1952b3d5f00072b9c",
"packages/paperclip-runner/src/drivers/acpx/grok-credentials.ts": "sha256:1c4ff0be6da798b6fcc604d20a9198dcc8523a3806d563b5b5345b7260549f73",
"packages/paperclip-runner/src/drivers/acpx/codex-runtime-adapter.ts": "sha256:601cbfe4e2811f771a3a59bf23fdbb05e33a04901af987f2ff96a8acf56374a3",
"packages/paperclip-runner/src/drivers/acpx/runtime-host.ts": "sha256:981a18aad23e34c3c675123d1dd0a920748821bad88885bb1a2e1a060c870921",
"packages/paperclip-runner/src/drivers/preconfigured-home.ts": "sha256:bb286f7ddc6e9597c56d46bf7ff6e3b556c5b680d7e147fd46518724432b083e",
"packages/paperclip-runner/src/drivers/acpx/runtime-sandbox.ts": "sha256:d631dc7a3554c5eb4ed47bef966007245a133862277c96011b1fe1639135f59d",
"packages/paperclip-runner/src/drivers/acpx/sidecar-protocol.ts": "sha256:26dd0cfbef8b2b401de6b7862a4af7f243fb703e23678a1a5ed8fa68d4784d42",
"packages/paperclip-runner/src/drivers/acpx/native-distribution-integrity.ts": "sha256:aed327c389e957483a503cb1bb8b247ee7cd7ff4b528fb4567c39bcb4577690b",
"packages/paperclip-runner/src/providers/grok/launcher.cjs": "sha256:f0b698395a3704ed2ffaf84ea19bdb20c36c8a0a70b7c629c7b6ffe144e59e55",
"packages/paperclip-runner/src/providers/grok/platforms.json": "sha256:931eed3abbf2bf041e6c72e6e9486d976f4352613cf069b216ddf010c9a8e704",
"packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_backend.rs": "sha256:ff22cccd54160797428e6c7affc70f7d30e3a6678d13058ca972b146c3cdd7d2",
"packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_session.rs": "sha256:e97a7c4d2cf9be9c6e0ada78076a5551b01401518597ab81cb6fbd5a1faf4a5e",
"packages/paperclip-runner/runner/crates/runner-core/src/acpx_sidecar_transport.rs": "sha256:cfbbb39a2e20f449df53ceaea4a6cbd068c954c10405bea2d908b93e3f387fdf"
}
}
}
@@ -0,0 +1,35 @@
{
"commandDigest": "sha256:3140bc190a025afa2f7380a3eb1a2d8aeecd24850ac69f82871847e78c3b17a0",
"sourceDigest": "sha256:8da223681ae5deefd04e192d181e09e5446729d4caf2f96eefac76769717bb09",
"declaration": {
"schema": "paperclip.grok-profile-identity.v1",
"agent": "grok",
"agentProfileVersion": 14,
"agentServerPackage": "builtin:grok-acp",
"agentServerVersion": "1",
"agentRuntimePackage": "native:grok",
"agentRuntimeVersion": "1.0.13",
"requiresProviderPolicy": false,
"acpxVersion": "0.13.1",
"sources": {
"patches/acpx@0.13.1.patch": "sha256:1e7dae8c83bf8620f53f2bea13c175eeff95e7e955783f6f529bb1dcbdcdb6d2",
"packages/paperclip-runner/src/cli/acpx-runtime-sidecar.ts": "sha256:152ec3e5066695c7a28b56cb9b4d5fbd30500c8e7beee54efb9a33fc8a532c9d",
"packages/paperclip-runner/src/cli/acpx-sidecar-input.ts": "sha256:17948ad74350dc487ab20d24a0fb89daf0b426b98396454fff0e3856e922d82c",
"packages/paperclip-runner/src/drivers/acpx/admission-diagnostics.ts": "sha256:df8f1aa4f2d1bc63b2635bdd09cb8165c8b7681ddcc2618435c7c08ca90475af",
"packages/paperclip-runner/src/drivers/acpx/grok-effort.ts": "sha256:f1e46cf2e1e36b7704bd797b678e3db8db2003f97bdb9d827cfa3d7662698777",
"packages/paperclip-runner/src/drivers/acpx/grok-web-search.ts": "sha256:754b5ca2345c045421f6007f34999508d996e1cea035f0f1952b3d5f00072b9c",
"packages/paperclip-runner/src/drivers/acpx/grok-credentials.ts": "sha256:1c4ff0be6da798b6fcc604d20a9198dcc8523a3806d563b5b5345b7260549f73",
"packages/paperclip-runner/src/drivers/acpx/codex-runtime-adapter.ts": "sha256:601cbfe4e2811f771a3a59bf23fdbb05e33a04901af987f2ff96a8acf56374a3",
"packages/paperclip-runner/src/drivers/acpx/runtime-host.ts": "sha256:981a18aad23e34c3c675123d1dd0a920748821bad88885bb1a2e1a060c870921",
"packages/paperclip-runner/src/drivers/preconfigured-home.ts": "sha256:bb286f7ddc6e9597c56d46bf7ff6e3b556c5b680d7e147fd46518724432b083e",
"packages/paperclip-runner/src/drivers/acpx/runtime-sandbox.ts": "sha256:d631dc7a3554c5eb4ed47bef966007245a133862277c96011b1fe1639135f59d",
"packages/paperclip-runner/src/drivers/acpx/sidecar-protocol.ts": "sha256:26dd0cfbef8b2b401de6b7862a4af7f243fb703e23678a1a5ed8fa68d4784d42",
"packages/paperclip-runner/src/drivers/acpx/native-distribution-integrity.ts": "sha256:aed327c389e957483a503cb1bb8b247ee7cd7ff4b528fb4567c39bcb4577690b",
"packages/paperclip-runner/src/providers/grok/launcher.cjs": "sha256:f0b698395a3704ed2ffaf84ea19bdb20c36c8a0a70b7c629c7b6ffe144e59e55",
"packages/paperclip-runner/src/providers/grok/platforms.json": "sha256:931eed3abbf2bf041e6c72e6e9486d976f4352613cf069b216ddf010c9a8e704",
"packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_backend.rs": "sha256:401b2edf0678e3880eed4120137fd1fef96da423955b222f506ddf582a7cc520",
"packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_session.rs": "sha256:e97a7c4d2cf9be9c6e0ada78076a5551b01401518597ab81cb6fbd5a1faf4a5e",
"packages/paperclip-runner/runner/crates/runner-core/src/acpx_sidecar_transport.rs": "sha256:cfbbb39a2e20f449df53ceaea4a6cbd068c954c10405bea2d908b93e3f387fdf"
}
}
}
@@ -0,0 +1,35 @@
{
"commandDigest": "sha256:99a7c5a38e3786fc08cc27e54902b0d36b07be15c61e3ca5645088c301c35067",
"sourceDigest": "sha256:1c16b81b5743471f4b5143943fcfc860f14f8ae0ca9255bc8b2fc8542bdede5a",
"declaration": {
"schema": "paperclip.grok-profile-identity.v1",
"agent": "grok",
"agentProfileVersion": 15,
"agentServerPackage": "builtin:grok-acp",
"agentServerVersion": "1",
"agentRuntimePackage": "native:grok",
"agentRuntimeVersion": "1.0.13",
"requiresProviderPolicy": false,
"acpxVersion": "0.13.1",
"sources": {
"patches/acpx@0.13.1.patch": "sha256:1e7dae8c83bf8620f53f2bea13c175eeff95e7e955783f6f529bb1dcbdcdb6d2",
"packages/paperclip-runner/src/cli/acpx-runtime-sidecar.ts": "sha256:6816fe12cdd274746b5241b75823b3c347b245f3cc03cdbe70f05ec1a0250663",
"packages/paperclip-runner/src/cli/acpx-sidecar-input.ts": "sha256:17948ad74350dc487ab20d24a0fb89daf0b426b98396454fff0e3856e922d82c",
"packages/paperclip-runner/src/drivers/acpx/admission-diagnostics.ts": "sha256:df8f1aa4f2d1bc63b2635bdd09cb8165c8b7681ddcc2618435c7c08ca90475af",
"packages/paperclip-runner/src/drivers/acpx/grok-effort.ts": "sha256:f1e46cf2e1e36b7704bd797b678e3db8db2003f97bdb9d827cfa3d7662698777",
"packages/paperclip-runner/src/drivers/acpx/grok-web-search.ts": "sha256:754b5ca2345c045421f6007f34999508d996e1cea035f0f1952b3d5f00072b9c",
"packages/paperclip-runner/src/drivers/acpx/grok-credentials.ts": "sha256:1c4ff0be6da798b6fcc604d20a9198dcc8523a3806d563b5b5345b7260549f73",
"packages/paperclip-runner/src/drivers/acpx/codex-runtime-adapter.ts": "sha256:c676b83d9dbef86d781069a8b25e160615b288177729974267fe0c2da25afb71",
"packages/paperclip-runner/src/drivers/acpx/runtime-host.ts": "sha256:f44e5555b722553ab7ea1c982d355b1694d3c5fe1cdf19b9868e4bfbaa587b72",
"packages/paperclip-runner/src/drivers/preconfigured-home.ts": "sha256:bb286f7ddc6e9597c56d46bf7ff6e3b556c5b680d7e147fd46518724432b083e",
"packages/paperclip-runner/src/drivers/acpx/runtime-sandbox.ts": "sha256:86dcc0abbbe2e32f88febbbab22f662d8490d438a9e9cb5df04589fdf66ebd88",
"packages/paperclip-runner/src/drivers/acpx/sidecar-protocol.ts": "sha256:26b6b21dad582810d00f46e947e682a9615ee9761c487f6315970d6d014c05ab",
"packages/paperclip-runner/src/drivers/acpx/native-distribution-integrity.ts": "sha256:aed327c389e957483a503cb1bb8b247ee7cd7ff4b528fb4567c39bcb4577690b",
"packages/paperclip-runner/src/providers/grok/launcher.cjs": "sha256:f0b698395a3704ed2ffaf84ea19bdb20c36c8a0a70b7c629c7b6ffe144e59e55",
"packages/paperclip-runner/src/providers/grok/platforms.json": "sha256:931eed3abbf2bf041e6c72e6e9486d976f4352613cf069b216ddf010c9a8e704",
"packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_backend.rs": "sha256:8c1d2bdc1cdd808b51b624b1bd1b576b8f72e72e89fbac3ff1f9beef14878480",
"packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_session.rs": "sha256:fc8d7cce62e0c02efddece8696e8d24f6a9fe19e5288a5e67a01ffbf931a3f6e",
"packages/paperclip-runner/runner/crates/runner-core/src/acpx_sidecar_transport.rs": "sha256:37a552c1a8a59b1815df99b79552e0fda711cfa934055073ffd682cd17d7fb54"
}
}
}
@@ -0,0 +1,35 @@
{
"commandDigest": "sha256:4d6b4c857ba6e63a3eb8c5c406280e4bd0164d3109c940918392c52868bb4263",
"sourceDigest": "sha256:a32325cdbc87730f602b1b9349310fcabab03de77b3e4b07a514948a03628601",
"declaration": {
"schema": "paperclip.grok-profile-identity.v1",
"agent": "grok",
"agentProfileVersion": 16,
"agentServerPackage": "builtin:grok-acp",
"agentServerVersion": "1",
"agentRuntimePackage": "native:grok",
"agentRuntimeVersion": "1.0.13",
"requiresProviderPolicy": false,
"acpxVersion": "0.13.1",
"sources": {
"patches/acpx@0.13.1.patch": "sha256:1e7dae8c83bf8620f53f2bea13c175eeff95e7e955783f6f529bb1dcbdcdb6d2",
"packages/paperclip-runner/src/cli/acpx-runtime-sidecar.ts": "sha256:6816fe12cdd274746b5241b75823b3c347b245f3cc03cdbe70f05ec1a0250663",
"packages/paperclip-runner/src/cli/acpx-sidecar-input.ts": "sha256:17948ad74350dc487ab20d24a0fb89daf0b426b98396454fff0e3856e922d82c",
"packages/paperclip-runner/src/drivers/acpx/admission-diagnostics.ts": "sha256:df8f1aa4f2d1bc63b2635bdd09cb8165c8b7681ddcc2618435c7c08ca90475af",
"packages/paperclip-runner/src/drivers/acpx/grok-effort.ts": "sha256:f1e46cf2e1e36b7704bd797b678e3db8db2003f97bdb9d827cfa3d7662698777",
"packages/paperclip-runner/src/drivers/acpx/grok-web-search.ts": "sha256:754b5ca2345c045421f6007f34999508d996e1cea035f0f1952b3d5f00072b9c",
"packages/paperclip-runner/src/drivers/acpx/grok-credentials.ts": "sha256:1c4ff0be6da798b6fcc604d20a9198dcc8523a3806d563b5b5345b7260549f73",
"packages/paperclip-runner/src/drivers/acpx/codex-runtime-adapter.ts": "sha256:c676b83d9dbef86d781069a8b25e160615b288177729974267fe0c2da25afb71",
"packages/paperclip-runner/src/drivers/acpx/runtime-host.ts": "sha256:f44e5555b722553ab7ea1c982d355b1694d3c5fe1cdf19b9868e4bfbaa587b72",
"packages/paperclip-runner/src/drivers/preconfigured-home.ts": "sha256:bb286f7ddc6e9597c56d46bf7ff6e3b556c5b680d7e147fd46518724432b083e",
"packages/paperclip-runner/src/drivers/acpx/runtime-sandbox.ts": "sha256:86dcc0abbbe2e32f88febbbab22f662d8490d438a9e9cb5df04589fdf66ebd88",
"packages/paperclip-runner/src/drivers/acpx/sidecar-protocol.ts": "sha256:26b6b21dad582810d00f46e947e682a9615ee9761c487f6315970d6d014c05ab",
"packages/paperclip-runner/src/drivers/acpx/native-distribution-integrity.ts": "sha256:aed327c389e957483a503cb1bb8b247ee7cd7ff4b528fb4567c39bcb4577690b",
"packages/paperclip-runner/src/providers/grok/launcher.cjs": "sha256:f0b698395a3704ed2ffaf84ea19bdb20c36c8a0a70b7c629c7b6ffe144e59e55",
"packages/paperclip-runner/src/providers/grok/platforms.json": "sha256:931eed3abbf2bf041e6c72e6e9486d976f4352613cf069b216ddf010c9a8e704",
"packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_backend.rs": "sha256:da62bf0a159b6fe65c3fff5d9ed7ad58ae32cff6b22ed1b787f909e8eaa0f564",
"packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_session.rs": "sha256:fc8d7cce62e0c02efddece8696e8d24f6a9fe19e5288a5e67a01ffbf931a3f6e",
"packages/paperclip-runner/runner/crates/runner-core/src/acpx_sidecar_transport.rs": "sha256:37a552c1a8a59b1815df99b79552e0fda711cfa934055073ffd682cd17d7fb54"
}
}
}
@@ -0,0 +1,35 @@
{
"commandDigest": "sha256:8c9cb917026844e362e1b28da8529662a15da23cad1002ab5bcec79031b1339e",
"sourceDigest": "sha256:57da46dc476d78a55ffb61111a8ab328c879f1d2689f615ef65bc757149b24b7",
"declaration": {
"schema": "paperclip.grok-profile-identity.v1",
"agent": "grok",
"agentProfileVersion": 17,
"agentServerPackage": "builtin:grok-acp",
"agentServerVersion": "1",
"agentRuntimePackage": "native:grok",
"agentRuntimeVersion": "1.0.13",
"requiresProviderPolicy": false,
"acpxVersion": "0.13.1",
"sources": {
"patches/acpx@0.13.1.patch": "sha256:1e7dae8c83bf8620f53f2bea13c175eeff95e7e955783f6f529bb1dcbdcdb6d2",
"packages/paperclip-runner/src/cli/acpx-runtime-sidecar.ts": "sha256:6816fe12cdd274746b5241b75823b3c347b245f3cc03cdbe70f05ec1a0250663",
"packages/paperclip-runner/src/cli/acpx-sidecar-input.ts": "sha256:17948ad74350dc487ab20d24a0fb89daf0b426b98396454fff0e3856e922d82c",
"packages/paperclip-runner/src/drivers/acpx/admission-diagnostics.ts": "sha256:df8f1aa4f2d1bc63b2635bdd09cb8165c8b7681ddcc2618435c7c08ca90475af",
"packages/paperclip-runner/src/drivers/acpx/grok-effort.ts": "sha256:f1e46cf2e1e36b7704bd797b678e3db8db2003f97bdb9d827cfa3d7662698777",
"packages/paperclip-runner/src/drivers/acpx/grok-web-search.ts": "sha256:754b5ca2345c045421f6007f34999508d996e1cea035f0f1952b3d5f00072b9c",
"packages/paperclip-runner/src/drivers/acpx/grok-credentials.ts": "sha256:1c4ff0be6da798b6fcc604d20a9198dcc8523a3806d563b5b5345b7260549f73",
"packages/paperclip-runner/src/drivers/acpx/codex-runtime-adapter.ts": "sha256:c676b83d9dbef86d781069a8b25e160615b288177729974267fe0c2da25afb71",
"packages/paperclip-runner/src/drivers/acpx/runtime-host.ts": "sha256:f44e5555b722553ab7ea1c982d355b1694d3c5fe1cdf19b9868e4bfbaa587b72",
"packages/paperclip-runner/src/drivers/preconfigured-home.ts": "sha256:bb286f7ddc6e9597c56d46bf7ff6e3b556c5b680d7e147fd46518724432b083e",
"packages/paperclip-runner/src/drivers/acpx/runtime-sandbox.ts": "sha256:86dcc0abbbe2e32f88febbbab22f662d8490d438a9e9cb5df04589fdf66ebd88",
"packages/paperclip-runner/src/drivers/acpx/sidecar-protocol.ts": "sha256:26b6b21dad582810d00f46e947e682a9615ee9761c487f6315970d6d014c05ab",
"packages/paperclip-runner/src/drivers/acpx/native-distribution-integrity.ts": "sha256:aed327c389e957483a503cb1bb8b247ee7cd7ff4b528fb4567c39bcb4577690b",
"packages/paperclip-runner/src/providers/grok/launcher.cjs": "sha256:f0b698395a3704ed2ffaf84ea19bdb20c36c8a0a70b7c629c7b6ffe144e59e55",
"packages/paperclip-runner/src/providers/grok/platforms.json": "sha256:931eed3abbf2bf041e6c72e6e9486d976f4352613cf069b216ddf010c9a8e704",
"packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_backend.rs": "sha256:01836e46cba936845c5e612775a9fa5dfc277cdcb7f54cb97da9a334d9580fe1",
"packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_session.rs": "sha256:fc8d7cce62e0c02efddece8696e8d24f6a9fe19e5288a5e67a01ffbf931a3f6e",
"packages/paperclip-runner/runner/crates/runner-core/src/acpx_sidecar_transport.rs": "sha256:37a552c1a8a59b1815df99b79552e0fda711cfa934055073ffd682cd17d7fb54"
}
}
}
@@ -0,0 +1,36 @@
{
"commandDigest": "sha256:4996686ac076be94980dc3f2e2ad58aac10b2a70e28e4507c263d7587b33dd4e",
"sourceDigest": "sha256:b10fe1bd9c5e5928d2afe984992093107ce10590e22296e1e3a91897567bfeb6",
"declaration": {
"schema": "paperclip.grok-profile-identity.v1",
"agent": "grok",
"agentProfileVersion": 18,
"agentServerPackage": "builtin:grok-acp",
"agentServerVersion": "1",
"agentRuntimePackage": "native:grok",
"agentRuntimeVersion": "1.0.13",
"requiresProviderPolicy": false,
"acpxVersion": "0.13.1",
"sources": {
"patches/acpx@0.13.1.patch": "sha256:1e7dae8c83bf8620f53f2bea13c175eeff95e7e955783f6f529bb1dcbdcdb6d2",
"packages/paperclip-runner/src/cli/acpx-runtime-sidecar.ts": "sha256:477a05847187159f9c6f07bf90f1c0c1d432a9eb6fdb15d5620daf54443dafd8",
"packages/paperclip-runner/src/cli/acpx-sidecar-input.ts": "sha256:17948ad74350dc487ab20d24a0fb89daf0b426b98396454fff0e3856e922d82c",
"packages/paperclip-runner/src/drivers/acpx/admission-diagnostics.ts": "sha256:df8f1aa4f2d1bc63b2635bdd09cb8165c8b7681ddcc2618435c7c08ca90475af",
"packages/paperclip-runner/src/drivers/acpx/grok-effort.ts": "sha256:f1e46cf2e1e36b7704bd797b678e3db8db2003f97bdb9d827cfa3d7662698777",
"packages/paperclip-runner/src/drivers/acpx/grok-web-search.ts": "sha256:754b5ca2345c045421f6007f34999508d996e1cea035f0f1952b3d5f00072b9c",
"packages/paperclip-runner/src/drivers/acpx/grok-credentials.ts": "sha256:1c4ff0be6da798b6fcc604d20a9198dcc8523a3806d563b5b5345b7260549f73",
"packages/paperclip-runner/src/drivers/acpx/codex-runtime-adapter.ts": "sha256:c676b83d9dbef86d781069a8b25e160615b288177729974267fe0c2da25afb71",
"packages/paperclip-runner/src/drivers/acpx/runtime-host.ts": "sha256:f44e5555b722553ab7ea1c982d355b1694d3c5fe1cdf19b9868e4bfbaa587b72",
"packages/paperclip-runner/src/drivers/preconfigured-home.ts": "sha256:bb286f7ddc6e9597c56d46bf7ff6e3b556c5b680d7e147fd46518724432b083e",
"packages/paperclip-runner/src/drivers/acpx/runtime-sandbox.ts": "sha256:86dcc0abbbe2e32f88febbbab22f662d8490d438a9e9cb5df04589fdf66ebd88",
"packages/paperclip-runner/src/drivers/acpx/sidecar-protocol.ts": "sha256:26b6b21dad582810d00f46e947e682a9615ee9761c487f6315970d6d014c05ab",
"packages/paperclip-runner/src/drivers/acpx/generated-sidecar-contract.ts": "sha256:b60e4b924e827e122860d2a4cc13b465ba748ee521620887c88f3c58c0df6081",
"packages/paperclip-runner/src/drivers/acpx/native-distribution-integrity.ts": "sha256:aed327c389e957483a503cb1bb8b247ee7cd7ff4b528fb4567c39bcb4577690b",
"packages/paperclip-runner/src/providers/grok/launcher.cjs": "sha256:f0b698395a3704ed2ffaf84ea19bdb20c36c8a0a70b7c629c7b6ffe144e59e55",
"packages/paperclip-runner/src/providers/grok/platforms.json": "sha256:931eed3abbf2bf041e6c72e6e9486d976f4352613cf069b216ddf010c9a8e704",
"packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_backend.rs": "sha256:01836e46cba936845c5e612775a9fa5dfc277cdcb7f54cb97da9a334d9580fe1",
"packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_session.rs": "sha256:fc8d7cce62e0c02efddece8696e8d24f6a9fe19e5288a5e67a01ffbf931a3f6e",
"packages/paperclip-runner/runner/crates/runner-core/src/acpx_sidecar_transport.rs": "sha256:37a552c1a8a59b1815df99b79552e0fda711cfa934055073ffd682cd17d7fb54"
}
}
}
@@ -0,0 +1,28 @@
{
"declaration": {
"schema": "paperclip.kimi-profile-identity.v1",
"agent": "kimi",
"agentProfileVersion": 1,
"agentServerPackage": "@moonshot-ai/kimi-code",
"agentServerVersion": "2.3.3",
"agentRuntimePackage": null,
"agentRuntimeVersion": null,
"requiresProviderPolicy": true,
"qualificationStatus": "pending",
"acpxVersion": "0.13.1",
"sources": {
"scripts/patch-kimi-runtime.mjs": "sha256:94a141bcd76dfa5a92ecf9ff51623474a5b46e4fe9a5955c0e030a6fbe00af62",
"scripts/kimi-instructions-runtime.mjs": "sha256:7697cd40f1123ce607ec61548dde1c31dff496f3fd7aed1afbe75bbe434e7859",
"scripts/materialize-kimi-distribution.mjs": "sha256:7d61f91d2b32a8d22e5949619faed009c2fded8e034e84a2615a76548e2aa4d0",
"scripts/provision-kimi.mjs": "sha256:d11a6320b47c1549572f192e6a3d532b4c48a7f2499afd91539626c04e917bca",
"scripts/kimi-distribution/package.json": "sha256:13511f26a31248e42063c49eeaf6235b7448df12049c1bf45c2170cc20767175",
"scripts/kimi-distribution/package-lock.json": "sha256:ff2cf7356dc031cac15d9f3339cf82bd1811399af59396e2d7629648c21298cf",
"src/drivers/acpx/kimi-closure-pins.ts": "sha256:9c291ba7a09e1dd5a6774e7c096c1e0829bb99d48aef927880890944e6676d45",
"src/drivers/acpx/kimi-config.ts": "sha256:718e238d97922211fa95e3df88a40321bf1ac2b63b395cd2e8f03e89b56616ed",
"src/drivers/acpx/kimi-installation.ts": "sha256:753a1f8505bcfaff83ac76c425e45e4ff780861a6b6b0fbcb71e96c0c482669d",
"src/drivers/acpx/kimi-instructions.ts": "sha256:a04e2d17aac37da2463c8a2c057f9e922ecdb68d9e922e9288e0445c870f9a36",
"src/drivers/acpx/instruction-admission.ts": "sha256:371c17f328abed44f90ac37f3b686e1c0a0d6b647518e62935262ecc31450b16"
}
},
"commandDigest": "sha256:260b99cef27309297ebf1366c6f588bcd83b2c35e4374106bdae2315a0edb84c"
}
@@ -0,0 +1,48 @@
{
"declaration": {
"schema": "paperclip.kimi-profile-identity.v1",
"agent": "kimi",
"agentProfileVersion": 10,
"agentServerPackage": "@moonshot-ai/kimi-code",
"agentServerVersion": "2.3.3",
"agentRuntimePackage": null,
"agentRuntimeVersion": null,
"requiresProviderPolicy": true,
"qualificationStatus": "pending",
"acpxVersion": "0.13.1",
"sources": {
"scripts/patch-kimi-runtime.mjs": "sha256:dd2f3608a875cf49e9093a9b76d6bda77fa9df6067fb5d5c40765d701247d97b",
"scripts/kimi-instructions-runtime.mjs": "sha256:c9a62629a7ed58119ed383a4ffdcc8def4337f1c429bb95363d41b8ffb23a746",
"scripts/materialize-kimi-distribution.mjs": "sha256:8960525611571023a18832e7b0fa8673dc52fd289433d6e555de066f68e9e879",
"scripts/provision-kimi.mjs": "sha256:b234438e37acd5f3698382bc53f14babd261bbf041334f8f793c055d4f694045",
"scripts/kimi-distribution/package.json": "sha256:3abd5a37af052ac1e4417f675453ed47b433edfa3e072c42bb7725811cfe7bbb",
"scripts/kimi-distribution/package-lock.json": "sha256:87f854ddd7f92254ccd8596b85962684ec176f92e93863771843bf416825f16b",
"src/drivers/acpx/kimi-closure-pins.ts": "sha256:d1ffc2f0be70c2f7eba3c5c67d3a24394b5bb5aed879003a31e333d189f50e2f",
"src/drivers/acpx/kimi-config.ts": "sha256:2307b7dd06bf33f2474243c801ee7d1a0a692ab3b47d2c709b6b4397ac4919c2",
"src/drivers/acpx/kimi-installation.ts": "sha256:83b9d821b5dda0a09b40d8828e6ac3b4ebeaafb58467ee14847c7ffa2efde453",
"src/drivers/acpx/kimi-instructions.ts": "sha256:6b306f98ba4c9ebe40cac24edc952f58177f4014def37718ed017ca2018f2991",
"src/drivers/acpx/instruction-admission.ts": "sha256:adf5301e86f2b652679f1b18d00659b9b7214d16539dbd12ef9041586ee97944",
"src/drivers/acpx/kimi-runtime-files.ts": "sha256:9ff7ea33588c423a50d0194b4327aa2840bbd8bdc7da9ec4b6da62fa827f054b",
"src/configured-environment.ts": "sha256:a872e5b939c496955615ce87889ad27eb1ba2a9d8fc25e6bb74e03b1c2293feb",
"src/drivers/acpx/environment.ts": "sha256:a6733e28a9468b744e1e72f1af0c2236e17372e51a9a3ba254a406e085591d2d",
"src/drivers/acpx/codex-runtime-adapter.ts": "sha256:601cbfe4e2811f771a3a59bf23fdbb05e33a04901af987f2ff96a8acf56374a3",
"src/drivers/acpx/runtime-host.ts": "sha256:981a18aad23e34c3c675123d1dd0a920748821bad88885bb1a2e1a060c870921",
"src/drivers/acpx/runtime-sandbox.ts": "sha256:d631dc7a3554c5eb4ed47bef966007245a133862277c96011b1fe1639135f59d",
"src/cli/acpx-runtime-sidecar.ts": "sha256:152ec3e5066695c7a28b56cb9b4d5fbd30500c8e7beee54efb9a33fc8a532c9d",
"scripts/build-verified-provider-entrypoints.mjs": "sha256:2860a13ee316924221c3bf4944e97ecde23c2f582270924b80e1e41648e21f31",
"src/drivers/acpx/kimi-models.ts": "sha256:9d4bb2d1e0db4f929ed819150c1b030dbf3c917d15d15acb7418db2479dd7a92",
"src/drivers/acpx/kimi-metadata-probe.ts": "sha256:56151bc4c58d5ba88018edb3588cd6f22451a4d83b2a129c9e23ab3c94cf2978",
"src/cli/kimi-metadata-probe.ts": "sha256:953cb37cbf16accde2f81848ad4d64c7c30355b02952f6528f966eee1511fbf9",
"src/drivers/acpx/kimi-message-boundary.ts": "sha256:11dbdabaa07d7909540b5041c642f3f60b20b660f72150e7b39155cf6abbfdd0",
"src/drivers/acpx/codex-acpx-driver.ts": "sha256:9ee8f25f1ebcd44af15f12a46e5735980083672cd317f44cd10cf2e77699e352",
"src/drivers/acpx/sidecar-protocol.ts": "sha256:26dd0cfbef8b2b401de6b7862a4af7f243fb703e23678a1a5ed8fa68d4784d42",
"src/drivers/acpx/acp-edit-context.ts": "sha256:7be0bd911bc6bb3587e57d25ab5e75a961801ad0c58f06e713dd64cfe17a3c43",
"src/drivers/acpx/acp-permission-adapter.ts": "sha256:444482de2abb23d9c9c39a3a93bc9b27af241db56f8329e9935bb5b603c08ae0",
"src/drivers/acpx/safe-locations.ts": "sha256:f39a81da395b6e23aa2a1a45572a28846e5e81bfd3d764d9a456f74a79c752e9",
"src/drivers/acpx/generated-sidecar-contract.ts": "sha256:1161eabd82e26133e3b3db3ab567f65d52808b03f176e93497e02c8330349fb4",
"src/semantic-tools/redaction.ts": "sha256:ad6770c69269087951790e2e87e22ac088e3d432769adf17ebc865ed512e6c4f",
"runner/crates/runner-core/src/acpx_provider_state.rs": "sha256:be0e1006763902efb6bdd3952edd58058ab9139859647d413ada4c853110a324"
}
},
"commandDigest": "sha256:c8a39af9d580cdb5fe20a3333a566e2f97a1b4ec3a0025cb647d2144df358604"
}
@@ -0,0 +1,48 @@
{
"declaration": {
"schema": "paperclip.kimi-profile-identity.v1",
"agent": "kimi",
"agentProfileVersion": 11,
"agentServerPackage": "@moonshot-ai/kimi-code",
"agentServerVersion": "2.3.3",
"agentRuntimePackage": null,
"agentRuntimeVersion": null,
"requiresProviderPolicy": true,
"qualificationStatus": "pending",
"acpxVersion": "0.13.1",
"sources": {
"scripts/patch-kimi-runtime.mjs": "sha256:dd2f3608a875cf49e9093a9b76d6bda77fa9df6067fb5d5c40765d701247d97b",
"scripts/kimi-instructions-runtime.mjs": "sha256:c9a62629a7ed58119ed383a4ffdcc8def4337f1c429bb95363d41b8ffb23a746",
"scripts/materialize-kimi-distribution.mjs": "sha256:8960525611571023a18832e7b0fa8673dc52fd289433d6e555de066f68e9e879",
"scripts/provision-kimi.mjs": "sha256:b234438e37acd5f3698382bc53f14babd261bbf041334f8f793c055d4f694045",
"scripts/kimi-distribution/package.json": "sha256:3abd5a37af052ac1e4417f675453ed47b433edfa3e072c42bb7725811cfe7bbb",
"scripts/kimi-distribution/package-lock.json": "sha256:87f854ddd7f92254ccd8596b85962684ec176f92e93863771843bf416825f16b",
"src/drivers/acpx/kimi-closure-pins.ts": "sha256:d1ffc2f0be70c2f7eba3c5c67d3a24394b5bb5aed879003a31e333d189f50e2f",
"src/drivers/acpx/kimi-config.ts": "sha256:2307b7dd06bf33f2474243c801ee7d1a0a692ab3b47d2c709b6b4397ac4919c2",
"src/drivers/acpx/kimi-installation.ts": "sha256:83b9d821b5dda0a09b40d8828e6ac3b4ebeaafb58467ee14847c7ffa2efde453",
"src/drivers/acpx/kimi-instructions.ts": "sha256:6b306f98ba4c9ebe40cac24edc952f58177f4014def37718ed017ca2018f2991",
"src/drivers/acpx/instruction-admission.ts": "sha256:adf5301e86f2b652679f1b18d00659b9b7214d16539dbd12ef9041586ee97944",
"src/drivers/acpx/kimi-runtime-files.ts": "sha256:9ff7ea33588c423a50d0194b4327aa2840bbd8bdc7da9ec4b6da62fa827f054b",
"src/configured-environment.ts": "sha256:a872e5b939c496955615ce87889ad27eb1ba2a9d8fc25e6bb74e03b1c2293feb",
"src/drivers/acpx/environment.ts": "sha256:a6733e28a9468b744e1e72f1af0c2236e17372e51a9a3ba254a406e085591d2d",
"src/drivers/acpx/codex-runtime-adapter.ts": "sha256:601cbfe4e2811f771a3a59bf23fdbb05e33a04901af987f2ff96a8acf56374a3",
"src/drivers/acpx/runtime-host.ts": "sha256:981a18aad23e34c3c675123d1dd0a920748821bad88885bb1a2e1a060c870921",
"src/drivers/acpx/runtime-sandbox.ts": "sha256:d631dc7a3554c5eb4ed47bef966007245a133862277c96011b1fe1639135f59d",
"src/cli/acpx-runtime-sidecar.ts": "sha256:152ec3e5066695c7a28b56cb9b4d5fbd30500c8e7beee54efb9a33fc8a532c9d",
"scripts/build-verified-provider-entrypoints.mjs": "sha256:70f7b314e86a22ad2df192eb6ff984e5f286002e165eec71292fff75064f7b9f",
"src/drivers/acpx/kimi-models.ts": "sha256:9d4bb2d1e0db4f929ed819150c1b030dbf3c917d15d15acb7418db2479dd7a92",
"src/drivers/acpx/kimi-metadata-probe.ts": "sha256:56151bc4c58d5ba88018edb3588cd6f22451a4d83b2a129c9e23ab3c94cf2978",
"src/cli/kimi-metadata-probe.ts": "sha256:953cb37cbf16accde2f81848ad4d64c7c30355b02952f6528f966eee1511fbf9",
"src/drivers/acpx/kimi-message-boundary.ts": "sha256:11dbdabaa07d7909540b5041c642f3f60b20b660f72150e7b39155cf6abbfdd0",
"src/drivers/acpx/codex-acpx-driver.ts": "sha256:9ee8f25f1ebcd44af15f12a46e5735980083672cd317f44cd10cf2e77699e352",
"src/drivers/acpx/sidecar-protocol.ts": "sha256:26dd0cfbef8b2b401de6b7862a4af7f243fb703e23678a1a5ed8fa68d4784d42",
"src/drivers/acpx/acp-edit-context.ts": "sha256:7be0bd911bc6bb3587e57d25ab5e75a961801ad0c58f06e713dd64cfe17a3c43",
"src/drivers/acpx/acp-permission-adapter.ts": "sha256:444482de2abb23d9c9c39a3a93bc9b27af241db56f8329e9935bb5b603c08ae0",
"src/drivers/acpx/safe-locations.ts": "sha256:f39a81da395b6e23aa2a1a45572a28846e5e81bfd3d764d9a456f74a79c752e9",
"src/drivers/acpx/generated-sidecar-contract.ts": "sha256:1161eabd82e26133e3b3db3ab567f65d52808b03f176e93497e02c8330349fb4",
"src/semantic-tools/redaction.ts": "sha256:ad6770c69269087951790e2e87e22ac088e3d432769adf17ebc865ed512e6c4f",
"runner/crates/runner-core/src/acpx_provider_state.rs": "sha256:be0e1006763902efb6bdd3952edd58058ab9139859647d413ada4c853110a324"
}
},
"commandDigest": "sha256:6bdee2692b41fea57ac9be810a5009bb5d65650beca9c816e310b27f0974cccc"
}
@@ -0,0 +1,72 @@
{
"declaration": {
"schema": "paperclip.kimi-profile-identity.v1",
"agent": "kimi",
"agentProfileVersion": 13,
"agentServerPackage": "@moonshot-ai/kimi-code",
"agentServerVersion": "2.3.3",
"agentRuntimePackage": null,
"agentRuntimeVersion": null,
"requiresProviderPolicy": true,
"qualificationStatus": "pending",
"acpxVersion": "0.13.1",
"sources": {
"scripts/patch-kimi-runtime.mjs": "sha256:dd2f3608a875cf49e9093a9b76d6bda77fa9df6067fb5d5c40765d701247d97b",
"scripts/kimi-instructions-runtime.mjs": "sha256:c9a62629a7ed58119ed383a4ffdcc8def4337f1c429bb95363d41b8ffb23a746",
"scripts/materialize-kimi-distribution.mjs": "sha256:8960525611571023a18832e7b0fa8673dc52fd289433d6e555de066f68e9e879",
"scripts/provision-kimi.mjs": "sha256:b234438e37acd5f3698382bc53f14babd261bbf041334f8f793c055d4f694045",
"scripts/kimi-distribution/package.json": "sha256:3abd5a37af052ac1e4417f675453ed47b433edfa3e072c42bb7725811cfe7bbb",
"scripts/kimi-distribution/package-lock.json": "sha256:87f854ddd7f92254ccd8596b85962684ec176f92e93863771843bf416825f16b",
"src/drivers/acpx/kimi-closure-pins.ts": "sha256:d1ffc2f0be70c2f7eba3c5c67d3a24394b5bb5aed879003a31e333d189f50e2f",
"src/drivers/acpx/kimi-config.ts": "sha256:2307b7dd06bf33f2474243c801ee7d1a0a692ab3b47d2c709b6b4397ac4919c2",
"src/drivers/acpx/kimi-installation.ts": "sha256:83b9d821b5dda0a09b40d8828e6ac3b4ebeaafb58467ee14847c7ffa2efde453",
"src/drivers/acpx/kimi-instructions.ts": "sha256:6b306f98ba4c9ebe40cac24edc952f58177f4014def37718ed017ca2018f2991",
"src/drivers/acpx/session-context-admission.ts": "sha256:c4026e6c51b9a7fb731b178e03077917f6f0f71835da0cdb083dce11f2ddae93",
"src/drivers/acpx/kimi-runtime-files.ts": "sha256:9ff7ea33588c423a50d0194b4327aa2840bbd8bdc7da9ec4b6da62fa827f054b",
"src/configured-environment.ts": "sha256:a872e5b939c496955615ce87889ad27eb1ba2a9d8fc25e6bb74e03b1c2293feb",
"src/drivers/acpx/environment.ts": "sha256:9ace39a71ba287838c1b9c56bed141248e805fd017eb8490770c3b579567e55b",
"src/drivers/acpx/codex-runtime-adapter.ts": "sha256:c676b83d9dbef86d781069a8b25e160615b288177729974267fe0c2da25afb71",
"src/drivers/acpx/runtime-host.ts": "sha256:f44e5555b722553ab7ea1c982d355b1694d3c5fe1cdf19b9868e4bfbaa587b72",
"src/drivers/acpx/runtime-sandbox.ts": "sha256:86dcc0abbbe2e32f88febbbab22f662d8490d438a9e9cb5df04589fdf66ebd88",
"src/cli/acpx-runtime-sidecar.ts": "sha256:6816fe12cdd274746b5241b75823b3c347b245f3cc03cdbe70f05ec1a0250663",
"scripts/build-verified-provider-entrypoints.mjs": "sha256:70f7b314e86a22ad2df192eb6ff984e5f286002e165eec71292fff75064f7b9f",
"src/drivers/acpx/kimi-models.ts": "sha256:9d4bb2d1e0db4f929ed819150c1b030dbf3c917d15d15acb7418db2479dd7a92",
"src/drivers/acpx/kimi-metadata-probe.ts": "sha256:0f6f2865065500d77460ec761fa13661a3149dd34422812201026709f7cb84f8",
"src/cli/kimi-metadata-probe.ts": "sha256:306e2caca87977c3ea511ec43c937fd801f4c8cf9b4337b1ed8a3e315c1cdb37",
"src/drivers/acpx/kimi-message-boundary.ts": "sha256:11dbdabaa07d7909540b5041c642f3f60b20b660f72150e7b39155cf6abbfdd0",
"src/drivers/acpx/codex-acpx-driver.ts": "sha256:d11dea41590394225d622c2f4b4141ede0445fdb529fec1d6ce3fe749f354234",
"src/drivers/acpx/sidecar-protocol.ts": "sha256:26b6b21dad582810d00f46e947e682a9615ee9761c487f6315970d6d014c05ab",
"src/drivers/acpx/acp-edit-context.ts": "sha256:7be0bd911bc6bb3587e57d25ab5e75a961801ad0c58f06e713dd64cfe17a3c43",
"src/drivers/acpx/acp-permission-adapter.ts": "sha256:444482de2abb23d9c9c39a3a93bc9b27af241db56f8329e9935bb5b603c08ae0",
"src/drivers/acpx/safe-locations.ts": "sha256:f39a81da395b6e23aa2a1a45572a28846e5e81bfd3d764d9a456f74a79c752e9",
"src/drivers/acpx/generated-sidecar-contract.ts": "sha256:1161eabd82e26133e3b3db3ab567f65d52808b03f176e93497e02c8330349fb4",
"src/semantic-tools/redaction.ts": "sha256:ad6770c69269087951790e2e87e22ac088e3d432769adf17ebc865ed512e6c4f",
"runner/crates/runner-core/src/acpx_provider_state.rs": "sha256:be0e1006763902efb6bdd3952edd58058ab9139859647d413ada4c853110a324",
"src/drivers/acpx/candidate-admission.ts": "sha256:72a3c8b1e97f6aeedaeff4fd4a75edfbd2104000607517c190dd4c34f6d6327c",
"src/drivers/acpx/qualified-profiles.ts": "sha256:f0c3948ba291aa4b9ae54c0aebd2bd7967739ce40d48ccbe717491500fd9105b",
"src/drivers/acpx/profile-installation.ts": "sha256:d229b6afef695991313acdf490991136d40d638359665e0c48afb675af94f863",
"src/drivers/acpx/driver-profile.ts": "sha256:857d75d11cb1b82d22275443dab79ef674214b35f103dff30e1ab14915d80a47",
"src/live/runnerd-codex-transport.ts": "sha256:1554851fd4b32561e8575b8ad72a28528172dfc0372a014d11f02668991d5e49",
"runner/crates/runner-core/src/acpx_candidate_admission.rs": "sha256:65e14dd8cd7304c92b63972801dad535d52b5a6a4ea499f6c315dbc82ce258d6",
"runner/crates/runner-core/src/acpx_provider_backend.rs": "sha256:8c1d2bdc1cdd808b51b624b1bd1b576b8f72e72e89fbac3ff1f9beef14878480",
"runner/crates/runner-core/src/acpx_provider_session.rs": "sha256:fc8d7cce62e0c02efddece8696e8d24f6a9fe19e5288a5e67a01ffbf931a3f6e",
"runner/crates/runner-core/src/acpx_sidecar_transport.rs": "sha256:37a552c1a8a59b1815df99b79552e0fda711cfa934055073ffd682cd17d7fb54",
"runner/crates/runner-core/src/native_provider_backend.rs": "sha256:d2aa6a65be9195e5db0fbe83103be7f6897dedb8195872191d3eb0392cb4a1cc",
"runner/crates/runner-core/src/durable/runner.rs": "sha256:7335562b0393c011fe60d7820afeea965345478dd72757dbf91f025d44d3c36c",
"runner/crates/runner-core/src/durable/mod.rs": "sha256:b5989da5304dfdfe04d0060a0a249e853c784af1cdd933bcf0d5a8fd07f0e895",
"src/provider-events.ts": "sha256:a6b77d969fd2f767dd8e583e81b907973c429b6e32d2c2d7fef0856f3568f07a",
"src/native-session-runtime.ts": "sha256:cbcefbceb0b2a24b0909cbb8361df6b8853b4f50b21d66328bc483951a8246ea",
"src/control-plane/durable-prp-control-plane.ts": "sha256:a8a8bed373cdd18397a762b9f67b04c789d9e5d63208f06c5ebe000faff090ac",
"src/drivers/codex/codex-harness-session.ts": "sha256:bb9bb3daac53ce5955ddf8f56839c7a57ae60c74ea3cdd08895ab6912fcf7851",
"src/drivers/codex/codex-session-notifications.ts": "sha256:23361d25e660ef7919bfb54f21727b899e7d6f8865307604ee15eca7488afeaa",
"src/drivers/codex/codex-session-state.ts": "sha256:c2f1059c5f1532cf3c2059792324a6f55d0c06ec8a62c3a4ab2c9451d617988a",
"runner/crates/runner-core/src/provider_backend.rs": "sha256:03a57d83901f0fbccfb7bcdaeae79baf8918f658ceb3463406211431944a461e",
"runner/crates/runner-core/src/provider_bridge.rs": "sha256:d417840ecd87e1a8a407629074f6c64bad4071c5e9add4b5a2aef0b3403b5529",
"runner/crates/runner-core/src/provider_events.rs": "sha256:91dfa4985691f86ab7f60514e46d924fb815900d6d456d78780bd94d29bff461",
"runner/crates/runner-core/src/acpx_event_scope.rs": "sha256:088f4b5c67b5663cbce2ef0b8b8cb3e6fe04d2b5c9cfa7a8139f8f0bf91e476e",
"runner/crates/runner-core/src/acpx_event_payload.rs": "sha256:f3b2f6ea9c2e9cf673790eef2f7d4e738c36a2e6347e1fd61ae501793cef1f15",
"scripts/generate-acpx-profiles.mjs": "sha256:e878a3f8afa9ce38940e61343cfbdc55d6431e9574108ca5fb17f0c72ead7423"
}
},
"commandDigest": "sha256:8fcd50b260d61244499bb2de97be745dca7652b9901acd04aa54a135c4bf23cb"
}
@@ -0,0 +1,72 @@
{
"declaration": {
"schema": "paperclip.kimi-profile-identity.v1",
"agent": "kimi",
"agentProfileVersion": 14,
"agentServerPackage": "@moonshot-ai/kimi-code",
"agentServerVersion": "2.3.3",
"agentRuntimePackage": null,
"agentRuntimeVersion": null,
"requiresProviderPolicy": true,
"qualificationStatus": "pending",
"acpxVersion": "0.13.1",
"sources": {
"scripts/patch-kimi-runtime.mjs": "sha256:dd2f3608a875cf49e9093a9b76d6bda77fa9df6067fb5d5c40765d701247d97b",
"scripts/kimi-instructions-runtime.mjs": "sha256:c9a62629a7ed58119ed383a4ffdcc8def4337f1c429bb95363d41b8ffb23a746",
"scripts/materialize-kimi-distribution.mjs": "sha256:8960525611571023a18832e7b0fa8673dc52fd289433d6e555de066f68e9e879",
"scripts/provision-kimi.mjs": "sha256:b234438e37acd5f3698382bc53f14babd261bbf041334f8f793c055d4f694045",
"scripts/kimi-distribution/package.json": "sha256:3abd5a37af052ac1e4417f675453ed47b433edfa3e072c42bb7725811cfe7bbb",
"scripts/kimi-distribution/package-lock.json": "sha256:87f854ddd7f92254ccd8596b85962684ec176f92e93863771843bf416825f16b",
"src/drivers/acpx/kimi-closure-pins.ts": "sha256:d1ffc2f0be70c2f7eba3c5c67d3a24394b5bb5aed879003a31e333d189f50e2f",
"src/drivers/acpx/kimi-config.ts": "sha256:2307b7dd06bf33f2474243c801ee7d1a0a692ab3b47d2c709b6b4397ac4919c2",
"src/drivers/acpx/kimi-installation.ts": "sha256:83b9d821b5dda0a09b40d8828e6ac3b4ebeaafb58467ee14847c7ffa2efde453",
"src/drivers/acpx/kimi-instructions.ts": "sha256:6b306f98ba4c9ebe40cac24edc952f58177f4014def37718ed017ca2018f2991",
"src/drivers/acpx/session-context-admission.ts": "sha256:c4026e6c51b9a7fb731b178e03077917f6f0f71835da0cdb083dce11f2ddae93",
"src/drivers/acpx/kimi-runtime-files.ts": "sha256:9ff7ea33588c423a50d0194b4327aa2840bbd8bdc7da9ec4b6da62fa827f054b",
"src/configured-environment.ts": "sha256:a872e5b939c496955615ce87889ad27eb1ba2a9d8fc25e6bb74e03b1c2293feb",
"src/drivers/acpx/environment.ts": "sha256:9ace39a71ba287838c1b9c56bed141248e805fd017eb8490770c3b579567e55b",
"src/drivers/acpx/codex-runtime-adapter.ts": "sha256:c676b83d9dbef86d781069a8b25e160615b288177729974267fe0c2da25afb71",
"src/drivers/acpx/runtime-host.ts": "sha256:f44e5555b722553ab7ea1c982d355b1694d3c5fe1cdf19b9868e4bfbaa587b72",
"src/drivers/acpx/runtime-sandbox.ts": "sha256:86dcc0abbbe2e32f88febbbab22f662d8490d438a9e9cb5df04589fdf66ebd88",
"src/cli/acpx-runtime-sidecar.ts": "sha256:6816fe12cdd274746b5241b75823b3c347b245f3cc03cdbe70f05ec1a0250663",
"scripts/build-verified-provider-entrypoints.mjs": "sha256:70f7b314e86a22ad2df192eb6ff984e5f286002e165eec71292fff75064f7b9f",
"src/drivers/acpx/kimi-models.ts": "sha256:9d4bb2d1e0db4f929ed819150c1b030dbf3c917d15d15acb7418db2479dd7a92",
"src/drivers/acpx/kimi-metadata-probe.ts": "sha256:0f6f2865065500d77460ec761fa13661a3149dd34422812201026709f7cb84f8",
"src/cli/kimi-metadata-probe.ts": "sha256:306e2caca87977c3ea511ec43c937fd801f4c8cf9b4337b1ed8a3e315c1cdb37",
"src/drivers/acpx/kimi-message-boundary.ts": "sha256:11dbdabaa07d7909540b5041c642f3f60b20b660f72150e7b39155cf6abbfdd0",
"src/drivers/acpx/codex-acpx-driver.ts": "sha256:d11dea41590394225d622c2f4b4141ede0445fdb529fec1d6ce3fe749f354234",
"src/drivers/acpx/sidecar-protocol.ts": "sha256:26b6b21dad582810d00f46e947e682a9615ee9761c487f6315970d6d014c05ab",
"src/drivers/acpx/acp-edit-context.ts": "sha256:7be0bd911bc6bb3587e57d25ab5e75a961801ad0c58f06e713dd64cfe17a3c43",
"src/drivers/acpx/acp-permission-adapter.ts": "sha256:444482de2abb23d9c9c39a3a93bc9b27af241db56f8329e9935bb5b603c08ae0",
"src/drivers/acpx/safe-locations.ts": "sha256:f39a81da395b6e23aa2a1a45572a28846e5e81bfd3d764d9a456f74a79c752e9",
"src/drivers/acpx/generated-sidecar-contract.ts": "sha256:1161eabd82e26133e3b3db3ab567f65d52808b03f176e93497e02c8330349fb4",
"src/semantic-tools/redaction.ts": "sha256:ad6770c69269087951790e2e87e22ac088e3d432769adf17ebc865ed512e6c4f",
"runner/crates/runner-core/src/acpx_provider_state.rs": "sha256:be0e1006763902efb6bdd3952edd58058ab9139859647d413ada4c853110a324",
"src/drivers/acpx/candidate-admission.ts": "sha256:72a3c8b1e97f6aeedaeff4fd4a75edfbd2104000607517c190dd4c34f6d6327c",
"src/drivers/acpx/qualified-profiles.ts": "sha256:f0c3948ba291aa4b9ae54c0aebd2bd7967739ce40d48ccbe717491500fd9105b",
"src/drivers/acpx/profile-installation.ts": "sha256:d229b6afef695991313acdf490991136d40d638359665e0c48afb675af94f863",
"src/drivers/acpx/driver-profile.ts": "sha256:857d75d11cb1b82d22275443dab79ef674214b35f103dff30e1ab14915d80a47",
"src/live/runnerd-codex-transport.ts": "sha256:1554851fd4b32561e8575b8ad72a28528172dfc0372a014d11f02668991d5e49",
"runner/crates/runner-core/src/acpx_candidate_admission.rs": "sha256:65e14dd8cd7304c92b63972801dad535d52b5a6a4ea499f6c315dbc82ce258d6",
"runner/crates/runner-core/src/acpx_provider_backend.rs": "sha256:da62bf0a159b6fe65c3fff5d9ed7ad58ae32cff6b22ed1b787f909e8eaa0f564",
"runner/crates/runner-core/src/acpx_provider_session.rs": "sha256:fc8d7cce62e0c02efddece8696e8d24f6a9fe19e5288a5e67a01ffbf931a3f6e",
"runner/crates/runner-core/src/acpx_sidecar_transport.rs": "sha256:37a552c1a8a59b1815df99b79552e0fda711cfa934055073ffd682cd17d7fb54",
"runner/crates/runner-core/src/native_provider_backend.rs": "sha256:d2aa6a65be9195e5db0fbe83103be7f6897dedb8195872191d3eb0392cb4a1cc",
"runner/crates/runner-core/src/durable/runner.rs": "sha256:7335562b0393c011fe60d7820afeea965345478dd72757dbf91f025d44d3c36c",
"runner/crates/runner-core/src/durable/mod.rs": "sha256:b5989da5304dfdfe04d0060a0a249e853c784af1cdd933bcf0d5a8fd07f0e895",
"src/provider-events.ts": "sha256:a6b77d969fd2f767dd8e583e81b907973c429b6e32d2c2d7fef0856f3568f07a",
"src/native-session-runtime.ts": "sha256:cbcefbceb0b2a24b0909cbb8361df6b8853b4f50b21d66328bc483951a8246ea",
"src/control-plane/durable-prp-control-plane.ts": "sha256:a8a8bed373cdd18397a762b9f67b04c789d9e5d63208f06c5ebe000faff090ac",
"src/drivers/codex/codex-harness-session.ts": "sha256:bb9bb3daac53ce5955ddf8f56839c7a57ae60c74ea3cdd08895ab6912fcf7851",
"src/drivers/codex/codex-session-notifications.ts": "sha256:23361d25e660ef7919bfb54f21727b899e7d6f8865307604ee15eca7488afeaa",
"src/drivers/codex/codex-session-state.ts": "sha256:c2f1059c5f1532cf3c2059792324a6f55d0c06ec8a62c3a4ab2c9451d617988a",
"runner/crates/runner-core/src/provider_backend.rs": "sha256:03a57d83901f0fbccfb7bcdaeae79baf8918f658ceb3463406211431944a461e",
"runner/crates/runner-core/src/provider_bridge.rs": "sha256:d417840ecd87e1a8a407629074f6c64bad4071c5e9add4b5a2aef0b3403b5529",
"runner/crates/runner-core/src/provider_events.rs": "sha256:91dfa4985691f86ab7f60514e46d924fb815900d6d456d78780bd94d29bff461",
"runner/crates/runner-core/src/acpx_event_scope.rs": "sha256:088f4b5c67b5663cbce2ef0b8b8cb3e6fe04d2b5c9cfa7a8139f8f0bf91e476e",
"runner/crates/runner-core/src/acpx_event_payload.rs": "sha256:f3b2f6ea9c2e9cf673790eef2f7d4e738c36a2e6347e1fd61ae501793cef1f15",
"scripts/generate-acpx-profiles.mjs": "sha256:e878a3f8afa9ce38940e61343cfbdc55d6431e9574108ca5fb17f0c72ead7423"
}
},
"commandDigest": "sha256:d917ef7222b71c8dbe1df46c33f7a439f15492db862307aa6b5427bf82ed196b"
}
@@ -0,0 +1,72 @@
{
"declaration": {
"schema": "paperclip.kimi-profile-identity.v1",
"agent": "kimi",
"agentProfileVersion": 15,
"agentServerPackage": "@moonshot-ai/kimi-code",
"agentServerVersion": "2.3.3",
"agentRuntimePackage": null,
"agentRuntimeVersion": null,
"requiresProviderPolicy": true,
"qualificationStatus": "pending",
"acpxVersion": "0.13.1",
"sources": {
"scripts/patch-kimi-runtime.mjs": "sha256:dd2f3608a875cf49e9093a9b76d6bda77fa9df6067fb5d5c40765d701247d97b",
"scripts/kimi-instructions-runtime.mjs": "sha256:c9a62629a7ed58119ed383a4ffdcc8def4337f1c429bb95363d41b8ffb23a746",
"scripts/materialize-kimi-distribution.mjs": "sha256:8960525611571023a18832e7b0fa8673dc52fd289433d6e555de066f68e9e879",
"scripts/provision-kimi.mjs": "sha256:b234438e37acd5f3698382bc53f14babd261bbf041334f8f793c055d4f694045",
"scripts/kimi-distribution/package.json": "sha256:3abd5a37af052ac1e4417f675453ed47b433edfa3e072c42bb7725811cfe7bbb",
"scripts/kimi-distribution/package-lock.json": "sha256:87f854ddd7f92254ccd8596b85962684ec176f92e93863771843bf416825f16b",
"src/drivers/acpx/kimi-closure-pins.ts": "sha256:d1ffc2f0be70c2f7eba3c5c67d3a24394b5bb5aed879003a31e333d189f50e2f",
"src/drivers/acpx/kimi-config.ts": "sha256:2307b7dd06bf33f2474243c801ee7d1a0a692ab3b47d2c709b6b4397ac4919c2",
"src/drivers/acpx/kimi-installation.ts": "sha256:83b9d821b5dda0a09b40d8828e6ac3b4ebeaafb58467ee14847c7ffa2efde453",
"src/drivers/acpx/kimi-instructions.ts": "sha256:6b306f98ba4c9ebe40cac24edc952f58177f4014def37718ed017ca2018f2991",
"src/drivers/acpx/session-context-admission.ts": "sha256:c4026e6c51b9a7fb731b178e03077917f6f0f71835da0cdb083dce11f2ddae93",
"src/drivers/acpx/kimi-runtime-files.ts": "sha256:9ff7ea33588c423a50d0194b4327aa2840bbd8bdc7da9ec4b6da62fa827f054b",
"src/configured-environment.ts": "sha256:a872e5b939c496955615ce87889ad27eb1ba2a9d8fc25e6bb74e03b1c2293feb",
"src/drivers/acpx/environment.ts": "sha256:9ace39a71ba287838c1b9c56bed141248e805fd017eb8490770c3b579567e55b",
"src/drivers/acpx/codex-runtime-adapter.ts": "sha256:c676b83d9dbef86d781069a8b25e160615b288177729974267fe0c2da25afb71",
"src/drivers/acpx/runtime-host.ts": "sha256:f44e5555b722553ab7ea1c982d355b1694d3c5fe1cdf19b9868e4bfbaa587b72",
"src/drivers/acpx/runtime-sandbox.ts": "sha256:86dcc0abbbe2e32f88febbbab22f662d8490d438a9e9cb5df04589fdf66ebd88",
"src/cli/acpx-runtime-sidecar.ts": "sha256:6816fe12cdd274746b5241b75823b3c347b245f3cc03cdbe70f05ec1a0250663",
"scripts/build-verified-provider-entrypoints.mjs": "sha256:70f7b314e86a22ad2df192eb6ff984e5f286002e165eec71292fff75064f7b9f",
"src/drivers/acpx/kimi-models.ts": "sha256:9d4bb2d1e0db4f929ed819150c1b030dbf3c917d15d15acb7418db2479dd7a92",
"src/drivers/acpx/kimi-metadata-probe.ts": "sha256:0f6f2865065500d77460ec761fa13661a3149dd34422812201026709f7cb84f8",
"src/cli/kimi-metadata-probe.ts": "sha256:306e2caca87977c3ea511ec43c937fd801f4c8cf9b4337b1ed8a3e315c1cdb37",
"src/drivers/acpx/kimi-message-boundary.ts": "sha256:11dbdabaa07d7909540b5041c642f3f60b20b660f72150e7b39155cf6abbfdd0",
"src/drivers/acpx/codex-acpx-driver.ts": "sha256:d11dea41590394225d622c2f4b4141ede0445fdb529fec1d6ce3fe749f354234",
"src/drivers/acpx/sidecar-protocol.ts": "sha256:26b6b21dad582810d00f46e947e682a9615ee9761c487f6315970d6d014c05ab",
"src/drivers/acpx/acp-edit-context.ts": "sha256:7be0bd911bc6bb3587e57d25ab5e75a961801ad0c58f06e713dd64cfe17a3c43",
"src/drivers/acpx/acp-permission-adapter.ts": "sha256:444482de2abb23d9c9c39a3a93bc9b27af241db56f8329e9935bb5b603c08ae0",
"src/drivers/acpx/safe-locations.ts": "sha256:f39a81da395b6e23aa2a1a45572a28846e5e81bfd3d764d9a456f74a79c752e9",
"src/drivers/acpx/generated-sidecar-contract.ts": "sha256:1161eabd82e26133e3b3db3ab567f65d52808b03f176e93497e02c8330349fb4",
"src/semantic-tools/redaction.ts": "sha256:ad6770c69269087951790e2e87e22ac088e3d432769adf17ebc865ed512e6c4f",
"runner/crates/runner-core/src/acpx_provider_state.rs": "sha256:be0e1006763902efb6bdd3952edd58058ab9139859647d413ada4c853110a324",
"src/drivers/acpx/candidate-admission.ts": "sha256:72a3c8b1e97f6aeedaeff4fd4a75edfbd2104000607517c190dd4c34f6d6327c",
"src/drivers/acpx/qualified-profiles.ts": "sha256:f0c3948ba291aa4b9ae54c0aebd2bd7967739ce40d48ccbe717491500fd9105b",
"src/drivers/acpx/profile-installation.ts": "sha256:d229b6afef695991313acdf490991136d40d638359665e0c48afb675af94f863",
"src/drivers/acpx/driver-profile.ts": "sha256:857d75d11cb1b82d22275443dab79ef674214b35f103dff30e1ab14915d80a47",
"src/live/runnerd-codex-transport.ts": "sha256:1554851fd4b32561e8575b8ad72a28528172dfc0372a014d11f02668991d5e49",
"runner/crates/runner-core/src/acpx_candidate_admission.rs": "sha256:65e14dd8cd7304c92b63972801dad535d52b5a6a4ea499f6c315dbc82ce258d6",
"runner/crates/runner-core/src/acpx_provider_backend.rs": "sha256:01836e46cba936845c5e612775a9fa5dfc277cdcb7f54cb97da9a334d9580fe1",
"runner/crates/runner-core/src/acpx_provider_session.rs": "sha256:fc8d7cce62e0c02efddece8696e8d24f6a9fe19e5288a5e67a01ffbf931a3f6e",
"runner/crates/runner-core/src/acpx_sidecar_transport.rs": "sha256:37a552c1a8a59b1815df99b79552e0fda711cfa934055073ffd682cd17d7fb54",
"runner/crates/runner-core/src/native_provider_backend.rs": "sha256:d2aa6a65be9195e5db0fbe83103be7f6897dedb8195872191d3eb0392cb4a1cc",
"runner/crates/runner-core/src/durable/runner.rs": "sha256:7335562b0393c011fe60d7820afeea965345478dd72757dbf91f025d44d3c36c",
"runner/crates/runner-core/src/durable/mod.rs": "sha256:b5989da5304dfdfe04d0060a0a249e853c784af1cdd933bcf0d5a8fd07f0e895",
"src/provider-events.ts": "sha256:a6b77d969fd2f767dd8e583e81b907973c429b6e32d2c2d7fef0856f3568f07a",
"src/native-session-runtime.ts": "sha256:cbcefbceb0b2a24b0909cbb8361df6b8853b4f50b21d66328bc483951a8246ea",
"src/control-plane/durable-prp-control-plane.ts": "sha256:a8a8bed373cdd18397a762b9f67b04c789d9e5d63208f06c5ebe000faff090ac",
"src/drivers/codex/codex-harness-session.ts": "sha256:bb9bb3daac53ce5955ddf8f56839c7a57ae60c74ea3cdd08895ab6912fcf7851",
"src/drivers/codex/codex-session-notifications.ts": "sha256:23361d25e660ef7919bfb54f21727b899e7d6f8865307604ee15eca7488afeaa",
"src/drivers/codex/codex-session-state.ts": "sha256:c2f1059c5f1532cf3c2059792324a6f55d0c06ec8a62c3a4ab2c9451d617988a",
"runner/crates/runner-core/src/provider_backend.rs": "sha256:03a57d83901f0fbccfb7bcdaeae79baf8918f658ceb3463406211431944a461e",
"runner/crates/runner-core/src/provider_bridge.rs": "sha256:d417840ecd87e1a8a407629074f6c64bad4071c5e9add4b5a2aef0b3403b5529",
"runner/crates/runner-core/src/provider_events.rs": "sha256:91dfa4985691f86ab7f60514e46d924fb815900d6d456d78780bd94d29bff461",
"runner/crates/runner-core/src/acpx_event_scope.rs": "sha256:088f4b5c67b5663cbce2ef0b8b8cb3e6fe04d2b5c9cfa7a8139f8f0bf91e476e",
"runner/crates/runner-core/src/acpx_event_payload.rs": "sha256:f3b2f6ea9c2e9cf673790eef2f7d4e738c36a2e6347e1fd61ae501793cef1f15",
"scripts/generate-acpx-profiles.mjs": "sha256:e878a3f8afa9ce38940e61343cfbdc55d6431e9574108ca5fb17f0c72ead7423"
}
},
"commandDigest": "sha256:606c0cfcaee89813bef5531d666eb208e839116de27cdd46035a08d38c00ecce"
}
@@ -0,0 +1,75 @@
{
"declaration": {
"schema": "paperclip.kimi-profile-identity.v1",
"agent": "kimi",
"agentProfileVersion": 16,
"agentServerPackage": "@moonshot-ai/kimi-code",
"agentServerVersion": "2.3.3",
"agentRuntimePackage": null,
"agentRuntimeVersion": null,
"requiresProviderPolicy": true,
"qualificationStatus": "pending",
"acpxVersion": "0.13.1",
"sources": {
"scripts/patch-kimi-runtime.mjs": "sha256:dd2f3608a875cf49e9093a9b76d6bda77fa9df6067fb5d5c40765d701247d97b",
"scripts/kimi-instructions-runtime.mjs": "sha256:c9a62629a7ed58119ed383a4ffdcc8def4337f1c429bb95363d41b8ffb23a746",
"scripts/materialize-kimi-distribution.mjs": "sha256:8960525611571023a18832e7b0fa8673dc52fd289433d6e555de066f68e9e879",
"scripts/provision-kimi.mjs": "sha256:b234438e37acd5f3698382bc53f14babd261bbf041334f8f793c055d4f694045",
"scripts/kimi-distribution/package.json": "sha256:3abd5a37af052ac1e4417f675453ed47b433edfa3e072c42bb7725811cfe7bbb",
"scripts/kimi-distribution/package-lock.json": "sha256:87f854ddd7f92254ccd8596b85962684ec176f92e93863771843bf416825f16b",
"src/drivers/acpx/kimi-closure-pins.ts": "sha256:d1ffc2f0be70c2f7eba3c5c67d3a24394b5bb5aed879003a31e333d189f50e2f",
"src/drivers/acpx/kimi-config.ts": "sha256:2307b7dd06bf33f2474243c801ee7d1a0a692ab3b47d2c709b6b4397ac4919c2",
"src/drivers/acpx/kimi-installation.ts": "sha256:83b9d821b5dda0a09b40d8828e6ac3b4ebeaafb58467ee14847c7ffa2efde453",
"src/drivers/acpx/kimi-instructions.ts": "sha256:6b306f98ba4c9ebe40cac24edc952f58177f4014def37718ed017ca2018f2991",
"src/drivers/acpx/session-context-admission.ts": "sha256:c4026e6c51b9a7fb731b178e03077917f6f0f71835da0cdb083dce11f2ddae93",
"src/drivers/acpx/kimi-runtime-files.ts": "sha256:9ff7ea33588c423a50d0194b4327aa2840bbd8bdc7da9ec4b6da62fa827f054b",
"src/configured-environment.ts": "sha256:a872e5b939c496955615ce87889ad27eb1ba2a9d8fc25e6bb74e03b1c2293feb",
"src/drivers/acpx/environment.ts": "sha256:9ace39a71ba287838c1b9c56bed141248e805fd017eb8490770c3b579567e55b",
"src/drivers/acpx/codex-runtime-adapter.ts": "sha256:c676b83d9dbef86d781069a8b25e160615b288177729974267fe0c2da25afb71",
"src/drivers/acpx/runtime-host.ts": "sha256:f44e5555b722553ab7ea1c982d355b1694d3c5fe1cdf19b9868e4bfbaa587b72",
"src/drivers/acpx/runtime-sandbox.ts": "sha256:86dcc0abbbe2e32f88febbbab22f662d8490d438a9e9cb5df04589fdf66ebd88",
"src/cli/acpx-runtime-sidecar.ts": "sha256:477a05847187159f9c6f07bf90f1c0c1d432a9eb6fdb15d5620daf54443dafd8",
"scripts/build-verified-provider-entrypoints.mjs": "sha256:70f7b314e86a22ad2df192eb6ff984e5f286002e165eec71292fff75064f7b9f",
"src/drivers/acpx/kimi-models.ts": "sha256:9d4bb2d1e0db4f929ed819150c1b030dbf3c917d15d15acb7418db2479dd7a92",
"src/drivers/acpx/kimi-metadata-probe.ts": "sha256:0f6f2865065500d77460ec761fa13661a3149dd34422812201026709f7cb84f8",
"src/cli/kimi-metadata-probe.ts": "sha256:306e2caca87977c3ea511ec43c937fd801f4c8cf9b4337b1ed8a3e315c1cdb37",
"src/drivers/acpx/kimi-message-boundary.ts": "sha256:11dbdabaa07d7909540b5041c642f3f60b20b660f72150e7b39155cf6abbfdd0",
"src/drivers/acpx/codex-acpx-driver.ts": "sha256:d11dea41590394225d622c2f4b4141ede0445fdb529fec1d6ce3fe749f354234",
"src/drivers/acpx/sidecar-protocol.ts": "sha256:26b6b21dad582810d00f46e947e682a9615ee9761c487f6315970d6d014c05ab",
"src/drivers/acpx/acp-edit-context.ts": "sha256:7be0bd911bc6bb3587e57d25ab5e75a961801ad0c58f06e713dd64cfe17a3c43",
"src/drivers/acpx/acp-permission-adapter.ts": "sha256:444482de2abb23d9c9c39a3a93bc9b27af241db56f8329e9935bb5b603c08ae0",
"src/drivers/acpx/safe-locations.ts": "sha256:f39a81da395b6e23aa2a1a45572a28846e5e81bfd3d764d9a456f74a79c752e9",
"src/drivers/acpx/generated-sidecar-contract.ts": "sha256:b60e4b924e827e122860d2a4cc13b465ba748ee521620887c88f3c58c0df6081",
"src/semantic-tools/redaction.ts": "sha256:ad6770c69269087951790e2e87e22ac088e3d432769adf17ebc865ed512e6c4f",
"runner/crates/runner-core/src/acpx_provider_state.rs": "sha256:be0e1006763902efb6bdd3952edd58058ab9139859647d413ada4c853110a324",
"src/drivers/acpx/candidate-admission.ts": "sha256:72a3c8b1e97f6aeedaeff4fd4a75edfbd2104000607517c190dd4c34f6d6327c",
"src/drivers/acpx/qualified-profiles.ts": "sha256:f0c3948ba291aa4b9ae54c0aebd2bd7967739ce40d48ccbe717491500fd9105b",
"src/drivers/acpx/profile-installation.ts": "sha256:d229b6afef695991313acdf490991136d40d638359665e0c48afb675af94f863",
"src/drivers/acpx/driver-profile.ts": "sha256:857d75d11cb1b82d22275443dab79ef674214b35f103dff30e1ab14915d80a47",
"src/live/runnerd-codex-transport.ts": "sha256:1554851fd4b32561e8575b8ad72a28528172dfc0372a014d11f02668991d5e49",
"runner/crates/runner-core/src/acpx_candidate_admission.rs": "sha256:65e14dd8cd7304c92b63972801dad535d52b5a6a4ea499f6c315dbc82ce258d6",
"runner/crates/runner-core/src/acpx_provider_backend.rs": "sha256:01836e46cba936845c5e612775a9fa5dfc277cdcb7f54cb97da9a334d9580fe1",
"runner/crates/runner-core/src/acpx_provider_session.rs": "sha256:fc8d7cce62e0c02efddece8696e8d24f6a9fe19e5288a5e67a01ffbf931a3f6e",
"runner/crates/runner-core/src/acpx_sidecar_transport.rs": "sha256:37a552c1a8a59b1815df99b79552e0fda711cfa934055073ffd682cd17d7fb54",
"runner/crates/runner-core/src/native_provider_backend.rs": "sha256:d2aa6a65be9195e5db0fbe83103be7f6897dedb8195872191d3eb0392cb4a1cc",
"runner/crates/runner-core/src/durable/runner.rs": "sha256:7335562b0393c011fe60d7820afeea965345478dd72757dbf91f025d44d3c36c",
"runner/crates/runner-core/src/durable/mod.rs": "sha256:b5989da5304dfdfe04d0060a0a249e853c784af1cdd933bcf0d5a8fd07f0e895",
"src/contracts/runtime-context.ts": "sha256:152d7187ce1dc91a15377d368776555c9897d6e018b65f0f59a92dcdbd6497d9",
"src/contracts/generated-runtime-context-contract.ts": "sha256:069f4bc3c4dc95888f30d3fea331adb0ee0a164d09f4f70ec9c132f24f69c7dd",
"src/contracts/runtime-context-prompts.ts": "sha256:fff5755dba9b7dce8a5f10ff6ac6d5ed06b92ed079ce1e0a44ac72f2ce7869c1",
"src/provider-events.ts": "sha256:a6b77d969fd2f767dd8e583e81b907973c429b6e32d2c2d7fef0856f3568f07a",
"src/native-session-runtime.ts": "sha256:cbcefbceb0b2a24b0909cbb8361df6b8853b4f50b21d66328bc483951a8246ea",
"src/control-plane/durable-prp-control-plane.ts": "sha256:a8a8bed373cdd18397a762b9f67b04c789d9e5d63208f06c5ebe000faff090ac",
"src/drivers/codex/codex-harness-session.ts": "sha256:bb9bb3daac53ce5955ddf8f56839c7a57ae60c74ea3cdd08895ab6912fcf7851",
"src/drivers/codex/codex-session-notifications.ts": "sha256:23361d25e660ef7919bfb54f21727b899e7d6f8865307604ee15eca7488afeaa",
"src/drivers/codex/codex-session-state.ts": "sha256:c2f1059c5f1532cf3c2059792324a6f55d0c06ec8a62c3a4ab2c9451d617988a",
"runner/crates/runner-core/src/provider_backend.rs": "sha256:03a57d83901f0fbccfb7bcdaeae79baf8918f658ceb3463406211431944a461e",
"runner/crates/runner-core/src/provider_bridge.rs": "sha256:d417840ecd87e1a8a407629074f6c64bad4071c5e9add4b5a2aef0b3403b5529",
"runner/crates/runner-core/src/provider_events.rs": "sha256:91dfa4985691f86ab7f60514e46d924fb815900d6d456d78780bd94d29bff461",
"runner/crates/runner-core/src/acpx_event_scope.rs": "sha256:088f4b5c67b5663cbce2ef0b8b8cb3e6fe04d2b5c9cfa7a8139f8f0bf91e476e",
"runner/crates/runner-core/src/acpx_event_payload.rs": "sha256:f3b2f6ea9c2e9cf673790eef2f7d4e738c36a2e6347e1fd61ae501793cef1f15",
"scripts/generate-acpx-profiles.mjs": "sha256:e878a3f8afa9ce38940e61343cfbdc55d6431e9574108ca5fb17f0c72ead7423"
}
},
"commandDigest": "sha256:e027eb4ec2f99fc485b76a3e17212810d0cefa873c55365b44b4e5ba815439bf"
}
@@ -0,0 +1,28 @@
{
"declaration": {
"schema": "paperclip.kimi-profile-identity.v1",
"agent": "kimi",
"agentProfileVersion": 2,
"agentServerPackage": "@moonshot-ai/kimi-code",
"agentServerVersion": "2.3.3",
"agentRuntimePackage": null,
"agentRuntimeVersion": null,
"requiresProviderPolicy": true,
"qualificationStatus": "pending",
"acpxVersion": "0.13.1",
"sources": {
"scripts/patch-kimi-runtime.mjs": "sha256:7bea24c45b7f32a72168bf6da57cb6fd472cd2ef9fac0c196b7f050e81a8b62a",
"scripts/kimi-instructions-runtime.mjs": "sha256:7697cd40f1123ce607ec61548dde1c31dff496f3fd7aed1afbe75bbe434e7859",
"scripts/materialize-kimi-distribution.mjs": "sha256:7d61f91d2b32a8d22e5949619faed009c2fded8e034e84a2615a76548e2aa4d0",
"scripts/provision-kimi.mjs": "sha256:d11a6320b47c1549572f192e6a3d532b4c48a7f2499afd91539626c04e917bca",
"scripts/kimi-distribution/package.json": "sha256:13511f26a31248e42063c49eeaf6235b7448df12049c1bf45c2170cc20767175",
"scripts/kimi-distribution/package-lock.json": "sha256:ff2cf7356dc031cac15d9f3339cf82bd1811399af59396e2d7629648c21298cf",
"src/drivers/acpx/kimi-closure-pins.ts": "sha256:b40e709dbd3fdc04bd1bc1f2ec5a34a2eb09b353a11d3b1b86c35bbe3dcbd513",
"src/drivers/acpx/kimi-config.ts": "sha256:b927c3f2437094d4492a1499559247220e154fcae719ecfe75bb63defc7df05e",
"src/drivers/acpx/kimi-installation.ts": "sha256:753a1f8505bcfaff83ac76c425e45e4ff780861a6b6b0fbcb71e96c0c482669d",
"src/drivers/acpx/kimi-instructions.ts": "sha256:a04e2d17aac37da2463c8a2c057f9e922ecdb68d9e922e9288e0445c870f9a36",
"src/drivers/acpx/instruction-admission.ts": "sha256:371c17f328abed44f90ac37f3b686e1c0a0d6b647518e62935262ecc31450b16"
}
},
"commandDigest": "sha256:103f3a3d84353fa6d3244fe51065bd62159dc32adb88a69d16dbde495c012360"
}
Loaded 100 of 111 files, more files were not shown because too many files have changed in this diff. Show more