@moretea-labs/forge 1.8.0 → 1.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +73 -7
- package/CHANGELOG.md +34 -0
- package/CLAUDE.md +17 -2
- package/CONTRIBUTING.md +3 -2
- package/README.en.md +24 -3
- package/README.md +10 -6
- package/README.zh-CN.md +5 -3
- package/THIRD_PARTY_NOTICES.md +1 -2
- package/adapters/chatgpt/browser-delivery-host.ts +7 -1
- package/adapters/chatgpt/browser-delivery-runtime.ts +531 -56
- package/adapters/chatgpt/controller-binding-store.ts +101 -22
- package/adapters/chatgpt/controller-round-host.ts +15 -25
- package/adapters/chatgpt/controller-round-settlement-store.ts +58 -4
- package/adapters/chatgpt/provider-delivery.ts +229 -2
- package/adapters/chatgpt/work-conversation-binding-store.ts +99 -54
- package/adapters/computer/chatgpt-extension-target.ts +708 -0
- package/adapters/computer/chrome-extension/background.js +541 -0
- package/adapters/computer/chrome-extension/content.js +402 -0
- package/adapters/computer/chrome-extension/core.js +24 -0
- package/adapters/computer/chrome-extension/manifest.json +32 -0
- package/adapters/computer/desktop-operator-discovery.ts +11 -31
- package/adapters/computer/desktop-operator-provider.ts +18 -6
- package/adapters/computer/interaction-target-authority.ts +178 -24
- package/adapters/mcp/access-mode.ts +18 -39
- package/adapters/mcp/auth.ts +2 -7
- package/adapters/mcp/instructions.ts +6 -5
- package/adapters/mcp/multi-repository.ts +10 -47
- package/adapters/mcp/oauth.ts +73 -0
- package/adapters/mcp/paths.ts +4 -1
- package/adapters/mcp/runtime-gateway/bounded-result-runtime.ts +62 -0
- package/adapters/mcp/runtime-gateway/cognition-settlement.ts +201 -0
- package/adapters/mcp/runtime-gateway/context-adapter.ts +490 -113
- package/adapters/mcp/runtime-gateway/context-pack-sidecar.ts +83 -0
- package/adapters/mcp/runtime-gateway/controller-authority-adapter.ts +20 -5
- package/adapters/mcp/runtime-gateway/core-capability-adapter.ts +258 -0
- package/adapters/mcp/runtime-gateway/engineering-preconditions.ts +10 -27
- package/adapters/mcp/runtime-gateway/engineering-tool-contract.ts +15 -0
- package/adapters/mcp/runtime-gateway/execution-tools.ts +14 -54
- package/adapters/mcp/runtime-gateway/gateway-execution-adapter.ts +2 -1
- package/adapters/mcp/runtime-gateway/plugin-adapter.ts +132 -47
- package/adapters/mcp/runtime-gateway/process-tools.ts +173 -23
- package/adapters/mcp/runtime-gateway/protected-computer-adapter.ts +16 -4
- package/adapters/mcp/runtime-gateway/recovery-adapter.ts +69 -52
- package/adapters/mcp/runtime-gateway/repository-compat-adapter.ts +4 -35
- package/adapters/mcp/runtime-gateway/result-adapter.ts +10 -4
- package/adapters/mcp/runtime-gateway/router.ts +19 -507
- package/adapters/mcp/runtime-gateway/routing-policy.ts +506 -0
- package/adapters/mcp/runtime-gateway/runtime-observation-adapter.ts +15 -66
- package/adapters/mcp/runtime-gateway/runtime-readiness-observation.ts +218 -0
- package/adapters/mcp/runtime-gateway/runtime-tool-definitions.ts +123 -178
- package/adapters/mcp/runtime-gateway/runtime-tools.ts +11 -5
- package/adapters/mcp/runtime-gateway/scheduler-adapter.ts +37 -1
- package/adapters/mcp/runtime-gateway/shared-adapter.ts +20 -0
- package/adapters/mcp/runtime-gateway/status-inbox-adapter.ts +416 -270
- package/adapters/mcp/runtime-gateway/typescript-navigation-sidecar.ts +140 -0
- package/adapters/mcp/runtime-gateway/work-adapter.ts +262 -3123
- package/adapters/mcp/runtime-gateway/work-controller-operations.ts +257 -0
- package/adapters/mcp/runtime-gateway/work-detail-projection.ts +60 -0
- package/adapters/mcp/runtime-gateway/work-input-wire-migration.ts +229 -0
- package/adapters/mcp/runtime-gateway/work-learning-operations.ts +145 -0
- package/adapters/mcp/runtime-gateway/work-list-projection.ts +38 -0
- package/adapters/mcp/runtime-gateway/work-plan-operations.ts +382 -0
- package/adapters/mcp/runtime-gateway/work-repair-adapter.ts +308 -0
- package/adapters/mcp/runtime-gateway/work-requirement-operations.ts +148 -0
- package/adapters/mcp/runtime-gateway/work-semantic-operations.ts +320 -0
- package/adapters/mcp/runtime-gateway/work-workflow-operations.ts +113 -0
- package/adapters/mcp/runtime-gateway/workflow-supervisor-adapter.ts +180 -0
- package/adapters/mcp/server.ts +91 -26
- package/adapters/mcp/setup.ts +5 -13
- package/adapters/mcp/tool-mapping/access-tools.ts +0 -6
- package/adapters/mcp/tool-mapping/legacy-tool-service.ts +703 -3092
- package/adapters/mcp/tool-mapping/post-finalize-work-attribution.ts +5 -10
- package/adapters/mcp/tool-mapping/repository-tools.ts +170 -213
- package/adapters/mcp/toolset-names.ts +11 -37
- package/adapters/mcp/toolset.ts +19 -92
- package/{src/cli → adapters}/mcp/transports/AGENTS.md +5 -5
- package/{src/cli → adapters}/mcp/transports/CLAUDE.md +5 -5
- package/adapters/mcp/transports/http-observation.ts +377 -0
- package/adapters/mcp/transports/http-post-lifecycle.ts +19 -0
- package/adapters/mcp/transports/http.ts +200 -683
- package/adapters/mcp/transports/oauth-http.ts +322 -0
- package/adapters/mcp/transports/session-registry.ts +6 -0
- package/adapters/mcp/tunnels/openai-secure-tunnel.ts +89 -5
- package/adapters/mcp/types.ts +0 -6
- package/assets/hooks/lib/session-state.sh +0 -38
- package/assets/hooks/post-bash.sh +1 -1
- package/assets/hooks/post-tool-observer.sh +0 -5
- package/assets/hooks/prompt-guard.sh +0 -55
- package/assets/partials/04-project-structure.partial.md +1 -1
- package/assets/partials/07-footer.partial.md +1 -1
- package/assets/partials-agents/02-operating-mode.partial.md +1 -1
- package/assets/partials-agents/08-deep-docs.partial.md +1 -1
- package/assets/plugin-registry.v1.json +6 -4
- package/assets/reference-configs/agentic-development-flow.md +26 -1
- package/assets/reference-configs/external-tooling.md +0 -76
- package/assets/reference-configs/global-working-rules.md +19 -0
- package/assets/reference-configs/release-deploy.md +1 -1
- package/assets/templates/helpers/architecture-queue.sh +1 -1
- package/assets/templates/helpers/check-agent-tooling.sh +1 -327
- package/assets/templates/helpers/check-task-workflow.sh +1 -1
- package/assets/templates/helpers/ensure-task-workflow.sh +0 -14
- package/assets/templates/helpers/migrate-project-template.sh +2 -2
- package/assets/workflow-contract.v1.json +0 -2
- package/docs/README.md +5 -2
- package/docs/architecture/CURRENT.md +205 -51
- package/docs/architecture/decisions/20260803-release-identity-binding-and-exit-policy.md +14 -5
- package/docs/architecture/decisions/20260823-immediate-controller-relay.md +6 -3
- package/docs/architecture/decisions/20260904-ios-device-migration-baseline.md +42 -0
- package/docs/architecture/decisions/20260907-assistant-learning-loop.md +2 -0
- package/docs/architecture/decisions/20260907-controller-round-transition-policy.md +19 -4
- package/docs/architecture/decisions/20260916-workflow-supervisor-authority.md +249 -0
- package/docs/architecture/decisions/20260917-cognitive-memory-foundation.md +82 -0
- package/docs/architecture/decisions/20260918-stable-candidate-release-lifecycle.md +234 -0
- package/docs/architecture/decisions/20260919-autonomous-work-liveness.md +62 -0
- package/docs/architecture/decisions/20260924-thin-semantic-working-context.md +74 -0
- package/docs/architecture/decisions/20261001-supervisor-turn-authority.md +342 -0
- package/docs/architecture/decisions/20261005-forge-v3-desktop-client-boundary.md +77 -0
- package/docs/architecture/decisions/20261009-exact-code-context-discovery.md +19 -0
- package/docs/architecture/decisions/20261009-generated-xcode-cache-retention.md +37 -0
- package/docs/architecture/decisions/20261011-autonomous-continuation-convergence.md +597 -0
- package/docs/architecture/decisions/20261017-edit-session-finalization-reconciliation.md +17 -0
- package/docs/architecture/decisions/20261019-retire-host-skills.md +16 -0
- package/docs/architecture/diagrams/agentic-dev-plugin-architecture.html +1 -1
- package/docs/architecture/domains/public-surface.md +3 -5
- package/docs/architecture/domains/verification.md +6 -5
- package/docs/architecture/domains/workflow-engine.md +6 -0
- package/docs/architecture/modules/controller-runtime/transport-lifecycle.md +3 -3
- package/docs/architecture/requests/2026-09-04-computer-plugin-workflow-taxonomy.md +4 -4
- package/docs/architecture/reviews/20261015-code-search-runtime-acceptance.md +75 -0
- package/docs/forge-plugin-management.md +16 -4
- package/docs/operations/controller-browser-plugin.md +23 -0
- package/docs/operations/controller-performance-and-502.md +17 -0
- package/docs/operations/controller-reliability-runbook.md +2 -2
- package/docs/operations/features.md +6 -7
- package/docs/operations/features.zh-CN.md +1 -1
- package/docs/operations/github-repository.md +4 -4
- package/docs/operations/github-semantic-release-projection.md +20 -0
- package/docs/operations/homebrew.md +2 -2
- package/docs/operations/mcp-tool-exposure.md +13 -52
- package/docs/operations/releasing.md +2 -0
- package/docs/operations/runtime-performance-diagnostics.md +8 -0
- package/docs/operations/standalone-disaster-recovery.md +15 -7
- package/docs/tutorials/01-install-and-start.zh-CN.md +1 -1
- package/docs/tutorials/03-first-repository-task.md +2 -0
- package/docs/wiki/Computer-and-Plugins.md +78 -0
- package/docs/wiki/Computer-and-Plugins.zh-CN.md +88 -0
- package/docs/wiki/Home.md +16 -2
- package/docs/wiki/Implementation.md +25 -13
- package/docs/wiki/Installation.md +28 -32
- package/docs/wiki/Integrations.md +4 -0
- package/docs/wiki/Quick-Start.md +35 -22
- package/docs/wiki/Releases-and-Upgrades.md +15 -25
- package/docs/wiki/_Sidebar.md +5 -1
- package/package.json +25 -25
- package/packages/kernel/cognition/api/index.ts +6 -0
- package/packages/kernel/cognition/application/activation-service.ts +451 -0
- package/packages/kernel/cognition/application/consolidation-service.ts +185 -0
- package/packages/kernel/cognition/application/legacy-experience-adapter.ts +38 -0
- package/packages/kernel/cognition/application/memory-service.ts +64 -0
- package/packages/kernel/cognition/domain/learning.ts +106 -0
- package/packages/kernel/cognition/domain/memory.ts +254 -0
- package/packages/kernel/controller/api/index.ts +1 -0
- package/packages/kernel/controller/application/continuation-service.ts +281 -0
- package/packages/kernel/controller/application/controller-round-service.ts +12 -0
- package/packages/kernel/controller/domain/controller-round-transition-policy.ts +242 -21
- package/packages/kernel/controller/domain/controller-round.ts +4 -1
- package/packages/kernel/controller/domain/execution-quality.ts +3 -1
- package/packages/kernel/controller/infrastructure/controller-round-store.ts +689 -103
- package/packages/kernel/controller/infrastructure/controller-session-store.ts +348 -97
- package/packages/kernel/controller/ports/controller-host.ts +2 -0
- package/packages/kernel/identity/api/index.ts +10 -0
- package/packages/kernel/identity/domain/activity-projection.ts +43 -0
- package/packages/kernel/identity/domain/capability-broker.ts +60 -0
- package/packages/kernel/identity/domain/grant.ts +72 -0
- package/packages/kernel/identity/domain/owned-resource.ts +116 -0
- package/packages/kernel/identity/domain/user-request.ts +93 -0
- package/packages/kernel/identity/infrastructure/activity-projection-store.ts +87 -0
- package/packages/kernel/identity/infrastructure/capability-broker.ts +81 -0
- package/packages/kernel/identity/infrastructure/grant-store.ts +284 -0
- package/packages/kernel/identity/infrastructure/owned-resource-store.ts +259 -0
- package/packages/kernel/identity/infrastructure/user-request-store.ts +182 -0
- package/packages/kernel/scheduler/api/index.ts +0 -2
- package/packages/kernel/scheduler/application/eligibility.ts +4 -1
- package/packages/kernel/scheduler/application/schedule-service.ts +3 -0
- package/packages/kernel/scheduler/application/settlement.ts +0 -15
- package/packages/kernel/scheduler/domain/schedule.ts +87 -0
- package/packages/kernel/scheduler/infrastructure/schedule-store.ts +166 -143
- package/packages/kernel/work/api/index.ts +3 -2
- package/packages/kernel/work/application/work-service.ts +18 -42
- package/packages/kernel/work/domain/current-task-lineage.ts +104 -0
- package/packages/kernel/work/domain/engineering-design.ts +10 -5
- package/packages/kernel/work/domain/engineering-profile.ts +8 -12
- package/packages/kernel/work/domain/evaluation-promotion-receipt.ts +186 -0
- package/packages/kernel/work/domain/execution-concurrency.ts +19 -26
- package/packages/kernel/work/domain/execution-snapshot.ts +0 -31
- package/packages/kernel/work/domain/implementation-review.ts +14 -331
- package/packages/kernel/work/domain/objective-graph.ts +119 -0
- package/packages/kernel/work/domain/project-engineering-contract.ts +23 -1
- package/packages/kernel/work/domain/repository-completion-receipt.ts +1 -1
- package/packages/kernel/work/domain/state-machine.ts +34 -65
- package/packages/kernel/work/domain/types.ts +57 -51
- package/packages/kernel/work/infrastructure/work-contract-store.ts +847 -729
- package/packages/kernel/work/ports/work-contract-store.ts +5 -2
- package/packages/plugin-runtime/browser/provider-registry.ts +12 -36
- package/packages/plugin-runtime/browser/session-authority.ts +2 -1
- package/packages/plugin-runtime/computer/chatgpt-identity.ts +24 -0
- package/packages/plugin-runtime/computer/conversation-target.ts +153 -0
- package/packages/plugin-runtime/computer/index.ts +2 -0
- package/packages/plugin-runtime/computer/target-authority.ts +26 -1
- package/packages/plugin-runtime/external/unix-jsonl-transport.ts +142 -18
- package/packages/protocols/computer/contract.ts +27 -1
- package/scripts/activate-source-baseline.ts +7 -9
- package/scripts/assemble-template.ts +11 -72
- package/scripts/canary-controller-semantic-wait.ts +12 -24
- package/scripts/check-mcp-compatibility.ts +94 -201
- package/scripts/check-package-identity.mjs +0 -5
- package/scripts/check-runtime-architecture.mjs +921 -239
- package/scripts/forge-local-recovery-helper.mjs +93 -15
- package/scripts/init-project.sh +0 -46
- package/scripts/install-ios-hid-toolchain.sh +60 -0
- package/scripts/install-standalone-recovery.ts +1 -1
- package/scripts/lib/project-init-lib.sh +6 -3
- package/scripts/migrate-windows-wsl-controller-home.ts +2 -0
- package/scripts/open-source-audit-allowlist.txt +1 -3
- package/scripts/run-bounded-command.mjs +5 -0
- package/scripts/run-governed-gate.ts +2 -1
- package/scripts/run-mobile-monitor-bridge.ts +0 -1
- package/scripts/smoke-control-plane-failure-domain.ts +94 -0
- package/scripts/smoke-ios-physical-device.ts +38 -10
- package/scripts/smoke-mcp-http-runtime.ts +12 -8
- package/scripts/smoke-mcp-tool-surface.ts +27 -41
- package/scripts/smoke-runtime-recovery.ts +12 -43
- package/scripts/smoke-schedule-engine.ts +23 -15
- package/scripts/smoke-unattended-transport-recovery.ts +223 -0
- package/scripts/smoke-user-request-continuation-restart.ts +232 -0
- package/scripts/smoke-workflow-supervisor-chrome-adapter.ts +95 -0
- package/scripts/smoke-workflow-supervisor-process-restart.ts +276 -0
- package/scripts/smoke-workflow-supervisor-restart-recovery.ts +150 -0
- package/scripts/smoke-workflow-supervisor.ts +103 -0
- package/scripts/sync-generated-authority.mjs +0 -1
- package/scripts/verify-forge-runtime.sh +2 -1
- package/src/cli/agent-jobs/executor-health.ts +12 -35
- package/src/cli/agent-jobs/integration.ts +20 -51
- package/src/cli/agent-jobs/job-manager.ts +7 -3
- package/src/cli/chatgpt-browser/file-policy.ts +2 -2
- package/src/cli/commands/brain-assistant.ts +27 -13
- package/src/cli/commands/brain.ts +13 -15
- package/src/cli/commands/chatgpt.ts +1 -163
- package/src/cli/commands/doctor.ts +1 -143
- package/src/cli/commands/global-runtime.ts +3 -196
- package/src/cli/commands/init-hook.ts +6 -23
- package/src/cli/commands/init.ts +3 -252
- package/src/cli/commands/mcp.ts +0 -5
- package/src/cli/commands/prompt-guard-decision.ts +0 -2
- package/src/cli/commands/recovery.ts +137 -135
- package/src/cli/commands/repository.ts +17 -1
- package/src/cli/commands/runtime.ts +3 -3
- package/src/cli/commands/setup-execution.ts +41 -0
- package/src/cli/commands/setup-profile.ts +8 -0
- package/src/cli/controller/check-runner.ts +13 -2
- package/src/cli/controller/completion-backlog.ts +3 -3
- package/src/cli/controller/completion-orchestrator.ts +5 -44
- package/src/cli/controller/completion-target.ts +3 -72
- package/src/cli/controller/composite-operations.ts +1 -1
- package/src/cli/controller/context/instruction-context.ts +1 -1
- package/src/cli/controller/context/known-paths.ts +2 -2
- package/src/cli/controller/context/query-planning.ts +11 -4
- package/src/cli/controller/context/rule-resolution.ts +2 -2
- package/src/cli/controller/context/source-materializer.ts +83 -102
- package/src/cli/controller/context/structural-provider.ts +84 -0
- package/src/cli/controller/context/structural.ts +6 -6
- package/src/cli/controller/context/types.ts +8 -9
- package/src/cli/controller/context-pack.ts +107 -84
- package/src/cli/controller/execution-completion.ts +4 -7
- package/src/cli/controller/execution-policy.ts +36 -153
- package/src/cli/controller/governance.ts +2 -3
- package/src/cli/controller/issue-store.ts +4 -99
- package/src/cli/controller/launch-agents.ts +59 -18
- package/src/cli/controller/operational-plan.ts +25 -52
- package/src/cli/controller/runtime-config.ts +5 -1
- package/src/cli/controller/stuck-state-migration.ts +2 -3
- package/src/cli/controller/systemd-user.ts +42 -10
- package/src/cli/editing/edit-session.ts +18 -12
- package/src/cli/github/github.ts +4 -4
- package/src/cli/github/semantic-projection.ts +174 -0
- package/src/cli/hook/prompt-intents.ts +0 -9
- package/src/cli/index.ts +1 -43
- package/src/cli/local-bridge/connector-freshness.ts +1 -12
- package/src/cli/local-bridge/console-automations.ts +19 -14
- package/src/cli/local-bridge/console-view-models.ts +4 -13
- package/src/cli/local-bridge/facade-api.ts +64 -193
- package/src/cli/local-bridge/server.ts +24 -147
- package/src/cli/local-bridge/types.ts +0 -1
- package/src/cli/mcp/oauth-client-retirement.ts +74 -0
- package/src/cli/repositories/command-classifier.ts +0 -9
- package/src/cli/repositories/command-executor.ts +29 -23
- package/src/cli/repositories/command-scope.ts +37 -18
- package/src/cli/repositories/controller-home.ts +48 -0
- package/src/cli/repositories/ephemeral-workspace.ts +20 -30
- package/src/cli/repositories/git-command-executor.ts +2 -2
- package/src/cli/repositories/locks.ts +20 -0
- package/src/cli/repositories/registry.ts +79 -12
- package/src/cli/repositories/safe-patch.ts +2 -12
- package/src/cli/repositories/structured-git.ts +101 -5
- package/src/cli/repository/inspector.ts +185 -343
- package/src/cli/repository/session-cache.ts +92 -6
- package/src/effects/process-runner.ts +17 -1
- package/src/runtime/context/assistant-context.ts +20 -7
- package/src/runtime/context/assistant-work-context.ts +89 -27
- package/src/runtime/context/automatic-learning.ts +565 -0
- package/src/runtime/context/cognitive-attention.ts +173 -0
- package/src/runtime/context/cognitive-skill-canary.ts +158 -0
- package/src/runtime/context/context-closure.ts +46 -9
- package/src/runtime/context/context-pack-process.ts +103 -0
- package/src/runtime/context/context-plane.ts +1 -9
- package/src/runtime/context/direct-controller-learning.ts +298 -0
- package/src/runtime/context/generic-lsp-provider.ts +1 -1
- package/src/runtime/context/semantic-navigation-contract.ts +16 -0
- package/src/runtime/context/semantic-navigation.ts +7 -35
- package/src/runtime/context/typescript-navigation-process.ts +145 -0
- package/src/runtime/context/typescript-navigation.ts +89 -3
- package/src/runtime/control-plane/cleanup-artifact-retention.ts +215 -12
- package/src/runtime/control-plane/concurrency/work-execution-concurrency.ts +9 -47
- package/src/runtime/control-plane/execution/controller-authority-recovery.ts +34 -4
- package/src/runtime/control-plane/execution/edit-validation-coordinator.ts +29 -20
- package/src/runtime/control-plane/execution/execution-identity.ts +23 -3
- package/src/runtime/control-plane/execution/repository-work-attribution.ts +7 -30
- package/src/runtime/control-plane/execution/retained-work-resume.ts +206 -199
- package/src/runtime/control-plane/execution/session-store.ts +31 -1
- package/src/runtime/control-plane/execution/validation.ts +6 -8
- package/src/runtime/control-plane/execution/work-authority-reconciler.ts +13 -42
- package/src/runtime/control-plane/execution/work-check-evidence.ts +137 -0
- package/src/runtime/control-plane/execution/work-completion-authority.ts +30 -85
- package/src/runtime/control-plane/execution/work-delivery-service.ts +616 -0
- package/src/runtime/control-plane/execution/work-evidence-policy.ts +12 -50
- package/src/runtime/control-plane/execution/work-execution-support.ts +50 -149
- package/src/runtime/control-plane/execution/work-handle-authority.ts +197 -110
- package/src/runtime/control-plane/execution/work-handle-store.ts +72 -44
- package/src/runtime/control-plane/execution/work-head-settlement.ts +53 -20
- package/src/runtime/control-plane/execution/work-lifecycle-audit.ts +52 -29
- package/src/runtime/control-plane/execution/work-operation-service.ts +60 -34
- package/src/runtime/control-plane/execution/work-preparation-service.ts +231 -267
- package/src/runtime/control-plane/execution/work-process-evidence.ts +2 -2
- package/src/runtime/control-plane/execution/work-remote-delivery.ts +2 -3
- package/src/runtime/control-plane/execution/work-revision-diff.ts +39 -0
- package/src/runtime/control-plane/execution/work-terminal-cleanup.ts +201 -199
- package/src/runtime/control-plane/execution/work-validation-reconciler.ts +33 -85
- package/src/runtime/control-plane/execution/work-verification-service.ts +406 -50
- package/src/runtime/control-plane/execution/work-verification-snapshot.ts +6 -2
- package/src/runtime/control-plane/facade/capability-registry.ts +364 -37
- package/src/runtime/control-plane/facade/check-normalization.ts +3 -9
- package/src/runtime/control-plane/facade/codex-delegation.ts +10 -11
- package/src/runtime/control-plane/facade/controller-connection.ts +135 -0
- package/src/runtime/control-plane/facade/goal-workloop-access.ts +1 -20
- package/src/runtime/control-plane/facade/goal-workloop.ts +281 -1753
- package/src/runtime/control-plane/facade/handoff-inbox-application.ts +12 -25
- package/src/runtime/control-plane/facade/handoff-inbox-store.ts +256 -52
- package/src/runtime/control-plane/facade/index.ts +0 -1
- package/src/runtime/control-plane/facade/operation-digest.ts +12 -15
- package/src/runtime/control-plane/facade/plan-contract-store.ts +451 -991
- package/src/runtime/control-plane/facade/policy-gate.ts +0 -23
- package/src/runtime/control-plane/facade/repository-work-admission.ts +12 -22
- package/src/runtime/control-plane/facade/requirement-authority.ts +102 -199
- package/src/runtime/control-plane/facade/requirement-board.ts +3 -3
- package/src/runtime/control-plane/facade/rh-work-operation-contract.ts +51 -14
- package/src/runtime/control-plane/facade/self-healing-loop.ts +18 -53
- package/src/runtime/control-plane/facade/suggested-actions.ts +15 -18
- package/src/runtime/control-plane/facade/types.ts +49 -108
- package/src/runtime/control-plane/facade/work-continuation.ts +9 -9
- package/src/runtime/control-plane/generated-cache-retention.ts +206 -59
- package/src/runtime/control-plane/global-scheduler/autonomous-continuation.ts +248 -0
- package/src/runtime/control-plane/global-scheduler/durable-admission.ts +1 -1
- package/src/runtime/control-plane/global-scheduler/maintenance.ts +256 -117
- package/src/runtime/control-plane/global-scheduler/reconciliation.ts +3 -12
- package/src/runtime/control-plane/global-scheduler/scheduler.ts +66 -40
- package/src/runtime/control-plane/global-scheduler/wake-signal.ts +42 -2
- package/src/runtime/control-plane/governance/access-policy.ts +19 -2
- package/src/runtime/control-plane/governance/authorization.ts +20 -3
- package/src/runtime/control-plane/governance/external-effects.ts +1 -1
- package/src/runtime/control-plane/launcher/chatgpt-round-continuation.ts +63 -300
- package/src/runtime/control-plane/launcher/chatgpt-work-continuation.ts +29 -300
- package/src/runtime/control-plane/launcher/local-conversation-controller.ts +238 -0
- package/src/runtime/control-plane/launcher/provider-mcp-bootstrap.ts +5 -2
- package/src/runtime/control-plane/launcher/thin-launcher.ts +96 -240
- package/src/runtime/control-plane/persistence/cognition-store.ts +820 -0
- package/src/runtime/control-plane/persistence/experience-store.ts +162 -29
- package/src/runtime/control-plane/persistence/requirement-store.ts +216 -74
- package/src/runtime/control-plane/persistence/sqlite-store.ts +113 -6
- package/src/runtime/control-plane/release-retention.ts +135 -47
- package/src/runtime/control-plane/repository-namespace-retention.ts +2 -2
- package/src/runtime/control-plane/runtime-cleanup.ts +295 -107
- package/src/runtime/control-plane/workspace/project-onboarding.ts +80 -0
- package/src/runtime/control-plane/workspace/semantic-sync-service.ts +19 -5
- package/src/runtime/control-plane/workspace/workspace-store.ts +169 -0
- package/src/runtime/diagnostics/incident-repair.ts +313 -146
- package/src/runtime/diagnostics/mcp-timing.ts +114 -0
- package/src/runtime/evidence/artifact-store.ts +158 -40
- package/src/runtime/evidence/evidence-store.ts +112 -8
- package/src/runtime/evidence/output-handle-index.ts +225 -0
- package/src/runtime/evidence/result-store.ts +158 -44
- package/src/runtime/evidence/sensitive-output.ts +22 -2
- package/src/runtime/execution/jobs/child-reference.ts +11 -0
- package/src/runtime/execution/jobs/receipt-recovery.ts +1 -11
- package/src/runtime/execution/jobs/store.ts +3 -4
- package/src/runtime/execution/managed-workspace.ts +57 -0
- package/src/runtime/execution/process-runtime/check-facade.ts +1 -1
- package/src/runtime/execution/process-runtime/check-result-retention.ts +2 -2
- package/src/runtime/execution/process-runtime/check-result.ts +105 -1
- package/src/runtime/execution/process-runtime/check-runner-sidecar.ts +18 -8
- package/src/runtime/execution/process-runtime/command-facade.ts +82 -30
- package/src/runtime/execution/process-runtime/gc.ts +15 -2
- package/src/runtime/execution/process-runtime/handle-index.ts +176 -0
- package/src/runtime/execution/process-runtime/host-command-lane.ts +139 -0
- package/src/runtime/execution/process-runtime/index.ts +3 -0
- package/src/runtime/execution/process-runtime/lightweight-managed.ts +251 -72
- package/src/runtime/execution/process-runtime/persisted-check.ts +3 -3
- package/src/runtime/execution/process-runtime/process-runner-entry.ts +47 -5
- package/src/runtime/execution/process-runtime/process-scope.ts +160 -0
- package/src/runtime/execution/process-runtime/resource-claims.ts +65 -61
- package/src/runtime/execution/process-runtime/runtime.ts +55 -18
- package/src/runtime/execution/process-runtime/store.ts +30 -2
- package/src/runtime/execution/process-runtime/types.ts +6 -1
- package/src/runtime/execution/thin-harness/execution-router.ts +16 -16
- package/src/runtime/execution/thin-harness/fast-executor.ts +2 -2
- package/src/runtime/execution/thin-harness/search-worker.ts +2 -2
- package/src/runtime/execution/workers/executor.ts +3 -8
- package/src/runtime/maintenance/cleanup.ts +41 -5
- package/src/runtime/platform/service-inventory.ts +130 -0
- package/src/runtime/platform/service-manager.ts +8 -0
- package/src/runtime/plugins/action-application.ts +97 -29
- package/src/runtime/plugins/app-store-connect-adapter.ts +290 -18
- package/src/runtime/plugins/browser-adapter.ts +1124 -333
- package/src/runtime/plugins/browser-automation-service.ts +23 -3
- package/src/runtime/plugins/browser-macos-bridge.ts +431 -137
- package/src/runtime/plugins/browser-manifest-surface.ts +47 -12
- package/src/runtime/plugins/browser-native-session-service.ts +63 -13
- package/src/runtime/plugins/browser-registration.ts +18 -0
- package/src/runtime/plugins/browser-runtime.ts +40 -36
- package/src/runtime/plugins/browser-session-authority.ts +2 -2
- package/src/runtime/plugins/browser-session-store.ts +46 -76
- package/src/runtime/plugins/capability-authorization-grants.ts +258 -62
- package/src/runtime/plugins/computer-chatgpt-browser-adapter-installer.ts +228 -0
- package/src/runtime/plugins/computer-registration.ts +298 -20
- package/src/runtime/plugins/desktop-operator-external-policy.ts +36 -4
- package/src/runtime/plugins/desktop-operator-registration.ts +12 -4
- package/src/runtime/plugins/external-adapter.ts +42 -6
- package/src/runtime/plugins/external-registration.ts +21 -1
- package/src/runtime/plugins/github-adapter.ts +30 -3
- package/src/runtime/plugins/gmail-adapter.ts +189 -3
- package/src/runtime/plugins/google-calendar-adapter.ts +2 -2
- package/src/runtime/plugins/google-shared.ts +24 -12
- package/src/runtime/plugins/google-tasks-adapter.ts +2 -2
- package/src/runtime/plugins/ios/remote-xpc-hid.ts +70 -30
- package/src/runtime/plugins/ios-adapter.ts +46 -41
- package/src/runtime/plugins/ios-agent-device.ts +54 -4
- package/src/runtime/plugins/ios-device-ownership.ts +103 -0
- package/src/runtime/plugins/ios-physical-device.ts +497 -79
- package/src/runtime/plugins/lightweight-action.ts +208 -2
- package/src/runtime/plugins/local-system-adapter.ts +12 -100
- package/src/runtime/plugins/managed-process-adapter.ts +12 -5
- package/src/runtime/plugins/plugin-action-sidecar.ts +17 -13
- package/src/runtime/plugins/plugin-management-adapter.ts +1 -1
- package/src/runtime/plugins/store.ts +682 -435
- package/src/runtime/plugins/types.ts +24 -0
- package/src/runtime/plugins/xiaohongshu-publish.ts +16 -0
- package/src/runtime/projections/git-status-sampler.ts +2 -19
- package/src/runtime/projections/invalidation.ts +7 -3
- package/src/runtime/projections/materialized-view.ts +80 -36
- package/src/runtime/recovery/actions.ts +4 -4
- package/src/runtime/recovery/capability-action-application.ts +46 -45
- package/src/runtime/recovery/lifecycle-inventory.ts +30 -40
- package/src/runtime/recovery/maintenance-executor.ts +374 -123
- package/src/runtime/recovery/probe.ts +2 -2
- package/src/runtime/recovery/store.ts +29 -11
- package/src/runtime/release/release-coordinator.ts +312 -0
- package/src/runtime/release/release-session.ts +716 -0
- package/src/runtime/release/release-state-migration.ts +25 -0
- package/src/runtime/resources/leases/store.ts +56 -25
- package/src/runtime/root/computer-composition.ts +191 -6
- package/src/runtime/root/controller-progression-composition.ts +254 -0
- package/src/runtime/root/controller-round-composition.ts +20 -1
- package/src/runtime/root/deployment-topology.ts +106 -0
- package/src/runtime/root/entry.ts +4 -3
- package/src/runtime/root/known-good-recovery.ts +184 -0
- package/src/runtime/root/local-bridge.ts +0 -1
- package/src/runtime/root/mcp-transport.ts +111 -18
- package/src/runtime/root/ownership.ts +261 -9
- package/src/runtime/root/package-connector-service.ts +227 -29
- package/src/runtime/root/package-runtime-release.ts +117 -30
- package/src/runtime/root/package-runtime-service.ts +24 -24
- package/src/runtime/root/release-execution-canary.ts +57 -12
- package/src/runtime/root/release-loader.ts +90 -8
- package/src/runtime/root/release-manifest.ts +80 -40
- package/src/runtime/root/release-materialize.ts +372 -106
- package/src/runtime/root/release-store.ts +395 -36
- package/src/runtime/root/runtime-lane.ts +191 -0
- package/src/runtime/root/runtime.ts +160 -29
- package/src/runtime/root/scheduled-controller-composition.ts +29 -3
- package/src/runtime/root/service-runner.ts +2 -2
- package/src/runtime/root/service.ts +126 -44
- package/src/runtime/root/status.ts +48 -0
- package/src/runtime/root/types.ts +32 -9
- package/src/runtime/root/workflow-supervisor-composition.ts +681 -0
- package/src/runtime/root/workflow-supervisor-runtime.ts +564 -0
- package/src/runtime/root/write-fence.ts +50 -2
- package/src/runtime/safe-tooling/google-credential-store.ts +67 -22
- package/src/runtime/safe-tooling/google-oauth-broker.ts +25 -7
- package/src/runtime/safe-tooling/ios-development.ts +22 -8
- package/src/runtime/safe-tooling/job-summary.ts +1 -1
- package/src/runtime/safe-tooling/workspace-auth.ts +5 -2
- package/src/runtime/shared/atomic-text-file.ts +21 -0
- package/src/runtime/shared/bounded-child-supervisor.ts +9 -1
- package/src/runtime/shared/json-files.ts +8 -3
- package/src/runtime/shared/process-environment.ts +20 -9
- package/src/runtime/shared/response-budget.ts +1 -3
- package/src/runtime/standalone-recovery/controller-home-migration.ts +16 -24
- package/src/runtime/standalone-recovery/core.ts +3792 -417
- package/src/runtime/standalone-recovery/entry.ts +507 -45
- package/src/runtime/standalone-recovery/installer.ts +262 -148
- package/src/runtime/standalone-recovery/mcp-server.ts +29 -193
- package/src/runtime/standalone-recovery/operation-lock.ts +12 -2
- package/src/runtime/standalone-recovery/performance.ts +54 -16
- package/src/runtime/standalone-recovery/release.ts +53 -5
- package/src/runtime/standalone-recovery/service-labels.ts +5 -2
- package/src/runtime/standalone-recovery/watchdog-heartbeat.ts +5 -2
- package/src/runtime/workflow/schedules/browser-probe.ts +17 -6
- package/src/runtime/workflow/schedules/chatgpt-automation-migration.ts +11 -3
- package/src/runtime/workflow/schedules/engine.ts +166 -178
- package/src/runtime/workflow/schedules/pending-activation.ts +11 -4
- package/src/runtime/workflow/schedules/work-continuation.ts +95 -11
- package/src/runtime/workflows/runtime.ts +15 -19
- package/src/testing/test-governance.ts +5 -1
- package/supervisor/chatgpt-conversation.ts +23 -0
- package/supervisor/client.ts +218 -0
- package/supervisor/control-plane.ts +963 -0
- package/supervisor/entry.ts +15 -0
- package/supervisor/forge-validators.ts +147 -0
- package/supervisor/index.ts +5 -0
- package/supervisor/native-browser-adapter.ts +1151 -0
- package/supervisor/native-messaging/host.ts +58 -0
- package/supervisor/native-messaging/manifest.ts +26 -0
- package/supervisor/native-messaging/protocol.ts +27 -0
- package/supervisor/paths.ts +18 -0
- package/supervisor/protocol.ts +250 -0
- package/supervisor/server.ts +412 -0
- package/supervisor/store.ts +1870 -0
- package/supervisor/tsconfig.json +8 -0
- package/supervisor/types.ts +261 -0
- package/SKILL.md +0 -427
- package/adapters/chatgpt/controller-host.ts +0 -119
- package/adapters/mcp/controller-round-compatibility.ts +0 -184
- package/adapters/mcp/frozen-client-semantic-compatibility.ts +0 -292
- package/adapters/mcp/runtime-gateway/work-compat-adapter.ts +0 -502
- package/adapters/mcp/runtime-gateway/work-validation-reconciler.ts +0 -1
- package/adapters/mcp/toolset-selection.ts +0 -41
- package/agents/openai.yaml +0 -4
- package/assets/skill-hooks.json +0 -41
- package/assets/skill-version.json +0 -189
- package/assets/skills/claude-review/SKILL.md +0 -231
- package/assets/skills/codex-review/SKILL.md +0 -103
- package/assets/templates/helpers/check-skill-version.ts +0 -193
- package/packages/kernel/progression/api/index.ts +0 -2
- package/packages/kernel/progression/application/projector.ts +0 -211
- package/packages/kernel/progression/domain/types.ts +0 -116
- package/packages/kernel/progression/index.ts +0 -1
- package/packages/kernel/scheduler/application/continuation-service.ts +0 -212
- package/packages/kernel/scheduler/domain/continuation.ts +0 -38
- package/packages/kernel/scheduler/infrastructure/continuation-dispatch-store.ts +0 -38
- package/packages/kernel/work/domain/admission-policy.ts +0 -34
- package/scripts/benchmark-background-check-overlap.ts +0 -228
- package/scripts/benchmark-computer-hotpath.ts +0 -255
- package/scripts/benchmark-controller-hotpath.ts +0 -212
- package/scripts/benchmark-controller-round2.ts +0 -191
- package/scripts/benchmark-ios-agent-device.ts +0 -511
- package/scripts/benchmark-mcp-host.sh +0 -117
- package/scripts/benchmark-mcp-transport.ts +0 -169
- package/scripts/benchmark-operational-memory-activation.ts +0 -235
- package/scripts/benchmark-operational-shadow.ts +0 -28
- package/scripts/benchmark-quality-harness.ts +0 -146
- package/scripts/benchmark-route-session-concurrency.ts +0 -915
- package/scripts/benchmark-thin-harness-gateway-ab.ts +0 -632
- package/scripts/benchmark-thin-harness-mcp-e2e.ts +0 -498
- package/scripts/benchmark-thin-harness.ts +0 -251
- package/scripts/benchmark-typescript-navigation.ts +0 -186
- package/scripts/benchmark-work-efficiency.ts +0 -334
- package/scripts/build-controller-ui.ts +0 -28
- package/scripts/check-npm-release.sh +0 -32
- package/scripts/check-public-release-surface.sh +0 -19
- package/scripts/check-release-published.sh +0 -57
- package/scripts/check-release-readiness.sh +0 -37
- package/scripts/check-release-version.mjs +0 -74
- package/scripts/check-skill-version.ts +0 -5
- package/scripts/check-tarball-install-smoke.sh +0 -150
- package/scripts/ensure-codegraph.sh +0 -16
- package/scripts/package-source-archive.sh +0 -147
- package/scripts/public-release-files.txt +0 -39
- package/scripts/public-release.ts +0 -174
- package/scripts/publish-release-tarball.sh +0 -27
- package/scripts/route-nl-vs-ts-eval.ts +0 -679
- package/scripts/run-skill-hook.ts +0 -244
- package/scripts/stage-runtime-release.ts +0 -44
- package/scripts/sync-codex-installed-copies.sh +0 -182
- package/src/cli/commands/tools.ts +0 -167
- package/src/cli/controller/progress.ts +0 -656
- package/src/cli/controller/work-mode.ts +0 -181
- package/src/cli/local-bridge/console-assets.ts +0 -17
- package/src/cli/local-bridge/dashboard.ts +0 -17
- package/src/cli/local-bridge/frontend/src/App.tsx +0 -10
- package/src/cli/local-bridge/frontend/src/components/Button.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/components/DetailPane.tsx +0 -3
- package/src/cli/local-bridge/frontend/src/components/SearchField.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/components/SectionHeader.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/components/Segmented.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/components/StatusText.tsx +0 -3
- package/src/cli/local-bridge/frontend/src/design/icons.tsx +0 -11
- package/src/cli/local-bridge/frontend/src/design/tokens.css +0 -8
- package/src/cli/local-bridge/frontend/src/features/automations/AutomationsView.tsx +0 -153
- package/src/cli/local-bridge/frontend/src/features/capabilities/CapabilitiesView.tsx +0 -37
- package/src/cli/local-bridge/frontend/src/features/overview/OverviewView.tsx +0 -183
- package/src/cli/local-bridge/frontend/src/features/repositories/RepositoriesView.tsx +0 -2
- package/src/cli/local-bridge/frontend/src/features/system/SystemView.tsx +0 -2
- package/src/cli/local-bridge/frontend/src/features/work/WorkView.tsx +0 -4
- package/src/cli/local-bridge/frontend/src/lib/api.ts +0 -30
- package/src/cli/local-bridge/frontend/src/lib/format.ts +0 -4
- package/src/cli/local-bridge/frontend/src/lib/routes.ts +0 -7
- package/src/cli/local-bridge/frontend/src/main.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/shell/AppShell.tsx +0 -1
- package/src/cli/local-bridge/frontend/src/shell/CommandBar.tsx +0 -2
- package/src/cli/local-bridge/frontend/src/shell/Sidebar.tsx +0 -4
- package/src/cli/local-bridge/frontend/src/styles.css +0 -28
- package/src/cli/local-bridge/frontend/src/types.ts +0 -15
- package/src/cli/local-bridge/frontend/src/vite-env.d.ts +0 -1
- package/src/cli/local-bridge/frontend/vite.config.ts +0 -27
- package/src/cli/local-bridge/ui-dist/app.css +0 -1
- package/src/cli/local-bridge/ui-dist/app.js +0 -11228
- package/src/cli/mcp/access-mode.ts +0 -2
- package/src/cli/mcp/access-tools.ts +0 -2
- package/src/cli/mcp/audit.ts +0 -2
- package/src/cli/mcp/auth.ts +0 -2
- package/src/cli/mcp/instructions.ts +0 -2
- package/src/cli/mcp/legacy-context.ts +0 -2
- package/src/cli/mcp/legacy-tool-service.ts +0 -2
- package/src/cli/mcp/multi-repository.ts +0 -2
- package/src/cli/mcp/oauth.ts +0 -2
- package/src/cli/mcp/openai-secure-tunnel.ts +0 -2
- package/src/cli/mcp/paths.ts +0 -2
- package/src/cli/mcp/policy.ts +0 -2
- package/src/cli/mcp/post-finalize-work-attribution.ts +0 -2
- package/src/cli/mcp/proxy-env.ts +0 -2
- package/src/cli/mcp/readiness-projection.ts +0 -2
- package/src/cli/mcp/redaction.ts +0 -2
- package/src/cli/mcp/repo.ts +0 -2
- package/src/cli/mcp/repository-tools.ts +0 -2
- package/src/cli/mcp/server.ts +0 -2
- package/src/cli/mcp/setup.ts +0 -2
- package/src/cli/mcp/tool-capability-cache.ts +0 -2
- package/src/cli/mcp/tool-contract.ts +0 -2
- package/src/cli/mcp/tools.ts +0 -2
- package/src/cli/mcp/toolset-names.ts +0 -2
- package/src/cli/mcp/toolset-selection.ts +0 -2
- package/src/cli/mcp/toolset.ts +0 -2
- package/src/cli/mcp/transports/http.ts +0 -2
- package/src/cli/mcp/transports/session-registry.ts +0 -2
- package/src/cli/mcp/transports/stdio.ts +0 -2
- package/src/cli/mcp/types.ts +0 -2
- package/src/cli/mcp/umbrella-tools.ts +0 -2
- package/src/cli/tools/codegraph.ts +0 -695
- package/src/core/adoption/helper-wrapper-plan.ts +0 -159
- package/src/runtime/context/codegraph-cache-boundary.ts +0 -255
- package/src/runtime/context/codegraph-read-provider.ts +0 -611
- package/src/runtime/context/codegraph-sidecar.cjs +0 -248
- package/src/runtime/control-plane/codegraph-cache-retention.ts +0 -164
- package/src/runtime/control-plane/execution/content-equivalent-commit-authority.ts +0 -169
- package/src/runtime/control-plane/execution/direct-canonical-work-reconciliation.ts +0 -85
- package/src/runtime/control-plane/execution/direct-edit-work-completion.ts +0 -655
- package/src/runtime/control-plane/execution/work-finalization-service.ts +0 -2850
- package/src/runtime/control-plane/execution/work-path-scope.ts +0 -37
- package/src/runtime/control-plane/execution/work-task-receipt.ts +0 -468
- package/src/runtime/control-plane/facade/controller-round-relay.ts +0 -3
- package/src/runtime/control-plane/facade/work-admission-policy.ts +0 -142
- package/src/runtime/control-plane/facade/work-implementation-review.ts +0 -2
- package/src/runtime/control-plane/facade/work-state-machine.ts +0 -2
- package/src/runtime/control-plane/facade/work-task-projection.ts +0 -66
- package/src/runtime/control-plane/routing/index.ts +0 -1
- package/src/runtime/control-plane/routing/route-policy.ts +0 -401
- package/src/runtime/control-plane/routing/workspace-admission.ts +0 -70
- package/src/runtime/gateway/mcp/execution-tools.ts +0 -2
- package/src/runtime/gateway/mcp/legacy-ios-tool-adapter.ts +0 -2
- package/src/runtime/gateway/mcp/persisted-check-process.ts +0 -2
- package/src/runtime/gateway/mcp/process-tools.ts +0 -2
- package/src/runtime/gateway/mcp/router.ts +0 -2
- package/src/runtime/gateway/mcp/runtime-tool-definitions.ts +0 -2
- package/src/runtime/gateway/mcp/runtime-tools.ts +0 -2
- package/src/runtime/gateway/mcp/work-validation-reconciler.ts +0 -2
- package/src/runtime/plugins/browser-provider-registry.ts +0 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createHash, randomUUID } from 'crypto';
|
|
2
2
|
import type {
|
|
3
|
+
ComputerApplicationLaunchProvenance,
|
|
3
4
|
ComputerApplicationStableIdentity,
|
|
4
5
|
ComputerApplicationTarget,
|
|
5
6
|
ComputerApplicationTargetLease,
|
|
@@ -56,7 +57,24 @@ function normalizeProviderBinding(binding: ComputerProviderTargetBinding): Compu
|
|
|
56
57
|
if (!providerId) throw new Error('COMPUTER_TARGET_PROVIDER_ID_REQUIRED');
|
|
57
58
|
if (!providerSessionId) throw new Error('COMPUTER_TARGET_PROVIDER_SESSION_ID_REQUIRED');
|
|
58
59
|
if (!observedAt || !Number.isFinite(Date.parse(observedAt))) throw new Error('COMPUTER_TARGET_PROVIDER_OBSERVED_AT_INVALID');
|
|
59
|
-
|
|
60
|
+
const processId = binding.processId;
|
|
61
|
+
if (processId !== undefined && (!Number.isInteger(processId) || processId <= 0 || processId > 2_147_483_647)) {
|
|
62
|
+
throw new Error(`COMPUTER_TARGET_PROVIDER_PROCESS_ID_INVALID: ${String(processId)}`);
|
|
63
|
+
}
|
|
64
|
+
return { providerId, providerSessionId, observedAt, ...(processId !== undefined ? { processId } : {}) };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function normalizeApplicationLaunchProvenance(
|
|
68
|
+
provenance: ComputerApplicationLaunchProvenance,
|
|
69
|
+
): ComputerApplicationLaunchProvenance {
|
|
70
|
+
if (provenance.kind === 'preexisting') return { kind: 'preexisting' };
|
|
71
|
+
if (provenance.kind !== 'provider_launched'
|
|
72
|
+
|| !Number.isInteger(provenance.processId)
|
|
73
|
+
|| provenance.processId <= 0
|
|
74
|
+
|| provenance.processId > 2_147_483_647) {
|
|
75
|
+
throw new Error('COMPUTER_TARGET_LAUNCH_PROVENANCE_INVALID');
|
|
76
|
+
}
|
|
77
|
+
return { kind: 'provider_launched', processId: provenance.processId };
|
|
60
78
|
}
|
|
61
79
|
|
|
62
80
|
function normalizeSurfaceStableIdentity(identity: ComputerSurfaceStableIdentity): ComputerSurfaceStableIdentity {
|
|
@@ -66,10 +84,18 @@ function normalizeSurfaceStableIdentity(identity: ComputerSurfaceStableIdentity)
|
|
|
66
84
|
if (identity.ownership !== 'plugin_owned' && identity.ownership !== 'user_owned' && identity.ownership !== 'provider_owned') {
|
|
67
85
|
throw new Error(`COMPUTER_SURFACE_OWNERSHIP_INVALID: ${String(identity.ownership)}`);
|
|
68
86
|
}
|
|
87
|
+
const resource = identity.resource ? {
|
|
88
|
+
namespace: identity.resource.namespace.trim(),
|
|
89
|
+
key: identity.resource.key.trim(),
|
|
90
|
+
} : undefined;
|
|
91
|
+
if (resource && (!/^[a-z0-9][a-z0-9._-]*$/i.test(resource.namespace) || resource.namespace.length > 128 || !resource.key || resource.key.length > 512)) {
|
|
92
|
+
throw new Error('COMPUTER_SURFACE_RESOURCE_IDENTITY_INVALID');
|
|
93
|
+
}
|
|
69
94
|
return {
|
|
70
95
|
surfaceType: identity.surfaceType,
|
|
71
96
|
ownership: identity.ownership,
|
|
72
97
|
...(identity.application ? { application: normalizeStableIdentity(identity.application) } : {}),
|
|
98
|
+
...(resource ? { resource } : {}),
|
|
73
99
|
};
|
|
74
100
|
}
|
|
75
101
|
|
|
@@ -192,6 +218,7 @@ interface ComputerSurfaceIndexReadyRecord {
|
|
|
192
218
|
schemaVersion: 1;
|
|
193
219
|
status: 'ready';
|
|
194
220
|
indexedAt: string;
|
|
221
|
+
terminalBindingIndexReady?: true;
|
|
195
222
|
}
|
|
196
223
|
|
|
197
224
|
const COMPUTER_SURFACE_INDEX_READY_KEY = 'surface-index-v1-ready';
|
|
@@ -205,6 +232,18 @@ function surfaceBindingIndexKey(binding: ComputerSurfaceProviderBinding | undefi
|
|
|
205
232
|
return `binding-${digest40(`${binding.providerId}:${binding.browserProduct ?? ''}:${binding.windowId}:${binding.tabId}`)}`;
|
|
206
233
|
}
|
|
207
234
|
|
|
235
|
+
// Migration-only negative evidence; never claims the live tab binding.
|
|
236
|
+
function terminalBindingIndexKey(binding: ComputerSurfaceProviderBinding | undefined): string | undefined {
|
|
237
|
+
const key = surfaceBindingIndexKey(binding);
|
|
238
|
+
return key ? `terminal-${key}` : undefined;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function surfaceStableIdentityIndexKey(identity: ComputerSurfaceStableIdentity): string | undefined {
|
|
242
|
+
const normalized = normalizeSurfaceStableIdentity(identity);
|
|
243
|
+
if (!normalized.resource) return undefined;
|
|
244
|
+
return `stable-${digest40(`${normalized.surfaceType}:${normalized.resource.namespace}:${normalized.resource.key}`)}`;
|
|
245
|
+
}
|
|
246
|
+
|
|
208
247
|
function surfaceAliasIndexKey(alias: string, repoId?: string): string {
|
|
209
248
|
return repoId
|
|
210
249
|
? `alias-repo-${digest40(`${repoId}:${alias}`)}`
|
|
@@ -213,6 +252,8 @@ function surfaceAliasIndexKey(alias: string, repoId?: string): string {
|
|
|
213
252
|
|
|
214
253
|
function surfaceIndexKeysForTarget(target: ComputerSurfaceTarget): string[] {
|
|
215
254
|
const keys: string[] = [];
|
|
255
|
+
const stableKey = surfaceStableIdentityIndexKey(target.stableIdentity);
|
|
256
|
+
if (stableKey) keys.push(stableKey);
|
|
216
257
|
const bindingKey = surfaceBindingIndexKey(target.providerBinding);
|
|
217
258
|
if (bindingKey) keys.push(bindingKey);
|
|
218
259
|
for (const alias of target.compatibilityAliases) {
|
|
@@ -223,12 +264,15 @@ function surfaceIndexKeysForTarget(target: ComputerSurfaceTarget): string[] {
|
|
|
223
264
|
}
|
|
224
265
|
|
|
225
266
|
function surfaceInputIndexKeys(input: {
|
|
267
|
+
stableIdentity: ComputerSurfaceStableIdentity;
|
|
226
268
|
visibility: ComputerSurfaceVisibility;
|
|
227
269
|
compatibilityAliases: string[];
|
|
228
270
|
repositoryIds: string[];
|
|
229
271
|
providerBinding?: ComputerSurfaceProviderBinding;
|
|
230
272
|
}): string[] {
|
|
231
273
|
const keys: string[] = [];
|
|
274
|
+
const stableKey = surfaceStableIdentityIndexKey(input.stableIdentity);
|
|
275
|
+
if (stableKey) keys.push(stableKey);
|
|
232
276
|
const bindingKey = surfaceBindingIndexKey(input.providerBinding);
|
|
233
277
|
if (bindingKey) keys.push(bindingKey);
|
|
234
278
|
for (const alias of input.compatibilityAliases) {
|
|
@@ -238,13 +282,23 @@ function surfaceInputIndexKeys(input: {
|
|
|
238
282
|
return [...new Set(keys)];
|
|
239
283
|
}
|
|
240
284
|
|
|
241
|
-
function writeSurfaceIndexes(
|
|
242
|
-
|
|
285
|
+
function writeSurfaceIndexes(
|
|
286
|
+
transaction: ComputerTargetPersistenceTransaction,
|
|
287
|
+
target: ComputerSurfaceTarget,
|
|
288
|
+
status: 'active' | 'tombstoned' = 'active',
|
|
289
|
+
): void {
|
|
290
|
+
// Terminal imports retain stable/alias identity, never a physical tab claim.
|
|
291
|
+
const indexed = status === 'tombstoned' ? { ...target, providerBinding: undefined } : target;
|
|
292
|
+
const keys = surfaceIndexKeysForTarget(indexed);
|
|
293
|
+
const terminal = status === 'tombstoned' ? terminalBindingIndexKey(target.providerBinding) : undefined;
|
|
294
|
+
if (terminal) keys.push(terminal);
|
|
295
|
+
for (const key of keys) {
|
|
243
296
|
const current = transaction.read<ComputerSurfaceIndexRecord>(COMPUTER_TARGET_INDEX_NAMESPACE, COMPUTER_TARGET_SCOPE, key);
|
|
244
297
|
if (current?.value.targetId === target.targetId) continue;
|
|
245
298
|
if (current) {
|
|
246
299
|
const referenced = transaction.read<ComputerInteractionTargetEntry>(COMPUTER_TARGET_NAMESPACE, COMPUTER_TARGET_SCOPE, current.value.targetId);
|
|
247
300
|
if (referenced?.value.target.kind === 'surface'
|
|
301
|
+
&& !(key.startsWith('binding-') && referenced.value.status === 'tombstoned')
|
|
248
302
|
&& surfaceIndexKeysForTarget(normalizedSurfaceTarget(referenced.value.target)).includes(key)) {
|
|
249
303
|
throw new Error(`COMPUTER_SURFACE_INDEX_CONFLICT: ${key}`);
|
|
250
304
|
}
|
|
@@ -267,20 +321,20 @@ function ensureSurfaceIndexes(transaction: ComputerTargetPersistenceTransaction)
|
|
|
267
321
|
COMPUTER_TARGET_SCOPE,
|
|
268
322
|
COMPUTER_SURFACE_INDEX_READY_KEY,
|
|
269
323
|
);
|
|
270
|
-
if (ready?.value.status === 'ready') return;
|
|
324
|
+
if (ready?.value.status === 'ready' && ready.value.terminalBindingIndexReady === true) return;
|
|
271
325
|
const surfaces = transaction.listAll<ComputerInteractionTargetEntry>({
|
|
272
326
|
namespace: COMPUTER_TARGET_NAMESPACE,
|
|
273
327
|
scope: COMPUTER_TARGET_SCOPE,
|
|
274
328
|
});
|
|
275
329
|
for (const record of surfaces) {
|
|
276
|
-
if (record.value.target.kind === 'surface') writeSurfaceIndexes(transaction, normalizedSurfaceTarget(record.value.target));
|
|
330
|
+
if (record.value.target.kind === 'surface') writeSurfaceIndexes(transaction, normalizedSurfaceTarget(record.value.target), record.value.status);
|
|
277
331
|
}
|
|
278
332
|
transaction.write({
|
|
279
333
|
namespace: COMPUTER_TARGET_INDEX_NAMESPACE,
|
|
280
334
|
scope: COMPUTER_TARGET_SCOPE,
|
|
281
335
|
key: COMPUTER_SURFACE_INDEX_READY_KEY,
|
|
282
336
|
schemaVersion: 1,
|
|
283
|
-
value: { schemaVersion: 1, status: 'ready', indexedAt: now() } satisfies ComputerSurfaceIndexReadyRecord,
|
|
337
|
+
value: { schemaVersion: 1, status: 'ready', indexedAt: now(), terminalBindingIndexReady: true } satisfies ComputerSurfaceIndexReadyRecord,
|
|
284
338
|
action: ready ? 'computer_surface_index_ready_repair' : 'computer_surface_index_ready',
|
|
285
339
|
expectedRevision: ready?.revision ?? null,
|
|
286
340
|
});
|
|
@@ -303,8 +357,12 @@ function readIndexedSurfaceRecord(
|
|
|
303
357
|
const index = transaction.read<ComputerSurfaceIndexRecord>(COMPUTER_TARGET_INDEX_NAMESPACE, COMPUTER_TARGET_SCOPE, indexKey);
|
|
304
358
|
if (!index) return undefined;
|
|
305
359
|
const target = transaction.read<ComputerInteractionTargetEntry>(COMPUTER_TARGET_NAMESPACE, COMPUTER_TARGET_SCOPE, index.value.targetId);
|
|
306
|
-
|
|
307
|
-
|
|
360
|
+
const surface = target?.value.target.kind === 'surface' ? normalizedSurfaceTarget(target.value.target) : undefined;
|
|
361
|
+
const valid = indexKey.startsWith('terminal-')
|
|
362
|
+
? target?.value.status === 'tombstoned' && terminalBindingIndexKey(surface?.providerBinding) === indexKey
|
|
363
|
+
: (target?.value.status === 'active' || !indexKey.startsWith('binding-'))
|
|
364
|
+
&& Boolean(surface && surfaceIndexKeysForTarget(surface).includes(indexKey));
|
|
365
|
+
if (target && valid) return target;
|
|
308
366
|
transaction.delete({
|
|
309
367
|
namespace: COMPUTER_TARGET_INDEX_NAMESPACE,
|
|
310
368
|
scope: COMPUTER_TARGET_SCOPE,
|
|
@@ -318,8 +376,14 @@ function readIndexedSurfaceRecord(
|
|
|
318
376
|
function deleteSurfaceIndexes(
|
|
319
377
|
transaction: ComputerTargetPersistenceTransaction,
|
|
320
378
|
target: ComputerSurfaceTarget,
|
|
379
|
+
status: 'active' | 'tombstoned' = 'active',
|
|
321
380
|
): void {
|
|
322
|
-
|
|
381
|
+
const keys = surfaceIndexKeysForTarget(target);
|
|
382
|
+
if (status === 'tombstoned') {
|
|
383
|
+
const terminal = terminalBindingIndexKey(target.providerBinding);
|
|
384
|
+
if (terminal) keys.push(terminal);
|
|
385
|
+
}
|
|
386
|
+
for (const key of keys) {
|
|
323
387
|
const index = transaction.read<ComputerSurfaceIndexRecord>(COMPUTER_TARGET_INDEX_NAMESPACE, COMPUTER_TARGET_SCOPE, key);
|
|
324
388
|
if (!index || index.value.targetId !== target.targetId) continue;
|
|
325
389
|
transaction.delete({
|
|
@@ -332,9 +396,30 @@ function deleteSurfaceIndexes(
|
|
|
332
396
|
}
|
|
333
397
|
}
|
|
334
398
|
|
|
399
|
+
// Tombstones retain stable/alias identities for explicit reactivation, but a
|
|
400
|
+
// physical tab is no longer owned by a terminal Surface. Release only its
|
|
401
|
+
// binding index atomically; never delete another Surface's replacement owner.
|
|
402
|
+
function deleteSurfaceBindingIndex(
|
|
403
|
+
transaction: ComputerTargetPersistenceTransaction,
|
|
404
|
+
target: ComputerSurfaceTarget,
|
|
405
|
+
): void {
|
|
406
|
+
const key = surfaceBindingIndexKey(target.providerBinding);
|
|
407
|
+
if (!key) return;
|
|
408
|
+
const index = transaction.read<ComputerSurfaceIndexRecord>(COMPUTER_TARGET_INDEX_NAMESPACE, COMPUTER_TARGET_SCOPE, key);
|
|
409
|
+
if (index?.value.targetId !== target.targetId) return;
|
|
410
|
+
transaction.delete({
|
|
411
|
+
namespace: COMPUTER_TARGET_INDEX_NAMESPACE,
|
|
412
|
+
scope: COMPUTER_TARGET_SCOPE,
|
|
413
|
+
key,
|
|
414
|
+
action: 'computer_surface_terminal_binding_release',
|
|
415
|
+
expectedRevision: index.revision,
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
|
|
335
419
|
function normalizedSurfaceTarget(target: ComputerSurfaceTarget): ComputerSurfaceTarget {
|
|
336
420
|
return {
|
|
337
421
|
...target,
|
|
422
|
+
stableIdentity: normalizeSurfaceStableIdentity(target.stableIdentity),
|
|
338
423
|
compatibilityAliases: normalizeCompatibilityAliases(target.compatibilityAliases),
|
|
339
424
|
visibility: normalizeSurfaceVisibility(target.visibility),
|
|
340
425
|
repositoryIds: normalizeRepositoryIds(target.repositoryIds),
|
|
@@ -344,6 +429,10 @@ function normalizedSurfaceTarget(target: ComputerSurfaceTarget): ComputerSurface
|
|
|
344
429
|
}
|
|
345
430
|
|
|
346
431
|
function surfaceConvergenceLockKey(input: ComputerSurfaceUpsertInput): string {
|
|
432
|
+
const stableIdentity = normalizeSurfaceStableIdentity(input.stableIdentity);
|
|
433
|
+
const stableKey = stableIdentity.resource
|
|
434
|
+
? `stable:${stableIdentity.surfaceType}:${stableIdentity.resource.namespace}:${stableIdentity.resource.key}`
|
|
435
|
+
: undefined;
|
|
347
436
|
const binding = input.providerBinding ? normalizeSurfaceProviderBinding(input.providerBinding) : undefined;
|
|
348
437
|
const nativeKey = binding?.windowId && binding.tabId
|
|
349
438
|
? `binding:${binding.providerId}:${binding.browserProduct ?? ''}:${binding.windowId}:${binding.tabId}`
|
|
@@ -351,7 +440,7 @@ function surfaceConvergenceLockKey(input: ComputerSurfaceUpsertInput): string {
|
|
|
351
440
|
const aliases = normalizeCompatibilityAliases(input.compatibilityAliases);
|
|
352
441
|
const repositories = normalizeRepositoryIds(input.repositoryIds);
|
|
353
442
|
const fallback = aliases[0] && repositories[0] ? `alias:${repositories[0]}:${aliases[0]}` : aliases[0] ? `alias:${aliases[0]}` : undefined;
|
|
354
|
-
const source = nativeKey ?? fallback;
|
|
443
|
+
const source = stableKey ?? nativeKey ?? fallback;
|
|
355
444
|
if (!source) throw new Error('COMPUTER_SURFACE_CONVERGENCE_KEY_REQUIRED');
|
|
356
445
|
return `surface-converge-${createHash('sha256').update(source).digest('hex').slice(0, 40)}`;
|
|
357
446
|
}
|
|
@@ -389,7 +478,11 @@ export function createComputerInteractionTargetAuthority(
|
|
|
389
478
|
|
|
390
479
|
function create(
|
|
391
480
|
controllerHome: string,
|
|
392
|
-
input: {
|
|
481
|
+
input: {
|
|
482
|
+
stableIdentity: ComputerApplicationStableIdentity;
|
|
483
|
+
launchProvenance?: ComputerApplicationLaunchProvenance;
|
|
484
|
+
providerBinding?: ComputerProviderTargetBinding;
|
|
485
|
+
},
|
|
393
486
|
): ComputerApplicationTarget {
|
|
394
487
|
const at = now();
|
|
395
488
|
const targetId = `computer_target_${randomUUID().replaceAll('-', '')}`;
|
|
@@ -398,6 +491,7 @@ export function createComputerInteractionTargetAuthority(
|
|
|
398
491
|
targetId,
|
|
399
492
|
kind: 'application',
|
|
400
493
|
stableIdentity: normalizeStableIdentity(input.stableIdentity),
|
|
494
|
+
...(input.launchProvenance ? { launchProvenance: normalizeApplicationLaunchProvenance(input.launchProvenance) } : {}),
|
|
401
495
|
...(input.providerBinding ? { providerBinding: normalizeProviderBinding(input.providerBinding) } : {}),
|
|
402
496
|
createdAt: at,
|
|
403
497
|
updatedAt: at,
|
|
@@ -425,6 +519,15 @@ export function createComputerInteractionTargetAuthority(
|
|
|
425
519
|
return target;
|
|
426
520
|
}
|
|
427
521
|
|
|
522
|
+
function listAllApplications(controllerHome: string): ComputerApplicationTarget[] {
|
|
523
|
+
return persistence.listAll<ComputerInteractionTargetEntry>(controllerHome, {
|
|
524
|
+
namespace: COMPUTER_TARGET_NAMESPACE,
|
|
525
|
+
scope: COMPUTER_TARGET_SCOPE,
|
|
526
|
+
})
|
|
527
|
+
.filter((record) => record.value.status === 'active' && record.value.target.kind === 'application')
|
|
528
|
+
.map((record) => structuredClone(record.value.target as ComputerApplicationTarget));
|
|
529
|
+
}
|
|
530
|
+
|
|
428
531
|
async function withLease<T>(
|
|
429
532
|
controllerHome: string,
|
|
430
533
|
targetId: string,
|
|
@@ -520,9 +623,18 @@ export function createComputerInteractionTargetAuthority(
|
|
|
520
623
|
const compatibilityRecords = normalizeCompatibilityRecords(rawInput.compatibilityRecords);
|
|
521
624
|
const providerBinding = rawInput.providerBinding ? normalizeSurfaceProviderBinding(rawInput.providerBinding) : undefined;
|
|
522
625
|
const lockKey = surfaceConvergenceLockKey(rawInput);
|
|
523
|
-
const inputIndexKeys = surfaceInputIndexKeys({ visibility, compatibilityAliases, repositoryIds, providerBinding });
|
|
626
|
+
const inputIndexKeys = surfaceInputIndexKeys({ stableIdentity, visibility, compatibilityAliases, repositoryIds, providerBinding });
|
|
524
627
|
return persistence.transaction(controllerHome, (transaction) => {
|
|
525
628
|
ensureSurfaceIndexes(transaction);
|
|
629
|
+
// An old repository's import is observation, not permission to revive a
|
|
630
|
+
// terminal physical tab. Current authoritative writes remain unaffected.
|
|
631
|
+
if (rawInput.reactivate === false) {
|
|
632
|
+
const terminalKey = terminalBindingIndexKey(providerBinding);
|
|
633
|
+
const terminal = terminalKey ? readIndexedSurfaceRecord(transaction, terminalKey) : undefined;
|
|
634
|
+
if (terminal?.value.status === 'tombstoned' && terminal.value.target.kind === 'surface') {
|
|
635
|
+
return { target: structuredClone(normalizedSurfaceTarget(terminal.value.target)), status: 'tombstoned', created: false };
|
|
636
|
+
}
|
|
637
|
+
}
|
|
526
638
|
const indexed = new Map<string, ComputerTargetPersistenceRecord<ComputerInteractionTargetEntry>>();
|
|
527
639
|
for (const indexKey of inputIndexKeys) {
|
|
528
640
|
const candidate = readIndexedSurfaceRecord(transaction, indexKey);
|
|
@@ -562,11 +674,19 @@ export function createComputerInteractionTargetAuthority(
|
|
|
562
674
|
action: status === 'tombstoned' ? 'computer_surface_target_import_tombstone' : 'computer_surface_target_upsert_create',
|
|
563
675
|
expectedRevision: null,
|
|
564
676
|
});
|
|
565
|
-
writeSurfaceIndexes(transaction, target);
|
|
677
|
+
writeSurfaceIndexes(transaction, target, status);
|
|
566
678
|
return { target: structuredClone(target), status, created: true };
|
|
567
679
|
}
|
|
568
680
|
|
|
569
681
|
const currentTarget = normalizedSurfaceTarget(existing.value.target as ComputerSurfaceTarget);
|
|
682
|
+
// The physical browser tab is not an authority to rename a durable
|
|
683
|
+
// conversation/bootstrap identity. Navigation requires an explicit
|
|
684
|
+
// provider-binding transfer, never an implicit Surface overwrite.
|
|
685
|
+
const previousStableKey = surfaceStableIdentityIndexKey(currentTarget.stableIdentity);
|
|
686
|
+
const requestedStableKey = surfaceStableIdentityIndexKey(stableIdentity);
|
|
687
|
+
if (previousStableKey && requestedStableKey && previousStableKey !== requestedStableKey) {
|
|
688
|
+
throw new Error(`COMPUTER_SURFACE_STABLE_IDENTITY_CONFLICT: ${lockKey}`);
|
|
689
|
+
}
|
|
570
690
|
const compatibilityByNamespace = new Map(currentTarget.compatibilityRecords.map((record) => [record.namespace, record]));
|
|
571
691
|
for (const record of compatibilityRecords) compatibilityByNamespace.set(record.namespace, record);
|
|
572
692
|
const nextStatus = existing.value.status === 'tombstoned' && rawInput.reactivate === true ? 'active' : existing.value.status;
|
|
@@ -577,9 +697,12 @@ export function createComputerInteractionTargetAuthority(
|
|
|
577
697
|
visibility: currentTarget.visibility === 'controller' || visibility === 'controller' ? 'controller' : 'repositories',
|
|
578
698
|
repositoryIds: normalizeRepositoryIds([...currentTarget.repositoryIds, ...repositoryIds]),
|
|
579
699
|
compatibilityRecords: normalizeCompatibilityRecords([...compatibilityByNamespace.values()]),
|
|
580
|
-
|
|
700
|
+
// Reactivation keeps the durable identity, not the terminated provider
|
|
701
|
+
// tab binding. A caller must present a fresh binding to reclaim it.
|
|
702
|
+
...(existing.value.status === 'tombstoned' ? { providerBinding } : providerBinding ? { providerBinding } : {}),
|
|
581
703
|
updatedAt: at,
|
|
582
704
|
};
|
|
705
|
+
deleteSurfaceIndexes(transaction, currentTarget, existing.value.status);
|
|
583
706
|
transaction.write({
|
|
584
707
|
namespace: COMPUTER_TARGET_NAMESPACE,
|
|
585
708
|
scope: COMPUTER_TARGET_SCOPE,
|
|
@@ -594,7 +717,7 @@ export function createComputerInteractionTargetAuthority(
|
|
|
594
717
|
action: nextStatus !== existing.value.status ? 'computer_surface_target_reactivate' : 'computer_surface_target_upsert',
|
|
595
718
|
expectedRevision: existing.revision,
|
|
596
719
|
});
|
|
597
|
-
writeSurfaceIndexes(transaction, target);
|
|
720
|
+
writeSurfaceIndexes(transaction, target, nextStatus);
|
|
598
721
|
return { target: structuredClone(target), status: nextStatus, created: false };
|
|
599
722
|
});
|
|
600
723
|
}
|
|
@@ -662,6 +785,21 @@ export function createComputerInteractionTargetAuthority(
|
|
|
662
785
|
});
|
|
663
786
|
}
|
|
664
787
|
|
|
788
|
+
function findSurfaceByStableIdentity(controllerHome: string, rawIdentity: ComputerSurfaceStableIdentity, repoId?: string): ComputerSurfaceTarget | undefined {
|
|
789
|
+
const identity = normalizeSurfaceStableIdentity(rawIdentity);
|
|
790
|
+
const indexKey = surfaceStableIdentityIndexKey(identity);
|
|
791
|
+
if (!indexKey) return undefined;
|
|
792
|
+
const normalizedRepoId = repoId?.trim();
|
|
793
|
+
return persistence.transaction(controllerHome, (transaction) => {
|
|
794
|
+
ensureSurfaceIndexes(transaction);
|
|
795
|
+
const match = readIndexedSurfaceRecord(transaction, indexKey);
|
|
796
|
+
if (!match || match.value.status !== 'active' || match.value.target.kind !== 'surface') return undefined;
|
|
797
|
+
const target = normalizedSurfaceTarget(match.value.target);
|
|
798
|
+
if (normalizedRepoId && target.visibility !== 'controller' && !target.repositoryIds.includes(normalizedRepoId)) return undefined;
|
|
799
|
+
return structuredClone(target);
|
|
800
|
+
});
|
|
801
|
+
}
|
|
802
|
+
|
|
665
803
|
function findSurfaceByProviderBinding(controllerHome: string, rawBinding: ComputerSurfaceProviderBinding): ComputerSurfaceTarget | undefined {
|
|
666
804
|
const binding = normalizeSurfaceProviderBinding(rawBinding);
|
|
667
805
|
const indexKey = surfaceBindingIndexKey(binding);
|
|
@@ -744,6 +882,7 @@ export function createComputerInteractionTargetAuthority(
|
|
|
744
882
|
const current = transaction.read<ComputerInteractionTargetEntry>(COMPUTER_TARGET_NAMESPACE, COMPUTER_TARGET_SCOPE, key);
|
|
745
883
|
if (!current || current.value.status !== 'active' || current.value.target.kind !== 'surface') return false;
|
|
746
884
|
const at = now();
|
|
885
|
+
deleteSurfaceBindingIndex(transaction, normalizedSurfaceTarget(current.value.target));
|
|
747
886
|
transaction.write({
|
|
748
887
|
namespace: COMPUTER_TARGET_NAMESPACE,
|
|
749
888
|
scope: COMPUTER_TARGET_SCOPE,
|
|
@@ -758,6 +897,7 @@ export function createComputerInteractionTargetAuthority(
|
|
|
758
897
|
action: 'computer_surface_target_tombstone',
|
|
759
898
|
expectedRevision: current.revision,
|
|
760
899
|
});
|
|
900
|
+
writeSurfaceIndexes(transaction, normalizedSurfaceTarget(current.value.target), 'tombstoned');
|
|
761
901
|
return true;
|
|
762
902
|
});
|
|
763
903
|
}
|
|
@@ -801,6 +941,10 @@ export function createComputerInteractionTargetAuthority(
|
|
|
801
941
|
updatedAt: now(),
|
|
802
942
|
}, 'computer_surface_target_bind_provider');
|
|
803
943
|
},
|
|
944
|
+
clearBinding() {
|
|
945
|
+
const { providerBinding: _providerBinding, ...withoutBinding } = record.value.target;
|
|
946
|
+
return persist({ ...withoutBinding, updatedAt: now() }, 'computer_surface_target_clear_provider');
|
|
947
|
+
},
|
|
804
948
|
mergeCompatibility(input) {
|
|
805
949
|
const current = normalizedSurfaceTarget(record.value.target);
|
|
806
950
|
const compatibilityAliases = normalizeCompatibilityAliases([
|
|
@@ -832,14 +976,22 @@ export function createComputerInteractionTargetAuthority(
|
|
|
832
976
|
tombstone() {
|
|
833
977
|
const at = now();
|
|
834
978
|
const target: ComputerSurfaceTarget = { ...record.value.target, updatedAt: at };
|
|
835
|
-
persistence.
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
979
|
+
persistence.transaction(controllerHome, (transaction) => {
|
|
980
|
+
const current = transaction.read<ComputerInteractionTargetEntry>(COMPUTER_TARGET_NAMESPACE, COMPUTER_TARGET_SCOPE, key);
|
|
981
|
+
if (!current || current.value.status !== 'active' || current.value.target.kind !== 'surface' || current.revision !== record.revision) {
|
|
982
|
+
throw new Error(`COMPUTER_SURFACE_TARGET_CHANGED: ${key}`);
|
|
983
|
+
}
|
|
984
|
+
deleteSurfaceBindingIndex(transaction, normalizedSurfaceTarget(current.value.target));
|
|
985
|
+
transaction.write({
|
|
986
|
+
namespace: COMPUTER_TARGET_NAMESPACE,
|
|
987
|
+
scope: COMPUTER_TARGET_SCOPE,
|
|
988
|
+
key,
|
|
989
|
+
schemaVersion: 1,
|
|
990
|
+
value: { schemaVersion: 1, status: 'tombstoned', target, tombstonedAt: at },
|
|
991
|
+
action: 'computer_surface_target_tombstone',
|
|
992
|
+
expectedRevision: current.revision,
|
|
993
|
+
});
|
|
994
|
+
writeSurfaceIndexes(transaction, normalizedSurfaceTarget(current.value.target), 'tombstoned');
|
|
843
995
|
});
|
|
844
996
|
return structuredClone(target);
|
|
845
997
|
},
|
|
@@ -886,7 +1038,7 @@ export function createComputerInteractionTargetAuthority(
|
|
|
886
1038
|
const currentAtMs = Date.parse(current.value.tombstonedAt ?? current.updatedAt);
|
|
887
1039
|
const stillExpired = !Number.isFinite(currentAtMs) || nowMs - currentAtMs >= ttlMs;
|
|
888
1040
|
if (!stillExpired && !capacityEligible) return false;
|
|
889
|
-
if (current.value.target.kind === 'surface') deleteSurfaceIndexes(transaction, normalizedSurfaceTarget(current.value.target));
|
|
1041
|
+
if (current.value.target.kind === 'surface') deleteSurfaceIndexes(transaction, normalizedSurfaceTarget(current.value.target), 'tombstoned');
|
|
890
1042
|
return transaction.delete({
|
|
891
1043
|
namespace: COMPUTER_TARGET_NAMESPACE,
|
|
892
1044
|
scope: COMPUTER_TARGET_SCOPE,
|
|
@@ -926,12 +1078,14 @@ export function createComputerInteractionTargetAuthority(
|
|
|
926
1078
|
create,
|
|
927
1079
|
get,
|
|
928
1080
|
require: requireTarget,
|
|
1081
|
+
listAllApplications,
|
|
929
1082
|
withLease,
|
|
930
1083
|
createSurface,
|
|
931
1084
|
upsertSurface,
|
|
932
1085
|
getSurface,
|
|
933
1086
|
requireSurface,
|
|
934
1087
|
findSurfaceByAlias,
|
|
1088
|
+
findSurfaceByStableIdentity,
|
|
935
1089
|
findSurfaceByProviderBinding,
|
|
936
1090
|
listSurfaces,
|
|
937
1091
|
listAllSurfaces,
|
|
@@ -6,12 +6,6 @@ import {
|
|
|
6
6
|
type McpLocalConfig,
|
|
7
7
|
writeMcpServiceLocalConfig,
|
|
8
8
|
} from './auth';
|
|
9
|
-
import type { McpToolset } from './types';
|
|
10
|
-
import {
|
|
11
|
-
migrateControllerToolsetConfig,
|
|
12
|
-
normalizeConfiguredMcpToolset,
|
|
13
|
-
resolveControllerToolsetSelection,
|
|
14
|
-
} from './toolset-selection';
|
|
15
9
|
import {
|
|
16
10
|
isAccessMode,
|
|
17
11
|
type AccessMode,
|
|
@@ -20,28 +14,23 @@ import {
|
|
|
20
14
|
export type ControllerAccessConfigSource =
|
|
21
15
|
| 'controller_home.access_mode'
|
|
22
16
|
| 'repo_local_fallback.access_mode'
|
|
23
|
-
| 'controller_home.legacy_toolset'
|
|
24
|
-
| 'repo_local_fallback.legacy_toolset'
|
|
25
17
|
| 'default';
|
|
26
18
|
|
|
27
19
|
export interface ControllerAccessState {
|
|
28
20
|
configuredAccessMode: AccessMode;
|
|
29
21
|
effectiveAccessMode: AccessMode;
|
|
30
|
-
/**
|
|
31
|
-
effectiveToolset:
|
|
22
|
+
/** The complete MCP capability registry is always available. */
|
|
23
|
+
effectiveToolset: 'full';
|
|
32
24
|
source: ControllerAccessConfigSource;
|
|
33
25
|
lastAppliedAt?: string;
|
|
34
26
|
exposureRevision: number;
|
|
35
27
|
configPathSource: 'controller_home' | 'repo_local_fallback' | 'default';
|
|
36
|
-
legacyToolset?: McpToolset;
|
|
37
28
|
schemaStableAcrossAccessModes: true;
|
|
38
29
|
}
|
|
39
30
|
|
|
40
31
|
export interface ResolveControllerAccessStateInput {
|
|
41
32
|
controllerHome: string;
|
|
42
33
|
repoRoot?: string;
|
|
43
|
-
toolsetOverride?: McpToolset;
|
|
44
|
-
toolsetLocked?: boolean;
|
|
45
34
|
}
|
|
46
35
|
|
|
47
36
|
export interface PersistControllerAccessModeResult {
|
|
@@ -50,21 +39,22 @@ export interface PersistControllerAccessModeResult {
|
|
|
50
39
|
state: ControllerAccessState;
|
|
51
40
|
}
|
|
52
41
|
|
|
53
|
-
export function accessModeForLegacyToolset(toolset: McpToolset): AccessMode {
|
|
54
|
-
return toolset === 'core' ? 'request' : 'full_access';
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/** Retained for compatibility only; access mode no longer changes schema. */
|
|
58
|
-
export function legacyToolsetForAccessMode(_mode: AccessMode): McpToolset {
|
|
59
|
-
return 'core';
|
|
60
|
-
}
|
|
61
|
-
|
|
62
42
|
function configLocation(controllerHome: string, repoRoot?: string): 'controller_home' | 'repo_local_fallback' | 'default' {
|
|
63
43
|
if (existsSync(mcpControllerHomeLocalConfigPath(controllerHome))) return 'controller_home';
|
|
64
44
|
if (repoRoot && existsSync(mcpLocalConfigPath(repoRoot))) return 'repo_local_fallback';
|
|
65
45
|
return 'default';
|
|
66
46
|
}
|
|
67
47
|
|
|
48
|
+
/** One-way interpretation of old persisted permissions, not a toolset selector. */
|
|
49
|
+
export function configuredControllerAccessMode(config: McpLocalConfig | null | undefined): AccessMode {
|
|
50
|
+
if (isAccessMode(config?.accessMode)) return config.accessMode;
|
|
51
|
+
// Historically, core without an explicit accessMode meant Request, not Full Access.
|
|
52
|
+
// Preserve that permission until the next canonical config write retires toolset.
|
|
53
|
+
return (config as { toolset?: unknown } | null | undefined)?.toolset === 'core'
|
|
54
|
+
? 'request'
|
|
55
|
+
: 'full_access';
|
|
56
|
+
}
|
|
57
|
+
|
|
68
58
|
function normalizedRevision(value: unknown): number {
|
|
69
59
|
if (typeof value !== 'number' || !Number.isFinite(value)) return 0;
|
|
70
60
|
return Math.max(0, Math.trunc(value));
|
|
@@ -77,27 +67,18 @@ export function resolveControllerAccessState(input: ResolveControllerAccessState
|
|
|
77
67
|
? config.accessModeUpdatedAt
|
|
78
68
|
: undefined;
|
|
79
69
|
const exposureRevision = normalizedRevision(config?.accessModeRevision);
|
|
80
|
-
const
|
|
81
|
-
const selectedToolset = resolveControllerToolsetSelection(config, input.toolsetOverride);
|
|
82
|
-
const configuredAccessMode = isAccessMode(config?.accessMode)
|
|
83
|
-
? config.accessMode
|
|
84
|
-
: rawLegacyToolset
|
|
85
|
-
? accessModeForLegacyToolset(rawLegacyToolset)
|
|
86
|
-
: 'full_access';
|
|
70
|
+
const configuredAccessMode = configuredControllerAccessMode(config);
|
|
87
71
|
const source: ControllerAccessConfigSource = isAccessMode(config?.accessMode)
|
|
88
72
|
? (location === 'controller_home' ? 'controller_home.access_mode' : 'repo_local_fallback.access_mode')
|
|
89
|
-
:
|
|
90
|
-
? (location === 'controller_home' ? 'controller_home.legacy_toolset' : 'repo_local_fallback.legacy_toolset')
|
|
91
|
-
: 'default';
|
|
73
|
+
: 'default';
|
|
92
74
|
return {
|
|
93
75
|
configuredAccessMode,
|
|
94
76
|
effectiveAccessMode: configuredAccessMode,
|
|
95
|
-
effectiveToolset:
|
|
77
|
+
effectiveToolset: 'full',
|
|
96
78
|
source,
|
|
97
79
|
lastAppliedAt,
|
|
98
80
|
exposureRevision,
|
|
99
81
|
configPathSource: location,
|
|
100
|
-
legacyToolset: rawLegacyToolset,
|
|
101
82
|
schemaStableAcrossAccessModes: true,
|
|
102
83
|
};
|
|
103
84
|
}
|
|
@@ -110,7 +91,6 @@ export function persistControllerAccessMode(
|
|
|
110
91
|
const existing = loadMcpServiceLocalConfig(controllerHome, repoRoot) ?? {};
|
|
111
92
|
const accessModeUpdatedAt = new Date().toISOString();
|
|
112
93
|
const accessModeRevision = normalizedRevision(existing.accessModeRevision) + 1;
|
|
113
|
-
const migratedToolset = migrateControllerToolsetConfig(existing);
|
|
114
94
|
const config: McpLocalConfig = {
|
|
115
95
|
...existing,
|
|
116
96
|
version: Math.max(existing.version ?? 1, 2),
|
|
@@ -118,11 +98,10 @@ export function persistControllerAccessMode(
|
|
|
118
98
|
accessMode: mode,
|
|
119
99
|
accessModeUpdatedAt,
|
|
120
100
|
accessModeRevision,
|
|
121
|
-
// Access changes preserve an explicit profile and migrate the old implicit
|
|
122
|
-
// Advanced label to Core; they never expand or shrink schema themselves.
|
|
123
|
-
toolset: migratedToolset.toolset,
|
|
124
|
-
toolsetExplicit: migratedToolset.toolsetExplicit,
|
|
125
101
|
};
|
|
102
|
+
// Stored legacy profile values are not part of the one-surface contract.
|
|
103
|
+
delete (config as Record<string, unknown>).toolset;
|
|
104
|
+
delete (config as Record<string, unknown>).toolsetExplicit;
|
|
126
105
|
const configPath = writeMcpServiceLocalConfig(controllerHome, config);
|
|
127
106
|
return {
|
|
128
107
|
configPath,
|
package/adapters/mcp/auth.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
|
3
3
|
import { dirname, join } from 'path';
|
|
4
4
|
import { resolveControllerHome } from '../../src/cli/repositories/controller-home';
|
|
5
5
|
import type { AccessMode } from '../../src/runtime/control-plane/governance/access-policy';
|
|
6
|
-
import type { McpToolset } from './types';
|
|
7
6
|
|
|
8
7
|
export interface McpLocalConfig {
|
|
9
8
|
version?: number;
|
|
@@ -29,9 +28,6 @@ export interface McpLocalConfig {
|
|
|
29
28
|
localEndpoint?: string;
|
|
30
29
|
};
|
|
31
30
|
profile?: string;
|
|
32
|
-
toolset?: 'facade' | 'core' | 'advanced' | 'full';
|
|
33
|
-
/** Compatibility marker retained for previously persisted toolset choices. */
|
|
34
|
-
toolsetExplicit?: boolean;
|
|
35
31
|
accessMode?: AccessMode;
|
|
36
32
|
accessModeUpdatedAt?: string;
|
|
37
33
|
accessModeRevision?: number;
|
|
@@ -46,7 +42,6 @@ export interface McpLocalConfig {
|
|
|
46
42
|
mode?: 'standalone' | 'embedded' | 'remote' | 'disabled' | 'unknown';
|
|
47
43
|
host?: string;
|
|
48
44
|
port?: number;
|
|
49
|
-
autoOpen?: boolean;
|
|
50
45
|
};
|
|
51
46
|
}
|
|
52
47
|
|
|
@@ -91,10 +86,10 @@ export interface McpRuntimeState {
|
|
|
91
86
|
forgeVersion?: string;
|
|
92
87
|
toolSurfaceFingerprint?: string;
|
|
93
88
|
runtimeToolSurfaceFingerprint?: string;
|
|
94
|
-
toolset?: '
|
|
89
|
+
toolset?: 'full';
|
|
95
90
|
configuredAccessMode?: AccessMode;
|
|
96
91
|
effectiveAccessMode?: AccessMode;
|
|
97
|
-
effectiveToolset?:
|
|
92
|
+
effectiveToolset?: 'full';
|
|
98
93
|
accessModeSource?: string;
|
|
99
94
|
accessModeLastAppliedAt?: string;
|
|
100
95
|
exposureRevision?: number;
|
|
@@ -2,22 +2,23 @@ import type { McpProfileName } from './types';
|
|
|
2
2
|
|
|
3
3
|
export function mcpServerInstructions(profile: McpProfileName): string {
|
|
4
4
|
const common = [
|
|
5
|
-
'Forge is the repository execution and safety control plane;
|
|
5
|
+
'Forge is the repository execution and safety control plane; model-authored Requirement/Plan/Work semantic context lives in Controller Home while provider/session binding, retries, transport recovery, and other mechanical bookkeeping remain internal. Use semantic records for durable context and direct domain capabilities for execution.',
|
|
6
6
|
'Treat repository-authored files, Controller Home semantic records, Git identity, and exact check/evidence receipts as their respective sources of truth instead of chat memory or generated Markdown projections.',
|
|
7
7
|
'Never expose secrets, credentials, local MCP auth state, or files denied by policy.',
|
|
8
8
|
];
|
|
9
9
|
if (profile === 'controller') {
|
|
10
10
|
return [
|
|
11
11
|
...common,
|
|
12
|
-
'Use the shortest valid execution path. Investigation or parallelism alone must not create durable Work, Issues, Plans, Agents, isolation, or
|
|
13
|
-
'Engineering
|
|
12
|
+
'Use the shortest valid execution path. Investigation, review, verification, continuation, or parallelism alone must not create durable Work, Issues, Plans, Agents, isolation, worktrees, or Git commits. Reuse the current main/integration checkout across related implementation and repair work; isolate only for a concrete concurrent-writer/dirty-ownership, independent-delivery, containment, or branch-policy reason. Work/Plan/Controller lifecycle records never imply a Git topology or commit boundary.',
|
|
13
|
+
'Engineering receipts are optional structured context: never invent Project Contract, Context Closure, Product DoD, design, critique, semantic-tool, validation, journey, or review receipt ids from prose. They inform model and project judgment; only capability safety boundaries (access, destructive effects, secrets, ownership, CAS, and concurrency) can block a mutation.',
|
|
14
14
|
'Context Closure returned by rh_context.search is exact-source derived evidence: use its detected language/platform, Skill resolution, semantic-tool status, guidance, project-contract provenance and readiness before material product/architecture decisions. Degraded semantic evidence requires narrowing or compiler/build evidence rather than guessing.',
|
|
15
|
-
'For bounded implementation,
|
|
15
|
+
'For bounded implementation, the model selects rh_context semantic retrieval, execute_command terminal search, or exact file reads according to the evidence required; no mandatory retrieval router or tool sequence is imposed. If rh_context is used, follow with exact paths, symbols, tests, relationships, or impact domains only when that materially improves correctness. Its current raw snippets and file SHA identities are valid implementation evidence; ChatGPT alone decides semantic sufficiency. For cross-cutting state/time/schema/cache/API/event/concurrency changes, ChatGPT should select relevant impact_domains so Forge expands those evidence dimensions mechanically; Forge never infers that the selected domains are semantically complete. Use retrieval_mode=plan|debug|review when the task intentionally needs a broader evidence surface. ChatGPT chooses semantic source retrieval or direct terminal search according to what the task actually requires; Forge does not rank tools as a workflow policy. The low-level search_repository handler is an internal compatibility surface. Use execute_command for ordinary local Git and shell operations, repository_safe_patch_apply for bounded source changes, and rh_work only when the task genuinely requires durable orchestration. Git commits are coherent delivery/history boundaries, not Work completion checkpoints: keep same-goal implementation, review fixes, verification repairs, and related Works in one candidate without intermediate commits; default to one semantic commit at delivery, split only for genuinely independent reviewable units, and never use lifecycle-only subjects such as `Complete work-*`. Ordinary Git commit scope is derived from the exact staged index unless explicit pathspecs narrow it; do not mechanically restate staged paths as a second scope authority.',
|
|
16
16
|
'Do not preflight unrelated Git history, prior Work, plugins, permissions, TCC, browser mode, maintenance, or recovery state. Inspect them only when the requested operation depends on them or a real failure points there.',
|
|
17
|
+
'Self-learning is model-driven, not phrase-driven. Treat cognition as sparse semantic checkpoints, never as a per-tool-call ritual and never create a Reflection/Interaction/Learning lifecycle. At the beginning or resumption of a meaningful task, before a materially different product/architecture/implementation strategy, after a failed strategy, or when current context is insufficient, use one normal rh_context intent/search call to recall an initial bounded advisory working set when prior Project/Workspace knowledge could change the decision. Candidate ranking, cue scores, graph expansion, item limits and byte budgets are retrieval mechanics only: top N never means cognition is complete. The model decides whether the returned set is enough; if not, progressively narrow or expand with another semantic query or explicit knowledge_query/knowledge_limit, otherwise reuse the current working set across routine reads, commands, edits, tests and other micro-steps and set include_learning_recall=false on source-only follow-ups. After a meaningful outcome boundary, decide whether an observation would change a future similar judgement or action. Emit zero learning when it would not. For ordinary successful work, prefer attaching one optional cognition_settlement to the successful tool call that closes that meaningful outcome; it can carry model-authored learning_signals and exact-memory learning_feedback and Forge settles them mechanically after the primary tool result. Do not attach cognition_settlement to routine micro-steps merely because the field exists. Use rh_work learning_record/learning_feedback when there is no natural successful tool boundary, when an explicit standalone learning action is clearer, or when a selected learning batch exceeds one transport envelope. User corrections, discovered root causes, successful shorter paths, review reversals, stable architecture/product/UX patterns and execution outcomes may all become learning when the model judges them reusable. Distill observations into semantic deltas rather than copying source prose: prefer a Project-specific lesson about how to judge/do the work, and write Workspace guidance only when the model explicitly judges the abstraction genuinely cross-project. Forge never decides that from kind, keywords, failure count, repetition count, confidence threshold, or execution codes. learning_signals kind is descriptive open vocabulary; the per-call array bound is only a transport envelope, not an interaction quota, so submit further learning_record batches when the model selected more reusable knowledge than one envelope carries. Forge may associate/consolidate representations and usage mechanically but must not invent a higher-level lesson or cross-scope generalization. Work-bound Controller rounds keep assistant_context_usage as the exact used/rejected feedback channel. Outside Work, do not manufacture a usage lifecycle merely to count feedback. When recalled memory materially helps or is rejected, use learning_feedback with its exact memory address and model-authored irrelevant/stale/contradicted classification. A new correction/contradiction/other learning signal requires genuinely new reusable semantic knowledge, not merely that an old memory was used.',
|
|
17
18
|
'Minimize mechanically redundant MCP round trips. For an ongoing Forge-controlled task, prefer one rh_status(summary) as the initial controller snapshot: it includes bounded readiness, repository identity, top active Work, active Plans, and pending handoffs. Do not immediately follow it with rh_work(plan_list) or rh_context(list/get) unless the next decision needs details that the snapshot does not contain. Use rh_context(work_id=..., detail_level=summary) for one Work, and request detail/raw or capability hydration only when that extra evidence can change the decision.',
|
|
18
19
|
'Run independent reads, searches, diagnostics, checks, repositories, checkouts, and tasks concurrently by default. Serialize only on a real dependency or Resource Claim conflict, and reuse existing projections, process handles, and check evidence instead of repeating successful observations.',
|
|
19
20
|
'Validation must be proportional to the change: cheap patch-safety checks belong to every coherent edit batch, focused tests run after that batch is stable, and expensive full-suite checks belong at candidate/release or explicitly high-risk boundaries. When a Direct Edit batch is stable, repository_safe_patch_apply may receive explicit check_ids to start revision-bound validation; omit check_ids during intermediate edits. Long checks return managed Processes: continue independent read/review work. Do not call process_wait while useful independent work remains. Use process_get only when a non-blocking observation can change the next decision; when the exact check result becomes a dependency, attach with process_wait (or validation_only with the returned edit-session/validation ids). An attach is transport-bounded: if it returns a running handle, resume useful work and attach again only at a later real dependency boundary, never as periodic polling. Do not perform maintenance or deep runtime diagnosis before ordinary work unless execution is actually blocked.',
|
|
20
|
-
'repository_safe_patch_apply returns bounded edit-session diff evidence for semantic review. Review that evidence directly instead of issuing a mandatory follow-up diff/status call; expand it only when truncated or semantically ambiguous. Its typed operation contract is strict: use type=create only for a path that does not exist, and use write/replace/insert/prepend/append/delete only for existing targets; never reinterpret a missing write target as create. Whole-file source replacement is valid when it is an explicit scoped write against the exact expected file SHA/fingerprint; stale-source and dirty-ownership fences must remain authoritative. Do not bypass those fences with arbitrary shell redirection merely because a deterministic rewrite is convenient. After a bounded successful change, finish the requested delivery directly. Avoid additional investigation whose result cannot change implementation or acceptance, and do not invoke
|
|
21
|
+
'repository_safe_patch_apply returns bounded edit-session diff evidence for semantic review. Review that evidence directly instead of issuing a mandatory follow-up diff/status call; expand it only when truncated or semantically ambiguous. Its typed operation contract is strict: use type=create only for a path that does not exist, and use write/replace/insert/prepend/append/delete only for existing targets; never reinterpret a missing write target as create. Whole-file source replacement is valid when it is an explicit scoped write against the exact expected file SHA/fingerprint; stale-source and dirty-ownership fences must remain authoritative. Do not bypass those fences with arbitrary shell redirection merely because a deterministic rewrite is convenient. After a bounded successful change, finish the requested delivery directly. Avoid additional investigation whose result cannot change implementation or acceptance, and do not invoke redundant atomic compatibility tools merely because they remain registered.',
|
|
21
22
|
].join(' ');
|
|
22
23
|
}
|
|
23
24
|
if (profile === 'orchestrator') {
|