sneakoscope 8.0.2 → 8.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +150 -37
- package/config/skills-hash-ledger.v1.json +1 -1
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/dist/bin/fast-inline.js +55 -27
- package/dist/bin/install.js +6 -32
- package/dist/bin/sks-dispatch.js +1 -1
- package/dist/cli/args.js +0 -2
- package/dist/cli/cli-theme.js +18 -9
- package/dist/cli/command-manifest-lite.js +6 -6
- package/dist/cli/command-registry.js +6 -6
- package/dist/cli/feature-commands.js +9 -7
- package/dist/cli/install-helpers-codex-lb-chain.js +198 -7
- package/dist/cli/install-helpers-codex-lb-config.js +78 -10
- package/dist/cli/install-helpers-install-support.js +9 -6
- package/dist/cli/install-helpers.js +101 -49
- package/dist/cli/install-tool-helpers.js +2 -82
- package/dist/cli/output.js +6 -1
- package/dist/cli/router.js +101 -2
- package/dist/commands/codex-lb.js +119 -19
- package/dist/commands/doctor-profile.js +1 -1
- package/dist/commands/doctor.js +727 -144
- package/dist/commands/mad-sks.js +1 -5
- package/dist/config/skills-manifest.json +4 -2
- package/dist/core/agents/agent-codex-cockpit.js +0 -3
- package/dist/core/agents/agent-effort-policy.js +5 -5
- package/dist/core/agents/agent-janitor.js +0 -20
- package/dist/core/agents/agent-orchestrator.js +9 -56
- package/dist/core/agents/agent-output-validator.js +2 -3
- package/dist/core/agents/agent-patch-schema.js +2 -2
- package/dist/core/agents/agent-proof-evidence.js +0 -65
- package/dist/core/agents/agent-recursion-guard.js +1 -1
- package/dist/core/agents/agent-runner-codex-exec.js +5 -3
- package/dist/core/agents/agent-scheduler.js +327 -85
- package/dist/core/agents/agent-schema.js +1 -1
- package/dist/core/agents/agent-trust-report.js +0 -36
- package/dist/core/agents/agent-worker-pipeline.js +0 -1
- package/dist/core/agents/fast-mode-policy.js +1 -3
- package/dist/core/agents/native-cli-worker-runtime-proof.js +1 -1
- package/dist/core/agents/native-cli-worker-runtime.js +69 -647
- package/dist/core/agents/native-cli-worker.js +6 -7
- package/dist/core/agents/native-worker-backend-router.js +2 -32
- package/dist/core/agents/no-subagent-scaling-policy.js +1 -1
- package/dist/core/agents/parallel-runtime-proof.js +1 -6
- package/dist/core/agents/runtime-proof-summary.js +1 -35
- package/dist/core/architecture-hardening/contracts/contracts.js +193 -0
- package/dist/core/architecture-hardening/migration/migration.js +111 -0
- package/dist/core/architecture-hardening/state/state-service.js +155 -0
- package/dist/core/artifact-schemas.js +0 -3
- package/dist/core/codex/codex-config-guard.js +238 -52
- package/dist/core/codex-adapter.js +5 -3
- package/dist/core/codex-app/auxiliary-oauth-policy.js +36 -0
- package/dist/core/codex-app/catalog-compat/catalog-service.js +104 -0
- package/dist/core/codex-app/child-policy/child-policy.js +35 -0
- package/dist/core/codex-app/codex-app-handoff.js +0 -1
- package/dist/core/codex-app/codex-hook-lifecycle.js +1 -1
- package/dist/core/codex-app/codex-init-deep.js +1 -1
- package/dist/core/codex-app/menubar/app-bundle.js +2 -0
- package/dist/core/codex-app/menubar/constants.js +14 -1
- package/dist/core/codex-app/menubar/global-install.js +288 -0
- package/dist/core/codex-app/menubar/installer.js +79 -14
- package/dist/core/codex-app/menubar/launch-agent.js +267 -45
- package/dist/core/codex-app/menubar/paths.js +3 -0
- package/dist/core/codex-app/menubar/rollback.js +55 -7
- package/dist/core/codex-app/menubar/status.js +75 -4
- package/dist/core/codex-app/provider-child-policy.js +64 -0
- package/dist/core/codex-app/provider-mode.js +91 -0
- package/dist/core/codex-app/provider-operation-stages.js +20 -0
- package/dist/core/codex-app/provider-session-policy.js +85 -0
- package/dist/core/codex-app/session-policy/session-pinning.js +68 -0
- package/dist/core/codex-app.js +3 -2
- package/dist/core/codex-control/codex-0139-image-path-real-probe.js +3 -1
- package/dist/core/codex-control/codex-0139-web-search-probe.js +3 -1
- package/dist/core/codex-control/codex-app-server-runtime-env.js +13 -4
- package/dist/core/codex-control/codex-app-server-v2-client.js +3 -3
- package/dist/core/codex-control/codex-control-proof.js +0 -1
- package/dist/core/codex-control/codex-task-runner.js +1 -4
- package/dist/core/codex-exec-output-schema.js +4 -1
- package/dist/core/codex-lb/codex-lb-env.js +63 -72
- package/dist/core/codex-lb/codex-lb-setup.js +15 -2
- package/dist/core/codex-lb/desktop-bridge/header-policy.js +6 -0
- package/dist/core/codex-lb/desktop-bridge/http-forward.js +48 -6
- package/dist/core/codex-lb/desktop-bridge/security.js +134 -0
- package/dist/core/codex-lb/desktop-bridge/server.js +9 -3
- package/dist/core/codex-lb/desktop-bridge/state.js +26 -6
- package/dist/core/codex-lb/desktop-bridge/types.js +1 -0
- package/dist/core/codex-lb/desktop-center-credentials.js +517 -58
- package/dist/core/codex-lb/desktop-controller.js +177 -56
- package/dist/core/codex-lb/desktop-service.js +179 -40
- package/dist/core/codex-lb/legacy-migration.js +1 -3
- package/dist/core/codex-lb/native-openai-transport/transport.js +68 -0
- package/dist/core/codex-lb/probes/cli-image-tool-probe.js +1 -1
- package/dist/core/codex-lb/provider-routing/provider-router.js +58 -0
- package/dist/core/codex-lb/routing-truth.js +327 -0
- package/dist/core/codex-native/codex-native-feature-broker.js +4 -0
- package/dist/core/codex-native/codex-native-pattern-analysis.js +1 -2
- package/dist/core/codex-native/core-skill-manifest.js +1 -1
- package/dist/core/codex-plugins/codex-plugin-json.js +26 -6
- package/dist/core/codex-plugins/codex-plugin-repair.js +32 -6
- package/dist/core/commands/basic-cli.js +9 -7
- package/dist/core/commands/computer-use-command.js +1 -1
- package/dist/core/commands/image-ux-review-command.js +16 -9
- package/dist/core/commands/install-package-command.js +105 -0
- package/dist/core/commands/intent-normalization/normalizer.js +96 -0
- package/dist/core/commands/mad-sks-command.js +23 -274
- package/dist/core/commands/mad-sks-headless.js +11 -30
- package/dist/core/commands/naruto-command.js +0 -25
- package/dist/core/commands/qa-loop-command.js +104 -22
- package/dist/core/commands/remote-command.js +2 -2
- package/dist/core/commands/research-command.js +10 -5
- package/dist/core/commands/telegram-command.js +407 -0
- package/dist/core/config-adopt/config-adopt-command.js +35 -0
- package/dist/core/config-adopt/config-adopt.js +346 -0
- package/dist/core/config-adopt/index.js +3 -0
- package/dist/core/doctor/command-alias-cleanup.js +4 -1
- package/dist/core/doctor/current-project-guidance-nested.js +37 -6
- package/dist/core/doctor/current-project-guidance.js +15 -9
- package/dist/core/doctor/doctor-dirty-planner.js +1 -4
- package/dist/core/doctor/doctor-readiness-matrix.js +15 -18
- package/dist/core/doctor/retired-managed-residue-private.js +4 -3
- package/dist/core/doctor/retired-managed-residue-runtime.js +2 -2
- package/dist/core/doctor/skill-legacy-surface.js +11 -10
- package/dist/core/doctor/sks-menubar-doctor.js +4 -0
- package/dist/core/evaluation.js +0 -19
- package/dist/core/evidence/v2/evidence-key.js +105 -0
- package/dist/core/feature-fixtures.js +12 -7
- package/dist/core/feature-registry.js +52 -21
- package/dist/core/hooks-runtime/hook-context.js +9 -0
- package/dist/core/hooks-runtime/managed-skill-admission.js +54 -4
- package/dist/core/hooks-runtime/official-subagent-lifecycle.js +69 -52
- package/dist/core/hooks-runtime/stop-finalization.js +226 -0
- package/dist/core/hooks-runtime/stop-repeat-guard.js +21 -2
- package/dist/core/hooks-runtime/subagent-skill-availability-contract.js +2 -2
- package/dist/core/hooks-runtime/subagent-skill-availability-evidence.js +3 -3
- package/dist/core/hooks-runtime/subagent-skill-availability-guards.js +43 -5
- package/dist/core/hooks-runtime/subagent-skill-availability.js +64 -30
- package/dist/core/hooks-runtime/subagent-stop-hook.js +15 -2
- package/dist/core/hooks-runtime.js +179 -212
- package/dist/core/image/reference-evidence/reference-registry.js +145 -0
- package/dist/core/image-ux-review/imagegen-adapter.js +21 -9
- package/dist/core/image-ux-review/reference-policy/reference-policy.js +9 -0
- package/dist/core/imagegen/codex-lb-imagegen-target.js +8 -0
- package/dist/core/imagegen/imagegen-capability.js +59 -2
- package/dist/core/imagegen/require-imagegen.js +2 -2
- package/dist/core/init/skills.js +17 -3
- package/dist/core/init.js +3 -3
- package/dist/core/install/installed-package-smoke.js +23 -5
- package/dist/core/json/canonical.js +9 -0
- package/dist/core/locks/file-lock.js +0 -1
- package/dist/core/loops/loop-continuation-enforcer.js +65 -7
- package/dist/core/loops/loop-decomposer.js +0 -1
- package/dist/core/loops/loop-gate-runner.js +65 -4
- package/dist/core/loops/loop-gate-selector.js +0 -2
- package/dist/core/loops/loop-proof-validation.js +38 -0
- package/dist/core/loops/loop-risk-classifier.js +1 -1
- package/dist/core/loops/loop-runtime.js +14 -2
- package/dist/core/loops/loop-scheduler.js +7 -2
- package/dist/core/loops/loop-worker-runtime.js +0 -15
- package/dist/core/loops/loop-worktree-runtime.js +52 -4
- package/dist/core/managed-assets/managed-assets-manifest.js +14 -14
- package/dist/core/naruto/hardware-capacity-probe.js +9 -6
- package/dist/core/naruto/naruto-active-pool.js +2 -14
- package/dist/core/naruto/naruto-concurrency-governor.js +71 -31
- package/dist/core/naruto/naruto-loop-worker-router.js +0 -2
- package/dist/core/naruto/naruto-verification-dag.js +0 -1
- package/dist/core/naruto/naruto-write-e2e.js +1 -2
- package/dist/core/naruto/resource-pressure-monitor.js +0 -4
- package/dist/core/observability/architecture-hardening/safe-projection.js +65 -0
- package/dist/core/perf/import-graph-budget.js +0 -1
- package/dist/core/perf/release-latency-slo.js +3 -2
- package/dist/core/preflight/parallel-preflight-engine.js +2 -15
- package/dist/core/product-design-app-server.js +13 -1
- package/dist/core/proof/fake-real-proof-policy.js +2 -17
- package/dist/core/proof/route-proof-gate.js +2 -10
- package/dist/core/proof/route-proof-policy.js +1 -1
- package/dist/core/proof/runtime-evidence-policy.js +185 -0
- package/dist/core/proof/runtime-truth-matrix.js +64 -39
- package/dist/core/proof/validation.js +27 -11
- package/dist/core/provider/provider-context.js +18 -2
- package/dist/core/providers/openrouter/openrouter-account.js +3 -2
- package/dist/core/python-tools/python-tool-runner.js +1 -1
- package/dist/core/qa-loop/qa-execution-control.js +57 -0
- package/dist/core/questions.js +1 -1
- package/dist/core/release/extreme-parallel-scheduler.js +0 -3
- package/dist/core/release/gate-manifest.js +3 -7
- package/dist/core/release/gate-pack-manifest.js +3 -7
- package/dist/core/release/package-size-budget.js +2 -2
- package/dist/core/release/physical-release-gates.js +189 -0
- package/dist/core/release/publish-preflight.js +113 -0
- package/dist/core/release/release-gate-affected-selector.js +0 -2
- package/dist/core/release/release-gate-batch-runner.js +1 -1
- package/dist/core/release/release-gate-node.js +0 -1
- package/dist/core/release/release-gate-resource-governor.js +0 -1
- package/dist/core/release/release-pack-receipt.js +5 -8
- package/dist/core/release/release-real-contract.js +0 -6
- package/dist/core/release/resource-class-budget.js +0 -1
- package/dist/core/release/stage-publish.js +178 -36
- package/dist/core/research/research-adversarial-review.js +103 -9
- package/dist/core/research.js +1 -1
- package/dist/core/retention.js +0 -1
- package/dist/core/routes/constants.js +1 -1
- package/dist/core/routes/diagnostic-allowlist.js +0 -1
- package/dist/core/routes/dollar-manifest-lite.js +1 -1
- package/dist/core/routes.js +46 -15
- package/dist/core/runtime/execution-control.js +226 -0
- package/dist/core/runtime/progress-recovery/progress-recovery.js +89 -0
- package/dist/core/runtime/task-profile.js +10 -4
- package/dist/core/runtime/verification-budget.js +10 -1
- package/dist/core/safety/intent-contract/intent-contract.js +94 -0
- package/dist/core/safety/mutation-guard.js +0 -2
- package/dist/core/safety/mutation-ledger.js +0 -2
- package/dist/core/safety/requested-scope-contract.js +0 -0
- package/dist/core/search-visibility/discovery.js +1 -1
- package/dist/core/search-visibility/index.js +12 -0
- package/dist/core/search-visibility/verifier.js +112 -3
- package/dist/core/security/private-credential-file.js +209 -0
- package/dist/core/session/project-namespace.js +0 -5
- package/dist/core/skills/skill-agent-metadata.js +1 -3
- package/dist/core/strategy/adhd-orchestrating-gate.js +0 -1
- package/dist/core/subagents/agent-catalog.js +19 -34
- package/dist/core/subagents/model-policy.js +65 -24
- package/dist/core/subagents/naruto-help-contract.js +8 -8
- package/dist/core/subagents/naruto-host-credentials.js +13 -0
- package/dist/core/subagents/official-subagent-config.js +16 -6
- package/dist/core/subagents/official-subagent-preparation.js +35 -16
- package/dist/core/subagents/official-subagent-prompt.js +7 -7
- package/dist/core/subagents/official-subagent-runner.js +27 -4
- package/dist/core/subagents/role-model-preferences.js +1 -1
- package/dist/core/subagents/thread-budget.js +19 -12
- package/dist/core/subagents/wave-lifecycle.js +18 -6
- package/dist/core/telegram/access.js +58 -0
- package/dist/core/telegram/client.js +157 -0
- package/dist/core/telegram/confirmation.js +37 -0
- package/dist/core/telegram/doctor.js +154 -0
- package/dist/core/telegram/index.js +9 -0
- package/dist/core/telegram/keychain.js +317 -0
- package/dist/core/telegram/liveness.js +118 -0
- package/dist/core/telegram/poller.js +90 -0
- package/dist/core/telegram/redaction.js +15 -0
- package/dist/core/telegram/state-lock.js +416 -0
- package/dist/core/telegram/types.js +1 -0
- package/dist/core/text/strings.js +3 -0
- package/dist/core/triwiki/context-graph/store/evidence-write-lock.js +29 -0
- package/dist/core/triwiki/context-graph/store/fragment-cache.js +24 -0
- package/dist/core/triwiki/context-graph/store/snapshot-store.js +69 -21
- package/dist/core/triwiki/triwiki-gate-impact-map.js +2 -2
- package/dist/core/triwiki/triwiki-module-card.js +1 -2
- package/dist/core/update/installed-cli-resolution.js +170 -0
- package/dist/core/update/update-diagnostics.js +52 -0
- package/dist/core/update/update-migration-state.js +30 -12
- package/dist/core/update/update-operation.js +2 -1
- package/dist/core/update/update-stage-diagnostics.js +38 -0
- package/dist/core/update/update-status.js +2 -9
- package/dist/core/update-check.js +279 -91
- package/dist/core/version.js +1 -1
- package/dist/native/sks-menubar/Sources/AppDelegate.swift +19 -1
- package/dist/native/sks-menubar/Sources/AppIdentity.swift +7 -0
- package/dist/native/sks-menubar/Sources/ControlCenterWindowController.swift +6 -2
- package/dist/native/sks-menubar/Sources/OperationCoordinator.swift +159 -92
- package/dist/native/sks-menubar/Sources/OperationModels.swift +389 -0
- package/dist/native/sks-menubar/Sources/OverviewViewController.swift +57 -0
- package/dist/native/sks-menubar/Sources/ProcessClient.swift +3 -1
- package/dist/native/sks-menubar/Sources/ProvidersConnectTest.swift +115 -0
- package/dist/native/sks-menubar/Sources/ProvidersFastMode.swift +17 -0
- package/dist/native/sks-menubar/Sources/ProvidersMultiProvider.swift +3 -0
- package/dist/native/sks-menubar/Sources/ProvidersOpenRouter.swift +58 -17
- package/dist/native/sks-menubar/Sources/ProvidersReliability.swift +302 -0
- package/dist/native/sks-menubar/Sources/ProvidersRoleModels.swift +5 -0
- package/dist/native/sks-menubar/Sources/ProvidersRoutingTruth.swift +190 -0
- package/dist/native/sks-menubar/Sources/ProvidersViewController.swift +158 -126
- package/dist/native/sks-menubar/Sources/RemoteCodingViewController.swift +462 -26
- package/dist/native/sks-menubar/Sources/SKSKeychainStore.swift +344 -0
- package/dist/native/sks-menubar/Sources/SecureProcessEnvelope.swift +27 -0
- package/dist/native/sks-menubar/Sources/SingletonInstanceGuard.swift +328 -0
- package/dist/native/sks-menubar/Sources/StatusItemController.swift +10 -2
- package/dist/native/sks-menubar/Sources/TelegramPrivateFileStore.swift +498 -0
- package/dist/native/sks-menubar/Sources/TelegramPrivateFileSupport.swift +236 -0
- package/dist/native/sks-menubar/Sources/TelegramProcessGateway.swift +454 -0
- package/dist/native/sks-menubar/Sources/TelegramRuntimeSupport.swift +56 -0
- package/dist/native/sks-menubar/Sources/TelegramStateLock.swift +448 -0
- package/dist/native/sks-menubar/Sources/TelegramSupport.swift +187 -0
- package/dist/native/sks-menubar/Sources/TelegramTransport.swift +499 -0
- package/dist/native/sks-menubar/Sources/main.swift +15 -1
- package/dist/scripts/all-feature-deep-completion-check.js +5 -1
- package/dist/scripts/check-publish-tag.js +56 -0
- package/dist/scripts/codex-lb-fast-mode-truth-check.js +10 -3
- package/dist/scripts/codex-lb-fast-ui-preservation-check.js +12 -3
- package/dist/scripts/codex-lb-gpt56-fast-profile-check.js +4 -2
- package/dist/scripts/codex-native-agent-role-content-check.js +3 -3
- package/dist/scripts/codex-native-gate-lib.js +14 -7
- package/dist/scripts/current-command-surface-check.js +7 -7
- package/dist/scripts/current-surface-update-e2e-check.js +4 -3
- package/dist/scripts/current-upgrade-matrix-check.js +5 -24
- package/dist/scripts/docs-truthfulness-check.js +17 -13
- package/dist/scripts/gate-lib.js +0 -2
- package/dist/scripts/gate-policy-audit-check.js +3 -2
- package/dist/scripts/harness-benchmark-check.js +1 -1
- package/dist/scripts/init-deep-backup-retention-check.js +1 -1
- package/dist/scripts/lib/codex-sdk-gate-lib.js +1 -2
- package/dist/scripts/loop-directive-check-lib.js +28 -38
- package/dist/scripts/mad-sks-app-ui-no-mutation-check.js +14 -180
- package/dist/scripts/mad-sks-launch-sql-plane-boundary-check.js +2 -11
- package/dist/scripts/official-subagent-workflow-check.js +1 -1
- package/dist/scripts/packlist-performance-check.js +1 -2
- package/dist/scripts/prepublish-release-check-or-fast.js +32 -0
- package/dist/scripts/publish-preflight.js +12 -0
- package/dist/scripts/release-affected-selector-check.js +2 -2
- package/dist/scripts/release-gate-batch-runner-check.js +2 -2
- package/dist/scripts/release-metadata-check.js +8 -12
- package/dist/scripts/release-real-check.js +2 -54
- package/dist/scripts/runtime-domain-gate-lib.js +2 -96
- package/dist/scripts/runtime-proof-summary-check.js +2 -6
- package/dist/scripts/search-visibility-gate-lib.js +0 -1
- package/dist/scripts/sks-cli-gate-lib.js +1 -1
- package/dist/scripts/typed-routing-gate-lib.js +7 -59
- package/docs/demo.tape +1 -1
- package/infra-harness-gates.json +1 -1456
- package/package.json +10 -7
- package/release-gates.v2.json +0 -1
- package/schemas/agents/parallel-runtime-proof.schema.json +0 -2
- package/schemas/codex/agent-result.schema.json +0 -6
- package/schemas/naruto/naruto-concurrency-governor.schema.json +1 -3
- package/schemas/release/release-gate-node.schema.json +1 -1
- package/dist/commands/zellij-lane.js +0 -22
- package/dist/commands/zellij-monitor-pane.js +0 -26
- package/dist/commands/zellij-slot-column-anchor.js +0 -22
- package/dist/commands/zellij-slot-pane.js +0 -80
- package/dist/commands/zellij-viewport-pane.js +0 -57
- package/dist/commands/zellij.js +0 -422
- package/dist/core/agents/agent-runner-zellij.js +0 -164
- package/dist/core/agents/agent-slot-pane-binding-proof.js +0 -96
- package/dist/core/agents/parallel-write-fixture.js +0 -305
- package/dist/core/agents/worker-pane-communication-contract.js +0 -100
- package/dist/core/agents/zellij-lane-supervisor.js +0 -428
- package/dist/core/agents/zellij-right-lane-cockpit.js +0 -66
- package/dist/core/doctor/doctor-zellij-repair.js +0 -40
- package/dist/core/ops/upgrade-migration-fixtures.js +0 -119
- package/dist/core/proof/route-finalizer-fixtures.js +0 -21
- package/dist/core/zellij/homebrew-policy.js +0 -43
- package/dist/core/zellij/zellij-capability.js +0 -126
- package/dist/core/zellij/zellij-clipboard-config.js +0 -52
- package/dist/core/zellij/zellij-command.js +0 -149
- package/dist/core/zellij/zellij-fake-adapter.js +0 -186
- package/dist/core/zellij/zellij-lane-renderer.js +0 -706
- package/dist/core/zellij/zellij-lane-runtime.js +0 -189
- package/dist/core/zellij/zellij-launcher.js +0 -268
- package/dist/core/zellij/zellij-layout-builder.js +0 -191
- package/dist/core/zellij/zellij-monitor-renderer.js +0 -52
- package/dist/core/zellij/zellij-official-subagent-activity.js +0 -526
- package/dist/core/zellij/zellij-official-subagent-telemetry.js +0 -258
- package/dist/core/zellij/zellij-pane-proof.js +0 -226
- package/dist/core/zellij/zellij-right-column-manager.js +0 -308
- package/dist/core/zellij/zellij-screen-proof.js +0 -120
- package/dist/core/zellij/zellij-self-heal-types.js +0 -44
- package/dist/core/zellij/zellij-self-heal.js +0 -408
- package/dist/core/zellij/zellij-slot-column-anchor.js +0 -304
- package/dist/core/zellij/zellij-slot-pane-renderer.js +0 -521
- package/dist/core/zellij/zellij-slot-telemetry.js +0 -384
- package/dist/core/zellij/zellij-theme.js +0 -66
- package/dist/core/zellij/zellij-ui-mode.js +0 -34
- package/dist/core/zellij/zellij-update.js +0 -348
- package/dist/core/zellij/zellij-viewport-binder.js +0 -61
- package/dist/core/zellij/zellij-worker-pane-manager.js +0 -881
- package/dist/core/zellij/zellij-worker-pane-summary.js +0 -64
- package/dist/native/sks-menubar/Tests/AppRuntimeTestSupport.swift +0 -26
- package/dist/native/sks-menubar/Tests/OperationCoordinatorTests.swift +0 -174
- package/dist/native/sks-menubar/Tests/ProcessClientTests.swift +0 -20
- package/dist/native/sks-menubar/Tests/ProvidersViewControllerTests.swift +0 -142
- package/dist/scripts/zellij-pane-proof-check.js +0 -88
- package/dist/scripts/zellij-real-session-cleanup-check.js +0 -139
- package/dist/scripts/zellij-real-session-launch-check.js +0 -126
- package/dist/scripts/zellij-screen-proof-check.js +0 -43
- package/schemas/zellij/zellij-right-column-state.schema.json +0 -40
- package/schemas/zellij/zellij-slot-telemetry.schema.json +0 -89
- package/schemas/zellij/zellij-worker-pane.schema.json +0 -53
- package/scripts/build-clean-atomic.mjs +0 -323
|
@@ -14,7 +14,6 @@ export const MUTATION_KINDS = [
|
|
|
14
14
|
'process_kill',
|
|
15
15
|
'codex_app_flag_change',
|
|
16
16
|
'codex_lb_auth_change',
|
|
17
|
-
'zellij_install',
|
|
18
17
|
'database_write',
|
|
19
18
|
'skill_snapshot_promotion'
|
|
20
19
|
];
|
|
@@ -30,7 +29,6 @@ const KIND_TO_SCOPE = {
|
|
|
30
29
|
process_kill: 'codex_app_process',
|
|
31
30
|
codex_app_flag_change: 'global_codex_config',
|
|
32
31
|
codex_lb_auth_change: 'codex_lb_auth',
|
|
33
|
-
zellij_install: 'zellij_install',
|
|
34
32
|
database_write: 'project_files',
|
|
35
33
|
skill_snapshot_promotion: 'skill_snapshot_promotion'
|
|
36
34
|
};
|
|
Binary file
|
|
@@ -79,7 +79,7 @@ export async function discoverSiteInventory(ctx, detected) {
|
|
|
79
79
|
locale_candidates: discoverLocales(files, htmlFiles),
|
|
80
80
|
metadata_helpers: files.filter((file) => /(seo|metadata|schema|json-ld|structured-data|canonical|sitemap|robots)/i.test(file)).slice(0, 100),
|
|
81
81
|
structured_data_sources: files.filter((file) => /(schema|json-ld|structured-data|ld-json)/i.test(file)).slice(0, 100),
|
|
82
|
-
live_url_checked:
|
|
82
|
+
live_url_checked: false,
|
|
83
83
|
browser_checked: false,
|
|
84
84
|
generated_at: new Date().toISOString(),
|
|
85
85
|
};
|
|
@@ -273,6 +273,18 @@ async function verifyMarketingMutationFlow(mode, mission, plan, options) {
|
|
|
273
273
|
http_verified: false,
|
|
274
274
|
browser_verified: false,
|
|
275
275
|
production_verified: false,
|
|
276
|
+
http_evidence: {
|
|
277
|
+
attempted: false,
|
|
278
|
+
verified: false,
|
|
279
|
+
requested_url: options.url,
|
|
280
|
+
final_url: null,
|
|
281
|
+
status_code: null,
|
|
282
|
+
content_type: null,
|
|
283
|
+
content_bytes: null,
|
|
284
|
+
content_sha256: null,
|
|
285
|
+
observed_at: null,
|
|
286
|
+
error: 'marketing_flow_does_not_perform_production_http_verification',
|
|
287
|
+
},
|
|
276
288
|
measured_outcome: 'pending',
|
|
277
289
|
checked_artifacts: requiredStatus.map((item) => ({ path: item.path, ok: item.present, message: item.present ? 'present' : 'missing' })),
|
|
278
290
|
blockers,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
2
3
|
import { exists } from '../fsx.js';
|
|
3
4
|
import { SEARCH_VISIBILITY_DIR, routeForMode } from './mission.js';
|
|
4
5
|
const COMMON_REQUIRED = [
|
|
@@ -9,7 +10,7 @@ const COMMON_REQUIRED = [
|
|
|
9
10
|
'robots-policy.json',
|
|
10
11
|
'structured-data-ledger.json',
|
|
11
12
|
];
|
|
12
|
-
export async function verifySearchVisibility(ctx, inventory, mission) {
|
|
13
|
+
export async function verifySearchVisibility(ctx, inventory, mission, dependencies = {}) {
|
|
13
14
|
const route = routeForMode(ctx.mode);
|
|
14
15
|
const required = [
|
|
15
16
|
...COMMON_REQUIRED,
|
|
@@ -23,9 +24,17 @@ export async function verifySearchVisibility(ctx, inventory, mission) {
|
|
|
23
24
|
}))
|
|
24
25
|
: [];
|
|
25
26
|
const blockers = checked.filter((item) => !item.ok).map((item) => `missing_artifact:${item.path}`);
|
|
26
|
-
const
|
|
27
|
+
const httpEvidence = await verifyProductionHttp(ctx, dependencies);
|
|
28
|
+
const productionVerified = httpEvidence.verified === true
|
|
29
|
+
&& httpEvidence.status_code !== null
|
|
30
|
+
&& httpEvidence.status_code >= 200
|
|
31
|
+
&& httpEvidence.status_code < 300
|
|
32
|
+
&& Boolean(httpEvidence.content_type)
|
|
33
|
+
&& Boolean(httpEvidence.content_sha256)
|
|
34
|
+
&& Boolean(httpEvidence.observed_at);
|
|
27
35
|
const unverified = [
|
|
28
|
-
...(
|
|
36
|
+
...(productionVerified ? [] : ['production_http_not_verified']),
|
|
37
|
+
...(httpEvidence.error ? [`production_http_verification_failed:${httpEvidence.error}`] : []),
|
|
29
38
|
...(ctx.framework === 'unsupported' ? ['framework_specific_mutation_not_verified'] : []),
|
|
30
39
|
...(ctx.mode === 'geo' ? ['external_ai_answer_observation_not_verified', 'measured_outcome_pending'] : ['search_ranking_or_traffic_outcome_not_measured']),
|
|
31
40
|
...(!ctx.strict ? ['strict_mode_not_requested'] : []),
|
|
@@ -46,12 +55,112 @@ export async function verifySearchVisibility(ctx, inventory, mission) {
|
|
|
46
55
|
http_verified: productionVerified,
|
|
47
56
|
browser_verified: false,
|
|
48
57
|
production_verified: productionVerified,
|
|
58
|
+
http_evidence: httpEvidence,
|
|
49
59
|
measured_outcome: 'pending',
|
|
50
60
|
checked_artifacts: checked,
|
|
51
61
|
blockers,
|
|
52
62
|
unverified,
|
|
53
63
|
};
|
|
54
64
|
}
|
|
65
|
+
async function verifyProductionHttp(ctx, dependencies) {
|
|
66
|
+
const requestedUrl = normalizeHttpUrl(ctx.origin);
|
|
67
|
+
if (ctx.offline || !requestedUrl) {
|
|
68
|
+
return emptyHttpEvidence(ctx.origin, ctx.offline ? null : 'invalid_or_missing_http_origin');
|
|
69
|
+
}
|
|
70
|
+
const fetchImpl = dependencies.fetch || globalThis.fetch;
|
|
71
|
+
if (typeof fetchImpl !== 'function')
|
|
72
|
+
return emptyHttpEvidence(requestedUrl, 'fetch_unavailable', true);
|
|
73
|
+
const observedAt = (dependencies.now || (() => new Date()))().toISOString();
|
|
74
|
+
const controller = new AbortController();
|
|
75
|
+
const timeout = setTimeout(() => controller.abort(), dependencies.timeoutMs ?? 10_000);
|
|
76
|
+
try {
|
|
77
|
+
const response = await fetchImpl(requestedUrl, {
|
|
78
|
+
method: 'GET',
|
|
79
|
+
redirect: 'follow',
|
|
80
|
+
signal: controller.signal,
|
|
81
|
+
headers: {
|
|
82
|
+
accept: 'text/html,application/xhtml+xml;q=0.9',
|
|
83
|
+
'user-agent': 'Sneakoscope-Search-Visibility-Verifier/8',
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
const body = await response.text();
|
|
87
|
+
const contentType = normalizedContentType(response.headers.get('content-type'));
|
|
88
|
+
const bytes = Buffer.byteLength(body, 'utf8');
|
|
89
|
+
const contentSha256 = bytes > 0 ? createHash('sha256').update(body).digest('hex') : null;
|
|
90
|
+
const error = httpVerificationError(response.status, contentType, body);
|
|
91
|
+
return {
|
|
92
|
+
attempted: true,
|
|
93
|
+
verified: error === null,
|
|
94
|
+
requested_url: requestedUrl,
|
|
95
|
+
final_url: response.url || requestedUrl,
|
|
96
|
+
status_code: response.status,
|
|
97
|
+
content_type: contentType,
|
|
98
|
+
content_bytes: bytes,
|
|
99
|
+
content_sha256: contentSha256,
|
|
100
|
+
observed_at: observedAt,
|
|
101
|
+
error,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
return {
|
|
106
|
+
...emptyHttpEvidence(requestedUrl, error instanceof Error && error.name === 'AbortError' ? 'request_timeout' : 'request_failed', true),
|
|
107
|
+
observed_at: observedAt,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
finally {
|
|
111
|
+
clearTimeout(timeout);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function normalizeHttpUrl(origin) {
|
|
115
|
+
if (!origin)
|
|
116
|
+
return null;
|
|
117
|
+
try {
|
|
118
|
+
const url = new URL(origin);
|
|
119
|
+
if (url.protocol !== 'http:' && url.protocol !== 'https:')
|
|
120
|
+
return null;
|
|
121
|
+
return url.href;
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
function normalizedContentType(value) {
|
|
128
|
+
const normalized = String(value || '').split(';', 1)[0]?.trim().toLowerCase() || '';
|
|
129
|
+
return normalized || null;
|
|
130
|
+
}
|
|
131
|
+
function httpVerificationError(status, contentType, body) {
|
|
132
|
+
if (status < 200 || status >= 300)
|
|
133
|
+
return `http_status_${status}`;
|
|
134
|
+
if (contentType !== 'text/html' && contentType !== 'application/xhtml+xml')
|
|
135
|
+
return 'non_html_content_type';
|
|
136
|
+
if (!body.trim())
|
|
137
|
+
return 'empty_response_body';
|
|
138
|
+
if (!/(?:<!doctype\s+html|<html\b)/i.test(body))
|
|
139
|
+
return 'html_document_marker_missing';
|
|
140
|
+
const visible = body
|
|
141
|
+
.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi, ' ')
|
|
142
|
+
.replace(/<style\b[^>]*>[\s\S]*?<\/style>/gi, ' ')
|
|
143
|
+
.replace(/<[^>]+>/g, ' ')
|
|
144
|
+
.replace(/\s+/g, ' ')
|
|
145
|
+
.trim();
|
|
146
|
+
if (visible.length < 20)
|
|
147
|
+
return 'insufficient_html_content';
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
function emptyHttpEvidence(requestedUrl, error, attempted = false) {
|
|
151
|
+
return {
|
|
152
|
+
attempted,
|
|
153
|
+
verified: false,
|
|
154
|
+
requested_url: requestedUrl,
|
|
155
|
+
final_url: null,
|
|
156
|
+
status_code: null,
|
|
157
|
+
content_type: null,
|
|
158
|
+
content_bytes: null,
|
|
159
|
+
content_sha256: null,
|
|
160
|
+
observed_at: null,
|
|
161
|
+
error,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
55
164
|
export function expectedArtifactPath(missionId, artifact) {
|
|
56
165
|
if (artifact.endsWith('-gate.json') || artifact === 'completion-proof.json')
|
|
57
166
|
return `.sneakoscope/missions/${missionId}/${artifact}`;
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import fsp from 'node:fs/promises';
|
|
2
|
+
import { constants as fsConstants } from 'node:fs';
|
|
3
|
+
import { createHash, randomBytes } from 'node:crypto';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { assertTestHomeWriteAllowed } from '../fsx.js';
|
|
6
|
+
import { ensureConfinedDirectory, inspectConfinedPath, isLexicallyConfined } from '../managed-path-safety.js';
|
|
7
|
+
export class PrivateCredentialFileError extends Error {
|
|
8
|
+
code;
|
|
9
|
+
file;
|
|
10
|
+
label;
|
|
11
|
+
constructor(code, file, label) {
|
|
12
|
+
super(`${label}_${code}:${file}`);
|
|
13
|
+
this.name = 'PrivateCredentialFileError';
|
|
14
|
+
this.code = code;
|
|
15
|
+
this.file = file;
|
|
16
|
+
this.label = label;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export async function readPrivateCredentialFile(boundary, file, label, opts = {}) {
|
|
20
|
+
if (opts.maxBytes !== undefined && (!Number.isSafeInteger(opts.maxBytes) || opts.maxBytes < 0)) {
|
|
21
|
+
throw new RangeError('maxBytes must be a non-negative safe integer');
|
|
22
|
+
}
|
|
23
|
+
if (!isLexicallyConfined(boundary, file))
|
|
24
|
+
throw new PrivateCredentialFileError('outside_boundary', file, label);
|
|
25
|
+
const inspected = await inspectConfinedPath(boundary, file);
|
|
26
|
+
if (!inspected.exists)
|
|
27
|
+
throw new PrivateCredentialFileError('missing', file, label);
|
|
28
|
+
if (inspected.leafSymlink || !inspected.stat?.isFile()) {
|
|
29
|
+
throw new PrivateCredentialFileError('not_regular', file, label);
|
|
30
|
+
}
|
|
31
|
+
if ((inspected.stat.mode & 0o777) !== 0o600) {
|
|
32
|
+
throw new PrivateCredentialFileError('mode_not_0600', file, label);
|
|
33
|
+
}
|
|
34
|
+
const expectedUid = typeof process.getuid === 'function' ? process.getuid() : null;
|
|
35
|
+
if (expectedUid !== null && inspected.stat.uid !== expectedUid) {
|
|
36
|
+
throw new PrivateCredentialFileError('owner_mismatch', file, label);
|
|
37
|
+
}
|
|
38
|
+
let handle = null;
|
|
39
|
+
try {
|
|
40
|
+
handle = await fsp.open(file, fsConstants.O_RDONLY | fsConstants.O_NOFOLLOW);
|
|
41
|
+
const before = await handle.stat();
|
|
42
|
+
if (!before.isFile()
|
|
43
|
+
|| before.dev !== inspected.stat.dev
|
|
44
|
+
|| before.ino !== inspected.stat.ino
|
|
45
|
+
|| (before.mode & 0o777) !== 0o600
|
|
46
|
+
|| (expectedUid !== null && before.uid !== expectedUid)) {
|
|
47
|
+
throw new PrivateCredentialFileError('identity_mismatch', file, label);
|
|
48
|
+
}
|
|
49
|
+
if (opts.maxBytes !== undefined && before.size > opts.maxBytes) {
|
|
50
|
+
throw new PrivateCredentialFileError('too_large', file, label);
|
|
51
|
+
}
|
|
52
|
+
const bytes = opts.maxBytes === undefined
|
|
53
|
+
? await handle.readFile()
|
|
54
|
+
: await readBounded(handle, opts.maxBytes, file, label);
|
|
55
|
+
const after = await handle.stat();
|
|
56
|
+
const pathAfter = await inspectConfinedPath(boundary, file);
|
|
57
|
+
if (!pathAfter.exists
|
|
58
|
+
|| pathAfter.leafSymlink
|
|
59
|
+
|| !pathAfter.stat?.isFile()
|
|
60
|
+
|| (after.mode & 0o777) !== 0o600
|
|
61
|
+
|| (pathAfter.stat.mode & 0o777) !== 0o600
|
|
62
|
+
|| (expectedUid !== null && (after.uid !== expectedUid || pathAfter.stat.uid !== expectedUid))
|
|
63
|
+
|| before.dev !== after.dev
|
|
64
|
+
|| before.ino !== after.ino
|
|
65
|
+
|| before.size !== after.size
|
|
66
|
+
|| before.mtimeMs !== after.mtimeMs
|
|
67
|
+
|| after.dev !== pathAfter.stat.dev
|
|
68
|
+
|| after.ino !== pathAfter.stat.ino) {
|
|
69
|
+
throw new PrivateCredentialFileError('changed_during_verification', file, label);
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
bytes,
|
|
73
|
+
sha256: createHash('sha256').update(bytes).digest('hex')
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
finally {
|
|
77
|
+
await handle?.close().catch(() => undefined);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async function readBounded(handle, maxBytes, file, label) {
|
|
81
|
+
const chunks = [];
|
|
82
|
+
let total = 0;
|
|
83
|
+
for (;;) {
|
|
84
|
+
const chunk = Buffer.allocUnsafe(Math.min(16 * 1024, maxBytes + 1 - total));
|
|
85
|
+
const { bytesRead } = await handle.read(chunk, 0, chunk.length, null);
|
|
86
|
+
if (bytesRead === 0)
|
|
87
|
+
break;
|
|
88
|
+
total += bytesRead;
|
|
89
|
+
if (total > maxBytes)
|
|
90
|
+
throw new PrivateCredentialFileError('too_large', file, label);
|
|
91
|
+
chunks.push(chunk.subarray(0, bytesRead));
|
|
92
|
+
}
|
|
93
|
+
return Buffer.concat(chunks, total);
|
|
94
|
+
}
|
|
95
|
+
export async function hardenPrivateCredentialFileMode(boundary, file, label) {
|
|
96
|
+
if (!isLexicallyConfined(boundary, file))
|
|
97
|
+
throw new PrivateCredentialFileError('outside_boundary', file, label);
|
|
98
|
+
const inspected = await inspectConfinedPath(boundary, file);
|
|
99
|
+
if (!inspected.exists)
|
|
100
|
+
throw new PrivateCredentialFileError('missing', file, label);
|
|
101
|
+
if (inspected.leafSymlink || !inspected.stat?.isFile()) {
|
|
102
|
+
throw new PrivateCredentialFileError('not_regular', file, label);
|
|
103
|
+
}
|
|
104
|
+
const expectedUid = typeof process.getuid === 'function' ? process.getuid() : null;
|
|
105
|
+
if (expectedUid !== null && inspected.stat.uid !== expectedUid) {
|
|
106
|
+
throw new PrivateCredentialFileError('owner_mismatch', file, label);
|
|
107
|
+
}
|
|
108
|
+
let handle = null;
|
|
109
|
+
try {
|
|
110
|
+
handle = await fsp.open(file, fsConstants.O_RDONLY | fsConstants.O_NOFOLLOW);
|
|
111
|
+
const before = await handle.stat();
|
|
112
|
+
if (!before.isFile()
|
|
113
|
+
|| before.dev !== inspected.stat.dev
|
|
114
|
+
|| before.ino !== inspected.stat.ino
|
|
115
|
+
|| (expectedUid !== null && before.uid !== expectedUid)) {
|
|
116
|
+
throw new PrivateCredentialFileError('identity_mismatch', file, label);
|
|
117
|
+
}
|
|
118
|
+
await handle.chmod(0o600);
|
|
119
|
+
const after = await handle.stat();
|
|
120
|
+
if ((after.mode & 0o777) !== 0o600 || after.dev !== before.dev || after.ino !== before.ino) {
|
|
121
|
+
throw new PrivateCredentialFileError('identity_mismatch', file, label);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
await handle?.close().catch(() => undefined);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
export async function writePrivateTextAtomic(boundary, file, text, label) {
|
|
129
|
+
if (!isLexicallyConfined(boundary, file))
|
|
130
|
+
throw new PrivateCredentialFileError('outside_boundary', file, label);
|
|
131
|
+
assertTestHomeWriteAllowed(file);
|
|
132
|
+
await ensureConfinedDirectory(boundary, path.dirname(file));
|
|
133
|
+
const before = await inspectConfinedPath(boundary, file);
|
|
134
|
+
if (before.exists && (before.leafSymlink || !before.stat?.isFile())) {
|
|
135
|
+
throw new PrivateCredentialFileError('not_regular', file, label);
|
|
136
|
+
}
|
|
137
|
+
if (before.stat && (before.stat.mode & 0o777) !== 0o600) {
|
|
138
|
+
throw new PrivateCredentialFileError('mode_not_0600', file, label);
|
|
139
|
+
}
|
|
140
|
+
const expectedUid = typeof process.getuid === 'function' ? process.getuid() : null;
|
|
141
|
+
if (before.stat && expectedUid !== null && before.stat.uid !== expectedUid) {
|
|
142
|
+
throw new PrivateCredentialFileError('owner_mismatch', file, label);
|
|
143
|
+
}
|
|
144
|
+
const temp = path.join(path.dirname(file), `.${path.basename(file)}.${process.pid}.${randomBytes(8).toString('hex')}.tmp`);
|
|
145
|
+
let handle = null;
|
|
146
|
+
try {
|
|
147
|
+
handle = await fsp.open(temp, fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL | fsConstants.O_NOFOLLOW, 0o600);
|
|
148
|
+
await handle.chmod(0o600);
|
|
149
|
+
const tempStat = await handle.stat();
|
|
150
|
+
if (!tempStat.isFile()
|
|
151
|
+
|| (tempStat.mode & 0o777) !== 0o600
|
|
152
|
+
|| (expectedUid !== null && tempStat.uid !== expectedUid)) {
|
|
153
|
+
throw new PrivateCredentialFileError('identity_mismatch', temp, label);
|
|
154
|
+
}
|
|
155
|
+
await handle.writeFile(text, 'utf8');
|
|
156
|
+
await handle.sync();
|
|
157
|
+
await handle.close();
|
|
158
|
+
handle = null;
|
|
159
|
+
const current = await inspectConfinedPath(boundary, file);
|
|
160
|
+
const unchanged = before.exists === current.exists
|
|
161
|
+
&& (!before.exists || (!current.leafSymlink
|
|
162
|
+
&& current.stat?.isFile() === true
|
|
163
|
+
&& before.stat?.dev === current.stat.dev
|
|
164
|
+
&& before.stat?.ino === current.stat.ino));
|
|
165
|
+
if (!unchanged)
|
|
166
|
+
throw new PrivateCredentialFileError('changed_during_verification', file, label);
|
|
167
|
+
await fsp.rename(temp, file);
|
|
168
|
+
const parentHandle = await fsp.open(path.dirname(file), fsConstants.O_RDONLY);
|
|
169
|
+
try {
|
|
170
|
+
await parentHandle.sync();
|
|
171
|
+
}
|
|
172
|
+
finally {
|
|
173
|
+
await parentHandle.close();
|
|
174
|
+
}
|
|
175
|
+
await readPrivateCredentialFile(boundary, file, label);
|
|
176
|
+
}
|
|
177
|
+
finally {
|
|
178
|
+
await handle?.close().catch(() => undefined);
|
|
179
|
+
await fsp.rm(temp, { force: true }).catch(() => undefined);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
export async function createPrivateTextExclusive(boundary, file, text, label, opts = {}) {
|
|
183
|
+
if (!isLexicallyConfined(boundary, file))
|
|
184
|
+
throw new PrivateCredentialFileError('outside_boundary', file, label);
|
|
185
|
+
assertTestHomeWriteAllowed(file);
|
|
186
|
+
await ensureConfinedDirectory(boundary, path.dirname(file));
|
|
187
|
+
const temp = path.join(path.dirname(file), `.${path.basename(file)}.${process.pid}.${randomBytes(8).toString('hex')}.claim`);
|
|
188
|
+
let handle = null;
|
|
189
|
+
try {
|
|
190
|
+
handle = await fsp.open(temp, fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL | fsConstants.O_NOFOLLOW, 0o600);
|
|
191
|
+
await handle.writeFile(text, 'utf8');
|
|
192
|
+
await handle.sync();
|
|
193
|
+
await handle.close();
|
|
194
|
+
handle = null;
|
|
195
|
+
await opts.beforePublish?.(temp);
|
|
196
|
+
await fsp.link(temp, file);
|
|
197
|
+
await readPrivateCredentialFile(boundary, file, label);
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
if (error?.code === 'EEXIST')
|
|
202
|
+
return false;
|
|
203
|
+
throw error;
|
|
204
|
+
}
|
|
205
|
+
finally {
|
|
206
|
+
await handle?.close().catch(() => undefined);
|
|
207
|
+
await fsp.rm(temp, { force: true }).catch(() => undefined);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
@@ -28,7 +28,6 @@ export async function buildProjectNamespace(input = {}) {
|
|
|
28
28
|
mission_id: missionId,
|
|
29
29
|
mission_namespace_id: missionNamespaceId,
|
|
30
30
|
orchestrator_id: orchestratorId,
|
|
31
|
-
zellij_prefix: namespaceForPaths,
|
|
32
31
|
temp_dir: path.join(os.tmpdir(), namespaceForPaths),
|
|
33
32
|
lock_dir: path.join(projectRoot, '.sneakoscope', 'locks', rootHash),
|
|
34
33
|
artifact_dir: missionId
|
|
@@ -40,10 +39,6 @@ export function namespacedAgentSessionId(input) {
|
|
|
40
39
|
const suffix = input.index === undefined ? '' : `-${String(input.index).padStart(2, '0')}`;
|
|
41
40
|
return `${input.agentId}-${input.missionId}-${input.rootHash}${suffix}`;
|
|
42
41
|
}
|
|
43
|
-
export function namespacedZellijSessionName(namespace, label = 'work') {
|
|
44
|
-
const raw = `${namespace.zellij_prefix}-${label}`;
|
|
45
|
-
return raw.replace(/[^A-Za-z0-9_.:-]+/g, '-').slice(0, 80);
|
|
46
|
-
}
|
|
47
42
|
export async function writeProjectNamespaceArtifact(artifactRoot, namespace) {
|
|
48
43
|
const file = path.join(artifactRoot, 'project-session-namespace.json');
|
|
49
44
|
await writeJsonAtomic(file, namespace);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { escapeRegExp } from '../text/regex.js';
|
|
1
2
|
const OFFICIAL_TOP_LEVEL_KEYS = new Set(['interface', 'policy', 'dependencies']);
|
|
2
3
|
const OFFICIAL_INTERFACE_KEYS = new Set([
|
|
3
4
|
'display_name',
|
|
@@ -343,6 +344,3 @@ function parseYamlScalar(rawValue) {
|
|
|
343
344
|
function yamlString(value) {
|
|
344
345
|
return JSON.stringify(value);
|
|
345
346
|
}
|
|
346
|
-
function escapeRegExp(value) {
|
|
347
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
348
|
-
}
|
|
@@ -79,7 +79,6 @@ export function buildDopamineOrchestrationArtifacts(gate) {
|
|
|
79
79
|
schema: MICRO_WIN_TASK_BOARD_SCHEMA,
|
|
80
80
|
generated_at: gate.generated_at,
|
|
81
81
|
summary_available: true,
|
|
82
|
-
zellij_summary_available: true,
|
|
83
82
|
items: gate.micro_wins.map((task) => ({
|
|
84
83
|
id: task.id,
|
|
85
84
|
title: task.title,
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import { MANAGED_OFFICIAL_SUBAGENT_ROLES, managedOfficialSubagentRoleByName } from '../managed-assets/managed-assets-manifest.js';
|
|
2
|
-
import { decideNarutoConcurrency } from '../naruto/naruto-concurrency-governor.js';
|
|
3
2
|
import { decideSubagentModel } from './model-policy.js';
|
|
4
|
-
import {
|
|
3
|
+
import { HARD_NARUTO_MAX_THREADS } from './thread-budget.js';
|
|
5
4
|
import { escapeRegExp } from '../text/regex.js';
|
|
6
5
|
export const DEFAULT_AUTOMATIC_SUBAGENT_COUNT = 4;
|
|
7
6
|
export const PARALLEL_AUTOMATIC_SUBAGENT_COUNT = 6;
|
|
8
7
|
export const LARGE_SCALE_AUTOMATIC_SUBAGENT_COUNT = 8;
|
|
9
|
-
export const MAX_AUTOMATIC_SUBAGENT_COUNT =
|
|
8
|
+
export const MAX_AUTOMATIC_SUBAGENT_COUNT = HARD_NARUTO_MAX_THREADS;
|
|
10
9
|
export const MAX_AUTOMATIC_REVIEWER_COUNT = 2;
|
|
11
10
|
export const MAX_CRITICAL_AUTOMATIC_REVIEWER_COUNT = 3;
|
|
12
11
|
export const MASS_PARALLEL_AUTOMATIC_SUBAGENT_COUNT = 16;
|
|
13
|
-
export const MAX_MASS_AUTOMATIC_SUBAGENT_COUNT =
|
|
14
|
-
export const MAX_ON_DEMAND_SUBAGENT_ROLE_COUNT =
|
|
12
|
+
export const MAX_MASS_AUTOMATIC_SUBAGENT_COUNT = HARD_NARUTO_MAX_THREADS;
|
|
13
|
+
export const MAX_ON_DEMAND_SUBAGENT_ROLE_COUNT = 25;
|
|
15
14
|
export function officialSubagentRoleCatalog() {
|
|
16
15
|
return MANAGED_OFFICIAL_SUBAGENT_ROLES.map(roleSummary);
|
|
17
16
|
}
|
|
@@ -74,7 +73,7 @@ export function recommendOfficialSubagentRoles(input = {}) {
|
|
|
74
73
|
if (ranked.length)
|
|
75
74
|
return unique(ranked).slice(0, limit);
|
|
76
75
|
const lane = decideSubagentModel({ description: text }).policy;
|
|
77
|
-
if (lane === '
|
|
76
|
+
if (lane === 'terra_max_context_tools')
|
|
78
77
|
return ['explorer'];
|
|
79
78
|
if (lane === 'luna_max_mechanical' && input.readOnly !== true)
|
|
80
79
|
return ['worker'];
|
|
@@ -92,9 +91,9 @@ export function officialSubagentFanoutPolicy(input = {}) {
|
|
|
92
91
|
? 'operator'
|
|
93
92
|
: 'automatic';
|
|
94
93
|
const explicit = countSource !== 'automatic';
|
|
95
|
-
const explicitRequested =
|
|
96
|
-
?
|
|
97
|
-
:
|
|
94
|
+
const explicitRequested = input.requestedSubagents === undefined || input.requestedSubagents === null
|
|
95
|
+
? DEFAULT_AUTOMATIC_SUBAGENT_COUNT
|
|
96
|
+
: boundedThreadCount(input.requestedSubagents, 'requested_subagents');
|
|
98
97
|
const automatic = automaticSubagentFanout({
|
|
99
98
|
...(input.taskProfile === undefined ? {} : { taskProfile: input.taskProfile }),
|
|
100
99
|
...(input.goal === undefined ? {} : { goal: input.goal }),
|
|
@@ -146,13 +145,15 @@ function automaticSubagentFanout(input) {
|
|
|
146
145
|
const massLane = decideSubagentModel({ description: text }).policy;
|
|
147
146
|
const massParallel = MASS_PARALLEL_WORK_RE.test(text)
|
|
148
147
|
&& !NON_CHEAP_MASS_ACTION_RE.test(text)
|
|
149
|
-
&& (massLane === 'luna_max_mechanical' || massLane === '
|
|
148
|
+
&& (massLane === 'luna_max_mechanical' || massLane === 'terra_max_context_tools')
|
|
150
149
|
&& !reviewerOnly
|
|
151
150
|
&& !criticalMultiDomain;
|
|
152
151
|
const automaticCeiling = massParallel ? MAX_MASS_AUTOMATIC_SUBAGENT_COUNT : MAX_AUTOMATIC_SUBAGENT_COUNT;
|
|
153
152
|
const decomposedSliceCount = Number(input.independentSliceCount);
|
|
154
153
|
const roleWidth = unique((input.suggestedRoles || []).map((role) => String(role || '').trim()).filter(Boolean)).length;
|
|
155
|
-
|
|
154
|
+
if (input.maxThreads !== undefined && input.maxThreads !== null) {
|
|
155
|
+
boundedThreadCount(input.maxThreads, 'max_threads');
|
|
156
|
+
}
|
|
156
157
|
if (Number.isFinite(decomposedSliceCount) && decomposedSliceCount > 0) {
|
|
157
158
|
const reviewerCeiling = criticalMultiDomain
|
|
158
159
|
? MAX_CRITICAL_AUTOMATIC_REVIEWER_COUNT
|
|
@@ -208,38 +209,22 @@ function automaticSubagentFanout(input) {
|
|
|
208
209
|
baseCount = Math.max(DEFAULT_AUTOMATIC_SUBAGENT_COUNT, Math.min(PARALLEL_AUTOMATIC_SUBAGENT_COUNT, roleWidth + 1));
|
|
209
210
|
reason = 'role_width_parallel';
|
|
210
211
|
}
|
|
211
|
-
const count =
|
|
212
|
+
const count = Math.min(baseCount, automaticCeiling);
|
|
212
213
|
return {
|
|
213
214
|
count,
|
|
214
215
|
ceiling: automaticCeiling,
|
|
215
|
-
reason
|
|
216
|
+
reason,
|
|
216
217
|
riskDomains,
|
|
217
218
|
criticalMultiDomain: Boolean(criticalMultiDomain),
|
|
218
219
|
massParallel
|
|
219
220
|
};
|
|
220
221
|
}
|
|
221
|
-
function
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
const decision = decideNarutoConcurrency({
|
|
226
|
-
requestedWorkers: targetCeiling,
|
|
227
|
-
totalWorkItems: targetCeiling,
|
|
228
|
-
parallelismMode: 'extreme',
|
|
229
|
-
maxThreads: frameBudget,
|
|
230
|
-
...(hardware ? { hardware } : {})
|
|
231
|
-
});
|
|
232
|
-
const probe = decision.hardware;
|
|
233
|
-
const cpuCap = Math.max(1, Math.floor(probe.cpu_core_count * 0.75));
|
|
234
|
-
const freeGb = probe.free_memory_bytes / (1024 * 1024 * 1024);
|
|
235
|
-
const memCap = Math.max(1, Math.floor(Math.max(0.5, freeGb - 2) / 1.5));
|
|
236
|
-
const apiCap = Math.max(1, probe.remote_api_rate_limit_budget);
|
|
237
|
-
const safe = clamp(Math.min(cpuCap, memCap, apiCap, targetCeiling), 1, targetCeiling);
|
|
238
|
-
return Math.max(floor, safe);
|
|
239
|
-
}
|
|
240
|
-
catch {
|
|
241
|
-
return floor;
|
|
222
|
+
function boundedThreadCount(value, label) {
|
|
223
|
+
const parsed = Number(value);
|
|
224
|
+
if (!Number.isSafeInteger(parsed) || parsed < 1 || parsed > HARD_NARUTO_MAX_THREADS) {
|
|
225
|
+
throw new RangeError(`${label}_must_be_integer_1_to_${HARD_NARUTO_MAX_THREADS}:${String(value)}`);
|
|
242
226
|
}
|
|
227
|
+
return parsed;
|
|
243
228
|
}
|
|
244
229
|
function isReviewerOnlyFanout(roles) {
|
|
245
230
|
const normalized = unique(roles.map((role) => String(role || '').trim()).filter(Boolean));
|