@phyzess/pappra 0.1.0-beta.13 → 0.1.0-beta.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +134 -15
- package/assets/integrations/skills/pappra/SKILL.md +28 -7
- package/assets/integrations/skills/pappra/references/collaboration.md +633 -0
- package/assets/integrations/skills/pappra/references/environment.md +360 -0
- package/assets/integrations/skills/pappra/references/hosts.md +20 -0
- package/assets/integrations/skills/pappra/references/operations.md +36 -5
- package/dist/adapters/pi/recovery-extension.d.ts +65 -0
- package/dist/adapters/pi/recovery-extension.js +238 -0
- package/dist/adapters/pi/session-transition-extension.d.ts +30 -0
- package/dist/adapters/pi/session-transition-extension.js +265 -0
- package/dist/app/automatic-handoff-events.d.ts +26 -0
- package/dist/app/automatic-handoff-events.js +134 -0
- package/dist/app/bounded-file.d.ts +2 -0
- package/dist/app/bounded-file.js +2 -0
- package/dist/app/capability-evidence/claude.d.ts +37 -0
- package/dist/app/capability-evidence/claude.js +206 -0
- package/dist/app/capability-evidence/codex.d.ts +35 -0
- package/dist/app/capability-evidence/codex.js +193 -0
- package/dist/app/capability-evidence/index.d.ts +33 -0
- package/dist/app/capability-evidence/index.js +117 -0
- package/dist/app/capability-evidence/pi.d.ts +73 -0
- package/dist/app/capability-evidence/pi.js +669 -0
- package/dist/app/capability-evidence/shared.d.ts +69 -0
- package/dist/app/capability-evidence/shared.js +195 -0
- package/dist/app/collab-auto-handoff.d.ts +55 -0
- package/dist/app/collab-auto-handoff.js +384 -0
- package/dist/app/collab-bindings.d.ts +57 -0
- package/dist/app/collab-bindings.js +1006 -0
- package/dist/app/collab-bootstrap-transport.d.ts +163 -0
- package/dist/app/collab-bootstrap-transport.js +769 -0
- package/dist/app/collab-bootstrap.d.ts +137 -0
- package/dist/app/collab-bootstrap.js +3455 -0
- package/dist/app/collab-handoff.d.ts +12 -0
- package/dist/app/collab-handoff.js +511 -0
- package/dist/app/collab-messages.d.ts +2 -0
- package/dist/app/collab-messages.js +2 -0
- package/dist/app/collab-notify.d.ts +156 -0
- package/dist/app/collab-notify.js +1208 -0
- package/dist/app/collab-preflight.d.ts +34 -0
- package/dist/app/collab-preflight.js +96 -0
- package/dist/app/collab-recovery-executor.d.ts +161 -0
- package/dist/app/collab-recovery-executor.js +1153 -0
- package/dist/app/collab-recovery-projection.d.ts +103 -0
- package/dist/app/collab-recovery-projection.js +659 -0
- package/dist/app/collab-recovery.d.ts +25 -0
- package/dist/app/collab-recovery.js +429 -0
- package/dist/app/collab-resources.d.ts +16 -0
- package/dist/app/collab-resources.js +278 -0
- package/dist/app/collab-role-events.d.ts +22 -0
- package/dist/app/collab-role-events.js +329 -0
- package/dist/app/collab-role-orchestration.d.ts +53 -0
- package/dist/app/collab-role-orchestration.js +601 -0
- package/dist/app/collab-role-plan.d.ts +81 -0
- package/dist/app/collab-role-plan.js +504 -0
- package/dist/app/collab-role-repair.d.ts +109 -0
- package/dist/app/collab-role-repair.js +821 -0
- package/dist/app/collab-rollover.d.ts +263 -0
- package/dist/app/collab-rollover.js +1112 -0
- package/dist/app/collab-route.d.ts +64 -0
- package/dist/app/collab-route.js +240 -0
- package/dist/app/collab-session-transition.d.ts +221 -0
- package/dist/app/collab-session-transition.js +3334 -0
- package/dist/app/collab-state.d.ts +7 -0
- package/dist/app/collab-state.js +162 -0
- package/dist/app/collab-task-store.d.ts +22 -0
- package/dist/app/collab-task-store.js +204 -0
- package/dist/app/collab-work-execution.d.ts +127 -0
- package/dist/app/collab-work-execution.js +1027 -0
- package/dist/app/collab-work-plan.d.ts +87 -0
- package/dist/app/collab-work-plan.js +437 -0
- package/dist/app/collaboration.d.ts +8 -2
- package/dist/app/collaboration.js +101 -12
- package/dist/app/doctor.js +108 -5
- package/dist/app/host-mcp.js +34 -8
- package/dist/app/host-probe.js +4 -4
- package/dist/app/init.d.ts +58 -4
- package/dist/app/init.js +768 -155
- package/dist/app/managed-pi-bootstrap-admission.d.ts +14 -0
- package/dist/app/managed-pi-bootstrap-admission.js +104 -0
- package/dist/app/managed-pi-bootstrap-refresh.d.ts +10 -0
- package/dist/app/managed-pi-bootstrap-refresh.js +78 -0
- package/dist/app/managed-pi-delivery.d.ts +8 -0
- package/dist/app/managed-pi-delivery.js +110 -0
- package/dist/app/managed-pi-handoff-receiver.d.ts +15 -0
- package/dist/app/managed-pi-handoff-receiver.js +263 -0
- package/dist/app/managed-pi-handoff-reference.d.ts +3 -0
- package/dist/app/managed-pi-handoff-reference.js +60 -0
- package/dist/app/managed-pi-herdr.d.ts +21 -0
- package/dist/app/managed-pi-herdr.js +185 -0
- package/dist/app/managed-pi-initial-admission.d.ts +28 -0
- package/dist/app/managed-pi-initial-admission.js +416 -0
- package/dist/app/managed-pi-initial-launch.d.ts +5 -0
- package/dist/app/managed-pi-initial-launch.js +61 -0
- package/dist/app/managed-pi-native-observation.d.ts +36 -0
- package/dist/app/managed-pi-native-observation.js +191 -0
- package/dist/app/managed-pi-readiness.d.ts +29 -0
- package/dist/app/managed-pi-readiness.js +288 -0
- package/dist/app/managed-pi-repair-stop.d.ts +21 -0
- package/dist/app/managed-pi-repair-stop.js +371 -0
- package/dist/app/managed-pi-resume-admission.d.ts +32 -0
- package/dist/app/managed-pi-resume-admission.js +618 -0
- package/dist/app/managed-pi-retirement.d.ts +28 -0
- package/dist/app/managed-pi-retirement.js +112 -0
- package/dist/app/managed-pi-sdk-control.d.ts +7 -0
- package/dist/app/managed-pi-sdk-control.js +169 -0
- package/dist/app/managed-pi-sdk-runtime.d.ts +3 -0
- package/dist/app/managed-pi-sdk-runtime.js +483 -0
- package/dist/app/managed-pi-source-admission.d.ts +14 -0
- package/dist/app/managed-pi-source-admission.js +323 -0
- package/dist/app/managed-pi-transition-host.d.ts +36 -0
- package/dist/app/managed-pi-transition-host.js +292 -0
- package/dist/app/managed-pi.d.ts +54 -0
- package/dist/app/managed-pi.js +248 -0
- package/dist/app/shell-readiness.d.ts +66 -0
- package/dist/app/shell-readiness.js +368 -0
- package/dist/app/task-pin.d.ts +2 -23
- package/dist/app/task-pin.js +2 -113
- package/dist/cli/commands/collaboration-binding.d.ts +13 -0
- package/dist/cli/commands/collaboration-binding.js +118 -0
- package/dist/cli/commands/collaboration-bootstrap.d.ts +10 -0
- package/dist/cli/commands/collaboration-bootstrap.js +84 -0
- package/dist/cli/commands/collaboration-capabilities.d.ts +13 -0
- package/dist/cli/commands/collaboration-capabilities.js +127 -0
- package/dist/cli/commands/collaboration-handoff.d.ts +13 -0
- package/dist/cli/commands/collaboration-handoff.js +102 -0
- package/dist/cli/commands/collaboration-message.d.ts +17 -0
- package/dist/cli/commands/collaboration-message.js +177 -0
- package/dist/cli/commands/collaboration-plan.d.ts +8 -0
- package/dist/cli/commands/collaboration-plan.js +108 -0
- package/dist/cli/commands/collaboration-preflight.d.ts +10 -0
- package/dist/cli/commands/collaboration-preflight.js +167 -0
- package/dist/cli/commands/collaboration-recovery-run.d.ts +46 -0
- package/dist/cli/commands/collaboration-recovery-run.js +224 -0
- package/dist/cli/commands/collaboration-recovery.d.ts +11 -0
- package/dist/cli/commands/collaboration-recovery.js +104 -0
- package/dist/cli/commands/collaboration-resources.d.ts +11 -0
- package/dist/cli/commands/collaboration-resources.js +96 -0
- package/dist/cli/commands/collaboration-role-plan.d.ts +9 -0
- package/dist/cli/commands/collaboration-role-plan.js +69 -0
- package/dist/cli/commands/collaboration-role-run.d.ts +11 -0
- package/dist/cli/commands/collaboration-role-run.js +128 -0
- package/dist/cli/commands/collaboration-rollover.d.ts +10 -0
- package/dist/cli/commands/collaboration-rollover.js +103 -0
- package/dist/cli/commands/collaboration-state.d.ts +10 -0
- package/dist/cli/commands/collaboration-state.js +96 -0
- package/dist/cli/commands/collaboration-transition.d.ts +10 -0
- package/dist/cli/commands/collaboration-transition.js +75 -0
- package/dist/cli/commands/collaboration-work-run.d.ts +34 -0
- package/dist/cli/commands/collaboration-work-run.js +178 -0
- package/dist/cli/commands/collaboration.d.ts +4 -0
- package/dist/cli/commands/collaboration.js +39 -4
- package/dist/cli/commands/continuity.js +2 -6
- package/dist/cli/commands/docs.d.ts +2 -0
- package/dist/cli/commands/docs.js +89 -15
- package/dist/cli/commands/host.d.ts +7 -1
- package/dist/cli/commands/host.js +122 -7
- package/dist/cli/commands/init.d.ts +20 -3
- package/dist/cli/commands/init.js +897 -232
- package/dist/cli/commands/mcp.d.ts +1 -0
- package/dist/cli/commands/mcp.js +11 -5
- package/dist/cli/commands/repair.d.ts +12 -0
- package/dist/cli/commands/repair.js +41 -0
- package/dist/cli/commands/runtime.d.ts +1 -1
- package/dist/cli/commands/runtime.js +139 -38
- package/dist/cli/commands/session.d.ts +7 -0
- package/dist/cli/commands/session.js +82 -0
- package/dist/cli/commands/task.js +19 -5
- package/dist/cli/run.js +866 -24
- package/dist/code/identity.d.ts +7 -0
- package/dist/code/identity.js +7 -3
- package/dist/code/registration.js +7 -0
- package/dist/code/service.d.ts +9 -0
- package/dist/code/service.js +16 -3
- package/dist/code/text.js +19 -7
- package/dist/collab/admission.d.ts +91 -66
- package/dist/collab/admission.js +21 -6
- package/dist/collab/canonical.d.ts +1 -1
- package/dist/collab/canonical.js +44 -3
- package/dist/collab/envelope.d.ts +2 -2
- package/dist/collab/envelope.js +12 -12
- package/dist/collab/first-work.d.ts +3 -0
- package/dist/collab/first-work.js +15 -0
- package/dist/collab/handoff.d.ts +16 -0
- package/dist/collab/handoff.js +39 -5
- package/dist/collab/index.d.ts +97 -1
- package/dist/collab/index.js +9 -1
- package/dist/collab/messages.js +126 -3
- package/dist/collab/persisted-messages.d.ts +123 -0
- package/dist/collab/persisted-messages.js +496 -0
- package/dist/collab/preflight.d.ts +1 -1
- package/dist/collab/resources.d.ts +13 -3
- package/dist/collab/resources.js +37 -6
- package/dist/collab/rollover.d.ts +311 -0
- package/dist/collab/rollover.js +1024 -0
- package/dist/collab/store.d.ts +1 -0
- package/dist/collab/store.js +1 -4
- package/dist/collab/types.d.ts +2 -354
- package/dist/collab/validation.d.ts +2 -10
- package/dist/collab/validation.js +2 -303
- package/dist/collab/work-plan.d.ts +105 -0
- package/dist/collab/work-plan.js +843 -0
- package/dist/continuity/context.d.ts +11 -2
- package/dist/continuity/context.js +100 -13
- package/dist/continuity/handoff-bundle.d.ts +296 -0
- package/dist/continuity/handoff-bundle.js +477 -0
- package/dist/continuity/index.d.ts +2 -0
- package/dist/continuity/index.js +1 -0
- package/dist/continuity/paths.js +10 -2
- package/dist/continuity/service.js +91 -15
- package/dist/continuity/task-pin.d.ts +24 -0
- package/dist/continuity/task-pin.js +590 -0
- package/dist/doctor.d.ts +1 -0
- package/dist/doctor.js +6 -0
- package/dist/experimental/index.d.ts +13 -0
- package/dist/experimental/index.js +25 -0
- package/dist/experimental/pi.d.ts +4 -0
- package/dist/experimental/pi.js +12 -0
- package/dist/hosts/claude/native.js +1 -1
- package/dist/hosts/codex/native.js +1 -1
- package/dist/hosts/codex/protocol.js +1 -1
- package/dist/hosts/integration/bootstrap-config.d.ts +58 -0
- package/dist/hosts/integration/bootstrap-config.js +254 -0
- package/dist/hosts/integration/bundle-export.d.ts +44 -0
- package/dist/hosts/integration/bundle-export.js +366 -3
- package/dist/hosts/integration/bundle.js +3 -0
- package/dist/hosts/integration/hook.js +36 -9
- package/dist/hosts/integration/pappra-bootstrap-extension.mjs +80 -0
- package/dist/hosts/integration/pappra-extension-runtime.mjs +59 -24631
- package/dist/hosts/integration/pappra-hook.mjs +61 -24749
- package/dist/hosts/integration/pappra-recovery-extension.mjs +259 -0
- package/dist/hosts/integration/pappra-session-transition-extension.mjs +276 -0
- package/dist/hosts/integration/pi-bootstrap-extension.d.ts +36 -0
- package/dist/hosts/integration/pi-bootstrap-extension.js +101 -0
- package/dist/hosts/integration/pi-bootstrap-guard.d.ts +125 -0
- package/dist/hosts/integration/pi-bootstrap-guard.js +438 -0
- package/dist/hosts/integration/pi-bootstrap-runtime.d.ts +63 -0
- package/dist/hosts/integration/pi-bootstrap-runtime.js +223 -0
- package/dist/hosts/integration/pi-native-events.d.ts +112 -0
- package/dist/hosts/integration/pi-native-events.js +348 -0
- package/dist/hosts/integration/pi-rollover-extension.d.ts +166 -0
- package/dist/hosts/integration/pi-rollover-extension.js +431 -0
- package/dist/hosts/integration/recovery-config.d.ts +48 -0
- package/dist/hosts/integration/recovery-config.js +117 -0
- package/dist/hosts/integration/service.d.ts +6 -1
- package/dist/hosts/integration/service.js +485 -35
- package/dist/hosts/integration/support.d.ts +7 -0
- package/dist/hosts/integration/support.js +9 -1
- package/dist/hosts/integration/templates.d.ts +3 -0
- package/dist/hosts/integration/templates.js +26 -3
- package/dist/hosts/pi/managed-host-identity.d.ts +2 -0
- package/dist/hosts/pi/managed-host-identity.js +40 -0
- package/dist/hosts/pi/managed-provider-diagnostics.d.ts +6 -0
- package/dist/hosts/pi/managed-provider-diagnostics.js +184 -0
- package/dist/hosts/pi/managed-sdk-session.d.ts +335 -0
- package/dist/hosts/pi/managed-sdk-session.js +1639 -0
- package/dist/hosts/pi/managed-session-extension.d.ts +20 -0
- package/dist/hosts/pi/managed-session-extension.js +84 -0
- package/dist/hosts/pi/managed-session.d.ts +177 -0
- package/dist/hosts/pi/managed-session.js +1557 -0
- package/dist/hosts/pi/protocol.js +1 -1
- package/dist/hosts/pi/query-result.js +1 -1
- package/dist/hosts/pi/resume-capability.d.ts +41 -0
- package/dist/hosts/pi/resume-capability.js +33 -0
- package/dist/hosts/pi/rpc.d.ts +182 -134
- package/dist/hosts/pi/rpc.js +230 -37
- package/dist/hosts/pilot.d.ts +97 -74
- package/dist/hosts/pilot.js +5 -1
- package/dist/hosts/version.d.ts +3 -0
- package/dist/hosts/version.js +18 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/infra/bounded-file.d.ts +19 -0
- package/dist/infra/bounded-file.js +66 -0
- package/dist/infra/fs.js +10 -2
- package/dist/infra/git.d.ts +29 -0
- package/dist/infra/git.js +45 -9
- package/dist/infra/json-property.d.ts +2 -0
- package/dist/infra/json-property.js +69 -0
- package/dist/infra/json.d.ts +4 -0
- package/dist/infra/json.js +24 -0
- package/dist/infra/owned-process-group.js +1 -1
- package/dist/infra/private-lock.d.ts +16 -0
- package/dist/infra/private-lock.js +148 -0
- package/dist/infra/private-state.d.ts +7 -0
- package/dist/infra/private-state.js +146 -0
- package/dist/infra/process-identity.d.ts +12 -0
- package/dist/infra/process-identity.js +142 -0
- package/dist/infra/validation.d.ts +5 -0
- package/dist/infra/validation.js +15 -0
- package/dist/init.d.ts +1 -0
- package/dist/init.js +6 -0
- package/dist/install/apply.d.ts +9 -1
- package/dist/install/apply.js +176 -12
- package/dist/install/dependencies.d.ts +38 -0
- package/dist/install/dependencies.js +282 -0
- package/dist/install/ownership.js +30 -1
- package/dist/install/references.d.ts +31 -0
- package/dist/install/references.js +208 -0
- package/dist/install/repair.d.ts +37 -0
- package/dist/install/repair.js +798 -0
- package/dist/install/reset-local.d.ts +16 -0
- package/dist/install/reset-local.js +304 -0
- package/dist/install/rollback.d.ts +3 -0
- package/dist/install/rollback.js +9 -3
- package/dist/install/runtime.d.ts +10 -6
- package/dist/install/runtime.js +299 -59
- package/dist/install/source-fingerprint.d.ts +2 -0
- package/dist/install/source-fingerprint.js +103 -0
- package/dist/knowledge/catalog.d.ts +1 -0
- package/dist/knowledge/catalog.js +143 -10
- package/dist/knowledge/journal.js +17 -7
- package/dist/knowledge/paths.js +2 -1
- package/dist/knowledge/refs.js +4 -0
- package/dist/knowledge/register-batch.d.ts +4 -0
- package/dist/knowledge/register-batch.js +225 -0
- package/dist/knowledge/relocate.d.ts +5 -0
- package/dist/knowledge/relocate.js +92 -0
- package/dist/knowledge/scan.js +103 -47
- package/dist/knowledge/service.d.ts +3 -0
- package/dist/knowledge/service.js +33 -1
- package/dist/knowledge/write.d.ts +4 -1
- package/dist/knowledge/write.js +1 -1
- package/dist/mcp/server.d.ts +4 -2
- package/dist/mcp/server.js +87 -136
- package/dist/schemas/collaboration-state-validation.d.ts +6 -0
- package/dist/schemas/collaboration-state-validation.js +342 -0
- package/dist/schemas/collaboration-state.d.ts +436 -0
- package/dist/schemas/collaboration-state.js +1 -0
- package/dist/schemas/collaboration.d.ts +335 -0
- package/dist/schemas/collaboration.js +272 -0
- package/dist/schemas/continuity.d.ts +8 -0
- package/dist/schemas/continuity.js +13 -3
- package/dist/schemas/doctor.d.ts +1 -0
- package/dist/schemas/doctor.js +1 -0
- package/dist/schemas/document.d.ts +61 -0
- package/dist/schemas/document.js +9 -0
- package/dist/schemas/errors.d.ts +1 -0
- package/dist/schemas/errors.js +1 -0
- package/dist/schemas/host.d.ts +24 -0
- package/dist/schemas/host.js +19 -0
- package/dist/schemas/install.d.ts +8 -2
- package/dist/schemas/install.js +11 -1
- package/dist/schemas/managed-pi-execution.d.ts +16 -0
- package/dist/schemas/managed-pi-execution.js +2 -0
- package/dist/schemas/outcome.d.ts +9 -5
- package/dist/workspace/config-file.js +1 -3
- package/dist/workspace/documents.js +12 -2
- package/dist/workspace/repositories.d.ts +7 -0
- package/dist/workspace/repositories.js +14 -5
- package/package.json +35 -35
- package/skills/pappra/SKILL.md +28 -7
- package/skills/pappra/references/collaboration.md +633 -0
- package/skills/pappra/references/environment.md +360 -0
- package/skills/pappra/references/hosts.md +20 -0
- package/skills/pappra/references/operations.md +36 -5
- package/dist/app/collab-from.d.ts +0 -35
- package/dist/app/collab-from.js +0 -84
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { object } from '../../
|
|
1
|
+
import { object } from '../../infra/validation.js';
|
|
2
2
|
const optionalString = (value) => value === undefined || typeof value === 'string';
|
|
3
3
|
function isEntry(value) {
|
|
4
4
|
const item = object(value) ? value['item'] : undefined;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { BootstrapGuardClaim, BootstrapGuardIdentity } from './pi-bootstrap-guard.js';
|
|
2
|
+
import type { BootstrapRuntimeConfig } from './pi-bootstrap-runtime.js';
|
|
3
|
+
/**
|
|
4
|
+
* Explicit, trusted local bootstrap binding for the opt-in Pi successor gate.
|
|
5
|
+
*
|
|
6
|
+
* This module only validates and pins data. It never creates directories, reads task
|
|
7
|
+
* records, claims resources or grants authority: exporting a guard is not writing and a
|
|
8
|
+
* valid pre-transfer record stays a valid export input. The accepted guard/runtime remain
|
|
9
|
+
* the authority for gating; this parser mirrors their limits without changing them.
|
|
10
|
+
*/
|
|
11
|
+
export declare const PI_BOOTSTRAP_CONFIG_SCHEMA = "pappra/pi-bootstrap-config/1";
|
|
12
|
+
export declare const MAX_PI_BOOTSTRAP_CONFIG_BYTES: number;
|
|
13
|
+
export interface PiBootstrapConfigGuard {
|
|
14
|
+
readonly taskId: string;
|
|
15
|
+
readonly intentId: string;
|
|
16
|
+
readonly handoffId: string;
|
|
17
|
+
readonly generation: number;
|
|
18
|
+
readonly subtaskId: string;
|
|
19
|
+
readonly attempt: number;
|
|
20
|
+
readonly inputRevision: string;
|
|
21
|
+
readonly coordinatorEpoch: number;
|
|
22
|
+
readonly successor: BootstrapGuardIdentity;
|
|
23
|
+
readonly claims: readonly BootstrapGuardClaim[];
|
|
24
|
+
}
|
|
25
|
+
export interface PiBootstrapConfig {
|
|
26
|
+
readonly schema: typeof PI_BOOTSTRAP_CONFIG_SCHEMA;
|
|
27
|
+
readonly domainRoot: string;
|
|
28
|
+
readonly taskId: string;
|
|
29
|
+
readonly guard: PiBootstrapConfigGuard;
|
|
30
|
+
}
|
|
31
|
+
export interface PiBootstrapConfigFailure {
|
|
32
|
+
readonly ok: false;
|
|
33
|
+
readonly code: string;
|
|
34
|
+
readonly message: string;
|
|
35
|
+
}
|
|
36
|
+
export type PiBootstrapConfigResult = {
|
|
37
|
+
readonly ok: true;
|
|
38
|
+
readonly config: PiBootstrapConfig;
|
|
39
|
+
/** Canonical `<domainRoot>/tasks/<taskId>` directory that must already exist. */
|
|
40
|
+
readonly taskRoot: string;
|
|
41
|
+
/** Digest of the exact bytes that were validated; output generation reuses them. */
|
|
42
|
+
readonly digest: string;
|
|
43
|
+
readonly bytes: Buffer;
|
|
44
|
+
} | PiBootstrapConfigFailure;
|
|
45
|
+
/**
|
|
46
|
+
* Bounded, no-follow read and strict validation of one explicit bootstrap config file.
|
|
47
|
+
* The returned bytes/digest are the pinned copy that output generation must write; the
|
|
48
|
+
* file is never read a second time.
|
|
49
|
+
*/
|
|
50
|
+
export declare function readPiBootstrapConfig(file: string): PiBootstrapConfigResult;
|
|
51
|
+
/** Maps the validated config onto the accepted runtime registration input. */
|
|
52
|
+
export declare function runtimeConfigOf(config: PiBootstrapConfig): BootstrapRuntimeConfig;
|
|
53
|
+
/**
|
|
54
|
+
* Total formatter for a status reason (never a permission signal). Unknown values, throwing
|
|
55
|
+
* `Error.message` getters, throwing `toString`/`valueOf` and hostile proxies all yield a
|
|
56
|
+
* bounded placeholder instead of escaping the caller.
|
|
57
|
+
*/
|
|
58
|
+
export declare function boundedReason(value: unknown): string;
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import { object as isRecord } from '../../infra/validation.js';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { readBoundedFile } from '../../infra/bounded-file.js';
|
|
5
|
+
/**
|
|
6
|
+
* Explicit, trusted local bootstrap binding for the opt-in Pi successor gate.
|
|
7
|
+
*
|
|
8
|
+
* This module only validates and pins data. It never creates directories, reads task
|
|
9
|
+
* records, claims resources or grants authority: exporting a guard is not writing and a
|
|
10
|
+
* valid pre-transfer record stays a valid export input. The accepted guard/runtime remain
|
|
11
|
+
* the authority for gating; this parser mirrors their limits without changing them.
|
|
12
|
+
*/
|
|
13
|
+
export const PI_BOOTSTRAP_CONFIG_SCHEMA = 'pappra/pi-bootstrap-config/1';
|
|
14
|
+
export const MAX_PI_BOOTSTRAP_CONFIG_BYTES = 64 * 1024;
|
|
15
|
+
const MAX_ID = 256;
|
|
16
|
+
const MAX_DOMAIN_ROOT = 4096;
|
|
17
|
+
const MAX_CLAIMS = 1024;
|
|
18
|
+
const MAX_REASON = 512;
|
|
19
|
+
const SAFE_TASK_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
|
|
20
|
+
const failure = (code, message) => ({
|
|
21
|
+
ok: false,
|
|
22
|
+
code,
|
|
23
|
+
message,
|
|
24
|
+
});
|
|
25
|
+
const isSafeText = (value, max = MAX_ID) => typeof value === 'string' &&
|
|
26
|
+
value.length > 0 &&
|
|
27
|
+
value.length <= max &&
|
|
28
|
+
!value.includes('\u0000');
|
|
29
|
+
const isSafeEpoch = (value) => typeof value === 'number' && Number.isSafeInteger(value) && value >= 0;
|
|
30
|
+
const isSafeRaisableEpoch = (value) => isSafeEpoch(value) && value < Number.MAX_SAFE_INTEGER;
|
|
31
|
+
function exactKeys(value, allowed) {
|
|
32
|
+
const keys = Object.keys(value);
|
|
33
|
+
return (keys.length === allowed.length && keys.every((key) => allowed.includes(key)));
|
|
34
|
+
}
|
|
35
|
+
function readIdentity(value) {
|
|
36
|
+
if (!isRecord(value) ||
|
|
37
|
+
!exactKeys(value, ['agentId', 'sessionId', 'harness']))
|
|
38
|
+
return null;
|
|
39
|
+
const agentId = value['agentId'];
|
|
40
|
+
const sessionId = value['sessionId'];
|
|
41
|
+
const harness = value['harness'];
|
|
42
|
+
if (!isSafeText(agentId, MAX_ID) ||
|
|
43
|
+
!isSafeText(sessionId, MAX_ID) ||
|
|
44
|
+
!isSafeText(harness, MAX_ID))
|
|
45
|
+
return null;
|
|
46
|
+
return { agentId, sessionId, harness };
|
|
47
|
+
}
|
|
48
|
+
function readClaims(value) {
|
|
49
|
+
if (!Array.isArray(value) || value.length === 0 || value.length > MAX_CLAIMS)
|
|
50
|
+
return null;
|
|
51
|
+
const claims = [];
|
|
52
|
+
const seen = new Set();
|
|
53
|
+
for (const entry of value) {
|
|
54
|
+
if (!isRecord(entry) ||
|
|
55
|
+
!exactKeys(entry, ['claimId', 'originalResourceEpoch']))
|
|
56
|
+
return null;
|
|
57
|
+
const claimId = entry['claimId'];
|
|
58
|
+
const original = entry['originalResourceEpoch'];
|
|
59
|
+
if (!isSafeText(claimId, MAX_ID) || !isSafeRaisableEpoch(original))
|
|
60
|
+
return null;
|
|
61
|
+
if (seen.has(claimId))
|
|
62
|
+
return null;
|
|
63
|
+
seen.add(claimId);
|
|
64
|
+
claims.push({ claimId, originalResourceEpoch: original });
|
|
65
|
+
}
|
|
66
|
+
return claims;
|
|
67
|
+
}
|
|
68
|
+
function readGuard(value, taskId) {
|
|
69
|
+
const keys = [
|
|
70
|
+
'taskId',
|
|
71
|
+
'intentId',
|
|
72
|
+
'handoffId',
|
|
73
|
+
'generation',
|
|
74
|
+
'subtaskId',
|
|
75
|
+
'attempt',
|
|
76
|
+
'inputRevision',
|
|
77
|
+
'coordinatorEpoch',
|
|
78
|
+
'successor',
|
|
79
|
+
'claims',
|
|
80
|
+
];
|
|
81
|
+
if (!isRecord(value) || !exactKeys(value, keys))
|
|
82
|
+
return failure('config_guard_keys_invalid', 'guard must contain exactly the pinned identity fields');
|
|
83
|
+
const guardTaskId = value['taskId'];
|
|
84
|
+
const intentId = value['intentId'];
|
|
85
|
+
const handoffId = value['handoffId'];
|
|
86
|
+
const subtaskId = value['subtaskId'];
|
|
87
|
+
const inputRevision = value['inputRevision'];
|
|
88
|
+
const generation = value['generation'];
|
|
89
|
+
const attempt = value['attempt'];
|
|
90
|
+
const coordinatorEpoch = value['coordinatorEpoch'];
|
|
91
|
+
if (guardTaskId !== taskId ||
|
|
92
|
+
!isSafeText(intentId, MAX_ID) ||
|
|
93
|
+
!isSafeText(handoffId, MAX_ID) ||
|
|
94
|
+
!isSafeText(subtaskId, MAX_ID) ||
|
|
95
|
+
!isSafeText(inputRevision, MAX_ID))
|
|
96
|
+
return failure('config_guard_invalid', 'guard taskId must equal the config taskId and every pinned id must be a positive-length short string');
|
|
97
|
+
if (!isSafeEpoch(generation) ||
|
|
98
|
+
!isSafeEpoch(attempt) ||
|
|
99
|
+
!isSafeEpoch(coordinatorEpoch))
|
|
100
|
+
return failure('config_guard_epoch_invalid', 'generation, attempt and coordinatorEpoch must be non-negative safe integers');
|
|
101
|
+
const successor = readIdentity(value['successor']);
|
|
102
|
+
if (successor === null)
|
|
103
|
+
return failure('config_successor_invalid', 'successor must be an exact {agentId,sessionId,harness} object with short non-empty values');
|
|
104
|
+
const claims = readClaims(value['claims']);
|
|
105
|
+
if (claims === null)
|
|
106
|
+
return failure('config_claims_invalid', `claims must be a non-empty set up to ${MAX_CLAIMS} of unique claimId/originalResourceEpoch entries`);
|
|
107
|
+
return {
|
|
108
|
+
taskId,
|
|
109
|
+
intentId,
|
|
110
|
+
handoffId,
|
|
111
|
+
generation,
|
|
112
|
+
subtaskId,
|
|
113
|
+
attempt,
|
|
114
|
+
inputRevision,
|
|
115
|
+
coordinatorEpoch,
|
|
116
|
+
successor,
|
|
117
|
+
claims,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
function canonicalDirectory(target) {
|
|
121
|
+
try {
|
|
122
|
+
if (!fs.lstatSync(target).isDirectory())
|
|
123
|
+
return false;
|
|
124
|
+
return fs.realpathSync(target) === target;
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/** Validates one parsed value. Never touches the filesystem except read-only canonical checks. */
|
|
131
|
+
function validateValue(parsed) {
|
|
132
|
+
if (!isRecord(parsed))
|
|
133
|
+
return failure('config_invalid', 'bootstrap config must be a JSON object');
|
|
134
|
+
if (!exactKeys(parsed, ['schema', 'domainRoot', 'taskId', 'guard']) ||
|
|
135
|
+
parsed['schema'] !== PI_BOOTSTRAP_CONFIG_SCHEMA)
|
|
136
|
+
return failure('config_schema_invalid', `bootstrap config must declare exactly schema ${PI_BOOTSTRAP_CONFIG_SCHEMA} plus domainRoot, taskId and guard`);
|
|
137
|
+
const domainRoot = parsed['domainRoot'];
|
|
138
|
+
const taskId = parsed['taskId'];
|
|
139
|
+
if (!isSafeText(domainRoot, MAX_DOMAIN_ROOT) || !path.isAbsolute(domainRoot))
|
|
140
|
+
return failure('config_domain_root_invalid', 'domainRoot must be an absolute path');
|
|
141
|
+
if (!isSafeText(taskId, 128) || !SAFE_TASK_ID.test(taskId))
|
|
142
|
+
return failure('config_task_id_invalid', 'taskId must match the short safe task-id pattern');
|
|
143
|
+
if (!canonicalDirectory(domainRoot))
|
|
144
|
+
return failure('config_domain_root_invalid', 'domainRoot must be an existing canonical directory (no symlink or redirected prefix)');
|
|
145
|
+
const guard = readGuard(parsed['guard'], taskId);
|
|
146
|
+
if ('ok' in guard)
|
|
147
|
+
return guard;
|
|
148
|
+
const taskRoot = path.join(domainRoot, 'tasks', taskId);
|
|
149
|
+
if (!canonicalDirectory(taskRoot))
|
|
150
|
+
return failure('config_task_root_invalid', 'the selected task root must already be a canonical directory inside the domain');
|
|
151
|
+
return {
|
|
152
|
+
ok: true,
|
|
153
|
+
config: {
|
|
154
|
+
schema: PI_BOOTSTRAP_CONFIG_SCHEMA,
|
|
155
|
+
domainRoot,
|
|
156
|
+
taskId,
|
|
157
|
+
guard,
|
|
158
|
+
},
|
|
159
|
+
taskRoot,
|
|
160
|
+
digest: '',
|
|
161
|
+
bytes: Buffer.alloc(0),
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Bounded, no-follow read and strict validation of one explicit bootstrap config file.
|
|
166
|
+
* The returned bytes/digest are the pinned copy that output generation must write; the
|
|
167
|
+
* file is never read a second time.
|
|
168
|
+
*/
|
|
169
|
+
export function readPiBootstrapConfig(file) {
|
|
170
|
+
if (!path.isAbsolute(file))
|
|
171
|
+
return failure('config_path_invalid', 'config path must be absolute');
|
|
172
|
+
const read = readBoundedFile(file, MAX_PI_BOOTSTRAP_CONFIG_BYTES);
|
|
173
|
+
if (read.ok === false) {
|
|
174
|
+
const code = read.code === 'too_large'
|
|
175
|
+
? 'config_too_large'
|
|
176
|
+
: read.code === 'symlink'
|
|
177
|
+
? 'config_symlink_refused'
|
|
178
|
+
: read.code === 'not_regular'
|
|
179
|
+
? 'config_not_regular'
|
|
180
|
+
: read.code === 'path_not_absolute'
|
|
181
|
+
? 'config_path_invalid'
|
|
182
|
+
: 'config_unreadable';
|
|
183
|
+
return failure(code, `bootstrap config must be a bounded (<= ${MAX_PI_BOOTSTRAP_CONFIG_BYTES} bytes) regular file read without following links`);
|
|
184
|
+
}
|
|
185
|
+
let parsed;
|
|
186
|
+
try {
|
|
187
|
+
parsed = JSON.parse(read.text);
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
return failure('config_invalid_json', 'bootstrap config is not valid JSON');
|
|
191
|
+
}
|
|
192
|
+
const validated = validateValue(parsed);
|
|
193
|
+
if (validated.ok === false)
|
|
194
|
+
return validated;
|
|
195
|
+
return { ...validated, digest: read.digest, bytes: read.bytes };
|
|
196
|
+
}
|
|
197
|
+
/** Maps the validated config onto the accepted runtime registration input. */
|
|
198
|
+
export function runtimeConfigOf(config) {
|
|
199
|
+
return {
|
|
200
|
+
domainRoot: config.domainRoot,
|
|
201
|
+
taskId: config.taskId,
|
|
202
|
+
guard: {
|
|
203
|
+
taskId: config.guard.taskId,
|
|
204
|
+
intentId: config.guard.intentId,
|
|
205
|
+
handoffId: config.guard.handoffId,
|
|
206
|
+
generation: config.guard.generation,
|
|
207
|
+
subtaskId: config.guard.subtaskId,
|
|
208
|
+
attempt: config.guard.attempt,
|
|
209
|
+
inputRevision: config.guard.inputRevision,
|
|
210
|
+
coordinatorEpoch: config.guard.coordinatorEpoch,
|
|
211
|
+
successor: { ...config.guard.successor },
|
|
212
|
+
claims: config.guard.claims.map((claim) => ({ ...claim })),
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
const UNREADABLE_REASON = 'unreadable failure value';
|
|
217
|
+
function readableMessage(error) {
|
|
218
|
+
try {
|
|
219
|
+
const message = error.message;
|
|
220
|
+
return typeof message === 'string' ? message : null;
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
return null;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Total formatter for a status reason (never a permission signal). Unknown values, throwing
|
|
228
|
+
* `Error.message` getters, throwing `toString`/`valueOf` and hostile proxies all yield a
|
|
229
|
+
* bounded placeholder instead of escaping the caller.
|
|
230
|
+
*/
|
|
231
|
+
export function boundedReason(value) {
|
|
232
|
+
let text = null;
|
|
233
|
+
try {
|
|
234
|
+
if (typeof value === 'string')
|
|
235
|
+
text = value;
|
|
236
|
+
else if (value instanceof Error)
|
|
237
|
+
text = readableMessage(value) ?? '[error]';
|
|
238
|
+
}
|
|
239
|
+
catch {
|
|
240
|
+
text = null;
|
|
241
|
+
}
|
|
242
|
+
if (text === null) {
|
|
243
|
+
try {
|
|
244
|
+
text = String(value);
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
text = UNREADABLE_REASON;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
const cleaned = text.replaceAll('\u0000', '');
|
|
251
|
+
return cleaned.length > MAX_REASON
|
|
252
|
+
? `${cleaned.slice(0, MAX_REASON)}…`
|
|
253
|
+
: cleaned;
|
|
254
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { HostName } from '../../schemas/host.js';
|
|
2
|
+
import type { PiBootstrapConfig } from './bootstrap-config.js';
|
|
2
3
|
export interface HostPluginBundle {
|
|
3
4
|
readonly host: HostName;
|
|
4
5
|
readonly outDir: string;
|
|
@@ -8,6 +9,43 @@ export interface HostPluginBundle {
|
|
|
8
9
|
readonly registration: readonly string[];
|
|
9
10
|
/** Plugin registration and native callability are not verified here. */
|
|
10
11
|
readonly verification: 'unsupported';
|
|
12
|
+
/** Present only for the opt-in Pi bootstrap export. */
|
|
13
|
+
readonly bootstrap?: {
|
|
14
|
+
readonly schema: string;
|
|
15
|
+
readonly configDigest: string;
|
|
16
|
+
readonly mode: 'deny-until-completed-transfer';
|
|
17
|
+
/** Export writes files only; a host loader must prove registration separately. */
|
|
18
|
+
readonly registeredByExport: false;
|
|
19
|
+
};
|
|
20
|
+
/** Present only for an explicitly configured Pi recovery export. */
|
|
21
|
+
readonly recovery?: {
|
|
22
|
+
readonly schema: string;
|
|
23
|
+
readonly configDigest: string;
|
|
24
|
+
readonly registeredByExport: false;
|
|
25
|
+
};
|
|
26
|
+
/** Present only when the Pi session-transition extension was explicitly requested. */
|
|
27
|
+
readonly transition?: {
|
|
28
|
+
readonly registeredByExport: false;
|
|
29
|
+
readonly nativeQuiescence: 'unavailable';
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export interface BootstrapBundleInput {
|
|
33
|
+
readonly config: PiBootstrapConfig;
|
|
34
|
+
/** The exact bytes that were validated and pinned; never re-read during generation. */
|
|
35
|
+
readonly configBytes: Buffer;
|
|
36
|
+
readonly configDigest: string;
|
|
37
|
+
/** Built self-contained extension artifact shipped next to the config. */
|
|
38
|
+
readonly artifactPath: string;
|
|
39
|
+
}
|
|
40
|
+
export interface RecoveryBundleInput {
|
|
41
|
+
/** Explicit user-selected config; validated again before exact bytes are staged. */
|
|
42
|
+
readonly configFile: string;
|
|
43
|
+
/** Self-contained extension artifact produced by the isolated asset build. */
|
|
44
|
+
readonly artifactPath: string;
|
|
45
|
+
}
|
|
46
|
+
export interface TransitionBundleInput {
|
|
47
|
+
/** Self-contained extension artifact produced by the isolated asset build. */
|
|
48
|
+
readonly artifactPath: string;
|
|
11
49
|
}
|
|
12
50
|
/**
|
|
13
51
|
* Writes a host-native plugin/package directory. This is an artifact export: it
|
|
@@ -21,4 +59,10 @@ export declare function exportHostPluginBundle(options: {
|
|
|
21
59
|
readonly packageVersion: string;
|
|
22
60
|
/** Writes a marketplace root with the plugin under `pappra/`. */
|
|
23
61
|
readonly marketplace?: boolean;
|
|
62
|
+
/** Opt-in Pi-only successor bootstrap export. */
|
|
63
|
+
readonly bootstrap?: BootstrapBundleInput;
|
|
64
|
+
/** Opt-in Pi recovery package with a bounded, task/session-bound config. */
|
|
65
|
+
readonly recovery?: RecoveryBundleInput;
|
|
66
|
+
/** Opt-in Pi transition command package; native quiescence remains unsupported. */
|
|
67
|
+
readonly transition?: TransitionBundleInput;
|
|
24
68
|
}): Promise<HostPluginBundle>;
|