@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
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-process native Pi event-fact capture (rollover observation source).
|
|
3
|
+
*
|
|
4
|
+
* A small, bounded, opt-in producer that subscribes to a fixed set of supported installed Pi 1.3.0
|
|
5
|
+
* extension callbacks and derives conservative in-process facts plus invalidation notifications. It is
|
|
6
|
+
* NOT authority, external control, writer fencing, or a native-stop/quiescence/transfer proof. It never
|
|
7
|
+
* calls the accepted freeze controller's `observe()`, never synthesizes queue/approval numbers, and
|
|
8
|
+
* never infers a stop from balanced tool events. Facts come only from live callback contexts, never from
|
|
9
|
+
* caller-supplied fact JSON.
|
|
10
|
+
*
|
|
11
|
+
* It holds no resources: no timer, watcher, filesystem, process, transcript, network, controller, or
|
|
12
|
+
* rollover import. In-memory only: a restart or reload loses every fact. There is no thaw and no
|
|
13
|
+
* transfer behavior.
|
|
14
|
+
*
|
|
15
|
+
* Conservative identity handling: an unknown, throwing, or malformed session read invalidates the prior
|
|
16
|
+
* session-derived facts (settled confidence and tool-tracking health) and never revalidates them on the
|
|
17
|
+
* next matching identity read; only a later trustworthy supported boundary can re-establish settled, and
|
|
18
|
+
* only a native session change starts fresh tool tracking. Payload reads are guarded so a throwing or
|
|
19
|
+
* proxy accessor is treated as malformed and still notifies subscribers.
|
|
20
|
+
*
|
|
21
|
+
* Notifications are delivered in chronological order under bounded reentrancy. If the bounded buffer or
|
|
22
|
+
* per-drain budget is exceeded, delivery is lost; this is a sticky delivery gap. Rather than ending any
|
|
23
|
+
* subscriber on an older healthy snapshot, the drain discards stale buffered facts and delivers one
|
|
24
|
+
* terminal, conservative gap invalidation to every still-subscribed listener. The gap is sticky: while it
|
|
25
|
+
* is unresolved every snapshot reports `notificationBacklogOverflow`, `settled: 'unknown'` and
|
|
26
|
+
* `toolTrackingHealthy: false`, and no ordinary later event restores healthy confidence.
|
|
27
|
+
*
|
|
28
|
+
* Installed Pi 1.3.0 API pinned from the installed docs/examples (the package ships no .d.ts):
|
|
29
|
+
* docs/extensions.md (sha256:a2b5ff0f95e7e470ed0846d7c4fbfc5781fe7e694b8e7f51ea08859f3ad7325d):
|
|
30
|
+
* lifecycle events `session_start`, `before_agent_start` (a run becomes busy), `agent_settled`
|
|
31
|
+
* (final, "Pi will not continue automatically"), and nested `tool_execution_start` /
|
|
32
|
+
* `tool_execution_end` carrying a string `toolCallId` (`<parent id>/<n>` for nested calls); the
|
|
33
|
+
* running session is read from `ctx.sessionManager.getSessionId()` and idleness from `ctx.isIdle()`
|
|
34
|
+
* (examples/extensions/send-user-message.ts
|
|
35
|
+
* sha256:9261e433c782f354530105e1c9723a19798868f72fd1f5d68af3a4624ad7e446). The narrow structural
|
|
36
|
+
* host interface below matches that shape; structural compatibility is not a shipped-declaration or
|
|
37
|
+
* live-load proof.
|
|
38
|
+
*/
|
|
39
|
+
export const PI_NATIVE_EVENTS_SCHEMA = 'pappra/pi-native-events/1';
|
|
40
|
+
/** The only installed callbacks this producer subscribes. Nothing else is observed. */
|
|
41
|
+
export const SUPPORTED_CALLBACKS = Object.freeze([
|
|
42
|
+
'session_start',
|
|
43
|
+
'before_agent_start',
|
|
44
|
+
'agent_settled',
|
|
45
|
+
'tool_execution_start',
|
|
46
|
+
'tool_execution_end',
|
|
47
|
+
]);
|
|
48
|
+
const MAX_ID_LENGTH = 256;
|
|
49
|
+
const DEFAULT_MAX_TRACKED_TOOLS = 4096;
|
|
50
|
+
const DEFAULT_MAX_SEQUENCE = Number.MAX_SAFE_INTEGER;
|
|
51
|
+
const DEFAULT_MAX_NOTIFY_QUEUE = 1024;
|
|
52
|
+
/**
|
|
53
|
+
* Honest boundaries of these facts. Shared frozen; a snapshot exposes the same immutable array.
|
|
54
|
+
*/
|
|
55
|
+
export const NATIVE_EVENT_LIMITATIONS = Object.freeze([
|
|
56
|
+
'in_process_observations_only_not_authority_external_control_or_writer_fencing',
|
|
57
|
+
'not_a_native_stop_quiescence_or_transfer_proof',
|
|
58
|
+
'queue_depth_and_global_approvals_unknown_no_supported_extension_api',
|
|
59
|
+
'in_flight_tool_completeness_unknown_observed_open_count_is_not_authoritative',
|
|
60
|
+
'unknown_session_identity_invalidates_settled_and_tool_tracking_confidence',
|
|
61
|
+
'notification_delivery_gap_delivers_a_terminal_invalidation_to_every_listener_and_stays_sticky',
|
|
62
|
+
'does_not_observe_background_or_external_non_managed_tool_activity',
|
|
63
|
+
'memory_only_facts_lost_on_restart_or_reload_no_thaw_no_transfer',
|
|
64
|
+
'produces_facts_only_never_calls_controller_observe_or_asserts_readiness',
|
|
65
|
+
]);
|
|
66
|
+
function isSafeId(value) {
|
|
67
|
+
return (typeof value === 'string' &&
|
|
68
|
+
value.length > 0 &&
|
|
69
|
+
value.length <= MAX_ID_LENGTH);
|
|
70
|
+
}
|
|
71
|
+
/** Pinned: the running session id is `ctx.sessionManager.getSessionId()`. Any failure stays unknown. */
|
|
72
|
+
function readSessionId(context) {
|
|
73
|
+
try {
|
|
74
|
+
if (typeof context !== 'object' || context === null)
|
|
75
|
+
return null;
|
|
76
|
+
const manager = context.sessionManager;
|
|
77
|
+
if (typeof manager !== 'object' || manager === null)
|
|
78
|
+
return null;
|
|
79
|
+
const getter = manager.getSessionId;
|
|
80
|
+
if (typeof getter !== 'function')
|
|
81
|
+
return null;
|
|
82
|
+
const value = getter.call(manager);
|
|
83
|
+
return isSafeId(value) ? value : null;
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/** Pinned: idleness is `ctx.isIdle()`. A throw, a missing method, or a non-boolean stays unknown. */
|
|
90
|
+
function readIdle(context) {
|
|
91
|
+
try {
|
|
92
|
+
if (typeof context !== 'object' || context === null)
|
|
93
|
+
return 'unknown';
|
|
94
|
+
const getter = context.isIdle;
|
|
95
|
+
if (typeof getter !== 'function')
|
|
96
|
+
return 'unknown';
|
|
97
|
+
const value = getter.call(context);
|
|
98
|
+
return typeof value === 'boolean' ? value : 'unknown';
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return 'unknown';
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* A tool event carries a string `toolCallId`. The property read is guarded: a throwing/proxy accessor or
|
|
106
|
+
* any non-string is treated as malformed (returns null), never propagated into the host event path.
|
|
107
|
+
*/
|
|
108
|
+
function readToolCallId(event) {
|
|
109
|
+
try {
|
|
110
|
+
if (typeof event !== 'object' || event === null)
|
|
111
|
+
return null;
|
|
112
|
+
const raw = event.toolCallId;
|
|
113
|
+
return isSafeId(raw) ? raw : null;
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
class Producer {
|
|
120
|
+
#maxTrackedTools;
|
|
121
|
+
#maxSequence;
|
|
122
|
+
#maxNotifyQueue;
|
|
123
|
+
#openTools = new Set();
|
|
124
|
+
#listeners = new Set();
|
|
125
|
+
#notifyQueue = [];
|
|
126
|
+
#sessionId;
|
|
127
|
+
#sessionKnown;
|
|
128
|
+
#settled = 'unknown';
|
|
129
|
+
#idle = 'unknown';
|
|
130
|
+
#toolTrackingHealthy = true;
|
|
131
|
+
#sequence = 0;
|
|
132
|
+
#sequenceSaturated = false;
|
|
133
|
+
#notificationOverflow = false;
|
|
134
|
+
#overflowPending = false;
|
|
135
|
+
#draining = false;
|
|
136
|
+
constructor(options) {
|
|
137
|
+
const seeded = isSafeId(options.sessionId) ? options.sessionId : null;
|
|
138
|
+
this.#sessionId = seeded;
|
|
139
|
+
this.#sessionKnown = seeded !== null;
|
|
140
|
+
this.#maxTrackedTools = positiveIntOr(options.maxTrackedTools, DEFAULT_MAX_TRACKED_TOOLS);
|
|
141
|
+
this.#maxSequence = positiveIntOr(options.maxSequence, DEFAULT_MAX_SEQUENCE);
|
|
142
|
+
this.#maxNotifyQueue = positiveIntOr(options.maxNotifyQueue, DEFAULT_MAX_NOTIFY_QUEUE);
|
|
143
|
+
}
|
|
144
|
+
handle(kind, event, context) {
|
|
145
|
+
// Every subscribed callback advances the sequence first, including malformed events, identity
|
|
146
|
+
// failures, and session changes; the monotonic sequence is never reset by any of them.
|
|
147
|
+
this.#advance();
|
|
148
|
+
this.#applySession(context);
|
|
149
|
+
this.#idle = readIdle(context);
|
|
150
|
+
// Boundary and tool facts are applied only under a known, trustworthy identity. An unknown session
|
|
151
|
+
// already invalidated settled and tool-tracking confidence in #applySession, so nothing is applied
|
|
152
|
+
// and no unassociated event mutates the last session's tracked ids.
|
|
153
|
+
if (this.#sessionKnown) {
|
|
154
|
+
switch (kind) {
|
|
155
|
+
case 'before_agent_start':
|
|
156
|
+
this.#settled = false;
|
|
157
|
+
break;
|
|
158
|
+
case 'agent_settled':
|
|
159
|
+
this.#settled = true;
|
|
160
|
+
break;
|
|
161
|
+
case 'tool_execution_start':
|
|
162
|
+
this.#trackStart(event);
|
|
163
|
+
break;
|
|
164
|
+
case 'tool_execution_end':
|
|
165
|
+
this.#trackEnd(event);
|
|
166
|
+
break;
|
|
167
|
+
case 'session_start':
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
this.#enqueueNotify();
|
|
172
|
+
}
|
|
173
|
+
#advance() {
|
|
174
|
+
if (this.#sequenceSaturated)
|
|
175
|
+
return;
|
|
176
|
+
if (this.#sequence >= this.#maxSequence) {
|
|
177
|
+
this.#sequenceSaturated = true;
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
this.#sequence += 1;
|
|
181
|
+
if (this.#sequence >= this.#maxSequence)
|
|
182
|
+
this.#sequenceSaturated = true;
|
|
183
|
+
}
|
|
184
|
+
#applySession(context) {
|
|
185
|
+
const id = readSessionId(context);
|
|
186
|
+
if (id === null) {
|
|
187
|
+
// Unknown identity: invalidate prior session-derived facts rather than resurrecting them on a
|
|
188
|
+
// later matching read. The last known id is retained only so a recovery is not mistaken for a
|
|
189
|
+
// change; confidence stays invalidated until a trustworthy boundary or a real session change.
|
|
190
|
+
this.#sessionKnown = false;
|
|
191
|
+
this.#settled = 'unknown';
|
|
192
|
+
this.#toolTrackingHealthy = false;
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
this.#sessionKnown = true;
|
|
196
|
+
if (this.#sessionId !== id) {
|
|
197
|
+
// Native session change: clear this session's facts and tracked ids, but never the sequence. A new
|
|
198
|
+
// session is the only trustworthy reset of tracking health (a delivery gap, if any, stays sticky).
|
|
199
|
+
this.#sessionId = id;
|
|
200
|
+
this.#settled = 'unknown';
|
|
201
|
+
this.#openTools.clear();
|
|
202
|
+
this.#toolTrackingHealthy = true;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
#trackStart(event) {
|
|
206
|
+
const id = readToolCallId(event);
|
|
207
|
+
if (id === null) {
|
|
208
|
+
this.#toolTrackingHealthy = false;
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
if (this.#openTools.has(id)) {
|
|
212
|
+
this.#toolTrackingHealthy = false;
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
if (this.#openTools.size >= this.#maxTrackedTools) {
|
|
216
|
+
this.#toolTrackingHealthy = false;
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
this.#openTools.add(id);
|
|
220
|
+
}
|
|
221
|
+
#trackEnd(event) {
|
|
222
|
+
const id = readToolCallId(event);
|
|
223
|
+
if (id === null) {
|
|
224
|
+
this.#toolTrackingHealthy = false;
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
if (!this.#openTools.has(id)) {
|
|
228
|
+
this.#toolTrackingHealthy = false;
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
this.#openTools.delete(id);
|
|
232
|
+
}
|
|
233
|
+
#markDeliveryGap() {
|
|
234
|
+
// A delivery gap is sticky and owes a terminal, subscriber-visible loss notification this drain.
|
|
235
|
+
this.#notificationOverflow = true;
|
|
236
|
+
this.#overflowPending = true;
|
|
237
|
+
}
|
|
238
|
+
#deliver(facts) {
|
|
239
|
+
// Copy the listener set so subscription changes during delivery cannot corrupt the walk, and isolate
|
|
240
|
+
// each listener so one throwing listener cannot starve the others or the producer.
|
|
241
|
+
for (const listener of [...this.#listeners]) {
|
|
242
|
+
try {
|
|
243
|
+
listener(facts);
|
|
244
|
+
}
|
|
245
|
+
catch {
|
|
246
|
+
// Listener isolation: swallow and continue.
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
#enqueueNotify() {
|
|
251
|
+
if (this.#notifyQueue.length >= this.#maxNotifyQueue) {
|
|
252
|
+
this.#markDeliveryGap();
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
this.#notifyQueue.push(this.snapshot());
|
|
256
|
+
}
|
|
257
|
+
if (this.#draining)
|
|
258
|
+
return;
|
|
259
|
+
this.#drain();
|
|
260
|
+
}
|
|
261
|
+
#drain() {
|
|
262
|
+
this.#draining = true;
|
|
263
|
+
try {
|
|
264
|
+
// Serialize delivery so reentrant events do not interleave: each subscriber sees snapshots in
|
|
265
|
+
// chronological sequence order. Delivery per drain is bounded to guarantee termination.
|
|
266
|
+
let delivered = 0;
|
|
267
|
+
while (this.#notifyQueue.length > 0) {
|
|
268
|
+
// Once a gap exists, stop delivering stale buffered healthy facts.
|
|
269
|
+
if (this.#overflowPending)
|
|
270
|
+
break;
|
|
271
|
+
if (delivered >= this.#maxNotifyQueue) {
|
|
272
|
+
this.#markDeliveryGap();
|
|
273
|
+
break;
|
|
274
|
+
}
|
|
275
|
+
const facts = this.#notifyQueue.shift();
|
|
276
|
+
if (facts === undefined)
|
|
277
|
+
break;
|
|
278
|
+
this.#deliver(facts);
|
|
279
|
+
delivered += 1;
|
|
280
|
+
}
|
|
281
|
+
if (this.#overflowPending) {
|
|
282
|
+
// Terminal, subscriber-visible loss: discard stale buffered facts and deliver exactly one
|
|
283
|
+
// conservative invalidation so every still-subscribed listener's final fact is the gap, never an
|
|
284
|
+
// older healthy snapshot. Events fired reentrantly during this delivery are dropped (bounded);
|
|
285
|
+
// the sticky overflow keeps every later snapshot invalid, so no further drain is started here.
|
|
286
|
+
this.#overflowPending = false;
|
|
287
|
+
this.#notifyQueue.length = 0;
|
|
288
|
+
this.#deliver(this.snapshot());
|
|
289
|
+
this.#notifyQueue.length = 0;
|
|
290
|
+
this.#overflowPending = false;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
finally {
|
|
294
|
+
this.#draining = false;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
snapshot() {
|
|
298
|
+
// A sticky delivery gap forces conservative confidence; no ordinary later event restores it.
|
|
299
|
+
const gap = this.#notificationOverflow;
|
|
300
|
+
const facts = {
|
|
301
|
+
schema: PI_NATIVE_EVENTS_SCHEMA,
|
|
302
|
+
sessionId: this.#sessionId,
|
|
303
|
+
sessionKnown: this.#sessionKnown,
|
|
304
|
+
settled: gap ? 'unknown' : this.#settled,
|
|
305
|
+
idle: this.#idle,
|
|
306
|
+
inFlightCompleteness: 'unknown',
|
|
307
|
+
observedOpenToolCount: this.#openTools.size,
|
|
308
|
+
toolTrackingHealthy: this.#toolTrackingHealthy && !gap,
|
|
309
|
+
queue: 'unknown',
|
|
310
|
+
approvals: 'unknown',
|
|
311
|
+
nativeStop: false,
|
|
312
|
+
sequence: this.#sequence,
|
|
313
|
+
sequenceSaturated: this.#sequenceSaturated,
|
|
314
|
+
notificationBacklogOverflow: gap,
|
|
315
|
+
limitations: NATIVE_EVENT_LIMITATIONS,
|
|
316
|
+
};
|
|
317
|
+
return Object.freeze(facts);
|
|
318
|
+
}
|
|
319
|
+
onInvalidate(listener) {
|
|
320
|
+
this.#listeners.add(listener);
|
|
321
|
+
let active = true;
|
|
322
|
+
return () => {
|
|
323
|
+
if (!active)
|
|
324
|
+
return;
|
|
325
|
+
active = false;
|
|
326
|
+
this.#listeners.delete(listener);
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
function positiveIntOr(value, fallback) {
|
|
331
|
+
return typeof value === 'number' && Number.isSafeInteger(value) && value > 0
|
|
332
|
+
? value
|
|
333
|
+
: fallback;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Subscribe a fresh producer to the five supported callbacks on `pi`. It only touches the supplied
|
|
337
|
+
* host (`pi.on`); it starts, installs, exports, and wires nothing else. The returned producer yields
|
|
338
|
+
* observations and invalidation notifications only — never authority, control, or a stop proof.
|
|
339
|
+
*/
|
|
340
|
+
export function registerPiNativeEvents(pi, options) {
|
|
341
|
+
const producer = new Producer(options);
|
|
342
|
+
for (const callback of SUPPORTED_CALLBACKS) {
|
|
343
|
+
pi.on(callback, (event, context) => {
|
|
344
|
+
producer.handle(callback, event, context);
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
return producer;
|
|
348
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Opt-in in-session Pi managed-tool freeze (rollover prerequisite).
|
|
3
|
+
*
|
|
4
|
+
* A separately opt-in Pi extension/controller: a later explicit integration calls
|
|
5
|
+
* `registerPiRolloverFreeze(pi, …)` inside a managed interactive session. This module does NOT
|
|
6
|
+
* activate in the current session, install itself, change default lifecycle hooks or touch user
|
|
7
|
+
* settings. It is self-contained: no subprocess, model, network, transcript, file watcher, timer,
|
|
8
|
+
* automatic handoff or successor launch, and no imports of the rollover orchestrator.
|
|
9
|
+
*
|
|
10
|
+
* What it is: a fail-closed managed Pi tool barrier. While latched it BLOCKS every tool except an
|
|
11
|
+
* explicit, vetted native read allowlist. Only tools in a fixed vetted read-tool universe can be
|
|
12
|
+
* allow-listed; bash/write/edit and every unknown/custom tool are blocked regardless of
|
|
13
|
+
* configuration. It never parses shell commands or tool paths and never calls a shell.
|
|
14
|
+
*
|
|
15
|
+
* What it is NOT: an OS sandbox, a stop proof, or an authority control. Pre-existing/background
|
|
16
|
+
* processes and external writers are outside it. A freeze latch alone is not "confirmed stopped".
|
|
17
|
+
* Native settled/queue/in-flight/approval facts are caller-supplied, UNAUTHENTICATED observations,
|
|
18
|
+
* never host-verified; any unknown/busy/pending condition and any session change or tool activity
|
|
19
|
+
* yield not-ready. Each readiness snapshot must be a complete coherent observation; absent facts are
|
|
20
|
+
* unknown, never an inherited historical all-clear. The latch is memory-only: a restart/reload loses
|
|
21
|
+
* it. There is intentionally NO thaw: recovery/release is a later, separately scoped,
|
|
22
|
+
* authority-checked integration.
|
|
23
|
+
*
|
|
24
|
+
* Installed Pi 1.3.0 API pinned from the installed example extensions (the package ships no .d.ts):
|
|
25
|
+
* permission-gate.ts (sha256:e32086ba9dd9b4ba0fd308b65241d9affa0b5ecd3f90ef7ea1b9f2b30cab8cc1),
|
|
26
|
+
* protected-paths.ts (sha256:9ca66b1f3b1b9a61cc5ddc660f92cca2ea66c4264a1bdb6b00e0da5844399fe2),
|
|
27
|
+
* commands.ts (sha256:36716b53da169936c7e1360a4fde1e2fc0c3356a6505f177235f09c5538c6e4f),
|
|
28
|
+
* docs/extensions.md (sha256:a2b5ff0f95e7e470ed0846d7c4fbfc5781fe7e694b8e7f51ea08859f3ad7325d):
|
|
29
|
+
* `pi.on("tool_call", async (event, ctx) => { … return { block: true, reason }; }` [allow: return
|
|
30
|
+
* undefined] with `event.toolName: string` and `event.input: Record<string, unknown>`;
|
|
31
|
+
* `pi.registerCommand(name, { description, handler })`; and the running session is read from
|
|
32
|
+
* `ctx.sessionManager.getSessionId()`. The narrow structural `PiFreezeHost` interface matches that
|
|
33
|
+
* shape. Structural compatibility checks are NOT a shipped-declaration or live-load proof.
|
|
34
|
+
*/
|
|
35
|
+
export declare const PI_ROLLOVER_FREEZE_STATUS_SCHEMA = "pappra/pi-rollover-freeze-status/1";
|
|
36
|
+
/**
|
|
37
|
+
* The fixed vetted native read-tool universe. Only these may ever be allow-listed while latched.
|
|
38
|
+
* Pi 1.3.0 built-in tools are read/bash/edit/write; `read` is the only read-only one. `bash` can
|
|
39
|
+
* read but also write, so it is deliberately excluded; write/edit/unknown/custom are never allowed.
|
|
40
|
+
*/
|
|
41
|
+
export declare const VETTED_NATIVE_READ_TOOLS: readonly string[];
|
|
42
|
+
/** Default allowlist (the full vetted read universe). A caller may only narrow within the vetted set. */
|
|
43
|
+
export declare const DEFAULT_READ_TOOL_ALLOWLIST: readonly string[];
|
|
44
|
+
export interface FreezeToken {
|
|
45
|
+
readonly sessionId: string;
|
|
46
|
+
readonly taskId: string;
|
|
47
|
+
readonly handoffId: string;
|
|
48
|
+
readonly generation: number;
|
|
49
|
+
}
|
|
50
|
+
export type FreezeOutcome = {
|
|
51
|
+
readonly ok: true;
|
|
52
|
+
readonly state: 'frozen' | 'already_frozen';
|
|
53
|
+
readonly idempotent: boolean;
|
|
54
|
+
readonly token: FreezeToken;
|
|
55
|
+
} | {
|
|
56
|
+
readonly ok: false;
|
|
57
|
+
readonly reason: 'invalid_token' | 'wrong_session' | 'conflicting_freeze' | 'stale_generation';
|
|
58
|
+
readonly detail: string;
|
|
59
|
+
};
|
|
60
|
+
export interface ToolDecision {
|
|
61
|
+
readonly block: boolean;
|
|
62
|
+
readonly reason: string | null;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* One caller-supplied, UNAUTHENTICATED native observation. It must carry the full freeze token and
|
|
66
|
+
* is a COMPLETE snapshot; an omitted count/flag is treated as unknown, never an inherited fact.
|
|
67
|
+
*/
|
|
68
|
+
export interface NativeObservation {
|
|
69
|
+
readonly token: FreezeToken;
|
|
70
|
+
readonly sequence: number;
|
|
71
|
+
readonly settled?: boolean;
|
|
72
|
+
readonly queuedMessages?: number;
|
|
73
|
+
readonly inFlightTools?: number;
|
|
74
|
+
readonly pendingApprovals?: number;
|
|
75
|
+
}
|
|
76
|
+
export type ObserveOutcome = {
|
|
77
|
+
readonly ok: true;
|
|
78
|
+
} | {
|
|
79
|
+
readonly ok: false;
|
|
80
|
+
readonly reason: 'not_frozen' | 'token_mismatch' | 'invalid_observation' | 'stale_sequence';
|
|
81
|
+
readonly detail: string;
|
|
82
|
+
};
|
|
83
|
+
export interface FreezeNativeStatus {
|
|
84
|
+
readonly settled: 'yes' | 'no' | 'unknown';
|
|
85
|
+
readonly queuedMessages: number | 'unknown';
|
|
86
|
+
readonly inFlightTools: number | 'unknown';
|
|
87
|
+
readonly pendingApprovals: number | 'unknown';
|
|
88
|
+
readonly observedSequence: number | null;
|
|
89
|
+
}
|
|
90
|
+
export interface FreezeStatus {
|
|
91
|
+
readonly schema: typeof PI_ROLLOVER_FREEZE_STATUS_SCHEMA;
|
|
92
|
+
readonly sessionId: string;
|
|
93
|
+
readonly frozen: boolean;
|
|
94
|
+
readonly token: FreezeToken | null;
|
|
95
|
+
readonly native: FreezeNativeStatus;
|
|
96
|
+
/** The replay fence: the last accepted observation sequence, surviving readiness invalidation. */
|
|
97
|
+
readonly lastAcceptedSequence: number | null;
|
|
98
|
+
/** True only when frozen AND every native fact is a fresh caller-supplied advisory all-clear snapshot (not authoritative live-native facts). */
|
|
99
|
+
readonly ready: boolean;
|
|
100
|
+
readonly readyBlockers: readonly string[];
|
|
101
|
+
/** Readiness is advisory: observations are caller-supplied and unauthenticated, not a stop proof. */
|
|
102
|
+
readonly observationSource: 'caller-supplied-unauthenticated';
|
|
103
|
+
readonly readinessIsNativeStopProof: false;
|
|
104
|
+
readonly thawSupported: false;
|
|
105
|
+
readonly limitations: readonly string[];
|
|
106
|
+
}
|
|
107
|
+
export interface RolloverFreezeOptions {
|
|
108
|
+
/** The native session this controller is bound to; freeze tokens and callbacks must match it. */
|
|
109
|
+
readonly sessionId: string;
|
|
110
|
+
/** Narrowing selection within the vetted read universe; unsafe names are dropped conservatively. */
|
|
111
|
+
readonly readAllowlist?: readonly string[];
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* In-memory, no-I/O freeze controller. One instance per managed session; the `pi` registration
|
|
115
|
+
* wires it to `tool_call` and the freeze/status commands. A fresh instance starts UNPROVEN
|
|
116
|
+
* (not frozen, not ready). There is no thaw.
|
|
117
|
+
*/
|
|
118
|
+
export declare class RolloverFreezeController {
|
|
119
|
+
#private;
|
|
120
|
+
constructor(options: RolloverFreezeOptions);
|
|
121
|
+
get sessionId(): string;
|
|
122
|
+
get frozen(): boolean;
|
|
123
|
+
freeze(token: FreezeToken): FreezeOutcome;
|
|
124
|
+
/**
|
|
125
|
+
* The fail-closed tool barrier, revalidating the live session on every call. A wrong/missing/
|
|
126
|
+
* changed context session invalidates readiness and fails closed while latched; any tool activity
|
|
127
|
+
* invalidates a prior all-clear so it cannot be reused without a fresh observation.
|
|
128
|
+
*/
|
|
129
|
+
decideToolCall(toolName: unknown, contextSessionId: string | null): ToolDecision;
|
|
130
|
+
/** Reset readiness to unknown (on session change or activity). Does not clear the latch. */
|
|
131
|
+
invalidateReadiness(): void;
|
|
132
|
+
/**
|
|
133
|
+
* Apply one caller-supplied, unauthenticated complete native snapshot correlated to the active
|
|
134
|
+
* freeze. Validates the full token and every field type; a malformed or stale observation never
|
|
135
|
+
* changes readiness. Omitted fields become unknown (no inherited all-clear).
|
|
136
|
+
*/
|
|
137
|
+
observe(observation: NativeObservation): ObserveOutcome;
|
|
138
|
+
/** A defensive, frozen in-memory status snapshot; mutating it cannot change the controller. */
|
|
139
|
+
status(): FreezeStatus;
|
|
140
|
+
}
|
|
141
|
+
/** Narrow structural view of the installed Pi 1.3.0 extension host (see header). */
|
|
142
|
+
export interface PiToolCallEvent {
|
|
143
|
+
readonly toolName: string;
|
|
144
|
+
readonly input: Record<string, unknown>;
|
|
145
|
+
}
|
|
146
|
+
export interface PiToolBlockDecision {
|
|
147
|
+
readonly block: true;
|
|
148
|
+
readonly reason: string;
|
|
149
|
+
}
|
|
150
|
+
export interface PiCommandOptions {
|
|
151
|
+
readonly description: string;
|
|
152
|
+
readonly handler: (args: string, context: unknown) => void | Promise<void>;
|
|
153
|
+
}
|
|
154
|
+
export interface PiFreezeHost {
|
|
155
|
+
on(event: 'tool_call', handler: (event: PiToolCallEvent, context: unknown) => Promise<PiToolBlockDecision | undefined>): void;
|
|
156
|
+
registerCommand(name: string, options: PiCommandOptions): void;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Concrete registration entry for a later explicit integration. Wires the controller to the Pi
|
|
160
|
+
* `tool_call` barrier (revalidating the live session on every call) and to validated
|
|
161
|
+
* `/rollover-freeze` and `/rollover-status` commands. There is intentionally NO thaw command.
|
|
162
|
+
* Returns the controller (the no-I/O orchestration surface). It only touches the supplied `pi`.
|
|
163
|
+
*/
|
|
164
|
+
export declare function registerPiRolloverFreeze(pi: PiFreezeHost, options: RolloverFreezeOptions & {
|
|
165
|
+
readonly controller?: RolloverFreezeController;
|
|
166
|
+
}): RolloverFreezeController;
|