pi-daddy 0.27.4 → 0.32.0
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/CHANGELOG.md +108 -124
- package/README.md +18 -896
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/contracts/ledger-record/v1/README.md +44 -0
- package/contracts/ledger-record/v1/fixtures/child-lifecycle.json +45 -0
- package/contracts/ledger-record/v1/fixtures/ledger-record.jsonl +3 -0
- package/contracts/ledger-record/v1/governance-event.schema.json +747 -0
- package/contracts/ledger-record/v1/record.schema.json +91 -0
- package/dist/cli.d.ts +6 -4
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +108 -103
- package/dist/cli.js.map +1 -1
- package/dist/executors/activity-session.d.ts +12 -0
- package/dist/executors/activity-session.d.ts.map +1 -0
- package/dist/executors/activity-session.js +43 -0
- package/dist/executors/activity-session.js.map +1 -0
- package/dist/executors/executor.d.ts +39 -0
- package/dist/executors/executor.d.ts.map +1 -0
- package/dist/executors/executor.js +95 -0
- package/dist/executors/executor.js.map +1 -0
- package/dist/executors/herdr-cli.d.ts +78 -0
- package/dist/executors/herdr-cli.d.ts.map +1 -0
- package/dist/executors/herdr-cli.js +114 -0
- package/dist/executors/herdr-cli.js.map +1 -0
- package/dist/executors/herdr-name.d.ts.map +1 -0
- package/dist/executors/herdr-name.js.map +1 -0
- package/dist/executors/herdr-pi-lifecycle.d.ts.map +1 -0
- package/dist/executors/herdr-pi-lifecycle.js +22 -0
- package/dist/executors/herdr-pi-lifecycle.js.map +1 -0
- package/dist/executors/herdr-poll.d.ts +140 -0
- package/dist/executors/herdr-poll.d.ts.map +1 -0
- package/dist/executors/herdr-poll.js +252 -0
- package/dist/executors/herdr-poll.js.map +1 -0
- package/dist/executors/herdr-stage.d.ts +40 -0
- package/dist/executors/herdr-stage.d.ts.map +1 -0
- package/dist/executors/herdr-stage.js +54 -0
- package/dist/executors/herdr-stage.js.map +1 -0
- package/dist/executors/herdr-start.d.ts.map +1 -0
- package/dist/executors/herdr-start.js.map +1 -0
- package/dist/executors/native-session-target.d.ts +9 -0
- package/dist/executors/native-session-target.d.ts.map +1 -0
- package/dist/executors/native-session-target.js +30 -0
- package/dist/executors/native-session-target.js.map +1 -0
- package/dist/executors/pane-reaper.d.ts +111 -0
- package/dist/executors/pane-reaper.d.ts.map +1 -0
- package/dist/executors/pane-reaper.js +242 -0
- package/dist/executors/pane-reaper.js.map +1 -0
- package/dist/executors/process-activity.d.ts +3 -0
- package/dist/executors/process-activity.d.ts.map +1 -0
- package/dist/executors/process-activity.js +59 -0
- package/dist/executors/process-activity.js.map +1 -0
- package/dist/executors/run-herdr.d.ts +122 -0
- package/dist/executors/run-herdr.d.ts.map +1 -0
- package/dist/executors/run-herdr.js +341 -0
- package/dist/executors/run-herdr.js.map +1 -0
- package/dist/executors/vendor/herdr-pi-lifecycle.d.ts.map +1 -0
- package/dist/executors/vendor/herdr-pi-lifecycle.js.map +1 -0
- package/dist/governance/approval-prompt.d.ts +119 -0
- package/dist/governance/approval-prompt.d.ts.map +1 -0
- package/dist/governance/approval-prompt.js +133 -0
- package/dist/governance/approval-prompt.js.map +1 -0
- package/dist/governance/approval-store.d.ts +149 -0
- package/dist/governance/approval-store.d.ts.map +1 -0
- package/dist/governance/approval-store.js +309 -0
- package/dist/governance/approval-store.js.map +1 -0
- package/dist/governance/execution-retention.d.ts +90 -0
- package/dist/governance/execution-retention.d.ts.map +1 -0
- package/dist/governance/execution-retention.js +317 -0
- package/dist/governance/execution-retention.js.map +1 -0
- package/dist/governance/file-lock.d.ts.map +1 -0
- package/dist/governance/file-lock.js +205 -0
- package/dist/governance/file-lock.js.map +1 -0
- package/dist/governance/finalization.d.ts.map +1 -0
- package/dist/governance/finalization.js.map +1 -0
- package/dist/governance/grant-store.d.ts +96 -0
- package/dist/governance/grant-store.d.ts.map +1 -0
- package/dist/governance/grant-store.js +186 -0
- package/dist/governance/grant-store.js.map +1 -0
- package/dist/governance/init.d.ts +129 -0
- package/dist/governance/init.d.ts.map +1 -0
- package/dist/governance/init.js +360 -0
- package/dist/governance/init.js.map +1 -0
- package/dist/governance/lease-helper.d.ts.map +1 -0
- package/dist/governance/lease-helper.js +121 -0
- package/dist/governance/lease-helper.js.map +1 -0
- package/dist/governance/lease-record.d.ts +90 -0
- package/dist/governance/lease-record.d.ts.map +1 -0
- package/dist/governance/lease-record.js.map +1 -0
- package/dist/governance/ledger-events.d.ts +111 -0
- package/dist/governance/ledger-events.d.ts.map +1 -0
- package/dist/governance/ledger-events.js +129 -0
- package/dist/governance/ledger-events.js.map +1 -0
- package/dist/governance/ledger-report.d.ts +134 -0
- package/dist/governance/ledger-report.d.ts.map +1 -0
- package/dist/governance/ledger-report.js +294 -0
- package/dist/governance/ledger-report.js.map +1 -0
- package/dist/governance/ledger-v3-validation.d.ts +21 -0
- package/dist/governance/ledger-v3-validation.d.ts.map +1 -0
- package/dist/governance/ledger-v3-validation.js +353 -0
- package/dist/governance/ledger-v3-validation.js.map +1 -0
- package/dist/governance/ledger.d.ts +258 -0
- package/dist/governance/ledger.d.ts.map +1 -0
- package/dist/governance/ledger.js +201 -0
- package/dist/governance/ledger.js.map +1 -0
- package/dist/governance/native-session.d.ts +59 -0
- package/dist/governance/native-session.d.ts.map +1 -0
- package/dist/governance/native-session.js +208 -0
- package/dist/governance/native-session.js.map +1 -0
- package/dist/governance/record.d.ts +65 -0
- package/dist/governance/record.d.ts.map +1 -0
- package/dist/governance/record.js +259 -0
- package/dist/governance/record.js.map +1 -0
- package/dist/governance/retention-contract.d.ts.map +1 -0
- package/dist/governance/retention-contract.js +187 -0
- package/dist/governance/retention-contract.js.map +1 -0
- package/dist/governance/retention-json.d.ts.map +1 -0
- package/dist/governance/retention-json.js.map +1 -0
- package/dist/governance/workspace-lease.d.ts +40 -0
- package/dist/governance/workspace-lease.d.ts.map +1 -0
- package/dist/governance/workspace-lease.js +357 -0
- package/dist/governance/workspace-lease.js.map +1 -0
- package/dist/index.d.ts +59 -42
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +61 -42
- package/dist/index.js.map +1 -1
- package/dist/kernel/approval.d.ts +241 -0
- package/dist/kernel/approval.d.ts.map +1 -0
- package/dist/kernel/approval.js +270 -0
- package/dist/kernel/approval.js.map +1 -0
- package/dist/kernel/capabilities.d.ts +136 -0
- package/dist/kernel/capabilities.d.ts.map +1 -0
- package/dist/kernel/capabilities.js +199 -0
- package/dist/kernel/capabilities.js.map +1 -0
- package/dist/kernel/catalog.d.ts +98 -0
- package/dist/kernel/catalog.d.ts.map +1 -0
- package/dist/kernel/catalog.js +280 -0
- package/dist/kernel/catalog.js.map +1 -0
- package/dist/kernel/chain.d.ts.map +1 -0
- package/dist/kernel/chain.js.map +1 -0
- package/dist/kernel/correlation.d.ts.map +1 -0
- package/dist/kernel/correlation.js +267 -0
- package/dist/kernel/correlation.js.map +1 -0
- package/dist/kernel/definitions.d.ts.map +1 -0
- package/dist/kernel/definitions.js +164 -0
- package/dist/kernel/definitions.js.map +1 -0
- package/dist/kernel/delegate-types.d.ts +160 -0
- package/dist/kernel/delegate-types.d.ts.map +1 -0
- package/dist/kernel/delegate-types.js +9 -0
- package/dist/kernel/delegate-types.js.map +1 -0
- package/dist/kernel/delegate.d.ts.map +1 -0
- package/dist/kernel/delegate.js +314 -0
- package/dist/kernel/delegate.js.map +1 -0
- package/dist/kernel/delegation-approval.d.ts.map +1 -0
- package/dist/kernel/delegation-approval.js +93 -0
- package/dist/kernel/delegation-approval.js.map +1 -0
- package/dist/kernel/env-names.d.ts +51 -0
- package/dist/kernel/env-names.d.ts.map +1 -0
- package/dist/kernel/env-names.js +112 -0
- package/dist/kernel/env-names.js.map +1 -0
- package/dist/kernel/execution-id.d.ts.map +1 -0
- package/dist/kernel/execution-id.js.map +1 -0
- package/dist/kernel/fanout.d.ts.map +1 -0
- package/dist/kernel/fanout.js +93 -0
- package/dist/kernel/fanout.js.map +1 -0
- package/dist/kernel/grant-env.d.ts +118 -0
- package/dist/kernel/grant-env.d.ts.map +1 -0
- package/dist/kernel/grant-env.js +104 -0
- package/dist/kernel/grant-env.js.map +1 -0
- package/dist/kernel/ledger-identifiers.d.ts.map +1 -0
- package/dist/kernel/ledger-identifiers.js.map +1 -0
- package/dist/kernel/model-preflight.d.ts +13 -0
- package/dist/kernel/model-preflight.d.ts.map +1 -0
- package/dist/kernel/model-preflight.js +30 -0
- package/dist/kernel/model-preflight.js.map +1 -0
- package/dist/kernel/pi-tools.d.ts.map +1 -0
- package/dist/kernel/pi-tools.js +29 -0
- package/dist/kernel/pi-tools.js.map +1 -0
- package/dist/kernel/progress.d.ts.map +1 -0
- package/dist/kernel/progress.js.map +1 -0
- package/dist/kernel/project-paths.d.ts +43 -0
- package/dist/kernel/project-paths.d.ts.map +1 -0
- package/dist/kernel/project-paths.js +81 -0
- package/dist/kernel/project-paths.js.map +1 -0
- package/dist/kernel/propagation.d.ts +195 -0
- package/dist/kernel/propagation.d.ts.map +1 -0
- package/dist/kernel/propagation.js +275 -0
- package/dist/kernel/propagation.js.map +1 -0
- package/dist/kernel/refusals.d.ts +16 -0
- package/dist/kernel/refusals.d.ts.map +1 -0
- package/dist/kernel/refusals.js +53 -0
- package/dist/kernel/refusals.js.map +1 -0
- package/dist/kernel/resolve.d.ts.map +1 -0
- package/dist/kernel/resolve.js +201 -0
- package/dist/kernel/resolve.js.map +1 -0
- package/dist/kernel/routing-authority.d.ts.map +1 -0
- package/dist/kernel/routing-authority.js.map +1 -0
- package/dist/kernel/run-child.d.ts +111 -0
- package/dist/kernel/run-child.d.ts.map +1 -0
- package/dist/kernel/run-child.js +324 -0
- package/dist/kernel/run-child.js.map +1 -0
- package/dist/kernel/skill-packages.d.ts +116 -0
- package/dist/kernel/skill-packages.d.ts.map +1 -0
- package/dist/kernel/skill-packages.js +300 -0
- package/dist/kernel/skill-packages.js.map +1 -0
- package/dist/kernel/skill-resources.d.ts.map +1 -0
- package/dist/kernel/skill-resources.js +56 -0
- package/dist/kernel/skill-resources.js.map +1 -0
- package/dist/kernel/spawn.d.ts.map +1 -0
- package/dist/kernel/spawn.js.map +1 -0
- package/dist/kernel/workspace.d.ts +51 -0
- package/dist/kernel/workspace.d.ts.map +1 -0
- package/dist/kernel/workspace.js +223 -0
- package/dist/kernel/workspace.js.map +1 -0
- package/dist/products/activity-timeline.d.ts +126 -0
- package/dist/products/activity-timeline.d.ts.map +1 -0
- package/dist/products/activity-timeline.js +542 -0
- package/dist/products/activity-timeline.js.map +1 -0
- package/dist/products/dashboard-cli.d.ts +26 -0
- package/dist/products/dashboard-cli.d.ts.map +1 -0
- package/dist/products/dashboard-cli.js +224 -0
- package/dist/products/dashboard-cli.js.map +1 -0
- package/dist/products/dashboard-display-controls.d.ts +17 -0
- package/dist/products/dashboard-display-controls.d.ts.map +1 -0
- package/dist/products/dashboard-display-controls.js +38 -0
- package/dist/products/dashboard-display-controls.js.map +1 -0
- package/dist/products/dashboard-handshake.d.ts +42 -0
- package/dist/products/dashboard-handshake.d.ts.map +1 -0
- package/dist/products/dashboard-handshake.js +158 -0
- package/dist/products/dashboard-handshake.js.map +1 -0
- package/dist/products/dashboard-herdr.d.ts +55 -0
- package/dist/products/dashboard-herdr.d.ts.map +1 -0
- package/dist/products/dashboard-herdr.js +324 -0
- package/dist/products/dashboard-herdr.js.map +1 -0
- package/dist/products/dashboard-projection.d.ts +62 -0
- package/dist/products/dashboard-projection.d.ts.map +1 -0
- package/dist/products/dashboard-projection.js +305 -0
- package/dist/products/dashboard-projection.js.map +1 -0
- package/dist/products/dashboard-render.d.ts.map +1 -0
- package/dist/products/dashboard-render.js +208 -0
- package/dist/products/dashboard-render.js.map +1 -0
- package/extensions/activity-timeline.ts +196 -0
- package/extensions/approval-banking.ts +3 -3
- package/extensions/approvals.ts +18 -12
- package/extensions/chain-approval-facts.ts +9 -6
- package/extensions/chain-ledger.ts +4 -4
- package/extensions/chain-plan.ts +6 -6
- package/extensions/correlation-shape.ts +42 -33
- package/extensions/delegate-chain.ts +93 -45
- package/extensions/delegation-authority.ts +7 -3
- package/extensions/delegation-ledger.ts +2 -2
- package/extensions/delegation-native.ts +24 -7
- package/extensions/delegation.ts +91 -80
- package/extensions/execute-child.ts +440 -293
- package/extensions/execution-occurrence.ts +2 -2
- package/extensions/executor-session.ts +5 -5
- package/extensions/fanout-outcome.ts +8 -6
- package/extensions/grant-store-refusal.ts +24 -12
- package/extensions/grants-command.ts +41 -33
- package/extensions/grants-connected-command.ts +29 -15
- package/extensions/grants.ts +78 -77
- package/extensions/init-command.ts +18 -12
- package/extensions/reload-environment.ts +12 -5
- package/extensions/run-delegation.ts +29 -19
- package/extensions/session-environment.ts +31 -14
- package/extensions/session-report.ts +60 -10
- package/extensions/session.ts +76 -66
- package/extensions/spawn-summary.ts +5 -5
- package/extensions/stored-grant-session.ts +5 -5
- package/extensions/tripwire.ts +1 -1
- package/extensions/workspace-runtime.ts +26 -24
- package/herdr-plugin/herdr-plugin.toml +1 -1
- package/package.json +5 -212
- package/src/cli.ts +136 -89
- package/src/executors/activity-session.ts +54 -0
- package/src/executors/executor.ts +123 -0
- package/src/executors/herdr-cli.ts +132 -0
- package/src/executors/herdr-pi-lifecycle.ts +21 -0
- package/src/executors/herdr-poll.ts +305 -0
- package/src/executors/herdr-stage.ts +55 -0
- package/src/executors/native-session-target.ts +31 -0
- package/src/executors/pane-reaper.ts +270 -0
- package/src/executors/process-activity.ts +54 -0
- package/src/executors/run-herdr.ts +426 -0
- package/src/governance/approval-prompt.ts +225 -0
- package/src/governance/approval-store.ts +385 -0
- package/src/governance/execution-retention.ts +372 -0
- package/src/governance/file-lock.ts +210 -0
- package/src/governance/finalization.ts +82 -0
- package/src/governance/grant-store.ts +235 -0
- package/src/governance/init.ts +447 -0
- package/src/governance/lease-helper.ts +124 -0
- package/src/governance/lease-record.ts +131 -0
- package/src/governance/ledger-events.ts +222 -0
- package/src/governance/ledger-report.ts +396 -0
- package/src/governance/ledger-v3-validation.ts +384 -0
- package/src/governance/ledger.ts +419 -0
- package/src/governance/native-session.ts +264 -0
- package/src/governance/record.ts +294 -0
- package/src/governance/retention-contract.ts +201 -0
- package/src/governance/retention-json.ts +24 -0
- package/src/governance/workspace-lease.ts +429 -0
- package/src/index.ts +82 -92
- package/src/kernel/approval.ts +406 -0
- package/src/kernel/capabilities.ts +216 -0
- package/src/kernel/catalog.ts +313 -0
- package/src/kernel/correlation.ts +351 -0
- package/src/kernel/definitions.ts +215 -0
- package/src/kernel/delegate-types.ts +162 -0
- package/src/kernel/delegate.ts +370 -0
- package/src/kernel/delegation-approval.ts +126 -0
- package/src/kernel/env-names.ts +119 -0
- package/src/kernel/fanout.ts +106 -0
- package/src/kernel/grant-env.ts +174 -0
- package/src/kernel/model-preflight.ts +44 -0
- package/src/kernel/pi-tools.ts +32 -0
- package/src/kernel/project-paths.ts +97 -0
- package/src/kernel/propagation.ts +341 -0
- package/src/kernel/refusals.ts +64 -0
- package/src/kernel/resolve.ts +258 -0
- package/src/kernel/run-child.ts +418 -0
- package/src/kernel/skill-packages.ts +329 -0
- package/src/kernel/skill-resources.ts +64 -0
- package/src/kernel/workspace.ts +336 -0
- package/src/products/activity-timeline.ts +679 -0
- package/src/products/dashboard-cli.ts +250 -0
- package/src/products/dashboard-display-controls.ts +44 -0
- package/src/products/dashboard-handshake.ts +222 -0
- package/src/products/dashboard-herdr.ts +427 -0
- package/src/products/dashboard-projection.ts +389 -0
- package/src/products/dashboard-render.ts +260 -0
- package/PRODUCT-GUIDE.md +0 -136
- package/REQUIREMENTS.md +0 -41
- package/contracts/daily-view/v1/README.md +0 -114
- package/contracts/daily-view/v1/fixtures/view.json +0 -525
- package/contracts/daily-view/v1/fixtures/view.txt +0 -75
- package/contracts/daily-view/v1/fixtures/work.jsonl +0 -17
- package/contracts/daily-view/v1/p03/README.md +0 -26
- package/contracts/daily-view/v1/p03/fixtures/retained-executions.json +0 -241
- package/contracts/daily-view/v1/p03/projection.schema.json +0 -194
- package/contracts/daily-view/v1/p03/provenance.json +0 -21
- package/contracts/dashboard-host/v1/README.md +0 -176
- package/contracts/debrief/v1/README.md +0 -146
- package/contracts/debrief/v1/intervention/README.md +0 -32
- package/contracts/debrief/v1/intervention/fixtures/artifact-3ee11136beb864f518252e5024dae9197421fbf97b6e981d3243c782b5c44bd0.txt +0 -1
- package/contracts/debrief/v1/intervention/fixtures/artifact-58905d872dd3c54a9705f67b05fa82edbad7af6476ae8993faf1a7b9fadfb905.txt +0 -1
- package/contracts/debrief/v1/intervention/fixtures/assessment.json +0 -29
- package/contracts/debrief/v1/intervention/fixtures/blind-view.json +0 -20
- package/contracts/debrief/v1/intervention/fixtures/choice.json +0 -7
- package/contracts/debrief/v1/intervention/fixtures/manifest.json +0 -57
- package/contracts/debrief/v1/intervention/fixtures/reveal.json +0 -39
- package/contracts/debrief/v1/provenance.json +0 -89
- package/contracts/debrief/v1/work-capture/README.md +0 -38
- package/contracts/debrief/v1/work-capture/fixtures/batch.json +0 -17
- package/contracts/debrief/v1/work-capture/fixtures/cases.json +0 -184
- package/contracts/debrief/v1/work-capture/fixtures/review.json +0 -184
- package/contracts/debrief/v1/work-capture/review-request.schema.json +0 -41
- package/contracts/debrief/v1/work-capture/work-case.schema.json +0 -190
- package/contracts/debrief/v2/README.md +0 -71
- package/contracts/debrief/v2/input-pin.json +0 -66
- package/contracts/debrief/v2/intervention-upstream.md +0 -40
- package/contracts/debrief/v2/work-signals-upstream.md +0 -22
- package/contracts/dispatch-control/v1/README.md +0 -109
- package/contracts/dispatch-control/v1/request.schema.json +0 -19
- package/contracts/effect-profile/v1/README.md +0 -124
- package/contracts/execution-retention/v1/README.md +0 -109
- package/contracts/execution-retention/v2/README.md +0 -148
- package/contracts/execution-retention/v2/fixtures/interrupted-native-bytes.json +0 -91
- package/contracts/execution-retention/v2/fixtures/missing-native-session.json +0 -91
- package/contracts/execution-retention/v2/fixtures/native-file-unknown-branch.json +0 -91
- package/contracts/execution-retention/v2/fixtures/native-id-without-bytes.json +0 -91
- package/contracts/execution-retention/v2/fixtures/native-live-branch.json +0 -90
- package/contracts/execution-retention/v2/fixtures/replaced-native-session.json +0 -92
- package/contracts/execution-retention/v2/fixtures/result-82c620cdfeb8ca6b858cf653d7f5e2eedca5315d6244216d60e8b36f03223d6a.bin +0 -1
- package/contracts/execution-retention/v2/fixtures/session-2ec1f134bc739984434f7fca689e1c3d1c39fce2dcadae709e9b6faedfcc4ac7.bin +0 -3
- package/contracts/execution-retention/v2/fixtures/session-9bdb4bd16a901da31580acf056bda525225259e15ec409e0410480109011772f.bin +0 -3
- package/contracts/execution-retention/v2/manifest.schema.json +0 -858
- package/contracts/experiment/v1/README.md +0 -164
- package/contracts/factory-order/v1/README.md +0 -151
- package/contracts/factory-order/v1/adoption-pin.json +0 -8
- package/contracts/intent-control/v1/README.md +0 -135
- package/contracts/intent-control/v1/request.schema.json +0 -1096
- package/contracts/intent-control/v2/README.md +0 -34
- package/contracts/intent-control/v2/request.schema.json +0 -1070
- package/contracts/ledger/v2/README.md +0 -59
- package/contracts/ledger/v2/fixtures/capability-decision.json +0 -95
- package/contracts/ledger/v2/fixtures/check-receipt.json +0 -40
- package/contracts/ledger/v2/fixtures/child-lifecycle.json +0 -42
- package/contracts/ledger/v2/fixtures/workspace-lease.json +0 -41
- package/contracts/ledger/v2/ledger-event.schema.json +0 -633
- package/contracts/ledger/v3/README.md +0 -36
- package/contracts/ledger/v3/fixtures/check-receipt.json +0 -41
- package/contracts/ledger/v3/fixtures/child-lifecycle.json +0 -44
- package/contracts/ledger/v3/fixtures/workflow-fact.json +0 -40
- package/contracts/ledger/v3/ledger-event.schema.json +0 -955
- package/contracts/ledger/v4/README.md +0 -241
- package/contracts/ledger/v4/fixtures/layout-options.json +0 -428
- package/contracts/ledger/v4/fixtures/work-acceptance.json +0 -57
- package/contracts/ledger/v4/fixtures/work-occurrence.json +0 -44
- package/contracts/ledger/v4/fixtures/work-revision.json +0 -26
- package/contracts/ledger/v4/fixtures/work-snapshot.json +0 -73
- package/contracts/ledger/v4/ledger-event.schema.json +0 -162
- package/contracts/ordinary-control/v1/README.md +0 -59
- package/contracts/producer-ipc/v1/README.md +0 -137
- package/dist/approval-prompt.d.ts +0 -119
- package/dist/approval-prompt.d.ts.map +0 -1
- package/dist/approval-prompt.js +0 -133
- package/dist/approval-prompt.js.map +0 -1
- package/dist/approval-store.d.ts +0 -149
- package/dist/approval-store.d.ts.map +0 -1
- package/dist/approval-store.js +0 -314
- package/dist/approval-store.js.map +0 -1
- package/dist/approval.d.ts +0 -241
- package/dist/approval.d.ts.map +0 -1
- package/dist/approval.js +0 -268
- package/dist/approval.js.map +0 -1
- package/dist/capabilities.d.ts +0 -136
- package/dist/capabilities.d.ts.map +0 -1
- package/dist/capabilities.js +0 -203
- package/dist/capabilities.js.map +0 -1
- package/dist/catalog.d.ts +0 -98
- package/dist/catalog.d.ts.map +0 -1
- package/dist/catalog.js +0 -273
- package/dist/catalog.js.map +0 -1
- package/dist/chain.d.ts.map +0 -1
- package/dist/chain.js.map +0 -1
- package/dist/check-runner.d.ts +0 -66
- package/dist/check-runner.d.ts.map +0 -1
- package/dist/check-runner.js +0 -275
- package/dist/check-runner.js.map +0 -1
- package/dist/control-journal.d.ts +0 -20
- package/dist/control-journal.d.ts.map +0 -1
- package/dist/control-journal.js +0 -73
- package/dist/control-journal.js.map +0 -1
- package/dist/correlation.d.ts.map +0 -1
- package/dist/correlation.js +0 -231
- package/dist/correlation.js.map +0 -1
- package/dist/daily-dashboard-host.d.ts +0 -136
- package/dist/daily-dashboard-host.d.ts.map +0 -1
- package/dist/daily-dashboard-host.js +0 -164
- package/dist/daily-dashboard-host.js.map +0 -1
- package/dist/daily-panel.d.ts +0 -36
- package/dist/daily-panel.d.ts.map +0 -1
- package/dist/daily-panel.js +0 -84
- package/dist/daily-panel.js.map +0 -1
- package/dist/daily-view-input.d.ts +0 -44
- package/dist/daily-view-input.d.ts.map +0 -1
- package/dist/daily-view-input.js +0 -68
- package/dist/daily-view-input.js.map +0 -1
- package/dist/daily-view-render.d.ts +0 -5
- package/dist/daily-view-render.d.ts.map +0 -1
- package/dist/daily-view-render.js +0 -42
- package/dist/daily-view-render.js.map +0 -1
- package/dist/daily-view.d.ts +0 -77
- package/dist/daily-view.d.ts.map +0 -1
- package/dist/daily-view.js +0 -176
- package/dist/daily-view.js.map +0 -1
- package/dist/dashboard-cli.d.ts +0 -48
- package/dist/dashboard-cli.d.ts.map +0 -1
- package/dist/dashboard-cli.js +0 -331
- package/dist/dashboard-cli.js.map +0 -1
- package/dist/dashboard-display-controls.d.ts +0 -10
- package/dist/dashboard-display-controls.d.ts.map +0 -1
- package/dist/dashboard-display-controls.js +0 -25
- package/dist/dashboard-display-controls.js.map +0 -1
- package/dist/dashboard-handshake.d.ts +0 -37
- package/dist/dashboard-handshake.d.ts.map +0 -1
- package/dist/dashboard-handshake.js +0 -136
- package/dist/dashboard-handshake.js.map +0 -1
- package/dist/dashboard-harness.d.ts +0 -22
- package/dist/dashboard-harness.d.ts.map +0 -1
- package/dist/dashboard-harness.js +0 -89
- package/dist/dashboard-harness.js.map +0 -1
- package/dist/dashboard-herdr.d.ts +0 -55
- package/dist/dashboard-herdr.d.ts.map +0 -1
- package/dist/dashboard-herdr.js +0 -293
- package/dist/dashboard-herdr.js.map +0 -1
- package/dist/dashboard-host-contract.d.ts +0 -127
- package/dist/dashboard-host-contract.d.ts.map +0 -1
- package/dist/dashboard-host-contract.js +0 -14
- package/dist/dashboard-host-contract.js.map +0 -1
- package/dist/dashboard-host-transport.d.ts +0 -16
- package/dist/dashboard-host-transport.d.ts.map +0 -1
- package/dist/dashboard-host-transport.js +0 -127
- package/dist/dashboard-host-transport.js.map +0 -1
- package/dist/dashboard-host.d.ts +0 -239
- package/dist/dashboard-host.d.ts.map +0 -1
- package/dist/dashboard-host.js +0 -474
- package/dist/dashboard-host.js.map +0 -1
- package/dist/dashboard-menu.d.ts +0 -16
- package/dist/dashboard-menu.d.ts.map +0 -1
- package/dist/dashboard-menu.js +0 -33
- package/dist/dashboard-menu.js.map +0 -1
- package/dist/dashboard-observation.d.ts +0 -28
- package/dist/dashboard-observation.d.ts.map +0 -1
- package/dist/dashboard-observation.js +0 -87
- package/dist/dashboard-observation.js.map +0 -1
- package/dist/dashboard-projection.d.ts +0 -73
- package/dist/dashboard-projection.d.ts.map +0 -1
- package/dist/dashboard-projection.js +0 -294
- package/dist/dashboard-projection.js.map +0 -1
- package/dist/dashboard-render.d.ts.map +0 -1
- package/dist/dashboard-render.js +0 -212
- package/dist/dashboard-render.js.map +0 -1
- package/dist/debrief-contract.d.ts +0 -65
- package/dist/debrief-contract.d.ts.map +0 -1
- package/dist/debrief-contract.js +0 -151
- package/dist/debrief-contract.js.map +0 -1
- package/dist/debrief-fixture.d.ts +0 -16
- package/dist/debrief-fixture.d.ts.map +0 -1
- package/dist/debrief-fixture.js +0 -41
- package/dist/debrief-fixture.js.map +0 -1
- package/dist/debrief-host.d.ts +0 -59
- package/dist/debrief-host.d.ts.map +0 -1
- package/dist/debrief-host.js +0 -49
- package/dist/debrief-host.js.map +0 -1
- package/dist/debrief-render.d.ts +0 -5
- package/dist/debrief-render.d.ts.map +0 -1
- package/dist/debrief-render.js +0 -65
- package/dist/debrief-render.js.map +0 -1
- package/dist/debrief.d.ts +0 -90
- package/dist/debrief.d.ts.map +0 -1
- package/dist/debrief.js +0 -263
- package/dist/debrief.js.map +0 -1
- package/dist/definitions.d.ts.map +0 -1
- package/dist/definitions.js +0 -164
- package/dist/definitions.js.map +0 -1
- package/dist/delegate-types.d.ts +0 -146
- package/dist/delegate-types.d.ts.map +0 -1
- package/dist/delegate-types.js +0 -8
- package/dist/delegate-types.js.map +0 -1
- package/dist/delegate.d.ts.map +0 -1
- package/dist/delegate.js +0 -305
- package/dist/delegate.js.map +0 -1
- package/dist/delegation-approval.d.ts.map +0 -1
- package/dist/delegation-approval.js +0 -94
- package/dist/delegation-approval.js.map +0 -1
- package/dist/dispatch-control.d.ts +0 -45
- package/dist/dispatch-control.d.ts.map +0 -1
- package/dist/dispatch-control.js +0 -76
- package/dist/dispatch-control.js.map +0 -1
- package/dist/effect-profile-runtime.d.ts +0 -40
- package/dist/effect-profile-runtime.d.ts.map +0 -1
- package/dist/effect-profile-runtime.js +0 -51
- package/dist/effect-profile-runtime.js.map +0 -1
- package/dist/effect-profile.d.ts +0 -40
- package/dist/effect-profile.d.ts.map +0 -1
- package/dist/effect-profile.js +0 -152
- package/dist/effect-profile.js.map +0 -1
- package/dist/execution-id.d.ts.map +0 -1
- package/dist/execution-id.js.map +0 -1
- package/dist/execution-retention.d.ts +0 -90
- package/dist/execution-retention.d.ts.map +0 -1
- package/dist/execution-retention.js +0 -247
- package/dist/execution-retention.js.map +0 -1
- package/dist/executor.d.ts +0 -39
- package/dist/executor.d.ts.map +0 -1
- package/dist/executor.js +0 -94
- package/dist/executor.js.map +0 -1
- package/dist/experiment-contract.d.ts +0 -56
- package/dist/experiment-contract.d.ts.map +0 -1
- package/dist/experiment-contract.js +0 -80
- package/dist/experiment-contract.js.map +0 -1
- package/dist/experiment-state.d.ts +0 -22
- package/dist/experiment-state.d.ts.map +0 -1
- package/dist/experiment-state.js +0 -79
- package/dist/experiment-state.js.map +0 -1
- package/dist/experiment-store.d.ts +0 -30
- package/dist/experiment-store.d.ts.map +0 -1
- package/dist/experiment-store.js +0 -147
- package/dist/experiment-store.js.map +0 -1
- package/dist/experiment.d.ts +0 -65
- package/dist/experiment.d.ts.map +0 -1
- package/dist/experiment.js +0 -362
- package/dist/experiment.js.map +0 -1
- package/dist/factory-contract.d.ts +0 -79
- package/dist/factory-contract.d.ts.map +0 -1
- package/dist/factory-contract.js +0 -89
- package/dist/factory-contract.js.map +0 -1
- package/dist/factory-migration.d.ts +0 -20
- package/dist/factory-migration.d.ts.map +0 -1
- package/dist/factory-migration.js +0 -55
- package/dist/factory-migration.js.map +0 -1
- package/dist/factory-order.d.ts +0 -848
- package/dist/factory-order.d.ts.map +0 -1
- package/dist/factory-order.js +0 -83
- package/dist/factory-order.js.map +0 -1
- package/dist/factory-registry.d.ts +0 -121
- package/dist/factory-registry.d.ts.map +0 -1
- package/dist/factory-registry.js +0 -133
- package/dist/factory-registry.js.map +0 -1
- package/dist/fanout.d.ts.map +0 -1
- package/dist/fanout.js +0 -93
- package/dist/fanout.js.map +0 -1
- package/dist/file-lock.d.ts.map +0 -1
- package/dist/file-lock.js +0 -201
- package/dist/file-lock.js.map +0 -1
- package/dist/finalization.d.ts.map +0 -1
- package/dist/finalization.js.map +0 -1
- package/dist/git-identity.d.ts +0 -13
- package/dist/git-identity.d.ts.map +0 -1
- package/dist/git-identity.js +0 -47
- package/dist/git-identity.js.map +0 -1
- package/dist/grant-env.d.ts +0 -75
- package/dist/grant-env.d.ts.map +0 -1
- package/dist/grant-env.js +0 -154
- package/dist/grant-env.js.map +0 -1
- package/dist/grant-store.d.ts +0 -96
- package/dist/grant-store.d.ts.map +0 -1
- package/dist/grant-store.js +0 -188
- package/dist/grant-store.js.map +0 -1
- package/dist/herdr-cli.d.ts +0 -78
- package/dist/herdr-cli.d.ts.map +0 -1
- package/dist/herdr-cli.js +0 -113
- package/dist/herdr-cli.js.map +0 -1
- package/dist/herdr-name.d.ts.map +0 -1
- package/dist/herdr-name.js.map +0 -1
- package/dist/herdr-pi-lifecycle.d.ts.map +0 -1
- package/dist/herdr-pi-lifecycle.js +0 -22
- package/dist/herdr-pi-lifecycle.js.map +0 -1
- package/dist/herdr-poll.d.ts +0 -133
- package/dist/herdr-poll.d.ts.map +0 -1
- package/dist/herdr-poll.js +0 -222
- package/dist/herdr-poll.js.map +0 -1
- package/dist/herdr-stage.d.ts +0 -40
- package/dist/herdr-stage.d.ts.map +0 -1
- package/dist/herdr-stage.js +0 -54
- package/dist/herdr-stage.js.map +0 -1
- package/dist/herdr-start.d.ts.map +0 -1
- package/dist/herdr-start.js.map +0 -1
- package/dist/init.d.ts +0 -117
- package/dist/init.d.ts.map +0 -1
- package/dist/init.js +0 -323
- package/dist/init.js.map +0 -1
- package/dist/intent-application.d.ts +0 -17
- package/dist/intent-application.d.ts.map +0 -1
- package/dist/intent-application.js +0 -114
- package/dist/intent-application.js.map +0 -1
- package/dist/intent-control.d.ts +0 -201
- package/dist/intent-control.d.ts.map +0 -1
- package/dist/intent-control.js +0 -110
- package/dist/intent-control.js.map +0 -1
- package/dist/intent-scheduling.d.ts +0 -9
- package/dist/intent-scheduling.d.ts.map +0 -1
- package/dist/intent-scheduling.js +0 -15
- package/dist/intent-scheduling.js.map +0 -1
- package/dist/learning-connection.d.ts +0 -127
- package/dist/learning-connection.d.ts.map +0 -1
- package/dist/learning-connection.js +0 -54
- package/dist/learning-connection.js.map +0 -1
- package/dist/lease-helper.d.ts.map +0 -1
- package/dist/lease-helper.js +0 -94
- package/dist/lease-helper.js.map +0 -1
- package/dist/lease-record.d.ts +0 -90
- package/dist/lease-record.d.ts.map +0 -1
- package/dist/lease-record.js.map +0 -1
- package/dist/ledger-append.d.ts +0 -15
- package/dist/ledger-append.d.ts.map +0 -1
- package/dist/ledger-append.js +0 -94
- package/dist/ledger-append.js.map +0 -1
- package/dist/ledger-events.d.ts +0 -131
- package/dist/ledger-events.d.ts.map +0 -1
- package/dist/ledger-events.js +0 -107
- package/dist/ledger-events.js.map +0 -1
- package/dist/ledger-identifiers.d.ts.map +0 -1
- package/dist/ledger-identifiers.js.map +0 -1
- package/dist/ledger-report.d.ts +0 -134
- package/dist/ledger-report.d.ts.map +0 -1
- package/dist/ledger-report.js +0 -271
- package/dist/ledger-report.js.map +0 -1
- package/dist/ledger-v3-validation.d.ts +0 -11
- package/dist/ledger-v3-validation.d.ts.map +0 -1
- package/dist/ledger-v3-validation.js +0 -265
- package/dist/ledger-v3-validation.js.map +0 -1
- package/dist/ledger.d.ts +0 -242
- package/dist/ledger.d.ts.map +0 -1
- package/dist/ledger.js +0 -142
- package/dist/ledger.js.map +0 -1
- package/dist/measured-order.d.ts +0 -249
- package/dist/measured-order.d.ts.map +0 -1
- package/dist/measured-order.js +0 -309
- package/dist/measured-order.js.map +0 -1
- package/dist/measured-session.d.ts +0 -97
- package/dist/measured-session.d.ts.map +0 -1
- package/dist/measured-session.js +0 -134
- package/dist/measured-session.js.map +0 -1
- package/dist/model-preflight.d.ts +0 -13
- package/dist/model-preflight.d.ts.map +0 -1
- package/dist/model-preflight.js +0 -29
- package/dist/model-preflight.js.map +0 -1
- package/dist/native-session-target.d.ts +0 -9
- package/dist/native-session-target.d.ts.map +0 -1
- package/dist/native-session-target.js +0 -29
- package/dist/native-session-target.js.map +0 -1
- package/dist/native-session.d.ts +0 -59
- package/dist/native-session.d.ts.map +0 -1
- package/dist/native-session.js +0 -154
- package/dist/native-session.js.map +0 -1
- package/dist/order-schedule.d.ts +0 -37
- package/dist/order-schedule.d.ts.map +0 -1
- package/dist/order-schedule.js +0 -81
- package/dist/order-schedule.js.map +0 -1
- package/dist/ordinary-children.d.ts +0 -52
- package/dist/ordinary-children.d.ts.map +0 -1
- package/dist/ordinary-children.js +0 -93
- package/dist/ordinary-children.js.map +0 -1
- package/dist/pane-reaper.d.ts +0 -111
- package/dist/pane-reaper.d.ts.map +0 -1
- package/dist/pane-reaper.js +0 -242
- package/dist/pane-reaper.js.map +0 -1
- package/dist/pi-tools.d.ts.map +0 -1
- package/dist/pi-tools.js +0 -21
- package/dist/pi-tools.js.map +0 -1
- package/dist/producer-ipc-contract.d.ts +0 -29
- package/dist/producer-ipc-contract.d.ts.map +0 -1
- package/dist/producer-ipc-contract.js +0 -29
- package/dist/producer-ipc-contract.js.map +0 -1
- package/dist/producer-ipc.d.ts +0 -55
- package/dist/producer-ipc.d.ts.map +0 -1
- package/dist/producer-ipc.js +0 -143
- package/dist/producer-ipc.js.map +0 -1
- package/dist/product-files.d.ts +0 -6
- package/dist/product-files.d.ts.map +0 -1
- package/dist/product-files.js +0 -55
- package/dist/product-files.js.map +0 -1
- package/dist/progress.d.ts.map +0 -1
- package/dist/progress.js.map +0 -1
- package/dist/propagation.d.ts +0 -203
- package/dist/propagation.d.ts.map +0 -1
- package/dist/propagation.js +0 -279
- package/dist/propagation.js.map +0 -1
- package/dist/refusals.d.ts +0 -16
- package/dist/refusals.d.ts.map +0 -1
- package/dist/refusals.js +0 -55
- package/dist/refusals.js.map +0 -1
- package/dist/resolve.d.ts.map +0 -1
- package/dist/resolve.js +0 -211
- package/dist/resolve.js.map +0 -1
- package/dist/resource-budget.d.ts +0 -334
- package/dist/resource-budget.d.ts.map +0 -1
- package/dist/resource-budget.js +0 -415
- package/dist/resource-budget.js.map +0 -1
- package/dist/retention-contract.d.ts.map +0 -1
- package/dist/retention-contract.js +0 -104
- package/dist/retention-contract.js.map +0 -1
- package/dist/retention-json.d.ts.map +0 -1
- package/dist/retention-json.js.map +0 -1
- package/dist/routing-authority.d.ts.map +0 -1
- package/dist/routing-authority.js.map +0 -1
- package/dist/run-child.d.ts +0 -87
- package/dist/run-child.d.ts.map +0 -1
- package/dist/run-child.js +0 -248
- package/dist/run-child.js.map +0 -1
- package/dist/run-herdr.d.ts +0 -119
- package/dist/run-herdr.d.ts.map +0 -1
- package/dist/run-herdr.js +0 -335
- package/dist/run-herdr.js.map +0 -1
- package/dist/skill-packages.d.ts +0 -116
- package/dist/skill-packages.d.ts.map +0 -1
- package/dist/skill-packages.js +0 -295
- package/dist/skill-packages.js.map +0 -1
- package/dist/skill-resources.d.ts.map +0 -1
- package/dist/skill-resources.js +0 -52
- package/dist/skill-resources.js.map +0 -1
- package/dist/spawn.d.ts.map +0 -1
- package/dist/spawn.js.map +0 -1
- package/dist/vendor/adoption.d.ts +0 -129
- package/dist/vendor/adoption.d.ts.map +0 -1
- package/dist/vendor/adoption.js +0 -102
- package/dist/vendor/adoption.js.map +0 -1
- package/dist/vendor/herdr-pi-lifecycle.d.ts.map +0 -1
- package/dist/vendor/herdr-pi-lifecycle.js.map +0 -1
- package/dist/work-command.d.ts +0 -32
- package/dist/work-command.d.ts.map +0 -1
- package/dist/work-command.js +0 -179
- package/dist/work-command.js.map +0 -1
- package/dist/work-ledger-destination.d.ts +0 -20
- package/dist/work-ledger-destination.d.ts.map +0 -1
- package/dist/work-ledger-destination.js +0 -131
- package/dist/work-ledger-destination.js.map +0 -1
- package/dist/work-ledger-json.d.ts +0 -25
- package/dist/work-ledger-json.d.ts.map +0 -1
- package/dist/work-ledger-json.js +0 -267
- package/dist/work-ledger-json.js.map +0 -1
- package/dist/work-ledger-occurrences.d.ts +0 -227
- package/dist/work-ledger-occurrences.d.ts.map +0 -1
- package/dist/work-ledger-occurrences.js +0 -115
- package/dist/work-ledger-occurrences.js.map +0 -1
- package/dist/work-ledger-projection.d.ts +0 -295
- package/dist/work-ledger-projection.d.ts.map +0 -1
- package/dist/work-ledger-projection.js +0 -237
- package/dist/work-ledger-projection.js.map +0 -1
- package/dist/work-ledger-snapshot.d.ts +0 -29
- package/dist/work-ledger-snapshot.d.ts.map +0 -1
- package/dist/work-ledger-snapshot.js +0 -267
- package/dist/work-ledger-snapshot.js.map +0 -1
- package/dist/work-ledger-types.d.ts +0 -261
- package/dist/work-ledger-types.d.ts.map +0 -1
- package/dist/work-ledger-types.js +0 -13
- package/dist/work-ledger-types.js.map +0 -1
- package/dist/work-ledger-validation.d.ts +0 -14
- package/dist/work-ledger-validation.d.ts.map +0 -1
- package/dist/work-ledger-validation.js +0 -226
- package/dist/work-ledger-validation.js.map +0 -1
- package/dist/work-ledger.d.ts +0 -43
- package/dist/work-ledger.d.ts.map +0 -1
- package/dist/work-ledger.js +0 -225
- package/dist/work-ledger.js.map +0 -1
- package/dist/work-policy-registry.d.ts +0 -133
- package/dist/work-policy-registry.d.ts.map +0 -1
- package/dist/work-policy-registry.js +0 -128
- package/dist/work-policy-registry.js.map +0 -1
- package/dist/work-run.d.ts +0 -56
- package/dist/work-run.d.ts.map +0 -1
- package/dist/work-run.js +0 -102
- package/dist/work-run.js.map +0 -1
- package/dist/work-setup.d.ts +0 -40
- package/dist/work-setup.d.ts.map +0 -1
- package/dist/work-setup.js +0 -174
- package/dist/work-setup.js.map +0 -1
- package/dist/workflow-fact-id.d.ts +0 -4
- package/dist/workflow-fact-id.d.ts.map +0 -1
- package/dist/workflow-fact-id.js +0 -14
- package/dist/workflow-fact-id.js.map +0 -1
- package/dist/workflow-facts.d.ts +0 -34
- package/dist/workflow-facts.d.ts.map +0 -1
- package/dist/workflow-facts.js +0 -43
- package/dist/workflow-facts.js.map +0 -1
- package/dist/workspace-lease.d.ts +0 -40
- package/dist/workspace-lease.d.ts.map +0 -1
- package/dist/workspace-lease.js +0 -333
- package/dist/workspace-lease.js.map +0 -1
- package/dist/workspace.d.ts +0 -57
- package/dist/workspace.d.ts.map +0 -1
- package/dist/workspace.js +0 -216
- package/dist/workspace.js.map +0 -1
- package/extensions/daily-dashboard-session.ts +0 -48
- package/extensions/daily-work-session.ts +0 -20
- package/extensions/learning-outcome-session.ts +0 -38
- package/extensions/learning-session.ts +0 -59
- package/extensions/ordinary-runtime.ts +0 -14
- package/extensions/primary-shadow.ts +0 -11
- package/extensions/work-policy-session.ts +0 -139
- package/extensions/work-run-session.ts +0 -75
- package/extensions/work-runtime.ts +0 -44
- package/extensions/work-session.ts +0 -132
- package/src/approval-prompt.ts +0 -225
- package/src/approval-store.ts +0 -386
- package/src/approval.ts +0 -399
- package/src/capabilities.ts +0 -220
- package/src/catalog.ts +0 -306
- package/src/check-runner.ts +0 -387
- package/src/control-journal.ts +0 -26
- package/src/correlation.ts +0 -320
- package/src/daily-dashboard-host.ts +0 -105
- package/src/daily-panel.ts +0 -80
- package/src/daily-view-input.ts +0 -59
- package/src/daily-view-render.ts +0 -45
- package/src/daily-view.ts +0 -160
- package/src/dashboard-cli.ts +0 -315
- package/src/dashboard-display-controls.ts +0 -18
- package/src/dashboard-handshake.ts +0 -194
- package/src/dashboard-harness.ts +0 -37
- package/src/dashboard-herdr.ts +0 -363
- package/src/dashboard-host-contract.ts +0 -50
- package/src/dashboard-host-transport.ts +0 -43
- package/src/dashboard-host.ts +0 -244
- package/src/dashboard-menu.ts +0 -28
- package/src/dashboard-observation.ts +0 -46
- package/src/dashboard-projection.ts +0 -390
- package/src/dashboard-render.ts +0 -259
- package/src/debrief-contract.ts +0 -127
- package/src/debrief-fixture.ts +0 -29
- package/src/debrief-host.ts +0 -53
- package/src/debrief-render.ts +0 -49
- package/src/debrief.ts +0 -198
- package/src/definitions.ts +0 -211
- package/src/delegate-types.ts +0 -150
- package/src/delegate.ts +0 -341
- package/src/delegation-approval.ts +0 -126
- package/src/dispatch-control.ts +0 -81
- package/src/effect-profile-runtime.ts +0 -46
- package/src/effect-profile.ts +0 -129
- package/src/execution-retention.ts +0 -230
- package/src/executor.ts +0 -123
- package/src/experiment-contract.ts +0 -66
- package/src/experiment-state.ts +0 -44
- package/src/experiment-store.ts +0 -98
- package/src/experiment.ts +0 -236
- package/src/factory-contract.ts +0 -47
- package/src/factory-migration.ts +0 -29
- package/src/factory-order.ts +0 -56
- package/src/factory-registry.ts +0 -60
- package/src/fanout.ts +0 -106
- package/src/file-lock.ts +0 -178
- package/src/finalization.ts +0 -79
- package/src/git-identity.ts +0 -56
- package/src/grant-env.ts +0 -221
- package/src/grant-store.ts +0 -235
- package/src/herdr-cli.ts +0 -125
- package/src/herdr-pi-lifecycle.ts +0 -21
- package/src/herdr-poll.ts +0 -253
- package/src/herdr-stage.ts +0 -55
- package/src/init.ts +0 -389
- package/src/intent-application.ts +0 -91
- package/src/intent-control.ts +0 -107
- package/src/intent-scheduling.ts +0 -14
- package/src/learning-connection.ts +0 -70
- package/src/lease-helper.ts +0 -97
- package/src/lease-record.ts +0 -131
- package/src/ledger-append.ts +0 -72
- package/src/ledger-events.ts +0 -226
- package/src/ledger-report.ts +0 -357
- package/src/ledger-v3-validation.ts +0 -266
- package/src/ledger.ts +0 -369
- package/src/measured-order.ts +0 -72
- package/src/measured-session.ts +0 -70
- package/src/model-preflight.ts +0 -41
- package/src/native-session-target.ts +0 -23
- package/src/native-session.ts +0 -139
- package/src/order-schedule.ts +0 -42
- package/src/ordinary-children.ts +0 -59
- package/src/pane-reaper.ts +0 -270
- package/src/pi-tools.ts +0 -25
- package/src/producer-ipc-contract.ts +0 -26
- package/src/producer-ipc.ts +0 -107
- package/src/product-files.ts +0 -34
- package/src/propagation.ts +0 -333
- package/src/refusals.ts +0 -70
- package/src/resolve.ts +0 -267
- package/src/resource-budget.ts +0 -349
- package/src/retention-contract.ts +0 -84
- package/src/retention-json.ts +0 -20
- package/src/run-child.ts +0 -303
- package/src/run-herdr.ts +0 -386
- package/src/skill-packages.ts +0 -314
- package/src/skill-resources.ts +0 -48
- package/src/vendor/adoption.ts +0 -109
- package/src/work-command.ts +0 -197
- package/src/work-ledger-destination.ts +0 -113
- package/src/work-ledger-json.ts +0 -228
- package/src/work-ledger-occurrences.ts +0 -99
- package/src/work-ledger-projection.ts +0 -262
- package/src/work-ledger-snapshot.ts +0 -246
- package/src/work-ledger-types.ts +0 -229
- package/src/work-ledger-validation.ts +0 -174
- package/src/work-ledger.ts +0 -186
- package/src/work-policy-registry.ts +0 -81
- package/src/work-run.ts +0 -79
- package/src/work-setup.ts +0 -141
- package/src/workflow-fact-id.ts +0 -16
- package/src/workflow-facts.ts +0 -65
- package/src/workspace-lease.ts +0 -363
- package/src/workspace.ts +0 -308
- /package/contracts/{ledger/v3 → ledger-record/v1}/fixtures/capability-decision.json +0 -0
- /package/contracts/{ledger/v3 → ledger-record/v1}/fixtures/workspace-lease.json +0 -0
- /package/dist/{herdr-name.d.ts → executors/herdr-name.d.ts} +0 -0
- /package/dist/{herdr-name.js → executors/herdr-name.js} +0 -0
- /package/dist/{herdr-pi-lifecycle.d.ts → executors/herdr-pi-lifecycle.d.ts} +0 -0
- /package/dist/{herdr-start.d.ts → executors/herdr-start.d.ts} +0 -0
- /package/dist/{herdr-start.js → executors/herdr-start.js} +0 -0
- /package/dist/{vendor → executors/vendor}/herdr-pi-lifecycle.d.ts +0 -0
- /package/dist/{vendor → executors/vendor}/herdr-pi-lifecycle.js +0 -0
- /package/dist/{file-lock.d.ts → governance/file-lock.d.ts} +0 -0
- /package/dist/{finalization.d.ts → governance/finalization.d.ts} +0 -0
- /package/dist/{finalization.js → governance/finalization.js} +0 -0
- /package/dist/{lease-helper.d.ts → governance/lease-helper.d.ts} +0 -0
- /package/dist/{lease-record.js → governance/lease-record.js} +0 -0
- /package/dist/{retention-contract.d.ts → governance/retention-contract.d.ts} +0 -0
- /package/dist/{retention-json.d.ts → governance/retention-json.d.ts} +0 -0
- /package/dist/{retention-json.js → governance/retention-json.js} +0 -0
- /package/dist/{chain.d.ts → kernel/chain.d.ts} +0 -0
- /package/dist/{chain.js → kernel/chain.js} +0 -0
- /package/dist/{correlation.d.ts → kernel/correlation.d.ts} +0 -0
- /package/dist/{definitions.d.ts → kernel/definitions.d.ts} +0 -0
- /package/dist/{delegate.d.ts → kernel/delegate.d.ts} +0 -0
- /package/dist/{delegation-approval.d.ts → kernel/delegation-approval.d.ts} +0 -0
- /package/dist/{execution-id.d.ts → kernel/execution-id.d.ts} +0 -0
- /package/dist/{execution-id.js → kernel/execution-id.js} +0 -0
- /package/dist/{fanout.d.ts → kernel/fanout.d.ts} +0 -0
- /package/dist/{ledger-identifiers.d.ts → kernel/ledger-identifiers.d.ts} +0 -0
- /package/dist/{ledger-identifiers.js → kernel/ledger-identifiers.js} +0 -0
- /package/dist/{pi-tools.d.ts → kernel/pi-tools.d.ts} +0 -0
- /package/dist/{progress.d.ts → kernel/progress.d.ts} +0 -0
- /package/dist/{progress.js → kernel/progress.js} +0 -0
- /package/dist/{resolve.d.ts → kernel/resolve.d.ts} +0 -0
- /package/dist/{routing-authority.d.ts → kernel/routing-authority.d.ts} +0 -0
- /package/dist/{routing-authority.js → kernel/routing-authority.js} +0 -0
- /package/dist/{skill-resources.d.ts → kernel/skill-resources.d.ts} +0 -0
- /package/dist/{spawn.d.ts → kernel/spawn.d.ts} +0 -0
- /package/dist/{spawn.js → kernel/spawn.js} +0 -0
- /package/dist/{dashboard-render.d.ts → products/dashboard-render.d.ts} +0 -0
- /package/src/{herdr-name.ts → executors/herdr-name.ts} +0 -0
- /package/src/{herdr-start.ts → executors/herdr-start.ts} +0 -0
- /package/src/{vendor → executors/vendor}/herdr-pi-lifecycle.ts +0 -0
- /package/src/{chain.ts → kernel/chain.ts} +0 -0
- /package/src/{execution-id.ts → kernel/execution-id.ts} +0 -0
- /package/src/{ledger-identifiers.ts → kernel/ledger-identifiers.ts} +0 -0
- /package/src/{progress.ts → kernel/progress.ts} +0 -0
- /package/src/{routing-authority.ts → kernel/routing-authority.ts} +0 -0
- /package/src/{spawn.ts → kernel/spawn.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,911 +1,33 @@
|
|
|
1
1
|
# pi-daddy
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
Both qualifiers are load-bearing and are not buried: a child granted `bash` can escape governance entirely
|
|
9
|
-
(ADR-0012, measured), and recording is opt-in — explicitly by environment or by running `/grants init` once
|
|
10
|
-
for this project. See *What this governs, and what it does not*.
|
|
11
|
-
|
|
12
|
-
> **0.13.0 was the first published release.** Earlier versions were developed in-repo and never shipped, so
|
|
13
|
-
> the breaking changes in the changelog describe how this package arrived at its current behaviour rather
|
|
14
|
-
> than anything you need to migrate from.
|
|
15
|
-
>
|
|
16
|
-
> It has been reviewed twice — once by its author against written hypotheses, then by four independent
|
|
17
|
-
> agents each given one hypothesis to attack. That pass found eight further defects, including a file lock
|
|
18
|
-
> that admitted two writers into its critical section, and all of them are fixed here. The reasoning for
|
|
19
|
-
> every decision is in **[CHANGELOG.md](./CHANGELOG.md)** and in the `docs/06-decisions/` ADRs upstream.
|
|
20
|
-
>
|
|
21
|
-
> **Known gaps are stated rather than implied** — see *Status* at the end of this file. The largest is
|
|
22
|
-
> deliberate: a child granted `bash` escapes governance entirely, by decision.
|
|
23
|
-
|
|
24
|
-
## Everyday work and learning — 0.27.0 release candidate
|
|
25
|
-
|
|
26
|
-
Paired with planned **skill-harness 0.16.0**. Producer runtime is Sol-approved; feature PR #52 merged
|
|
27
|
-
with green CI at `b974963a7d0ba5a74fdafe331356c348a1fba565`. Release PR CI/merge, installed qualification
|
|
28
|
-
and publication remain pending. Release preparation changes metadata and test synchronization only,
|
|
29
|
-
not runtime or dependencies.
|
|
30
|
-
|
|
31
|
-
Start with the short installed **[PRODUCT-GUIDE.md](./PRODUCT-GUIDE.md)** and
|
|
32
|
-
**[current requirement register](./REQUIREMENTS.md)**. `/grants work` now authors/selects bounded multi-task
|
|
33
|
-
and dependent work with explicit agent/model/effort choices; `/grants host` and `/grants dashboard` show
|
|
34
|
-
outcomes, real active work and numbered controls; `/grants learning` opens retained cases, comparisons,
|
|
35
|
-
trust, quality/adoption choices and next-order settings through the loaded harness. These are source
|
|
36
|
-
implementation paths, not evidence that calibration, human acceptance or publication has occurred.
|
|
37
|
-
The historical worked-example transcripts below remain evidence for their stated versions.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
Configured runtime skills are used directly at their installed paths; setup creates no duplicate
|
|
41
|
-
`.pi/skills/` copies. Pi package/resource filters and `PI_CODING_AGENT_DIR` apply. Existing local overrides
|
|
42
|
-
and `.pi/grants.env` stay intact. Only legacy npm packages never registered with Pi are copied by init;
|
|
43
|
-
`--force` applies only to those copies. Review old local copies before removing them to use package updates.
|
|
44
|
-
|
|
45
|
-
## What this governs, and what it does not
|
|
46
|
-
|
|
47
|
-
**It governs the tool surface: which tools pi exposes to a model.** That part is structural, not advisory —
|
|
48
|
-
`--tools` is enforced by pi core, and an `-e`-loaded extension cannot re-add its own tool past it
|
|
49
|
-
(measured). A child granted `read` has no write tool, and no prompt can talk it into having one.
|
|
50
|
-
|
|
51
|
-
**It does not contain an agent that holds an execution primitive.** A child granted `bash` can run
|
|
52
|
-
`env -u PI_GRANTS_GRANT pi …` and obtain a completely ungoverned descendant — no ledger entry, no depth
|
|
53
|
-
increment, no grant. Measured, not theorised: `docs/probes/g5-bash-escape`. `env -u` is incidental; the
|
|
54
|
-
mechanism is *"the child can execute programs"*, and governance state lives in that program's environment.
|
|
55
|
-
Containing **that** is the operating system's job, and is out of scope here (**ADR-0012**).
|
|
56
|
-
|
|
57
|
-
So: **`bash` is gated by default in a governed session** — a human is asked before any child receives it —
|
|
58
|
-
and gating is closed under subsumption, so gating `write` gates `bash` too. Neither makes the escape
|
|
59
|
-
impossible. Both stop it happening silently, which is the difference that matters when the realistic threat
|
|
60
|
-
is a confused or prompt-injected agent rather than a determined one.
|
|
61
|
-
|
|
62
|
-
## The invariant
|
|
63
|
-
|
|
64
|
-
```
|
|
65
|
-
effective = ( requested ∩ parentGrant ∩ ceiling ) \ (gated \ approved)
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
Escalation is impossible **by construction**, not by policy. The root holds the full catalog, so grants are
|
|
69
|
-
free from the top; every level below can only subtract. No policy engine, no LLM on the security path.
|
|
70
|
-
|
|
71
|
-
Depth control falls out for free: spawning is itself a capability. Withhold `tool:delegate` and the child is
|
|
72
|
-
a leaf — it receives neither `delegate` nor `delegate_all`.
|
|
73
|
-
|
|
74
|
-
**Cardinality is bounded separately** (ADR-0008, amended 2026-08-12). The invariant above says what a child
|
|
75
|
-
may *hold* and nothing about how many children exist; a blocking `delegate` bounded that to one by accident,
|
|
76
|
-
and fan-out removes the accident. `PI_GRANTS_FANOUT` is a **subtree budget**: a call
|
|
77
|
-
spends from `B` before dividing the remainder among the children, so no *subtree* can exceed what its root
|
|
78
|
-
held. A per-call cap of K with depth D would still permit K^D — the same exponential wearing a smaller
|
|
79
|
-
number — so the bound is subtractive instead, and composes across processes with no shared state.
|
|
80
|
-
|
|
81
|
-
**It is not a session total, and the distinction is measurable:** the value is read once from the
|
|
82
|
-
environment and never decremented, so one session may issue successive `delegate_all` calls at the full
|
|
83
|
-
width. What is bounded is the shape of any *one* tree, not how many trees a turn builds. Bound depth with
|
|
84
|
-
`PI_GRANTS_MAX_DEPTH`; nothing bounds the number of turns.
|
|
85
|
-
|
|
86
|
-
## Why pi's `--tools` is the enforcement point
|
|
87
|
-
|
|
88
|
-
Measured, not assumed (probes 9–11 in `docs/probes/pi-fabric-eval`):
|
|
89
|
-
|
|
90
|
-
- `pi --tools read -e npm:pi-fabric` → the model **cannot** call `fabric_exec`.
|
|
91
|
-
- `pi --no-tools -e npm:pi-fabric` → likewise blocked.
|
|
92
|
-
- No flag → `fabric_exec` works.
|
|
93
|
-
|
|
94
|
-
So pi core hard-blocks extension tools, and an explicitly `-e`-loaded extension **cannot re-add its own tool
|
|
95
|
-
past the allowlist**. That is why this package needs no runtime inside the descendant: it computes the
|
|
96
|
-
allowlist and hands it to pi.
|
|
97
|
-
|
|
98
|
-
## Definitions are Agent Skills, and `allowed-tools` is the ceiling
|
|
99
|
-
|
|
100
|
-
A sub-agent is a skill you spawn. Definitions are `SKILL.md` files under pi's own skill roots — a directory
|
|
101
|
-
containing `SKILL.md` is one definition named after the **directory**, and a top-level `.md` is one named
|
|
102
|
-
after the **file**:
|
|
103
|
-
|
|
104
|
-
```
|
|
105
|
-
.pi/skills/deploy/SKILL.md project, wins on a name collision
|
|
106
|
-
~/.pi/agent/skills/review/SKILL.md global
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
```markdown
|
|
110
|
-
---
|
|
111
|
-
name: docs-writer
|
|
112
|
-
description: Fixes documentation typos.
|
|
113
|
-
allowed-tools: Read, Write
|
|
114
|
-
---
|
|
115
|
-
Fix typos in the documentation. Do not restructure anything.
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
The body becomes the child's system prompt (`--append-system-prompt`); `allowed-tools` becomes its ceiling.
|
|
119
|
-
|
|
120
|
-
| `allowed-tools` | Ceiling |
|
|
121
|
-
| :--- | :--- |
|
|
122
|
-
| **absent** | **undeclared — not spawnable at all.** The refusal names the file. |
|
|
123
|
-
| empty | nothing; a child with no tools |
|
|
124
|
-
| `Read, Write` or `Read Write` | `tool:read`, `tool:write`. Space-separated is the spec's form; commas are tolerated because it is what people type |
|
|
125
|
-
| `ext:pkg/tool`, `skill:x`, `agent:y` | passed through **as written** |
|
|
126
|
-
| anything else | lowercased and prefixed `tool:` — so `Glob` becomes `tool:glob`, which the catalog then refuses as unknown |
|
|
127
|
-
| contains a pattern, e.g. `Bash(git:*)` | **refused, not reinterpreted** |
|
|
128
|
-
|
|
129
|
-
**Two of those rows are the load-bearing ones.**
|
|
130
|
-
|
|
131
|
-
*Absent means undeclared.* Under the pi-subagents frontmatter this package used to read, a missing `tools:`
|
|
132
|
-
key meant pi's **full default toolset**, so an undeclared definition was the most powerful kind and every
|
|
133
|
-
parse failure produced a wildcard — the direction that caused R-28 and review finding F18. The sense is now
|
|
134
|
-
inverted: a typo or an unreadable YAML form costs a refusal instead of a grant.
|
|
135
|
-
|
|
136
|
-
*A sub-tool pattern is refused because every reinterpretation of it is wrong.* pi's `--tools` matches whole
|
|
137
|
-
tool names, so granting bare `bash` for `Bash(git:*)` would **widen** a deliberately narrow declaration,
|
|
138
|
-
dropping it would silently **narrow** and yield a child that mysteriously cannot work, and matching the
|
|
139
|
-
pattern inside a wrapper would be a security control implemented by string-matching a shell command.
|
|
140
|
-
|
|
141
|
-
**Identity comes from the path, never the frontmatter `name`.** pi keys skills by their directory, so
|
|
142
|
-
trusting the frontmatter lets our view and the loader's disagree about which file a name refers to. The spec
|
|
143
|
-
requires them to match anyway, so a mismatch is the file's defect and not something to honour.
|
|
144
|
-
|
|
145
|
-
## Universal capabilities
|
|
146
|
-
|
|
147
|
-
`fabric_exec` is treated as **universal** — granting it is equivalent to granting the whole catalog, because
|
|
148
|
-
it reaches `pi.write`, `pi.bash`, and unrestricted `agents.run`. This is measured, not theoretical: a child
|
|
149
|
-
granted `tools: []` (nothing at all) plus `recursive: true` still spawned a grandchild that wrote to disk.
|
|
150
|
-
|
|
151
|
-
`assertNarrowing()` therefore **throws** if a supposedly narrow grant contains one. A narrow grant with
|
|
152
|
-
`fabric_exec` in it is full authority wearing a narrow grant's clothing.
|
|
153
|
-
|
|
154
|
-
Narrowing is checked **before** the gate, and the order is load-bearing rather than stylistic: because
|
|
155
|
-
`assertNarrowing` refuses whatever a human says, the old order reported *"requires explicit approval"* for a
|
|
156
|
-
spawn that could never be approved — telling the operator to go and find a human who cannot help. For the
|
|
157
|
-
same reason **no dialog is raised** for a spawn retaining a universal capability: asking would be worse than
|
|
158
|
-
useless, since a `session`- or `always`-scoped *yes* given there is banked and reused for later spawns that
|
|
159
|
-
**do** proceed.
|
|
160
|
-
|
|
161
|
-
A delegator that legitimately holds `fabric_exec` and knowingly wants a child to have it **cannot** spawn
|
|
162
|
-
that child. `assertNarrowing`'s `allowUniversal` flag exists but is deliberately not plumbed through; the
|
|
163
|
-
first real need for that override is the evidence it should be added.
|
|
164
|
-
|
|
165
|
-
## The three tools
|
|
166
|
-
|
|
167
|
-
```
|
|
168
|
-
delegate({ task: "summarise src/", agent: "docs-writer" }) // preferred: an operator-authored definition
|
|
169
|
-
delegate({ task: "summarise src/", tools: ["read"] }) // when no definition fits
|
|
170
|
-
delegate_all({ children: [ {…}, {…}, {…} ] }) // several at once, each independently governed
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
- **Prefer `agent`.** Its capabilities *and* its instructions were written by the operator, and the session
|
|
174
|
-
must hold `agent:<name>` to name it at all. `tools:` is the escape hatch: the model chooses the tool list,
|
|
175
|
-
which is why that form can never persist an approval (see below).
|
|
176
|
-
- **You cannot grant what you do not hold.** Refusals name the capability and are recorded.
|
|
177
|
-
- **Spawning is itself a capability.** Grant `delegate` and the child can sub-delegate; withhold it and the
|
|
178
|
-
child is a leaf — the extension is only passed to children that hold it, so the machinery isn't even
|
|
179
|
-
present. `PI_GRANTS_MAX_DEPTH` remains a backstop.
|
|
180
|
-
- **A refusal is a tool *error*, not an answer.** All three tools throw, because `AgentToolResult` has **no
|
|
181
|
-
`isError` field** — pi sets it only when `execute` throws, and a normal return is hardcoded
|
|
182
|
-
`isError: false`. Until 0.5.0 the tool returned `isError: true`, which was silently discarded, so every
|
|
183
|
-
refusal this package made was recorded by pi as a **successful** tool call. Found by the integration suite
|
|
184
|
-
on its first run.
|
|
185
|
-
- **A child cannot outlive or overwhelm you.** Output is capped (1 MiB), there is a wall-clock timeout
|
|
186
|
-
(`PI_GRANTS_CHILD_TIMEOUT`, default 1200s) with `SIGTERM` → `SIGKILL` escalation so a child cannot ignore
|
|
187
|
-
its way past it, an abort is honoured even if it arrived before the spawn, and a child that exits
|
|
188
|
-
non-zero, times out or is cancelled comes back as a **tool error naming which** — not as an answer.
|
|
189
|
-
- **Fan-out stays bounded and waits for all by default.** At most 8 children per call, and the subtree budget
|
|
190
|
-
bounds the whole tree. Every child uses the same plan-gate-audit path. The opt-in
|
|
191
|
-
`completion:"primary", primary:N` form returns when that one-based child settles while the original
|
|
192
|
-
session retains bounded role/outcome accounting for its shadows; `/grants variants` displays it and explicitly
|
|
193
|
-
labels child provider usage unavailable because the print transport retains no Pi `Usage` event. Fan-out,
|
|
194
|
-
output bytes and wall time remain controller-bounded. Shadow failure or later cancellation cannot replace/delay the primary result. This is not detached job recovery:
|
|
195
|
-
process exit ends ownership, and there is no retry, acceptance, winner selection or result-text store.
|
|
196
|
-
- **One child can be refused while its siblings succeed**, and every outcome is reported. A fan-out that
|
|
197
|
-
hid its refusals would let an orchestrator summarise four reviews when only three happened.
|
|
198
|
-
|
|
199
|
-
**Verified live, with a real model** (`test-integration/delegation.it.ts`):
|
|
200
|
-
|
|
201
|
-
| Scenario | Result |
|
|
202
|
-
| :--- | :--- |
|
|
203
|
-
| Holds `read,write,delegate`; delegates `tools:["read"]`; child told to write a file | **No file exists.** `--tools` is the enforcement point and this is what it buys |
|
|
204
|
-
| Holds `read,delegate`; tries `tools:["read","write"]` | Tool **error**: `cannot grant tool:write — this session does not hold it (capability escalation blocked)`; ledger `denied:["tool:write"]`, `blocked:true` |
|
|
205
|
-
| `PI_GRANTS_LEDGER` pointed somewhere unwritable | Delegation **refused** — asking for an audit trail makes it a precondition |
|
|
206
|
-
|
|
207
|
-
### Three ways to delegate
|
|
208
|
-
|
|
209
|
-
| Tool | Shape |
|
|
210
|
-
| :--- | :--- |
|
|
211
|
-
| `delegate` | one sub-agent |
|
|
212
|
-
| `delegate_all` | several **at once**, independent and unaware of each other |
|
|
213
|
-
| `delegate_chain` | several **in order**, each receiving the previous one's output |
|
|
214
|
-
|
|
215
|
-
A chain's handoff is wrapped in a labelled, **nonce-delimited** fence, so the previous agent's output arrives as
|
|
216
|
-
data — and because the nonce is minted after that agent finished, it cannot forge a closing delimiter to escape its
|
|
217
|
-
own fence. The label itself is framing and this README will not pretend otherwise; the nonce is the mechanism.
|
|
218
|
-
|
|
219
|
-
A legacy uncorrelated chain is **gated upfront**: every step is planned first, and every approval it needs is
|
|
220
|
-
asked for before the first step starts. Exact correlated steps gate only after their composed task exists;
|
|
221
|
-
binding a template and spending it on different generated instructions would be false assurance. One dialog
|
|
222
|
-
per capability and definition names the step that needs it. Decline an upfront gate and nothing runs. A step
|
|
223
|
-
that could never run refuses before anyone is asked; `Allow once` covers exactly the step it named. A failed
|
|
224
|
-
step stops the rest, and you still get everything completed—except `BLOCKED_CRITICAL_ASSURANCE`, which
|
|
225
|
-
remains a failed tool call. Each step spends one unit of the fan-out budget.
|
|
226
|
-
|
|
227
|
-
### Two executors, one plan
|
|
228
|
-
|
|
229
|
-
Either a captured child process, or a visible, attachable **herdr** pane — the same governed argv, the same
|
|
230
|
-
`--tools` enforcement, somewhere you can watch it.
|
|
231
|
-
|
|
232
|
-
**Which one runs is decided by a probe (ADR-0031).** `PI_GRANTS_HERDR` is three-state: **unset** probes once at
|
|
233
|
-
session start (`herdr tab list`, 2s bound) and uses panes if a server *answers*; **`1`** demands herdr and
|
|
234
|
-
**refuses every delegation** if it is unreachable, rather than quietly relocating; **`0`** demands subprocesses and
|
|
235
|
-
skips the probe. Which one was chosen is printed at session start, shown by `/grants`, and recorded per child in
|
|
236
|
-
the ledger.
|
|
237
|
-
|
|
238
|
-
Still **never auto-detected from `herdr` being on `PATH`** — a binary with no server behind it would make every
|
|
239
|
-
delegation fail at `tab create`, on a path nobody chose. Only a reachable server counts.
|
|
240
|
-
|
|
241
|
-
A child's pane goes in **your own herdr workspace** by default, so switching to one is a tab away. Constraints found by building it are in `docs/probes/g16-herdr` — herdr has
|
|
242
|
-
no `--env` (the grant rides on the pane, which the agent's shell inherits), `agent start` types argv into a
|
|
243
|
-
shell so a multi-line argument must be staged to a file, and `agent wait --until idle` matches the state the
|
|
244
|
-
agent was *already* in, so settling requires a state counter to advance.
|
|
245
|
-
|
|
246
|
-
### Persistent Herdr dashboard
|
|
247
|
-
|
|
248
|
-
When this pi process is itself hosted inside Herdr 0.8+, `/grants dashboard` opens a managed right split:
|
|
249
|
-
|
|
250
|
-
```text
|
|
251
|
-
PI-DADDY
|
|
252
|
-
◆ principal-feature · critical · declared
|
|
253
|
-
● plan running 0:42 · pane w7:p13
|
|
254
|
-
└─ ⛔ deploy refused 0:00
|
|
255
|
-
|
|
256
|
-
depth 2 · 1 active
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
The plugin ships inside pi-daddy and is linked globally only after an explicit **Install and open** choice.
|
|
260
|
-
Literal **Not now** and **Never ask** choices are persisted; dismissing or losing the dialog stores nothing.
|
|
261
|
-
If the same plugin ID points at another package root after an isolated install or upgrade, startup offers an
|
|
262
|
-
explicit **Relink and open** repair. **Not now** or dismissal leaves both the existing link and prompt preference
|
|
263
|
-
unchanged; protocol mismatches are not replaced by guesswork.
|
|
264
|
-
A connected host can publish exact pre-authorized actions as short commands such as `pause-new-dispatch` or `defer-weekly`; the dashboard lists their human labels and accepts the key followed by Enter. The host resolves the key to its current CAS-bound request, so a person does not type JSON or tokens. Unknown/stale keys refuse before effects; raw JSON remains compatibility-only.
|
|
265
|
-
|
|
266
|
-
For the planned pi-daddy 0.27.0 / skill-harness 0.16.0 pair, start a fresh Pi session after installing the qualified releases (the immutable harness bridge survives `/reload`), declare work, then run `/grants host <fresh-id>`. Library hosts can use the explicit `pi-daddy/daily-dashboard-host` export. This creates one process-owned daily host, captures the current work/facts sources, publishes its private socket to `/grants dashboard`, and lists `pause-new-dispatch` or `resume-dispatch` plus `refresh-current-work`. Compatible recorded P01 snapshots and selected obligations also become labelled scope-successor, alternative, and put-first actions; choosing one still passes exact intent authority and host/selection/tip CAS, then atomically rebinds both persisted and current-session declared work before new ordinary dispatch is released. Refresh is a deliberate action that atomically mirrors the current declared ledger and advances the existing source checkpoint; periodic dashboard redraw remains read-only. Pausing blocks only new governed ordinary children; a child already running keeps its original caller/result. An active retained child also gets an exact `cancel-exec-…` action (up to the ordinary eight-child width); choosing it requests abort through the original handle without cancelling siblings or implying acceptance/rejection. `/grants host closing` declares two minutes of explicit closing presence; only a paused, reservation-free, ordinary-quiescent host offers case-card preparation, and absent trust qualification defers without spending the five-card budget. `/grants host stop` refuses while paused, busy, pending or acknowledgement-unknown: resume new work in the original dashboard first, and reconcile pending controls explicitly. Refusal preserves the original host/socket; unknown effects are never silently released. A successful stop closes the host and never cancels a child. Restart uses a fresh id; no PID, user-entered JSON/CAS envelope or prior controller is recovered.
|
|
267
|
-
|
|
268
|
-
The separate `pi-daddy/measured-order` export composes no-tool measured Sol/Terra sessions into a bounded dependent order. Every retry and deterministic output contract is predeclared; bounded JSON projection contracts admit free-form prose without pre-knowing the whole artifact hash, and dependent prompts consume the actual retained predecessor output with its observed seal. A reopened controller treats another owner's unfinished claim as unknown and cannot replay it; an independently authorized exact acknowledgement can consume that schedule position, but never refunds or settles the original resource reservation. See ADR-0072.
|
|
269
|
-
|
|
270
|
-
The final candidate requirement/code/evidence index and exact unresolved human actions are in [`docs/FINAL-READINESS-INDEX.md`](../../docs/FINAL-READINESS-INDEX.md).
|
|
271
|
-
|
|
272
|
-
`/grants dashboard` never installs silently and prints the exact manual command when the plugin is absent. It
|
|
273
|
-
checks the bundled plugin root and protocol before suggesting that a disabled plugin be enabled. Panes and
|
|
274
|
-
ledgers stay workspace/tab-specific: reuse rechecks the pane's current workspace/tab, a wrong-host open is
|
|
275
|
-
closed and rejected, and malformed nested pane state refuses rather than risking a duplicate. A stored entry's
|
|
276
|
-
workspace/tab/ledger must also agree with its hash key before reuse. Invocation `cwd` sets the first pane
|
|
277
|
-
process directory but is not pane identity, so the same workspace/tab/ledger still reuses one pane across caller directories. Opening uses a right split targeted at this pi pane with `--no-focus`.
|
|
278
|
-
|
|
279
|
-
The view is a read-only ledger projection. Yellow is authorised/starting/running, green completed, red failed
|
|
280
|
-
or refused, and grey incomplete/historical. Old completed subtrees collapse; active ancestry stays visible.
|
|
281
|
-
It never displays task text, prompts, tool arguments, child output, or raw corrupt lines. Displayed ledger
|
|
282
|
-
values must satisfy the v3 identifier grammars (unsafe frozen-v2 values are redacted), and Unicode C1/bidi or
|
|
283
|
-
other control/format characters are removed before terminal output.
|
|
284
|
-
|
|
285
|
-
Provenance markers are explicit: **P** planned phase, **O** observed inline activity, **V**
|
|
286
|
-
controller-validated transition, **E** pi-daddy-enforced child, **D** caller-declared correlation. A principal
|
|
287
|
-
run can label itself through `run_id`, `phase`, effective assurance and `policy_label`; pi-daddy does not parse
|
|
288
|
-
principal workflow prose or invent pending/completed phases.
|
|
289
|
-
|
|
290
|
-
## Approving a gated capability
|
|
291
|
-
|
|
292
|
-
`gated` capabilities are ones a session holds but may not pass on without a human saying so.
|
|
293
|
-
|
|
294
|
-
```
|
|
295
|
-
grants: approve tool:bash for deploy?
|
|
296
|
-
task: roll out the staging build
|
|
297
|
-
|
|
298
|
-
> Deny
|
|
299
|
-
Allow once
|
|
300
|
-
Allow for this session
|
|
301
|
-
Always allow in this project (30 days)
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
**What a yes is *about* differs by call form, and that decides which scopes are offered.**
|
|
305
|
-
|
|
306
|
-
- **`delegate({agent: X})`** is approved against **`X` itself** — an operator-authored file the session must
|
|
307
|
-
hold `agent:X` to name at all. That is a human-authored subject, so `always` is on offer.
|
|
308
|
-
- **`delegate({tools: […]})`** is approved against the constant `<delegate>` and is offered only `once` and
|
|
309
|
-
`session`. The only things naming that child are the task and the tool list, both model-chosen, and **a
|
|
310
|
-
key the model controls is not a key.**
|
|
311
|
-
|
|
312
|
-
**A persisted approval is void the moment what it was granted for changes.** It pins both the definition's
|
|
313
|
-
`allowed-tools` and its body digest, and `/grants approvals` reports *which* check failed rather than
|
|
314
|
-
silently showing fewer rows:
|
|
315
|
-
|
|
316
|
-
| Verdict | Means |
|
|
317
|
-
| :--- | :--- |
|
|
318
|
-
| `type-changed` | `allowed-tools` gained or lost a capability after approval |
|
|
319
|
-
| `instructions-changed` | the tools are untouched but the **body** was rewritten — or the entry carries no body pin at all, which fails closed |
|
|
320
|
-
| `expired` | past its 30 days. An unparseable expiry is treated as expired: a cache we cannot read the expiry of is a cache we do not trust |
|
|
321
|
-
| `foreign-cwd` | the entry belongs to another directory. Nobody in *this* checkout was asked |
|
|
322
|
-
| `type-missing` | the definition was deleted or renamed, and a new file could later claim the name |
|
|
323
|
-
|
|
324
|
-
**The store lives outside the governed workspace**, one file per governed directory under
|
|
325
|
-
`$PI_CODING_AGENT_DIR/grants-approvals/` (default `~/.pi/agent/`). It used to sit at `<cwd>/.pi/grants-approvals.json`, which was self-defeating in
|
|
326
|
-
this package's own recommended configuration: `PI_GRANTS_GATED=tool:write` means *"may use write, may not
|
|
327
|
-
pass it down without a human"* — and **a session that may use `write` can write the approvals file.** A
|
|
328
|
-
reviewer forged an entry end to end, including a matching definition so the ceiling compared equal, and got
|
|
329
|
-
a ledger line reading `approvalSource: "persisted"` that was indistinguishable from a real approval. A
|
|
330
|
-
legacy in-workspace file is **ignored, not migrated**, with a warning naming it: importing it would import
|
|
331
|
-
exactly the entries the move exists to stop trusting. This does **not** defend against a child holding
|
|
332
|
-
`bash` (ADR-0012); it closes the self-defeating case, not a boundary the package does not have.
|
|
333
|
-
|
|
334
|
-
Writes are atomic (temp file plus `rename`, in the same directory so the rename really is atomic) and refuse
|
|
335
|
-
to follow a symlink, so a crash or a concurrent writer cannot leave a half-written file, and a corrupt file
|
|
336
|
-
cannot make the next legitimate write destroy every other entry.
|
|
337
|
-
|
|
338
|
-
**Other properties worth knowing:**
|
|
339
|
-
|
|
340
|
-
- **Legacy session/always approvals ride down the tree with the grant**, intersected with what each child
|
|
341
|
-
actually receives, so `approved ⊆ grant` holds at every level. `once` is dropped. A correlated approval
|
|
342
|
-
instead binds the exact definition, task, requested/effective sets, workspace/context and parent, and
|
|
343
|
-
never crosses a delegation boundary — approval for one probe cannot become subtree authority.
|
|
344
|
-
- **Concurrent callers share one dialog per `capability@subject`, but only share the *answer* when it was
|
|
345
|
-
about more than one spawn.** `session`, `always`, a decline and an error answer everyone; **a `once` is
|
|
346
|
-
consumed by exactly one caller** and the rest are asked their own question. Measured before the fix: four
|
|
347
|
-
concurrent delegations gating `tool:bash`, one dialog, one click of *Allow once* → four grants, with the
|
|
348
|
-
human having seen only the first caller's task.
|
|
349
|
-
- **Holding `tool:*` is authority to grant widely, never authority to skip a human.** A gate is the
|
|
350
|
-
operator's, not the delegator's. A wildcard holder reaches the ordinary dialog like anyone else.
|
|
351
|
-
- **A child can never be asked anything.** It runs `--print` with no interactive user, so a gate it hits has
|
|
352
|
-
only two outcomes: satisfied by an inherited approval, or refused with a reason naming the fix. This is
|
|
353
|
-
pi's own behaviour — non-interactive modes install a no-op UI context whose `select` resolves `undefined`
|
|
354
|
-
— so a background delegation hitting a gate is refused, not hung.
|
|
355
|
-
- **The ledger distinguishes three flavours of "no"**: `denied` (an agent asked for more than it holds — an
|
|
356
|
-
escalation attempt), `humanDenied` (a person was asked and declined — working as designed), and
|
|
357
|
-
`gatedBlocked` with no `approvalSource` (nobody was there to ask — an operator should pre-approve).
|
|
358
|
-
`humanDenied` is set only for a genuine decline, never for a dismissal, a timeout, or a dialog error —
|
|
359
|
-
those get their own outcome kinds so a caller can tell them apart.
|
|
360
|
-
|
|
361
|
-
```
|
|
362
|
-
/grants approvals list them, with why any are being ignored
|
|
363
|
-
/grants revoke tool:bash@deploy take one back
|
|
364
|
-
/grants revoke --all
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
**Pruning is lazy and scoped to one project.** Entries are validated on read and removed only on write, so
|
|
368
|
-
an expired or type-changed entry lingers in the file until the next approval or revoke. It cannot reach
|
|
369
|
-
another project: since ADR-0020 each governed directory has its own file, which is what makes
|
|
370
|
-
`/grants revoke --all` mean *this project* rather than *this machine*.
|
|
371
|
-
|
|
372
|
-
### Verified live, end to end
|
|
373
|
-
|
|
374
|
-
The whole lifecycle is exercised by `test-integration/approval.it.ts` against a real pi process, and its
|
|
375
|
-
model tier watches a real model, a real dialog and a real file. In one test, in this order: the model called
|
|
376
|
-
`delegate({agent: "bash-user"})`; the dialog was raised naming the **definition** as its subject with
|
|
377
|
-
*Always allow* on offer; the entry landed on disk pinning the ceiling *and* the body digest; the ledger
|
|
378
|
-
recorded `approvalScope: "always"`, `approvalSource: "prompt"`; a **different pi process** then ran the same
|
|
379
|
-
delegation with **zero dialogs** and a ledger line reading `approvalSource: "persisted"`; and after
|
|
380
|
-
rewriting the body — frontmatter byte-identical, so only the digest can catch it — the dialog was raised
|
|
381
|
-
again and the dismissed delegation failed.
|
|
382
|
-
|
|
383
|
-
Seven further tests in that file cost no model tokens and cover the reload and every void reason above.
|
|
384
|
-
|
|
385
|
-
**What this does not establish.** Dialogs are driven through `pi --mode rpc`, which is the same
|
|
386
|
-
`ctx.ui.select` call the TUI dialog serves; **the TUI's own rendering is not exercised.** The earlier
|
|
387
|
-
transcripts in `docs/probes/approval-ux` describe an interceptor path that no longer exists — they are kept
|
|
388
|
-
as the record of that run and are not a description of this version.
|
|
389
|
-
|
|
390
|
-
## Runtime enforcement for external controllers (0.18.0)
|
|
391
|
-
|
|
392
|
-
All fields are optional; existing callers behave unchanged.
|
|
393
|
-
|
|
394
|
-
- `correlation` carries join-only run/task/workspace/context IDs, opaque policy metadata, base/head/tree SHAs
|
|
395
|
-
and sequence floors. Supplied IDs/digests never authorize; trusted digests are computed separately.
|
|
396
|
-
- `workspace: {workspace_id, access}` resolves through `PI_GRANTS_WORKSPACE_REGISTRY`, validates a canonical
|
|
397
|
-
Git worktree root, and sets initial CWD. A caller cannot label a write-capable grant read-only. Kernel
|
|
398
|
-
util-linux `flock` allows one **pi-daddy-governed** writer per canonical root; `setpriv --pdeathsig` plus
|
|
399
|
-
helper attachment stops the writer process or herdr tab on parent death before release. This does not confine paths or exclude unrelated writers; `bash` remains an escape.
|
|
400
|
-
|
|
401
|
-
**BREAKING in 0.19.0 — routing now requires a capability.** A delegation naming `workspace_id: W` needs
|
|
402
|
-
`workspace:W` in the caller's grant, or it is refused `WORKSPACE_NOT_AUTHORIZED`. Every grant that routes
|
|
403
|
-
must add it: `PI_GRANTS_GRANT="tool:read,tool:delegate,workspace:W"`. `pi-daddy init` lists the registered
|
|
404
|
-
ids commented in `.pi/grants.env`. A child can only route on to ids it was granted itself, so this is also
|
|
405
|
-
the list of what any descendant could reach; `workspace:*` exists but is held and never inherited, which
|
|
406
|
-
makes it the wrong answer for anything but a single-worktree setup. `PI_GRANTS_GATED=workspace:W` asks a
|
|
407
|
-
human first. Enforced by pi-daddy before the spawn, not by pi's `--tools` — see `docs/SPEC.md` on the
|
|
408
|
-
enforcement classes.
|
|
409
|
-
|
|
410
|
-
**BREAKING in 0.19.0 — a registry id must match `[A-Za-z0-9][A-Za-z0-9._/-]*`.** An id is now the tail of a
|
|
411
|
-
capability id, so it has to survive the grant grammar. **Slashes and dots are fine**, so a worktree named
|
|
412
|
-
after its branch (`feature/x`) works. Refused, with the file and the id named: whitespace (it splits a
|
|
413
|
-
definition's `allowed-tools`), commas and newlines (they split a grant), `*` (it collided with
|
|
414
|
-
`workspace:*`), shell metacharacters (they reach a generated file you are told to paste from), non-ASCII,
|
|
415
|
-
and `@ + % = ^ ! ? ~ { } [ ]` or a leading `_`, `-` or `.`. **One bad entry refuses the whole registry**, so
|
|
416
|
-
rename before upgrading. The regex is the specification; that list is a summary.
|
|
417
|
-
|
|
418
|
-
**Also new in 0.19.0:** the registry must be a **regular file under 1 MiB**. A FIFO or device there would
|
|
419
|
-
block session start rather than fail, and the read is bounded so a file that grows after its size is checked
|
|
420
|
-
is refused rather than allocated. What is *not* checked: ownership, permissions, and whether a descendant
|
|
421
|
-
holding a write tool repointed an entry — routing attenuates by **id**, not by **destination**
|
|
422
|
-
(`docs/probes/g37-registry-tamper`, tracked as R-137).
|
|
423
|
-
- Refusals retain current prose and add stable codes such as `CAPABILITY_ESCALATION`,
|
|
424
|
-
`GATED_UNAPPROVED`, `APPROVAL_SCOPE_MISMATCH`, and `WORKSPACE_WRITE_CONFLICT`.
|
|
425
|
-
- Ledger v3 adds unique execution/parent identity, joinable capability/lease/lifecycle/check events, and
|
|
426
|
-
provenance-labelled workflow facts while retaining frozen v2 and legacy readers.
|
|
427
|
-
- `pi-daddy/check-runner` selects an operator-named absolute executable+argv definition, never a shell
|
|
428
|
-
command string. Check IDs use the v3 ASCII identifier alphabet and are refused before execution if they do
|
|
429
|
-
not fit their generated receipt identity. It strips sensitive inherited environment, enforces timeout/output caps, executes a
|
|
430
|
-
private copy of the exact executable bytes it hashed, and pre/post-verifies Git head/candidate-tree
|
|
431
|
-
identity under an exclusive coordination lease. The executable remains arbitrary code; no filesystem or
|
|
432
|
-
network sandbox is claimed.
|
|
433
|
-
|
|
434
|
-
Public subpaths: `pi-daddy/correlation`, `pi-daddy/refusals`, `pi-daddy/workspace`,
|
|
435
|
-
`pi-daddy/check-runner`.
|
|
436
|
-
|
|
437
|
-
### Canonical ledger v3 contract
|
|
438
|
-
|
|
439
|
-
Machine consumers should import or resolve
|
|
440
|
-
`pi-daddy/contracts/ledger/v3/ledger-event.schema.json`, not infer a format from prose. Generated fixtures for
|
|
441
|
-
all five events are adjacent. v3 adds globally unique `executionId`, explicit `parentExecutionId`, bounded
|
|
442
|
-
start deadlines, optional Herdr pane identity, and provenance-labelled workflow facts. `childId` remains the
|
|
443
|
-
readable logical tree position and is never an occurrence join.
|
|
444
|
-
|
|
445
|
-
Dispatch on version before event: no version/discriminator is a legacy 0.17 grant record; explicit v2 uses the
|
|
446
|
-
frozen published v2 contract; explicit v3 uses the new closed contract; every other explicit version fails
|
|
447
|
-
closed and is never read as legacy. `verifyLedger` and the dashboard share exact runtime v3 validation, so a
|
|
448
|
-
lookalike string version, missing join identity or malformed nested correlation cannot be `OK` in one and
|
|
449
|
-
corrupt in the other. Explicit v2 is checked against its exact frozen schema before the dashboard labels it
|
|
450
|
-
historical; malformed v2 never becomes a grey row or orphan count. A field/event/enum/requiredness or semantic change requires another ledger version. See
|
|
451
|
-
`contracts/ledger/v3/README.md`; the v2 path remains available unchanged.
|
|
452
|
-
|
|
453
|
-
## Running it
|
|
454
|
-
|
|
455
|
-
```bash
|
|
456
|
-
# `agent:` ids say WHICH definitions this session may spawn (0.8.0); `tool:` ids say what it may grant them.
|
|
457
|
-
PI_GRANTS_GRANT="agent:review,tool:read,tool:grep,tool:find,tool:ls,tool:delegate" \
|
|
458
|
-
PI_GRANTS_LEDGER=.pi/grants.jsonl \
|
|
459
|
-
PI_GRANTS_MAX_DEPTH=2 \
|
|
460
|
-
pi
|
|
461
|
-
# The relative ledger is resolved once at session start and inherited as one absolute path,
|
|
462
|
-
# so routed descendants changing cwd still append to this tree.
|
|
463
|
-
```
|
|
464
|
-
|
|
465
|
-
**Plain `pi`, no `-e`, when you installed this from npm** — the package declares `pi.extensions` and pi
|
|
466
|
-
auto-loads it (verified by execution). `-e ./extensions/grants.ts` is for running from a **clone** of the
|
|
467
|
-
repository, where there is no `node_modules/pi-daddy` for pi to find.
|
|
468
|
-
|
|
469
|
-
`/grants` shows the session's grant, its depth, the catalog by kind, and an allow/BLOCK verdict per known
|
|
470
|
-
definition — computed by **the same function a real spawn uses**, so the diagnostic cannot disagree with the
|
|
471
|
-
enforcer. That is not cosmetic, and it has been got wrong twice. R-28 was a `/grants` that reported "allow"
|
|
472
|
-
for spawns the enforcement path refused with a reason misstating the definition file. **R-38 was the same
|
|
473
|
-
shape one layer up**: the listing shared the *planner* with enforcement but not the *sequence*, so a
|
|
474
|
-
definition covered by a valid persisted approval was reported as blocked while a real spawn proceeded with
|
|
475
|
-
no human in the loop. Both paths now go through one `planWithApprovals`, differing in a single argument —
|
|
476
|
-
the preview never asks a human and never claims one is missing — and an `allow` that rests on a standing
|
|
477
|
-
approval says so:
|
|
478
|
-
|
|
479
|
-
```
|
|
480
|
-
allow deploy tool:bash, tool:read (tool:bash approved: persisted)
|
|
481
|
-
BLOCK undeclared — agent "undeclared" declares no `allowed-tools`, so it cannot be spawned — add
|
|
482
|
-
one to …/.pi/skills/undeclared/SKILL.md. An undeclared capability set is treated
|
|
483
|
-
as NONE, never as everything.
|
|
484
|
-
```
|
|
485
|
-
|
|
486
|
-
`/grants dashboard` verifies that this exact pi PID is hosted in its declared Herdr pane, verifies the ledger
|
|
487
|
-
and plugin, then opens or reuses a right split without changing focus. `/grants ledger` reads the audit file
|
|
488
|
-
back and reports its integrity — record count, escalation attempts, any unparseable lines with line numbers
|
|
489
|
-
and content-free reasons (never copied ledger bytes), and **which instructions actually ran**: records grouped by definition
|
|
490
|
-
digest, each compared against the file on disk (`current` / `CHANGED since`), which is what makes ADR-0018's
|
|
491
|
-
`definitionDigest` answerable rather than decorative. It exists because nothing in this package had ever read a ledger
|
|
492
|
-
back, so a torn line was indistinguishable from a spawn that never happened. A corrupt line is **evidence**
|
|
493
|
-
and is left alone rather than repaired. Session start checks integrity automatically; `/grants ledger` gives
|
|
494
|
-
the full report.
|
|
495
|
-
|
|
496
|
-
## Worked example: governing `principal-pi-skills`
|
|
497
|
-
|
|
498
|
-
The abstract examples above use invented definitions. This one uses the seven skills people actually have
|
|
499
|
-
installed. Every transcript below is **copied from a run**, not retyped — the run is
|
|
500
|
-
`docs/probes/b2-init-principal-pi-skills` (2026-08-17, `principal-pi-skills@2.3.1`, pi 0.84.1), and where
|
|
501
|
-
this section abridges output it says so.
|
|
3
|
+
Capability governance and coordination for [pi](https://github.com/badlogic/pi-mono)'s multi-level agent system. An
|
|
4
|
+
orchestrator grants each sub-agent a deliberate subset of what it holds and withholds the rest; a sub-agent may delegate
|
|
5
|
+
further, but only ever a subset of what it holds. Enforcement is pi's own `--tools` allowlist on a separate child
|
|
6
|
+
process, with an append-only, hash-chained ledger of every grant and refusal.
|
|
502
7
|
|
|
503
8
|
```bash
|
|
504
9
|
pi install npm:pi-daddy
|
|
505
|
-
pi
|
|
506
|
-
pi # then, inside pi:
|
|
507
|
-
/grants init
|
|
508
|
-
```
|
|
509
|
-
|
|
510
|
-
**`pi install`, not `npm install`** — it registers the package with pi, which is what makes the extension
|
|
511
|
-
auto-load; presence in `node_modules` alone does nothing. `/grants init` asks only about the capabilities
|
|
512
|
-
that can change your machine and applies the answer to the running session, no restart (ADR-0030). That one
|
|
513
|
-
project opt-in now also enables `.pi/grants.jsonl` immediately and for every later plain `pi` start
|
|
514
|
-
(ADR-0037), so `/grants ledger` and `/grants dashboard` need no shell export. Merely installing the package
|
|
515
|
-
does not initialize unrelated directories. `npx pi-daddy init` does the same scaffolding from a shell, and
|
|
516
|
-
both search pi's install root as well as the project's. A pre-0.21 stored grant is not retroactive recording
|
|
517
|
-
consent; run `/grants init` once after upgrading to enable its default ledger.
|
|
518
|
-
|
|
519
|
-
```
|
|
520
|
-
found principal-pi-skills@2.3.1 — 7 skill(s), 0 declaring allowed-tools
|
|
521
|
-
wrote .pi/skills/decide/SKILL.md
|
|
522
|
-
… six more `wrote` lines, one per skill …
|
|
523
|
-
wrote .pi/grants.env
|
|
524
|
-
|
|
525
|
-
7 skill(s) declare no allowed-tools and cannot be spawned until they do: decide, architect, plan,
|
|
526
|
-
build, review, debug, git-ops. Each copy carries a commented `allowed-tools:` line. pi-daddy does
|
|
527
|
-
not choose ceilings — that decision is what you review and commit, so it is yours to write.
|
|
528
|
-
|
|
529
|
-
Live grant (1 capabilities): tool:delegate
|
|
530
|
-
```
|
|
531
|
-
|
|
532
|
-
**That is the honest state today, and the zero is the interesting number.** `principal-pi-skills@2.3.1` —
|
|
533
|
-
the published version — declares `allowed-tools` on none of its seven skills, so none of them is spawnable
|
|
534
|
-
and `init` says so rather than inventing capability sets to make its output look better. (It is being fixed
|
|
535
|
-
at the source, in their PR #30; until that ships, this is what `npm install` gives you.) `init` did the
|
|
536
|
-
mechanical work — seven directories, seven copies, the grant file — and left the one decision that has to be
|
|
537
|
-
a human's.
|
|
538
|
-
|
|
539
|
-
You make it, in the file. This is the copy `init` wrote for `decide`, with its commented block elided, and
|
|
540
|
-
the ceiling is the one `principal-pi-skills` PR #30 settled on by re-deriving it from the skill's own body:
|
|
541
|
-
|
|
542
|
-
```diff
|
|
543
|
-
---
|
|
544
|
-
name: decide
|
|
545
|
-
description: >
|
|
546
|
-
Use when a decision needs making …
|
|
547
|
-
# pi-daddy: this skill declares no `allowed-tools`, so it CANNOT be spawned as a governed sub-agent —
|
|
548
|
-
… four more comment lines …
|
|
549
|
-
- # allowed-tools: <list the tools this skill needs, e.g. Read, Grep>
|
|
550
|
-
+ allowed-tools: read, grep, find, ls
|
|
551
|
-
---
|
|
552
|
-
```
|
|
553
|
-
|
|
554
|
-
and in `.pi/grants.env`, whose `PI_GRANTS_GRANT` line `init` wrote as `"tool:delegate"` — you add the rest:
|
|
555
|
-
|
|
556
|
-
```sh
|
|
557
|
-
export PI_GRANTS_GRANT="agent:decide,tool:read,tool:grep,tool:find,tool:ls,tool:delegate"
|
|
10
|
+
pi
|
|
558
11
|
```
|
|
559
12
|
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
13
|
+
`/grants` shows the session's ceiling and spawnable definitions; `/grants init` writes `.pi/pi-daddy/settings.json`,
|
|
14
|
+
the one reviewable file you commit. A definition is an [Agent Skills](https://agentskills.io/specification) `SKILL.md`
|
|
15
|
+
whose `allowed-tools` is the ceiling and whose body is the child's system prompt.
|
|
563
16
|
|
|
564
17
|
```
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
git-ops (needs agent:git-ops); plan (needs agent:plan); review (needs agent:review)
|
|
569
|
-
```
|
|
570
|
-
|
|
571
|
-
The second line is the one worth having. A `decide` sub-agent that **physically cannot write** is a
|
|
572
|
-
different object from one that has been asked not to — and now that is enforced by `--tools` rather than
|
|
573
|
-
requested in prose. The other six are visibly withheld, each naming its own missing capability, which is the
|
|
574
|
-
difference between *governance is working* and *did the install fail?*
|
|
575
|
-
|
|
576
|
-
**`decide` and not `review`, and the reason is worth a sentence.** An earlier version of this section used
|
|
577
|
-
`review` as the read-only example and sourced that to its description saying *"Reports findings; never
|
|
578
|
-
edits"* — **a string that appears nowhere in `principal-pi-skills`**. It was invented for a demo file in
|
|
579
|
-
this repository and then cited back as their evidence. `review`'s real ceiling, settled upstream from its
|
|
580
|
-
body, is `read, grep, find, ls, bash`: it creates a disposable worktree and runs the tests, and denied
|
|
581
|
-
`bash` every verdict it returns is `UNVERIFIED`. The structurally read-only tier is `decide`, `architect`
|
|
582
|
-
and `plan`.
|
|
583
|
-
|
|
584
|
-
**Capabilities that can change your machine are written commented** (ADR-0029). When the seven skills do
|
|
585
|
-
declare their ceilings, `init` puts `tool:read`, `tool:grep` and friends in the live grant and writes
|
|
586
|
-
`tool:bash`, `tool:write` and `tool:edit` — plus the `agent:` ids of the definitions that need them — as
|
|
587
|
-
commented lines naming who asked for what. `init` + `source` gives you a working read-only setup; the wide
|
|
588
|
-
half costs one deliberate uncomment. The reason is that `PI_GRANTS_GRANT` is what *bounds* a declared
|
|
589
|
-
ceiling, so generating it from those same ceilings would give the bound and the bounded one author, and it
|
|
590
|
-
would not be you.
|
|
591
|
-
|
|
592
|
-
Two things this example does **not** claim. pi-daddy governs which **tools**, never which **paths**: a
|
|
593
|
-
`Write(docs/**)` is refused rather than reinterpreted, so *"an architect that may write an ADR but not your
|
|
594
|
-
source"* is not expressible — the honest choice is between a document-producing agent with real write power
|
|
595
|
-
and a read-only one that hands its output back for the parent to write. And the ceilings above are an
|
|
596
|
-
example, not a recommendation: what each skill needs is the skill author's call.
|
|
597
|
-
|
|
598
|
-
### The tripwire
|
|
599
|
-
|
|
600
|
-
In a **governed** session the `tool_call` hook refuses third-party spawn tools (`Agent`, `subagent`,
|
|
601
|
-
`spawn_agent`) and records the refusal, because such a spawn would create a descendant this package did not
|
|
602
|
-
provision, does not bound by depth, and does not record. Installing such an extension is a single command,
|
|
603
|
-
so refusing is cheap and silence is not.
|
|
604
|
-
|
|
605
|
-
**It is a tripwire, not a boundary, and the difference is measured:** `subagents:rpc:spawn` reaches
|
|
606
|
-
`manager.spawn()` over the event bus and never produces a `tool_call` at all (ADR-0013 Finding 6), so a
|
|
607
|
-
tool-name check cannot see it. It catches the ordinary case loudly. It is not containment.
|
|
608
|
-
|
|
609
|
-
**Governance is opt-in.** With `PI_GRANTS_GRANT` unset, the session holds the wildcard and nothing is
|
|
610
|
-
blocked — this extension must never silently tighten a normal workflow. Since 0.5.0 that holds for
|
|
611
|
-
**descendants** too: an ungoverned session publishes no governance variables at all. It previously
|
|
612
|
-
exported its own observed tool surface as its children's grant, so "inactive" governance quietly governed
|
|
613
|
-
everything below it.
|
|
614
|
-
|
|
615
|
-
### Configuration, and how it fails
|
|
616
|
-
|
|
617
|
-
| Variable | Default | Notes |
|
|
618
|
-
| :--- | :--- | :--- |
|
|
619
|
-
| `PI_GRANTS_GRANT` | unset → use this directory's stored init choice, or ungoverned when none exists | Presence switches governance on and bypasses the whole cwd store; this is how children and CI stay environment-only. |
|
|
620
|
-
| `PI_GRANTS_MAX_DEPTH` | `2` | Child-depth bound. `0` disables spawning. |
|
|
621
|
-
| `PI_GRANTS_DEPTH` | `0` | This session's own depth; set by the parent, not by hand. |
|
|
622
|
-
| `PI_GRANTS_GATED` | **`tool:bash`** in a governed session | Capabilities needing human approval. Set to `""` to gate nothing. Gating is closed under subsumption, so this also covers `write`/`edit`/`read`/`grep`/`find`/`ls` (ADR-0012). |
|
|
623
|
-
| `PI_GRANTS_APPROVED` | unset | Inherited `capability@subject#sha256` entries; set by the parent, clamped to the child's own grant, and honoured only against the definition body the child itself loaded (ADR-0022). |
|
|
624
|
-
| `PI_GRANTS_APPROVAL_TIMEOUT` | `120` (seconds) | How long a dialog waits. `0` or an unreadable value means **no timeout**: waiting forever denies nothing, so it is the safe reading of a value we do not understand. |
|
|
625
|
-
| `PI_GRANTS_LEDGER` | unset → a v2 `/grants init` choice uses `<cwd>/.pi/grants.jsonl`; otherwise not recording | Presence overrides the project default; `""` disables it for one run. Any effective path is load-bearing. |
|
|
626
|
-
| `PI_GRANTS_WORKSPACE_REGISTRY` | unset | Operator-owned `{version:1, workspaces:{id:{path}}}` file, required only for workspace-routed spawns. |
|
|
627
|
-
| `PI_GRANTS_WORKSPACE_LEASE_DIR` | under `$PI_CODING_AGENT_DIR/pi-daddy/` | Kernel writer locks and ownership metadata. |
|
|
628
|
-
| `PI_GRANTS_CHILD_TIMEOUT` | `1200` (seconds) | Wall-clock limit for a child. Inherited by descendants — an operator preference, deliberately *not* attenuating state. |
|
|
629
|
-
| `PI_GRANTS_ALLOW_UNRESOLVED_MODELS` | unset | Exact `1` lets pi attempt custom model resolution; otherwise an explicit provider/id missing from pi's session catalogue refuses before lease, approval or spawn. |
|
|
630
|
-
| `PI_GRANTS_FANOUT` | `8` | Per-call width and downward subtree budget; not a session-total counter. Malformed or `0` falls back to the default. |
|
|
631
|
-
| `PI_GRANTS_PARENT_ID` | `d0` | Readable logical tree position; set by the parent and allowed to repeat across calls. |
|
|
632
|
-
| `PI_GRANTS_EXECUTION_ID` | unset at a root | Unique governed execution occurrence; set by the parent. Lifecycle/lease joins use this, never `PI_GRANTS_PARENT_ID`. |
|
|
633
|
-
| `PI_GRANTS_HERDR` | unset ⇒ **probe** | Three-state. Unset probes for a reachable herdr and uses panes if one answers; `1` demands panes and refuses every delegation if herdr is unreachable; `0` demands captured subprocesses. Never detected from `herdr` merely being on `PATH`. |
|
|
634
|
-
| `PI_GRANTS_HERDR_WORKSPACE` | the parent's `HERDR_WORKSPACE_ID` | herdr workspace for spawned panes. Defaults to the workspace this session is in, so a child is a tab away rather than a workspace away. |
|
|
635
|
-
| `PI_GRANTS_HERDR_KEEP_PANE` | unset | `1` keeps each child's pane for inspection, and no sweep closes it. Off by default: a fan-out would flood the workspace. |
|
|
636
|
-
| `PI_CODING_AGENT_DIR` | `~/.pi/agent` | pi's own variable, not ours — but it decides where stored project grants/ledger consent and persisted approvals live. |
|
|
637
|
-
|
|
638
|
-
**A malformed value disables spawning; it never falls back to a default.** Stored grants are likewise
|
|
639
|
-
tri-state: only a missing file is opt-out; malformed, unsupported-version, unreadable or wrong-cwd state is a
|
|
640
|
-
loud empty-grant session with a `GRANT_STORE_INVALID` ledger line. An unreadable
|
|
641
|
-
`PI_GRANTS_MAX_DEPTH` or `PI_GRANTS_DEPTH` yields `maxDepth: 0` and a startup warning naming the
|
|
642
|
-
variable. Before 0.5.0 these were read with `parseInt`, which accepts numeric prefixes (`"2abc"` → `2`)
|
|
643
|
-
and otherwise gives `NaN` — and since every comparison against `NaN` is false, a typo did not tighten the
|
|
644
|
-
depth limit, it **removed** it.
|
|
645
|
-
|
|
646
|
-
**Configuring a ledger makes it a precondition, not a log.** This applies equally to an explicit
|
|
647
|
-
`PI_GRANTS_LEDGER` and to the project default accepted through `/grants init`: if the write fails, delegation
|
|
648
|
-
is **refused**. Asking for an audit trail is an explicit act, and `ledger.ts` has always documented that an
|
|
649
|
-
unrecorded grant should fail closed; until 0.5.0 both call sites silently swallowed the error. Legacy v1 grant
|
|
650
|
-
stores and sessions with no ledger configured are unaffected. Concurrent appends are serialised by a lock file
|
|
651
|
-
with a short timeout — failing closed beats hanging — and a lock abandoned by a killed process is broken after
|
|
652
|
-
10s.
|
|
653
|
-
|
|
654
|
-
## The ledger
|
|
655
|
-
|
|
656
|
-
Append-only JSONL. Version 3 records capability decisions, workspace leases, child lifecycle, check receipts
|
|
657
|
-
and workflow facts. Every per-child capability decision is present, **including refusals**. The reader still
|
|
658
|
-
accepts frozen v2 and legacy grant-only lines.
|
|
659
|
-
|
|
660
|
-
`childId` is hierarchical and readable (`d0.1`, `d0.1.2`) but repeated/parallel calls may reuse it. v3 adds a
|
|
661
|
-
random `executionId` and explicit `parentExecutionId`; those are the only lifecycle/lease occurrence join.
|
|
662
|
-
A v2 lifecycle is therefore shown historical/unjoined rather than guessed. A v3 starting deadline and the
|
|
663
|
-
executor timer share one absolute budget — waiting for the strict starting append consumes it, a later running
|
|
664
|
-
event cannot replace it, and process SIGTERM grace stays inside it under an independent hard-kill timer. That
|
|
665
|
-
timer bounds the governed PID while live. Soft and hard deadline callbacks first allow one event-loop turn for
|
|
666
|
-
pending child exit delivery; retained descendant pipes cannot rewrite a PID that already exited successfully as
|
|
667
|
-
timed out. A pending running append always lands before a terminal event. `denied` non-empty remains the designated escalation signal — **an agent asking for what it does not hold is an escalation attempt, and it
|
|
668
|
-
is invisible without a record.**
|
|
669
|
-
|
|
670
|
-
Workflow facts are identifier-only and mark `planned`, `observed`, or `controller_validated`; they can never
|
|
671
|
-
claim pi-daddy enforcement. Capability/lifecycle records are the enforced class. Correlation remains
|
|
672
|
-
caller-declared: optional `schema_version` is exactly `1.0`, and `assurance_scope` is either entire-run with an
|
|
673
|
-
empty selector list or selectors with one or more non-empty strings. Fields eligible for display use the v3
|
|
674
|
-
ASCII identifier grammar rather than prose.
|
|
675
|
-
|
|
676
|
-
**Privacy is a property of this file, and the boundary is exact: capability ids, counts and identifiers only
|
|
677
|
-
— never prompts, task text, tool arguments or results.** Trusted `definitionDigest` and `taskDigest` values
|
|
678
|
-
identify the exact operator body and task. A predictable task can be guessed from SHA-256, so its digest is
|
|
679
|
-
sensitive/linkable metadata, not anonymization. Caller-supplied digest-looking values remain under
|
|
680
|
-
`correlation` and never authorize. Public v3 builders validate their serialized wire form against the same
|
|
681
|
-
closed runtime contract the readers use; `deadlineAt` therefore cannot be a `Date.parse` lookalike. Schema and
|
|
682
|
-
runtime share the seconds `00`–`59` timestamp profile because JavaScript deadline arithmetic cannot represent
|
|
683
|
-
leap seconds, and a normalized-away top-level null assurance scope is not schema-valid.
|
|
684
|
-
|
|
685
|
-
## Propagation is race-free by construction
|
|
686
|
-
|
|
687
|
-
An earlier version wrote each child's computed grant into `process.env`. The environment is process-global,
|
|
688
|
-
so concurrent spawns could read each other's values — a real hole. The fix removes the need for a per-child
|
|
689
|
-
channel rather than building one:
|
|
690
|
-
|
|
691
|
-
1. **Everything published to the environment is a parent-level fact** — the parent's own grant, the child
|
|
692
|
-
depth (`parent + 1`), the configured bounds, and this session's own approvals. Identical for every
|
|
693
|
-
sibling, so there is nothing to race on. It is written once at session start and republished only when
|
|
694
|
-
this session's own approvals change, never per spawn.
|
|
695
|
-
2. **Each child is spawned with its own explicit `env` object.** It is built by stripping every
|
|
696
|
-
`PI_GRANTS_*` variable from this process's environment and then applying the plan, so the plan is the
|
|
697
|
-
only source of all of them — a key the plan does not set cannot let the parent's value through.
|
|
698
|
-
3. **Each child derives its own grant on arrival**: `inheritedGrant ∩ ownObservedTools`, where the observed
|
|
699
|
-
set comes from the `tools` array of its first provider request — authoritative, because it is exactly
|
|
700
|
-
what pi sent the model. (A session's first provider request always precedes its first tool call, so the
|
|
701
|
-
grant is settled before it can delegate.) Only `tool:` and `ext:` ids are filtered this way; an
|
|
702
|
-
observation says nothing about `skill:` or `agent:` (R-36).
|
|
703
|
-
|
|
704
|
-
The invariant holds transitively — `own = observed ∩ inherited ⊆ inherited` — and it doubles as defence in
|
|
705
|
-
depth: a child clamps itself even if it were handed too much.
|
|
706
|
-
|
|
707
|
-
**The wildcard is held but never inherited.** A root may hold `tool:*` (authority to grant anything), but
|
|
708
|
-
handing it down would let every descendant reacquire the full catalog and make attenuation meaningless
|
|
709
|
-
below the root. Children inherit the enumerated grant only. A wildcard root that has not yet observed its
|
|
710
|
-
tools hands children an empty grant — fail closed.
|
|
711
|
-
|
|
712
|
-
**The task never touches argv.** pi dispatches `@file` and `-flag` on the *first character* of an argv
|
|
713
|
-
element, and `@file` is read **before any tool exists**, so `--tools` cannot stop it: a task beginning `@`
|
|
714
|
-
made pi read an arbitrary file into a child holding no tools at all. The task is now the final argv element,
|
|
715
|
-
prefixed with one space, unconditionally — a positional guarantee rather than a pattern match against pi's
|
|
716
|
-
current parser. Reproduced and closed; `docs/probes/g1-argv`.
|
|
717
|
-
|
|
718
|
-
## Functional subsumption: `bash` is not one capability among eight
|
|
719
|
-
|
|
720
|
-
pi's **default** tool surface is `read`, `bash`, `edit`, `write` — measured, not assumed (`grep`, `find`,
|
|
721
|
-
and `ls` exist but are not default). So a definition declaring `Read, Grep, Find, Ls` would look
|
|
722
|
-
like an escalation from any normal parent, despite being strictly weaker.
|
|
723
|
-
|
|
724
|
-
It isn't, because **`bash` can run `grep`, `find`, `ls`, `cat`, and `sed`**. `SUBSUMPTION` models that
|
|
725
|
-
explicitly, which removes the false positives *and* makes the uncomfortable part visible: a grant
|
|
726
|
-
containing `bash` is not a narrow grant. `result.subsumedBy` lists what the parent covers only indirectly,
|
|
727
|
-
so a reviewer can see what a grant really means. Pass `subsumption: false` for a strict name-equality check.
|
|
728
|
-
|
|
729
|
-
## Live capability catalog
|
|
730
|
-
|
|
731
|
-
Grants are validated against what actually exists in the session, not just against definition files:
|
|
732
|
-
|
|
733
|
-
| Source | Gives | Why it's trusted |
|
|
734
|
-
| :--- | :--- | :--- |
|
|
735
|
-
| provider request `tools` array | `tool:` capabilities, **including extension-provided ones** | authoritative — it is exactly what pi sent the model, and reflects any `--tools` allowlist already in force |
|
|
736
|
-
| skill roots (`.pi/skills`, `~/.pi/agent/skills`) | `skill:` capabilities | `SKILL.md` directories and top-level `.md` files, per pi's convention |
|
|
737
|
-
| the same roots | `agent:` capabilities | one per definition, from the same discovery `delegate` spawns from — so a definition can never be grantable but unspawnable, or listed but unknown |
|
|
738
|
-
|
|
739
|
-
This closes the **skills** half of "skills and tools" — previously ungovernable — and makes extension tools
|
|
740
|
-
visible, which is the only way `ext:`/`tool:` grants can be validated at all.
|
|
741
|
-
|
|
742
|
-
**Unknown is reported separately from denied**, because the causes and fixes differ: *denied* means the
|
|
743
|
-
delegator lacks authority; *unknown* means the capability does not exist here — a typo, or an uninstalled
|
|
744
|
-
package. Collapsing them would hide both. Verified live: `tools:["reed"]` →
|
|
745
|
-
`unknown capability: tool:reed — not present in this session's catalog (typo, or an uninstalled package?)`,
|
|
746
|
-
with no mention of escalation.
|
|
747
|
-
|
|
748
|
-
Provenance caveat: a provider payload gives tool *names*, not owning packages, so extension tools are
|
|
749
|
-
catalogued as `tool:<name>` (which is also how pi's `--tools` matches) and marked `kind: "extension"` for
|
|
750
|
-
display rather than qualified as `ext:<pkg>/<tool>`.
|
|
751
|
-
|
|
752
|
-
**`PI_BUILTIN_TOOLS` is a pinned observation** of pi 0.84.1. Drift misfiles a capability in the catalog; it
|
|
753
|
-
cannot grant one, because `--tools` is the authority.
|
|
754
|
-
|
|
755
|
-
## Use as a library
|
|
756
|
-
|
|
757
|
-
The resolver, ledger, spawn planner and the whole approval model are pure functions, exported and usable
|
|
758
|
-
without pi:
|
|
759
|
-
|
|
760
|
-
```ts
|
|
761
|
-
import { resolve, assertNarrowing, planSpawn, buildRecord, appendRecord, digestTask, newExecutionId } from "pi-daddy";
|
|
762
|
-
|
|
763
|
-
const result = resolve({
|
|
764
|
-
requested: ["tool:read", "tool:grep"],
|
|
765
|
-
parentGrant: ["tool:read", "tool:grep", "tool:write"], // what the delegator holds
|
|
766
|
-
ceiling: ["tool:read", "tool:grep"], // the definition's declared maximum
|
|
767
|
-
gated: ["tool:write"], // needs human approval, ever
|
|
768
|
-
});
|
|
769
|
-
|
|
770
|
-
assertNarrowing(result); // throws on a smuggled universal capability
|
|
771
|
-
const plan = planSpawn({ effective: result.effective, prompt: task });
|
|
772
|
-
// -> ["--print","--no-session","--no-extensions","--no-skills","--no-context-files",
|
|
773
|
-
// "--no-prompt-templates","--tools","grep,read"," summarise src/"]
|
|
774
|
-
|
|
775
|
-
await appendRecord({ path: ".pi/grants.jsonl" }, buildRecord({
|
|
776
|
-
/* capability fields … */ result, blocked: false, executor: "process",
|
|
777
|
-
executionId: newExecutionId(), parentExecutionId: null, taskDigest: digestTask(task), now: new Date(),
|
|
778
|
-
}));
|
|
18
|
+
delegate({ agent: "review-security", task: "Review the diff." })
|
|
19
|
+
delegate_all({ children: [ { agent: "review-security", task: "…" }, { agent: "review-perf", task: "…" } ] })
|
|
20
|
+
delegate_chain({ steps: [ { agent: "plan", task: "…" }, { agent: "build", task: "Implement: {previous}" } ] })
|
|
779
21
|
```
|
|
780
22
|
|
|
781
|
-
Subpaths are exported individually (`pi-daddy/resolve`, `/ledger`, `/spawn`, `/delegate`, `/catalog`,
|
|
782
|
-
`/propagation`, `/definitions`, `/fanout`, `/pi-tools`, `/approval`, `/approval-store`, `/approval-prompt`,
|
|
783
|
-
`/run-child`, `/run-herdr`, `/dashboard-projection`, `/dashboard-render`).
|
|
784
|
-
|
|
785
|
-
## Design decisions worth knowing
|
|
786
|
-
|
|
787
|
-
- **A zero grant is `--no-tools`, never "no flag".** pi rejects an empty `--tools`, and omitting the flag
|
|
788
|
-
silently falls back to pi's defaults — the opposite of a zero grant.
|
|
789
|
-
- **`--no-extensions` is always passed**, so ambient user extensions cannot widen a governed child. An
|
|
790
|
-
explicit `-e` still loads, which is exactly why the extension is re-added by hand for a child that holds
|
|
791
|
-
`tool:delegate`, and never otherwise.
|
|
792
|
-
- **Each resource class needs its own switch.** `--no-extensions` does not disable skills, context files or
|
|
793
|
-
prompt templates; all three are passed explicitly, and `--skill` *adds* to the discovered set unless
|
|
794
|
-
`--no-skills` goes with it. A granted skill is passed by path and refused if it cannot be located —
|
|
795
|
-
granting a capability the child would silently lack is a lie in the ledger.
|
|
796
|
-
- **The ledger fails closed by default.** An unrecorded grant is a hole; `strict: false` only where the
|
|
797
|
-
ledger is advisory.
|
|
798
|
-
- **Skills and definitions are capabilities too** (`skill:`, `agent:`), governed by the same machinery — but
|
|
799
|
-
they are not `--tools` entries, so `toPiToolsAllowlist()` filters them out.
|
|
800
|
-
- **Rejection reasons never mask one another** — `denied` (escalation), `clipped` (ceiling), and
|
|
801
|
-
`gatedBlocked` (needs approval) are computed independently and reported together, so a request with two
|
|
802
|
-
problems does not report one and hide the other.
|
|
803
|
-
|
|
804
|
-
## Install
|
|
805
|
-
|
|
806
|
-
```bash
|
|
807
|
-
pi install npm:pi-daddy # as a pi extension
|
|
808
|
-
npm i pi-daddy # as a library (the resolver, ledger and spawn planner are pure)
|
|
809
|
-
npx pi-daddy init # as a command: prepare .pi/grants.env using enabled installed
|
|
810
|
-
# skill packages — see the worked example above
|
|
811
|
-
npx pi-daddy work add --id daily-1 --outcome "Ship the declared slice"
|
|
812
|
-
# select one digest-only obligation; /reload then /grants dashboard
|
|
813
23
|
```
|
|
814
|
-
|
|
815
|
-
The package is also the source of the optional Herdr plugin: the extension offers to link the trusted
|
|
816
|
-
`herdr-plugin/` directory explicitly, and `pi-daddy-dashboard` is the terminal renderer binary. pi loads
|
|
817
|
-
`extensions/grants.ts` through its own transpiling loader, which reads
|
|
818
|
-
TypeScript from `node_modules` quite happily; **Node does not** — it refuses to strip types under
|
|
819
|
-
`node_modules` — so the library entry points are compiled to `dist/`. Until 0.6.0 `exports` pointed at
|
|
820
|
-
`./src/*.ts`, and every consumer import failed with `ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING` while
|
|
821
|
-
every in-repo test passed. `npm run test:smoke` packs a tarball, installs it into a scratch project and
|
|
822
|
-
*uses* it, so that gap cannot reopen silently.
|
|
823
|
-
|
|
824
|
-
## Testing
|
|
825
|
-
|
|
826
|
-
```bash
|
|
827
|
-
npm test # 741 unit tests. Fast, pure, no pi, no network.
|
|
828
|
-
npm run typecheck # src + extensions + tests + integration tests
|
|
829
|
-
npm run test:integration # 48 tests against a REAL pi process/Herdr server, no model tokens.
|
|
830
|
-
npm run test:smoke # pack/install; exercise library exports, both bins, the v2/v3 contracts,
|
|
831
|
-
# bundled Herdr plugin, dashboard, and `pi-daddy init`
|
|
832
|
-
PI_GRANTS_IT_MODEL=1 npm run test:integration # + 10 end-to-end tests with a real model. Costs money.
|
|
24
|
+
effective = ( requested ∩ parentGrant ∩ ceiling ) \ (gated \ approved)
|
|
833
25
|
```
|
|
834
26
|
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
ceilings, and the measured `fabric_exec` escalation.
|
|
839
|
-
|
|
840
|
-
**The integration suite exists because the extension is where the wiring bugs live** — every defect the live
|
|
841
|
-
probes ever found was there rather than in `src/`, and a pure test cannot see how configuration is *read*.
|
|
842
|
-
Its default tier drives slash commands, whose handlers run the real decision path over real `SKILL.md` files
|
|
843
|
-
in a real pi process **without a model deciding anything**, so it is deterministic and free. The opt-in tier
|
|
844
|
-
adds a model choosing to call tools, and asserts on structure (`isError`, the ledger JSON, whether a file
|
|
845
|
-
appeared on disk) rather than on model wording.
|
|
846
|
-
|
|
847
|
-
It earned itself immediately: its first run found that **every delegation refusal was being recorded by pi
|
|
848
|
-
as a success.** It is also checked against reintroduced defects, which is the point — restoring the G7 `NaN`
|
|
849
|
-
bug makes two of its tests fail, and the approval tests were verified by mutation (making an unpinned body
|
|
850
|
-
digest fail *open* fails exactly one test; deleting the body comparison fails three).
|
|
851
|
-
|
|
852
|
-
`test/file-size.test.ts` fails the build if any file in `src/` or `extensions/` exceeds 400 lines. It caught
|
|
853
|
-
its own author the day after it was added: rather than raise the cap, `delegation.ts` was split.
|
|
854
|
-
|
|
855
|
-
## Status
|
|
856
|
-
|
|
857
|
-
**0.20.0 — live Herdr dashboard and ledger v3.** Adds the explicit installation handshake,
|
|
858
|
-
`/grants dashboard`, duplicate-safe right split, pure live projection, unique execution/parent identity,
|
|
859
|
-
workflow provenance facts and principal correlation labels. Enforcement is unchanged.
|
|
860
|
-
|
|
861
|
-
**0.19.0 — workspace routing is a capability.** Routing now attenuates through `workspace:<id>`; see the
|
|
862
|
-
changelog for the breaking migration.
|
|
863
|
-
|
|
864
|
-
**0.18.1 — security fix for malformed capability IDs.** Capability IDs containing comma, CR, LF, NUL or
|
|
865
|
-
surrounding whitespace are refused before resolution and again before grant serialization, preventing a
|
|
866
|
-
wildcard-covered string from splitting into authority the parent never held.
|
|
867
|
-
|
|
868
|
-
**0.18.0 — generic runtime enforcement, still honest about scope.** The governed spawn path now includes
|
|
869
|
-
optional correlation, exact task-bound approvals, registered-worktree CWD validation, OS-backed governed
|
|
870
|
-
writer leases, structured refusals, lifecycle/lease ledger events, and a no-shell named-check subpath. All
|
|
871
|
-
new spawn fields are optional; legacy callers retain their behavior.
|
|
872
|
-
|
|
873
|
-
Known gaps, stated because a gap nobody wrote down is the one that surprises somebody:
|
|
874
|
-
|
|
875
|
-
- **`bash` escapes governance.** Out of scope by decision (ADR-0012); workspace routing and leases do not contain it.
|
|
876
|
-
- **A workspace lease coordinates only pi-daddy-governed writers.** It is not a filesystem sandbox and cannot stop unrelated processes. The measured writer path currently requires util-linux `flock`.
|
|
877
|
-
- **A named check is arbitrary code without shell interpolation.** It may write, use the network, invoke a shell or leave descendants; no OS containment is claimed.
|
|
878
|
-
- **`subagents:rpc:spawn` bypasses the tripwire.** Unfixable from here.
|
|
879
|
-
- **The ledger is verified at session start** when one is configured: a damaged trail announces itself, an intact one stays quiet.
|
|
880
|
-
- **A pane outlives its tool call only if its child settled.** A child that answered keeps its pane so you can
|
|
881
|
-
read it, and it is swept when you get your prompt back (`agent_settled`), with process `exit` as a backstop. A
|
|
882
|
-
child that did **not** settle — timeout, abort, failed start — loses its tab at once, because closing the tab is
|
|
883
|
-
the only way to stop a herdr agent (`herdr agent stop` does not exist). At most 8 panes are open at once, and
|
|
884
|
-
only *settled* ones are ever reclaimed: if they are all live the cap yields rather than killing a child.
|
|
885
|
-
- **Pane cleanup does not cover being killed outright.** SIGKILL, and a SIGTERM nothing else is listening for,
|
|
886
|
-
run no `exit` handlers — by Node's design — so a pane can be orphaned; `herdr tab close <id>` is the remedy. No
|
|
887
|
-
signal handler is installed, deliberately: one here would suppress Node's default termination and turn pi's
|
|
888
|
-
*"interrupt this turn"* into *"exit pi"* (R-62, re-rated M×L now that panes are the default path).
|
|
889
|
-
- **A running delegation is visible.** One status block per call — per child: its definition, its herdr agent, its
|
|
890
|
-
pane id, its state, elapsed time, and the last three lines it printed. Bounded in height and width, so a fan-out
|
|
891
|
-
cannot flood your screen. It is a **display, never the result**.
|
|
892
|
-
- **The dashboard whole-file polls.** The MVP is sized for 10 MiB; 50 MiB or 100 ms p95 projection is the
|
|
893
|
-
switch point for incremental replay.
|
|
894
|
-
- **v2 is historical in the dashboard.** It has no unique occurrence ID, so lifecycle is reported unjoined
|
|
895
|
-
rather than matched by reusable `childId`.
|
|
896
|
-
- **principal-pi-skills does not yet publish a generated graph declaration.** Explicit correlation and
|
|
897
|
-
provenance facts render; prompt prose is never parsed into a graph.
|
|
898
|
-
- **A definition's *instructions* are governed only by identity.** `agent:<name>` says which file may be
|
|
899
|
-
spawned and the digest says which version ran, but nothing reads a body and judges what it says — the
|
|
900
|
-
operator authorises a file, and its contents are their responsibility.
|
|
901
|
-
- **No background delegation.** `delegate` runs to completion and returns the child's output (ADR-0015).
|
|
902
|
-
If one is ever built, ADR-0026 fixes the rule that blocked it twice: a background spawn whose gates are
|
|
903
|
-
unresolved when its tool call returns is **refused**, and an approval arriving later starts nothing —
|
|
904
|
-
otherwise a child's capability set would depend on when a human reached the dialog.
|
|
905
|
-
- **Whether persisted approvals earn their keep is still unmeasured.** `/grants ledger` now counts where
|
|
906
|
-
every approval came from, so the question ADR-0020 left open has a command; what it does not have yet is
|
|
907
|
-
a few weeks of real use to answer it.
|
|
908
|
-
|
|
909
|
-
`docs/SPEC.md` in the repository is the authoritative current-state document; the ADRs hold the reasoning.
|
|
27
|
+
Escalation is impossible by construction on the tool surface. It does not contain an agent holding an execution
|
|
28
|
+
primitive: a child granted `bash` can start an ungoverned descendant, so `bash` is gated by default and every gate
|
|
29
|
+
answer is recorded.
|
|
910
30
|
|
|
911
|
-
|
|
31
|
+
The full product description is the repository [README](https://github.com/mojomanyana/pi-daddy#readme); the
|
|
32
|
+
[CHANGELOG](./CHANGELOG.md) says what each release changed and what to do about breaking changes. The one shipped
|
|
33
|
+
contract is `contracts/ledger-record/v1`.
|