gentle-pi 4.0.0 → 4.2.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/README.md +157 -18
- package/assets/agents/gentle-ai-explore.md +11 -4
- package/assets/agents/gentle-ai-verify.md +23 -4
- package/assets/agents/gentle-ai-worker.md +6 -6
- package/assets/install-wizard/index.html +47 -0
- package/assets/install-wizard/wizard.css +1279 -0
- package/assets/install-wizard/wizard.js +951 -0
- package/assets/orchestrator-delegation.md +70 -163
- package/assets/orchestrator-memory.md +11 -4
- package/assets/orchestrator-prompts.md +48 -0
- package/assets/orchestrator-tracking.md +53 -0
- package/assets/orchestrator-verification.md +28 -0
- package/assets/orchestrator-writer.md +38 -0
- package/assets/orchestrator.md +29 -25
- package/assets/sounds/LICENSE.md +52 -0
- package/assets/sounds/attention.wav +0 -0
- package/assets/sounds/error.wav +0 -0
- package/assets/sounds/success.wav +0 -0
- package/bin/engram-guard +9 -0
- package/bin/gentle-shell-install.mjs +302 -0
- package/bin/gentle-shell.mjs +708 -22
- package/contracts/review-provider-contract-mirror/provider-contract.lock.json +7 -7
- package/contracts/review-provider-contract-mirror/{v1.2.0 → v1.3.0}/bundle/manifest.json +2 -2
- package/contracts/review-provider-contract-mirror/{v1.2.0 → v1.3.0}/bundle/orchestration/pi.md +16 -4
- package/contracts/review-provider-contract-mirror/{v1.2.0 → v1.3.0}/generated/provider-capabilities.baseline.json +2 -2
- package/contracts/review-provider-contract-mirror/{v1.2.0 → v1.3.0}/generated/provider-roles.baseline.json +1 -1
- package/docs/auto-permission-answers.md +25 -0
- package/docs/auto-permission-evidence.md +39 -0
- package/docs/bundled-install.md +399 -0
- package/docs/delegated-verification.md +3 -5
- package/docs/gentle-agents-activity.md +513 -0
- package/docs/gentle-shell-uninstall.md +136 -0
- package/docs/gentle-shell.md +90 -33
- package/docs/install-wizard.md +2040 -0
- package/docs/native-authority-architecture.md +1 -1
- package/docs/permission-modes.md +127 -0
- package/docs/prompt-history.md +1 -1
- package/docs/readme-reference.md +310 -47
- package/docs/render-cache-performance.md +28 -0
- package/docs/session-profile-format.md +39 -0
- package/docs/sound-notifications-proposal.md +191 -0
- package/docs/sound-notifications.md +114 -0
- package/docs/yolo-mode.md +11 -10
- package/extensions/ask-user-choice.ts +4 -0
- package/extensions/ask-user-question.ts +6 -1
- package/extensions/child-context.ts +11 -2
- package/extensions/child-safety.ts +4 -2
- package/extensions/codegraph-tools.ts +18 -5
- package/extensions/gentle-agents.ts +718 -87
- package/extensions/gentle-ai.ts +991 -263
- package/extensions/gentle-herdr-activity.ts +81 -0
- package/extensions/gentle-notifications.ts +104 -0
- package/extensions/gentle-shell.ts +271 -80
- package/extensions/gentle-todo.ts +123 -18
- package/extensions/history/index.ts +11 -6
- package/extensions/pi-pretty.ts +39 -3
- package/extensions/quiet-tools.ts +91 -21
- package/extensions/skill-registry.ts +175 -46
- package/extensions/startup-banner.ts +11 -2
- package/lib/agent-home.ts +10 -1
- package/lib/agent-model-resolution.ts +80 -0
- package/lib/agent-profiles.ts +13 -3
- package/lib/agents-completion-delivery.ts +11 -3
- package/lib/agents-messaging.ts +1 -1
- package/lib/agents-protocol.ts +40 -1
- package/lib/agents-runner.ts +90 -15
- package/lib/auto-permission-answers.ts +133 -0
- package/lib/auto-permission-classifier.ts +459 -0
- package/lib/auto-permission-evidence.ts +88 -0
- package/lib/auto-permission-memory.ts +69 -0
- package/lib/auto-permission-runtime.ts +484 -0
- package/lib/auto-permission-tool-context.ts +61 -0
- package/lib/background-jobs-tools.ts +202 -0
- package/lib/background-jobs.ts +253 -0
- package/lib/background-monitor.ts +154 -0
- package/lib/bounded-writer-admission.ts +83 -10
- package/lib/builtin-codemode-optout.ts +166 -0
- package/lib/card-content-policy.ts +85 -0
- package/lib/child-package-injection.ts +62 -0
- package/lib/codemode-renderer.ts +14 -4
- package/lib/command-palette-catalog.ts +3 -2
- package/lib/context-threshold.ts +26 -0
- package/lib/destructive-command-guard.ts +104 -28
- package/lib/gentle-ai-binary.ts +109 -4
- package/lib/gentle-shell-bundled.ts +535 -0
- package/lib/gentle-shell-launcher.ts +75 -24
- package/lib/gentle-shell-startup-flow.ts +54 -0
- package/lib/gentle-shell-startup-update.ts +92 -0
- package/lib/gentle-shell-uninstall.ts +840 -0
- package/lib/gentle-shell-update-panel.ts +231 -0
- package/lib/herdr-activity.ts +183 -0
- package/lib/inprocess-reviewer.ts +3 -0
- package/lib/jobs-sidebar-state.ts +20 -0
- package/lib/jobs-view.ts +161 -0
- package/lib/model-price-ratio.ts +83 -0
- package/lib/model-routing-authority.ts +6 -1
- package/lib/nan-provider.ts +33 -11
- package/lib/native-review-cli.ts +194 -73
- package/lib/notification-audio-native.ts +162 -0
- package/lib/notification-audio-windows.ts +399 -0
- package/lib/notification-audio.ts +332 -0
- package/lib/notification-customize.ts +241 -0
- package/lib/notification-events.ts +113 -0
- package/lib/notification-policy.ts +148 -0
- package/lib/notification-pulse-client.ts +367 -0
- package/lib/notification-pulse-protocol.ts +305 -0
- package/lib/notification-pulse-stream.ts +213 -0
- package/lib/notification-pulse-worker.ts +66 -0
- package/lib/notification-scheduler.ts +173 -0
- package/lib/notification-service.ts +202 -0
- package/lib/notification-ui.ts +87 -0
- package/lib/odd-phase.ts +1 -1
- package/lib/orchestrator-alias.ts +20 -0
- package/lib/orchestrator-catalog.ts +79 -0
- package/lib/orchestrator-consultation.ts +61 -0
- package/lib/orchestrator-discovery.ts +49 -0
- package/lib/orchestrator-helper-consent.ts +122 -0
- package/lib/orchestrator-helper.ts +167 -0
- package/lib/orchestrator-message-card.ts +105 -0
- package/lib/orchestrator-presence.ts +115 -14
- package/lib/orchestrator-scope.ts +80 -0
- package/lib/orchestrator-state.ts +107 -0
- package/lib/orchestrator-tool-card.ts +280 -0
- package/lib/orchestrator-work-search.ts +218 -0
- package/lib/orchestrator-work.ts +79 -0
- package/lib/permission-mode-policy.ts +59 -0
- package/lib/review-candidate-view-owner.ts +8 -6
- package/lib/review-candidate-view.ts +3 -2
- package/lib/review-compact-contract.ts +2 -2
- package/lib/review-host-relay.ts +7 -2
- package/lib/review-integration-v2.ts +100 -22
- package/lib/review-publication-gate.ts +1 -1
- package/lib/review-risk-assessment.ts +77 -51
- package/lib/review-sidebar-state.ts +2 -1
- package/lib/review-transaction.ts +72 -3
- package/lib/runtime-metrics-children.ts +1 -1
- package/lib/runtime-metrics-native.ts +3 -2
- package/lib/selection-engine.ts +22 -7
- package/lib/session-change-capture.ts +5 -4
- package/lib/session-changes.ts +27 -22
- package/lib/session-profile-binding.ts +83 -0
- package/lib/session-profile-freeze.ts +261 -0
- package/lib/session-profile-persistence.ts +187 -0
- package/lib/session-worktree-registry.ts +74 -8
- package/lib/shell-bar.ts +41 -11
- package/lib/shell-changes-view.ts +40 -13
- package/lib/shell-changes.ts +88 -71
- package/lib/shell-prompt.ts +6 -4
- package/lib/shell-sidebar-layout.ts +5 -1
- package/lib/shell-todo.ts +81 -26
- package/lib/shell-usage.ts +4 -3
- package/lib/status-timing-diagnostics.ts +201 -0
- package/lib/telemetry-trigger.ts +3 -1
- package/lib/vim-editor-adapter.ts +27 -5
- package/lib/visual-customization-policy.ts +20 -9
- package/lib/visual-customize-view.ts +171 -20
- package/lib/writer-surfaces.ts +162 -0
- package/lib/yolo-session-policy.ts +198 -121
- package/package.json +5 -5
- package/runtime/child-package-injection.mjs +63 -0
- package/runtime/gentle-ai-binary.mjs +109 -4
- package/runtime/gentle-shell-bundled.mjs +536 -0
- package/runtime/gentle-shell-launcher.mjs +74 -23
- package/runtime/gentle-shell-startup-flow.mjs +55 -0
- package/runtime/gentle-shell-startup-update.mjs +93 -0
- package/runtime/gentle-shell-uninstall.mjs +841 -0
- package/runtime/gentle-shell-update-panel.mjs +232 -0
- package/runtime/native-review-cli.mjs +191 -70
- package/runtime/review-integration-v2.mjs +100 -22
- package/runtime/review-risk-assessment.mjs +77 -51
- package/runtime/status-timing-diagnostics.mjs +202 -0
- package/runtime/telemetry-trigger.mjs +3 -1
- package/scripts/bootstrap.cmd +255 -0
- package/scripts/bootstrap.sh +168 -0
- package/scripts/build-distribution.mjs +157 -0
- package/scripts/build-installer-bundles.mjs +136 -0
- package/scripts/build-runtime-modules.mjs +7 -0
- package/scripts/bundled-install.mjs +1308 -0
- package/scripts/bundled-wizard.mjs +399 -0
- package/scripts/check-types.mjs +4 -6
- package/scripts/gentle-ai-installer.mjs +79 -32
- package/scripts/install-gentle-ai.mjs +48 -1
- package/scripts/install-tui-mode-setting.mjs +10 -1
- package/scripts/install-wizard-preview.mjs +154 -0
- package/scripts/installer-downloads.mjs +648 -0
- package/scripts/installer-preflight.mjs +387 -0
- package/scripts/installer-probes.mjs +564 -0
- package/scripts/installer-runner.mjs +1102 -0
- package/scripts/installer-server.mjs +881 -0
- package/scripts/installer-windows-artifacts.json +15 -0
- package/scripts/installer-windows.mjs +752 -0
- package/scripts/main-channel.mjs +452 -0
- package/scripts/npm-pack-result.mjs +31 -0
- package/scripts/pi-update.mjs +223 -0
- package/scripts/render-cache-performance-worker.mjs +205 -0
- package/scripts/render-cache-performance.mjs +115 -0
- package/scripts/run-test-suite.mjs +22 -8
- package/scripts/test-installer-acceptance.sh +161 -0
- package/scripts/test-packed-runner.mjs +23 -5
- package/scripts/types-baseline.json +2 -92
- package/scripts/verify-package-files.mjs +82 -18
- package/skills/gentle-ai/SKILL.md +12 -11
- package/tests/agent-home.test.ts +56 -3
- package/tests/agent-model-resolution.test.ts +113 -0
- package/tests/agent-profiles.test.ts +12 -0
- package/tests/agent-risk-escalation.test.ts +123 -0
- package/tests/agents-completion-delivery.test.ts +17 -0
- package/tests/agents-protocol.test.ts +57 -0
- package/tests/agents-queries.test.ts +9 -9
- package/tests/agents-runner-process.test.ts +31 -0
- package/tests/agents-runner.test.ts +89 -4
- package/tests/append-system-prompt-route.test.ts +18 -1
- package/tests/auto-mode-human-answers.test.ts +68 -0
- package/tests/auto-mode-invariants.test.ts +276 -0
- package/tests/auto-mode-sdk.test.ts +84 -0
- package/tests/auto-mode.test.ts +49 -0
- package/tests/auto-permission-answers.test.ts +170 -0
- package/tests/auto-permission-classifier.test.ts +634 -0
- package/tests/auto-permission-compound.test.ts +24 -0
- package/tests/auto-permission-evidence.test.ts +88 -0
- package/tests/auto-permission-memory.test.ts +46 -0
- package/tests/auto-permission-public-regressions.test.ts +111 -0
- package/tests/auto-permission-runtime.test.ts +454 -0
- package/tests/autonomous-guard.test.ts +86 -16
- package/tests/background-cache-warming.test.ts +2 -1
- package/tests/background-jobs.test.ts +227 -0
- package/tests/background-monitor.test.ts +195 -0
- package/tests/background-subagents-default-mode.test.ts +28 -5
- package/tests/bounded-stop-contract.test.ts +85 -0
- package/tests/bounded-writer-admission.test.ts +52 -1
- package/tests/bridge-wake-lifecycle.test.ts +129 -0
- package/tests/bridge-wake-rendering.test.ts +56 -0
- package/tests/build-distribution.test.ts +269 -0
- package/tests/builtin-codemode-optout.test.ts +242 -0
- package/tests/bundled-install.test.ts +1319 -0
- package/tests/bundled-wizard.test.ts +505 -0
- package/tests/card-content-policy.test.ts +68 -0
- package/tests/card-style-policy.test.ts +34 -2
- package/tests/child-codegraph-bootstrap.test.ts +74 -0
- package/tests/child-package-entrypoints.test.ts +65 -0
- package/tests/child-package-injection.test.ts +74 -0
- package/tests/child-safety.test.ts +12 -0
- package/tests/child-web-package.test.ts +224 -0
- package/tests/codegraph-tools.test.ts +35 -0
- package/tests/codemode-rendering.test.ts +107 -2
- package/tests/command-palette.test.ts +5 -5
- package/tests/context-threshold.test.ts +31 -0
- package/tests/delegate-for-reason-contract.test.ts +327 -0
- package/tests/delegated-key-learnings-contract.test.ts +3 -2
- package/tests/devbinary/native-review-parity.devtest.ts +1 -1
- package/tests/devbinary/pi-host-relay.devtest.ts +173 -3
- package/tests/engram-safety.test.ts +316 -0
- package/tests/generic-agent-tools.test.ts +16 -1
- package/tests/gentle-agents.test.ts +1895 -76
- package/tests/gentle-ai-binary-isolation.test.ts +135 -0
- package/tests/gentle-ai-binary.test.ts +19 -2
- package/tests/gentle-ai-child-guards.test.ts +202 -0
- package/tests/gentle-ai-dev-binary-surfacing.test.ts +125 -15
- package/tests/gentle-ai-installer.test.ts +548 -58
- package/tests/gentle-ai-prompt-model-routing.test.ts +123 -0
- package/tests/gentle-ai-renderer.test.ts +6 -6
- package/tests/gentle-ai.test.ts +999 -31
- package/tests/gentle-herdr-activity.test.ts +100 -0
- package/tests/gentle-notifications.test.ts +427 -0
- package/tests/gentle-shell-bin.test.ts +263 -19
- package/tests/gentle-shell-bundled.test.ts +1036 -0
- package/tests/gentle-shell-launcher.test.ts +251 -25
- package/tests/gentle-shell-startup-flow.test.ts +75 -0
- package/tests/gentle-shell-startup-update.test.ts +85 -0
- package/tests/gentle-shell-uninstall.test.ts +978 -0
- package/tests/gentle-shell-update-panel.test.ts +158 -0
- package/tests/gentle-shell.test.ts +611 -100
- package/tests/gentle-todo.test.ts +317 -14
- package/tests/herdr-activity.test.ts +243 -0
- package/tests/history-agent-home.test.ts +81 -0
- package/tests/history-child-guard.test.ts +70 -0
- package/tests/inprocess-reviewer.test.ts +20 -0
- package/tests/install-gentle-ai-failure.test.ts +69 -0
- package/tests/install-tui-mode-setting.test.ts +15 -0
- package/tests/install-wizard.test.ts +1223 -0
- package/tests/installer-bundles.test.ts +122 -0
- package/tests/installer-posix-bootstrap.test.ts +1201 -0
- package/tests/installer-preflight.test.ts +750 -0
- package/tests/installer-probes.test.ts +1106 -0
- package/tests/installer-runner.test.ts +2159 -0
- package/tests/installer-server.test.ts +1567 -0
- package/tests/installer-windows-bootstrap.test.ts +2410 -0
- package/tests/jobs-view.test.ts +160 -0
- package/tests/main-channel-upgrade.test.ts +395 -0
- package/tests/main-channel.test.ts +344 -0
- package/tests/maintainer/provider-relay.maintest.ts +13 -12
- package/tests/model-price-ratio.test.ts +116 -0
- package/tests/model-profiles-preservation.test.ts +153 -0
- package/tests/model-routing-package.test.ts +10 -0
- package/tests/nan-provider-runtime.test.ts +156 -0
- package/tests/nan-provider.test.ts +28 -18
- package/tests/native-binary-gate.test.ts +2 -0
- package/tests/native-review-capability-contract.test.ts +7 -1
- package/tests/native-review-cli.test.ts +236 -1
- package/tests/native-review-consent.test.ts +2 -2
- package/tests/native-review-parity-runtime.test.ts +1 -1
- package/tests/native-review-parity.test.ts +12 -48
- package/tests/native-risk-evidence-parity.test.ts +21 -0
- package/tests/no-self-pause-contract.test.ts +87 -0
- package/tests/notification-audio-native.test.ts +281 -0
- package/tests/notification-audio-windows.test.ts +581 -0
- package/tests/notification-audio.test.ts +548 -0
- package/tests/notification-customize.test.ts +655 -0
- package/tests/notification-events.test.ts +115 -0
- package/tests/notification-policy.test.ts +201 -0
- package/tests/notification-pulse-client.test.ts +356 -0
- package/tests/notification-pulse-protocol.test.ts +213 -0
- package/tests/notification-pulse-stream.test.ts +320 -0
- package/tests/notification-scheduler.test.ts +258 -0
- package/tests/notification-ui.test.ts +157 -0
- package/tests/npm-pack-result.test.ts +41 -0
- package/tests/odd-integration.test.ts +14 -5
- package/tests/odd-routing-canonical-ratchet.test.ts +53 -12
- package/tests/odd-routing-contract.test.ts +80 -23
- package/tests/odd-runtime-delegation-gate.test.ts +4 -1
- package/tests/orchestrator-budget.test.ts +29 -6
- package/tests/orchestrator-catalog.test.ts +146 -0
- package/tests/orchestrator-consultation-sdk.test.ts +614 -0
- package/tests/orchestrator-consultation.test.ts +111 -0
- package/tests/orchestrator-discovery.test.ts +241 -0
- package/tests/orchestrator-helper-consent.test.ts +171 -0
- package/tests/orchestrator-helper.test.ts +297 -0
- package/tests/orchestrator-message-card.test.ts +190 -0
- package/tests/orchestrator-presence.test.ts +23 -0
- package/tests/orchestrator-rdd-ownership.test.ts +6 -5
- package/tests/orchestrator-scope.test.ts +107 -0
- package/tests/orchestrator-state.test.ts +114 -0
- package/tests/orchestrator-status-publication-contract.test.ts +34 -0
- package/tests/orchestrator-tool-card.test.ts +398 -0
- package/tests/orchestrator-work-search.test.ts +318 -0
- package/tests/orchestrator-work.test.ts +147 -0
- package/tests/package-manifest.test.ts +105 -21
- package/tests/packed-runner-owned-path.test.ts +35 -1
- package/tests/parallel-reason-contract.test.ts +21 -0
- package/tests/parallel-writer-admission.test.ts +210 -0
- package/tests/permission-mode-policy.test.ts +194 -0
- package/tests/persona-single-channel.test.ts +4 -12
- package/tests/pi-pretty.test.ts +56 -0
- package/tests/pi-update-launcher.test.ts +87 -0
- package/tests/pi-update.test.ts +186 -0
- package/tests/provider-defect-handoff.test.ts +4 -3
- package/tests/quiet-tool-rendering.test.ts +160 -3
- package/tests/rdd-aware-verification-contract.test.ts +29 -41
- package/tests/rdd-status-line.test.ts +52 -0
- package/tests/render-cache-performance.test.ts +48 -0
- package/tests/review-agent-end-preflight.test.ts +62 -10
- package/tests/review-candidate-view.test.ts +101 -12
- package/tests/review-contract-prompt.test.ts +33 -4
- package/tests/review-controller-native-recovery.test.ts +327 -17
- package/tests/review-controller-native-routing.test.ts +255 -1
- package/tests/review-controller-workspace-root.test.ts +43 -2
- package/tests/review-controller.test.ts +2 -2
- package/tests/review-correction-lifecycle.test.ts +2 -1
- package/tests/review-gate.test.ts +7 -4
- package/tests/review-graph-schema.test.ts +2 -2
- package/tests/review-host-relay-routing.test.ts +5 -3
- package/tests/review-host-relay.test.ts +49 -2
- package/tests/review-integration-v2-forward.test.ts +21 -1
- package/tests/review-json-arguments.test.ts +167 -0
- package/tests/review-last-event-closure.test.ts +157 -8
- package/tests/review-ledger-contract.test.ts +5 -4
- package/tests/review-policy-judgment-day.test.ts +1 -1
- package/tests/review-policy-ordinary.test.ts +2 -2
- package/tests/review-relay-transport-agent.test.ts +66 -1
- package/tests/review-risk-assessment.test.ts +109 -33
- package/tests/review-session-standing-permission-controller.test.ts +16 -17
- package/tests/review-session-standing-permission-ipc.test.ts +6 -5
- package/tests/review-test-fixtures.ts +7 -1
- package/tests/review-transaction.test.ts +18 -1
- package/tests/run-test-suite.test.ts +83 -5
- package/tests/runtime-harness.mjs +42 -15
- package/tests/runtime-metrics-extension.test.ts +1 -1
- package/tests/runtime-metrics-native.test.ts +31 -1
- package/tests/selection-engine.test.ts +65 -5
- package/tests/session-change-capture.test.ts +10 -10
- package/tests/session-changes-shell.test.ts +242 -48
- package/tests/session-changes.test.ts +17 -24
- package/tests/session-profile-binding.test.ts +163 -0
- package/tests/session-profile-freeze.test.ts +394 -0
- package/tests/session-profile-persistence.test.ts +334 -0
- package/tests/session-subject-routing-contract.test.ts +34 -0
- package/tests/session-worktree-registry.test.ts +57 -2
- package/tests/shell-bar.test.ts +40 -0
- package/tests/shell-changes-view.test.ts +85 -34
- package/tests/shell-changes.test.ts +79 -62
- package/tests/shell-render-cache-runtime.test.ts +69 -0
- package/tests/shell-render-cache.test.ts +129 -0
- package/tests/shell-sidebar-layout.test.ts +27 -2
- package/tests/shell-todo.test.ts +132 -11
- package/tests/shell-usage-view.test.ts +1 -1
- package/tests/shell-usage.test.ts +35 -0
- package/tests/short-check-routing-contract.test.ts +49 -0
- package/tests/skill-registry-watcher.test.ts +119 -0
- package/tests/skill-registry.test.ts +311 -5
- package/tests/startup-banner.test.ts +117 -3
- package/tests/startup-home-repo.test.ts +170 -0
- package/tests/status-timing-diagnostics.test.ts +283 -0
- package/tests/support/orchestrator-modules.ts +19 -0
- package/tests/task-size-routing-contract.test.ts +241 -0
- package/tests/telemetry-trigger.test.ts +27 -1
- package/tests/test-strength-contract.test.ts +124 -0
- package/tests/verify-agent-contract.test.ts +90 -0
- package/tests/verify-first-launch-contract.test.ts +139 -0
- package/tests/verify-package-files.test.ts +56 -0
- package/tests/vim-editor-adapter.test.ts +47 -21
- package/tests/visual-customization-policy.test.ts +32 -3
- package/tests/visual-customize-view.test.ts +288 -10
- package/tests/writer-edit-surface-scope.test.ts +59 -2
- package/tests/writer-surfaces.test.ts +199 -0
- package/tests/yolo-customize.test.ts +18 -3
- package/tests/yolo-mode-runtime.test.ts +37 -10
- package/tests/yolo-mode.test.ts +38 -5
- package/tests/yolo-session-policy.test.ts +1 -1
- /package/contracts/review-provider-contract-mirror/{v1.2.0 → v1.3.0}/bundle/README.md +0 -0
- /package/contracts/review-provider-contract-mirror/{v1.2.0 → v1.3.0}/bundle/schemas/lens.schema.json +0 -0
- /package/contracts/review-provider-contract-mirror/{v1.2.0 → v1.3.0}/bundle/schemas/refuter.schema.json +0 -0
- /package/contracts/review-provider-contract-mirror/{v1.2.0 → v1.3.0}/bundle/schemas/targeted-validator.schema.json +0 -0
- /package/contracts/review-provider-contract-mirror/{v1.2.0 → v1.3.0}/bundle/vectors/lens.json +0 -0
- /package/contracts/review-provider-contract-mirror/{v1.2.0 → v1.3.0}/bundle/vectors/refuter.json +0 -0
- /package/contracts/review-provider-contract-mirror/{v1.2.0 → v1.3.0}/bundle/vectors/targeted-validator.json +0 -0
|
@@ -78,8 +78,8 @@ export const REVIEW_START_STATE = {
|
|
|
78
78
|
const START_ACTIONS = ["created", "resumed", "closed", "blocked-scope-action"] ;
|
|
79
79
|
const RISK_LEVELS = ["low", "medium", "high"] ;
|
|
80
80
|
const REVIEW_LENSES = ["review-risk", "review-resilience", "review-readability", "review-reliability"] ;
|
|
81
|
-
const RISK_REASON_CODES = ["configuration_change", "empty_content", "executable_change", "executable_mode", "hot_path", "large_change", "non_executable_only", "process_boundary", "process_scan_limit", "service_token", "shell_source"] ;
|
|
82
|
-
const RISK_SIGNALS = ["auth", "update", "security", "payments", "permissions", "shell_process"] ;
|
|
81
|
+
const RISK_REASON_CODES = ["agent_escalation", "configuration_change", "dangerous_sink", "empty_content", "executable_change", "executable_mode", "hot_path", "large_change", "non_executable_only", "process_boundary", "process_scan_limit", "service_token", "shell_source"] ;
|
|
82
|
+
const RISK_SIGNALS = ["auth", "update", "security", "payments", "permissions", "shell_process", "dangerous_sink", "agent_escalation"] ;
|
|
83
83
|
// "collect" and "execute" are the v2 envelope's projection of a live
|
|
84
84
|
// transaction whose next_transition is mandatory: the root action names the
|
|
85
85
|
// transition kind instead of reading as a terminal stop.
|
|
@@ -637,6 +637,23 @@ const ESCALATION_REFUTER_OUTCOMES = ["corroborated", "refuted", "inconclusive"]
|
|
|
637
637
|
|
|
638
638
|
|
|
639
639
|
|
|
640
|
+
function decodeReviewEscalationV1(value , label ) {
|
|
641
|
+
const source = exactRecord(value, label, ["cause", "finding_ids"], ["refuter_outcomes"]);
|
|
642
|
+
const escalation = {
|
|
643
|
+
cause: enumeration(source.cause, ESCALATION_CAUSES, `${label}.cause`),
|
|
644
|
+
findingIds: stringArray(source.finding_ids, `${label}.finding_ids`),
|
|
645
|
+
};
|
|
646
|
+
if (Object.hasOwn(source, "refuter_outcomes")) escalation.refuterOutcomes = array(source.refuter_outcomes, `${label}.refuter_outcomes`, (entry, itemLabel) => {
|
|
647
|
+
const row = exactRecord(entry, itemLabel, ["finding_id", "outcome", "proof"]);
|
|
648
|
+
return {
|
|
649
|
+
findingId: nonempty(row.finding_id, `${itemLabel}.finding_id`),
|
|
650
|
+
outcome: enumeration(row.outcome, ESCALATION_REFUTER_OUTCOMES, `${itemLabel}.outcome`),
|
|
651
|
+
proof: nonempty(row.proof, `${itemLabel}.proof`),
|
|
652
|
+
};
|
|
653
|
+
});
|
|
654
|
+
return escalation;
|
|
655
|
+
}
|
|
656
|
+
|
|
640
657
|
|
|
641
658
|
|
|
642
659
|
|
|
@@ -2105,23 +2122,9 @@ export function decodeReviewStatusV3(value ) {
|
|
|
2105
2122
|
};
|
|
2106
2123
|
}
|
|
2107
2124
|
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
const source = exactRecord(body.escalation, label, ["cause", "finding_ids"], ["refuter_outcomes"]);
|
|
2112
|
-
escalation = {
|
|
2113
|
-
cause: enumeration(source.cause, ESCALATION_CAUSES, `${label}.cause`),
|
|
2114
|
-
findingIds: stringArray(source.finding_ids, `${label}.finding_ids`),
|
|
2115
|
-
};
|
|
2116
|
-
if (Object.hasOwn(source, "refuter_outcomes")) escalation.refuterOutcomes = array(source.refuter_outcomes, `${label}.refuter_outcomes`, (entry, itemLabel) => {
|
|
2117
|
-
const row = exactRecord(entry, itemLabel, ["finding_id", "outcome", "proof"]);
|
|
2118
|
-
return {
|
|
2119
|
-
findingId: nonempty(row.finding_id, `${itemLabel}.finding_id`),
|
|
2120
|
-
outcome: enumeration(row.outcome, ESCALATION_REFUTER_OUTCOMES, `${itemLabel}.outcome`),
|
|
2121
|
-
proof: nonempty(row.proof, `${itemLabel}.proof`),
|
|
2122
|
-
};
|
|
2123
|
-
});
|
|
2124
|
-
}
|
|
2125
|
+
const escalation = Object.hasOwn(body, "escalation")
|
|
2126
|
+
? decodeReviewEscalationV1(body.escalation, "status.escalation")
|
|
2127
|
+
: undefined;
|
|
2125
2128
|
|
|
2126
2129
|
// status/v7 top-level optional digest (gentle-ai v2.6.0): resolves #4066's
|
|
2127
2130
|
// closed loop where `sdd-attempt finish` named a digest status never
|
|
@@ -2584,7 +2587,11 @@ function assertReviewApprovedAcknowledgementExecuteShapeV1(execute
|
|
|
2584
2587
|
if (execute.arguments.length !== REVIEW_APPROVED_ACKNOWLEDGEMENT_ARGUMENTS.length) throw new TypeError(`acknowledgement.execute.arguments must carry exactly ${REVIEW_APPROVED_ACKNOWLEDGEMENT_ARGUMENTS.length} provider-issued arguments`);
|
|
2585
2588
|
const values = execute.arguments.map((argument, index) => { const name = REVIEW_APPROVED_ACKNOWLEDGEMENT_ARGUMENTS[index] ; if (argument.name !== name) throw new TypeError(`acknowledgement.execute.arguments[${index}].name must be ${name}`); const value = nonempty(argument.value, `acknowledgement.execute.arguments[${index}].value`); if (nonempty(argument.token, `acknowledgement.execute.arguments[${index}].token`) !== `--${name}=${value}`) throw new TypeError(`acknowledgement.execute.arguments[${index}].token must exactly match ${name}`); return value; });
|
|
2586
2589
|
if (execute.preconditions.length !== 1 || execute.preconditions[0]?.name !== "state" || execute.preconditions[0]?.value !== "approved") throw new TypeError("acknowledgement.execute.preconditions must be the single approved state precondition");
|
|
2587
|
-
|
|
2590
|
+
const tokens = execute.arguments.map((argument) => argument.token );
|
|
2591
|
+
// The exact five-argument check above validates both vectors before tuple construction.
|
|
2592
|
+
const tokenTuple = [tokens[0] , tokens[1] , tokens[2] , tokens[3] , tokens[4] ];
|
|
2593
|
+
const valueTuple = [values[0] , values[1] , values[2] , values[3] , values[4] ];
|
|
2594
|
+
return { tokens: tokenTuple, values: valueTuple, lineageId: lineage(execute.binding.lineageId, "acknowledgement.execute.binding.lineage_id"), targetIdentity: sha256(execute.binding.targetIdentity, "acknowledgement.execute.binding.target_identity"), revision: sha256(execute.binding.revision, "acknowledgement.execute.binding.revision") };
|
|
2588
2595
|
}
|
|
2589
2596
|
|
|
2590
2597
|
/**
|
|
@@ -2689,6 +2696,28 @@ const REVIEW_LAST_EVENT_CAUSAL_DISPOSITIONS = ["introduced", "behavior-activated
|
|
|
2689
2696
|
|
|
2690
2697
|
|
|
2691
2698
|
|
|
2699
|
+
|
|
2700
|
+
|
|
2701
|
+
|
|
2702
|
+
|
|
2703
|
+
|
|
2704
|
+
|
|
2705
|
+
|
|
2706
|
+
|
|
2707
|
+
|
|
2708
|
+
|
|
2709
|
+
|
|
2710
|
+
|
|
2711
|
+
|
|
2712
|
+
|
|
2713
|
+
|
|
2714
|
+
|
|
2715
|
+
|
|
2716
|
+
|
|
2717
|
+
|
|
2718
|
+
|
|
2719
|
+
|
|
2720
|
+
|
|
2692
2721
|
|
|
2693
2722
|
|
|
2694
2723
|
|
|
@@ -2836,18 +2865,67 @@ function decodeReviewLastEventReviewerResultV1(value , label )
|
|
|
2836
2865
|
};
|
|
2837
2866
|
}
|
|
2838
2867
|
|
|
2868
|
+
function decodeReviewTargetedValidatorCheckEvidenceV1(value , label ) {
|
|
2869
|
+
const check = exactRecord(value, label, ["passed", "evidence"], ["regressions"]);
|
|
2870
|
+
const regressions = Object.hasOwn(check, "regressions")
|
|
2871
|
+
? array(check.regressions, `${label}.regressions`, (entry, entryLabel) => {
|
|
2872
|
+
const row = exactRecord(entry, entryLabel, ["location", "claim", "proof_refs"], ["id"]);
|
|
2873
|
+
return {
|
|
2874
|
+
...(Object.hasOwn(row, "id") ? { id: nonempty(row.id, `${entryLabel}.id`) } : {}),
|
|
2875
|
+
location: nonempty(row.location, `${entryLabel}.location`),
|
|
2876
|
+
claim: nonempty(row.claim, `${entryLabel}.claim`),
|
|
2877
|
+
proofRefs: stringArray(row.proof_refs, `${entryLabel}.proof_refs`, { minimum: 1 }),
|
|
2878
|
+
};
|
|
2879
|
+
}) : undefined;
|
|
2880
|
+
return {
|
|
2881
|
+
passed: boolean(check.passed, `${label}.passed`),
|
|
2882
|
+
// Native admission rejects observations containing only Unicode whitespace.
|
|
2883
|
+
evidence: stringArray(check.evidence, `${label}.evidence`, { minimum: 1, pattern: /[^\p{White_Space}]/u }),
|
|
2884
|
+
...(regressions === undefined ? {} : { regressions }),
|
|
2885
|
+
};
|
|
2886
|
+
}
|
|
2887
|
+
|
|
2888
|
+
function decodeReviewTargetedValidatorEvidenceV1(value , label ) {
|
|
2889
|
+
const body = exactRecord(value, label, ["targeted_validation_request_hash", "correction_target_identity", "original_criteria", "correction_regression", "follow_ups"]);
|
|
2890
|
+
return {
|
|
2891
|
+
targetedValidationRequestHash: sha256(body.targeted_validation_request_hash, `${label}.targeted_validation_request_hash`),
|
|
2892
|
+
correctionTargetIdentity: sha256(body.correction_target_identity, `${label}.correction_target_identity`),
|
|
2893
|
+
originalCriteria: decodeReviewTargetedValidatorCheckEvidenceV1(body.original_criteria, `${label}.original_criteria`),
|
|
2894
|
+
correctionRegression: decodeReviewTargetedValidatorCheckEvidenceV1(body.correction_regression, `${label}.correction_regression`),
|
|
2895
|
+
followUps: array(body.follow_ups, `${label}.follow_ups`, (entry, entryLabel) => {
|
|
2896
|
+
const row = exactRecord(entry, entryLabel, ["observation", "proof_refs"]);
|
|
2897
|
+
return { observation: nonempty(row.observation, `${entryLabel}.observation`), proofRefs: stringArray(row.proof_refs, `${entryLabel}.proof_refs`, { minimum: 1 }) };
|
|
2898
|
+
}),
|
|
2899
|
+
raw: body,
|
|
2900
|
+
};
|
|
2901
|
+
}
|
|
2902
|
+
|
|
2839
2903
|
export function decodeReviewLastEventClosureV1(value ) {
|
|
2840
|
-
const body = exactRecord(value, "last_event_closure", ["schema", "operation", "lineage_id", "state", "store_revision"], ["target_identity", "request_hash", "correction_lines", "action", "advisory_findings", "reviewer_results", "status_continuation", "acknowledgement"]);
|
|
2904
|
+
const body = exactRecord(value, "last_event_closure", ["schema", "operation", "lineage_id", "state", "store_revision"], ["target_identity", "request_hash", "correction_lines", "action", "escalation", "targeted_validator_evidence", "advisory_findings", "reviewer_results", "status_continuation", "acknowledgement"]);
|
|
2841
2905
|
if (body.schema !== REVIEW_LAST_EVENT_CLOSURE_SCHEMA) throw new TypeError(`last_event_closure.schema must be ${REVIEW_LAST_EVENT_CLOSURE_SCHEMA}`);
|
|
2842
2906
|
const operation = enumeration(body.operation, Object.values(REVIEW_LAST_EVENT_CLOSURE_OPERATION), "last_event_closure.operation") ;
|
|
2843
2907
|
const state = enumeration(body.state, REVIEW_LAST_EVENT_TERMINAL_STATES, "last_event_closure.state") ;
|
|
2908
|
+
if (Object.hasOwn(body, "targeted_validator_evidence") && (operation !== REVIEW_LAST_EVENT_CLOSURE_OPERATION.CAPTURE_VALIDATION || state !== "escalated")) {
|
|
2909
|
+
throw new TypeError("last_event_closure targeted_validator_evidence requires escalated review/capture-validation");
|
|
2910
|
+
}
|
|
2911
|
+
// Diagnostic evidence is optional for older providers and never controls terminal authority.
|
|
2912
|
+
const targetedValidatorEvidence = Object.hasOwn(body, "targeted_validator_evidence")
|
|
2913
|
+
? decodeReviewTargetedValidatorEvidenceV1(body.targeted_validator_evidence, "last_event_closure.targeted_validator_evidence")
|
|
2914
|
+
: undefined;
|
|
2915
|
+
if (Object.hasOwn(body, "escalation") && state !== "escalated") throw new TypeError("last_event_closure escalation requires escalated state");
|
|
2916
|
+
// Older native closures omit this diagnostic; its presence never grants a continuation.
|
|
2917
|
+
const escalation = Object.hasOwn(body, "escalation")
|
|
2918
|
+
? decodeReviewEscalationV1(body.escalation, "last_event_closure.escalation")
|
|
2919
|
+
: undefined;
|
|
2844
2920
|
const shared = {
|
|
2845
2921
|
schema: REVIEW_LAST_EVENT_CLOSURE_SCHEMA,
|
|
2846
2922
|
operation,
|
|
2847
2923
|
lineageId: lineage(body.lineage_id, "last_event_closure.lineage_id"),
|
|
2848
2924
|
state,
|
|
2849
2925
|
storeRevision: sha256(body.store_revision, "last_event_closure.store_revision"),
|
|
2850
|
-
|
|
2926
|
+
...(escalation === undefined ? {} : { escalation }),
|
|
2927
|
+
...(targetedValidatorEvidence === undefined ? {} : { targetedValidatorEvidence }),
|
|
2928
|
+
} ;
|
|
2851
2929
|
if (operation === REVIEW_LAST_EVENT_CLOSURE_OPERATION.CAPTURE_CORRECTION_PLAN) {
|
|
2852
2930
|
if (body.reviewer_results !== undefined) throw new TypeError("last_event_closure reviewer_results requires approved state");
|
|
2853
2931
|
if (body.action !== undefined || body.advisory_findings !== undefined || body.status_continuation !== undefined) throw new TypeError("last_event_closure correction-plan cannot carry action, advisory_findings, or status_continuation");
|
|
@@ -140,18 +140,23 @@ const DUE_REVIEW_REASONS = [REVIEW_DUE_REASON.HIGH_R
|
|
|
140
140
|
|
|
141
141
|
/**
|
|
142
142
|
* Rejects a review_due/review_due_reason/consumed combination the native
|
|
143
|
-
* schema can never produce.
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
143
|
+
* schema can never produce. A consumed candidate must report
|
|
144
|
+
* `already_reviewed`, but that reason can also describe an acknowledged
|
|
145
|
+
* committed predecessor followed by a passive delta (#1954). It does not
|
|
146
|
+
* prove this exact candidate was consumed; preserve native's explicit false.
|
|
147
|
+
* Native v2 requires consumed, so missing evidence with already_reviewed is
|
|
148
|
+
* still rejected. Envelopes without the pair (older binaries) are unchecked.
|
|
147
149
|
*/
|
|
148
150
|
function validateReviewDueConsistency(reviewDue , reviewDueReason , candidate ) {
|
|
149
151
|
if (reviewDue !== DUE_REVIEW_REASONS.includes(reviewDueReason)) {
|
|
150
152
|
throw new TypeError(`review assessment review_due ${reviewDue} contradicts review_due_reason ${reviewDueReason}`);
|
|
151
153
|
}
|
|
152
154
|
const alreadyReviewed = reviewDueReason === REVIEW_DUE_REASON.ALREADY_REVIEWED;
|
|
153
|
-
if (
|
|
154
|
-
throw new TypeError("review assessment
|
|
155
|
+
if (candidate.consumed === true && !alreadyReviewed) {
|
|
156
|
+
throw new TypeError("review assessment candidate.consumed true requires review_due_reason already_reviewed");
|
|
157
|
+
}
|
|
158
|
+
if (alreadyReviewed && candidate.consumed === undefined) {
|
|
159
|
+
throw new TypeError("review assessment review_due_reason already_reviewed requires explicit candidate.consumed evidence");
|
|
155
160
|
}
|
|
156
161
|
}
|
|
157
162
|
|
|
@@ -260,6 +265,53 @@ export const VERIFICATION_TIER = {
|
|
|
260
265
|
} ;
|
|
261
266
|
|
|
262
267
|
|
|
268
|
+
// ---------------------------------------------------------------------------
|
|
269
|
+
// Agent-raised risk (gentle-shell#1494). The agent that made the change may
|
|
270
|
+
// raise its risk to high by citing one item of the high-risk list in the
|
|
271
|
+
// always-on Task Size section; it can never lower a tier. Lowering stays with
|
|
272
|
+
// the deterministic native assessment.
|
|
273
|
+
// ---------------------------------------------------------------------------
|
|
274
|
+
|
|
275
|
+
export const HIGH_RISK_ITEMS = Object.freeze({
|
|
276
|
+
1: "data or irreversible effects",
|
|
277
|
+
2: "security",
|
|
278
|
+
3: "changing or removing contracts others already consume",
|
|
279
|
+
4: "concurrency",
|
|
280
|
+
5: "delivery or environment",
|
|
281
|
+
6: "no test would catch a regression",
|
|
282
|
+
} );
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
export const AGENT_RISK_ESCALATION_REASON_MAX = 500;
|
|
291
|
+
|
|
292
|
+
export function decodeAgentRiskEscalation(value ) {
|
|
293
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
294
|
+
throw new Error("escalate must be an object with item and reason");
|
|
295
|
+
}
|
|
296
|
+
const record = value ;
|
|
297
|
+
const unexpected = Object.keys(record).find((key) => key !== "item" && key !== "reason");
|
|
298
|
+
if (unexpected !== undefined) throw new Error(`escalate does not accept ${unexpected}`);
|
|
299
|
+
const { item, reason } = record;
|
|
300
|
+
if (typeof item !== "number" || !Number.isInteger(item) || !(item in HIGH_RISK_ITEMS)) {
|
|
301
|
+
throw new Error("escalate item must be an integer from 1 to 6 naming a high-risk item");
|
|
302
|
+
}
|
|
303
|
+
if (typeof reason !== "string" || reason.trim() === "" || reason.length > AGENT_RISK_ESCALATION_REASON_MAX) {
|
|
304
|
+
throw new Error(`escalate reason must be a non-empty string of at most ${AGENT_RISK_ESCALATION_REASON_MAX} characters`);
|
|
305
|
+
}
|
|
306
|
+
return Object.freeze({ item: item , reason });
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/** Raises passive or medium to high when the agent escalated; never lowers. */
|
|
310
|
+
export function escalatedRisk(risk , escalation ) {
|
|
311
|
+
if (escalation === undefined) return risk;
|
|
312
|
+
return risk === VERIFICATION_TIER.PASSIVE || risk === VERIFICATION_TIER.MEDIUM ? VERIFICATION_TIER.HIGH : risk;
|
|
313
|
+
}
|
|
314
|
+
|
|
263
315
|
export const RDD_LINE = {
|
|
264
316
|
ON: "on",
|
|
265
317
|
OFF: "off",
|
|
@@ -364,59 +416,33 @@ function nonClosedOutcomeClause(outcome ) {
|
|
|
364
416
|
}
|
|
365
417
|
|
|
366
418
|
/**
|
|
367
|
-
* Computes who verifies a delegated writer's change
|
|
368
|
-
*
|
|
419
|
+
* Computes who verifies a delegated writer's change. Verification follows the
|
|
420
|
+
* native risk tier whatever the RDD line and native review outcome
|
|
421
|
+
* (verify-always-rdd-high S1, superseding the gentle-pi#662/#668 on-path): the
|
|
422
|
+
* native review is an additional outside view and never replaces or skips the
|
|
423
|
+
* tier's verification. `nativeReviewOutcome` only shapes the reason text.
|
|
369
424
|
*
|
|
370
|
-
* - `
|
|
371
|
-
*
|
|
372
|
-
*
|
|
373
|
-
*
|
|
374
|
-
*
|
|
375
|
-
*
|
|
376
|
-
*
|
|
377
|
-
*
|
|
378
|
-
*
|
|
379
|
-
*
|
|
380
|
-
* never lowers a tier relative to `off`; `nativeReviewOutcome` is ignored
|
|
381
|
-
* entirely on these lines):
|
|
382
|
-
* - `passive`: structural readback by the parent only; no verifier, no
|
|
383
|
-
* tests.
|
|
384
|
-
* - `medium`: the writer self-verifies; a separate independent verifier
|
|
385
|
-
* runs only when `writerProfile` is `"small"` -- the small-model bias
|
|
386
|
-
* raises the tier by one for verification purposes (medium -> high). An
|
|
387
|
-
* unknown or omitted writer profile resolves to `"small"` before it
|
|
388
|
-
* reaches this function (see `resolveWriterProfile`), so an unrecognized
|
|
389
|
-
* profile never lowers a tier below what a known small model would get.
|
|
390
|
-
* - `high` or `unassessable` (a failed or unrecognized native assessment is
|
|
391
|
-
* always treated as high): the writer self-verifies and an independent
|
|
392
|
-
* verifier always runs.
|
|
425
|
+
* - `passive`: structural readback by the parent only; no verifier, no tests.
|
|
426
|
+
* - `medium`: the writer self-verifies; a separate independent verifier runs
|
|
427
|
+
* only when `writerProfile` is `"small"` -- the small-model bias raises the
|
|
428
|
+
* tier by one for verification purposes (medium -> high). An unknown or
|
|
429
|
+
* omitted writer profile resolves to `"small"` before it reaches this
|
|
430
|
+
* function (see `resolveWriterProfile`), so an unrecognized profile never
|
|
431
|
+
* lowers a tier below what a known small model would get.
|
|
432
|
+
* - `high` or `unassessable` (a failed or unrecognized native assessment is
|
|
433
|
+
* always treated as high): the writer self-verifies and an independent
|
|
434
|
+
* verifier always runs.
|
|
393
435
|
*/
|
|
394
436
|
export function verificationPlan(input ) {
|
|
395
437
|
const { rddLine, risk, writerProfile } = input;
|
|
396
438
|
|
|
397
439
|
if (rddLine === RDD_LINE.ON) {
|
|
398
440
|
const outcome = input.nativeReviewOutcome ?? NATIVE_REVIEW_OUTCOME.UNKNOWN;
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
writerSelfVerification: false,
|
|
403
|
-
structuralReadbackOnly: true,
|
|
404
|
-
independentVerifier: false,
|
|
405
|
-
reason: "receipt-driven development is on and the native review closed for this candidate; the assessment also reports passive risk: a structural readback by the parent replaces both the writer's self-verification and any separate verifier.",
|
|
406
|
-
});
|
|
407
|
-
}
|
|
408
|
-
return Object.freeze({
|
|
409
|
-
writerSelfVerification: true,
|
|
410
|
-
structuralReadbackOnly: false,
|
|
411
|
-
independentVerifier: false,
|
|
412
|
-
reason: "receipt-driven development is on and the native review closed for this candidate: the writer's self-verification is the record and the closed native review was the independent check the writer cannot influence, so no separate verifier is required.",
|
|
413
|
-
});
|
|
414
|
-
}
|
|
415
|
-
// The on branch holds only while the native review reaches a terminal
|
|
416
|
-
// outcome for this candidate. Anything else -- declined, unavailable, or
|
|
417
|
-
// unknown -- falls back to the exact same risk-gated path as off.
|
|
441
|
+
const clause = outcome === NATIVE_REVIEW_OUTCOME.CLOSED
|
|
442
|
+
? "the native review closed for this candidate"
|
|
443
|
+
: nonClosedOutcomeClause(outcome);
|
|
418
444
|
return riskGatedPlan(
|
|
419
|
-
`receipt-driven development is on
|
|
445
|
+
`receipt-driven development is on and ${clause}; the native review is an additional outside view that never replaces verification, so the risk-gated path applies exactly as receipt-driven development off, and`,
|
|
420
446
|
risk,
|
|
421
447
|
writerProfile,
|
|
422
448
|
);
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
// Generated by scripts/build-runtime-modules.mjs. Do not edit.
|
|
2
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
const MAX_STATUSES = 8;
|
|
7
|
+
const MAX_ACTIVE_OBSERVATIONS = 8;
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
const hostScope = new AsyncLocalStorage ();
|
|
38
|
+
const nativeScope = new AsyncLocalStorage ();
|
|
39
|
+
|
|
40
|
+
// Observer failures must never replace the operation's result or exception.
|
|
41
|
+
function safely (run ) {
|
|
42
|
+
try { return run(); } catch { return undefined; }
|
|
43
|
+
}
|
|
44
|
+
function now(host ) {
|
|
45
|
+
const value = safely(host.clock);
|
|
46
|
+
if (value !== undefined && Number.isFinite(value) && value >= 0) return value;
|
|
47
|
+
host.summary.clock_unavailable = true;
|
|
48
|
+
return 0;
|
|
49
|
+
}
|
|
50
|
+
function elapsed(start , end ) { return Math.max(0, end - start); }
|
|
51
|
+
|
|
52
|
+
// Failure/v2 codes and next_action are extensible strings, not safe diagnostic
|
|
53
|
+
// text. Only recognized values enter this summary; no messages or raw envelopes.
|
|
54
|
+
const CLI_CODES = new Set(["unavailable", "timeout", "non-zero", "signal", "unexpected-stderr", "output-limit", "empty-output", "malformed-json", "schema-incompatible", "identity-mismatch", "version-incompatible", "cancelled", "package-local-binary-missing", "unsupported-transition-operation"]);
|
|
55
|
+
const NATIVE_CODES = new Set(["operation_timeout", "invalid_request", "binding_revision_conflict", "internal_error", "cancelled"]);
|
|
56
|
+
function outcome(error ) {
|
|
57
|
+
return safely(() => {
|
|
58
|
+
if (typeof error !== "object" || error === null) return { kind: "unknown" };
|
|
59
|
+
const value = error ;
|
|
60
|
+
if (value.name === "NativeReviewCliError") return { kind: "cli_error", code: typeof value.code === "string" && CLI_CODES.has(value.code) ? value.code : "other" };
|
|
61
|
+
if (value.name !== "NativeReviewIntegrationError" || !value.failureEnvelope) return { kind: "unknown" };
|
|
62
|
+
const failure = value.failureEnvelope;
|
|
63
|
+
const result = { kind: "native_failure", code: typeof failure.code === "string" && NATIVE_CODES.has(failure.code) ? failure.code : "other" };
|
|
64
|
+
if (["preflight", "pre_native", "native_running", "native_committed", "reconciliation"].includes(String(failure.phase))) result.phase = String(failure.phase);
|
|
65
|
+
if (["not_started", "committed", "unknown"].includes(String(failure.mutationOutcome))) result.mutation_outcome = String(failure.mutationOutcome);
|
|
66
|
+
if (typeof failure.retrySafe === "boolean") result.retry_safe = failure.retrySafe;
|
|
67
|
+
if (["stop", "review.status"].includes(String(failure.nextAction))) result.next_action = String(failure.nextAction);
|
|
68
|
+
return result;
|
|
69
|
+
}) ?? { kind: "unknown" };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** The next already-authorized STATUS-bearing tool call consumes the arm. */
|
|
73
|
+
export class StatusTimingDiagnostics {
|
|
74
|
+
armed = false;
|
|
75
|
+
epoch = 0;
|
|
76
|
+
manager ;
|
|
77
|
+
session ;
|
|
78
|
+
last ;
|
|
79
|
+
active = new Set ();
|
|
80
|
+
clock ;
|
|
81
|
+
constructor(clock = () => performance.now()) { this.clock = clock; }
|
|
82
|
+
|
|
83
|
+
reset(ctx ) {
|
|
84
|
+
this.epoch++;
|
|
85
|
+
this.armed = false;
|
|
86
|
+
this.last = undefined;
|
|
87
|
+
for (const host of this.active) host.summary.statuses.length = 0;
|
|
88
|
+
this.active.clear();
|
|
89
|
+
this.manager = ctx?.sessionManager;
|
|
90
|
+
this.session = safely(() => ctx?.sessionManager.getSessionId());
|
|
91
|
+
}
|
|
92
|
+
matches(ctx ) {
|
|
93
|
+
return safely(() => this.manager === ctx.sessionManager && !!this.session && this.session === ctx.sessionManager.getSessionId()) === true;
|
|
94
|
+
}
|
|
95
|
+
command(args , ctx ) {
|
|
96
|
+
if (!this.matches(ctx)) this.reset(ctx);
|
|
97
|
+
const action = args.trim() || "show";
|
|
98
|
+
if (action === "enable") {
|
|
99
|
+
this.reset(ctx);
|
|
100
|
+
this.armed = !!this.session;
|
|
101
|
+
ctx.ui.notify(this.armed
|
|
102
|
+
? "STATUS timing armed for the next separately authorized STATUS-bearing tool call. No STATUS is invoked or retried. Use /gentle:status-timing show to consult the completed summary."
|
|
103
|
+
: "STATUS timing requires a live session.", "info");
|
|
104
|
+
} else if (action === "disable") {
|
|
105
|
+
this.reset(ctx);
|
|
106
|
+
ctx.ui.notify("STATUS timing disabled; in-memory observations cleared.", "info");
|
|
107
|
+
} else if (action === "show") {
|
|
108
|
+
ctx.ui.notify(this.last ? JSON.stringify(this.last, null, 2) : `No completed STATUS timing summary. Diagnostic is ${this.armed ? "armed" : "off"}.`, "info");
|
|
109
|
+
} else {
|
|
110
|
+
ctx.ui.notify("Unknown /gentle:status-timing sub-action. Use enable, disable, or show.", "warning");
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
tool (definition ) {
|
|
114
|
+
return {
|
|
115
|
+
...definition,
|
|
116
|
+
execute: async (toolCallId, params, signal, onUpdate, ctx) => {
|
|
117
|
+
const run = () => definition.execute(toolCallId, params, signal, onUpdate, ctx);
|
|
118
|
+
if (!this.matches(ctx)) this.reset(ctx);
|
|
119
|
+
if (!this.armed || this.active.size >= MAX_ACTIVE_OBSERVATIONS) return run();
|
|
120
|
+
const epoch = this.epoch;
|
|
121
|
+
const host = {
|
|
122
|
+
clock: this.clock,
|
|
123
|
+
current: () => this.epoch === epoch && this.matches(ctx),
|
|
124
|
+
claim: () => {
|
|
125
|
+
if (!host.current() || !this.armed) return false;
|
|
126
|
+
this.armed = false;
|
|
127
|
+
return true;
|
|
128
|
+
},
|
|
129
|
+
claimed: false, started: 0, lastNativeEnd: 0,
|
|
130
|
+
summary: { schema: "gentle-pi.status-timing/v1", host_total_ms: 0, dispatch_ms: 0, sidebar_ms: 0, completion_ms: 0, truncated: false, statuses: [] },
|
|
131
|
+
};
|
|
132
|
+
this.active.add(host);
|
|
133
|
+
host.started = now(host);
|
|
134
|
+
return hostScope.run(host, async () => {
|
|
135
|
+
try { return await run(); }
|
|
136
|
+
finally {
|
|
137
|
+
this.active.delete(host);
|
|
138
|
+
safely(() => {
|
|
139
|
+
if (!host.claimed || !host.current()) return;
|
|
140
|
+
const ended = now(host);
|
|
141
|
+
host.summary.host_total_ms = elapsed(host.started, ended);
|
|
142
|
+
host.summary.completion_ms = elapsed(host.lastNativeEnd, ended);
|
|
143
|
+
this.last = host.summary;
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** Only called by the existing STATUS entry points; never invokes one itself. */
|
|
153
|
+
export async function observeNativeStatus (timeoutMs , run ) {
|
|
154
|
+
const host = hostScope.getStore();
|
|
155
|
+
if (!host || !safely(host.current)) return run();
|
|
156
|
+
if (!host.claimed) {
|
|
157
|
+
if (!safely(host.claim)) return run();
|
|
158
|
+
host.claimed = true;
|
|
159
|
+
host.summary.dispatch_ms = elapsed(host.started, now(host));
|
|
160
|
+
}
|
|
161
|
+
const sample = { timeout_ms: timeoutMs, total_ms: 0, resolution_ms: 0, adapter_ms: 0, decode_ms: 0, outcome: { kind: "success" } };
|
|
162
|
+
if (host.summary.statuses.length < MAX_STATUSES) host.summary.statuses.push(sample);
|
|
163
|
+
else host.summary.truncated = true;
|
|
164
|
+
const started = now(host);
|
|
165
|
+
return nativeScope.run({ host, sample }, async () => {
|
|
166
|
+
try { return await run(); }
|
|
167
|
+
catch (error) { safely(() => { sample.outcome = outcome(error); }); throw error; }
|
|
168
|
+
finally {
|
|
169
|
+
safely(() => {
|
|
170
|
+
const ended = now(host);
|
|
171
|
+
sample.total_ms = elapsed(started, ended);
|
|
172
|
+
host.lastNativeEnd = ended;
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function activeNative() {
|
|
179
|
+
const observation = nativeScope.getStore();
|
|
180
|
+
return observation && safely(observation.host.current) ? observation : undefined;
|
|
181
|
+
}
|
|
182
|
+
export function measureStatusSync (stage , run ) {
|
|
183
|
+
const observation = activeNative();
|
|
184
|
+
if (!observation) return run();
|
|
185
|
+
const started = now(observation.host);
|
|
186
|
+
try { return run(); }
|
|
187
|
+
finally { safely(() => { observation.sample[`${stage}_ms`] += elapsed(started, now(observation.host)); }); }
|
|
188
|
+
}
|
|
189
|
+
export async function measureStatusAsync (stage , run ) {
|
|
190
|
+
const observation = activeNative();
|
|
191
|
+
if (!observation) return run();
|
|
192
|
+
const started = now(observation.host);
|
|
193
|
+
try { return await run(); }
|
|
194
|
+
finally { safely(() => { observation.sample[`${stage}_ms`] += elapsed(started, now(observation.host)); }); }
|
|
195
|
+
}
|
|
196
|
+
export function measureStatusSidebar (run ) {
|
|
197
|
+
const host = hostScope.getStore();
|
|
198
|
+
if (!host || !safely(host.current)) return run();
|
|
199
|
+
const started = now(host);
|
|
200
|
+
try { return run(); }
|
|
201
|
+
finally { safely(() => { host.summary.sidebar_ms += elapsed(started, now(host)); }); }
|
|
202
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Generated by scripts/build-runtime-modules.mjs. Do not edit.
|
|
2
2
|
import { spawn as nodeSpawn } from "node:child_process";
|
|
3
|
+
import { gentleAiIsolationEnv } from "./gentle-ai-binary.mjs";
|
|
3
4
|
|
|
4
5
|
// gentle-ai#4309 owns anonymous usage telemetry end to end: install and
|
|
5
6
|
// heartbeat events, the notice, every kill switch, and the wire contract.
|
|
@@ -129,7 +130,8 @@ export function spawnTelemetryTrigger(options )
|
|
|
129
130
|
try {
|
|
130
131
|
const child = spawnImpl(options.executable, ["telemetry", "trigger", "--json"], {
|
|
131
132
|
cwd: options.cwd,
|
|
132
|
-
|
|
133
|
+
// S9: a bundled install keeps Gentle AI's telemetry state inside its prefix.
|
|
134
|
+
env: gentleAiIsolationEnv(options.env),
|
|
133
135
|
detached: true,
|
|
134
136
|
windowsHide: true,
|
|
135
137
|
stdio: "ignore",
|