@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,633 @@
|
|
|
1
|
+
# Collaboration messages and notification
|
|
2
|
+
|
|
3
|
+
Use this reference when a task needs task-scoped messages between two agent
|
|
4
|
+
sessions. Persisting a message, notifying a recipient, the recipient's ACK, its
|
|
5
|
+
REPORT, and the coordinator's acceptance are five different facts. This surface
|
|
6
|
+
keeps them separate and never infers one from another.
|
|
7
|
+
|
|
8
|
+
## MCP collaboration preparation
|
|
9
|
+
|
|
10
|
+
The default MCP server is read-only. A trusted host must enable
|
|
11
|
+
`pappra mcp --allow-workspace-writes` at server startup before checkpoint,
|
|
12
|
+
knowledge registration or workspace-private collaboration preparation can write.
|
|
13
|
+
Tool `apply`/`confirm` fields never grant that policy. Runtime installation,
|
|
14
|
+
external engine preparation and process launch require the authorized CLI.
|
|
15
|
+
MCP preparation domains resolve under `.pappra/local/collaboration`, with cwd
|
|
16
|
+
and resources inside the workspace; use the CLI for explicitly authorized
|
|
17
|
+
external domains. The CLI workflow below is independent of MCP write policy.
|
|
18
|
+
|
|
19
|
+
MCP `collab_prepare` uses the same strict `pappra/collaboration-goal/1` as the installed CLI and accepts exactly `{ domainRoot, goal }`:
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"domainRoot": "/absolute/domain",
|
|
24
|
+
"goal": {
|
|
25
|
+
"schema": "pappra/collaboration-goal/1",
|
|
26
|
+
"task_id": "FIJI-123456",
|
|
27
|
+
"subtask_id": "implementation-slice",
|
|
28
|
+
"attempt": 1,
|
|
29
|
+
"phase": "implementation",
|
|
30
|
+
"objective": "Prepare one bounded collaboration slice.",
|
|
31
|
+
"acceptance": ["prepared references verify"],
|
|
32
|
+
"prompt": "Use only the frozen prompt.",
|
|
33
|
+
"roles": ["implementer"],
|
|
34
|
+
"coordinator": {
|
|
35
|
+
"agent_id": "pappra-coordinator",
|
|
36
|
+
"session_id": "coordinator-session",
|
|
37
|
+
"harness": "codex",
|
|
38
|
+
"owner_epoch": 1
|
|
39
|
+
},
|
|
40
|
+
"assignee": {
|
|
41
|
+
"agent_id": "pappra-implement",
|
|
42
|
+
"session_id": "assignee-session",
|
|
43
|
+
"harness": "pi",
|
|
44
|
+
"surface": "cli",
|
|
45
|
+
"configuration_id": "daily-herdr",
|
|
46
|
+
"cwd": "/absolute/assignee/workspace"
|
|
47
|
+
},
|
|
48
|
+
"resources": [{ "path": "/absolute/repository", "access": "write" }],
|
|
49
|
+
"required": { "skills": [], "tools": ["read"] },
|
|
50
|
+
"preferred": { "skills": [], "tools": [] }
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The former flat `objective`/`task`/`acceptance`/`resources`/`coordinatorSession`/`assigneeSession`/`harness`/`subtaskId` arguments are rejected before task or claim writes. Migrate by moving those values under `goal` with protocol names (`task_id`, `subtask_id`, snake_case identities and requirements); explicitly supply coordinator `owner_epoch` and assignee `surface`, `configuration_id`, and independent `cwd`. Unknown or mixed legacy fields are errors. Omitted `roles` retains the documented `['implementer']` compatibility default; explicit roles are bounded, unique, and copied to the assignment.
|
|
56
|
+
|
|
57
|
+
Preparation returns the prepared bundle and goal. It does not create a synthesized declared card and does not return the removed `cardPath`/`card` outputs. Supply actual runtime evidence separately by deriving a card from the receiving session and checking it with preflight. Runner metadata maps `pi`/`codex`/`claude` to `pi-cli`/`codex-exec`/`claude-cli`, but the only real live controller here is `pi-rpc` for Pi; `fixture` remains explicit test-only behavior. `collab_start` returns `cli_required` without launching; the user must run `pappra collab run` with confirmation and admitted runtime evidence in the CLI.
|
|
58
|
+
|
|
59
|
+
## Before you start
|
|
60
|
+
|
|
61
|
+
A task root is `<domain>/tasks/<task-id>` and already contains `task.json`,
|
|
62
|
+
`messages/` and `ledger.jsonl`. `pappra collab prepare` creates it. All message
|
|
63
|
+
commands require the absolute `--task-root`; nothing is discovered from the
|
|
64
|
+
current directory, chat text, or another task.
|
|
65
|
+
|
|
66
|
+
## Commands
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
# Validate an envelope without writing anything (default is plan-only).
|
|
70
|
+
pappra collab message send --task-root <abs-task-root> \
|
|
71
|
+
--message <abs-envelope.json> --json
|
|
72
|
+
|
|
73
|
+
# Register and apply the message through the existing protocol.
|
|
74
|
+
pappra collab message send --task-root <abs-task-root> \
|
|
75
|
+
--message <abs-envelope.json> --apply --json
|
|
76
|
+
|
|
77
|
+
# Read one registered message and its record entry (read-only).
|
|
78
|
+
pappra collab message read --task-root <abs-task-root> \
|
|
79
|
+
--message-id <id> --json
|
|
80
|
+
|
|
81
|
+
# List the most recent applied messages (read-only, bounded by --limit 1-100).
|
|
82
|
+
pappra collab message list --task-root <abs-task-root> --limit 20 --json
|
|
83
|
+
|
|
84
|
+
# Validate task, message, binding and recipient without querying Herdr.
|
|
85
|
+
pappra collab message notify --task-root <abs-task-root> \
|
|
86
|
+
--message-id <id> --binding <abs-binding.json> --json
|
|
87
|
+
|
|
88
|
+
# Send exactly one pointer-only Herdr prompt for the registered message.
|
|
89
|
+
pappra collab message notify --task-root <abs-task-root> \
|
|
90
|
+
--message-id <id> --binding <abs-binding.json> --apply --json
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
```sh
|
|
94
|
+
# Inspect or plan one writer rollover (read-only; there is no apply action).
|
|
95
|
+
pappra collab rollover inspect --task-root <abs-task-root> \
|
|
96
|
+
--request <abs-rollover-request.json> --json
|
|
97
|
+
pappra collab rollover plan --task-root <abs-task-root> \
|
|
98
|
+
--request <abs-rollover-request.json> --json
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
`send` never notifies and `notify` never changes the task record. A successful
|
|
102
|
+
`notify` means one prompt was submitted to a named Herdr agent; it does not mean
|
|
103
|
+
the recipient read it, consumed it, or accepted the work.
|
|
104
|
+
|
|
105
|
+
## Envelope
|
|
106
|
+
|
|
107
|
+
Messages use `harness-collab/message/1`; validate them with the same rules the
|
|
108
|
+
protocol already applies (`type`, explicit `from`/`to` identities, required
|
|
109
|
+
`reply_to`/`subtask_id`/`attempt` per type, `body.status` restricted to the
|
|
110
|
+
report statuses). Message ids are single path segments: a letter or digit
|
|
111
|
+
followed by letters, digits, dot, dash or underscore (maximum 128 characters).
|
|
112
|
+
|
|
113
|
+
Protocol behaviour is unchanged:
|
|
114
|
+
|
|
115
|
+
- `ASSIGN` registers or updates the attempt and opens a
|
|
116
|
+
`registered_not_started` uncertainty; it does not launch anything.
|
|
117
|
+
- `ACK` correlates to the assignment and records consumption, not progress.
|
|
118
|
+
- `ASK` is evidence only. It records the question and changes no task state.
|
|
119
|
+
Blocking a clarification remains `BLOCK(kind=clarification)`.
|
|
120
|
+
- `ANSWER` resolves a correlated `needs_input`/clarification attempt back to
|
|
121
|
+
`running`; an uncorrelated ANSWER is recorded without a transition; an ANSWER
|
|
122
|
+
to an approval block is refused (`approval_not_auto_answerable`).
|
|
123
|
+
- `REPORT` is admitted only from the attempt's current assignee; a stale sender's
|
|
124
|
+
report is retained as evidence with an uncertainty and changes nothing.
|
|
125
|
+
- `CANCEL` records intent and keeps claims; `CANCELLED` requires stop evidence.
|
|
126
|
+
- `HANDOFF`, `STATUS`, `STATUS_QUERY` and `BLOCK` keep their existing semantics.
|
|
127
|
+
|
|
128
|
+
## Binding document
|
|
129
|
+
|
|
130
|
+
A binding is task-local routing metadata, not authority. It maps the exact
|
|
131
|
+
protocol recipient to a named Herdr agent so a notification cannot target a
|
|
132
|
+
focused pane or an unrelated session.
|
|
133
|
+
|
|
134
|
+
```json
|
|
135
|
+
{
|
|
136
|
+
"schema": "pappra/collab-binding/1",
|
|
137
|
+
"task_id": "FIJI-123456",
|
|
138
|
+
"task_root": "/absolute/domain/tasks/FIJI-123456",
|
|
139
|
+
"channel": "herdr",
|
|
140
|
+
"participants": [
|
|
141
|
+
{
|
|
142
|
+
"agent_id": "pappra-implement",
|
|
143
|
+
"harness": "pi",
|
|
144
|
+
"cwd": "/absolute/workspace",
|
|
145
|
+
"herdr_agent": "pappra-implement",
|
|
146
|
+
"pane_id": "w3:p3",
|
|
147
|
+
"native_session_id": "b4c18851-d297-4f99-9850-9be1a0f9a9a7"
|
|
148
|
+
}
|
|
149
|
+
]
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
`native_session_id` may be `null` when the harness exposes no native session.
|
|
154
|
+
Both sender and recipient must be in the binding. The selected sender pane must
|
|
155
|
+
equal the sender binding pane, and live sender/recipient name, pane, harness and
|
|
156
|
+
cwd must match. Routing has two modes:
|
|
157
|
+
|
|
158
|
+
- **current context (default):** requires a nonempty inherited `HERDR_PANE_ID`
|
|
159
|
+
before `herdr pane current --current`; missing context refuses rather than
|
|
160
|
+
resolving through focus, and stale IDs fail visibly.
|
|
161
|
+
- **explicit task-bound (`--caller-pane <id>`):** uses
|
|
162
|
+
`herdr pane current --pane <id>` without changing the environment or focus.
|
|
163
|
+
Stale inherited IDs do not override it.
|
|
164
|
+
|
|
165
|
+
Selecting a pane is routing, not sender authentication or process proof; hosted
|
|
166
|
+
or detached agents are supported through the task-bound binding. Native session
|
|
167
|
+
evidence is compared exactly, not by substring: for Pi (`kind: "path"`) the
|
|
168
|
+
native identity is the final `_<session-id>` segment; a different session in an
|
|
169
|
+
ancestor directory is a mismatch. Sender and recipient sessions are checked even
|
|
170
|
+
when a binding leaves `native_session_id` null. Missing session stays
|
|
171
|
+
`native_session: "unknown"` instead of claiming a match. A moved task or binding
|
|
172
|
+
must be revalidated and re-bound; nothing is relocated automatically.
|
|
173
|
+
|
|
174
|
+
## Controller-owned native Pi sessions
|
|
175
|
+
|
|
176
|
+
`pappra session plan --config <abs managed-pi.json>` validates a fresh launch
|
|
177
|
+
request. `session start` runs the native Pi TUI in the calling visible terminal
|
|
178
|
+
with its normal daily configuration and an explicit OpenRouter model. The
|
|
179
|
+
request schema is `pappra/managed-pi-session-request/1` with `cwd`, `model` and
|
|
180
|
+
`journalPath`; use an existing private directory for the journal.
|
|
181
|
+
|
|
182
|
+
`session status|fence|stop --config <same-file> --json` uses only that launch's
|
|
183
|
+
private endpoint. Fencing stops terminal ingress; stopping waits for the exact
|
|
184
|
+
owned child. Neither proves complete queues, approvals or external-writer
|
|
185
|
+
quiescence, and automatic handoff/resource transfer remains blocked. Existing
|
|
186
|
+
interactive sessions cannot be adopted. Input journals can contain private
|
|
187
|
+
keystrokes; preserve their private permissions and never replay raw bytes.
|
|
188
|
+
|
|
189
|
+
## Role-based planning
|
|
190
|
+
|
|
191
|
+
`pappra collab role-plan expand --request <abs role-plan.json> --json`
|
|
192
|
+
expands explicit participants, assignments and disjoint writer scopes into the
|
|
193
|
+
existing work-plan format. Save its `plan` field, then use `collab plan` and
|
|
194
|
+
`collab work-run` with their existing admission and capability requirements.
|
|
195
|
+
The reviewer depends on all writers and waits for coordinator acceptance.
|
|
196
|
+
|
|
197
|
+
`pappra collab role-plan aggregate --request <abs role-plan.json> --task-root <abs> --config <abs expanded-plan.json> --json`
|
|
198
|
+
checks the persisted plan against the request and reads authoritative task
|
|
199
|
+
evidence through the work-plan inspector. Rejected, unknown, missing and pending
|
|
200
|
+
outcomes remain visible. A delivery acknowledgement never becomes acceptance.
|
|
201
|
+
Neither command launches a model, claims resources or creates an assignment.
|
|
202
|
+
|
|
203
|
+
## Native capability evidence
|
|
204
|
+
|
|
205
|
+
`pappra collab capabilities derive --harness <pi|codex|claude> --assignment <abs assignment.json> --template <abs card.declared.json> --execution <abs execution.json> [--session <abs pi-session.jsonl> | --events <abs events.jsonl>] [--json]`
|
|
206
|
+
turns saved native evidence into a runtime capability card with the maintained
|
|
207
|
+
Pi, Codex and Claude semantics. It is read-only: deriving writes no file, starts
|
|
208
|
+
no process, spends no model turn and dispatches nothing. Pi requires `--session`;
|
|
209
|
+
Codex and Claude require `--events`; wrong-host, duplicate and unknown flags are
|
|
210
|
+
rejected. Exit 0 derived, 1 needs_input, 2 invalid request. JSON uses
|
|
211
|
+
`pappra/collaboration-capabilities/1`.
|
|
212
|
+
|
|
213
|
+
Assignment and template files are bounded at 1 MiB, native evidence at 16 MiB;
|
|
214
|
+
all paths must be absolute. Final symlinks, FIFOs and special files are refused
|
|
215
|
+
without blocking, with descriptor-level checks. Diagnostics never include
|
|
216
|
+
evidence content.
|
|
217
|
+
|
|
218
|
+
- **Pi:** tools need correlated successful results; a skill is verified only by a
|
|
219
|
+
successful read of its `SKILL.md`. Observation time is the session's own last
|
|
220
|
+
usable timestamp; incomplete results or an indeterminate `toolUse` turn end are
|
|
221
|
+
refused.
|
|
222
|
+
- **Codex:** only explicit item-to-tool mappings can promote tools; skills stay
|
|
223
|
+
unknown because `exec --json` does not report invocation. Unknown rows/items
|
|
224
|
+
fail closed.
|
|
225
|
+
- **Claude:** discovery/bootstrap may use only `Read` and `Skill`; verified skills
|
|
226
|
+
require the injected base directory to match the fingerprinted source.
|
|
227
|
+
|
|
228
|
+
Old evidence never becomes fresh and a fixture shape is not live-version proof.
|
|
229
|
+
The card remains a claim from the supplied evidence; preflight still checks it
|
|
230
|
+
separately and no authentication, ownership, admission or launch is implied.
|
|
231
|
+
|
|
232
|
+
For an interactive Pi session that is still open, replace `--execution <file>`
|
|
233
|
+
with `--live`. This derives the standard card directly from a settled saved
|
|
234
|
+
session, without fabricating a process-exit receipt or manually normalizing a
|
|
235
|
+
model-written card. Pending tool results, a trailing user message, a non-`stop`
|
|
236
|
+
assistant result or a later model change refuse derivation. Metadata appends do
|
|
237
|
+
not refresh the observation timestamp. This is a historical snapshot of observed
|
|
238
|
+
successful tools and skill reads, not proof of current tool registration, live
|
|
239
|
+
process state, queue contents, approvals or ownership.
|
|
240
|
+
|
|
241
|
+
```nu
|
|
242
|
+
let derived = (^pappra collab capabilities derive --harness pi --assignment /abs/assignment.json --template /abs/card.declared.json --live --session /abs/session.jsonl --json | from json)
|
|
243
|
+
if $derived.status != 'derived' { error make {msg: $"derive refused: ($derived.status)"} }
|
|
244
|
+
$derived.card | to json | save --raw /abs/task/card.runtime.json
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
```nu
|
|
248
|
+
let derived = (^pappra collab capabilities derive --harness pi --assignment /abs/assignment.json --template /abs/card.declared.json --execution /abs/execution.json --session /abs/session.jsonl --json | from json)
|
|
249
|
+
if $derived.status != 'derived' { error make {msg: $"derive refused: ($derived.status)"} }
|
|
250
|
+
$derived.card | to json | save --raw /abs/task/card.runtime.json
|
|
251
|
+
^pappra collab preflight --assignment /abs/assignment.json --capabilities /abs/task/card.runtime.json --json
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Task state and resource controls
|
|
255
|
+
|
|
256
|
+
```sh
|
|
257
|
+
pappra collab state show|doctor --task-root <abs> [--json]
|
|
258
|
+
pappra collab state epoch-check --task-root <abs> --owner-epoch <positive> [--json]
|
|
259
|
+
pappra collab resource list --task-root <abs> [--json]
|
|
260
|
+
pappra collab resource claim|release --task-root <abs> --request <abs> [--apply] [--json]
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
State commands reuse the existing record/lock/transaction/doctor primitives and
|
|
264
|
+
are read-only; doctor never repairs, breaks a lock, releases or launches.
|
|
265
|
+
Unresolved uncertain or invalid findings make doctor needs-input (exit 1); a live
|
|
266
|
+
lock observation alone is active evidence, not a readiness failure.
|
|
267
|
+
`resource list` reports domain claims and unreadable tasks as `state: "unknown"`;
|
|
268
|
+
its displayed claims share one global 500-claim budget across at most 100 tasks,
|
|
269
|
+
with full counts and actual `omitted`/`truncated` metadata.
|
|
270
|
+
|
|
271
|
+
Resource requests use `pappra/collaboration-resource-request/1` with an exact
|
|
272
|
+
action, explicit holder agent/session, canonical resource kinds and `access:
|
|
273
|
+
read|write`; release names one `claim_id`. Files are bounded at 1 MiB and read
|
|
274
|
+
with the special-file-safe loader. Plan without `--apply` validates only the
|
|
275
|
+
strict request and task namespace; it reserves nothing. Apply revalidates and
|
|
276
|
+
calls exactly the existing claim/release primitive. This is cooperative record
|
|
277
|
+
mutation, not OS fencing.
|
|
278
|
+
|
|
279
|
+
The namespace proof reuses the message task validator and also refuses redirected
|
|
280
|
+
or special `.write.lock`, transaction, ledger, aborted/broken-lock, `.domain.lock`
|
|
281
|
+
and neighboring task-record paths before reading or mutating them. System aliases
|
|
282
|
+
above the domain remain valid. Exit 0 success, 1 conflict/uncertainty/refusal,
|
|
283
|
+
2 invalid request/options. Use fresh fixture domains in tests; never alter live
|
|
284
|
+
claims.
|
|
285
|
+
|
|
286
|
+
## Recorded ownership handoff
|
|
287
|
+
|
|
288
|
+
```sh
|
|
289
|
+
pappra collab handoff inventory --task-root <abs> [--subtask-id <id>] [--attempt <n>] [--json]
|
|
290
|
+
pappra collab handoff <begin|stopped|rebind|transfer|confirm|complete|abort|release-dispatch> \
|
|
291
|
+
--task-root <abs> --request <abs> [--apply] [--json]
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Requests use `pappra/collaboration-handoff-request/1` with an exact action, actor,
|
|
295
|
+
positive current `owner_epoch`, optional `expect_revision`, and action fields that
|
|
296
|
+
map to the existing primitives. Actor/epoch are editable protocol inputs, not
|
|
297
|
+
authentication. Plan without `--apply` validates request/namespace only and writes
|
|
298
|
+
nothing; apply revalidates and checks the epoch inside the guarded transaction,
|
|
299
|
+
preserving refusal rollback. This records cooperative ownership transfer; it is
|
|
300
|
+
not OS fencing, stop proof or a launch mechanism.
|
|
301
|
+
|
|
302
|
+
Confirmation is a registered message that is already present in the authoritative
|
|
303
|
+
record as an accepted/recorded ACK or HANDOFF entry. It must match its stored
|
|
304
|
+
content digest, come from the receiver to the current coordinator, carry the
|
|
305
|
+
current owner epoch, and explicitly correlate via `body.handoff_id` or `reply_to`
|
|
306
|
+
to the handoff with no conflicting body id. HANDOFF confirmations use a
|
|
307
|
+
non-request phase such as `confirmation`. Missing, unapplied, wrong-identity,
|
|
308
|
+
wrong-epoch, replayed, unrelated, symlink or FIFO confirmations cannot transfer
|
|
309
|
+
ownership. Writer completion transfers recorded claims and raises resource epochs;
|
|
310
|
+
coordinator completion raises owner_epoch and keeps dispatch frozen until an
|
|
311
|
+
explicit current-epoch `release-dispatch`.
|
|
312
|
+
|
|
313
|
+
Inventory is stored-state-only, bounded, read-only and never prints message bodies
|
|
314
|
+
or arbitrary inventory payloads. No command queries pane idle, stops a process,
|
|
315
|
+
answers an approval or launches an agent.
|
|
316
|
+
|
|
317
|
+
## Explicit recovery
|
|
318
|
+
|
|
319
|
+
```sh
|
|
320
|
+
pappra collab recovery inspect --task-root <abs> [--json]
|
|
321
|
+
pappra collab recovery reconcile --task-root <abs> --request <abs> [--apply] [--json]
|
|
322
|
+
pappra collab recovery lock-break --task-root <abs> --request <abs> [--apply] [--json]
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
Requests use `pappra/collaboration-recovery-request/1`; results use
|
|
326
|
+
`pappra/collaboration-recovery/1`. Request JSON is bounded at 1 MiB through the
|
|
327
|
+
special-file-safe loader. Inspect is read-only and reports bounded uncertainty,
|
|
328
|
+
task lock/transactions and a stable lock-content fingerprint; PID liveness is an
|
|
329
|
+
observation, not stop proof. Exit 1 for open uncertainty, interrupted
|
|
330
|
+
transactions or an unavailable/oversized lock snapshot.
|
|
331
|
+
|
|
332
|
+
Reconcile records one explicit resolution and evidence reference, optionally
|
|
333
|
+
applying an existing state transition for that uncertainty's exact
|
|
334
|
+
subtask/attempt. Resolution and transition share one guarded transaction: an
|
|
335
|
+
invalid/approval-denied transition or missing context refuses both, without
|
|
336
|
+
committing resolution first. It does not release claims, clear `cancel_pending`
|
|
337
|
+
or invent native evidence.
|
|
338
|
+
|
|
339
|
+
An unexpected reconcile transaction exception is reported conservatively as
|
|
340
|
+
`reconcile_uncertain`: the record commit may already have happened even if ledger
|
|
341
|
+
evidence failed. Inspect the task record and ledger before any explicit retry; no
|
|
342
|
+
automatic rollback, retry or second journal is created.
|
|
343
|
+
|
|
344
|
+
Lock-break requires current epoch, reason, a literal `confirm_holder_stopped: true`
|
|
345
|
+
and the exact fingerprint from inspect; the operator assertion is not a Pappra
|
|
346
|
+
native proof. Plan writes nothing. Apply revalidates namespace, epoch and exact
|
|
347
|
+
lock content before the existing `breakLock`; changed/unavailable snapshots are
|
|
348
|
+
refused. The old lock, holder, transactions and break record are archived without
|
|
349
|
+
overwrite, age-based reclaim or deletion of unknown evidence. Ambiguous
|
|
350
|
+
post-mutation failure is reported as uncertain. Only the task write lock is
|
|
351
|
+
recovered, never the domain lock or an execution.
|
|
352
|
+
|
|
353
|
+
## Portable task bindings
|
|
354
|
+
|
|
355
|
+
```sh
|
|
356
|
+
pappra collab binding list [--root <abs>] [--json]
|
|
357
|
+
pappra collab binding resolve --task-id <alias> [--root <abs>] [--roots <abs roots.json>] [--json]
|
|
358
|
+
pappra collab binding bind --task-id <alias> --record <abs task.json> [--root <abs>] [--apply] [--json]
|
|
359
|
+
pappra collab binding unbind --task-id <alias> [--root <abs>] [--apply] [--json]
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
The workspace-local `<workspace>/.pappra/local/collab-bindings.json` table
|
|
363
|
+
(schema `pappra/collaboration-bindings/1`, tied to `workspaceId`) stores pointer
|
|
364
|
+
metadata only: canonical record/task/domain paths, alias, protocol task ID,
|
|
365
|
+
domain identity, immutable record `created_at`, bound time, and explicit
|
|
366
|
+
tombstones. It never copies protocol content and is not execution authority.
|
|
367
|
+
|
|
368
|
+
Bind validates a real `<task_root>/task.json` before writing; normal revision or
|
|
369
|
+
inode replacement stays usable, while reinitialization/identity drift is a
|
|
370
|
+
conflict requiring explicit unbind. Plan writes nothing; apply serializes via
|
|
371
|
+
the existing private-state lock, rereads and atomically publishes. Unbind never
|
|
372
|
+
reads the target and leaves a tombstone; a later bind clears it. Present invalid
|
|
373
|
+
metadata is preserved and never bypassed.
|
|
374
|
+
|
|
375
|
+
The same 1 MiB ceiling applies to exact serialized publications: bind/unbind
|
|
376
|
+
returns `bindings_capacity` before index replacement if the new bytes exceed the
|
|
377
|
+
limit; previous bytes and every pointer/tombstone stay intact. Pappra never drops
|
|
378
|
+
entries to fit.
|
|
379
|
+
|
|
380
|
+
An alias present in both `bindings` and `unbound` makes the index invalid for
|
|
381
|
+
every action; the bytes are preserved and resolution never falls through to
|
|
382
|
+
discovery. A valid tombstone is removed only by a later explicit bind.
|
|
383
|
+
|
|
384
|
+
Resolve precedence is invalid index (fail), explicit binding (exclusive),
|
|
385
|
+
tombstone, explicit `--roots` discovery (≤32 absolute collaboration domain
|
|
386
|
+
roots, only `<root>/tasks/<alias>/task.json`, canonical dedupe, unique or
|
|
387
|
+
ambiguous/incomplete), then none. No home registry scan or automatic persistence
|
|
388
|
+
of discovered targets. A usable target reports persisted revision/coordinator/
|
|
389
|
+
freeze/attempt summaries with `scope: persisted-history` and
|
|
390
|
+
`liveStatus: unknown`; it never proves native running/stopped/accepted state.
|
|
391
|
+
List/resolve/plan are read-only.
|
|
392
|
+
|
|
393
|
+
`--json` emits one versioned result (`pappra/collaboration-binding-result/1`).
|
|
394
|
+
From an unrelated cwd with an explicit root:
|
|
395
|
+
|
|
396
|
+
```sh
|
|
397
|
+
pappra collab binding bind --root /abs/ws --task-id workspace-experience \
|
|
398
|
+
--record /abs/domain/tasks/workspace-experience/task.json # plan, no write
|
|
399
|
+
pappra collab binding resolve --root /abs/ws --task-id workspace-experience
|
|
400
|
+
# Alias workspace-experience: binding (usable true).
|
|
401
|
+
pappra collab binding unbind --root /abs/ws --task-id workspace-experience --apply
|
|
402
|
+
# Unbind unbound; applied true. Later resolve reports unbound.
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
Without `--root` the caller's nearest registered workspace is used; a caller
|
|
406
|
+
outside any workspace fails `workspace_unavailable` (exit 2) rather than
|
|
407
|
+
scanning home or an outer registry.
|
|
408
|
+
|
|
409
|
+
## Readiness preflight
|
|
410
|
+
|
|
411
|
+
`pappra collab preflight --assignment <abs assignment.json> --capabilities <abs card.json> [--max-age-minutes <n>] [--json]`
|
|
412
|
+
checks reported readiness with the existing primitive. It is read-only: no
|
|
413
|
+
launch, claim, task mutation, evidence refresh, file-content output or model
|
|
414
|
+
turn. Exit codes: 0 ready, 1 needs_input, 2 invalid request/JSON/contract/card.
|
|
415
|
+
JSON uses `pappra/collaboration-preflight/1`; `ok` is true only for `ready`.
|
|
416
|
+
|
|
417
|
+
Pre-dispatch walkthrough:
|
|
418
|
+
|
|
419
|
+
```sh
|
|
420
|
+
# A card observed from the real receiving session.
|
|
421
|
+
pappra collab preflight --assignment /abs/assignment.json \
|
|
422
|
+
--capabilities /abs/card.runtime.json --json
|
|
423
|
+
|
|
424
|
+
# A declared template only plans; it does not pass work readiness.
|
|
425
|
+
pappra collab preflight --assignment /abs/assignment.json \
|
|
426
|
+
--capabilities /abs/card.declared.json --json
|
|
427
|
+
# -> needs_input, blocker runtime_capabilities_unconfirmed
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
Do not relabel a declared template as runtime. Derive a runtime card from
|
|
431
|
+
native evidence with `pappra collab capabilities derive`, or pass a separately
|
|
432
|
+
obtained card. `ready` means only current reported capability/evidence readiness;
|
|
433
|
+
self-reported facts, authorize dispatch, acquire resources, verify epochs,
|
|
434
|
+
launch, prove completion or replace launch admission. Warnings (for example a
|
|
435
|
+
write resource whose ownership is not enforced) and limits remain visible. The
|
|
436
|
+
default freshness window is 30 minutes; `--max-age-minutes` accepts a positive
|
|
437
|
+
finite override.
|
|
438
|
+
|
|
439
|
+
### Model choice and readiness recovery
|
|
440
|
+
|
|
441
|
+
Model, provider and reasoning level are mutable **runtime observations** recorded in
|
|
442
|
+
a card's `native_observation`; they are not task identity, session identity,
|
|
443
|
+
`configuration_id`, ownership epoch or evidence freshness. A user-selected model
|
|
444
|
+
change alone therefore requires neither a new task identity nor reverting to the
|
|
445
|
+
original model, and no product check compares model or provider today.
|
|
446
|
+
|
|
447
|
+
Keep the current user model. When readiness fails, apply the recovery that matches
|
|
448
|
+
the actual blocker: derive _fresh_ evidence from the current receiving session for
|
|
449
|
+
stale evidence (never retimestamp older evidence); compare host and native
|
|
450
|
+
timestamps for future-clock evidence; treat an unavailable tool or skill code as
|
|
451
|
+
unconfirmed readiness rather than proven absence — inspect the current runtime
|
|
452
|
+
exposure, obtain actual current evidence, and restore or enable the capability when
|
|
453
|
+
it is in fact missing (changing a requirement is the coordinator's explicit scope
|
|
454
|
+
decision, not a worker recovery step); supply evidence for the exact
|
|
455
|
+
assignee identity/session/cwd/configuration for identity mismatches. Earlier
|
|
456
|
+
successful tool use does not prove the current runtime still exposes that tool, so
|
|
457
|
+
re-derive after a material change instead of promoting history into evidence.
|
|
458
|
+
Needs-input human output groups these recoveries; JSON status, blockers and exit
|
|
459
|
+
codes are unchanged, and unknown blockers keep their code without an invented
|
|
460
|
+
remedy.
|
|
461
|
+
|
|
462
|
+
## Read-only work-plan inspection
|
|
463
|
+
|
|
464
|
+
```nu
|
|
465
|
+
# Plan document: role/dependency nodes over the existing task protocol.
|
|
466
|
+
# A ready node is not authorization to run it.
|
|
467
|
+
^pappra collab plan --task-root /abs/domain/tasks/example --config /abs/work-plan.json --json
|
|
468
|
+
| from json
|
|
469
|
+
| select status stale summary
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
`collab plan` loads one bounded regular plan file and the exact task namespace,
|
|
473
|
+
then re-reads every registered decision envelope the evaluation needs. Each node
|
|
474
|
+
names a role label, the assignment attempt it expects, its pinned input revision,
|
|
475
|
+
its dependencies and its intended resource scope. Roles describe
|
|
476
|
+
responsibilities only; they grant no authority.
|
|
477
|
+
|
|
478
|
+
Node `assignment_id` is the existing task subtask identity
|
|
479
|
+
(`record.attempts[].subtask_id`); there is no second assignment registry.
|
|
480
|
+
|
|
481
|
+
Acceptance convention: a dependency advances only after the current coordinator
|
|
482
|
+
registers an `ANSWER` that is applied, digest-verifiable, and correlated to the
|
|
483
|
+
predecessor's assignment attempt, pinned input revision and registered report
|
|
484
|
+
digest. The complete registered decision set is authoritative, so an omitted
|
|
485
|
+
later rejection leaves acceptance `unknown`; sender timestamps never order
|
|
486
|
+
decisions (record application order does). A finished `REPORT` alone keeps the
|
|
487
|
+
node `awaiting_acceptance` and its dependents blocked.
|
|
488
|
+
|
|
489
|
+
Limits: the report is a persisted snapshot, advisory only, with no claim, launch,
|
|
490
|
+
dispatch, refresh, reconcile, native query or message write, and no resource
|
|
491
|
+
fencing. Evidence is scoped to the plan: only decisions addressed to the current
|
|
492
|
+
applied reports of the planned attempts are read, so unrelated task messages never
|
|
493
|
+
become required and are never counted. Plan documents are bounded at 512 KiB;
|
|
494
|
+
relevant decision evidence is bounded at 128 envelopes, 1 MiB per file and 4 MiB
|
|
495
|
+
aggregate, measured in the raw file bytes consumed by the bounded read (including
|
|
496
|
+
files later rejected by validation) before any full parse; record arrays are bounded
|
|
497
|
+
at 512 entries. Exceeding a bound reports `incomplete` with an explicit diagnostic
|
|
498
|
+
instead of returning truncated readiness. Read the human output for role, node
|
|
499
|
+
status, the blocking dependency/resource condition and the next action; message
|
|
500
|
+
bodies are never printed.
|
|
501
|
+
|
|
502
|
+
## Read-only rollover inspection
|
|
503
|
+
|
|
504
|
+
```nu
|
|
505
|
+
# Request: schema pappra/collaboration-rollover-request/1, bounded at 64 KiB.
|
|
506
|
+
^pappra collab rollover inspect --task-root /abs/domain/tasks/example \
|
|
507
|
+
--request /abs/rollover-request.json --json
|
|
508
|
+
| from json
|
|
509
|
+
| select action ok plan_complete intent bundle steps
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
`collab rollover <inspect|plan>` reads the exact authoritative task record and one
|
|
513
|
+
exact linked continuity handoff bundle, then reports the current rollover facts and
|
|
514
|
+
the steps a later execution would need. `--task-root` must equal the request
|
|
515
|
+
`task_root`; the working directory is never used to infer a workspace or task.
|
|
516
|
+
|
|
517
|
+
The request names the absolute task root, the bundle `root`,
|
|
518
|
+
`continuity_task_id`, `bundle_id` and pinned `digest`, and either a recorded
|
|
519
|
+
`intent_id` (`inspect`) or a `proposed_intent` (`plan`). A plan with no recorded
|
|
520
|
+
intent types the intent against the accepted record reducer on a clone and reports
|
|
521
|
+
its refusal code, so nothing is persisted.
|
|
522
|
+
|
|
523
|
+
A recorded intent pins one exact bundle: the request must name
|
|
524
|
+
`handoff-bundles/<bundleId>.json` under its continuity task with the digest recorded
|
|
525
|
+
at intent creation. Any other bundle, including a different valid one, is refused
|
|
526
|
+
with `bundle_pin_mismatch`; a freshly readable bundle is never substituted for the
|
|
527
|
+
originally pinned checkpoint context.
|
|
528
|
+
|
|
529
|
+
The bundle is read exactly, its digest must equal the pin, and it is verified with
|
|
530
|
+
the accepted handoff-bundle verifier. Its workspace, continuity task, collaboration
|
|
531
|
+
task/attempt/input/owner-epoch, source session agent/session/harness and the bounded
|
|
532
|
+
handoff snapshot must match the plan: the snapshot claims must equal the intent's
|
|
533
|
+
original holder/epoch, and claims plus pending tools/messages/approvals must all be
|
|
534
|
+
`complete` with no pending items. Partial or unknown inventory stays unknown and
|
|
535
|
+
blocks completion. Complete artifact context alone never grants authority;
|
|
536
|
+
`execution_allowed` stays `false`.
|
|
537
|
+
|
|
538
|
+
The report names the current `stage` and evaluates expected facts by stage. Before
|
|
539
|
+
transfer it expects the source assignee, the source-held claims at their intent
|
|
540
|
+
epochs and the pinned source native identity. After a completed transfer it expects
|
|
541
|
+
the successor assignee, the successor-held claims at epoch+1 and the pinned successor
|
|
542
|
+
native identity, so archived source history is not reported as current drift. An
|
|
543
|
+
aborted handoff is not executable. `plan_complete` is true only when every step is
|
|
544
|
+
satisfied, no drift or evidence issue exists, and the bundle association, snapshot
|
|
545
|
+
inventory and context integrity all agree.
|
|
546
|
+
|
|
547
|
+
Optional `evidence` ids name at most two registered `ACK`/`REPORT` envelopes. Each is
|
|
548
|
+
read descriptor-bounded through the safe id, namespace and realpath checks, and the
|
|
549
|
+
actual raw bytes are charged before JSON or envelope refusal, so a corrupt or padded
|
|
550
|
+
file is never inspected for free. Correlations include type, sender, recipient, task,
|
|
551
|
+
subtask, attempt, input revision, intent, generation, epoch, ledger identity and
|
|
552
|
+
first-work proof ordering; a missing, unreadable or contradictory id is a reported
|
|
553
|
+
blocker, never a report that stays complete.
|
|
554
|
+
|
|
555
|
+
Current-record drift is reported explicitly: coordinator epoch, handoff state, latest
|
|
556
|
+
attempt, assignee, input revision, waiting writer, claim holder/epoch/release, pinned
|
|
557
|
+
native identity and any missing transfer boundary. `prepare-transfer` stays
|
|
558
|
+
`unavailable` because no accepted host adapter produces authenticated quiescence
|
|
559
|
+
evidence; a caller-supplied stop observation, exit code or producer label is never
|
|
560
|
+
stop proof. `routing_removal` stays `pending` and `native_session_archive` stays
|
|
561
|
+
`unavailable`, so an applied transfer never claims that dispatch routing or the old
|
|
562
|
+
native session was archived.
|
|
563
|
+
|
|
564
|
+
There is no apply action: `rollover apply` and unknown actions are rejected with
|
|
565
|
+
exit 2. Exit 0 means the inspection ran (`plan_complete` reports whether every step
|
|
566
|
+
is satisfied), exit 1 means the exact record or bundle cannot support it, exit 2
|
|
567
|
+
means the request is invalid. Nothing is claimed, transferred, launched, archived,
|
|
568
|
+
routed, notified or written, and no native query is made.
|
|
569
|
+
|
|
570
|
+
A validated succession also excludes its archived old native identity from
|
|
571
|
+
`collab message notify`: an excluded sender or recipient fails with
|
|
572
|
+
`sender_route_excluded`/`recipient_route_excluded` before any caller or live Herdr
|
|
573
|
+
query and before any send, while stored messages, deliveries and bindings keep their
|
|
574
|
+
history unchanged. The current successor identity stays an active route.
|
|
575
|
+
|
|
576
|
+
A completed handoff alone is not proof. Exclusion requires the matching intent (task,
|
|
577
|
+
handoff, generation, source and successor identities), a recorded transfer boundary,
|
|
578
|
+
the registered applied first-work `REPORT` whose digest matches the retained proof and
|
|
579
|
+
which was applied after the boundary, and an admitted `completed` result entry for
|
|
580
|
+
that report. A missing or contradictory chain makes the queried identity `unknown`,
|
|
581
|
+
including when it matches the named successor, so a notify is refused instead of
|
|
582
|
+
silently rerouted.
|
|
583
|
+
|
|
584
|
+
## Notification states
|
|
585
|
+
|
|
586
|
+
| Status | Meaning |
|
|
587
|
+
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
588
|
+
| `planned` | Task, message, binding and recipient validated; nothing sent. |
|
|
589
|
+
| `submitted` | One `herdr agent prompt` was accepted. Consumption is still unknown. |
|
|
590
|
+
| `blocked` | Herdr reported `agent_blocked`; a blocked native UI is never answered. |
|
|
591
|
+
| `refused` | Herdr rejected the prompt with an explicit recognized pre-submission refusal (`agent_not_found`). |
|
|
592
|
+
| `unknown` | The prompt may have been submitted (timeout, stalled, signal, nonzero exit without a recognized result, an unrecognized error code, or transport error after the reservation). Never resend implicitly. |
|
|
593
|
+
| `failed` | The transport failed without a possible submission (for example an unresolvable delivery directory). |
|
|
594
|
+
| `herdr_unavailable` | Not inside Herdr, or the CLI is not callable. The message stays persisted. |
|
|
595
|
+
| `herdr_caller_unverified` | The caller pane could not be resolved or the environment caller IDs are stale. Nothing was inspected or sent. |
|
|
596
|
+
| `already_recorded` | Delivery metadata already exists for this message id; no new wakeup was sent. |
|
|
597
|
+
| `in_flight_unknown` | A delivery reservation is still in flight or its outcome is unknown; it is never resent or reclaimed by age. |
|
|
598
|
+
| `retry_limit` | Explicit retry attempts are exhausted (3). |
|
|
599
|
+
|
|
600
|
+
Notification metadata lives in `<task-root>/notifications/<message-id>.json`; it
|
|
601
|
+
is delivery evidence, not a second task record. Each retry reserves a distinct
|
|
602
|
+
attempt under a task-private lock, so concurrent retries cannot lose an attempt
|
|
603
|
+
or exceed the bound. Retries are explicit operator actions with `--retry` on the
|
|
604
|
+
same message identity.
|
|
605
|
+
|
|
606
|
+
## Working loop
|
|
607
|
+
|
|
608
|
+
1. The coordinator prepares the task and claims the resources.
|
|
609
|
+
2. The coordinator sends one `ASSIGN` envelope, then notifies the recipient once.
|
|
610
|
+
3. The recipient ACKs by sending its own envelope and notifying the coordinator
|
|
611
|
+
once; it asks a question with `BLOCK(kind=clarification)` or `ASK`, and
|
|
612
|
+
reports with `REPORT`.
|
|
613
|
+
4. The coordinator reads the report, checks the evidence, and answers with a
|
|
614
|
+
correlated message. Acceptance remains a separate decision.
|
|
615
|
+
|
|
616
|
+
No polling, timers, repeated status reads, or `herdr agent prompt --wait` are
|
|
617
|
+
part of this loop. If no reply arrives, the outcome is uncertain; inspect the
|
|
618
|
+
record before retrying rather than sending another wakeup.
|
|
619
|
+
|
|
620
|
+
## Direct mode and receiver verification
|
|
621
|
+
|
|
622
|
+
This surface works without Herdr for persistence and reading. Notification
|
|
623
|
+
requires `HERDR_ENV=1` plus a routing mode: inherited current context (which must
|
|
624
|
+
be present and consistent) or an explicit task-bound `--caller-pane <id>` for
|
|
625
|
+
stale inherited IDs. Outside Herdr it returns `herdr_unavailable`; missing, stale
|
|
626
|
+
or unresolved context returns `herdr_caller_unverified`, with the persisted
|
|
627
|
+
pointer and no launch, focus change, pane creation, or channel switch. Direct
|
|
628
|
+
coordination uses the same envelopes and explicit sessions.
|
|
629
|
+
|
|
630
|
+
A pane id is not a native session id, and pane idle is not proof of stop or
|
|
631
|
+
acceptance. The receiver verifies its exact `to` identity (agent id, harness,
|
|
632
|
+
session id) before consuming a message, and never adopts an arbitrary PID or
|
|
633
|
+
session because a notification arrived.
|