toolroll 0.9.104 → 0.9.105
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 +62 -5
- package/README.md +18 -20
- package/dist/accent-colors.js +0 -29
- package/dist/acp-agents.js +0 -3
- package/dist/acp-attest.js +0 -30
- package/dist/acp-check.js +3 -70
- package/dist/acp-client.js +3 -94
- package/dist/acp-inspect.js +1 -20
- package/dist/action-ledger.js +0 -8
- package/dist/activity-line.js +0 -14
- package/dist/actor.js +0 -15
- package/dist/advanced-schema.js +12 -0
- package/dist/advanced-view.js +26 -0
- package/dist/advanced.js +61 -0
- package/dist/agent-board.js +0 -117
- package/dist/agent-fence.js +11 -367
- package/dist/agent-onboard.js +12 -50
- package/dist/agent-pulse.js +5 -38
- package/dist/agent-state-words.js +0 -8
- package/dist/agent-state.js +1 -45
- package/dist/agent-turns.js +3 -17
- package/dist/agentconfig.js +1 -99
- package/dist/agents-board.js +0 -60
- package/dist/agents-live.js +1 -8
- package/dist/api-tokens.js +0 -27
- package/dist/approval-authority.js +0 -59
- package/dist/approval-password.js +0 -10
- package/dist/approval-policy.js +0 -29
- package/dist/approval-rules-ui.js +0 -9
- package/dist/assignment-adapters.js +0 -14
- package/dist/assignment-brief.js +1 -17
- package/dist/assignment-delivery.js +0 -22
- package/dist/assignment-presentation.js +0 -14
- package/dist/assignment-status.js +1 -30
- package/dist/assignment-ui.js +0 -12
- package/dist/assignment.js +17 -139
- package/dist/attest.js +0 -38
- package/dist/audit-cli.js +0 -9
- package/dist/backend.js +0 -59
- package/dist/backup-ui.js +0 -12
- package/dist/backup.js +8 -61
- package/dist/batch-checks.js +0 -20
- package/dist/batch-policy.js +0 -4
- package/dist/beads.js +0 -48
- package/dist/bin.js +0 -8
- package/dist/board.js +1 -36
- package/dist/boot-identity.js +0 -42
- package/dist/bounded-spawn.js +4 -28
- package/dist/brand-mark.js +0 -21
- package/dist/brief-fence.js +0 -16
- package/dist/browser/terminal.css +1 -1
- package/dist/browser/terminal.js +16 -16
- package/dist/browser/workspace.css +2 -2
- package/dist/browser/workspace.js +26 -26
- package/dist/browser-crew.js +0 -8
- package/dist/browser-shell.js +2 -15
- package/dist/browser-workspace.js +6 -30
- package/dist/budget-alerts.js +1 -4
- package/dist/build-review.js +2 -50
- package/dist/builder-restart.js +0 -13
- package/dist/builder.js +21 -1035
- package/dist/canonical-json.js +0 -12
- package/dist/capscan.js +1 -32
- package/dist/card-catalog.js +0 -12
- package/dist/card-cli.js +0 -1
- package/dist/card-render.js +0 -25
- package/dist/card-sources.js +0 -10
- package/dist/chat-acceptance.js +0 -7
- package/dist/chat-actions.js +5 -190
- package/dist/chat-admission.js +0 -7
- package/dist/chat-approval.js +0 -25
- package/dist/chat-ask.js +0 -17
- package/dist/chat-card-part.js +0 -3
- package/dist/chat-card.js +0 -6
- package/dist/chat-channel.js +2 -83
- package/dist/chat-continuity.js +0 -31
- package/dist/chat-controls.js +0 -7
- package/dist/chat-core.js +0 -55
- package/dist/chat-decide.js +2 -153
- package/dist/chat-delivery-state.js +0 -49
- package/dist/chat-delivery.js +2 -143
- package/dist/chat-display.js +0 -2
- package/dist/chat-evidence.js +0 -65
- package/dist/chat-flow.js +0 -72
- package/dist/chat-follow.js +0 -13
- package/dist/chat-inbox.js +0 -34
- package/dist/chat-live-schema.js +0 -14
- package/dist/chat-live.js +2 -87
- package/dist/chat-message-states.js +13 -40
- package/dist/chat-messages.js +0 -153
- package/dist/chat-migration.js +0 -57
- package/dist/chat-polish.js +0 -7
- package/dist/chat-quiet.js +0 -37
- package/dist/chat-review.js +0 -4
- package/dist/chat-rooms.js +0 -22
- package/dist/chat-settings-page.js +0 -4
- package/dist/chat-task-actions.js +0 -7
- package/dist/chat-terms.js +0 -21
- package/dist/chat-voice.js +0 -38
- package/dist/chat-warmth.js +1 -3
- package/dist/check-access.js +0 -30
- package/dist/check-facts.js +2 -62
- package/dist/check-failure.js +0 -98
- package/dist/check-levels-ui.js +4 -10
- package/dist/check-levels.js +3 -35
- package/dist/check-load.js +1 -49
- package/dist/check-only-standing.js +0 -6
- package/dist/check-only.js +0 -22
- package/dist/check-progress.js +0 -32
- package/dist/check-repair.js +2 -35
- package/dist/check-report.js +1 -108
- package/dist/check-stamp.js +0 -20
- package/dist/checkout-cleanup.js +0 -84
- package/dist/checkout-proof.js +1 -13
- package/dist/child-database.js +0 -3
- package/dist/claim.js +4 -508
- package/dist/claude-print.js +0 -10
- package/dist/cli-fast.js +0 -8
- package/dist/cli-help.js +90 -78
- package/dist/cli-http.js +0 -10
- package/dist/cli.js +26 -241
- package/dist/code-extract.js +0 -6
- package/dist/code-map-acts.js +0 -7
- package/dist/code-map-admission.js +2 -26
- package/dist/code-map-build.js +3 -24
- package/dist/code-map-cli.js +0 -4
- package/dist/code-map-main.js +0 -6
- package/dist/code-map-read.js +0 -12
- package/dist/code-map-report.js +0 -9
- package/dist/code-map-shape.js +0 -19
- package/dist/code-map-store.js +0 -26
- package/dist/codex-limits.js +1 -17
- package/dist/coding-context.js +0 -10
- package/dist/coding-handoff.js +0 -14
- package/dist/coding-provider.js +0 -39
- package/dist/coding-shipping-ui.js +0 -1
- package/dist/coding-ui.js +0 -1
- package/dist/coding-update.js +1 -18
- package/dist/coding-workspace.js +0 -27
- package/dist/commit-extract.js +0 -83
- package/dist/connect-cli.js +0 -19
- package/dist/console-chrome.js +1 -34
- package/dist/console-instance.js +2 -91
- package/dist/container-state.js +0 -4
- package/dist/containment.js +2 -105
- package/dist/contract-changes.js +0 -6
- package/dist/contracts/acceptance-terms.js +0 -7
- package/dist/contracts/chat-actions.js +0 -46
- package/dist/contracts/chat-callback-rows.js +0 -8
- package/dist/contracts/chat-card.js +0 -14
- package/dist/contracts/chat-content.js +0 -55
- package/dist/contracts/chat-tables.js +0 -7
- package/dist/contracts/cli.js +0 -59
- package/dist/contracts/coding-activity.js +0 -15
- package/dist/contracts/coding-context.js +0 -15
- package/dist/contracts/coding-handoff.js +0 -11
- package/dist/contracts/coding-workspace.js +0 -14
- package/dist/contracts/console-api.js +1 -54
- package/dist/contracts/contract-test.js +0 -14
- package/dist/contracts/contract.js +0 -48
- package/dist/contracts/decision.js +0 -20
- package/dist/contracts/diff-stat.js +0 -16
- package/dist/contracts/discord-callback.js +0 -9
- package/dist/contracts/flow-card.js +0 -18
- package/dist/contracts/flow-propose.js +0 -8
- package/dist/contracts/flow-send.js +0 -31
- package/dist/contracts/flow.js +0 -112
- package/dist/contracts/gateway-tools.js +0 -22
- package/dist/contracts/handoff.js +0 -22
- package/dist/contracts/integration-metadata.js +0 -39
- package/dist/contracts/lead-context.js +0 -14
- package/dist/contracts/lead-tools.js +0 -49
- package/dist/contracts/mcp-oauth.js +0 -12
- package/dist/contracts/memory-pass.js +0 -21
- package/dist/contracts/model-catalog.js +0 -9
- package/dist/contracts/observation-request.js +0 -11
- package/dist/contracts/plan.js +0 -16
- package/dist/contracts/project-knowledge.js +0 -26
- package/dist/contracts/project-memory.js +0 -16
- package/dist/contracts/project-skills.js +0 -31
- package/dist/contracts/proof.js +0 -23
- package/dist/contracts/provider.js +0 -9
- package/dist/contracts/recipes.js +0 -16
- package/dist/contracts/release-check.js +0 -61
- package/dist/contracts/release-terms.js +0 -27
- package/dist/contracts/retention.js +0 -12
- package/dist/contracts/review-findings.js +0 -13
- package/dist/contracts/route-results.js +0 -15
- package/dist/contracts/route.js +0 -33
- package/dist/contracts/scope.js +0 -29
- package/dist/contracts/scout-report.js +0 -34
- package/dist/contracts/slack-callback.js +0 -11
- package/dist/contracts/sort-answer.js +0 -24
- package/dist/contracts/stage-output.js +0 -46
- package/dist/contracts/storage.js +0 -8
- package/dist/contracts/store-json.js +0 -41
- package/dist/contracts/subagent-turn.js +0 -23
- package/dist/contracts/task-sizing.js +0 -10
- package/dist/contracts/teams-callback.js +0 -7
- package/dist/contracts/telegram-callback.js +0 -27
- package/dist/contracts/trigger-payloads.js +0 -41
- package/dist/contracts/update-journal.js +0 -47
- package/dist/contracts/verification-receipt.js +0 -36
- package/dist/contracts/verification-view.js +0 -15
- package/dist/contracts/youiyoux-request.js +0 -26
- package/dist/control-setup.js +0 -7
- package/dist/control-ui.js +0 -3
- package/dist/controller-service.js +0 -4
- package/dist/controller-supervisor.js +0 -15
- package/dist/converse.js +3 -129
- package/dist/coordinator-proposals.js +1 -6
- package/dist/coordinator.js +0 -65
- package/dist/credentials-ui.js +0 -6
- package/dist/daemon.js +0 -137
- package/dist/database-reclaim.js +0 -3
- package/dist/decision.js +0 -78
- package/dist/demo-chat.js +4 -15
- package/dist/demo-sign-in.js +77 -0
- package/dist/demo.js +5 -194
- package/dist/deploy-gate.js +0 -20
- package/dist/deploy-lock.js +0 -4
- package/dist/deploy-phase.js +0 -22
- package/dist/deploy-rescue.js +0 -21
- package/dist/deprecations.js +0 -12
- package/dist/design/kit.css +9 -6
- package/dist/design/kit.js +2 -33
- package/dist/desktop-access.js +0 -9
- package/dist/desktop-bundle.js +1 -3
- package/dist/desktop-host.js +0 -34
- package/dist/desktop-update-gate.js +0 -8
- package/dist/desktop-update-recovery.js +1 -18
- package/dist/desktop-update.js +2 -48
- package/dist/digest-times.js +0 -2
- package/dist/disclosure.js +0 -5
- package/dist/discord-api.js +0 -6
- package/dist/discord-chat.js +0 -31
- package/dist/discord.js +0 -7
- package/dist/discover.js +0 -50
- package/dist/dispatch.js +61 -60
- package/dist/dispose.js +0 -208
- package/dist/doctor.js +0 -48
- package/dist/easy-start-args.js +7 -7
- package/dist/easy-start.js +32 -45
- package/dist/egress.js +1 -63
- package/dist/email-settings.js +0 -8
- package/dist/envelope.js +50 -86
- package/dist/eval-gate.js +1 -37
- package/dist/eval-hooks.js +0 -120
- package/dist/eval-oracle-main.js +0 -7
- package/dist/eval-oracle.js +3 -42
- package/dist/eval-world.js +1 -23
- package/dist/evals.js +6 -134
- package/dist/evidence-pack.js +0 -29
- package/dist/evidence-pair.js +0 -17
- package/dist/evidence.js +4 -280
- package/dist/exec.js +19 -404
- package/dist/exhaustion.js +0 -30
- package/dist/export-ui.js +0 -7
- package/dist/export.js +1 -38
- package/dist/failing-first.js +0 -6
- package/dist/fallback-schema.js +0 -5
- package/dist/fallback.js +0 -81
- package/dist/fast-start.js +0 -97
- package/dist/fast-terms.js +0 -3
- package/dist/fenced-check-coverage.js +0 -11
- package/dist/findings.js +1 -63
- package/dist/first-run.js +4 -57
- package/dist/first-tasks-child.js +0 -5
- package/dist/flaky-ci.js +1 -24
- package/dist/flaky-cli.js +0 -4
- package/dist/flaky.js +0 -43
- package/dist/fleet-schema.js +0 -11
- package/dist/flow-actions.js +0 -31
- package/dist/flow-browser.js +0 -42
- package/dist/flow-cadence.js +1 -24
- package/dist/flow-card-task.js +0 -11
- package/dist/flow-changed.js +0 -16
- package/dist/flow-code.js +1 -45
- package/dist/flow-draft.js +0 -17
- package/dist/flow-engine.js +2 -76
- package/dist/flow-gallery-ui.js +0 -28
- package/dist/flow-gallery.js +0 -54
- package/dist/flow-insights.js +0 -12
- package/dist/flow-items.js +0 -27
- package/dist/flow-live.js +0 -31
- package/dist/flow-people.js +0 -14
- package/dist/flow-pull-request.js +0 -32
- package/dist/flow-replies.js +0 -9
- package/dist/flow-result-card.js +0 -8
- package/dist/flow-schedule.js +0 -74
- package/dist/flow-scripts.js +0 -13
- package/dist/flow-secrets.js +0 -10
- package/dist/flow-send.js +0 -45
- package/dist/flow-share.js +0 -60
- package/dist/flow-sort.js +1 -24
- package/dist/flow-starters-ui.js +0 -2
- package/dist/flow-starters.js +0 -13
- package/dist/flow-steps.js +0 -80
- package/dist/flow-triggers.js +2 -256
- package/dist/flow-unattended-words.js +0 -13
- package/dist/flow-unattended.js +2 -115
- package/dist/flows-cli.js +2 -36
- package/dist/flows-ui.js +0 -51
- package/dist/flows.js +0 -158
- package/dist/folder-gate.js +0 -21
- package/dist/folder-look.js +0 -42
- package/dist/follow-through-brief.js +0 -6
- package/dist/follow-through-cli.js +0 -5
- package/dist/fonts.js +0 -13
- package/dist/gaps.js +0 -20
- package/dist/gate-failure.js +0 -7
- package/dist/git-floor.js +0 -12
- package/dist/git-incident.js +2 -38
- package/dist/git-views.js +0 -24
- package/dist/git.js +0 -31
- package/dist/github-import.js +0 -22
- package/dist/github-jobs.js +0 -12
- package/dist/google-mail.js +2 -27
- package/dist/grant.js +0 -110
- package/dist/graph.js +0 -108
- package/dist/guides.js +4 -15
- package/dist/handover-note.js +0 -12
- package/dist/health-cli.js +0 -2
- package/dist/home-groups.js +0 -15
- package/dist/html.js +0 -54
- package/dist/install-method.js +0 -12
- package/dist/integrations-ui.js +0 -15
- package/dist/integrations.js +7 -50
- package/dist/invoke.js +1 -381
- package/dist/is-record.js +0 -1
- package/dist/issues.js +0 -48
- package/dist/jsonl-discriminants.js +0 -6
- package/dist/keymap.js +0 -17
- package/dist/keys.js +0 -56
- package/dist/kits-ui.js +0 -3
- package/dist/kits.js +1 -24
- package/dist/knowledge-cli.js +0 -4
- package/dist/knowledge-ui.js +0 -8
- package/dist/landed-cleanup.js +0 -119
- package/dist/laptop-background.js +0 -85
- package/dist/laptop-service.js +0 -67
- package/dist/latency-timeline.js +2 -23
- package/dist/lead-about.js +0 -7
- package/dist/lead-answer-eval.js +0 -39
- package/dist/lead-capabilities.js +0 -19
- package/dist/lead-cli-live.js +0 -22
- package/dist/lead-cli.js +0 -27
- package/dist/lead-commitments.js +1 -27
- package/dist/lead-context.js +2 -42
- package/dist/lead-contract.js +0 -8
- package/dist/lead-doors.js +0 -105
- package/dist/lead-follow.js +0 -41
- package/dist/lead-identity.js +1 -4
- package/dist/lead-latency-schema.js +0 -13
- package/dist/lead-people.js +3 -18
- package/dist/lead-progress.js +0 -12
- package/dist/lead-queue-runtime.js +0 -26
- package/dist/lead-queue.js +0 -35
- package/dist/lead-route.js +0 -33
- package/dist/lead-status.js +0 -37
- package/dist/lead-sweep.js +0 -18
- package/dist/lead-tools.js +0 -160
- package/dist/lead-voice.js +0 -54
- package/dist/lead.js +2 -105
- package/dist/learning-child.js +0 -6
- package/dist/learning-look.js +0 -14
- package/dist/ledger-chain.js +0 -34
- package/dist/ledger-csv.js +0 -2
- package/dist/ledger-view.js +0 -3
- package/dist/lesson-notes.js +0 -56
- package/dist/limits-ui.js +0 -14
- package/dist/link.js +0 -79
- package/dist/live-backup.js +3 -33
- package/dist/live-bus.js +7 -81
- package/dist/live-children-read.js +4 -47
- package/dist/live-children.js +4 -44
- package/dist/live-detail.js +0 -17
- package/dist/live-input.js +5 -68
- package/dist/live-main-read.js +1 -14
- package/dist/live-notes.js +0 -12
- package/dist/live-open.js +1 -23
- package/dist/live-records.js +4 -151
- package/dist/live-reply.js +1 -51
- package/dist/live-terminal.js +12 -111
- package/dist/live.js +4 -130
- package/dist/local-owner-acts.js +0 -53
- package/dist/local-owner.js +2 -93
- package/dist/log.js +0 -8
- package/dist/login-secrets.js +2 -38
- package/dist/machine-check.js +0 -2
- package/dist/machine-identity.js +1 -46
- package/dist/mailbox.js +0 -30
- package/dist/maintenance.js +1 -3
- package/dist/mcp-connect.js +0 -88
- package/dist/mcp-core.js +0 -45
- package/dist/mcp-http.js +0 -13
- package/dist/mcp-oauth.js +0 -37
- package/dist/mcp-person.js +0 -11
- package/dist/mcp.js +3 -73
- package/dist/memory-cli.js +0 -3
- package/dist/memory-pass.js +0 -53
- package/dist/memory-tidy.js +0 -55
- package/dist/memory-use.js +2 -24
- package/dist/merge-checklist.js +21 -29
- package/dist/metrics.js +0 -10
- package/dist/mobile-viewport.js +0 -6
- package/dist/model-catalog.js +1 -33
- package/dist/model-choices.js +9 -84
- package/dist/model-names.js +0 -9
- package/dist/models-cli.js +0 -13
- package/dist/models-ui.js +0 -17
- package/dist/modes.js +0 -35
- package/dist/monitoring-settings.js +2 -27
- package/dist/monitoring-ui.js +2 -14
- package/dist/monitoring.js +2 -38
- package/dist/names.js +0 -39
- package/dist/needs-you.js +7 -70
- package/dist/never-index.js +0 -9
- package/dist/nightly-check.js +0 -74
- package/dist/nightly-github.js +0 -168
- package/dist/notification-delivery.js +0 -3
- package/dist/notification-rows.js +0 -17
- package/dist/oauth-run-token.js +1 -37
- package/dist/observations.js +0 -16
- package/dist/oidc.js +1 -20
- package/dist/onboard.js +4 -57
- package/dist/one-step-chat-schema.js +0 -15
- package/dist/openrouter-models.js +0 -6
- package/dist/operate-remote-arguments.js +0 -17
- package/dist/operate-remote.js +0 -33
- package/dist/operate.js +227 -2326
- package/dist/orphan-sweep.js +3 -37
- package/dist/page-work-contract.js +0 -3
- package/dist/password-bearer.js +1 -11
- package/dist/passwordless.js +0 -3
- package/dist/peek-cli.js +0 -46
- package/dist/peek.js +2 -61
- package/dist/people-audit-ui.js +0 -6
- package/dist/person-proof.js +0 -6
- package/dist/phase-routing.js +8 -183
- package/dist/plain-schema.js +0 -14
- package/dist/plain-words.js +18 -12
- package/dist/plan-auto.js +0 -20
- package/dist/plan-login.js +0 -16
- package/dist/plan.js +0 -68
- package/dist/plane-review.js +0 -56
- package/dist/planner-source.js +0 -96
- package/dist/planner.js +0 -117
- package/dist/policy-ui.js +0 -8
- package/dist/policy.js +0 -47
- package/dist/prepared-evidence.js +0 -5
- package/dist/principal.js +0 -29
- package/dist/probe.js +0 -30
- package/dist/process-custody.js +0 -15
- package/dist/process-liveness.js +0 -32
- package/dist/process-tree.js +3 -29
- package/dist/project-access.js +0 -10
- package/dist/project-admission.js +1 -41
- package/dist/project-cli.js +0 -6
- package/dist/project-concurrency.js +0 -35
- package/dist/project-delete-ui.js +4 -29
- package/dist/project-delete.js +1 -73
- package/dist/project-demo.js +0 -13
- package/dist/project-file.js +0 -2
- package/dist/project-identity.js +0 -41
- package/dist/project-knowledge.js +0 -39
- package/dist/project-learning.js +3 -55
- package/dist/project-memory.js +2 -45
- package/dist/project-outcomes.js +0 -6
- package/dist/project-sandbox.js +0 -23
- package/dist/project-skills.js +0 -12
- package/dist/project-tools.js +6 -184
- package/dist/project.js +0 -48
- package/dist/prompt.js +0 -31
- package/dist/proof.js +0 -220
- package/dist/proposal.js +0 -50
- package/dist/protected-storage-look.js +0 -6
- package/dist/protected-storage.js +1 -84
- package/dist/provider-auth.js +3 -69
- package/dist/provider-capture.js +1 -15
- package/dist/provider-connection.js +0 -8
- package/dist/provider-home.js +0 -25
- package/dist/provider-limits.js +0 -14
- package/dist/provider.js +0 -324
- package/dist/public-access.js +0 -34
- package/dist/public-check.js +0 -16
- package/dist/publish.js +1 -150
- package/dist/pull-request-flow.js +0 -77
- package/dist/pull-request-schema.js +0 -4
- package/dist/pull-request-ui.js +0 -5
- package/dist/pulls.js +0 -80
- package/dist/push.js +5 -89
- package/dist/quick-start.js +1 -23
- package/dist/read-executor-worker.js +0 -1
- package/dist/read-executor.js +0 -10
- package/dist/read-only-request.js +0 -7
- package/dist/recipe-ui.js +0 -6
- package/dist/recipes.js +0 -13
- package/dist/release-adapters.js +6 -214
- package/dist/release-approval.js +0 -74
- package/dist/release-authority.js +0 -42
- package/dist/release-auto.js +0 -142
- package/dist/release-card.js +0 -100
- package/dist/release-carry.js +0 -132
- package/dist/release-ci-hold.js +0 -20
- package/dist/release-cli.js +0 -46
- package/dist/release-coverage.js +0 -16
- package/dist/release-gate.js +0 -30
- package/dist/release-git.js +0 -24
- package/dist/release-links.js +0 -17
- package/dist/release-net.js +0 -42
- package/dist/release-next.js +0 -25
- package/dist/release-recheck.js +0 -89
- package/dist/release-refusal.js +0 -18
- package/dist/release-view.js +0 -5
- package/dist/release.js +7 -341
- package/dist/releases.js +0 -49
- package/dist/remote-audit.js +0 -25
- package/dist/remote-command.js +0 -16
- package/dist/remote-destination.js +5 -26
- package/dist/remote-exec.js +1 -27
- package/dist/remote-main.js +1 -53
- package/dist/remote-run.js +0 -5
- package/dist/remote.js +0 -49
- package/dist/render.js +0 -133
- package/dist/reply-shape.js +0 -85
- package/dist/reply-voice.js +0 -7
- package/dist/report-summary.js +0 -5
- package/dist/reported-usage.js +0 -30
- package/dist/repos.js +9 -62
- package/dist/repository-context.js +1 -24
- package/dist/request-budget-ui.js +0 -4
- package/dist/request-budget.js +0 -23
- package/dist/restart-certification.js +0 -37
- package/dist/result-actions.js +0 -62
- package/dist/result-acts.js +0 -34
- package/dist/result-completion.js +0 -25
- package/dist/result-evidence-readers.js +0 -3
- package/dist/result-follow-ups.js +1 -39
- package/dist/result-review.js +0 -86
- package/dist/result-shots.js +0 -39
- package/dist/retention-ui.js +0 -7
- package/dist/retention.js +2 -46
- package/dist/review-context.js +0 -129
- package/dist/review-evidence.js +0 -4
- package/dist/review-switch.js +1 -7
- package/dist/reviewer.js +0 -35
- package/dist/route-change-check.js +0 -2
- package/dist/route-change.js +0 -16
- package/dist/route-hooks.js +0 -27
- package/dist/route-results.js +2 -58
- package/dist/route-rules.js +1 -106
- package/dist/route-savings.js +0 -36
- package/dist/route-store.js +1 -133
- package/dist/run-closeout.js +2 -50
- package/dist/run-efficiency.js +2 -44
- package/dist/run-ending.js +0 -13
- package/dist/runner-process.js +0 -33
- package/dist/runner.js +17 -189
- package/dist/sample-project.js +2 -27
- package/dist/sandbox-launch.js +4 -25
- package/dist/sandbox-runtime.js +1 -88
- package/dist/scan.js +0 -27
- package/dist/scope.js +4 -567
- package/dist/scout-browser-lock.js +0 -6
- package/dist/scout-browser.js +2 -68
- package/dist/scout-net.js +1 -32
- package/dist/scout-report.js +0 -22
- package/dist/scout.js +1 -116
- package/dist/secret-mint.js +0 -6
- package/dist/serve.js +21 -555
- package/dist/server/agents-computers.js +0 -10
- package/dist/server/agents-live-filed.js +0 -13
- package/dist/server/agents-live-lead.js +0 -19
- package/dist/server/agents-live-room.js +0 -19
- package/dist/server/chat.js +2 -194
- package/dist/server/chrome.js +17 -263
- package/dist/server/console.css +4 -4
- package/dist/server/edge-refusal.js +0 -3
- package/dist/server/flows.js +5 -74
- package/dist/server/guards.js +1 -88
- package/dist/server/handler-registry.js +0 -2
- package/dist/server/home-asks.js +1 -22
- package/dist/server/home.js +1 -30
- package/dist/server/http.js +0 -82
- package/dist/server/in-place.js +0 -15
- package/dist/server/kit-standalone.js +0 -20
- package/dist/server/kit.js +2 -114
- package/dist/server/last-checks.js +0 -2
- package/dist/server/live.js +1 -36
- package/dist/server/merge-ready-view.js +0 -6
- package/dist/server/mutation-key.js +3 -40
- package/dist/server/pages-assets.js +0 -16
- package/dist/server/pages.js +7 -195
- package/dist/server/people-tokens.js +3 -101
- package/dist/server/remote-hooks.js +0 -13
- package/dist/server/remote.js +0 -28
- package/dist/server/render-chat.js +8 -144
- package/dist/server/render-code-map.js +0 -5
- package/dist/server/render-flaky.js +0 -8
- package/dist/server/render-follow-through.js +2 -5
- package/dist/server/render-history.js +2 -34
- package/dist/server/render-new-task.js +2 -29
- package/dist/server/render-pages.js +1 -111
- package/dist/server/render-people.js +2 -46
- package/dist/server/render-projects.js +15 -32
- package/dist/server/render-release.js +1 -14
- package/dist/server/render-results.js +4 -355
- package/dist/server/render-settings.js +0 -15
- package/dist/server/render-tasks.js +13 -493
- package/dist/server/request-context.js +2 -9
- package/dist/server/retired-routes.js +0 -11
- package/dist/server/route-policy.js +0 -3
- package/dist/server/route-table.js +6 -135
- package/dist/server/runtime.js +0 -1
- package/dist/server/session.js +0 -28
- package/dist/server/settings.js +40 -246
- package/dist/server/signup-gate.js +0 -11
- package/dist/server/sweeps.js +0 -6
- package/dist/server/task-views.js +9 -227
- package/dist/server/tasks.js +5 -539
- package/dist/server/terminals.js +2 -46
- package/dist/server/welcome.js +2 -22
- package/dist/server-telemetry.js +0 -9
- package/dist/settings-groups-ui.js +50 -63
- package/dist/settings-kit-script.js +0 -19
- package/dist/settings-kit.js +0 -63
- package/dist/settings-proofs.js +0 -23
- package/dist/setup-guide.js +1 -9
- package/dist/shared-deps.js +9 -84
- package/dist/sign-in-guard.js +0 -27
- package/dist/skills-ui.js +0 -2
- package/dist/skills.js +2 -54
- package/dist/slack-api.js +0 -3
- package/dist/slack-chat.js +0 -25
- package/dist/slack-settings.js +0 -1
- package/dist/slack-socket.js +0 -5
- package/dist/slack.js +0 -4
- package/dist/sleep.js +0 -1
- package/dist/source-key.js +0 -10
- package/dist/spend-report.js +0 -29
- package/dist/spend-ui.js +0 -26
- package/dist/spend.js +0 -40
- package/dist/sqlite-runtime.js +0 -2
- package/dist/sqlite-telemetry.js +0 -9
- package/dist/sso-settings.js +0 -13
- package/dist/sso-ui.js +0 -2
- package/dist/staged-runtimes.js +5 -39
- package/dist/steer-capabilities.js +1 -7
- package/dist/steer-controls.js +0 -10
- package/dist/steer-live.js +0 -31
- package/dist/steer-mailbox.js +4 -65
- package/dist/steer-status.js +0 -7
- package/dist/stop-proof.js +5 -62
- package/dist/storage-sweep-child.js +1 -5
- package/dist/storage-sweep-process.js +2 -20
- package/dist/storage-sweep-schedule.js +0 -32
- package/dist/storage-sweep.js +2 -51
- package/dist/storage-ui.js +0 -18
- package/dist/storage.js +0 -31
- package/dist/store-baseline.js +0 -14
- package/dist/store.js +109 -4763
- package/dist/stream-scope.js +0 -16
- package/dist/structured-output.js +0 -39
- package/dist/style-asset.js +0 -2
- package/dist/subagent-admin.js +0 -9
- package/dist/subagent-desk.js +0 -29
- package/dist/subagent-memory.js +0 -38
- package/dist/subagent-question.js +0 -29
- package/dist/subagent-tools.js +1 -60
- package/dist/subagent-week.js +0 -28
- package/dist/subagent-work.js +1 -39
- package/dist/subagents-ui.js +1 -13
- package/dist/subagents.js +0 -40
- package/dist/subscription-chat.js +1 -42
- package/dist/summary.js +0 -19
- package/dist/surface.js +0 -75
- package/dist/sweep-gate.js +0 -2
- package/dist/sweep-quarantine.js +2 -13
- package/dist/sync.js +0 -47
- package/dist/tailnet.js +0 -9
- package/dist/tamper-scan.js +0 -15
- package/dist/task-activity.js +1 -16
- package/dist/task-aliases.js +0 -3
- package/dist/task-archive.js +0 -7
- package/dist/task-base.js +0 -18
- package/dist/task-composer.js +0 -2
- package/dist/task-control.js +0 -74
- package/dist/task-live.js +0 -23
- package/dist/task-moves.js +0 -28
- package/dist/task-outcome-cli.js +17 -28
- package/dist/task-review-brief.js +0 -7
- package/dist/task-sizing.js +0 -47
- package/dist/task-source.js +0 -23
- package/dist/task-status.js +0 -106
- package/dist/task-text.js +0 -12
- package/dist/team-chat-authorization.js +0 -3
- package/dist/team-contract.js +0 -2
- package/dist/team-http.js +0 -4
- package/dist/team-leads.js +1 -16
- package/dist/team-runtime.js +0 -13
- package/dist/team-ui.js +0 -1
- package/dist/team-updates.js +0 -4
- package/dist/teams-api.js +0 -12
- package/dist/teams-chat.js +0 -28
- package/dist/teams.js +0 -12
- package/dist/teardown-git.js +6 -294
- package/dist/telegram-flow.js +0 -51
- package/dist/telegram-lead.js +2 -203
- package/dist/telegram-live.js +1 -42
- package/dist/telegram-progress.js +0 -18
- package/dist/telegram-settings.js +0 -7
- package/dist/telegram-status.js +0 -46
- package/dist/telegram-team.js +1 -33
- package/dist/telegram.js +6 -454
- package/dist/templates.js +0 -24
- package/dist/terminal-catalog.js +2 -20
- package/dist/terminal-text.js +0 -12
- package/dist/test-infra.js +0 -50
- package/dist/test-temp.js +3 -26
- package/dist/text-limits.js +0 -92
- package/dist/tidy.js +0 -76
- package/dist/tier-report.js +0 -2
- package/dist/token-notices.js +1 -9
- package/dist/tokens-cli.js +0 -13
- package/dist/tool-broker.js +2 -53
- package/dist/tool-launcher.js +0 -14
- package/dist/tool-secret-store.js +3 -125
- package/dist/toolroll-update-cli.js +0 -9
- package/dist/toolroll-update-ui.js +0 -14
- package/dist/toolroll-update.js +13 -252
- package/dist/tools-ui.js +0 -17
- package/dist/transitions-recipes.js +0 -2
- package/dist/tree-proof.js +0 -23
- package/dist/tui-contract.js +0 -8
- package/dist/tui-source.js +16 -36
- package/dist/tui.js +1 -1
- package/dist/typed-start.js +0 -27
- package/dist/unfenced-test-support.js +0 -5
- package/dist/up-processes.js +1 -40
- package/dist/up-role-child.js +1 -13
- package/dist/update-notice.js +0 -1
- package/dist/vanished-retry.js +0 -40
- package/dist/verification-evidence.js +0 -39
- package/dist/version.js +0 -1
- package/dist/wake-hub.js +0 -28
- package/dist/webhook-limits.js +0 -7
- package/dist/webhook-readers.js +0 -30
- package/dist/webhook-signing.js +0 -14
- package/dist/webhooks.js +0 -54
- package/dist/welcome-facts.js +2 -14
- package/dist/when-html.js +0 -27
- package/dist/work-index.js +26 -98
- package/dist/work-summary.js +2 -17
- package/dist/workspace-motion.js +0 -2
- package/dist/workspace-revision.js +1 -21
- package/dist/workspace-ui.js +15 -135
- package/dist/worktree-notices.js +0 -3
- package/dist/worktree.js +0 -308
- package/dist/writes-mode.js +0 -1
- package/dist/youiyoux-intake.js +4 -159
- package/package.json +4 -3
- package/dist/accent-colors.d.ts +0 -51
- package/dist/acp-agents.d.ts +0 -43
- package/dist/acp-attest.d.ts +0 -44
- package/dist/acp-check.d.ts +0 -37
- package/dist/acp-client.d.ts +0 -163
- package/dist/acp-inspect.d.ts +0 -23
- package/dist/action-ledger.d.ts +0 -27
- package/dist/activity-line.d.ts +0 -29
- package/dist/actor.d.ts +0 -11
- package/dist/agent-board.d.ts +0 -229
- package/dist/agent-fence.d.ts +0 -479
- package/dist/agent-onboard.d.ts +0 -158
- package/dist/agent-pulse.d.ts +0 -43
- package/dist/agent-state-words.d.ts +0 -19
- package/dist/agent-state.d.ts +0 -65
- package/dist/agent-turns.d.ts +0 -52
- package/dist/agentconfig.d.ts +0 -191
- package/dist/agents-board.d.ts +0 -145
- package/dist/agents-live.d.ts +0 -31
- package/dist/api-tokens.d.ts +0 -80
- package/dist/approval-authority.d.ts +0 -51
- package/dist/approval-password.d.ts +0 -31
- package/dist/approval-policy.d.ts +0 -69
- package/dist/approval-rules-ui.d.ts +0 -40
- package/dist/assignment-adapters.d.ts +0 -152
- package/dist/assignment-brief.d.ts +0 -83
- package/dist/assignment-delivery.d.ts +0 -86
- package/dist/assignment-presentation.d.ts +0 -37
- package/dist/assignment-status.d.ts +0 -71
- package/dist/assignment-ui.d.ts +0 -68
- package/dist/assignment.d.ts +0 -350
- package/dist/attest.d.ts +0 -59
- package/dist/audit-cli.d.ts +0 -17
- package/dist/backend.d.ts +0 -97
- package/dist/backup-ui.d.ts +0 -32
- package/dist/backup.d.ts +0 -92
- package/dist/batch-checks.d.ts +0 -15
- package/dist/batch-policy.d.ts +0 -23
- package/dist/beads.d.ts +0 -34
- package/dist/bin.d.ts +0 -2
- package/dist/board.d.ts +0 -134
- package/dist/boot-identity.d.ts +0 -64
- package/dist/bounded-spawn.d.ts +0 -57
- package/dist/brand-icons.d.ts +0 -168
- package/dist/brand-mark.d.ts +0 -28
- package/dist/brief-fence.d.ts +0 -9
- package/dist/browser-crew.d.ts +0 -12
- package/dist/browser-shell.d.ts +0 -9
- package/dist/browser-workspace.d.ts +0 -1985
- package/dist/budget-alerts.d.ts +0 -19
- package/dist/build-review.d.ts +0 -38
- package/dist/builder-restart.d.ts +0 -21
- package/dist/builder.d.ts +0 -409
- package/dist/canonical-json.d.ts +0 -14
- package/dist/capscan.d.ts +0 -35
- package/dist/card-catalog.d.ts +0 -209
- package/dist/card-cli.d.ts +0 -43
- package/dist/card-render.d.ts +0 -43
- package/dist/card-sources.d.ts +0 -68
- package/dist/chat-acceptance.d.ts +0 -74
- package/dist/chat-actions.d.ts +0 -460
- package/dist/chat-admission.d.ts +0 -19
- package/dist/chat-approval.d.ts +0 -58
- package/dist/chat-ask.d.ts +0 -32
- package/dist/chat-card-part.d.ts +0 -11
- package/dist/chat-card.d.ts +0 -46
- package/dist/chat-channel.d.ts +0 -126
- package/dist/chat-continuity.d.ts +0 -32
- package/dist/chat-controls.d.ts +0 -117
- package/dist/chat-core.d.ts +0 -177
- package/dist/chat-decide.d.ts +0 -269
- package/dist/chat-delivery-state.d.ts +0 -132
- package/dist/chat-delivery.d.ts +0 -71
- package/dist/chat-display.d.ts +0 -1
- package/dist/chat-evidence.d.ts +0 -123
- package/dist/chat-flow.d.ts +0 -70
- package/dist/chat-follow.d.ts +0 -20
- package/dist/chat-inbox.d.ts +0 -57
- package/dist/chat-live-schema.d.ts +0 -17
- package/dist/chat-live.d.ts +0 -161
- package/dist/chat-message-states.d.ts +0 -75
- package/dist/chat-messages.d.ts +0 -338
- package/dist/chat-migration.d.ts +0 -30
- package/dist/chat-polish.d.ts +0 -17
- package/dist/chat-quiet.d.ts +0 -40
- package/dist/chat-review.d.ts +0 -51
- package/dist/chat-rooms.d.ts +0 -123
- package/dist/chat-settings-page.d.ts +0 -43
- package/dist/chat-task-actions.d.ts +0 -59
- package/dist/chat-terms.d.ts +0 -29
- package/dist/chat-voice.d.ts +0 -69
- package/dist/chat-warmth.d.ts +0 -21
- package/dist/check-access.d.ts +0 -54
- package/dist/check-facts.d.ts +0 -126
- package/dist/check-failure.d.ts +0 -113
- package/dist/check-levels-ui.d.ts +0 -36
- package/dist/check-levels.d.ts +0 -70
- package/dist/check-load.d.ts +0 -85
- package/dist/check-only-standing.d.ts +0 -36
- package/dist/check-only.d.ts +0 -15
- package/dist/check-progress.d.ts +0 -78
- package/dist/check-repair.d.ts +0 -47
- package/dist/check-report.d.ts +0 -177
- package/dist/check-stamp.d.ts +0 -46
- package/dist/checkout-cleanup.d.ts +0 -157
- package/dist/checkout-proof.d.ts +0 -28
- package/dist/child-database.d.ts +0 -12
- package/dist/claim.d.ts +0 -627
- package/dist/claude-print.d.ts +0 -12
- package/dist/cli-fast.d.ts +0 -8
- package/dist/cli-help.d.ts +0 -8
- package/dist/cli-http.d.ts +0 -58
- package/dist/cli.d.ts +0 -149
- package/dist/code-extract.d.ts +0 -44
- package/dist/code-map-acts.d.ts +0 -24
- package/dist/code-map-admission.d.ts +0 -52
- package/dist/code-map-build.d.ts +0 -63
- package/dist/code-map-cli.d.ts +0 -153
- package/dist/code-map-main.d.ts +0 -1
- package/dist/code-map-read.d.ts +0 -106
- package/dist/code-map-report.d.ts +0 -37
- package/dist/code-map-shape.d.ts +0 -172
- package/dist/code-map-store.d.ts +0 -136
- package/dist/codex-limits.d.ts +0 -15
- package/dist/coding-context.d.ts +0 -18
- package/dist/coding-handoff.d.ts +0 -39
- package/dist/coding-provider.d.ts +0 -88
- package/dist/coding-shipping-ui.d.ts +0 -5
- package/dist/coding-types.d.ts +0 -16
- package/dist/coding-ui.d.ts +0 -19
- package/dist/coding-update.d.ts +0 -28
- package/dist/coding-workspace.d.ts +0 -141
- package/dist/commit-extract.d.ts +0 -135
- package/dist/connect-cli.d.ts +0 -34
- package/dist/console-chrome.d.ts +0 -41
- package/dist/console-instance.d.ts +0 -157
- package/dist/container-state.d.ts +0 -5
- package/dist/containment.d.ts +0 -205
- package/dist/contract-changes.d.ts +0 -52
- package/dist/contracts/acceptance-terms.d.ts +0 -14
- package/dist/contracts/chat-actions.d.ts +0 -465
- package/dist/contracts/chat-callback-rows.d.ts +0 -59
- package/dist/contracts/chat-card.d.ts +0 -91
- package/dist/contracts/chat-content.d.ts +0 -551
- package/dist/contracts/chat-tables.d.ts +0 -12
- package/dist/contracts/cli.d.ts +0 -987
- package/dist/contracts/coding-activity.d.ts +0 -64
- package/dist/contracts/coding-context.d.ts +0 -97
- package/dist/contracts/coding-handoff.d.ts +0 -44
- package/dist/contracts/coding-workspace.d.ts +0 -165
- package/dist/contracts/console-api.d.ts +0 -540
- package/dist/contracts/contract-test.d.ts +0 -45
- package/dist/contracts/contract.d.ts +0 -92
- package/dist/contracts/decision.d.ts +0 -45
- package/dist/contracts/diff-stat.d.ts +0 -58
- package/dist/contracts/discord-callback.d.ts +0 -45
- package/dist/contracts/flow-card.d.ts +0 -53
- package/dist/contracts/flow-propose.d.ts +0 -334
- package/dist/contracts/flow-send.d.ts +0 -245
- package/dist/contracts/flow.d.ts +0 -19565
- package/dist/contracts/gateway-tools.d.ts +0 -472
- package/dist/contracts/handoff.d.ts +0 -91
- package/dist/contracts/health.d.ts +0 -82
- package/dist/contracts/integration-metadata.d.ts +0 -100
- package/dist/contracts/lead-context.d.ts +0 -165
- package/dist/contracts/lead-tools.d.ts +0 -2312
- package/dist/contracts/mcp-oauth.d.ts +0 -53
- package/dist/contracts/memory-pass.d.ts +0 -157
- package/dist/contracts/model-catalog.d.ts +0 -21
- package/dist/contracts/observation-request.d.ts +0 -37
- package/dist/contracts/plan.d.ts +0 -58
- package/dist/contracts/project-knowledge.d.ts +0 -159
- package/dist/contracts/project-memory.d.ts +0 -119
- package/dist/contracts/project-skills.d.ts +0 -120
- package/dist/contracts/proof.d.ts +0 -136
- package/dist/contracts/provider.d.ts +0 -40
- package/dist/contracts/recipes.d.ts +0 -166
- package/dist/contracts/release-check.d.ts +0 -371
- package/dist/contracts/release-terms.d.ts +0 -107
- package/dist/contracts/retention.d.ts +0 -42
- package/dist/contracts/review-findings.d.ts +0 -46
- package/dist/contracts/route-results.d.ts +0 -121
- package/dist/contracts/route.d.ts +0 -897
- package/dist/contracts/scope.d.ts +0 -105
- package/dist/contracts/scout-report.d.ts +0 -234
- package/dist/contracts/slack-callback.d.ts +0 -43
- package/dist/contracts/sort-answer.d.ts +0 -83
- package/dist/contracts/stage-output.d.ts +0 -127
- package/dist/contracts/storage.d.ts +0 -37
- package/dist/contracts/store-json.d.ts +0 -313
- package/dist/contracts/subagent-turn.d.ts +0 -43
- package/dist/contracts/task-sizing.d.ts +0 -24
- package/dist/contracts/teams-callback.d.ts +0 -13
- package/dist/contracts/telegram-callback.d.ts +0 -120
- package/dist/contracts/trigger-payloads.d.ts +0 -389
- package/dist/contracts/update-journal.d.ts +0 -254
- package/dist/contracts/verification-receipt.d.ts +0 -200
- package/dist/contracts/verification-view.d.ts +0 -102
- package/dist/contracts/youiyoux-request.d.ts +0 -248
- package/dist/control-setup.d.ts +0 -44
- package/dist/control-ui.d.ts +0 -37
- package/dist/controller-service.d.ts +0 -1
- package/dist/controller-supervisor.d.ts +0 -38
- package/dist/converse.d.ts +0 -316
- package/dist/coordinator-proposals.d.ts +0 -29
- package/dist/coordinator.d.ts +0 -186
- package/dist/credentials-ui.d.ts +0 -33
- package/dist/daemon.d.ts +0 -226
- package/dist/database-reclaim.d.ts +0 -4
- package/dist/decision.d.ts +0 -119
- package/dist/demo-chat.d.ts +0 -32
- package/dist/demo.d.ts +0 -153
- package/dist/deploy-gate.d.ts +0 -20
- package/dist/deploy-lock.d.ts +0 -8
- package/dist/deploy-phase.d.ts +0 -37
- package/dist/deploy-rescue.d.ts +0 -42
- package/dist/deprecations.d.ts +0 -20
- package/dist/design/kit.d.ts +0 -216
- package/dist/desktop-access.d.ts +0 -28
- package/dist/desktop-bundle.d.ts +0 -16
- package/dist/desktop-host.d.ts +0 -54
- package/dist/desktop-update-gate.d.ts +0 -12
- package/dist/desktop-update-recovery.d.ts +0 -14
- package/dist/desktop-update.d.ts +0 -147
- package/dist/digest-times.d.ts +0 -3
- package/dist/disclosure.d.ts +0 -6
- package/dist/discord-api.d.ts +0 -24
- package/dist/discord-chat.d.ts +0 -27
- package/dist/discord-settings.d.ts +0 -4
- package/dist/discord.d.ts +0 -10
- package/dist/discover.d.ts +0 -75
- package/dist/dispatch.d.ts +0 -123
- package/dist/dispose.d.ts +0 -194
- package/dist/doctor.d.ts +0 -67
- package/dist/easy-start-args.d.ts +0 -13
- package/dist/easy-start.d.ts +0 -77
- package/dist/egress.d.ts +0 -121
- package/dist/email-settings.d.ts +0 -34
- package/dist/envelope.d.ts +0 -47
- package/dist/eval-gate.d.ts +0 -51
- package/dist/eval-hooks.d.ts +0 -94
- package/dist/eval-oracle-main.d.ts +0 -1
- package/dist/eval-oracle.d.ts +0 -60
- package/dist/eval-world.d.ts +0 -17
- package/dist/evals.d.ts +0 -299
- package/dist/evidence-pack.d.ts +0 -186
- package/dist/evidence-pair.d.ts +0 -53
- package/dist/evidence.d.ts +0 -371
- package/dist/exec.d.ts +0 -355
- package/dist/exhaustion.d.ts +0 -58
- package/dist/export-ui.d.ts +0 -11
- package/dist/export.d.ts +0 -48
- package/dist/failing-first.d.ts +0 -31
- package/dist/fallback-schema.d.ts +0 -8
- package/dist/fallback.d.ts +0 -138
- package/dist/fast-start.d.ts +0 -213
- package/dist/fast-terms.d.ts +0 -9
- package/dist/fenced-check-coverage.d.ts +0 -62
- package/dist/findings.d.ts +0 -224
- package/dist/first-run.d.ts +0 -197
- package/dist/first-tasks-child.d.ts +0 -1
- package/dist/flaky-ci.d.ts +0 -31
- package/dist/flaky-cli.d.ts +0 -60
- package/dist/flaky.d.ts +0 -83
- package/dist/fleet-schema.d.ts +0 -17
- package/dist/flow-actions.d.ts +0 -79
- package/dist/flow-browser.d.ts +0 -103
- package/dist/flow-cadence.d.ts +0 -48
- package/dist/flow-card-task.d.ts +0 -11
- package/dist/flow-changed.d.ts +0 -14
- package/dist/flow-code.d.ts +0 -84
- package/dist/flow-draft.d.ts +0 -42
- package/dist/flow-engine.d.ts +0 -82
- package/dist/flow-gallery-ui.d.ts +0 -73
- package/dist/flow-gallery.d.ts +0 -147
- package/dist/flow-insights.d.ts +0 -104
- package/dist/flow-items.d.ts +0 -37
- package/dist/flow-live.d.ts +0 -16
- package/dist/flow-people.d.ts +0 -23
- package/dist/flow-pull-request.d.ts +0 -14
- package/dist/flow-replies.d.ts +0 -48
- package/dist/flow-result-card.d.ts +0 -22
- package/dist/flow-schedule.d.ts +0 -154
- package/dist/flow-scripts.d.ts +0 -31
- package/dist/flow-secrets.d.ts +0 -13
- package/dist/flow-send.d.ts +0 -54
- package/dist/flow-share.d.ts +0 -78
- package/dist/flow-sort.d.ts +0 -63
- package/dist/flow-starters-ui.d.ts +0 -15
- package/dist/flow-starters.d.ts +0 -63
- package/dist/flow-steps.d.ts +0 -52
- package/dist/flow-triggers.d.ts +0 -303
- package/dist/flow-unattended-words.d.ts +0 -48
- package/dist/flow-unattended.d.ts +0 -259
- package/dist/flows-cli.d.ts +0 -358
- package/dist/flows-ui.d.ts +0 -70
- package/dist/flows.d.ts +0 -136
- package/dist/folder-gate.d.ts +0 -32
- package/dist/folder-look.d.ts +0 -110
- package/dist/follow-through-brief.d.ts +0 -12
- package/dist/follow-through-cli.d.ts +0 -23
- package/dist/fonts.d.ts +0 -19
- package/dist/gaps.d.ts +0 -35
- package/dist/gate-failure.d.ts +0 -40
- package/dist/git-floor.d.ts +0 -16
- package/dist/git-incident.d.ts +0 -65
- package/dist/git-views.d.ts +0 -20
- package/dist/git.d.ts +0 -54
- package/dist/github-import.d.ts +0 -62
- package/dist/github-jobs.d.ts +0 -25
- package/dist/google-mail.d.ts +0 -59
- package/dist/grant.d.ts +0 -136
- package/dist/graph.d.ts +0 -164
- package/dist/guides.d.ts +0 -22
- package/dist/handover-note.d.ts +0 -33
- package/dist/health-cli.d.ts +0 -3
- package/dist/home-groups.d.ts +0 -39
- package/dist/html.d.ts +0 -85
- package/dist/install-method.d.ts +0 -17
- package/dist/integrations-ui.d.ts +0 -17
- package/dist/integrations.d.ts +0 -138
- package/dist/invoke.d.ts +0 -228
- package/dist/is-record.d.ts +0 -2
- package/dist/issues.d.ts +0 -41
- package/dist/jsonl-discriminants.d.ts +0 -11
- package/dist/keymap.d.ts +0 -43
- package/dist/keys.d.ts +0 -108
- package/dist/kits-ui.d.ts +0 -16
- package/dist/kits.d.ts +0 -88
- package/dist/knowledge-cli.d.ts +0 -132
- package/dist/knowledge-ui.d.ts +0 -45
- package/dist/landed-cleanup.d.ts +0 -175
- package/dist/laptop-background.d.ts +0 -187
- package/dist/laptop-service.d.ts +0 -111
- package/dist/latency-timeline.d.ts +0 -46
- package/dist/lead-about.d.ts +0 -35
- package/dist/lead-answer-eval.d.ts +0 -93
- package/dist/lead-capabilities.d.ts +0 -57
- package/dist/lead-cli-live.d.ts +0 -56
- package/dist/lead-cli.d.ts +0 -58
- package/dist/lead-commitments.d.ts +0 -84
- package/dist/lead-context.d.ts +0 -45
- package/dist/lead-contract.d.ts +0 -10
- package/dist/lead-doors.d.ts +0 -122
- package/dist/lead-follow.d.ts +0 -26
- package/dist/lead-identity.d.ts +0 -23
- package/dist/lead-latency-schema.d.ts +0 -24
- package/dist/lead-people.d.ts +0 -55
- package/dist/lead-progress.d.ts +0 -67
- package/dist/lead-queue-runtime.d.ts +0 -46
- package/dist/lead-queue.d.ts +0 -104
- package/dist/lead-route.d.ts +0 -56
- package/dist/lead-status.d.ts +0 -116
- package/dist/lead-sweep.d.ts +0 -67
- package/dist/lead-tools.d.ts +0 -167
- package/dist/lead-voice.d.ts +0 -85
- package/dist/lead.d.ts +0 -142
- package/dist/learning-child.d.ts +0 -1
- package/dist/learning-look.d.ts +0 -25
- package/dist/ledger-chain.d.ts +0 -46
- package/dist/ledger-csv.d.ts +0 -4
- package/dist/ledger-view.d.ts +0 -27
- package/dist/lesson-notes.d.ts +0 -81
- package/dist/limits-ui.d.ts +0 -34
- package/dist/link.d.ts +0 -72
- package/dist/live-backup.d.ts +0 -39
- package/dist/live-bus.d.ts +0 -141
- package/dist/live-children-read.d.ts +0 -52
- package/dist/live-children.d.ts +0 -73
- package/dist/live-detail.d.ts +0 -27
- package/dist/live-input.d.ts +0 -68
- package/dist/live-main-read.d.ts +0 -19
- package/dist/live-notes.d.ts +0 -20
- package/dist/live-open.d.ts +0 -28
- package/dist/live-records.d.ts +0 -149
- package/dist/live-reply.d.ts +0 -83
- package/dist/live-terminal.d.ts +0 -273
- package/dist/live.d.ts +0 -152
- package/dist/local-owner-acts.d.ts +0 -83
- package/dist/local-owner.d.ts +0 -135
- package/dist/log.d.ts +0 -7
- package/dist/login-secrets.d.ts +0 -60
- package/dist/machine-check.d.ts +0 -16
- package/dist/machine-identity.d.ts +0 -75
- package/dist/mailbox.d.ts +0 -57
- package/dist/maintenance.d.ts +0 -13
- package/dist/mcp-connect.d.ts +0 -181
- package/dist/mcp-core.d.ts +0 -110
- package/dist/mcp-http.d.ts +0 -32
- package/dist/mcp-oauth.d.ts +0 -92
- package/dist/mcp-person.d.ts +0 -22
- package/dist/mcp.d.ts +0 -20
- package/dist/memory-cli.d.ts +0 -768
- package/dist/memory-pass.d.ts +0 -151
- package/dist/memory-tidy.d.ts +0 -181
- package/dist/memory-use.d.ts +0 -35
- package/dist/merge-checklist.d.ts +0 -55
- package/dist/metrics.d.ts +0 -6
- package/dist/mobile-viewport.d.ts +0 -7
- package/dist/model-catalog.d.ts +0 -123
- package/dist/model-choices.d.ts +0 -235
- package/dist/model-names.d.ts +0 -6
- package/dist/models-cli.d.ts +0 -307
- package/dist/models-ui.d.ts +0 -161
- package/dist/modes.d.ts +0 -99
- package/dist/monitoring-settings.d.ts +0 -44
- package/dist/monitoring-ui.d.ts +0 -23
- package/dist/monitoring.d.ts +0 -34
- package/dist/names.d.ts +0 -67
- package/dist/needs-you.d.ts +0 -164
- package/dist/never-index.d.ts +0 -3
- package/dist/nightly-check.d.ts +0 -107
- package/dist/nightly-github.d.ts +0 -318
- package/dist/notification-delivery.d.ts +0 -19
- package/dist/notification-rows.d.ts +0 -30
- package/dist/oauth-run-token.d.ts +0 -51
- package/dist/observations.d.ts +0 -36
- package/dist/oidc.d.ts +0 -71
- package/dist/onboard.d.ts +0 -108
- package/dist/one-step-chat-schema.d.ts +0 -22
- package/dist/openrouter-models.d.ts +0 -34
- package/dist/operate-remote-arguments.d.ts +0 -36
- package/dist/operate-remote.d.ts +0 -98
- package/dist/operate.d.ts +0 -401
- package/dist/orphan-sweep.d.ts +0 -65
- package/dist/page-work-contract.d.ts +0 -21
- package/dist/password-bearer.d.ts +0 -25
- package/dist/passwordless.d.ts +0 -23
- package/dist/peek-cli.d.ts +0 -112
- package/dist/peek.d.ts +0 -110
- package/dist/people-audit-ui.d.ts +0 -16
- package/dist/person-proof.d.ts +0 -2
- package/dist/phase-routing.d.ts +0 -401
- package/dist/plain-schema.d.ts +0 -23
- package/dist/plain-words.d.ts +0 -20
- package/dist/plan-auto.d.ts +0 -25
- package/dist/plan-login.d.ts +0 -14
- package/dist/plan.d.ts +0 -188
- package/dist/plane-review.d.ts +0 -54
- package/dist/planner-source.d.ts +0 -225
- package/dist/planner.d.ts +0 -76
- package/dist/policy-ui.d.ts +0 -22
- package/dist/policy.d.ts +0 -92
- package/dist/prepared-evidence.d.ts +0 -17
- package/dist/principal.d.ts +0 -42
- package/dist/probe.d.ts +0 -46
- package/dist/process-custody.d.ts +0 -17
- package/dist/process-liveness.d.ts +0 -13
- package/dist/process-tree.d.ts +0 -39
- package/dist/project-access.d.ts +0 -17
- package/dist/project-activity.d.ts +0 -20
- package/dist/project-admission.d.ts +0 -105
- package/dist/project-cli.d.ts +0 -19
- package/dist/project-concurrency.d.ts +0 -62
- package/dist/project-delete-ui.d.ts +0 -96
- package/dist/project-delete.d.ts +0 -59
- package/dist/project-demo.d.ts +0 -12
- package/dist/project-file.d.ts +0 -3
- package/dist/project-identity.d.ts +0 -52
- package/dist/project-knowledge.d.ts +0 -124
- package/dist/project-learning.d.ts +0 -120
- package/dist/project-memory.d.ts +0 -70
- package/dist/project-outcomes.d.ts +0 -119
- package/dist/project-sandbox.d.ts +0 -59
- package/dist/project-skills.d.ts +0 -139
- package/dist/project-tools.d.ts +0 -318
- package/dist/project.d.ts +0 -65
- package/dist/prompt.d.ts +0 -33
- package/dist/proof.d.ts +0 -457
- package/dist/proposal.d.ts +0 -70
- package/dist/protected-storage-look.d.ts +0 -1
- package/dist/protected-storage.d.ts +0 -98
- package/dist/provider-auth.d.ts +0 -143
- package/dist/provider-capture.d.ts +0 -34
- package/dist/provider-connection.d.ts +0 -23
- package/dist/provider-home.d.ts +0 -22
- package/dist/provider-limits.d.ts +0 -37
- package/dist/provider.d.ts +0 -369
- package/dist/public-access.d.ts +0 -61
- package/dist/public-check.d.ts +0 -37
- package/dist/publish.d.ts +0 -146
- package/dist/pull-request-flow.d.ts +0 -189
- package/dist/pull-request-schema.d.ts +0 -5
- package/dist/pull-request-ui.d.ts +0 -25
- package/dist/pulls.d.ts +0 -121
- package/dist/push.d.ts +0 -120
- package/dist/quality.d.ts +0 -8
- package/dist/quick-start.d.ts +0 -26
- package/dist/read-executor-worker.d.ts +0 -1
- package/dist/read-executor.d.ts +0 -66
- package/dist/read-only-request.d.ts +0 -4
- package/dist/recipe-ui.d.ts +0 -21
- package/dist/recipes.d.ts +0 -56
- package/dist/release-adapters.d.ts +0 -205
- package/dist/release-approval.d.ts +0 -180
- package/dist/release-authority.d.ts +0 -173
- package/dist/release-auto.d.ts +0 -184
- package/dist/release-card.d.ts +0 -170
- package/dist/release-carry.d.ts +0 -261
- package/dist/release-ci-hold.d.ts +0 -41
- package/dist/release-cli.d.ts +0 -34
- package/dist/release-coverage.d.ts +0 -16
- package/dist/release-gate.d.ts +0 -84
- package/dist/release-git.d.ts +0 -43
- package/dist/release-links.d.ts +0 -29
- package/dist/release-net.d.ts +0 -90
- package/dist/release-next.d.ts +0 -48
- package/dist/release-recheck.d.ts +0 -146
- package/dist/release-refusal.d.ts +0 -32
- package/dist/release-view.d.ts +0 -37
- package/dist/release.d.ts +0 -806
- package/dist/releases.d.ts +0 -94
- package/dist/remote-audit.d.ts +0 -79
- package/dist/remote-command.d.ts +0 -45
- package/dist/remote-destination.d.ts +0 -36
- package/dist/remote-exec.d.ts +0 -38
- package/dist/remote-main.d.ts +0 -111
- package/dist/remote-run.d.ts +0 -20
- package/dist/remote.d.ts +0 -67
- package/dist/render.d.ts +0 -64
- package/dist/reply-shape.d.ts +0 -106
- package/dist/reply-voice.d.ts +0 -23
- package/dist/report-summary.d.ts +0 -22
- package/dist/reported-usage.d.ts +0 -69
- package/dist/repos.d.ts +0 -67
- package/dist/repository-context-ui.d.ts +0 -3
- package/dist/repository-context.d.ts +0 -66
- package/dist/request-budget-ui.d.ts +0 -14
- package/dist/request-budget.d.ts +0 -127
- package/dist/restart-certification.d.ts +0 -133
- package/dist/result-actions.d.ts +0 -36
- package/dist/result-acts.d.ts +0 -112
- package/dist/result-completion.d.ts +0 -39
- package/dist/result-evidence-readers.d.ts +0 -42
- package/dist/result-follow-ups.d.ts +0 -118
- package/dist/result-review.d.ts +0 -220
- package/dist/result-shots.d.ts +0 -59
- package/dist/retention-ui.d.ts +0 -21
- package/dist/retention.d.ts +0 -77
- package/dist/review-context.d.ts +0 -245
- package/dist/review-evidence.d.ts +0 -33
- package/dist/review-switch.d.ts +0 -36
- package/dist/reviewer.d.ts +0 -99
- package/dist/route-change-check.d.ts +0 -4
- package/dist/route-change.d.ts +0 -22
- package/dist/route-hooks.d.ts +0 -54
- package/dist/route-results.d.ts +0 -75
- package/dist/route-rules.d.ts +0 -324
- package/dist/route-savings.d.ts +0 -136
- package/dist/route-store.d.ts +0 -300
- package/dist/run-closeout.d.ts +0 -89
- package/dist/run-efficiency.d.ts +0 -74
- package/dist/run-ending.d.ts +0 -21
- package/dist/runner-process.d.ts +0 -76
- package/dist/runner.d.ts +0 -324
- package/dist/sample-project.d.ts +0 -31
- package/dist/sandbox-launch.d.ts +0 -1
- package/dist/sandbox-runtime.d.ts +0 -128
- package/dist/scan.d.ts +0 -32
- package/dist/scope.d.ts +0 -1098
- package/dist/scout-browser-lock.d.ts +0 -69
- package/dist/scout-browser.d.ts +0 -107
- package/dist/scout-net.d.ts +0 -25
- package/dist/scout-report.d.ts +0 -23
- package/dist/scout.d.ts +0 -142
- package/dist/secret-mint.d.ts +0 -1
- package/dist/serve.d.ts +0 -11
- package/dist/server/agents-computers.d.ts +0 -9
- package/dist/server/agents-live-filed.d.ts +0 -17
- package/dist/server/agents-live-lead.d.ts +0 -47
- package/dist/server/agents-live-room.d.ts +0 -23
- package/dist/server/chat.d.ts +0 -39
- package/dist/server/chrome.d.ts +0 -328
- package/dist/server/edge-refusal.d.ts +0 -7
- package/dist/server/flows.d.ts +0 -8
- package/dist/server/guards.d.ts +0 -81
- package/dist/server/handler-context.d.ts +0 -22
- package/dist/server/handler-registry.d.ts +0 -23
- package/dist/server/home-asks.d.ts +0 -45
- package/dist/server/home.d.ts +0 -65
- package/dist/server/http.d.ts +0 -337
- package/dist/server/in-place.d.ts +0 -15
- package/dist/server/kit-standalone.d.ts +0 -22
- package/dist/server/kit.d.ts +0 -452
- package/dist/server/last-checks.d.ts +0 -17
- package/dist/server/live.d.ts +0 -74
- package/dist/server/merge-ready-view.d.ts +0 -10
- package/dist/server/mutation-key.d.ts +0 -70
- package/dist/server/pages-assets.d.ts +0 -11
- package/dist/server/pages.d.ts +0 -8
- package/dist/server/people-tokens.d.ts +0 -18
- package/dist/server/remote-hooks.d.ts +0 -29
- package/dist/server/remote.d.ts +0 -60
- package/dist/server/render-chat.d.ts +0 -439
- package/dist/server/render-code-map.d.ts +0 -30
- package/dist/server/render-flaky.d.ts +0 -20
- package/dist/server/render-follow-through.d.ts +0 -11
- package/dist/server/render-history.d.ts +0 -51
- package/dist/server/render-new-task.d.ts +0 -54
- package/dist/server/render-pages.d.ts +0 -236
- package/dist/server/render-people.d.ts +0 -102
- package/dist/server/render-projects.d.ts +0 -104
- package/dist/server/render-release.d.ts +0 -19
- package/dist/server/render-results.d.ts +0 -758
- package/dist/server/render-settings.d.ts +0 -93
- package/dist/server/render-tasks.d.ts +0 -783
- package/dist/server/request-context.d.ts +0 -78
- package/dist/server/retired-routes.d.ts +0 -17
- package/dist/server/route-policy.d.ts +0 -18
- package/dist/server/route-table.d.ts +0 -114
- package/dist/server/runtime.d.ts +0 -343
- package/dist/server/session.d.ts +0 -192
- package/dist/server/settings.d.ts +0 -76
- package/dist/server/signup-gate.d.ts +0 -9
- package/dist/server/sweeps.d.ts +0 -4
- package/dist/server/task-views.d.ts +0 -98
- package/dist/server/tasks.d.ts +0 -108
- package/dist/server/terminals.d.ts +0 -31
- package/dist/server/welcome.d.ts +0 -28
- package/dist/server-telemetry.d.ts +0 -87
- package/dist/settings-groups-ui.d.ts +0 -286
- package/dist/settings-kit-script.d.ts +0 -21
- package/dist/settings-kit.d.ts +0 -173
- package/dist/settings-proofs.d.ts +0 -64
- package/dist/setup-guide.d.ts +0 -39
- package/dist/shared-deps.d.ts +0 -115
- package/dist/sign-in-guard.d.ts +0 -70
- package/dist/skills-ui.d.ts +0 -12
- package/dist/skills.d.ts +0 -99
- package/dist/slack-api.d.ts +0 -59
- package/dist/slack-chat.d.ts +0 -37
- package/dist/slack-settings.d.ts +0 -4
- package/dist/slack-socket.d.ts +0 -12
- package/dist/slack.d.ts +0 -6
- package/dist/sleep.d.ts +0 -2
- package/dist/source-key.d.ts +0 -2
- package/dist/spend-report.d.ts +0 -87
- package/dist/spend-ui.d.ts +0 -80
- package/dist/spend.d.ts +0 -142
- package/dist/sqlite-runtime.d.ts +0 -3
- package/dist/sqlite-telemetry.d.ts +0 -9
- package/dist/sso-settings.d.ts +0 -33
- package/dist/sso-ui.d.ts +0 -26
- package/dist/staged-runtimes.d.ts +0 -54
- package/dist/steer-capabilities.d.ts +0 -32
- package/dist/steer-controls.d.ts +0 -14
- package/dist/steer-live.d.ts +0 -19
- package/dist/steer-mailbox.d.ts +0 -46
- package/dist/steer-status.d.ts +0 -25
- package/dist/stop-proof.d.ts +0 -67
- package/dist/storage-sweep-child.d.ts +0 -1
- package/dist/storage-sweep-process.d.ts +0 -55
- package/dist/storage-sweep-schedule.d.ts +0 -30
- package/dist/storage-sweep.d.ts +0 -77
- package/dist/storage-ui.d.ts +0 -23
- package/dist/storage.d.ts +0 -68
- package/dist/store-baseline.d.ts +0 -19
- package/dist/store.d.ts +0 -8613
- package/dist/stream-scope.d.ts +0 -18
- package/dist/structured-output.d.ts +0 -57
- package/dist/style-asset.d.ts +0 -7
- package/dist/subagent-admin.d.ts +0 -53
- package/dist/subagent-desk.d.ts +0 -59
- package/dist/subagent-memory.d.ts +0 -65
- package/dist/subagent-question.d.ts +0 -59
- package/dist/subagent-tools.d.ts +0 -125
- package/dist/subagent-week.d.ts +0 -68
- package/dist/subagent-work.d.ts +0 -76
- package/dist/subagents-ui.d.ts +0 -22
- package/dist/subagents.d.ts +0 -146
- package/dist/subscription-chat.d.ts +0 -54
- package/dist/summary.d.ts +0 -33
- package/dist/surface.d.ts +0 -49
- package/dist/sweep-gate.d.ts +0 -10
- package/dist/sweep-quarantine.d.ts +0 -29
- package/dist/sync.d.ts +0 -94
- package/dist/tailnet.d.ts +0 -11
- package/dist/tamper-scan.d.ts +0 -4
- package/dist/task-activity.d.ts +0 -27
- package/dist/task-aliases.d.ts +0 -5
- package/dist/task-archive.d.ts +0 -13
- package/dist/task-base.d.ts +0 -39
- package/dist/task-composer.d.ts +0 -14
- package/dist/task-control.d.ts +0 -159
- package/dist/task-live.d.ts +0 -8
- package/dist/task-moves.d.ts +0 -90
- package/dist/task-outcome-cli.d.ts +0 -48
- package/dist/task-review-brief.d.ts +0 -69
- package/dist/task-sizing.d.ts +0 -58
- package/dist/task-source.d.ts +0 -77
- package/dist/task-status.d.ts +0 -324
- package/dist/task-text.d.ts +0 -31
- package/dist/team-chat-authorization.d.ts +0 -11
- package/dist/team-contract.d.ts +0 -103
- package/dist/team-http.d.ts +0 -25
- package/dist/team-leads.d.ts +0 -85
- package/dist/team-runtime.d.ts +0 -25
- package/dist/team-ui.d.ts +0 -4
- package/dist/team-updates.d.ts +0 -8
- package/dist/teams-api.d.ts +0 -33
- package/dist/teams-chat.d.ts +0 -36
- package/dist/teams-settings.d.ts +0 -14
- package/dist/teams.d.ts +0 -24
- package/dist/teardown-git.d.ts +0 -164
- package/dist/telegram-flow.d.ts +0 -112
- package/dist/telegram-lead.d.ts +0 -151
- package/dist/telegram-live.d.ts +0 -116
- package/dist/telegram-progress.d.ts +0 -20
- package/dist/telegram-settings.d.ts +0 -9
- package/dist/telegram-status.d.ts +0 -83
- package/dist/telegram-team.d.ts +0 -68
- package/dist/telegram.d.ts +0 -271
- package/dist/templates.d.ts +0 -69
- package/dist/terminal-catalog.d.ts +0 -11
- package/dist/terminal-text.d.ts +0 -11
- package/dist/test-infra.d.ts +0 -34
- package/dist/test-temp.d.ts +0 -40
- package/dist/text-limits.d.ts +0 -297
- package/dist/tidy.d.ts +0 -130
- package/dist/tier-report.d.ts +0 -44
- package/dist/token-notices.d.ts +0 -11
- package/dist/tokens-cli.d.ts +0 -21
- package/dist/tool-broker.d.ts +0 -52
- package/dist/tool-launcher.d.ts +0 -1
- package/dist/tool-secret-store.d.ts +0 -167
- package/dist/toolroll-update-cli.d.ts +0 -15
- package/dist/toolroll-update-ui.d.ts +0 -47
- package/dist/toolroll-update.d.ts +0 -265
- package/dist/tools-ui.d.ts +0 -51
- package/dist/transitions-recipes.d.ts +0 -1
- package/dist/tree-proof.d.ts +0 -34
- package/dist/tui-contract.d.ts +0 -202
- package/dist/tui-source.d.ts +0 -14
- package/dist/typed-start.d.ts +0 -51
- package/dist/unfenced-test-support.d.ts +0 -2
- package/dist/up-processes.d.ts +0 -162
- package/dist/up-role-child.d.ts +0 -1
- package/dist/update-notice.d.ts +0 -5
- package/dist/vanished-retry.d.ts +0 -30
- package/dist/verification-evidence.d.ts +0 -68
- package/dist/version.d.ts +0 -2
- package/dist/wake-hub.d.ts +0 -72
- package/dist/webhook-limits.d.ts +0 -23
- package/dist/webhook-readers.d.ts +0 -56
- package/dist/webhook-signing.d.ts +0 -27
- package/dist/webhooks.d.ts +0 -84
- package/dist/welcome-facts.d.ts +0 -18
- package/dist/when-html.d.ts +0 -40
- package/dist/work-index.d.ts +0 -175
- package/dist/work-summary.d.ts +0 -61
- package/dist/workspace-motion.d.ts +0 -4
- package/dist/workspace-revision.d.ts +0 -48
- package/dist/workspace-ui.d.ts +0 -385
- package/dist/worktree-notices.d.ts +0 -13
- package/dist/worktree.d.ts +0 -365
- package/dist/writes-mode.d.ts +0 -9
- package/dist/youiyoux-intake.d.ts +0 -234
package/dist/scope.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// The rubric's vocabulary loads before anything that reaches the plan contract (see contracts/acceptance-terms.ts).
|
|
2
1
|
export { ACCEPTANCE_LIMITS, EVIDENCE_KINDS } from "./contracts/acceptance-terms.js";
|
|
3
2
|
import { cardShowsScope, cardTermsDigest } from "./chat-terms.js";
|
|
4
3
|
import { mintSecret } from "./secret-mint.js";
|
|
@@ -18,31 +17,6 @@ import { isAcpProfile, isAcpProvider } from "./acp-agents.js";
|
|
|
18
17
|
import { levelOfProfile } from "./policy.js";
|
|
19
18
|
import { canonicalJson } from "./canonical-json.js";
|
|
20
19
|
export { isAcpProfile };
|
|
21
|
-
/**
|
|
22
|
-
* What a task is allowed to become, agreed before anything builds it.
|
|
23
|
-
*
|
|
24
|
-
* The gap this closes is the one an operator notices immediately and a
|
|
25
|
-
* scheduler never does: a task called "fix the payouts flow" is a sentence, and
|
|
26
|
-
* an agent handed it at 3am will decide for itself what that means. It might
|
|
27
|
-
* mean a two-line guard. It might mean rewriting the billing model. Nobody
|
|
28
|
-
* agreed to the second one, and by morning it is a diff.
|
|
29
|
-
*
|
|
30
|
-
* So a scope is written down, and a human opts in to it, and the builder will
|
|
31
|
-
* not run on a task where that has not happened. Not a code review after the
|
|
32
|
-
* fact — an agreement about the goal, before the work.
|
|
33
|
-
*
|
|
34
|
-
* **Approval binds to the words that were approved.** The record keeps a digest
|
|
35
|
-
* of the scope text, and approval stores the digest it saw. Rewriting the scope
|
|
36
|
-
* afterwards does not carry the approval with it; the digests stop matching and
|
|
37
|
-
* the task is unapproved again. Without that, "approved" would mean "was
|
|
38
|
-
* approved once, in some form" — which is exactly the loophole an agent editing
|
|
39
|
-
* its own brief would walk through.
|
|
40
|
-
*
|
|
41
|
-
* The scope is deliberately three plain fields rather than a template. What is
|
|
42
|
-
* the goal, what is explicitly not in it, and which paths it expects to touch.
|
|
43
|
-
* An operator reading that at a glance can tell whether they agree, and that
|
|
44
|
-
* glance is the whole safety property.
|
|
45
|
-
*/
|
|
46
20
|
import { createHash, randomBytes, scryptSync, timingSafeEqual } from "node:crypto";
|
|
47
21
|
import { networkFromValue, networkWords } from "./egress.js";
|
|
48
22
|
import { isWritesMode, writesWords } from "./writes-mode.js";
|
|
@@ -56,28 +30,18 @@ import { taskArchived, taskCancelled } from "./task-archive.js";
|
|
|
56
30
|
import { releaseCiHoldOf, releaseCiHoldWords } from "./release-ci-hold.js";
|
|
57
31
|
import { releaseApprovalRefusal } from "./release-refusal.js";
|
|
58
32
|
import { NO_READINESS, exactModelId, legOf, projectRoute, routeDigestOf, routeFromJson, routeJsonProblem, routeWords, } from "./phase-routing.js";
|
|
59
|
-
/** Same shape as a runner's credential, for the same reasons. */
|
|
60
33
|
function mintToken() {
|
|
61
34
|
return mintSecret(32);
|
|
62
35
|
}
|
|
63
36
|
export function hashToken(token) {
|
|
64
37
|
return createHash("sha256").update(token, "utf8").digest("hex");
|
|
65
38
|
}
|
|
66
|
-
/**
|
|
67
|
-
* A person's chosen password gets a real KDF. Bare sha256 is fine for the
|
|
68
|
-
* minted 256-bit tokens — nothing brute-forces that space — but a password a
|
|
69
|
-
* human picked lives in a much smaller one, so it is salted and stretched
|
|
70
|
-
* (scrypt), and the stored string names its own scheme so both generations
|
|
71
|
-
* of credential verify side by side.
|
|
72
|
-
*/
|
|
73
39
|
export function hashPassword(password) {
|
|
74
40
|
const salt = randomBytes(16).toString("hex");
|
|
75
41
|
const hash = scryptSync(password, salt, 32).toString("hex");
|
|
76
42
|
return `scrypt$${salt}$${hash}`;
|
|
77
43
|
}
|
|
78
|
-
/** Verify a presented secret against a stored hash of either scheme. */
|
|
79
44
|
export function verifyCredential(stored, presented) {
|
|
80
|
-
// v100: an account that signs in only with the identity provider has no password to match.
|
|
81
45
|
if (stored.startsWith("sso-only$"))
|
|
82
46
|
return false;
|
|
83
47
|
if (stored.startsWith("scrypt$")) {
|
|
@@ -95,20 +59,7 @@ function sameDigest(left, right) {
|
|
|
95
59
|
const b = Buffer.from(right, "utf8");
|
|
96
60
|
return a.length === b.length && timingSafeEqual(a, b);
|
|
97
61
|
}
|
|
98
|
-
/**
|
|
99
|
-
* The execution profile (Parity II foundations, findings 1/2/13/14/22):
|
|
100
|
-
* WHAT RUNS, bound into what the operator signs. A discriminated union —
|
|
101
|
-
* each variant asserts only what its provider actually supports, with the
|
|
102
|
-
* EFFECTIVE constants the argv will carry, never aspirations. The model
|
|
103
|
-
* is always an exact string and always emitted on the argv: nothing in an
|
|
104
|
-
* approved profile is left for later resolution to decide (ruling 10).
|
|
105
|
-
* providerVersion and resolvedFrom are PROVENANCE and live outside these
|
|
106
|
-
* shapes (finding 20) — they never enter a digest.
|
|
107
|
-
*/
|
|
108
62
|
export const CLAUDE_LIMITS = {
|
|
109
|
-
// The activity watchdog is the real safety rail. Keep a very high turn
|
|
110
|
-
// breaker only for a pathological loop; ordinary long-horizon work should
|
|
111
|
-
// finish, checkpoint, or park long before it can reach this number.
|
|
112
63
|
maxTurns: 1_000,
|
|
113
64
|
repairMaxTurns: 4,
|
|
114
65
|
timeoutSeconds: 1_200,
|
|
@@ -122,63 +73,41 @@ export const GEMINI_LIMITS = {
|
|
|
122
73
|
timeoutSeconds: 1200,
|
|
123
74
|
repairTimeoutSeconds: 300,
|
|
124
75
|
};
|
|
125
|
-
/** An ACP agent runs under two clocks at once: the whole attempt, and silence (no line from the agent). */
|
|
126
76
|
export const ACP_LIMITS = {
|
|
127
77
|
timeoutSeconds: 3600,
|
|
128
78
|
idleTimeoutSeconds: 900,
|
|
129
79
|
repairTimeoutSeconds: 900,
|
|
130
80
|
repairIdleTimeoutSeconds: 300,
|
|
131
81
|
};
|
|
132
|
-
/** Whether a profile's clock is a no-progress window (an ACP profile has both clocks; its overall one is a deadline). */
|
|
133
82
|
export function idleClock(profile) {
|
|
134
83
|
return !isAcpProfile(profile) && profile.timeoutKind === "idle";
|
|
135
84
|
}
|
|
136
|
-
/**
|
|
137
|
-
* The watchdogs an attempt runs under, from its sealed profile and the overall bound the caller resolved: an ACP
|
|
138
|
-
* profile gets both clocks at once (the deadline and its silence window — a repair its own pair); the others one,
|
|
139
|
-
* a no-progress window when the profile says idle, else a deadline.
|
|
140
|
-
*/
|
|
141
85
|
export function watchdogsOf(profile, timeoutMs, repair = false) {
|
|
142
86
|
if (isAcpProfile(profile))
|
|
143
87
|
return { timeoutMs, idleTimeoutMs: (repair ? profile.repairIdleTimeoutSeconds : profile.idleTimeoutSeconds) * 1000 };
|
|
144
88
|
return profile.timeoutKind === "idle" ? { idleTimeoutMs: timeoutMs } : { timeoutMs };
|
|
145
89
|
}
|
|
146
90
|
export const PROFILE_DIGEST_VERSION = 2;
|
|
147
|
-
/** The stored snapshot bytes: version embedded IN the snapshot (finding 17). */
|
|
148
91
|
export function canonicalProfileJson(profile) {
|
|
149
92
|
return canonicalJson({ digestVersion: PROFILE_DIGEST_VERSION, profile });
|
|
150
93
|
}
|
|
151
|
-
/** sha256 over a domain-separated canonical encoding, truncated to the
|
|
152
|
-
* same 128 bits every other safety digest here uses (finding 21). */
|
|
153
94
|
export function profileDigestOf(profile) {
|
|
154
95
|
return createHash("sha256")
|
|
155
96
|
.update(`standing-orders:profile:${canonicalProfileJson(profile)}`, "utf8")
|
|
156
97
|
.digest("hex")
|
|
157
98
|
.slice(0, 32);
|
|
158
99
|
}
|
|
159
|
-
// ---- fallback chains (fallback.ts, docs/plans/fallback-chains.md) ----------
|
|
160
|
-
// Version 1 is history (v30-v114): an old approval still decodes and its digest
|
|
161
|
-
// still re-derives, so old tasks verify and render, and it holds no authority.
|
|
162
|
-
// Version 2 is what filing writes now: only it dispatches.
|
|
163
100
|
export const CHAIN_DIGEST_VERSION = 1;
|
|
164
101
|
export const LIVE_CHAIN_VERSION = 2;
|
|
165
|
-
/** The stored snapshot bytes for a chain: the version rides IN the
|
|
166
|
-
* snapshot, exactly like a single profile's. */
|
|
167
102
|
export function canonicalChainJson(entries, version = CHAIN_DIGEST_VERSION) {
|
|
168
103
|
return canonicalJson({ digestVersion: version, chain: entries });
|
|
169
104
|
}
|
|
170
|
-
/** sha256 over a domain-separated canonical chain encoding — a DIFFERENT
|
|
171
|
-
* domain from a single profile ("standing-orders:chain:" vs
|
|
172
|
-
* ":profile:"), so a chain digest can never collide with a profile
|
|
173
|
-
* digest, truncated to the same 128 bits. */
|
|
174
105
|
export function chainDigestOf(entries, version = CHAIN_DIGEST_VERSION) {
|
|
175
106
|
return createHash("sha256")
|
|
176
107
|
.update(`standing-orders:chain:v${version}:${canonicalChainJson(entries, version)}`, "utf8")
|
|
177
108
|
.digest("hex")
|
|
178
109
|
.slice(0, 32);
|
|
179
110
|
}
|
|
180
|
-
/** Strict re-hydration of a stored chain — every entry proved through the
|
|
181
|
-
* single-profile rehydrator; anything unexpected is null. */
|
|
182
111
|
export function chainFromJson(json, version = CHAIN_DIGEST_VERSION) {
|
|
183
112
|
if (json === null)
|
|
184
113
|
return null;
|
|
@@ -194,8 +123,6 @@ export function chainFromJson(json, version = CHAIN_DIGEST_VERSION) {
|
|
|
194
123
|
const wrapper = parsed;
|
|
195
124
|
if (wrapper.digestVersion !== version)
|
|
196
125
|
return null;
|
|
197
|
-
// Exact keys on the wrapper and on every entry (v48 integrity): a
|
|
198
|
-
// snapshot carrying anything this code never writes is not one it wrote.
|
|
199
126
|
if (!exactKeys(wrapper, ["digestVersion", "chain"], []))
|
|
200
127
|
return null;
|
|
201
128
|
if (!Array.isArray(wrapper.chain) || wrapper.chain.length === 0 || wrapper.chain.length > 4)
|
|
@@ -208,20 +135,13 @@ export function chainFromJson(json, version = CHAIN_DIGEST_VERSION) {
|
|
|
208
135
|
const e = raw;
|
|
209
136
|
if (!exactKeys(e, ["profile", "authMode"], []))
|
|
210
137
|
return null;
|
|
211
|
-
// A malformed auth mode is a malformed entry — never a default.
|
|
212
138
|
if (e.authMode !== "subscription" && e.authMode !== "api-key")
|
|
213
139
|
return null;
|
|
214
140
|
if (e.profile === null || typeof e.profile !== "object" || Array.isArray(e.profile))
|
|
215
141
|
return null;
|
|
216
|
-
// The profile rehydrates through the SAME strict path, wrapped as its
|
|
217
|
-
// own canonical snapshot so profileFromJson can prove it — and the
|
|
218
|
-
// canonical bytes must be the stored bytes' own keys (canonicalJson
|
|
219
|
-
// drops nothing, so an extra key survives into the strict parse).
|
|
220
142
|
const profile = profileFromJson(canonicalProfileJson(e.profile));
|
|
221
143
|
if (profile === null)
|
|
222
144
|
return null;
|
|
223
|
-
// Duplicate exact entries are rejected (open q i): the key is the
|
|
224
|
-
// profile digest + auth mode.
|
|
225
145
|
const key = `${profileDigestOf(profile)}:${e.authMode}`;
|
|
226
146
|
if (seen.has(key))
|
|
227
147
|
return null;
|
|
@@ -230,15 +150,6 @@ export function chainFromJson(json, version = CHAIN_DIGEST_VERSION) {
|
|
|
230
150
|
}
|
|
231
151
|
return entries;
|
|
232
152
|
}
|
|
233
|
-
/**
|
|
234
|
-
* THE STRICT RAW TERMS READ (raw authority repair): the stored columns of
|
|
235
|
-
* a scope or a standing order, proved EXACTLY — a JSON list is a list of
|
|
236
|
-
* strings and nothing else, a rubric is a list of whole criteria carrying
|
|
237
|
-
* exactly the keys this code writes and parsing with zero problems, a
|
|
238
|
-
* budget is a safe integer or null. Nothing is filtered, defaulted, or
|
|
239
|
-
* coerced on the way to an authority: the words say what is wrong, and
|
|
240
|
-
* the caller refuses.
|
|
241
|
-
*/
|
|
242
153
|
export function exactStringList(value, what) {
|
|
243
154
|
if (typeof value !== "string")
|
|
244
155
|
return { ok: false, problem: `${what} is not stored as text` };
|
|
@@ -269,7 +180,6 @@ export function exactAcceptance(value) {
|
|
|
269
180
|
}
|
|
270
181
|
if (!Array.isArray(parsed))
|
|
271
182
|
return { ok: false, problem: "the rubric is not a JSON list" };
|
|
272
|
-
// Stored, a criterion carries exactly the keys this code writes: the saved rubric schema is strict about them.
|
|
273
183
|
const strict = parseContract(z.object({ acceptance: storedRubricSchema }), { acceptance: parsed });
|
|
274
184
|
for (const issue of strict.ok ? [] : strict.issues) {
|
|
275
185
|
const entry = /^acceptance\[(\d+)\]$/.exec(issue.path);
|
|
@@ -292,35 +202,19 @@ export function exactSafeIntegerOrNull(value, what) {
|
|
|
292
202
|
return `${what} is not a safe integer`;
|
|
293
203
|
return null;
|
|
294
204
|
}
|
|
295
|
-
/**
|
|
296
|
-
* The longest clock a snapshot may bind, in seconds: a JavaScript timer
|
|
297
|
-
* holds at most 2^31 − 1 milliseconds, and a bound past that fires at
|
|
298
|
-
* once instead of never — a "timeout" that is not one. Every stored
|
|
299
|
-
* clock is proved against this before it is believed (v48 integrity).
|
|
300
|
-
*/
|
|
301
205
|
export const MAX_TIMER_SECONDS = Math.floor(2_147_483_647 / 1000);
|
|
302
|
-
/** A positive integer the platform can represent exactly. */
|
|
303
206
|
export function safePositiveInteger(v) {
|
|
304
207
|
return typeof v === "number" && Number.isSafeInteger(v) && v > 0;
|
|
305
208
|
}
|
|
306
|
-
/** A positive whole number of seconds a timer can actually wait. */
|
|
307
209
|
export function timerSafeSeconds(v) {
|
|
308
210
|
return safePositiveInteger(v) && v <= MAX_TIMER_SECONDS;
|
|
309
211
|
}
|
|
310
|
-
/**
|
|
311
|
-
* Whether an object carries exactly the named keys: every required key
|
|
312
|
-
* present, only optional keys otherwise, nothing unknown. Stored snapshots
|
|
313
|
-
* are proved this way so a key this code never writes is a refusal, never
|
|
314
|
-
* an ignorable extra.
|
|
315
|
-
*/
|
|
316
212
|
export function exactKeys(value, required, optional) {
|
|
317
213
|
const keys = Object.keys(value);
|
|
318
214
|
if (required.some(key => !keys.includes(key)))
|
|
319
215
|
return false;
|
|
320
216
|
return keys.every(key => required.includes(key) || optional.includes(key));
|
|
321
217
|
}
|
|
322
|
-
/** Strict re-hydration of a stored snapshot — every field type-proved;
|
|
323
|
-
* anything unexpected is null, never a guess. */
|
|
324
218
|
export function profileFromJson(json) {
|
|
325
219
|
if (json === null)
|
|
326
220
|
return null;
|
|
@@ -336,42 +230,26 @@ export function profileFromJson(json) {
|
|
|
336
230
|
const wrapper = parsed;
|
|
337
231
|
if (wrapper.digestVersion !== PROFILE_DIGEST_VERSION)
|
|
338
232
|
return null;
|
|
339
|
-
// EXACT KEYS (v48 integrity): the wrapper carries the version and the
|
|
340
|
-
// profile and nothing else, and the profile carries exactly its
|
|
341
|
-
// provider's fields — a snapshot with a key this code never writes was
|
|
342
|
-
// not written by this code and rehydrates as nothing, never as "the
|
|
343
|
-
// known part of it".
|
|
344
233
|
if (!exactKeys(wrapper, ["digestVersion", "profile"], []))
|
|
345
234
|
return null;
|
|
346
235
|
const p = wrapper.profile;
|
|
347
236
|
if (p === null || p === undefined || typeof p !== "object" || Array.isArray(p))
|
|
348
237
|
return null;
|
|
349
|
-
// STRICT fields (v48 authority repair): a model is an exact id (the same shape every
|
|
350
|
-
// provider argv accepts), a repair model is `inherit` or an exact id, a
|
|
351
|
-
// turn bound is a positive SAFE integer, and a clock is a positive whole
|
|
352
|
-
// number of seconds a timer can actually hold — a snapshot carrying
|
|
353
|
-
// anything else (a negative turn count, a fractional second, a model
|
|
354
|
-
// that is not an id, a clock past what setTimeout can wait) was not
|
|
355
|
-
// written by this code and rehydrates as nothing.
|
|
356
238
|
const str = (v) => exactModelId(v);
|
|
357
239
|
const repairRef = (v) => v === "inherit" || exactModelId(v);
|
|
358
240
|
const num = (v) => safePositiveInteger(v);
|
|
359
241
|
const clock = (v) => timerSafeSeconds(v);
|
|
360
242
|
const PROVIDER_KEYS = ["provider", "model", "maxTurns", "repairMaxTurns", "timeoutSeconds", "repairTimeoutSeconds", "repairModel"];
|
|
361
|
-
// The network a scope was written with: present and exact, or absent (an approval from before network policies).
|
|
362
243
|
const network = p["network"] === undefined ? undefined : networkFromValue(p["network"]);
|
|
363
244
|
if (network === null)
|
|
364
245
|
return null;
|
|
365
246
|
const writes = p["writes"];
|
|
366
247
|
if (writes !== undefined && !isWritesMode(writes))
|
|
367
248
|
return null;
|
|
368
|
-
// Check access is sealed only when wider than sandboxed: an explicit "sandboxed", or any other word, is not this code's.
|
|
369
249
|
const sealedAccess = p["checkAccess"];
|
|
370
250
|
if (sealedAccess !== undefined && (sealedAccess === "sandboxed" || !isCheckAccess(sealedAccess)))
|
|
371
251
|
return null;
|
|
372
252
|
const checkAccess = sealedAccess;
|
|
373
|
-
// Sandbox parity (v133): the policy version is exactly 2 when present; the lists, when present, are non-empty, sorted,
|
|
374
|
-
// distinct and valid (project-sandbox.ts), as only this code writes them.
|
|
375
253
|
const policy = p["fencePolicy"];
|
|
376
254
|
if (policy !== undefined && policy !== 2)
|
|
377
255
|
return null;
|
|
@@ -479,19 +357,8 @@ export function profileFromJson(json) {
|
|
|
479
357
|
}
|
|
480
358
|
return null;
|
|
481
359
|
}
|
|
482
|
-
/**
|
|
483
|
-
* Parse a rubric from already-JSON-parsed input (the planner's handoff, a
|
|
484
|
-
* console form, a template or a schedule's terms): fail closed, every
|
|
485
|
-
* problem reported at once, each naming its path — the acceptance contract
|
|
486
|
-
* (contracts/scope.ts) reads it. An absent or empty `value` parses to `[]`
|
|
487
|
-
* with no problems: whether that is ALLOWED is a question for the caller
|
|
488
|
-
* (`propose` says yes; every authoring road says no), never for this parser.
|
|
489
|
-
*/
|
|
490
360
|
export function parseAcceptanceCriteria(value) {
|
|
491
361
|
const read = readAcceptance(value);
|
|
492
|
-
// Keep the prose shape plan.ts's existing acceptanceLine consumes. Validation stays in the contract; only this
|
|
493
|
-
// compatibility boundary formats messages. That mapping takes a field followed by a space, not a colon, and
|
|
494
|
-
// evidence-array indices belong in the detail because it recognizes only the criterion's index.
|
|
495
362
|
return {
|
|
496
363
|
...read,
|
|
497
364
|
problems: read.problems.map(problem => ({
|
|
@@ -502,37 +369,12 @@ export function parseAcceptanceCriteria(value) {
|
|
|
502
369
|
})),
|
|
503
370
|
};
|
|
504
371
|
}
|
|
505
|
-
/** The exact bytes a rubric's SIGNED terms reduce to for the digest: sorted
|
|
506
|
-
* by id, `how` dropped (advisory, never signed), evidence kinds sorted so
|
|
507
|
-
* two equivalent lists never digest differently. */
|
|
508
|
-
/**
|
|
509
|
-
* The plain-text rubric encoding shared by every non-JSON authoring
|
|
510
|
-
* surface — the console's rubric textarea (one line each) and the CLI's
|
|
511
|
-
* `--acceptance` flag (one line per `;`-separated entry): one criterion
|
|
512
|
-
* per line, shaped
|
|
513
|
-
*
|
|
514
|
-
* [id:] statement | evidence,kinds [| how]
|
|
515
|
-
*
|
|
516
|
-
* `id` is optional — auto-numbered `c1`, `c2`, ... in encounter order when
|
|
517
|
-
* every line omits it, so a person can write the rubric without inventing
|
|
518
|
-
* ids by hand. This function never validates; it only turns text into the
|
|
519
|
-
* same plain-object shape `parseAcceptanceCriteria` already validates, so
|
|
520
|
-
* both entry points can never drift on what counts as a valid criterion.
|
|
521
|
-
*/
|
|
522
|
-
/** The one criterion a filing may carry when nobody has written the rubric
|
|
523
|
-
* yet: the console's scout follow-ups file with it, and `--acceptance plan`
|
|
524
|
-
* on the command line expands to it. A mode with planAuto sends such a
|
|
525
|
-
* filing to the planner instead of building against it. */
|
|
526
372
|
export const PLACEHOLDER_RUBRIC_STATEMENT = "The operator has reviewed this follow-up and written a real rubric before approving it.";
|
|
527
373
|
export const PLACEHOLDER_RUBRIC = [{ id: "c1", statement: PLACEHOLDER_RUBRIC_STATEMENT, how: null, evidence: ["manual-review"] }];
|
|
528
374
|
export function rubricIsPlaceholder(acceptance) {
|
|
529
375
|
return acceptance.length === 1 && acceptance[0].statement === PLACEHOLDER_RUBRIC_STATEMENT &&
|
|
530
376
|
acceptance[0].evidence.length === 1 && acceptance[0].evidence[0] === "manual-review";
|
|
531
377
|
}
|
|
532
|
-
/** Split a `--acceptance` rubric into criteria. Criteria are `;`-separated,
|
|
533
|
-
* but a `;` inside a statement must not split it: every criterion ends with
|
|
534
|
-
* its `|<evidence kinds>` part, so a segment with no `|` is the front of the
|
|
535
|
-
* next one and is glued back on. The single word `plan` means the placeholder. */
|
|
536
378
|
export function splitAcceptanceRubric(text) {
|
|
537
379
|
if (text.trim().toLowerCase() === "plan")
|
|
538
380
|
return [`${PLACEHOLDER_RUBRIC_STATEMENT}|manual-review`];
|
|
@@ -570,8 +412,6 @@ export function acceptanceLinesToInput(lines) {
|
|
|
570
412
|
}
|
|
571
413
|
return out;
|
|
572
414
|
}
|
|
573
|
-
/** The inverse of `acceptanceLinesToInput`, for pre-filling an editor from
|
|
574
|
-
* a stored rubric — round-trips through `parseAcceptanceCriteria` exactly. */
|
|
575
415
|
export function acceptanceToLines(criteria) {
|
|
576
416
|
return criteria.map(c => `${c.id}: ${c.statement} | ${c.evidence.join(",")}${c.how === null ? "" : ` | ${c.how}`}`);
|
|
577
417
|
}
|
|
@@ -581,27 +421,7 @@ export function canonicalAcceptance(criteria) {
|
|
|
581
421
|
.map(c => ({ id: c.id, statement: c.statement.trim(), evidence: [...c.evidence].sort() }));
|
|
582
422
|
}
|
|
583
423
|
export const APPROVAL_BASES = ["password", "mode", "chat", "grant", "schedule", "lead", "carried", "auto-check", "auto-green"];
|
|
584
|
-
|
|
585
|
-
* The exact bytes an operator agreed to.
|
|
586
|
-
*
|
|
587
|
-
* Every field that constrains the work goes in. If a change to a field would
|
|
588
|
-
* change what an operator would have said, it has to move the digest, or the
|
|
589
|
-
* approval it invalidates would be an approval of something else.
|
|
590
|
-
*/
|
|
591
|
-
export function digestOf(scope,
|
|
592
|
-
// The execution target: a single profile (legacy v24), OR an explicit
|
|
593
|
-
// fallback chain (v30). BOTH fold through the SAME outer `profileDigest`
|
|
594
|
-
// key — the discriminator lives INSIDE the digest value (a chain digest
|
|
595
|
-
// is domain-separated from a profile digest), NEVER as an outer field
|
|
596
|
-
// (an outer field would change the legacy bytes; C1). A chain-of-one is
|
|
597
|
-
// still an EXPLICIT chain and uses the chain digest, distinct from the
|
|
598
|
-
// single-profile digest by design.
|
|
599
|
-
target,
|
|
600
|
-
// v47: the phase route. EVERY route filed since v47 folds in — routine
|
|
601
|
-
// shaped ones included — so the approval binds exactly which agent runs
|
|
602
|
-
// each phase. Absent (null) only for a row proven to predate v47, whose
|
|
603
|
-
// digest bytes are therefore untouched.
|
|
604
|
-
route) {
|
|
424
|
+
export function digestOf(scope, target, route) {
|
|
605
425
|
const innerDigest = target == null
|
|
606
426
|
? null
|
|
607
427
|
: "chain" in target
|
|
@@ -612,44 +432,24 @@ route) {
|
|
|
612
432
|
goal: scope.goal.trim(),
|
|
613
433
|
outOfScope: scope.outOfScope?.trim() ?? null,
|
|
614
434
|
touches: [...scope.touches].sort(),
|
|
615
|
-
// Absent and null digest identically, so every pre-v15 approval
|
|
616
|
-
// stays exactly as approved.
|
|
617
435
|
...(scope.budgetMicrousd == null ? {} : { budget: scope.budgetMicrousd }),
|
|
618
|
-
// Same absent/[] equivalence as budget, one key up: a rubric-less
|
|
619
|
-
// scope (every scope before v39, and any road that sends none)
|
|
620
|
-
// digests identically to today.
|
|
621
436
|
...(scope.acceptance === undefined || scope.acceptance.length === 0
|
|
622
437
|
? {}
|
|
623
438
|
: { acceptance: canonicalAcceptance(scope.acceptance) }),
|
|
624
|
-
// Default is the historical behavior and therefore hashes exactly
|
|
625
|
-
// like an absent v41 field. Strict is an explicit signed promise.
|
|
626
439
|
...(scope.qualityMode === "strict" ? { qualityMode: "strict" } : {}),
|
|
627
440
|
...(scope.candidate ? { candidate: scope.candidate } : {}),
|
|
628
441
|
...(scope.releaseTerms == null ? {} : { releaseTerms: releaseTermsDigest(scope.releaseTerms) }),
|
|
629
442
|
...(scope.releaseCheck == null ? {} : { releaseCheck: releaseCheckPurposeDigest(scope.releaseCheck) }),
|
|
630
|
-
// The single outer key, whichever target produced its inner value:
|
|
631
|
-
// absent => the golden and every profileless approval are untouched;
|
|
632
|
-
// a legacy profile => its exact profileDigestOf; an explicit chain
|
|
633
|
-
// => its chainDigestOf. Same key, discriminated value.
|
|
634
443
|
...(innerDigest == null ? {} : { profileDigest: innerDigest }),
|
|
635
|
-
// The route's own domain-separated digest, under its own key —
|
|
636
|
-
// absent only for a pre-v47 row.
|
|
637
444
|
...(route == null ? {} : { route: routeDigestOf(route) }),
|
|
638
445
|
}), "utf8")
|
|
639
446
|
.digest("hex")
|
|
640
|
-
// 128 bits. This is a safety token binding an approval to exact content,
|
|
641
|
-
// so it has to be well past the reach of a deliberate collision search —
|
|
642
|
-
// 64 bits is not, and the only cost of the longer one is a longer thing to
|
|
643
|
-
// paste back.
|
|
644
447
|
.slice(0, 32);
|
|
645
448
|
}
|
|
646
449
|
export function propose(store, input) {
|
|
647
450
|
return store.transact(() => {
|
|
648
451
|
const previous = store.getScope(input.taskId);
|
|
649
452
|
const saved = proposeLocked(store, input);
|
|
650
|
-
// A rewritten goal, exclusions, touches or rubric on a task that is planning starts its planning again (v119), in
|
|
651
|
-
// the same transaction: the next planner plans for the new terms, never from the old plan or its answers. An
|
|
652
|
-
// identical refile changes nothing; the planner's own handoff writes its draft without coming through here.
|
|
653
453
|
const ref = store.lookupRef(input.taskId);
|
|
654
454
|
if (ref !== null && ref.plan !== null && (previous === null || contractChangesOf(previous, saved).length > 0))
|
|
655
455
|
store.restartPlanning(ref.id, input.now);
|
|
@@ -665,11 +465,6 @@ function proposeLocked(store, input) {
|
|
|
665
465
|
...draft,
|
|
666
466
|
proposedAt: now.toISOString(),
|
|
667
467
|
digest: digestOf(draft),
|
|
668
|
-
// The previous approval is kept rather than cleared, and is invalidated by
|
|
669
|
-
// the digest no longer matching. Same safety — `approvalOf` requires them
|
|
670
|
-
// equal — but it preserves the fact that somebody once agreed to
|
|
671
|
-
// something, so the refusal can say "this was approved and then rewritten"
|
|
672
|
-
// instead of the much less useful "this was never approved".
|
|
673
468
|
approvedAt: previous?.approvedAt ?? null,
|
|
674
469
|
approvedBy: previous?.approvedBy ?? null,
|
|
675
470
|
approvedDigest: previous?.approvedDigest ?? null,
|
|
@@ -683,35 +478,13 @@ function proposeLocked(store, input) {
|
|
|
683
478
|
...(input.releaseCheck === undefined ? {} : { releaseCheck: input.releaseCheck }),
|
|
684
479
|
proposedVia,
|
|
685
480
|
});
|
|
686
|
-
// The store may have RECOMPUTED the digest to bind the resolved profile
|
|
687
|
-
// (v24 filing invariant) — what callers display must be what is stored.
|
|
688
481
|
const saved = store.getScope(taskId) ?? scope;
|
|
689
482
|
if (input.author !== undefined && input.author !== "")
|
|
690
483
|
store.recordScopeAuthor(taskId, saved.digest, input.author, now);
|
|
691
484
|
return saved;
|
|
692
485
|
}
|
|
693
|
-
/**
|
|
694
|
-
* A scope edit from a surface where the editor might be stale — two browser
|
|
695
|
-
* tabs, a form submitted after the world moved. `sawDigest` names the version
|
|
696
|
-
* the editor was looking at (null: they saw no scope at all); a mismatch is a
|
|
697
|
-
* refusal, never a silent overwrite of somebody else's words. Edits are also
|
|
698
|
-
* refused while a live claim holds the task: the running build read its scope
|
|
699
|
-
* at start, and rewording the agreement under it would make the digest lie
|
|
700
|
-
* about what the work was agreed to. Field caps and control-character rules
|
|
701
|
-
* live here because every one of these strings will later be rendered.
|
|
702
|
-
*
|
|
703
|
-
* v39: this is a scope-producing ROAD, not the `propose` primitive, so it is
|
|
704
|
-
* where the rubric becomes mandatory — every edit through here (a fresh
|
|
705
|
-
* proposal or a rewrite of an already-approved one) must carry at least one
|
|
706
|
-
* criterion, or it is refused with a clear `acceptance-required` reason
|
|
707
|
-
* rather than silently filing without one. A scope that already carries a
|
|
708
|
-
* live, unrewritten approval from before this code existed never reaches
|
|
709
|
-
* this function again unless somebody edits it — which is exactly when the
|
|
710
|
-
* requirement should start applying.
|
|
711
|
-
*/
|
|
712
486
|
export function proposeGuarded(store, input) {
|
|
713
487
|
const touches = [...(input.touches ?? [])].map(one => one.trim()).filter(one => one !== "");
|
|
714
|
-
// Plain words first for what a person typed (lengths, bytes, hidden text), then the scope contract.
|
|
715
488
|
const badText = validateScopeText({ goal: input.goal, outOfScope: input.outOfScope ?? null, touches });
|
|
716
489
|
if (badText !== null)
|
|
717
490
|
return badText;
|
|
@@ -738,35 +511,14 @@ export function proposeGuarded(store, input) {
|
|
|
738
511
|
return { ok: true, scope };
|
|
739
512
|
});
|
|
740
513
|
}
|
|
741
|
-
export function addApprover(store, name, now, by, newToken = mintToken, mutation = {},
|
|
742
|
-
/** A password the person chose. Absent, a token is minted and shown once. */
|
|
743
|
-
password) {
|
|
514
|
+
export function addApprover(store, name, now, by, newToken = mintToken, mutation = {}, password) {
|
|
744
515
|
if (password !== undefined && password.length < 8) {
|
|
745
516
|
return { ok: false, reason: "weak-password" };
|
|
746
517
|
}
|
|
747
|
-
// The first one bootstraps, because somebody has to be able to create the
|
|
748
|
-
// first one and there is nobody to ask yet. Every one after it has to be
|
|
749
|
-
// vouched for by an existing approver.
|
|
750
|
-
//
|
|
751
|
-
// Without that second rule the credential is worth nothing: an agent that
|
|
752
|
-
// can run these commands would simply mint an approver for itself and
|
|
753
|
-
// approve its own scope with it. The bootstrap window is real and is why
|
|
754
|
-
// this is the first thing an operator should do, before anything else can
|
|
755
|
-
// reach the queue.
|
|
756
|
-
// ONE transaction around detection, vouching, and the write (Codex
|
|
757
|
-
// people round 2, finding 1): a voucher revoked between the check and
|
|
758
|
-
// the save must lose — BEGIN IMMEDIATE serializes against the
|
|
759
|
-
// revocation cascade, so there is no between.
|
|
760
518
|
return store.transact(() => {
|
|
761
519
|
const existing = store.listApprovers();
|
|
762
520
|
const bootstrap = existing.length === 0;
|
|
763
521
|
if (!bootstrap) {
|
|
764
|
-
// ACTIVE approver standing, not a bare hash match (Codex people round
|
|
765
|
-
// 1, finding 1): a viewer's or a revoked person's credential is real
|
|
766
|
-
// and still vouches for nothing — the CLI is a ceremony site like any
|
|
767
|
-
// other, and this was the one road that forgot.
|
|
768
|
-
// Creating an approver is a credential act (docs/plans/passwordless.md): a password typed now, never a session or
|
|
769
|
-
// the CLI's remembered login under Passwordless.
|
|
770
522
|
const vouching = by === undefined ? { ok: false } : proveCredential(store, by.name, by.token);
|
|
771
523
|
if (!vouching.ok) {
|
|
772
524
|
return { ok: false, reason: "not-an-approver" };
|
|
@@ -781,26 +533,9 @@ password) {
|
|
|
781
533
|
return { ok: true, name, token, bootstrap, chosen: false };
|
|
782
534
|
});
|
|
783
535
|
}
|
|
784
|
-
/**
|
|
785
|
-
* Whether this name-and-token pair is a person the store knows. Shared by
|
|
786
|
-
* every act that requires a human's authority — approving a scope, answering
|
|
787
|
-
* a decision — because "who said yes" must never be a string the caller
|
|
788
|
-
* typed. Fails closed: with no approver registered there is nobody who can
|
|
789
|
-
* agree to anything, and treating that as "authority is not required here"
|
|
790
|
-
* would make the gate optional — which is the same as not having one.
|
|
791
|
-
*/
|
|
792
|
-
/**
|
|
793
|
-
* IDENTITY, split from authority (modes chain, D2/E2): who this credential
|
|
794
|
-
* belongs to and what standing they hold. Viewers authenticate here and
|
|
795
|
-
* read; every consequential act goes through authenticateApprover below,
|
|
796
|
-
* which additionally demands ACTIVE approver standing — so the forty
|
|
797
|
-
* ceremony sites enforce the role without one of them changing.
|
|
798
|
-
*/
|
|
799
536
|
export function authenticateAccount(store, by, secret) {
|
|
800
537
|
if (store.listApprovers().length === 0)
|
|
801
538
|
return { ok: false, reason: "no-approvers" };
|
|
802
|
-
// A remote run (runOperateAs) is its token's person: only that run's own credential names them, no password is
|
|
803
|
-
// checked or counted, and a read token stands as a viewer.
|
|
804
539
|
const remote = activeRemote();
|
|
805
540
|
if (remote !== null) {
|
|
806
541
|
const account = by === remote.account && secret === remote.secret ? store.accountOf(by) : null;
|
|
@@ -808,7 +543,6 @@ export function authenticateAccount(store, by, secret) {
|
|
|
808
543
|
return { ok: false, reason: "unknown" };
|
|
809
544
|
return { ok: true, role: remote.scope === "act" ? account.role : "viewer", generation: account.generation };
|
|
810
545
|
}
|
|
811
|
-
// A lead token signs in as its owner, only inside a command the lead runs with it (never a console sign-in).
|
|
812
546
|
const acting = currentActor();
|
|
813
547
|
if (acting?.lead === true && parseLeadToken(secret) !== null) {
|
|
814
548
|
const lead = store.leadFor(secret), account = store.accountOf(by);
|
|
@@ -816,22 +550,16 @@ export function authenticateAccount(store, by, secret) {
|
|
|
816
550
|
return { ok: false, reason: "unknown" };
|
|
817
551
|
return { ok: true, role: account.role, generation: account.generation };
|
|
818
552
|
}
|
|
819
|
-
// v99: wrong passwords in a row lock the name for a while from where they came, whatever road they came by. A
|
|
820
|
-
// locked or held-back source is refused before the password is checked.
|
|
821
553
|
const guard = passwordGuardOf(store), now = Date.now(), source = currentPasswordSource();
|
|
822
554
|
const account = store.accountOf(by), proof = provenPasswordAccount.getStore();
|
|
823
555
|
const proven = proof?.name === by && account !== null && account.revokedAt === null && proof.generation === account.generation;
|
|
824
556
|
const wait = guard.preflight(by, now, source, proven);
|
|
825
557
|
if (wait > 0)
|
|
826
558
|
return { ok: false, reason: "locked", retryAfterMs: wait };
|
|
827
|
-
// Unknown names and legacy minted-token/SSO accounts do the same one KDF as a password account. Throttled
|
|
828
|
-
// attempts above do none, for either name class; never disclose account existence through password work.
|
|
829
559
|
const dummy = `scrypt$${"0".repeat(32)}$${"0".repeat(64)}`;
|
|
830
560
|
const hash = account?.credentialHash ?? dummy;
|
|
831
561
|
if (!hash.startsWith("scrypt$"))
|
|
832
562
|
verifyCredential(dummy, secret);
|
|
833
|
-
// v147: an account with no password set (a local-mode owner) has a random hash; the KDF still runs (same timing), and
|
|
834
|
-
// nothing it is given ever matches.
|
|
835
563
|
const matches = verifyCredential(hash, secret) && account !== null && account.passwordSet;
|
|
836
564
|
if (account === null || !matches) {
|
|
837
565
|
guard.failed(by, now, source, account !== null);
|
|
@@ -840,28 +568,14 @@ export function authenticateAccount(store, by, secret) {
|
|
|
840
568
|
guard.succeeded(by, source);
|
|
841
569
|
if (account.revokedAt !== null)
|
|
842
570
|
return { ok: false, reason: "revoked" };
|
|
843
|
-
// Inside a command, the person who signed in is who acted (their own acts never ping them).
|
|
844
571
|
claimActor(by);
|
|
845
572
|
return { ok: true, role: account.role, generation: account.generation };
|
|
846
573
|
}
|
|
847
|
-
/**
|
|
848
|
-
* The local CLI's remembered login, marked for the one command that read it (operate.ts credentialsFrom): with
|
|
849
|
-
* Passwordless on, a proof made with it records "cli-login" — never a typed password — and no credential act accepts it.
|
|
850
|
-
* Scoped to that command's async chain; a browser request in the console's own process never carries it.
|
|
851
|
-
*/
|
|
852
574
|
export const rememberedLogin = new AsyncLocalStorage();
|
|
853
575
|
export const FRESH_WINDOW_MS = 15 * 60_000;
|
|
854
|
-
/** How long an explicit provider re-check stands in for one password typed now. */
|
|
855
576
|
export const SSO_NOW_MS = 5 * 60_000;
|
|
856
577
|
export const freshFacts = new AsyncLocalStorage();
|
|
857
578
|
const refunds = new AsyncLocalStorage();
|
|
858
|
-
/**
|
|
859
|
-
* Run an act a re-check may prove, spending the re-check only if the act happens: when it throws (a rolled-back
|
|
860
|
-
* transaction) or `failed` says it was refused, every re-check it spent is put back. ONLY for acts whose every effect
|
|
861
|
-
* is in one database transaction (an approval, a chat approval proposal, a chat turn opening): there, "refused" and
|
|
862
|
-
* "thrown" prove nothing happened. Every other step-up spends its re-check whatever comes of it (fail-closed: at worst
|
|
863
|
-
* the person confirms with their provider again). Synchronous acts only.
|
|
864
|
-
*/
|
|
865
579
|
export function spendingOnlyOnSuccess(act, failed) {
|
|
866
580
|
const spent = [];
|
|
867
581
|
let result;
|
|
@@ -876,18 +590,13 @@ export function spendingOnlyOnSuccess(act, failed) {
|
|
|
876
590
|
if (failed(result))
|
|
877
591
|
for (const refund of spent)
|
|
878
592
|
refund();
|
|
879
|
-
// Succeeded here, but an enclosing act (an outer transaction, the request itself) may still fail: it owns them now.
|
|
880
593
|
else
|
|
881
594
|
refunds.getStore()?.push(...spent);
|
|
882
595
|
return result;
|
|
883
596
|
}
|
|
884
597
|
const freshScope = new AsyncLocalStorage();
|
|
885
|
-
/** Run an allowlisted act: within it, a fresh password or re-check may stand in for one typed now. */
|
|
886
598
|
export function withFreshness(op, act) { return freshScope.run(op, act); }
|
|
887
599
|
const within = (at, floor, spanMs, now) => at !== null && at > 0 && at > floor && at <= now + 60_000 && now - at < spanMs;
|
|
888
|
-
/** The freshness this act may stand on now, or null: only inside an allowlisted act on an allowlisted route, for this
|
|
889
|
-
* person, on a direct local request, on a live session, within the window, after any Forget. `preview` asks it from a
|
|
890
|
-
* page (a GET) about the allowlisted act its form posts to — for words only, never to authorise. */
|
|
891
600
|
export function freshnessFor(by, now = Date.now(), preview = false) {
|
|
892
601
|
const op = freshScope.getStore(), facts = freshFacts.getStore();
|
|
893
602
|
if (op === undefined || facts == null || facts.actor !== by || !(facts.allowlisted || preview) || !facts.local || !facts.live())
|
|
@@ -899,21 +608,12 @@ export function freshnessFor(by, now = Date.now(), preview = false) {
|
|
|
899
608
|
return { method: "fresh-sso", at: sso };
|
|
900
609
|
return null;
|
|
901
610
|
}
|
|
902
|
-
/** Whether an explicit provider re-check is waiting to stand in for one step-up (the page says "Confirmed with …"). */
|
|
903
611
|
export function ssoNowAvailable(by, now = Date.now()) {
|
|
904
612
|
const facts = freshFacts.getStore();
|
|
905
613
|
return facts != null && facts.actor === by && facts.live() && within(facts.ssoNow(), facts.floor(), SSO_NOW_MS, now);
|
|
906
614
|
}
|
|
907
|
-
/**
|
|
908
|
-
* Proof that this person is here now, for any account step-up (an approver's or not): a password typed now, or an
|
|
909
|
-
* explicit provider re-check (consumed). The core of every console step-up; `authenticateApprover` adds standing.
|
|
910
|
-
*/
|
|
911
615
|
export function proveAccountNow(store, by, token, options = {}) {
|
|
912
616
|
const now = Date.now();
|
|
913
|
-
// Easy-start C1: a local owner is decided FIRST, before Passwordless and freshness, whatever was typed. An allowlisted
|
|
914
|
-
// act of its own, still standing (re-read here, inside the caller's transaction), is "local-owner"; anything else —
|
|
915
|
-
// a credential act, a read, another person, local mode moved — proves nothing. It never upgrades to a typed password.
|
|
916
|
-
// A lead's token or a remote API token in that chain is never the local owner (it stays a machine's proof below).
|
|
917
617
|
const local = activeRemote() === null && currentActor()?.lead !== true ? currentLocalOwner() : null;
|
|
918
618
|
if (local !== null) {
|
|
919
619
|
if (options.credential === true || local.account !== by || local.act === "read" || !localOwnerInFlight(local) || !localOwnerStandsNow(store, local))
|
|
@@ -923,11 +623,7 @@ export function proveAccountNow(store, by, token, options = {}) {
|
|
|
923
623
|
const facts = freshFacts.getStore();
|
|
924
624
|
if (facts != null && facts.actor === by && !facts.live())
|
|
925
625
|
return { ok: false, reason: "not-an-approver" };
|
|
926
|
-
// An empty password is never checked as a password (and never counts toward a lockout).
|
|
927
626
|
if (token === "") {
|
|
928
|
-
// Passwordless (read live): the person's own live browser session is the proof. Only a browser request carries facts;
|
|
929
|
-
// a CLI, a token, a chat bridge or detached work has none, and falls through to the rules below.
|
|
930
|
-
// A credential act never takes this road, so its own proofs (a one-use provider re-check) are reached and spent.
|
|
931
627
|
if (options.credential !== true && facts != null && facts.actor === by && facts.live() && passwordlessOn(store))
|
|
932
628
|
return { ok: true, method: "session", at: now };
|
|
933
629
|
if (ssoNowAvailable(by, now)) {
|
|
@@ -942,7 +638,6 @@ export function proveAccountNow(store, by, token, options = {}) {
|
|
|
942
638
|
const account = authenticateAccount(store, by, token);
|
|
943
639
|
if (!account.ok)
|
|
944
640
|
return { ok: false, reason: account.reason === "no-approvers" ? "no-approvers" : "not-an-approver" };
|
|
945
|
-
// A machine credential named the person (authenticateAccount takes it as them): say so, never "a password typed now".
|
|
946
641
|
if (activeRemote() !== null)
|
|
947
642
|
return { ok: true, method: "remote-token", at: now };
|
|
948
643
|
if (currentActor()?.lead === true && parseLeadToken(token) !== null)
|
|
@@ -954,17 +649,10 @@ export function proveAccountNow(store, by, token, options = {}) {
|
|
|
954
649
|
facts.stamp(now);
|
|
955
650
|
return { ok: true, method: "password-now", at: now };
|
|
956
651
|
}
|
|
957
|
-
/**
|
|
958
|
-
* A credential act (docs/plans/passwordless.md, the closed list: one that creates or widens a way in): only a password
|
|
959
|
-
* typed now, or a one-use identity-provider re-check, proves it — never a session, never a remembered password.
|
|
960
|
-
*/
|
|
961
|
-
/** Whether an empty password would pass for `by` right now because Passwordless is on and this is their live browser
|
|
962
|
-
* session. Read only — the act itself proves it again inside `proveAccountNow`. */
|
|
963
652
|
export function passwordlessSessionFor(store, by) {
|
|
964
653
|
const facts = freshFacts.getStore();
|
|
965
654
|
return facts != null && facts.actor === by && facts.live() && passwordlessOn(store);
|
|
966
655
|
}
|
|
967
|
-
/** Whether a proof is one a credential act accepts: a password typed now, or a one-use identity-provider re-check. */
|
|
968
656
|
export const credentialProof = (method) => method === "password-now" || method === "sso-now";
|
|
969
657
|
export function proveCredential(store, by, token, repo) {
|
|
970
658
|
const proved = authenticateApprover(store, by, token, repo, { credential: true });
|
|
@@ -979,15 +667,8 @@ export function authenticateApprover(store, by, token, repo, options = {}) {
|
|
|
979
667
|
const standing = approverStanding(store, by, repo);
|
|
980
668
|
return standing.ok ? proved : standing;
|
|
981
669
|
}
|
|
982
|
-
/**
|
|
983
|
-
* What an approval needs besides the password (v100: an identity-provider
|
|
984
|
-
* sign-in moments ago stands in for the password; nothing stands in for
|
|
985
|
-
* this): an active account in the approver role, with access to the project.
|
|
986
|
-
*/
|
|
987
670
|
export function approverStanding(store, by, repo) {
|
|
988
671
|
const account = store.accountOf(by);
|
|
989
|
-
// A viewer's credential is real and still cannot agree to anything —
|
|
990
|
-
// the words every refused ceremony shows are the viewer words.
|
|
991
672
|
if (account === null || account.revokedAt !== null || account.role !== "approver")
|
|
992
673
|
return { ok: false, reason: "not-an-approver" };
|
|
993
674
|
const context = projectAuthority.getStore();
|
|
@@ -996,21 +677,6 @@ export function approverStanding(store, by, repo) {
|
|
|
996
677
|
return { ok: false, reason: "not-an-approver" };
|
|
997
678
|
return { ok: true };
|
|
998
679
|
}
|
|
999
|
-
/**
|
|
1000
|
-
* C1's atomic road: file the scope AND seal its approval in ONE
|
|
1001
|
-
* transaction, under a mode the SAME transaction re-proves. The caller
|
|
1002
|
-
* has already authenticated the actor and matched channel rules; this
|
|
1003
|
-
* function owns the predicate's transactional half — mode active, actor
|
|
1004
|
-
* IS the signer, repo matches, and the sealed digest is the filed one
|
|
1005
|
-
* (trivially true here: they are the same transaction). Never
|
|
1006
|
-
* sealScopeApproval after a filing — that was the TOCTOU.
|
|
1007
|
-
*/
|
|
1008
|
-
/**
|
|
1009
|
-
* C1's coverage question, answerable from ANY filing road: does a live
|
|
1010
|
-
* mode make THIS actor's credentialed filing auto-approve here, and with
|
|
1011
|
-
* which defaults? Callers re-ask INSIDE their filing transaction — an
|
|
1012
|
-
* answer carried across transactions would be the TOCTOU again.
|
|
1013
|
-
*/
|
|
1014
680
|
export function modeFilingCoverage(store, repo, actor, now) {
|
|
1015
681
|
const mode = repo === null ? null : store.activeMode(repo, now);
|
|
1016
682
|
if (mode === null || mode.signedBy !== actor)
|
|
@@ -1050,9 +716,6 @@ export function fileAndSealUnderMode(store, input) {
|
|
|
1050
716
|
}
|
|
1051
717
|
if (!autoApprove)
|
|
1052
718
|
return { ok: false, reason: "not-covered" };
|
|
1053
|
-
// v39: a mode auto-approves a filing with NOBODY reading it at that
|
|
1054
|
-
// instant — of every road, this one can least afford to seal a scope
|
|
1055
|
-
// with no rubric to answer.
|
|
1056
719
|
if (parseAcceptanceCriteria(input.acceptance).criteria.length === 0) {
|
|
1057
720
|
return { ok: false, reason: "acceptance-required" };
|
|
1058
721
|
}
|
|
@@ -1061,39 +724,19 @@ export function fileAndSealUnderMode(store, input) {
|
|
|
1061
724
|
...(input.budgetMicrousd == null && defaultBudget !== null ? { budgetMicrousd: defaultBudget } : {}),
|
|
1062
725
|
...(escalated ? { posture: "escalated" } : {}),
|
|
1063
726
|
});
|
|
1064
|
-
// A scope that cannot say exactly which agents run (v47: every phase
|
|
1065
|
-
// exact, the route readable) is never auto-sealed — the words say why.
|
|
1066
727
|
if (scope.profileState === "unresolved") {
|
|
1067
728
|
return { ok: false, reason: "profile-unresolved", ...(scope.unresolvedReason == null ? {} : { detail: scope.unresolvedReason }) };
|
|
1068
729
|
}
|
|
1069
730
|
const sealed = store.sealScopeApproval(input.taskId, input.actor, input.now, input.mutation ?? {}, { kind: "mode", modeDigest: mode.digest });
|
|
1070
|
-
// The quarantine speaks through every caller (review finding 7): a
|
|
1071
|
-
// coordinator-filed task is never mode-admitted, and pretending the
|
|
1072
|
-
// seal landed would hide exactly the refusal the operator must see.
|
|
1073
731
|
if (!sealed)
|
|
1074
732
|
return { ok: false, reason: "coordinator-filed" };
|
|
1075
733
|
return { ok: true, scope: store.getScope(input.taskId), basis: "mode" };
|
|
1076
734
|
});
|
|
1077
735
|
}
|
|
1078
|
-
export function approve(store, taskId, by, now, sawDigest, token, mutation = {},
|
|
1079
|
-
/** A fast start (fast-start.ts): Build is this same yes, with its marker in the proof. Only that road passes it.
|
|
1080
|
-
* `typed`: a typed yes to a Start card (one-step-chat.md C5), the message that was the yes, recorded beside the marker. */
|
|
1081
|
-
fastStart,
|
|
1082
|
-
/** A person's own yes in chat (owner's decision, docs/plans/toolroll-cards.md): their tap or signed-in click stands in
|
|
1083
|
-
* for a password, so `token` is unused. Every rule below still applies. The caller has proved the person is the one
|
|
1084
|
-
* tapping. `shown` is what a card that showed its terms whole showed: those words, and the digest kept when it was
|
|
1085
|
-
* made. Null when the card showed less: the seal then opens none of the walls a person's reading opens. */
|
|
1086
|
-
chat) {
|
|
1087
|
-
// Read and write in one transaction, re-reading inside it — the credential
|
|
1088
|
-
// check included, so a token rotated between authentication and the write
|
|
1089
|
-
// cannot leave an approval signed by an authority that no longer exists.
|
|
1090
|
-
// Apart, a scope rewritten between the read and the write is overwritten by
|
|
1091
|
-
// this approval — which would resurrect the old wording *and* mark it
|
|
1092
|
-
// agreed, the precise opposite of what the digest is for.
|
|
736
|
+
export function approve(store, taskId, by, now, sawDigest, token, mutation = {}, fastStart, chat) {
|
|
1093
737
|
return store.transact(() => {
|
|
1094
738
|
const repoNow = store.lookupRef(taskId)?.repo ?? null;
|
|
1095
739
|
const account = chat === undefined ? null : store.accountOf(by);
|
|
1096
|
-
// A machine never reaches this road, and the person's role and reach are read here, in the seal's transaction.
|
|
1097
740
|
if (chat !== undefined && machineActing())
|
|
1098
741
|
return { ok: false, reason: "machine-proof" };
|
|
1099
742
|
if (chat !== undefined && (account === null || account.revokedAt !== null || account.role !== "approver" || repoNow === null || !store.accountCanAccess(by, repoNow)))
|
|
@@ -1101,12 +744,8 @@ chat) {
|
|
|
1101
744
|
const authenticated = chat !== undefined ? { ok: true, method: "chat", at: now.getTime() } : authenticateApprover(store, by, token, repoNow);
|
|
1102
745
|
if (!authenticated.ok)
|
|
1103
746
|
return authenticated;
|
|
1104
|
-
// ONLY A PERSON APPROVES (docs/plans/approval-policy.md, phase 1): a lead token or a remote API token proves the
|
|
1105
|
-
// credential, not a person at a ceremony. Refused before any vote or proof row is written.
|
|
1106
747
|
if (!personProof(authenticated.method))
|
|
1107
748
|
return { ok: false, reason: "machine-proof" };
|
|
1108
|
-
// Easy-start C5: a local owner approves only as the approve-plan act, and only eligible work (one shared rule:
|
|
1109
|
-
// localApprovalEligible, read again here inside the seal's transaction).
|
|
1110
749
|
const local = authenticated.method === "local-owner" ? currentLocalOwner() : null;
|
|
1111
750
|
if (authenticated.method === "local-owner") {
|
|
1112
751
|
if (local === null || (local.act !== "approve-plan" && !(local.act === "build-now" && fastStart !== undefined)))
|
|
@@ -1118,91 +757,57 @@ chat) {
|
|
|
1118
757
|
const scope = store.getScope(taskId);
|
|
1119
758
|
if (scope === null)
|
|
1120
759
|
return { ok: false, reason: "no-scope" };
|
|
1121
|
-
// A release takes no yes the release sheet would refuse (put away, CI held or failed, its check failed on this
|
|
1122
|
-
// commit, terms changed after an earlier yes), in the sheet's words, on every road: read here, before any vote.
|
|
1123
760
|
const releaseRefusal = releaseApprovalRefusal(store, taskId, scope);
|
|
1124
761
|
if (releaseRefusal !== null)
|
|
1125
762
|
return { ok: false, reason: "policy", message: releaseRefusal };
|
|
1126
|
-
// A put-away task (v145) is restored first; sealScopeApproval refuses it too, on every road.
|
|
1127
763
|
if (taskArchived(store, taskId))
|
|
1128
764
|
return { ok: false, reason: "archived" };
|
|
1129
|
-
// A cancelled task takes no yes either — read here, in the seal's transaction, before any vote or proof is
|
|
1130
|
-
// written: an approval page left open while the task was cancelled elsewhere, or the CLI, approves nothing.
|
|
1131
765
|
if (taskCancelled(store, taskId))
|
|
1132
766
|
return { ok: false, reason: "cancelled" };
|
|
1133
|
-
// The digest is required, not optional. An operator reads a scope, somebody
|
|
1134
|
-
// rewrites it, and an approval that did not name what it saw would agree to
|
|
1135
|
-
// the new one in silence — which is the whole failure this guards.
|
|
1136
767
|
if (sawDigest !== scope.digest)
|
|
1137
768
|
return { ok: false, reason: "changed" };
|
|
1138
|
-
// What the card showed when it was made is what this yes is to: other words, or words leaving out a widening, aren't.
|
|
1139
769
|
const shown = chat?.shown ?? null;
|
|
1140
770
|
if (shown !== null && (cardTermsDigest(shown.terms) !== shown.expect || !cardShowsScope(scope, shown.terms)))
|
|
1141
771
|
return { ok: false, reason: "changed" };
|
|
1142
|
-
// The "what changed" line a person read describes this exact route, or this yes isn't to what they read (route-change.ts).
|
|
1143
772
|
if (routeChangeProblem(store, taskId, scope))
|
|
1144
773
|
return { ok: false, reason: "changed" };
|
|
1145
|
-
// A fast start is never a task from outside (github-import.ts): that takes the ordinary ceremony.
|
|
1146
774
|
if (fastStart !== undefined && issueImported(store, taskId))
|
|
1147
775
|
return { ok: false, reason: "policy", message: "A task from outside takes the ordinary approval." };
|
|
1148
|
-
// An unresolved scope cannot say exactly what would run, so nobody can
|
|
1149
|
-
// agree to it (foundations finding 16) — restatement is the road.
|
|
1150
776
|
if (scope.profileState === "unresolved") {
|
|
1151
777
|
return { ok: false, reason: "profile-unresolved" };
|
|
1152
778
|
}
|
|
1153
|
-
// A row that predates agent routing cannot take a NEW yes (v48): an
|
|
1154
|
-
// approval now names exactly which agent plans, builds, repairs, and
|
|
1155
|
-
// reviews, and this row names none — re-filing routes it.
|
|
1156
779
|
if (scope.routeEra == null) {
|
|
1157
780
|
return { ok: false, reason: "unrouted" };
|
|
1158
781
|
}
|
|
1159
|
-
// SEPARATION OF DUTIES (v102): the project's rules, asked first so the
|
|
1160
|
-
// answer is words, not a silent refusal from the seal. Protected work
|
|
1161
|
-
// keeps each person's yes to these exact bytes and seals on the second.
|
|
1162
|
-
// Sprint 8: the organisation policy, before any vote is kept: a disallowed provider or model, or terms above the
|
|
1163
|
-
// permission ceiling, are refused in words that name the rule.
|
|
1164
782
|
const policy = store.scopePolicyRefusal(taskId);
|
|
1165
783
|
if (policy !== null)
|
|
1166
784
|
return { ok: false, reason: "policy", message: policy };
|
|
1167
|
-
// A release scope's yes opens its authority record (release-once.md); say first why it can't.
|
|
1168
785
|
const releaseProblem = scope.releaseTerms == null ? null : releaseSealProblem(store, scope.releaseTerms);
|
|
1169
786
|
if (releaseProblem !== null)
|
|
1170
787
|
return { ok: false, reason: "policy", message: releaseProblem };
|
|
1171
|
-
// Filed while CI still ran: nobody approves it before the plane read exact-head CI passing (round 1, finding 4).
|
|
1172
788
|
const ciHold = releaseCiHoldOf(store, taskId);
|
|
1173
789
|
if (ciHold !== null)
|
|
1174
790
|
return { ok: false, reason: "policy", message: releaseCiHoldWords(ciHold) };
|
|
1175
791
|
const gate = store.approvalGate(taskId, by, "person");
|
|
1176
792
|
if (gate.verdict === "refuse")
|
|
1177
793
|
return { ok: false, reason: gate.reason };
|
|
1178
|
-
// A remembered password (cockpit B2) approves only everyday work: one approver, standard permissions, terms a
|
|
1179
|
-
// person filed. Protected work, escalated terms and quarantined filings take a password typed now.
|
|
1180
794
|
if ((authenticated.method === "fresh-password" || authenticated.method === "fresh-sso") && !freshlyApprovable(store, taskId, scope, gate.verdict === "seal" && !gate.protectedWork)) {
|
|
1181
795
|
return { ok: false, reason: "password-now" };
|
|
1182
796
|
}
|
|
1183
|
-
// How the person was proved, beside every yes they give (a vote kept for protected work, or the seal): a password
|
|
1184
|
-
// typed now, a re-check now, or a remembered one — with when, the credential generation and the exact digest.
|
|
1185
797
|
const proved = () => store.recordAction({ at: now.toISOString(), actor: by, repo: store.lookupRef(taskId)?.repo ?? null, taskId, runId: null, action: APPROVAL_PROOF,
|
|
1186
798
|
outcome: authenticated.method, source: "work", detail: (fastStart === undefined ? approvalProofDetail : fastProofDetail(fastStart))(authenticated.at, store.accountOf(by)?.generation ?? 0, scope.digest, local === null ? undefined : { generation: local.localGeneration, transport: local.transport }) });
|
|
1187
799
|
if (gate.verdict === "vote") {
|
|
1188
|
-
// The same person again adds nothing: no new vote, no proof row (and the approval roads refund a re-check).
|
|
1189
800
|
if (gate.already)
|
|
1190
801
|
return { ok: false, reason: "second-approver", have: gate.have, need: gate.need, already: true };
|
|
1191
802
|
store.recordApprovalVote(taskId, scope.digest, by, now, authenticated.method);
|
|
1192
803
|
proved();
|
|
1193
804
|
return { ok: false, reason: "second-approver", have: gate.have, need: gate.need, already: gate.already };
|
|
1194
805
|
}
|
|
1195
|
-
// The vote, the seal and its proof stand or fall together: a seal that is refused takes this yes back with it
|
|
1196
|
-
// (savepoint rolled back), so a refusal leaves nothing written — the approval roads may then refund a re-check.
|
|
1197
806
|
const refused = {};
|
|
1198
807
|
try {
|
|
1199
808
|
return store.savepoint(() => {
|
|
1200
809
|
if (gate.protectedWork)
|
|
1201
810
|
store.recordApprovalVote(taskId, scope.digest, by, now, authenticated.method);
|
|
1202
|
-
// SEAL, never re-resolve: the approval snapshots the stored working
|
|
1203
|
-
// profile — the exact bytes the digest the approver signed was bound
|
|
1204
|
-
// to. Routing saveScope here would re-run resolution and could sign a
|
|
1205
|
-
// profile nobody saw.
|
|
1206
811
|
const sealed = chat === undefined ? store.sealScopeApproval(taskId, by, now, mutation)
|
|
1207
812
|
: store.sealScopeApproval(taskId, by, now, mutation, { kind: "chat", modeDigest: chat.modeDigest, ...(shown === null ? {} : { card: "shown", cardDigest: shown.expect, shownTerms: shown.terms }) }, "person");
|
|
1208
813
|
const approved = sealed ? store.getScope(taskId) : null;
|
|
@@ -1221,14 +826,9 @@ chat) {
|
|
|
1221
826
|
}
|
|
1222
827
|
});
|
|
1223
828
|
}
|
|
1224
|
-
/** The ledger act that records how an approval's person was proved (password-now, sso-now, fresh-password, fresh-sso). */
|
|
1225
829
|
export const APPROVAL_PROOF = "approval proved";
|
|
1226
|
-
/** The proof row's detail: when the person was proved, the generation, and the exact digest they said yes to. */
|
|
1227
830
|
export const approvalProofDetail = (at, generation, digest, local) => `${new Date(at).toISOString()} · generation ${generation}${local === undefined ? "" : ` · local ${local.generation} ${local.transport}`} · digest ${digest}`;
|
|
1228
|
-
/** A fast start's proof: the v1 record proofDetailOf reads, with the marker. `local` keeps the legacy words
|
|
1229
|
-
* localSealStandsSql reads, so a local owner's seal stands on the same rule. */
|
|
1230
831
|
const fastProofDetail = ({ typed, ...fastStart }) => (at, generation, digest, local) => JSON.stringify({ v: 1, at: new Date(at).toISOString(), generation, digest, fastStart, ...(typed === undefined ? {} : { typed: { provider: typed.provider, event: typed.event } }), ...(local === undefined ? {} : { local: `proof · local ${local.generation} ${local.transport} · seal` }) });
|
|
1231
|
-
/** The proof of THIS approval: the approver's own row for these exact bytes (never another approval's words). */
|
|
1232
832
|
export function approvalProofOf(store, taskId, by, digest) {
|
|
1233
833
|
const rows = store.handle.prepare("SELECT outcome, detail FROM action_ledger WHERE task_id = ? AND action = ? AND actor = ? ORDER BY id DESC LIMIT 50").all(taskId, APPROVAL_PROOF, by);
|
|
1234
834
|
for (const row of rows) {
|
|
@@ -1239,8 +839,6 @@ export function approvalProofOf(store, taskId, by, digest) {
|
|
|
1239
839
|
}
|
|
1240
840
|
return null;
|
|
1241
841
|
}
|
|
1242
|
-
/** Whether a remembered password may approve these terms: one approver (no protected work), standard permissions
|
|
1243
|
-
* (never escalated), and not filed by a coordinator, a lead or a scout (those keep their own password ceremony). */
|
|
1244
842
|
export function freshlyApprovable(store, taskId, scope, singleApprover) {
|
|
1245
843
|
if (!singleApprover)
|
|
1246
844
|
return false;
|
|
@@ -1252,14 +850,6 @@ export function freshlyApprovable(store, taskId, scope, singleApprover) {
|
|
|
1252
850
|
const via = store.handle.prepare("SELECT proposed_via FROM task_scope WHERE task_id = ?").get(taskId)?.["proposed_via"];
|
|
1253
851
|
return !quarantinedAuthor(typeof via === "string" ? via : null);
|
|
1254
852
|
}
|
|
1255
|
-
/**
|
|
1256
|
-
* Whether this task may be built.
|
|
1257
|
-
*
|
|
1258
|
-
* `changed` is the interesting answer and the reason the digest exists: the
|
|
1259
|
-
* scope was approved, and then somebody — possibly an agent, possibly the
|
|
1260
|
-
* operator, possibly a different session — rewrote it. The old yes does not
|
|
1261
|
-
* transfer.
|
|
1262
|
-
*/
|
|
1263
853
|
export function approvalOf(scope) {
|
|
1264
854
|
if (scope === null)
|
|
1265
855
|
return { approved: false, reason: "never-proposed" };
|
|
@@ -1268,27 +858,13 @@ export function approvalOf(scope) {
|
|
|
1268
858
|
}
|
|
1269
859
|
if (scope.approvedDigest !== scope.digest)
|
|
1270
860
|
return { approved: false, reason: "changed" };
|
|
1271
|
-
// A seal stands on a known authority (approval-policy plan §1.5): one left out or undefined, null (a row from before
|
|
1272
|
-
// the basis column) or a word this code doesn't write is no approval.
|
|
1273
861
|
if (scope.approvalBasis === undefined || scope.approvalBasis === null || !APPROVAL_BASES.includes(scope.approvalBasis)) {
|
|
1274
862
|
return { approved: false, reason: "none" };
|
|
1275
863
|
}
|
|
1276
|
-
// Phase 1: only people approve, so a lead's seal (including an old one a lead token made through the person's road,
|
|
1277
|
-
// which Store.getScope reads as `lead`) is no approval, and the person sees the Approve control again.
|
|
1278
864
|
if (scope.approvalBasis === "lead")
|
|
1279
865
|
return { approved: false, reason: "none" };
|
|
1280
866
|
return { approved: true, at: scope.approvedAt, by: scope.approvedBy };
|
|
1281
867
|
}
|
|
1282
|
-
/**
|
|
1283
|
-
* THE PARITY every projection proves between a route and the profile and
|
|
1284
|
-
* terms it was filed beside (atomic authority closure): the build and
|
|
1285
|
-
* repair legs ARE the profile's exact pairs, and the route's signed risk
|
|
1286
|
-
* and quality ARE the row's — a row whose risk says high over a route
|
|
1287
|
-
* recommended for routine was not filed by this code, and neither the
|
|
1288
|
-
* seal, the consent door, nor the dispatch proof believes it. One
|
|
1289
|
-
* function, so the working side, the sealed side, and the last-mile
|
|
1290
|
-
* dispatch proof cannot drift. Null when everything agrees.
|
|
1291
|
-
*/
|
|
1292
868
|
export function routeParityProblem(route, profile, terms) {
|
|
1293
869
|
const buildLeg = legOf(route, "build");
|
|
1294
870
|
const repairLeg = legOf(route, "repair");
|
|
@@ -1304,12 +880,7 @@ export function routeParityProblem(route, profile, terms) {
|
|
|
1304
880
|
}
|
|
1305
881
|
return null;
|
|
1306
882
|
}
|
|
1307
|
-
// Recovery reuses this exact raw-terms check before considering saved evidence.
|
|
1308
|
-
// Decoding authority does not renew approval or authorize a process-custody write.
|
|
1309
883
|
export function scopeAuthorityOf(scope, env = {}) {
|
|
1310
|
-
// THE RAW TERMS FIRST (raw authority repair): a row whose stored terms
|
|
1311
|
-
// or metadata do not read back exactly is no authority at all — not
|
|
1312
|
-
// the filtered, defaulted, or coerced reading of it.
|
|
1313
884
|
if (scope.termsProblem != null) {
|
|
1314
885
|
return { ok: false, reason: "terms", problem: `the scope's stored terms cannot be read exactly (${scope.termsProblem})` };
|
|
1315
886
|
}
|
|
@@ -1324,8 +895,6 @@ export function scopeAuthorityOf(scope, env = {}) {
|
|
|
1324
895
|
if (profile === null) {
|
|
1325
896
|
return { ok: false, reason: "profile", problem: profileJson === null ? "the scope carries no agent profile" : "the scope's agent profile cannot be read exactly (unknown keys, an unsafe number, or a clock no timer can hold)" };
|
|
1326
897
|
}
|
|
1327
|
-
// Fallback agents: a current chain whose base IS this profile. An older
|
|
1328
|
-
// chain (v30-v114) holds no authority: saving the scope again re-files it.
|
|
1329
898
|
const chain = scope.proposedChainJson == null ? null : liveChainFromJson(scope.proposedChainJson);
|
|
1330
899
|
if (scope.proposedChainJson != null && (chain === null || profileDigestOf(chain[0].profile) !== profileDigestOf(profile))) {
|
|
1331
900
|
return { ok: false, reason: "chain", problem: "this scope named fallback agents from an older version, or they can't be read — save the scope again to choose its agents" };
|
|
@@ -1342,28 +911,17 @@ export function scopeAuthorityOf(scope, env = {}) {
|
|
|
1342
911
|
if (digest !== scope.digest) {
|
|
1343
912
|
return { ok: false, reason: "digest", problem: "the scope's reference does not re-derive from its own terms, agents, and route — file it again" };
|
|
1344
913
|
}
|
|
1345
|
-
// THE AUTH MODE, strictly (atomic authority closure): the credential the
|
|
1346
|
-
// profile's provider would spend under is read through the caller's
|
|
1347
|
-
// strict reader — a present mode file that says neither word closes
|
|
1348
|
-
// the door in its words, never the default a lenient read would coerce
|
|
1349
|
-
// it to (the spawn reads the same way, so nothing sealed here spends
|
|
1350
|
-
// on a credential the operator never named).
|
|
1351
914
|
let authMode = null;
|
|
1352
915
|
if (env.authMode !== undefined) {
|
|
1353
916
|
const read = env.authMode(profile.provider);
|
|
1354
917
|
if (!read.ok)
|
|
1355
918
|
return { ok: false, reason: "auth-mode", problem: read.problem };
|
|
1356
919
|
authMode = read.mode;
|
|
1357
|
-
// The base was filed under one credential; a yes on another isn't a yes to these terms.
|
|
1358
920
|
if (chain !== null && chain[0].authMode !== authMode)
|
|
1359
921
|
return { ok: false, reason: "auth-mode", problem: "the agent's sign-in changed since this was filed — save the scope again" };
|
|
1360
922
|
}
|
|
1361
923
|
return { ok: true, profile, route, digest, authMode, ...(chain === null ? {} : { chain }) };
|
|
1362
924
|
}
|
|
1363
|
-
/** The rubric's approval-card lines (v39): one per criterion, the id in
|
|
1364
|
-
* front (the exact string a proof must answer by) and its required
|
|
1365
|
-
* evidence kinds after it — `how` is deliberately absent here, the same way
|
|
1366
|
-
* it is absent from the digest: it is guidance, never a signed term. */
|
|
1367
925
|
export function acceptanceWords(criteria) {
|
|
1368
926
|
if (criteria.length === 0)
|
|
1369
927
|
return [];
|
|
@@ -1372,17 +930,11 @@ export function acceptanceWords(criteria) {
|
|
|
1372
930
|
...criteria.slice(1).map(c => ` ${c.id}: ${c.statement} [shown by: ${c.evidence.join(", ")}]`),
|
|
1373
931
|
];
|
|
1374
932
|
}
|
|
1375
|
-
/** The route's approval-card lines (v47): the WORKING route the digest
|
|
1376
|
-
* bound, projected with whatever readiness the caller can see — the same
|
|
1377
|
-
* bytes the task page and chat render. Empty on a scope with no route. */
|
|
1378
933
|
export function scopeRouteWords(scope, readiness = NO_READINESS) {
|
|
1379
934
|
const route = routeFromJson(scope.proposedRouteJson ?? null);
|
|
1380
935
|
return route === null ? [] : routeWords(projectRoute(route, readiness));
|
|
1381
936
|
}
|
|
1382
|
-
|
|
1383
|
-
export function describeScope(scope, readiness = NO_READINESS,
|
|
1384
|
-
/** Results routing: the evidence line when an earned rule chose the builder (route-rules.ts taskEvidenceWords). */
|
|
1385
|
-
evidence = null) {
|
|
937
|
+
export function describeScope(scope, readiness = NO_READINESS, evidence = null) {
|
|
1386
938
|
const approval = approvalOf(scope);
|
|
1387
939
|
return [
|
|
1388
940
|
` goal ${scope.goal}`,
|
|
@@ -1393,16 +945,12 @@ evidence = null) {
|
|
|
1393
945
|
...(scope.budgetMicrousd === null
|
|
1394
946
|
? []
|
|
1395
947
|
: [` budget $${(scope.budgetMicrousd / 1_000_000).toFixed(2)} per build attempt — the agent is stopped at this figure`]),
|
|
1396
|
-
// The ROUTE, in the words the yes agrees to (v47): posture and every
|
|
1397
|
-
// leg with its reason and readiness — before anyone signs.
|
|
1398
948
|
...scopeRouteWords(scope, readiness),
|
|
1399
949
|
...(evidence === null ? [] : [` why model ${evidence.replace(/^Why this model: /, "")}`]),
|
|
1400
950
|
...chainTermsLines(scope).map((line, at) => at === 0 ? ` fallback ${line}` : ` ${line}`),
|
|
1401
|
-
// What the build may reach (egress.ts), part of what the yes agrees to.
|
|
1402
951
|
...(scope.profile === null || scope.profile === undefined ? [] : [` network ${networkWords(scope.profile.network ?? null).replace(/^Network: /, "")}`]),
|
|
1403
952
|
...(scope.profile === null || scope.profile === undefined ? [] : [` writes ${writesWords(scope.profile.writes)}`]),
|
|
1404
953
|
...(scope.profile?.checkAccess === undefined ? [] : [` checks ${checkAccessWords(scope.profile.checkAccess)}`]),
|
|
1405
|
-
// Its sandbox terms (project-sandbox.ts), part of what the yes agrees to: what it reads, and any widening.
|
|
1406
954
|
...(scope.profile === null || scope.profile === undefined ? [] : ((terms) => [` reads ${terms.reads}`, ...(terms.mach === null ? [] : [` services ${terms.mach}`])])(sandboxTermsWords(scope.profile))),
|
|
1407
955
|
...releaseTermsWords(scope.releaseTerms ?? null),
|
|
1408
956
|
...(scope.releaseCheck == null ? [] : [` release ${releaseCheckSentence(scope.releaseCheck)}`]),
|
|
@@ -1410,18 +958,15 @@ evidence = null) {
|
|
|
1410
958
|
` approved ${describeApproval(approval)}`,
|
|
1411
959
|
];
|
|
1412
960
|
}
|
|
1413
|
-
/** The approval sheet's release lines (release-once.md): the release in one sentence, then what asks again. */
|
|
1414
961
|
export function releaseTermsSentence(terms) {
|
|
1415
962
|
if (!terms.policy.carry)
|
|
1416
963
|
return `Release ${terms.packageVersion} from pull request #${terms.pr} at ${terms.approvedSha.slice(0, 7)}. Every later commit asks for your approval again.`;
|
|
1417
964
|
const outside = terms.access === "sandboxed" ? "" : " This project's checks don't run in the sandbox: those later test-only commits will run outside the sandbox without being shown to you first.";
|
|
1418
965
|
return `Release ${terms.packageVersion} from pull request #${terms.pr} at ${terms.approvedSha.slice(0, 7)}. Later commits on this pull request that only change tests, docs or the changelog ship without asking you again, until it merges or for 3 days. You'll see each one in the release summary.${outside}`;
|
|
1419
966
|
}
|
|
1420
|
-
/** The approval sheet's line for a release check purpose (pipeline-speed.md, P0): a release that can't carry. */
|
|
1421
967
|
export function releaseCheckSentence(purpose) {
|
|
1422
968
|
return `Release ${purpose.packageVersion} from pull request #${purpose.pr} at ${purpose.approvedSha.slice(0, 7)}. Every later commit asks for your approval again. If Toolroll's own machine fails during the check, it reruns this same commit's check (at most twice).`;
|
|
1423
969
|
}
|
|
1424
|
-
/** What asks again, in full: the terms behind the sentence. */
|
|
1425
970
|
export function releaseAsksAgainWords(terms) {
|
|
1426
971
|
const p = terms.policy;
|
|
1427
972
|
return [
|
|
@@ -1446,7 +991,6 @@ function describeApproval(approval) {
|
|
|
1446
991
|
}
|
|
1447
992
|
return "no — nothing will build this until somebody agrees to it";
|
|
1448
993
|
}
|
|
1449
|
-
// ---- Only a person approves (docs/plans/approval-policy.md, phase 1). Kept last: the freshness tripwire pins places.
|
|
1450
994
|
export { personProof } from "./person-proof.js";
|
|
1451
995
|
import { personProof } from "./person-proof.js";
|
|
1452
996
|
import { isProtectedWork, protectedChanges } from "./approval-policy.js";
|
|
@@ -1455,10 +999,7 @@ import { limitRecognised } from "./exhaustion.js";
|
|
|
1455
999
|
import { SUBSCRIPTION_CAPABLE } from "./keys.js";
|
|
1456
1000
|
import { releaseCheckPurposeDigest, releaseTermsDigest } from "./contracts/release-terms.js";
|
|
1457
1001
|
import { CHECK_ACCESS_WIDTH, autoEvidenceOf, belongsToRelease, carriesUnsandboxed, newestReleaseGeneration, releaseAuthorityOfTask, releaseAutoApproves, releaseSealProblem, releaseStateAt } from "./release-authority.js";
|
|
1458
|
-
/** Whether the command running now is a machine's: the lead (its token) or a remote API run. Trusted context only. */
|
|
1459
1002
|
export const machineActing = () => currentActor()?.lead === true || activeRemote() !== null;
|
|
1460
|
-
/** A proof row's detail, either form: the legacy text (`<at> · generation <n> · digest <d>`) or the versioned record
|
|
1461
|
-
* (`{"v":1,"at":…,"digest":…}`, more fields allowed). Any other shape is no proof. */
|
|
1462
1003
|
export function proofDetailOf(detail) {
|
|
1463
1004
|
if (typeof detail !== "string")
|
|
1464
1005
|
return null;
|
|
@@ -1476,7 +1017,6 @@ export function proofDetailOf(detail) {
|
|
|
1476
1017
|
}
|
|
1477
1018
|
}
|
|
1478
1019
|
const parts = detail.split(" · ");
|
|
1479
|
-
// Easy-start C5: a local owner's proof names its local generation and transport between the two (approvalProofDetail).
|
|
1480
1020
|
const local = parts.length === 4 ? parts.splice(2, 1)[0] : null;
|
|
1481
1021
|
if (local !== null && !/^local \d+ (browser|terminal)$/.test(local))
|
|
1482
1022
|
return null;
|
|
@@ -1484,12 +1024,6 @@ export function proofDetailOf(detail) {
|
|
|
1484
1024
|
return null;
|
|
1485
1025
|
return { at: parts[0], digest: parts[2].slice("digest ".length) };
|
|
1486
1026
|
}
|
|
1487
|
-
/**
|
|
1488
|
-
* A person's approval of this task as it stands: approved, on the current digest, by the ceremony (`password`) or a
|
|
1489
|
-
* paired-chat tap (`chat`), with a person's proof recorded for that approver and those exact bytes. Release, deploy
|
|
1490
|
-
* and the protected-work counters ask this; a lead, a mode, a grant, a schedule or an approval with no proof is not
|
|
1491
|
-
* a person's.
|
|
1492
|
-
*/
|
|
1493
1027
|
export function personApprovalOf(store, taskId) {
|
|
1494
1028
|
const scope = store.getScope(taskId);
|
|
1495
1029
|
if (scope === null || scope.approvedAt === null || scope.approvedBy === null || scope.approvedDigest === null)
|
|
@@ -1510,17 +1044,6 @@ export function personApprovalOf(store, taskId) {
|
|
|
1510
1044
|
return { ok: false, why: "no record shows a person approved these exact words; approve it again" };
|
|
1511
1045
|
return { ok: true, by: scope.approvedBy, at: scope.approvedAt, method: origin.method };
|
|
1512
1046
|
}
|
|
1513
|
-
/**
|
|
1514
|
-
* Who made a seal that says it came through a person's road (`password`, `chat`), from the acts recorded AT THAT SEAL
|
|
1515
|
-
* (approval policy §1.5): the proof rows its approver left at the seal's own instant, and the lead's task act then.
|
|
1516
|
-
* - `machine`: any proof there that isn't a person's (a lead or remote token, or a word this code doesn't know), or the
|
|
1517
|
-
* lead's act — fail closed, whatever its digest says;
|
|
1518
|
-
* - `person`: a person's proof there for these exact bytes (parsed, either form);
|
|
1519
|
-
* - `automation`: a standing order's firing that no person's proof stands behind;
|
|
1520
|
-
* - `unproven`: none of these (a seal from before proof rows): it dispatches as before, and is never a person's yes.
|
|
1521
|
-
* An older proof for the same bytes never vouches for a later seal. The dispatch belts ask the same in SQL
|
|
1522
|
-
* (approval-authority.ts).
|
|
1523
|
-
*/
|
|
1524
1047
|
export function sealOriginOf(store, taskId, by, digest, at) {
|
|
1525
1048
|
const rows = store.handle.prepare("SELECT outcome, detail FROM action_ledger WHERE task_id = ? AND action = ? AND actor = ? AND at = ? ORDER BY id DESC").all(taskId, APPROVAL_PROOF, by, at);
|
|
1526
1049
|
const leadAct = store.handle.prepare(`SELECT 1 AS hit FROM task_act a JOIN task_ref r ON r.id = a.task_ref AND r.backend = 'built-in'
|
|
@@ -1535,33 +1058,18 @@ export function sealOriginOf(store, taskId, by, digest, at) {
|
|
|
1535
1058
|
return { origin: "automation" };
|
|
1536
1059
|
return { origin: "unproven" };
|
|
1537
1060
|
}
|
|
1538
|
-
/** Text another machine wrote (a confirmed chat proposal, a coordinator, a scout): no mode, grant, remembered password
|
|
1539
|
-
* or chat tap seals it. The lead's own CLI text (`lead`) is not quarantined. */
|
|
1540
1061
|
export const quarantinedAuthor = (via) => via === "mate" || via === "coordinator" || via === "scout";
|
|
1541
|
-
/** Which states each action may start from (deploy and merge also resume their own reservation). */
|
|
1542
1062
|
const RELEASE_ACTION_STATES = {
|
|
1543
1063
|
dispatch: ["open"], complete: ["open"], deploy: ["open", "deploying"], merge: ["deploying", "merge-reserved"],
|
|
1544
1064
|
};
|
|
1545
|
-
/**
|
|
1546
|
-
* Whether a task that belongs to a release authority may do `action` now. It applies to EVERY such task, whether its
|
|
1547
|
-
* seal is the person's own or `carried`, and requires all of: the authority's current generation (never superseded,
|
|
1548
|
-
* revoked or expired before it started); a state that fits the action; the task is the authority's current tip; the
|
|
1549
|
-
* anchor's seal is a person's (personApprovalOf, unchanged) on the exact sealed anchor digest; the anchor's approver is
|
|
1550
|
-
* still an active approver with access to the project; for a carried task, a carry row for exactly this task, scope
|
|
1551
|
-
* digest, candidate and generation; the release check grant and check access as sealed (access only ever the fence);
|
|
1552
|
-
* a sealed policy this runtime knows; and, for deploy and merge, no open main-check failure blocking a composed check.
|
|
1553
|
-
* A task that belongs to no release reads `applies: false` — the ordinary rules decide it.
|
|
1554
|
-
*/
|
|
1555
1065
|
export function liveReleaseOf(store, taskId, action, now = new Date()) {
|
|
1556
1066
|
const found = releaseAuthorityOfTask(store, taskId);
|
|
1557
1067
|
if (found === null)
|
|
1558
1068
|
return { applies: false };
|
|
1559
1069
|
const { authority: a, carry } = found;
|
|
1560
1070
|
const refuse = (why) => ({ applies: true, ok: false, why, authority: a });
|
|
1561
|
-
// A put-away task (v145, task-tidy.md), or a put-away anchor, deploys, merges and carries nothing: restore it first.
|
|
1562
1071
|
if (taskArchived(store, taskId) || taskArchived(store, a.anchorTask))
|
|
1563
1072
|
return refuse("the release task is put away");
|
|
1564
|
-
// A cancelled task, or a cancelled anchor, the same: cancelling ends what its approval allows.
|
|
1565
1073
|
if (taskCancelled(store, taskId) || taskCancelled(store, a.anchorTask))
|
|
1566
1074
|
return refuse("the release task was cancelled");
|
|
1567
1075
|
const newest = newestReleaseGeneration(store, a.repo, a.version, a.pr);
|
|
@@ -1571,7 +1079,6 @@ export function liveReleaseOf(store, taskId, action, now = new Date()) {
|
|
|
1571
1079
|
return refuse("a newer approval of this release replaced this one");
|
|
1572
1080
|
if (a.state === "revoked")
|
|
1573
1081
|
return refuse(`${a.endedBy ?? "an approver"} stopped carrying commits for this release`);
|
|
1574
|
-
// Expiry stops every live state (security review): an operation already reserved finishes only through reconciliation.
|
|
1575
1082
|
if (releaseStateAt(a, now) === "expired")
|
|
1576
1083
|
return refuse("the release approval expired");
|
|
1577
1084
|
if (a.state === "merged")
|
|
@@ -1581,7 +1088,6 @@ export function liveReleaseOf(store, taskId, action, now = new Date()) {
|
|
|
1581
1088
|
if (a.tipTask !== taskId)
|
|
1582
1089
|
return refuse("this is not the release's current commit");
|
|
1583
1090
|
const anchor = store.getScope(a.anchorTask);
|
|
1584
|
-
// A person's yes, or the plane's own automatic one while the project still approves releases automatically.
|
|
1585
1091
|
const person = releaseApprovalOf(store, a.anchorTask, now);
|
|
1586
1092
|
if (!person.ok)
|
|
1587
1093
|
return refuse(`the release approval no longer stands: ${person.why}`);
|
|
@@ -1603,8 +1109,6 @@ export function liveReleaseOf(store, taskId, action, now = new Date()) {
|
|
|
1603
1109
|
const grant = store.liveVerifyCommand(a.repo);
|
|
1604
1110
|
if (grant === null || grant.id !== a.verifyCommand || grant.digest !== a.verifyDigest)
|
|
1605
1111
|
return refuse("the release check command changed since the approval");
|
|
1606
|
-
// The checks reach no further than at the approval. Wider than the sandbox, a carried commit stands only while both
|
|
1607
|
-
// the sealed and the current "Carry release approvals when checks aren't sandboxed" allow it (the stricter of the two).
|
|
1608
1112
|
const access = store.projectCheckAccess(a.repo);
|
|
1609
1113
|
const sealedWidth = CHECK_ACCESS_WIDTH[a.accessDigest], nowWidth = CHECK_ACCESS_WIDTH[access];
|
|
1610
1114
|
if (sealedWidth === undefined || nowWidth === undefined || nowWidth > sealedWidth)
|
|
@@ -1621,10 +1125,6 @@ export function liveReleaseOf(store, taskId, action, now = new Date()) {
|
|
|
1621
1125
|
}
|
|
1622
1126
|
return { applies: true, ok: true, authority: a, carry };
|
|
1623
1127
|
}
|
|
1624
|
-
/**
|
|
1625
|
-
* Open main-check failures (the nightly full check, part 3) block the deploy and the merge of a release whose gate
|
|
1626
|
-
* check was composed from a targeted run: a full pass is needed first. Null when nothing blocks.
|
|
1627
|
-
*/
|
|
1628
1128
|
export function mainDebtProblem(store, repo, taskId) {
|
|
1629
1129
|
const open = Number(store.handle.prepare("SELECT COUNT(*) AS n FROM main_check_failure WHERE repo = ? AND cleared_at IS NULL").get(repo)?.["n"] ?? 0);
|
|
1630
1130
|
if (open === 0)
|
|
@@ -1638,31 +1138,12 @@ export function mainDebtProblem(store, repo, taskId) {
|
|
|
1638
1138
|
return null;
|
|
1639
1139
|
return `the nightly full check on main has ${open} open failure${open === 1 ? "" : "s"}, so a check made from a re-run of what failed can't deploy; a full check has to pass first`;
|
|
1640
1140
|
}
|
|
1641
|
-
/**
|
|
1642
|
-
* A deploy gate (docs/plans/chat-management.md §0a.5): a scope whose signed terms name a prepared candidate or carry
|
|
1643
|
-
* release terms. Both are in the scope digest and written at filing, before any release authority exists, so this is
|
|
1644
|
-
* read from the scope alone: a first approval and a fallback gate filed without --release are deploy gates too. From
|
|
1645
|
-
* chat it is approved only through the release card.
|
|
1646
|
-
*/
|
|
1647
1141
|
export function deployGateScope(scope) {
|
|
1648
1142
|
return (scope.candidate ?? null) !== null || (scope.releaseTerms ?? null) !== null;
|
|
1649
1143
|
}
|
|
1650
|
-
/**
|
|
1651
|
-
* Whether a scope's check is a release's check (docs/plans/pipeline-speed.md, P0): it carries signed release terms, or a
|
|
1652
|
-
* release check purpose sealed with it. Read from the scope's signed fields only, independent of whether the release can
|
|
1653
|
-
* carry. It makes the check stricter (a complete, valid report; CI never stands in for its units) and, through
|
|
1654
|
-
* check-failure.ts recheckReleaseTask, lets the plane rerun the identical candidate after confirmed infrastructure; it
|
|
1655
|
-
* never carries a later commit or approves anything.
|
|
1656
|
-
*/
|
|
1657
1144
|
export function releaseCheckScope(scope) {
|
|
1658
1145
|
return scope !== null && ((scope.releaseTerms ?? null) !== null || (scope.releaseCheck ?? null) !== null);
|
|
1659
1146
|
}
|
|
1660
|
-
/**
|
|
1661
|
-
* The plane's own automatic approval of a release task (docs/plans/auto-approve-green.md), read the way the dispatch
|
|
1662
|
-
* belts read it (release-authority.ts autoSealSql): sealed `kind` on the current digest, its evidence row naming exactly
|
|
1663
|
-
* this task, kind, digest and candidate, a release task (candidate and terms signed in), the project's setting on now,
|
|
1664
|
-
* and the person who turned it on still an approver there. Never a person's approval.
|
|
1665
|
-
*/
|
|
1666
1147
|
export function autoReleaseApprovalOf(store, taskId, kind) {
|
|
1667
1148
|
const scope = store.getScope(taskId);
|
|
1668
1149
|
const ref = store.lookupRef(taskId);
|
|
@@ -1684,8 +1165,6 @@ export function autoReleaseApprovalOf(store, taskId, kind) {
|
|
|
1684
1165
|
return { ok: false, why: `${scope.approvedBy}, who turned on automatic release approval, can no longer approve in this project` };
|
|
1685
1166
|
return { ok: true, by: scope.approvedBy, at: scope.approvedAt, evidence };
|
|
1686
1167
|
}
|
|
1687
|
-
/** A release's approval: a person's (personApprovalOf, unchanged), or the plane's own `auto-green`. Only release
|
|
1688
|
-
* readers ask this (liveReleaseOf, and the deploy gates inside `toolroll release`); everything else asks for a person. */
|
|
1689
1168
|
export function releaseApprovalOf(store, taskId, _now = new Date()) {
|
|
1690
1169
|
const person = personApprovalOf(store, taskId);
|
|
1691
1170
|
if (person.ok)
|
|
@@ -1695,8 +1174,6 @@ export function releaseApprovalOf(store, taskId, _now = new Date()) {
|
|
|
1695
1174
|
const auto = autoReleaseApprovalOf(store, taskId, "auto-green");
|
|
1696
1175
|
return auto.ok ? { ok: true, by: auto.by, at: auto.at, method: "auto-green" } : auto;
|
|
1697
1176
|
}
|
|
1698
|
-
/** When a password typed at `at` (ISO) stops standing in, for a page's words (ISO); null when `at` isn't a time. Words
|
|
1699
|
-
* only: freshnessFor decides whether it stands in, at the moment of use. */
|
|
1700
1177
|
export function freshUntil(at) {
|
|
1701
1178
|
const ms = Date.parse(at);
|
|
1702
1179
|
return Number.isFinite(ms) ? new Date(ms + FRESH_WINDOW_MS).toISOString() : null;
|
|
@@ -1710,32 +1187,16 @@ const LOCAL_APPROVAL_WORDS = {
|
|
|
1710
1187
|
escalated: "Work with wider permissions needs your password.",
|
|
1711
1188
|
coordinator: "Work a coordinator filed needs your password.",
|
|
1712
1189
|
unsandboxed: "This project's checks run without a sandbox, so approving needs your password.",
|
|
1713
|
-
// Not an approve refusal (approve keeps today's rule); the type needs words for it.
|
|
1714
1190
|
imported: "A task from outside needs your password.",
|
|
1715
1191
|
};
|
|
1716
|
-
/**
|
|
1717
|
-
* Whether the local owner may approve this task without a password (easy-start plan C5). ONE rule, read by the
|
|
1718
|
-
* preview (the task page's approve form and the chat review render no password field when it is ok), the chat
|
|
1719
|
-
* precheck (an empty field passes) and the seal itself (approve(), inside its transaction). Refused: local mode off or
|
|
1720
|
-
* another person; no plan; release or deploy terms; protected or two-person work; an escalated profile; work a
|
|
1721
|
-
* coordinator filed; a project whose checks are stored as unsandboxed (or a plan that sealed that). Plans a lead or
|
|
1722
|
-
* a scout proposed are allowed.
|
|
1723
|
-
*/
|
|
1724
1192
|
export function localApprovalEligible(store, by, taskId) {
|
|
1725
|
-
// The one rule, shared with completing a result (localWorkEligible, below).
|
|
1726
1193
|
return localWorkEligible(store, by, taskId, { act: "approve" });
|
|
1727
1194
|
}
|
|
1728
|
-
// ---- Fallback chains (fallback.ts). Kept last too.
|
|
1729
|
-
/** A chain that may dispatch: version 2, a base and at least one fallback. An older chain is history, never this. */
|
|
1730
1195
|
export function liveChainFromJson(json) {
|
|
1731
1196
|
const chain = chainFromJson(json, LIVE_CHAIN_VERSION);
|
|
1732
1197
|
return chain === null || chain.length < 2 ? null : chain;
|
|
1733
1198
|
}
|
|
1734
|
-
// The chain's four providers by name, here rather than provider-auth.ts: this file sits under the contracts, and that one
|
|
1735
|
-
// loads every adapter.
|
|
1736
1199
|
const CHAIN_AGENT_NAMES = { claude: "Claude", codex: "Codex", gemini: "Gemini", openrouter: "OpenRouter" };
|
|
1737
|
-
/** The chain in full, the words a yes agrees to: order, agent, model, how it bills, what it may do, and whether Toolroll
|
|
1738
|
-
* can see it run out. Every approval surface shows these lines; empty for a scope with no chain. */
|
|
1739
1200
|
export function chainTermsLines(scope) {
|
|
1740
1201
|
const chain = liveChainFromJson(scope.proposedChainJson ?? null);
|
|
1741
1202
|
if (chain === null)
|
|
@@ -1749,8 +1210,6 @@ export function chainTermsLines(scope) {
|
|
|
1749
1210
|
}),
|
|
1750
1211
|
];
|
|
1751
1212
|
}
|
|
1752
|
-
// ---- Local owner, slice 0 (docs/plans/local-owner-acts.md): one work rule for a no-password act. Kept last.
|
|
1753
|
-
/** What a local owner hears when a result isn't one it may accept without a password. */
|
|
1754
1213
|
const LOCAL_COMPLETION_WORDS = {
|
|
1755
1214
|
"local-mode-off": "Local mode is off, so accepting this result needs your password.",
|
|
1756
1215
|
"not-owner": "Only this computer's owner accepts results here without a password.",
|
|
@@ -1760,10 +1219,8 @@ const LOCAL_COMPLETION_WORDS = {
|
|
|
1760
1219
|
escalated: "Work with wider permissions needs your password.",
|
|
1761
1220
|
coordinator: "Work a coordinator filed needs your password to accept.",
|
|
1762
1221
|
unsandboxed: "This project's checks run without a sandbox, so accepting needs your password.",
|
|
1763
|
-
// Not a completion refusal (completion keeps slice 0's rule); the type needs words for it.
|
|
1764
1222
|
imported: "A task from outside needs your password to accept.",
|
|
1765
1223
|
};
|
|
1766
|
-
/** What a local owner hears when a task isn't one it may ask a plan for without a password (local-owner slice 2). */
|
|
1767
1224
|
const LOCAL_PLAN_WORDS = {
|
|
1768
1225
|
"local-mode-off": "Local mode is off, so asking for a plan needs your password.",
|
|
1769
1226
|
"not-owner": "Only this computer's owner asks for plans here without a password.",
|
|
@@ -1775,7 +1232,6 @@ const LOCAL_PLAN_WORDS = {
|
|
|
1775
1232
|
unsandboxed: "This project's checks run without a sandbox, so planning needs your password.",
|
|
1776
1233
|
imported: "A task from outside needs your password to plan.",
|
|
1777
1234
|
};
|
|
1778
|
-
/** What a local owner hears when a build isn't one it may retry without a password (local-owner slice 3). */
|
|
1779
1235
|
const LOCAL_RETRY_WORDS = {
|
|
1780
1236
|
"local-mode-off": "Local mode is off, so retrying needs your password.",
|
|
1781
1237
|
"not-owner": "Only this computer's owner retries builds here without a password.",
|
|
@@ -1787,18 +1243,6 @@ const LOCAL_RETRY_WORDS = {
|
|
|
1787
1243
|
unsandboxed: "This project's checks run without a sandbox, so retrying needs your password.",
|
|
1788
1244
|
imported: "A task from outside needs your password to retry.",
|
|
1789
1245
|
};
|
|
1790
|
-
/**
|
|
1791
|
-
* Whether the local owner may do this act on this task without a password: ONE rule (easy-start C5, split out for
|
|
1792
|
-
* local-owner slice 0), read inside the act's own transaction. Both acts refuse: local mode off or another person;
|
|
1793
|
-
* release or deploy work; protected or two-person work; work a coordinator filed (or a task with no built-in record).
|
|
1794
|
-
* Approving also refuses no plan, an escalated profile and a project stored as unsandboxed (what a build may do, which
|
|
1795
|
-
* is what an approval agrees to). Completing reads release work from the release records too, and protected work from
|
|
1796
|
-
* what the result actually changed as well as what its scope declared (v102's rule: declared paths are only a promise).
|
|
1797
|
-
* Asking for a plan (local-owner slice 2) reads approve's rule for a task that may have no scope yet (no declared paths
|
|
1798
|
-
* count as protected; the task's own permission mode counts as escalated), the release records too, and also refuses a
|
|
1799
|
-
* task from outside (an imported issue): a new act, so no existing act changes. Retrying (slice 3) is approve's rule
|
|
1800
|
-
* exactly (work the owner could approve again now), plus the release records and a task from outside.
|
|
1801
|
-
*/
|
|
1802
1246
|
export function localWorkEligible(store, by, taskId, purpose) {
|
|
1803
1247
|
const words = purpose.act === "approve" ? LOCAL_APPROVAL_WORDS : purpose.act === "complete" ? LOCAL_COMPLETION_WORDS : purpose.act === "plan" ? LOCAL_PLAN_WORDS : LOCAL_RETRY_WORDS;
|
|
1804
1248
|
const no = (reason) => ({ ok: false, reason, message: words[reason] });
|
|
@@ -1815,7 +1259,6 @@ export function localWorkEligible(store, by, taskId, purpose) {
|
|
|
1815
1259
|
if (purpose.act !== "approve" && (belongsToRelease(store, taskId) || releaseAuthorityOfTask(store, taskId) !== null))
|
|
1816
1260
|
return no("release");
|
|
1817
1261
|
const ref = store.handle.prepare("SELECT repo, coordinator_cid, permission_mode FROM task_ref WHERE backend = 'built-in' AND external_id = ?").get(taskId);
|
|
1818
|
-
// Retrying spends again under an existing yes: only on work the owner could approve again now (approve's own rule).
|
|
1819
1262
|
if (purpose.act === "approve" || purpose.act === "retry") {
|
|
1820
1263
|
const gate = store.approvalGate(taskId, by, "person");
|
|
1821
1264
|
if (gate.verdict !== "seal" || gate.protectedWork)
|
|
@@ -1824,8 +1267,6 @@ export function localWorkEligible(store, by, taskId, purpose) {
|
|
|
1824
1267
|
return no("escalated");
|
|
1825
1268
|
}
|
|
1826
1269
|
else if (purpose.act === "plan") {
|
|
1827
|
-
// Approve's rule, read for a task that may have no scope yet: protected or two-person work (no declared paths count
|
|
1828
|
-
// as protected), and an escalated profile or task-level permission mode.
|
|
1829
1270
|
const gate = store.approvalGate(taskId, by, "person");
|
|
1830
1271
|
if (gate.verdict !== "seal" || gate.protectedWork)
|
|
1831
1272
|
return no("protected");
|
|
@@ -1833,7 +1274,6 @@ export function localWorkEligible(store, by, taskId, purpose) {
|
|
|
1833
1274
|
return no("escalated");
|
|
1834
1275
|
}
|
|
1835
1276
|
else if (ref !== undefined && ref["repo"] != null) {
|
|
1836
|
-
// Declared (no declared paths counts as protected) or actually changed (an unreadable diff counts as changed).
|
|
1837
1277
|
const rules = store.approvalRules(String(ref["repo"]));
|
|
1838
1278
|
if ((rules.protectProject || rules.protectedPaths.length > 0)
|
|
1839
1279
|
&& (isProtectedWork(rules, scope?.touches ?? []) || purpose.changed === null || protectedChanges(rules, purpose.changed).length > 0))
|
|
@@ -1841,13 +1281,10 @@ export function localWorkEligible(store, by, taskId, purpose) {
|
|
|
1841
1281
|
}
|
|
1842
1282
|
if (ref === undefined || ref["coordinator_cid"] != null)
|
|
1843
1283
|
return no("coordinator");
|
|
1844
|
-
// What the build may do was agreed at its approval; a result already built is judged by what it is and changed.
|
|
1845
1284
|
if (purpose.act === "complete")
|
|
1846
1285
|
return { ok: true };
|
|
1847
|
-
// Asking for a plan (a new act, so no behaviour changes): never a task from outside (a GitHub import, or a revision of one).
|
|
1848
1286
|
if ((purpose.act === "plan" || purpose.act === "retry") && issueImported(store, taskId))
|
|
1849
1287
|
return no("imported");
|
|
1850
|
-
// The stored level, never the launch cap: a project saved as unsandboxed is refused even though local mode confines it.
|
|
1851
1288
|
const stored = ref["repo"] == null ? undefined : store.handle.prepare("SELECT level FROM project_check_access WHERE repo = ?").get(ref["repo"])?.["level"];
|
|
1852
1289
|
if (stored === "unsandboxed" || scope?.profile?.checkAccess === "unsandboxed")
|
|
1853
1290
|
return no("unsandboxed");
|