@phyzess/pappra 0.0.0-stage → 0.1.0-beta.2

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.
Files changed (221) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +80 -2
  3. package/THIRD_PARTY_NOTICES.md +16 -0
  4. package/assets/integrations/skills/pappra/SKILL.md +68 -0
  5. package/assets/integrations/skills/pappra/references/hosts.md +30 -0
  6. package/assets/integrations/skills/pappra/references/lifecycle.md +37 -0
  7. package/assets/integrations/skills/pappra/references/operations.md +14 -0
  8. package/assets/manifest.json +4 -0
  9. package/dist/app/collaboration.d.ts +170 -0
  10. package/dist/app/collaboration.js +1650 -0
  11. package/dist/app/doctor.d.ts +9 -0
  12. package/dist/app/doctor.js +1030 -0
  13. package/dist/app/init.d.ts +143 -0
  14. package/dist/app/init.js +1111 -0
  15. package/dist/cli/commands/code.d.ts +16 -0
  16. package/dist/cli/commands/code.js +127 -0
  17. package/dist/cli/commands/collaboration.d.ts +13 -0
  18. package/dist/cli/commands/collaboration.js +186 -0
  19. package/dist/cli/commands/continuity.d.ts +29 -0
  20. package/dist/cli/commands/continuity.js +133 -0
  21. package/dist/cli/commands/docs.d.ts +11 -0
  22. package/dist/cli/commands/docs.js +133 -0
  23. package/dist/cli/commands/doctor.d.ts +14 -0
  24. package/dist/cli/commands/doctor.js +57 -0
  25. package/dist/cli/commands/host.d.ts +13 -0
  26. package/dist/cli/commands/host.js +125 -0
  27. package/dist/cli/commands/init.d.ts +51 -0
  28. package/dist/cli/commands/init.js +668 -0
  29. package/dist/cli/main.d.ts +2 -0
  30. package/dist/cli/main.js +10 -0
  31. package/dist/cli/output.d.ts +4 -0
  32. package/dist/cli/output.js +1 -0
  33. package/dist/cli/run.d.ts +2 -0
  34. package/dist/cli/run.js +597 -0
  35. package/dist/code/budget.d.ts +14 -0
  36. package/dist/code/budget.js +39 -0
  37. package/dist/code/exec.d.ts +23 -0
  38. package/dist/code/exec.js +133 -0
  39. package/dist/code/identity.d.ts +13 -0
  40. package/dist/code/identity.js +214 -0
  41. package/dist/code/index.d.ts +6 -0
  42. package/dist/code/index.js +3 -0
  43. package/dist/code/providers/codegraph.d.ts +59 -0
  44. package/dist/code/providers/codegraph.js +567 -0
  45. package/dist/code/registration.d.ts +9 -0
  46. package/dist/code/registration.js +293 -0
  47. package/dist/code/service.d.ts +53 -0
  48. package/dist/code/service.js +633 -0
  49. package/dist/code/text.d.ts +3 -0
  50. package/dist/code/text.js +202 -0
  51. package/dist/collab/admission.d.ts +450 -0
  52. package/dist/collab/admission.js +797 -0
  53. package/dist/collab/canonical.d.ts +26 -0
  54. package/dist/collab/canonical.js +136 -0
  55. package/dist/collab/contracts.d.ts +73 -0
  56. package/dist/collab/contracts.js +76 -0
  57. package/dist/collab/envelope.d.ts +52 -0
  58. package/dist/collab/envelope.js +241 -0
  59. package/dist/collab/fingerprint.d.ts +7 -0
  60. package/dist/collab/fingerprint.js +58 -0
  61. package/dist/collab/handoff.d.ts +350 -0
  62. package/dist/collab/handoff.js +513 -0
  63. package/dist/collab/index.d.ts +9 -0
  64. package/dist/collab/index.js +8 -0
  65. package/dist/collab/lifecycle.d.ts +449 -0
  66. package/dist/collab/lifecycle.js +534 -0
  67. package/dist/collab/messages.d.ts +148 -0
  68. package/dist/collab/messages.js +583 -0
  69. package/dist/collab/notify.d.ts +47 -0
  70. package/dist/collab/notify.js +140 -0
  71. package/dist/collab/preflight.d.ts +31 -0
  72. package/dist/collab/preflight.js +271 -0
  73. package/dist/collab/resources.d.ts +119 -0
  74. package/dist/collab/resources.js +451 -0
  75. package/dist/collab/store.d.ts +143 -0
  76. package/dist/collab/store.js +606 -0
  77. package/dist/collab/types.d.ts +354 -0
  78. package/dist/collab/types.js +1 -0
  79. package/dist/collab/validation.d.ts +10 -0
  80. package/dist/collab/validation.js +303 -0
  81. package/dist/continuity/context.d.ts +24 -0
  82. package/dist/continuity/context.js +179 -0
  83. package/dist/continuity/index.d.ts +3 -0
  84. package/dist/continuity/index.js +1 -0
  85. package/dist/continuity/paths.d.ts +37 -0
  86. package/dist/continuity/paths.js +258 -0
  87. package/dist/continuity/service.d.ts +59 -0
  88. package/dist/continuity/service.js +1258 -0
  89. package/dist/hosts/claude/native.d.ts +79 -0
  90. package/dist/hosts/claude/native.js +853 -0
  91. package/dist/hosts/codex/native.d.ts +345 -0
  92. package/dist/hosts/codex/native.js +1528 -0
  93. package/dist/hosts/codex/protocol.d.ts +51 -0
  94. package/dist/hosts/codex/protocol.js +42 -0
  95. package/dist/hosts/detect.d.ts +28 -0
  96. package/dist/hosts/detect.js +73 -0
  97. package/dist/hosts/index.d.ts +10 -0
  98. package/dist/hosts/index.js +10 -0
  99. package/dist/hosts/integration/bundle.d.ts +16 -0
  100. package/dist/hosts/integration/bundle.js +81 -0
  101. package/dist/hosts/integration/hook-entry.d.ts +1 -0
  102. package/dist/hosts/integration/hook-entry.js +68 -0
  103. package/dist/hosts/integration/hook.d.ts +32 -0
  104. package/dist/hosts/integration/hook.js +781 -0
  105. package/dist/hosts/integration/pi-extension-runtime.d.ts +18 -0
  106. package/dist/hosts/integration/pi-extension-runtime.js +89 -0
  107. package/dist/hosts/integration/pi-template.d.ts +3 -0
  108. package/dist/hosts/integration/pi-template.js +5 -0
  109. package/dist/hosts/integration/service.d.ts +41 -0
  110. package/dist/hosts/integration/service.js +1381 -0
  111. package/dist/hosts/integration/support.d.ts +36 -0
  112. package/dist/hosts/integration/support.js +41 -0
  113. package/dist/hosts/integration/templates.d.ts +22 -0
  114. package/dist/hosts/integration/templates.js +70 -0
  115. package/dist/hosts/pi/protocol.d.ts +22 -0
  116. package/dist/hosts/pi/protocol.js +28 -0
  117. package/dist/hosts/pi/query-result.d.ts +22 -0
  118. package/dist/hosts/pi/query-result.js +710 -0
  119. package/dist/hosts/pi/rpc.d.ts +937 -0
  120. package/dist/hosts/pi/rpc.js +1621 -0
  121. package/dist/hosts/pilot.d.ts +485 -0
  122. package/dist/hosts/pilot.js +593 -0
  123. package/dist/index.d.ts +5 -0
  124. package/dist/index.js +4 -0
  125. package/dist/infra/fs.d.ts +27 -0
  126. package/dist/infra/fs.js +130 -0
  127. package/dist/infra/git.d.ts +60 -0
  128. package/dist/infra/git.js +358 -0
  129. package/dist/infra/owned-process-group.d.ts +173 -0
  130. package/dist/infra/owned-process-group.js +571 -0
  131. package/dist/install/apply.d.ts +65 -0
  132. package/dist/install/apply.js +663 -0
  133. package/dist/install/index.d.ts +5 -0
  134. package/dist/install/index.js +5 -0
  135. package/dist/install/ownership.d.ts +85 -0
  136. package/dist/install/ownership.js +430 -0
  137. package/dist/install/plan.d.ts +39 -0
  138. package/dist/install/plan.js +97 -0
  139. package/dist/install/rollback.d.ts +18 -0
  140. package/dist/install/rollback.js +544 -0
  141. package/dist/install/runtime.d.ts +76 -0
  142. package/dist/install/runtime.js +1145 -0
  143. package/dist/knowledge/catalog.d.ts +47 -0
  144. package/dist/knowledge/catalog.js +308 -0
  145. package/dist/knowledge/context.d.ts +28 -0
  146. package/dist/knowledge/context.js +61 -0
  147. package/dist/knowledge/index.d.ts +3 -0
  148. package/dist/knowledge/index.js +1 -0
  149. package/dist/knowledge/journal.d.ts +16 -0
  150. package/dist/knowledge/journal.js +109 -0
  151. package/dist/knowledge/lifecycle.d.ts +8 -0
  152. package/dist/knowledge/lifecycle.js +1001 -0
  153. package/dist/knowledge/paths.d.ts +37 -0
  154. package/dist/knowledge/paths.js +236 -0
  155. package/dist/knowledge/refs.d.ts +36 -0
  156. package/dist/knowledge/refs.js +267 -0
  157. package/dist/knowledge/service.d.ts +21 -0
  158. package/dist/knowledge/service.js +393 -0
  159. package/dist/knowledge/types.d.ts +171 -0
  160. package/dist/knowledge/types.js +1 -0
  161. package/dist/knowledge/write.d.ts +8 -0
  162. package/dist/knowledge/write.js +1223 -0
  163. package/dist/package-info.d.ts +6 -0
  164. package/dist/package-info.js +19 -0
  165. package/dist/schemas/code.d.ts +377 -0
  166. package/dist/schemas/code.js +145 -0
  167. package/dist/schemas/collaboration.d.ts +115 -0
  168. package/dist/schemas/collaboration.js +106 -0
  169. package/dist/schemas/continuity.d.ts +315 -0
  170. package/dist/schemas/continuity.js +199 -0
  171. package/dist/schemas/diagnostics.d.ts +28 -0
  172. package/dist/schemas/diagnostics.js +27 -0
  173. package/dist/schemas/doctor.d.ts +157 -0
  174. package/dist/schemas/doctor.js +75 -0
  175. package/dist/schemas/document.d.ts +644 -0
  176. package/dist/schemas/document.js +296 -0
  177. package/dist/schemas/errors.d.ts +177 -0
  178. package/dist/schemas/errors.js +176 -0
  179. package/dist/schemas/evidence.d.ts +24 -0
  180. package/dist/schemas/evidence.js +16 -0
  181. package/dist/schemas/host.d.ts +436 -0
  182. package/dist/schemas/host.js +201 -0
  183. package/dist/schemas/index.d.ts +15 -0
  184. package/dist/schemas/index.js +15 -0
  185. package/dist/schemas/init.d.ts +121 -0
  186. package/dist/schemas/init.js +94 -0
  187. package/dist/schemas/install.d.ts +213 -0
  188. package/dist/schemas/install.js +139 -0
  189. package/dist/schemas/machine.d.ts +43 -0
  190. package/dist/schemas/machine.js +96 -0
  191. package/dist/schemas/outcome.d.ts +23 -0
  192. package/dist/schemas/outcome.js +17 -0
  193. package/dist/schemas/paths.d.ts +19 -0
  194. package/dist/schemas/paths.js +63 -0
  195. package/dist/schemas/workspace.d.ts +120 -0
  196. package/dist/schemas/workspace.js +201 -0
  197. package/dist/workspace/config-file.d.ts +36 -0
  198. package/dist/workspace/config-file.js +237 -0
  199. package/dist/workspace/config.d.ts +28 -0
  200. package/dist/workspace/config.js +79 -0
  201. package/dist/workspace/discover.d.ts +34 -0
  202. package/dist/workspace/discover.js +195 -0
  203. package/dist/workspace/documents.d.ts +21 -0
  204. package/dist/workspace/documents.js +395 -0
  205. package/dist/workspace/ignore.d.ts +10 -0
  206. package/dist/workspace/ignore.js +48 -0
  207. package/dist/workspace/index.d.ts +7 -0
  208. package/dist/workspace/index.js +3 -0
  209. package/dist/workspace/repositories.d.ts +24 -0
  210. package/dist/workspace/repositories.js +411 -0
  211. package/dist/workspace/resolve.d.ts +24 -0
  212. package/dist/workspace/resolve.js +268 -0
  213. package/dist/workspace/types.d.ts +71 -0
  214. package/dist/workspace/types.js +1 -0
  215. package/dist/workspace/validation.d.ts +18 -0
  216. package/dist/workspace/validation.js +197 -0
  217. package/package.json +105 -4
  218. package/skills/pappra/SKILL.md +68 -0
  219. package/skills/pappra/references/hosts.md +30 -0
  220. package/skills/pappra/references/lifecycle.md +37 -0
  221. package/skills/pappra/references/operations.md +14 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 phyzess
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,81 @@
1
- # Temporary Holding Version
1
+ # Pappra
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Pappra is a portable workspace manager for coding-agent workflows. It keeps workspace configuration, selected project knowledge, checkpoints, recovery context and bounded code navigation in files owned by the workspace rather than in one chat transcript.
4
+
5
+ Pappra is the manager. External coding hosts, code-graph engines and collaboration controllers are optional integrations, not installation prerequisites.
6
+
7
+ ## Quick start
8
+
9
+ Requirements: Node.js 24 or later. `pnpm` 12.3.4 is required only for development inside this repository; Git is required only when a command observes repository identity.
10
+
11
+ The package is published as `@phyzess/pappra`. Run it with `npx` from the target workspace, or install it globally when you use it every day.
12
+
13
+ ```sh
14
+ # In an empty target workspace
15
+ mkdir -p /tmp/pappra-demo
16
+ cd /tmp/pappra-demo
17
+ curl -fsSL https://raw.githubusercontent.com/phyzess/pappra/main/examples/minimal-choices.json -o ./minimal-choices.json
18
+
19
+ # Preview first. JSON/config mode is non-interactive and does not prompt.
20
+ npx @phyzess/pappra@beta init --config ./minimal-choices.json --json
21
+
22
+ # Apply the same choices. With no runtime installed, apply intentionally
23
+ # reports external-actions-pending and exits nonzero after writing config.
24
+ npx @phyzess/pappra@beta init --config ./minimal-choices.json --apply --json
25
+ npx @phyzess/pappra@beta doctor --json
26
+ ```
27
+
28
+ `examples/minimal-choices.json` is complete for a host-free, no-graph, single-directory workspace. The example intentionally has no repositories or optional hosts.
29
+
30
+ `init --json` without `--config` fails closed because JSON mode does not open the interactive wizard; run `npx @phyzess/pappra@beta init` without `--json` in a TTY if you want to enter selections interactively. `--config` and `--json` never prompt.
31
+
32
+ Development from a checkout works the same way: `pnpm install --frozen-lockfile`, `pnpm build`, then invoke `dist/cli/main.js` by absolute path from the target workspace.
33
+
34
+ An apply result can be `ok:true` with `status:"external-actions-pending"` and a
35
+ nonzero process exit. That is a successful, partial configuration write, not a
36
+ claim that a runtime or external tool was installed. Inspect `pendingExternalActions`
37
+ and run `doctor` before adding optional integrations.
38
+
39
+ Optional examples have prerequisites rather than generated files: code-graph and
40
+ host commands require the selected external CLI/support, and collaboration
41
+ requires an explicit controller. They are not needed for the core workflow above.
42
+
43
+ ## What it manages
44
+
45
+ - **Workspace configuration:** `.pappra/workspace.json` and checkout-local `.pappra/local/machine.json`.
46
+ - **Knowledge:** workspace and private document catalogs with explicit preview/apply operations.
47
+ - **Continuity:** private task checkpoints and bounded advisory resume packets. Resume never grants execution by itself.
48
+ - **Code intelligence:** status, explicit preparation and bounded query for selected repositories. Text/structure fallback is available when the optional graph engine is absent.
49
+ - **Host integrations:** optional Pi, Codex and Claude Code adapters that merge Pappra-owned entries without taking over user configuration.
50
+ - **Bounded collaboration:** an optional, explicitly controlled one-request workflow. It is not a scheduler or daemon.
51
+
52
+ ## Optional integrations and support
53
+
54
+ | Capability | Requirement | Default |
55
+ | ----------------------------------------------------- | -------------------------------------------------------- | --------------------------------------------------------- |
56
+ | Workspace, init, doctor, checkpoint/resume, knowledge | Node.js only; Git for repository identity | Core |
57
+ | Code graph status/prepare/query | Optional external code-graph engine | Disabled unless selected; text fallback remains available |
58
+ | Host hooks | Explicitly selected Pi, Codex or Claude Code integration | Not installed automatically |
59
+ | Collaboration controller | Explicit `--controller <fixture\|pi-rpc>` | No implicit controller |
60
+
61
+ Host names and external protocol identifiers describe supported integration surfaces. They do not make any host, model, graph engine or private workspace a prerequisite for core use.
62
+
63
+ ## Development checks
64
+
65
+ ```sh
66
+ pnpm check
67
+ ```
68
+
69
+ The check runs the source policy, type checks, formatting, deterministic tests and a local package smoke test. The package smoke test prefers an offline local tarball (falling back to registry resolution when the runner has no offline metadata) and an isolated fixture home/state; it does not install a model or contact a model provider.
70
+
71
+ ## Status and limits
72
+
73
+ Pappra is development software (`0.1.0-beta.2`) published as `@phyzess/pappra` under the `beta` dist-tag. Releases are published from GitHub Actions with npm trusted publishing (OIDC), so no npm token is stored in this repository. Pin either the moving `beta` tag or an exact version such as `@phyzess/pappra@0.1.0-beta.2`, because pre-release versions are never republished.
74
+
75
+ The deterministic suite covers synthetic workspaces, fixtures and local process boundaries. It does not establish real-model behavior, native host callability on every platform, CodeGraph completeness, Windows/Linux parity or production performance. A host adapter version pin is an observed support claim, not proof that a particular native installation will load or run correctly.
76
+
77
+ ## License
78
+
79
+ Pappra is licensed under the MIT License. See [LICENSE](LICENSE) and [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).
80
+
81
+ More detail: [quick start](docs/quickstart.md), [API boundaries](docs/api.md), [support and limitations](docs/support.md).
@@ -0,0 +1,16 @@
1
+ # Third-party notices
2
+
3
+ Pappra depends on the following packages. Runtime dependencies are installed by
4
+ the consumer and are not copied into Pappra source files.
5
+
6
+ | Package | Version | License | Role |
7
+ | ---------------- | ------- | ---------- | ---------------------- |
8
+ | `@clack/prompts` | 1.8.1 | MIT | Interactive prompts |
9
+ | `zod` | 4.6.6 | MIT | Runtime validation |
10
+ | `@types/node` | 24.19.1 | MIT | Development types |
11
+ | `prettier` | 3.9.9 | MIT | Development formatting |
12
+ | `typescript` | 7.0.2 | Apache-2.0 | Development compiler |
13
+
14
+ The package manager `pnpm` is a development tool and is not shipped in the
15
+ published package contents. This notice is informational; it does not replace
16
+ the license texts or attribution supplied by the projects above.
@@ -0,0 +1,68 @@
1
+ ---
2
+ name: pappra
3
+ description: Use Pappra workspace knowledge, checkpoint/resume, and selected-repository code intelligence from any supported coding agent. Use when a task needs durable handoff context, workspace documents, or bounded code navigation.
4
+ ---
5
+
6
+ # Pappra
7
+
8
+ Pappra keeps workspace knowledge, continuity, and code navigation outside the
9
+ host transcript. Use the installed `pappra` CLI for durable operations; hooks
10
+ only record bounded lifecycle observations and never start a model, download,
11
+ index, or new writer.
12
+
13
+ ## Start here
14
+
15
+ 1. Read `references/lifecycle.md` before relying on a host lifecycle event.
16
+ 2. Read `references/hosts.md` when the host surface is Pi, Codex, or Claude.
17
+ 3. Use `pappra checkpoint` / `pappra resume` for handoffs. A stored checkpoint
18
+ is context, not permission to execute or to trust a previous session.
19
+ 4. Use `pappra docs` and `pappra code` only for the workspace selected by the
20
+ current root. Never infer a workspace from an unrelated session.
21
+ 5. For a new bounded collaboration request, build an explicit
22
+ `pappra/collaboration-goal/1` from the user's objective and named choices,
23
+ run `pappra collab prepare --goal <file> --domain-root <dir>`, admit against a fresh capability
24
+ card, then use `pappra collab run` with the reviewed controller. Never turn
25
+ prose into identity, approval, or capability claims.
26
+
27
+ ## One-request collaboration
28
+
29
+ `pappra collab prepare --goal <file> --domain-root <dir>` requires an explicit
30
+ shared domain. It validates the canonical domain/tasks/task/private namespace
31
+ before writing any task metadata and again around each write, so a task-root or
32
+ mid-write directory redirect fails closed instead of scattering artifacts. It
33
+ then writes a private task record, assignment, prompt, and resource claims; read
34
+ resources stay read claims. The captured identities also guard live query, finish, disposal and lower RPC artifact writes; after a redirect, no new query/execution/proof/current-result pathname is written. `pappra collab run` requires an explicit `--controller <fixture|pi-rpc>`,
35
+ performs the single admitted launch, and accepts bounded
36
+ `pappra/collaboration-command/1` JSONL on stdin; it emits
37
+ `pappra/collaboration-event/1` JSONL. `query` reads persisted history only and
38
+ reports live ownership as unknown. A `finish` produces one deterministic REPORT;
39
+ only a result whose stored classification was `applied` for the same fixed
40
+ identity/attempt/input may repeat successfully as a duplicate — repeated
41
+ rejections stay rejected. Cancel records and validates intent first: a denied
42
+ intent never calls the native controller. Claims are retained and stop proof is
43
+ never invented.
44
+
45
+ Use `--controller fixture` only for deterministic, no-model tests; it is a
46
+ restricted explicit fixture, never a silent default. The optional `pi-rpc` controller
47
+ uses the existing owned Pi RPC daily path and preserves required skills, tools,
48
+ MCP, hooks, and model settings; missing capabilities or stale/forged admission
49
+ fail before launch. A native run reports only the current prompt-correlated
50
+ result: terminal success requires a supported terminal reason and no pending
51
+ tool call, so text-plus-toolUse/intermediate, tool-only, empty, old, malformed or
52
+ missing answers are `unknown`; an explicit error is `failed` and an abort is
53
+ `cancelled`. The current result must be published as validated
54
+ `native-current-result/1` evidence; EIO/conflict/symlink/partial publication
55
+ makes delivery `unknown`, not success, and repeated finish reuses verified
56
+ content instead of overwriting it. A clean transport exit is not task success.
57
+ No approval is auto-answered, no cancel is inferred from an acknowledgement, and no new thread or
58
+ arbitrary PID is adopted. Do not launch a model or real user session without
59
+ the task's explicit authorization.
60
+
61
+ ## Boundaries
62
+
63
+ - Hooks are local and bounded. They do not read transcripts, run commands,
64
+ call models, fetch the network, or continue a conversation.
65
+ - Missing semantic context stays missing; do not fabricate summaries.
66
+ - Treat unknown ownership, stale bundles, untrusted hooks, and changed host
67
+ versions as visible conditions, not silent fallbacks.
68
+ - Preserve user settings and unrelated keys when integrating a host.
@@ -0,0 +1,30 @@
1
+ # Host surfaces
2
+
3
+ ## Pi
4
+
5
+ The integration installs a project extension plus a copied `pappra` skill.
6
+ Pi extensions run with host permissions. Load only a trusted copy from this
7
+ workspace/target; the generated entrypoint imports the fixed Pappra runtime by
8
+ absolute file URL and registers lifecycle handlers only.
9
+
10
+ ## Codex
11
+
12
+ The integration installs a command-hook entry and merges only Pappra-owned
13
+ entries into `hooks.json`. Existing hooks and unrelated keys are preserved.
14
+ Codex hook definitions are trusted individually; installation is not trust.
15
+ Observed 0.163.0 hook keys do not include a compact event, so compact and
16
+ automatic checkpoint requests remain unsupported.
17
+
18
+ ## Claude Code
19
+
20
+ The integration installs a command-hook entry and merges only Pappra-owned
21
+ entries into `settings.json`. `SessionStart` and `PostCompact` are distinct;
22
+ matchers, trust, timeout, and output behavior remain host/version-specific.
23
+ Installing a command is not proof it ran.
24
+
25
+ ## Common safety
26
+
27
+ All surfaces use the event's canonical cwd/root, bounded stdin, a one-second
28
+ local deadline, no transcript reads, no arbitrary configured commands, and no
29
+ network/model/index/session side effects. Paths with spaces or Unicode are
30
+ passed as argv/file URLs, never interpolated into a shell.
@@ -0,0 +1,37 @@
1
+ # Lifecycle reference
2
+
3
+ ## Supported mapping
4
+
5
+ Pappra distinguishes four local lifecycle intents:
6
+
7
+ | Intent | Pi | Codex | Claude |
8
+ | -------------------- | ---------------------------- | ------------------------------------------ | ------------------------------------------ |
9
+ | `startup` | `session_start` | `SessionStart` with source `startup`/`new` | `SessionStart` with source `startup`/`new` |
10
+ | `resume` | `session_start` | `SessionStart` with source `resume` | `SessionStart` with source `resume` |
11
+ | `compact` | `session_before_compact` | unsupported in observed 0.163.0 hook keys | `PostCompact` |
12
+ | `checkpoint-request` | explicit Pappra command/hook | unsupported automatic event | unsupported automatic event |
13
+
14
+ The matrix is version-specific. A host version outside the observed support
15
+ range is `unsupported`/`unknown`, not a fallback to name similarity.
16
+
17
+ ## What a hook does
18
+
19
+ A hook validates the host payload, resolves the current workspace from the
20
+ event cwd (never from a last-session cache), derives a bounded event identity,
21
+ suppresses a duplicate identity, and records a private local event observation.
22
+ It may print a short advisory context. It never starts a model, fetches,
23
+ indexes, runs arbitrary commands, creates a new agent, or writes a checkpoint
24
+ with invented semantics.
25
+
26
+ ## Manual continuity
27
+
28
+ `pappra checkpoint --task <id> ...` and `pappra resume <id>` remain available
29
+ without hooks. A hook observation is not a checkpoint and does not grant
30
+ `executionAllowed`. A resume packet is read-only context; an unknown or
31
+ non-stopped writer fails closed.
32
+
33
+ ## Reload and trust
34
+
35
+ Installing files does not prove the host loaded them or trusted their exact
36
+ definition. Report reload-needed and trust-needed separately. Do not approve a
37
+ host trust prompt on the user's behalf.
@@ -0,0 +1,14 @@
1
+ # Operations reference
2
+
3
+ - `pappra init` plans or applies workspace configuration.
4
+ - `pappra doctor` is passive: it does not install hooks, start hosts, or fix
5
+ state.
6
+ - `pappra checkpoint` writes a task checkpoint; `pappra resume` reads a
7
+ stored snapshot and reports whether execution is allowed.
8
+ - `pappra docs` manages knowledge documents.
9
+ - `pappra code` operates on an explicitly selected repository and keeps
10
+ index mutations behind an explicit `--apply`.
11
+
12
+ Preserve user bytes. If an operation reports a conflict or residual path,
13
+ inspect that path and resolve ownership before retrying. Never delete an
14
+ unknown file to make a retry succeed.
@@ -0,0 +1,4 @@
1
+ {
2
+ "schema": "pappra/assets/1",
3
+ "stage": "toolchain"
4
+ }
@@ -0,0 +1,170 @@
1
+ import type { Diagnostic } from '../schemas/diagnostics.js';
2
+ import { type CollaborationEvent, type CollaborationGoal, type CollaborationPrepared } from '../schemas/collaboration.js';
3
+ import { admitLaunch } from '../collab/admission.js';
4
+ import type { Assignment } from '../collab/contracts.js';
5
+ export type CollaborationFailureStatus = 'invalid' | 'needs_input' | 'conflict' | 'unsupported' | 'failed';
6
+ export interface CollaborationFailure {
7
+ readonly ok: false;
8
+ readonly status: CollaborationFailureStatus;
9
+ readonly code: string;
10
+ readonly message: string;
11
+ readonly nextAction: string | null;
12
+ readonly diagnostics: readonly Diagnostic[];
13
+ }
14
+ export type CollaborationResult<T> = {
15
+ readonly ok: true;
16
+ readonly value: T;
17
+ } | CollaborationFailure;
18
+ export interface PrepareOptions {
19
+ readonly domainRoot: string;
20
+ readonly clock?: number;
21
+ }
22
+ export interface PreparedBundle {
23
+ readonly prepared: CollaborationPrepared;
24
+ readonly goal: CollaborationGoal;
25
+ readonly assignment: Assignment;
26
+ }
27
+ export interface StartOptions {
28
+ readonly capabilitiesFile: string;
29
+ readonly controller: CollaborationController;
30
+ readonly controllerId: string;
31
+ readonly clock?: number;
32
+ }
33
+ export interface ControllerStartRequest {
34
+ readonly prepared: CollaborationPrepared;
35
+ readonly goal: CollaborationGoal;
36
+ readonly assignment: Assignment;
37
+ readonly capabilitiesFile: string;
38
+ readonly prompt: string;
39
+ readonly promptFile: string;
40
+ readonly taskRoot: string;
41
+ readonly evidenceDir: string;
42
+ readonly namespace?: PrivateNamespace;
43
+ }
44
+ export interface ControllerObservation {
45
+ readonly status: string;
46
+ readonly detail: string | null;
47
+ readonly data: unknown;
48
+ }
49
+ export interface ControllerCancel {
50
+ readonly acknowledged: boolean;
51
+ readonly terminal_observed: boolean;
52
+ readonly stop_evidence: unknown;
53
+ }
54
+ export interface ControllerFinish {
55
+ readonly outcome: string;
56
+ readonly status: string;
57
+ readonly exitCode: number | null;
58
+ readonly sessionId: string | null;
59
+ readonly outputs: readonly unknown[];
60
+ readonly nativeRef: unknown;
61
+ readonly evidenceRef: string | null;
62
+ }
63
+ export interface ControllerSession {
64
+ query(): Promise<ControllerObservation>;
65
+ cancel(): Promise<ControllerCancel>;
66
+ finish(): Promise<ControllerFinish>;
67
+ dispose?(): Promise<void>;
68
+ }
69
+ export interface CollaborationController {
70
+ readonly id: string;
71
+ start(token: object, request: ControllerStartRequest): Promise<{
72
+ readonly ok: true;
73
+ readonly session: ControllerSession;
74
+ } | {
75
+ readonly ok: false;
76
+ readonly status: CollaborationFailureStatus;
77
+ readonly code: string;
78
+ readonly message: string;
79
+ readonly nextAction: string | null;
80
+ readonly possible_start?: boolean;
81
+ }>;
82
+ }
83
+ interface NamespaceIdentity {
84
+ readonly path: string;
85
+ readonly canonical: string;
86
+ readonly dev: number;
87
+ readonly ino: number;
88
+ }
89
+ export interface PrivateNamespace {
90
+ readonly domain: NamespaceIdentity;
91
+ readonly taskRoot: NamespaceIdentity;
92
+ readonly privateDir: NamespaceIdentity;
93
+ }
94
+ export declare function validateLaunchToken(token: unknown, expected: {
95
+ readonly taskRoot: string;
96
+ readonly assignmentDigest: string;
97
+ readonly subtaskId: string;
98
+ readonly attempt: number;
99
+ }): boolean;
100
+ export declare function prepareCollaboration(input: unknown, options: PrepareOptions): Promise<CollaborationResult<PreparedBundle>>;
101
+ export interface AdmissionResult {
102
+ readonly prepared: CollaborationPrepared;
103
+ readonly goal: CollaborationGoal;
104
+ readonly assignment: Assignment;
105
+ readonly admission: Awaited<ReturnType<typeof admitLaunch>>;
106
+ readonly token: object;
107
+ }
108
+ export declare function admitPrepared(preparedFile: string, capabilitiesFile: string, options?: {
109
+ readonly clock?: number;
110
+ }): Promise<CollaborationResult<AdmissionResult>>;
111
+ export interface StartedRun {
112
+ readonly prepared: CollaborationPrepared;
113
+ readonly goal: CollaborationGoal;
114
+ readonly assignment: Assignment;
115
+ readonly token: object;
116
+ readonly controller: CollaborationController;
117
+ readonly session: ControllerSession;
118
+ readonly reservationId: string | null;
119
+ }
120
+ export declare function startPrepared(preparedFile: string, options: StartOptions): Promise<CollaborationResult<StartedRun>>;
121
+ export interface ReportResult {
122
+ readonly ok: boolean;
123
+ readonly messageId: string;
124
+ readonly duplicate: boolean;
125
+ readonly classification: string | null;
126
+ readonly detail: string | null;
127
+ }
128
+ export declare function submitResultReport(started: StartedRun, finish: ControllerFinish, { clock }?: {
129
+ clock?: number;
130
+ }): ReportResult;
131
+ export declare function finishStarted(started: StartedRun): Promise<CollaborationResult<ControllerFinish>>;
132
+ export declare function driveRun(started: StartedRun, commands: AsyncIterable<unknown>, emit: (event: CollaborationEvent) => void, { clock }?: {
133
+ clock?: number;
134
+ }): Promise<CollaborationResult<ReportResult>>;
135
+ export declare class FixtureController implements CollaborationController {
136
+ private readonly options;
137
+ readonly id = "fixture";
138
+ constructor(options?: {
139
+ readonly status?: 'completed' | 'failed' | 'cancelled' | 'needs_input';
140
+ readonly outputs?: readonly unknown[];
141
+ readonly sessionId?: string;
142
+ });
143
+ start(token: object, request: ControllerStartRequest): Promise<{
144
+ readonly ok: true;
145
+ readonly session: ControllerSession;
146
+ } | {
147
+ readonly ok: false;
148
+ readonly status: CollaborationFailureStatus;
149
+ readonly code: string;
150
+ readonly message: string;
151
+ readonly nextAction: string | null;
152
+ readonly possible_start?: boolean;
153
+ }>;
154
+ }
155
+ export declare class PiRpcController implements CollaborationController {
156
+ readonly id = "pi-rpc";
157
+ start(token: object, request: ControllerStartRequest): Promise<{
158
+ readonly ok: true;
159
+ readonly session: ControllerSession;
160
+ } | {
161
+ readonly ok: false;
162
+ readonly status: CollaborationFailureStatus;
163
+ readonly code: string;
164
+ readonly message: string;
165
+ readonly nextAction: string | null;
166
+ readonly possible_start?: boolean;
167
+ }>;
168
+ }
169
+ export declare function inspectPreparedHistory(preparedFile: string): CollaborationResult<Record<string, unknown>>;
170
+ export {};