@phyzess/pappra 0.1.0-beta.14 → 0.1.0-beta.19
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 +133 -14
- package/assets/integrations/skills/pappra/SKILL.md +56 -7
- package/assets/integrations/skills/pappra/references/collaboration.md +646 -0
- package/assets/integrations/skills/pappra/references/environment.md +367 -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-request.d.ts +50 -0
- package/dist/app/collab-session-transition-request.js +339 -0
- package/dist/app/collab-session-transition-validation.d.ts +19 -0
- package/dist/app/collab-session-transition-validation.js +44 -0
- package/dist/app/collab-session-transition.d.ts +181 -0
- package/dist/app/collab-session-transition.js +2970 -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 +104 -3
- 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/collaboration-router.d.ts +17 -0
- package/dist/cli/collaboration-router.js +604 -0
- 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/options.d.ts +806 -0
- package/dist/cli/options.js +293 -0
- package/dist/cli/run.js +280 -310
- 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 +90 -67
- 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 +37 -35
- package/skills/pappra/SKILL.md +56 -7
- package/skills/pappra/references/collaboration.md +646 -0
- package/skills/pappra/references/environment.md +367 -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
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { AppliedMessage, Identity, ResultEntry, RolloverIntent, TaskRecord } from '../collab/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Pure current-record notify route exclusion.
|
|
4
|
+
*
|
|
5
|
+
* A completed, valid succession retains the old native agent/session identity as history.
|
|
6
|
+
* That identity is no longer an active notify sender or recipient. This module only answers
|
|
7
|
+
* the notify question: it never rewrites messages, deliveries or bindings, and it does not
|
|
8
|
+
* claim that dispatch routing or the native session archive changed.
|
|
9
|
+
*
|
|
10
|
+
* A completed handoff alone proves nothing. A succession is usable only when its matching
|
|
11
|
+
* intent, recorded transfer boundary, registered applied first-work REPORT and admitted
|
|
12
|
+
* result entry all agree; anything missing or contradictory is `unknown`, never a silent
|
|
13
|
+
* reroute and never an accepted exclusion.
|
|
14
|
+
*/
|
|
15
|
+
export declare const ROUTE_EXCLUSION_SCHEMA = "pappra/collaboration-route-exclusion/1";
|
|
16
|
+
export interface RouteExclusion {
|
|
17
|
+
readonly schema: typeof ROUTE_EXCLUSION_SCHEMA;
|
|
18
|
+
readonly agent_id: string;
|
|
19
|
+
readonly session_id: string;
|
|
20
|
+
readonly intent_id: string;
|
|
21
|
+
readonly handoff_id: string;
|
|
22
|
+
readonly generation: number;
|
|
23
|
+
readonly archived_at: string;
|
|
24
|
+
readonly proof_message_id: string;
|
|
25
|
+
readonly proof_digest: string;
|
|
26
|
+
/** Routing removal is not implemented: the value stays pending. */
|
|
27
|
+
readonly routing: 'pending';
|
|
28
|
+
/** The Pi native session archive is unavailable. */
|
|
29
|
+
readonly native_archive: 'unavailable';
|
|
30
|
+
}
|
|
31
|
+
export interface RouteExclusionLookup {
|
|
32
|
+
readonly state: 'active' | 'excluded' | 'unknown';
|
|
33
|
+
readonly exclusion: RouteExclusion | null;
|
|
34
|
+
readonly conflict: string | null;
|
|
35
|
+
}
|
|
36
|
+
export interface SuccessionFailure {
|
|
37
|
+
readonly ok: false;
|
|
38
|
+
readonly code: string;
|
|
39
|
+
readonly detail: string;
|
|
40
|
+
}
|
|
41
|
+
export type SuccessionValidation = {
|
|
42
|
+
readonly ok: true;
|
|
43
|
+
readonly intent: RolloverIntent;
|
|
44
|
+
readonly proof: AppliedMessage;
|
|
45
|
+
readonly result: ResultEntry;
|
|
46
|
+
readonly exclusion: RouteExclusion;
|
|
47
|
+
} | SuccessionFailure;
|
|
48
|
+
/**
|
|
49
|
+
* Validates one recorded succession end to end against the record it belongs to. The check
|
|
50
|
+
* is purely historical: it reads the immutable intent, the registered message ledger, the
|
|
51
|
+
* admitted result entry and the recorded transfer boundary. Live claims and later attempt
|
|
52
|
+
* states are not required, so an intact historical chain stays valid after further work.
|
|
53
|
+
*/
|
|
54
|
+
export declare function validateSuccession(record: TaskRecord, entry: unknown): SuccessionValidation;
|
|
55
|
+
export declare function routeExclusions(record: TaskRecord): readonly RouteExclusion[];
|
|
56
|
+
/**
|
|
57
|
+
* Answers the notify question for one identity: is it an archived old native identity
|
|
58
|
+
* (`excluded`), an active identity (`active`), or is a relevant succession contradictory
|
|
59
|
+
* (`unknown`, which notify must refuse rather than guess)?
|
|
60
|
+
*
|
|
61
|
+
* A successor match is validated too: a succession that names this identity as its receiver
|
|
62
|
+
* but cannot prove the transfer is `unknown`, never a silent pass.
|
|
63
|
+
*/
|
|
64
|
+
export declare function routeExclusionFor(record: TaskRecord, identity: Identity): RouteExclusionLookup;
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { object as isRecord } from '../infra/validation.js';
|
|
2
|
+
import { isTaskRecord } from '../collab/validation.js';
|
|
3
|
+
import { findHandoff } from '../collab/handoff.js';
|
|
4
|
+
import { isNativeFirstWorkResult } from '../collab/first-work.js';
|
|
5
|
+
/**
|
|
6
|
+
* Pure current-record notify route exclusion.
|
|
7
|
+
*
|
|
8
|
+
* A completed, valid succession retains the old native agent/session identity as history.
|
|
9
|
+
* That identity is no longer an active notify sender or recipient. This module only answers
|
|
10
|
+
* the notify question: it never rewrites messages, deliveries or bindings, and it does not
|
|
11
|
+
* claim that dispatch routing or the native session archive changed.
|
|
12
|
+
*
|
|
13
|
+
* A completed handoff alone proves nothing. A succession is usable only when its matching
|
|
14
|
+
* intent, recorded transfer boundary, registered applied first-work REPORT and admitted
|
|
15
|
+
* result entry all agree; anything missing or contradictory is `unknown`, never a silent
|
|
16
|
+
* reroute and never an accepted exclusion.
|
|
17
|
+
*/
|
|
18
|
+
export const ROUTE_EXCLUSION_SCHEMA = 'pappra/collaboration-route-exclusion/1';
|
|
19
|
+
const isText = (value, max = 2048) => typeof value === 'string' &&
|
|
20
|
+
value.length > 0 &&
|
|
21
|
+
value.length <= max &&
|
|
22
|
+
!value.includes('\u0000');
|
|
23
|
+
const sameIdentity = (left, right) => left !== null &&
|
|
24
|
+
left.agent_id === right.agent_id &&
|
|
25
|
+
left.session_id === right.session_id;
|
|
26
|
+
const rejected = (code, detail) => ({
|
|
27
|
+
ok: false,
|
|
28
|
+
code,
|
|
29
|
+
detail,
|
|
30
|
+
});
|
|
31
|
+
const nativeMatchesIdentity = (native, identity) => sameIdentity(native, identity);
|
|
32
|
+
/**
|
|
33
|
+
* Validates one recorded succession end to end against the record it belongs to. The check
|
|
34
|
+
* is purely historical: it reads the immutable intent, the registered message ledger, the
|
|
35
|
+
* admitted result entry and the recorded transfer boundary. Live claims and later attempt
|
|
36
|
+
* states are not required, so an intact historical chain stays valid after further work.
|
|
37
|
+
*/
|
|
38
|
+
export function validateSuccession(record, entry) {
|
|
39
|
+
if (!isTaskRecord(record))
|
|
40
|
+
return rejected('record_invalid', 'task record failed validation');
|
|
41
|
+
if (!isRecord(entry))
|
|
42
|
+
return rejected('succession_malformed', 'succession is not an object');
|
|
43
|
+
const handoffId = entry['handoff_id'];
|
|
44
|
+
const intentId = entry['intent_id'];
|
|
45
|
+
const generation = entry['generation'];
|
|
46
|
+
const archivedAt = entry['archived_at'];
|
|
47
|
+
const oldNative = entry['old_native'];
|
|
48
|
+
const successorNative = entry['successor_native'];
|
|
49
|
+
const proof = entry['proof'];
|
|
50
|
+
if (!isText(handoffId, 256) ||
|
|
51
|
+
!isText(intentId, 256) ||
|
|
52
|
+
!isText(archivedAt, 64) ||
|
|
53
|
+
!Number.isSafeInteger(generation) ||
|
|
54
|
+
generation < 1 ||
|
|
55
|
+
!isRecord(oldNative) ||
|
|
56
|
+
!isRecord(successorNative) ||
|
|
57
|
+
!isRecord(proof))
|
|
58
|
+
return rejected('succession_malformed', 'succession is missing intent, handoff, generation, native identities or proof');
|
|
59
|
+
const oldAgent = oldNative['agent_id'];
|
|
60
|
+
const oldSession = oldNative['session_id'];
|
|
61
|
+
const successorAgent = successorNative['agent_id'];
|
|
62
|
+
const successorSession = successorNative['session_id'];
|
|
63
|
+
const proofMessageId = proof['message_id'];
|
|
64
|
+
const proofDigest = proof['digest'];
|
|
65
|
+
if (!isText(oldAgent, 256) ||
|
|
66
|
+
!isText(oldSession, 256) ||
|
|
67
|
+
!isText(successorAgent, 256) ||
|
|
68
|
+
!isText(successorSession, 256) ||
|
|
69
|
+
!isText(proofMessageId, 256) ||
|
|
70
|
+
!isText(proofDigest, 128))
|
|
71
|
+
return rejected('succession_native_missing', 'succession has an incomplete native identity or proof pointer');
|
|
72
|
+
if (entry['history_retained'] !== true ||
|
|
73
|
+
entry['routing'] !== 'pending' ||
|
|
74
|
+
entry['native_archive'] !== 'unavailable')
|
|
75
|
+
return rejected('succession_history_invalid', 'succession does not record retained history, pending routing and an unavailable native archive');
|
|
76
|
+
if (successorAgent === oldAgent && successorSession === oldSession)
|
|
77
|
+
return rejected('succession_native_inherited', 'succession successor reuses the archived source native identity');
|
|
78
|
+
const handoff = findHandoff(record, handoffId);
|
|
79
|
+
if (handoff === null)
|
|
80
|
+
return rejected('succession_handoff_unknown', `succession references unknown handoff ${handoffId}`);
|
|
81
|
+
if (handoff.state !== 'completed')
|
|
82
|
+
return rejected('succession_handoff_not_completed', `handoff ${handoffId} is in state ${handoff.state}`);
|
|
83
|
+
if (!sameIdentity(handoff.from, { agent_id: oldAgent, session_id: oldSession }))
|
|
84
|
+
return rejected('succession_handoff_identity_mismatch', `handoff ${handoffId} source does not match the archived old native identity`);
|
|
85
|
+
if (!sameIdentity(handoff.to, {
|
|
86
|
+
agent_id: successorAgent,
|
|
87
|
+
session_id: successorSession,
|
|
88
|
+
}))
|
|
89
|
+
return rejected('succession_handoff_identity_mismatch', `handoff ${handoffId} receiver does not match the successor native identity`);
|
|
90
|
+
const intent = (record.rollover ?? []).find((item) => item.intent_id === intentId);
|
|
91
|
+
if (intent === undefined)
|
|
92
|
+
return rejected('succession_intent_missing', `succession references no recorded intent ${intentId}`);
|
|
93
|
+
if (intent.task_id !== record.task_id ||
|
|
94
|
+
intent.handoff_id !== handoffId ||
|
|
95
|
+
intent.generation !== generation)
|
|
96
|
+
return rejected('succession_intent_mismatch', `intent ${intentId} does not belong to this task, handoff or generation`);
|
|
97
|
+
if (!nativeMatchesIdentity(intent.from, {
|
|
98
|
+
agent_id: oldAgent,
|
|
99
|
+
session_id: oldSession,
|
|
100
|
+
}))
|
|
101
|
+
return rejected('succession_intent_source_mismatch', `intent ${intentId} source is not the archived old native identity`);
|
|
102
|
+
if (!nativeMatchesIdentity(intent.to, {
|
|
103
|
+
agent_id: successorAgent,
|
|
104
|
+
session_id: successorSession,
|
|
105
|
+
}))
|
|
106
|
+
return rejected('succession_intent_successor_mismatch', `intent ${intentId} receiver is not the successor native identity`);
|
|
107
|
+
if (!nativeMatchesIdentity(intent.source_native, {
|
|
108
|
+
agent_id: oldAgent,
|
|
109
|
+
session_id: oldSession,
|
|
110
|
+
}) ||
|
|
111
|
+
intent.source_native.runner !== (oldNative['runner'] ?? null) ||
|
|
112
|
+
intent.source_native.run_id !== (oldNative['run_id'] ?? null))
|
|
113
|
+
return rejected('succession_source_native_mismatch', `intent ${intentId} pinned source native identity does not match the archived history`);
|
|
114
|
+
const pinnedSuccessor = intent.successor_native ?? null;
|
|
115
|
+
if (pinnedSuccessor === null ||
|
|
116
|
+
!nativeMatchesIdentity(pinnedSuccessor, {
|
|
117
|
+
agent_id: successorAgent,
|
|
118
|
+
session_id: successorSession,
|
|
119
|
+
}) ||
|
|
120
|
+
pinnedSuccessor.runner !== (successorNative['runner'] ?? null) ||
|
|
121
|
+
pinnedSuccessor.run_id !== (successorNative['run_id'] ?? null))
|
|
122
|
+
return rejected('succession_successor_native_mismatch', `intent ${intentId} pinned successor native identity does not match the archived history`);
|
|
123
|
+
const boundary = intent.transfer_boundary ?? null;
|
|
124
|
+
if (boundary === null)
|
|
125
|
+
return rejected('succession_boundary_missing', `intent ${intentId} has no recorded transfer boundary`);
|
|
126
|
+
const messages = record.messages ?? [];
|
|
127
|
+
const index = messages.findIndex((item) => item.message_id === proofMessageId);
|
|
128
|
+
if (index < 0)
|
|
129
|
+
return rejected('succession_proof_missing', `first-work REPORT ${proofMessageId} is not registered`);
|
|
130
|
+
const applied = messages[index];
|
|
131
|
+
if (applied.state !== 'applied')
|
|
132
|
+
return rejected('succession_proof_not_applied', `first-work REPORT ${proofMessageId} is ${applied.state}, not applied`);
|
|
133
|
+
if (applied.content_digest !== proofDigest)
|
|
134
|
+
return rejected('succession_proof_digest_mismatch', `first-work REPORT ${proofMessageId} digest differs from the retained proof`);
|
|
135
|
+
if (applied.type !== 'REPORT')
|
|
136
|
+
return rejected('succession_proof_type_mismatch', `first-work proof ${proofMessageId} is ${applied.type}, not REPORT`);
|
|
137
|
+
if (index < boundary.message_count)
|
|
138
|
+
return rejected('succession_proof_pre_transfer', `first-work REPORT is registered before the recorded transfer boundary`);
|
|
139
|
+
if (!sameIdentity(applied.from, {
|
|
140
|
+
agent_id: successorAgent,
|
|
141
|
+
session_id: successorSession,
|
|
142
|
+
}))
|
|
143
|
+
return rejected('succession_proof_sender_mismatch', 'first-work REPORT was not sent by the successor native identity');
|
|
144
|
+
if (applied.subtask_id !== intent.subtask_id ||
|
|
145
|
+
applied.attempt !== intent.attempt)
|
|
146
|
+
return rejected('succession_proof_correlation_mismatch', 'first-work REPORT does not match the intent subtask and attempt');
|
|
147
|
+
const result = (record.results ?? []).find((item) => item.message_id === proofMessageId);
|
|
148
|
+
if (result === undefined)
|
|
149
|
+
return rejected('succession_result_missing', `first-work REPORT ${proofMessageId} has no admitted result`);
|
|
150
|
+
if (result.classification !== 'applied')
|
|
151
|
+
return rejected('succession_result_not_admitted', `first-work result is ${result.classification}, not applied`);
|
|
152
|
+
if (result.status !== 'completed' && !isNativeFirstWorkResult(result, intent))
|
|
153
|
+
return rejected('succession_result_not_completed', `first-work result is ${result.status}, not completed`);
|
|
154
|
+
if (result.subtask_id !== intent.subtask_id ||
|
|
155
|
+
result.attempt !== intent.attempt ||
|
|
156
|
+
result.input_revision !== intent.input_revision)
|
|
157
|
+
return rejected('succession_result_mismatch', 'first-work result does not match the intent subtask, attempt and input');
|
|
158
|
+
return {
|
|
159
|
+
ok: true,
|
|
160
|
+
intent,
|
|
161
|
+
proof: applied,
|
|
162
|
+
result,
|
|
163
|
+
exclusion: {
|
|
164
|
+
schema: ROUTE_EXCLUSION_SCHEMA,
|
|
165
|
+
agent_id: oldAgent,
|
|
166
|
+
session_id: oldSession,
|
|
167
|
+
intent_id: intentId,
|
|
168
|
+
handoff_id: handoffId,
|
|
169
|
+
generation: generation,
|
|
170
|
+
archived_at: archivedAt,
|
|
171
|
+
proof_message_id: proofMessageId,
|
|
172
|
+
proof_digest: proofDigest,
|
|
173
|
+
routing: 'pending',
|
|
174
|
+
native_archive: 'unavailable',
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
function matchOf(entry, identity) {
|
|
179
|
+
if (!isRecord(entry))
|
|
180
|
+
return null;
|
|
181
|
+
const oldNative = entry['old_native'];
|
|
182
|
+
const successorNative = entry['successor_native'];
|
|
183
|
+
const old = isRecord(oldNative) &&
|
|
184
|
+
oldNative['agent_id'] === identity.agent_id &&
|
|
185
|
+
oldNative['session_id'] === identity.session_id;
|
|
186
|
+
const successor = isRecord(successorNative) &&
|
|
187
|
+
successorNative['agent_id'] === identity.agent_id &&
|
|
188
|
+
successorNative['session_id'] === identity.session_id;
|
|
189
|
+
if (!old && !successor)
|
|
190
|
+
return null;
|
|
191
|
+
return { old, successor };
|
|
192
|
+
}
|
|
193
|
+
export function routeExclusions(record) {
|
|
194
|
+
if (!isTaskRecord(record))
|
|
195
|
+
return [];
|
|
196
|
+
const exclusions = [];
|
|
197
|
+
for (const entry of record.successions ?? []) {
|
|
198
|
+
const validated = validateSuccession(record, entry);
|
|
199
|
+
if (validated.ok)
|
|
200
|
+
exclusions.push(validated.exclusion);
|
|
201
|
+
}
|
|
202
|
+
return exclusions;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Answers the notify question for one identity: is it an archived old native identity
|
|
206
|
+
* (`excluded`), an active identity (`active`), or is a relevant succession contradictory
|
|
207
|
+
* (`unknown`, which notify must refuse rather than guess)?
|
|
208
|
+
*
|
|
209
|
+
* A successor match is validated too: a succession that names this identity as its receiver
|
|
210
|
+
* but cannot prove the transfer is `unknown`, never a silent pass.
|
|
211
|
+
*/
|
|
212
|
+
export function routeExclusionFor(record, identity) {
|
|
213
|
+
if (!isTaskRecord(record))
|
|
214
|
+
return {
|
|
215
|
+
state: 'unknown',
|
|
216
|
+
exclusion: null,
|
|
217
|
+
conflict: 'task record failed validation',
|
|
218
|
+
};
|
|
219
|
+
let conflict = null;
|
|
220
|
+
for (const entry of record.successions ?? []) {
|
|
221
|
+
const match = matchOf(entry, identity);
|
|
222
|
+
if (match === null)
|
|
223
|
+
continue;
|
|
224
|
+
const validated = validateSuccession(record, entry);
|
|
225
|
+
if (validated.ok) {
|
|
226
|
+
// A successor identity is the current route; only an archived old identity excludes.
|
|
227
|
+
if (match.old)
|
|
228
|
+
return {
|
|
229
|
+
state: 'excluded',
|
|
230
|
+
exclusion: validated.exclusion,
|
|
231
|
+
conflict: null,
|
|
232
|
+
};
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
conflict = `${validated.code}: ${validated.detail}`;
|
|
236
|
+
}
|
|
237
|
+
if (conflict !== null)
|
|
238
|
+
return { state: 'unknown', exclusion: null, conflict };
|
|
239
|
+
return { state: 'active', exclusion: null, conflict: null };
|
|
240
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { type ManagedPiExecutionScope } from '../schemas/managed-pi-execution.js';
|
|
2
|
+
import type { RolloverBundleRequest, RolloverIntentRequest } from './collab-rollover.js';
|
|
3
|
+
export declare const COLLAB_SESSION_TRANSITION_REQUEST_SCHEMA = "pappra/collaboration-session-transition-request/1";
|
|
4
|
+
export interface SessionTransitionRequest {
|
|
5
|
+
readonly schema: typeof COLLAB_SESSION_TRANSITION_REQUEST_SCHEMA;
|
|
6
|
+
readonly managed_execution_scope?: ManagedPiExecutionScope;
|
|
7
|
+
readonly task_root: string;
|
|
8
|
+
readonly transition_id: string;
|
|
9
|
+
readonly intent: RolloverIntentRequest;
|
|
10
|
+
readonly bundle: RolloverBundleRequest;
|
|
11
|
+
readonly bootstrap_request: {
|
|
12
|
+
readonly ref: string;
|
|
13
|
+
readonly digest: string;
|
|
14
|
+
};
|
|
15
|
+
readonly evidence: {
|
|
16
|
+
readonly ack_message_id: string | null;
|
|
17
|
+
readonly first_work_report_id: string | null;
|
|
18
|
+
};
|
|
19
|
+
readonly archive_mode: 'task-retirement';
|
|
20
|
+
}
|
|
21
|
+
export interface LoadedSessionTransitionRequest {
|
|
22
|
+
readonly request: SessionTransitionRequest;
|
|
23
|
+
readonly file: string;
|
|
24
|
+
readonly file_digest: string;
|
|
25
|
+
readonly immutable_digest: string;
|
|
26
|
+
}
|
|
27
|
+
export type SessionTransitionRequestResult = {
|
|
28
|
+
readonly ok: true;
|
|
29
|
+
readonly value: LoadedSessionTransitionRequest;
|
|
30
|
+
} | {
|
|
31
|
+
readonly ok: false;
|
|
32
|
+
readonly kind: 'invalid';
|
|
33
|
+
readonly code: string;
|
|
34
|
+
readonly message: string;
|
|
35
|
+
readonly next_action: string | null;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* The immutable digest deliberately excludes `evidence`: adding an ACK or a
|
|
39
|
+
* first-work REPORT pointer must not change a request's identity.
|
|
40
|
+
*/
|
|
41
|
+
export declare function immutableDigest(request: SessionTransitionRequest): string;
|
|
42
|
+
export declare function validateSessionTransitionRequest(value: unknown): {
|
|
43
|
+
readonly ok: true;
|
|
44
|
+
readonly request: SessionTransitionRequest;
|
|
45
|
+
} | {
|
|
46
|
+
readonly ok: false;
|
|
47
|
+
readonly code: string;
|
|
48
|
+
readonly message: string;
|
|
49
|
+
};
|
|
50
|
+
export declare function loadSessionTransitionRequest(file: string): SessionTransitionRequestResult;
|