@danceiny/gotry 0.0.1-rc.8 → 0.2.0-rc.27
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 +172 -217
- package/README.zh-CN.md +222 -0
- package/bin/gotry-backend.js +53 -0
- package/bin/gotry-booking-copilot.js +53 -0
- package/bin/gotry-bootstrap.js +1744 -0
- package/bin/gotry-inner.js +733 -83
- package/bin/gotry-process-liveness.d.ts +27 -0
- package/bin/gotry-process-liveness.js +97 -0
- package/bin/gotry-runtime-resolution.d.ts +27 -0
- package/bin/gotry-runtime-resolution.js +49 -0
- package/bin/gotry.js +1 -1
- package/client/client.js +203 -0
- package/cordis.gotry-patch.yml +80 -49
- package/data/airline-airports.json +39 -0
- package/data/stations-12306-verify.json +524 -0
- package/dist/capabilities/agent-reach-deep.js +45 -122
- package/dist/capabilities/agent-reach.js +101 -146
- package/dist/capabilities/anything.js +135 -94
- package/dist/capabilities/artifacts.js +370 -0
- package/dist/capabilities/channel-health.js +131 -0
- package/dist/capabilities/channel-registry.js +256 -0
- package/dist/capabilities/doctor.js +546 -0
- package/dist/capabilities/effect.js +394 -0
- package/dist/capabilities/external-event.js +149 -0
- package/dist/capabilities/fact-log.js +55 -0
- package/dist/capabilities/flyai-config.js +337 -0
- package/dist/capabilities/flyai.js +968 -0
- package/dist/capabilities/fx-contract.js +293 -0
- package/dist/capabilities/geo-atlas.js +246 -0
- package/dist/capabilities/ground-transfer.js +509 -0
- package/dist/capabilities/hbcli.js +260 -123
- package/dist/capabilities/hotelbyte-transaction.js +194 -0
- package/dist/capabilities/incident-log.js +131 -61
- package/dist/capabilities/itinerary-artifact.js +190 -0
- package/dist/capabilities/itinerary-deck-artifact.js +194 -0
- package/dist/capabilities/itinerary-deck-export.js +339 -0
- package/dist/capabilities/lavish-local.js +924 -0
- package/dist/capabilities/model-override.js +38 -0
- package/dist/capabilities/opensky.js +54 -43
- package/dist/capabilities/resilience.js +191 -0
- package/dist/capabilities/session/action-cache.js +126 -0
- package/dist/capabilities/session/adapters/ctrip-flight.js +141 -0
- package/dist/capabilities/session/adapters/ctrip-hotel.js +222 -0
- package/dist/capabilities/session/adapters/dida-portal.js +274 -0
- package/dist/capabilities/session/adapters/meituan-local.js +54 -0
- package/dist/capabilities/session/adapters/rail-12306.js +342 -0
- package/dist/capabilities/session/benchmark.js +189 -0
- package/dist/capabilities/session/bridge-ledger.js +224 -0
- package/dist/capabilities/session/extension-bridge.js +636 -0
- package/dist/capabilities/session/extension-channel.js +109 -0
- package/dist/capabilities/session/extension-distribution.js +230 -0
- package/dist/capabilities/session/extract.js +50 -0
- package/dist/capabilities/session/golden-score.js +114 -0
- package/dist/capabilities/session/health-watch.js +215 -0
- package/dist/capabilities/session/read-guard.js +107 -0
- package/dist/capabilities/session/static-flight-golden.js +150 -0
- package/dist/capabilities/session/transport.js +109 -0
- package/dist/capabilities/session/wizard.js +117 -0
- package/dist/capabilities/session-consent.js +178 -0
- package/dist/capabilities/session-login.js +170 -0
- package/dist/capabilities/session-search.js +686 -0
- package/dist/capabilities/spawn-bounded.js +203 -0
- package/dist/capabilities/sponsor-plugin.js +341 -0
- package/dist/capabilities/visa-policy.js +140 -0
- package/dist/capabilities/weather.js +243 -138
- package/dist/data/session-golden-20.json +25 -0
- package/dist/data/sf-golden-manifest.json +103 -0
- package/dist/data/sf-static-routes.json +91 -0
- package/dist/scripts/action-cache-tests.js +72 -0
- package/dist/scripts/agent-planning-turn-deadline-e2e.js +242 -0
- package/dist/scripts/agent-planning-turn-deadline-tests.js +185 -0
- package/dist/scripts/agent-reach-deep-tests.js +30 -40
- package/dist/scripts/agent-reach-error-tests.js +354 -0
- package/dist/scripts/agent-reach-tests.js +26 -18
- package/dist/scripts/agent-reach-wrapper-tests.js +50 -50
- package/dist/scripts/anything-tests.js +116 -60
- package/dist/scripts/artifact-client-contract-tests.js +220 -0
- package/dist/scripts/artifacts-capability-tests.js +727 -0
- package/dist/scripts/async-collect.js +68 -10
- package/dist/scripts/benchmark-environment-bridge-e2e.js +741 -0
- package/dist/scripts/benchmark-environment-bridge-tests.js +1452 -0
- package/dist/scripts/booking-copilot-availability-ledger-binding-tests.js +126 -0
- package/dist/scripts/booking-copilot-availability-policy-tests.js +265 -0
- package/dist/scripts/booking-copilot-bin-proof-tests.js +66 -0
- package/dist/scripts/booking-copilot-cleanup-proof-helper.js +76 -0
- package/dist/scripts/booking-copilot-crossrepo-fixture-server.js +144 -0
- package/dist/scripts/booking-copilot-dsh-core-proof-tests.js +424 -0
- package/dist/scripts/booking-copilot-dsh-planner-proof-tests.js +2839 -0
- package/dist/scripts/booking-copilot-dsh-plugin-proof-tests.js +309 -0
- package/dist/scripts/booking-copilot-dsh-readiness-proof.js +238 -0
- package/dist/scripts/booking-copilot-dsh-warmer-proof.js +123 -0
- package/dist/scripts/booking-copilot-event-sequence-concurrency-proof-tests.js +156 -0
- package/dist/scripts/booking-copilot-gap-code-contract-proof-tests.js +70 -0
- package/dist/scripts/booking-copilot-intent-proof-tests.js +422 -0
- package/dist/scripts/booking-copilot-operation-ledger-concurrency-proof-tests.js +184 -0
- package/dist/scripts/booking-copilot-planner-live-probe.js +95 -0
- package/dist/scripts/booking-copilot-proof-runtime.js +42 -0
- package/dist/scripts/booking-copilot-receipt-ledger-concurrency-proof-tests.js +210 -0
- package/dist/scripts/booking-copilot-runtime-proof-tests.js +2349 -0
- package/dist/scripts/booking-copilot-server-proof-tests.js +784 -0
- package/dist/scripts/booking-copilot-startup-proof-tests.js +94 -0
- package/dist/scripts/booking-executor-tests.js +80 -0
- package/dist/scripts/booking-recovery-chain-tests.js +182 -0
- package/dist/scripts/booking-saga-tests.js +125 -0
- package/dist/scripts/booking-surface-contract-proof-tests.js +212 -0
- package/dist/scripts/bootstrap-tests.js +1479 -0
- package/dist/scripts/bridge-events-tests.js +239 -0
- package/dist/scripts/bridge-ledger-tests.js +428 -0
- package/dist/scripts/build-changelog.js +238 -0
- package/dist/scripts/build-metrics-report.js +331 -0
- package/dist/scripts/changelog-tests.js +118 -0
- package/dist/scripts/channel-probe-tests.js +103 -0
- package/dist/scripts/channel-probe.js +169 -0
- package/dist/scripts/channel-registry-tests.js +208 -0
- package/dist/scripts/companion-tests.js +67 -0
- package/dist/scripts/dida-cookie-probe.js +87 -0
- package/dist/scripts/dida-runner-stop-tests.js +311 -0
- package/dist/scripts/dida-sw-probe.js +114 -0
- package/dist/scripts/diff-test.js +17 -12
- package/dist/scripts/doctor-tests.js +564 -0
- package/dist/scripts/dsh-artifact-e2e.js +279 -0
- package/dist/scripts/dsh-artifact-web-e2e.js +675 -0
- package/dist/scripts/dsh-http-proxy-sse-proof.js +90 -0
- package/dist/scripts/dsh-runtime-closure-tests.js +182 -0
- package/dist/scripts/dsh-runtime-closure.js +162 -0
- package/dist/scripts/dsh-session-v3-migration-proof.js +109 -0
- package/dist/scripts/dsh-subprocess-local-proof.js +150 -0
- package/dist/scripts/dsh-target-closure-proof.js +178 -0
- package/dist/scripts/effect-tests.js +539 -0
- package/dist/scripts/engine-run.js +1 -3
- package/dist/scripts/engine-tests.js +16 -10
- package/dist/scripts/evaluation-cadence-tests.js +174 -0
- package/dist/scripts/evaluation-contract-tests.js +268 -0
- package/dist/scripts/extension-distribution-cli.js +39 -0
- package/dist/scripts/extension-distribution-tests.js +443 -0
- package/dist/scripts/extension-tests.js +988 -0
- package/dist/scripts/external-event-tests.js +350 -0
- package/dist/scripts/fact-gate-tests.js +869 -0
- package/dist/scripts/fixtures/extension-bridge-unref-child.mjs +21 -0
- package/dist/scripts/flight-hotel-anchor-363-registered-e2e.js +169 -0
- package/dist/scripts/flight-malformed-tests.js +159 -0
- package/dist/scripts/flyai-setup-tests.js +228 -0
- package/dist/scripts/flyai-setup-tool-tests.js +54 -0
- package/dist/scripts/flyai-tests.js +692 -0
- package/dist/scripts/flyai-tool-registration-contract-tests.js +91 -0
- package/dist/scripts/fx-contract-tests.js +201 -0
- package/dist/scripts/g5-guard-tests.js +131 -0
- package/dist/scripts/g5-guard.js +189 -0
- package/dist/scripts/gen-lunar-anchors.js +106 -0
- package/dist/scripts/geo-atlas-tests.js +283 -0
- package/dist/scripts/gotry-backend-kernel-tests.js +206 -0
- package/dist/scripts/gotry-try-demo-tests.js +79 -0
- package/dist/scripts/gotry-try-demo.js +49 -0
- package/dist/scripts/ground-transfer-tests.js +956 -0
- package/dist/scripts/hbcli-e2e-tests.js +159 -0
- package/dist/scripts/hbcli-live-optin-tests.js +96 -0
- package/dist/scripts/hbcli-release-contract-tests.js +122 -0
- package/dist/scripts/hbcli-tests.js +121 -69
- package/dist/scripts/health-watch-cli.js +73 -0
- package/dist/scripts/hotel-date-gate-tests.js +496 -0
- package/dist/scripts/hotelbyte-reconcile-tests.js +141 -0
- package/dist/scripts/hotelbyte-spawn-e2e-tests.js +373 -0
- package/dist/scripts/i18n-tests.js +41 -0
- package/dist/scripts/incident-tests.js +281 -87
- package/dist/scripts/issue-194-job-id-guard-tests.js +106 -0
- package/dist/scripts/issue-233-cancel-refund-commission-tests.js +392 -0
- package/dist/scripts/issue-271-liveness-tests.js +569 -0
- package/dist/scripts/issue-289-model-retry-real-tests.js +296 -0
- package/dist/scripts/issue-289-model-retry-tests.js +441 -0
- package/dist/scripts/issue-289-web-retry-e2e.js +630 -0
- package/dist/scripts/issue-338-home-city-e2e.js +577 -0
- package/dist/scripts/issue343-real-entry-e2e.js +160 -0
- package/dist/scripts/issue436-persisted-routing-e2e.js +247 -0
- package/dist/scripts/itinerary-artifact-tests.js +368 -0
- package/dist/scripts/itinerary-deck-artifact-tests.js +416 -0
- package/dist/scripts/itinerary-deck-export-tests.js +552 -0
- package/dist/scripts/itinerary-deck-tests.js +435 -0
- package/dist/scripts/itinerary-html-tests.js +426 -0
- package/dist/scripts/journey-tests.js +22 -27
- package/dist/scripts/kernel-manifest-evidence.js +109 -0
- package/dist/scripts/kernel-manifest-gate.js +126 -0
- package/dist/scripts/kernel-manifest-tests.js +212 -0
- package/dist/scripts/kernel-manifest-trace-entry.js +7 -0
- package/dist/scripts/kernel-manifest-trace-hook.mjs +28 -0
- package/dist/scripts/kernel-manifest.js +369 -0
- package/dist/scripts/lavish-local-tests.js +1226 -0
- package/dist/scripts/lavish-product-tools-tests.js +537 -0
- package/dist/scripts/ledger-repair-apply-tests.js +316 -0
- package/dist/scripts/ledger-repair-plan-tests.js +375 -0
- package/dist/scripts/ledger-tests.js +480 -0
- package/dist/scripts/ledger-workflow-crash.js +32 -0
- package/dist/scripts/managed-dsh-cleanup-diagnostic-proof.js +184 -0
- package/dist/scripts/managed-dsh-close-failure-proof.js +172 -0
- package/dist/scripts/managed-dsh-run-port-proof.js +153 -0
- package/dist/scripts/managed-dsh-terminal-proof.js +252 -0
- package/dist/scripts/map-tools-vendor-package-proof.js +365 -0
- package/dist/scripts/memory-capture-tests.js +242 -61
- package/dist/scripts/memory-decay-tests.js +49 -0
- package/dist/scripts/memory-lifecycle-tests.js +657 -0
- package/dist/scripts/memory-lifecycle.js +196 -0
- package/dist/scripts/memory-metrics.js +29 -31
- package/dist/scripts/memory-value-report.js +631 -0
- package/dist/scripts/memory-value-tests.js +328 -0
- package/dist/scripts/metrics-report-tests.js +151 -0
- package/dist/scripts/model-override-e2e.js +137 -0
- package/dist/scripts/nightly-evidence-tests.js +161 -0
- package/dist/scripts/nightly-evidence.js +286 -0
- package/dist/scripts/nudge-digest.js +43 -42
- package/dist/scripts/observability-tests.js +381 -0
- package/dist/scripts/onboarding-tests.js +161 -0
- package/dist/scripts/opensky-check.js +18 -13
- package/dist/scripts/opensky-tests.js +28 -28
- package/dist/scripts/persona-surface-guard-tests.js +49 -0
- package/dist/scripts/pnpm-dsh-closure-proof.js +17 -0
- package/dist/scripts/policy-anchor-359-registered-e2e.js +214 -0
- package/dist/scripts/price-drift-tests.js +340 -0
- package/dist/scripts/price-drift-watch.js +447 -0
- package/dist/scripts/probe-poi-tests.js +53 -45
- package/dist/scripts/product-metrics.js +483 -0
- package/dist/scripts/publish-preverify.js +110 -0
- package/dist/scripts/realtime-pricing-tests.js +76 -0
- package/dist/scripts/recall-tests.js +513 -0
- package/dist/scripts/replay-async.js +20 -18
- package/dist/scripts/replay-real.js +18 -18
- package/dist/scripts/replay.js +52 -82
- package/dist/scripts/session-attach-diagnose.js +31 -0
- package/dist/scripts/session-attach-poc.js +62 -0
- package/dist/scripts/session-benchmark.js +180 -0
- package/dist/scripts/session-dida-live-e2e.js +199 -0
- package/dist/scripts/session-extract-tests.js +60 -0
- package/dist/scripts/session-link-tests.js +478 -0
- package/dist/scripts/session-login.js +29 -0
- package/dist/scripts/session-tests.js +862 -0
- package/dist/scripts/session-zones-tests.js +358 -0
- package/dist/scripts/sf-live-benchmark.js +367 -0
- package/dist/scripts/sf-live-challenge-stop-tests.js +453 -0
- package/dist/scripts/sf-live-cli-tests.js +92 -0
- package/dist/scripts/sf-live-options.js +46 -0
- package/dist/scripts/sf-manifest-tests.js +30 -0
- package/dist/scripts/sf-manifest.js +33 -0
- package/dist/scripts/sf-soft-score-tests.js +67 -0
- package/dist/scripts/sf-summary-tests.js +324 -0
- package/dist/scripts/sf-summary.js +525 -0
- package/dist/scripts/share-tests.js +432 -0
- package/dist/scripts/skeleton-check.js +16 -14
- package/dist/scripts/skeleton-integration-test.js +28 -11
- package/dist/scripts/skills-contract-tests.js +51 -46
- package/dist/scripts/smoke-session-gate-tests.js +21 -0
- package/dist/scripts/smoke.js +703 -219
- package/dist/scripts/spawn-bounded-abort-tests.js +241 -0
- package/dist/scripts/sponsor-reuse-tests.js +262 -0
- package/dist/scripts/state-cli-tests.js +261 -0
- package/dist/scripts/state-cli.js +585 -0
- package/dist/scripts/state-repair-cli.js +66 -0
- package/dist/scripts/state-repair-tests.js +140 -0
- package/dist/scripts/static-golden-tests.js +165 -0
- package/dist/scripts/time-eval-tests.js +210 -192
- package/dist/scripts/travel-timeline-tests.js +59 -0
- package/dist/scripts/turn-handoff-collect-tests.js +169 -0
- package/dist/scripts/turn-handoff-collect.js +161 -0
- package/dist/scripts/turn-policy-tests.js +55 -0
- package/dist/scripts/typed-contract-canary.js +176 -0
- package/dist/scripts/tz-resolver-sanity.js +50 -0
- package/dist/scripts/tz-resolver-tests.js +584 -0
- package/dist/scripts/unified-tests.js +23 -19
- package/dist/scripts/visa-policy-tests.js +62 -0
- package/dist/scripts/weather-tests.js +276 -41
- package/dist/scripts/wish-channel-gate-tests.js +54 -0
- package/dist/scripts/write-gate-tests.js +522 -0
- package/dist/scripts/z3-lifecycle-fault-tests.js +188 -0
- package/dist/scripts/z3-lifecycle-tests.js +170 -0
- package/dist/scripts/z3-race-repeat-tests.js +39 -0
- package/dist/scripts/z3-race-tests.js +41 -0
- package/dist/src/artifact-gate.js +829 -0
- package/dist/src/backend/kernel.js +91 -0
- package/dist/src/backend/modules/booking-copilot.js +92 -0
- package/dist/src/backend/modules/booking-executor.js +124 -0
- package/dist/src/backend/modules/session-search.js +551 -0
- package/dist/src/benchmark-agent-conformance.js +578 -0
- package/dist/src/benchmark-environment-bridge.js +515 -0
- package/dist/src/benchmark-headless-child-diagnostics.js +166 -0
- package/dist/src/benchmark-tool-isolation.js +151 -0
- package/dist/src/bookable-facts.js +533 -0
- package/dist/src/booking-saga.js +97 -0
- package/dist/src/booking-surface/availability-policy.js +697 -0
- package/dist/src/booking-surface/booking-intent.js +43 -0
- package/dist/src/booking-surface/cancel-refund-commission.js +379 -0
- package/dist/src/booking-surface/canonical-schema.js +116 -0
- package/dist/src/booking-surface/contracts.js +75 -0
- package/dist/src/booking-surface/dsh-planner.js +1854 -0
- package/dist/src/booking-surface/dsh-plugin.js +378 -0
- package/dist/src/booking-surface/dsh-worker.js +98 -0
- package/dist/src/booking-surface/error-codes.js +231 -0
- package/dist/src/booking-surface/index.js +9 -0
- package/dist/src/booking-surface/managed-dsh-cleanup-diagnostic.js +97 -0
- package/dist/src/booking-surface/managed-dsh-run-port.js +244 -0
- package/dist/src/booking-surface/profile.js +24 -0
- package/dist/src/booking-surface/recovery-chain.js +367 -0
- package/dist/src/booking-surface/runtime.js +1968 -0
- package/dist/src/booking-surface/server.js +674 -0
- package/dist/src/booking-surface/startup.js +168 -0
- package/dist/src/booking-surface/validation.js +261 -0
- package/dist/src/bridge.js +20 -13
- package/dist/src/companions.js +86 -0
- package/dist/src/contracts.js +21 -43
- package/dist/src/dsh-llm.js +97 -111
- package/dist/src/engine.js +276 -193
- package/dist/src/evaluation-cadence.js +97 -0
- package/dist/src/evaluation-contracts.js +283 -0
- package/dist/src/flight-pack-adapter.js +54 -0
- package/dist/src/flight-pack-contract.js +2 -0
- package/dist/src/flyai-setup-tool.js +70 -0
- package/dist/src/gotry-backend.js +125 -0
- package/dist/src/hotel-date-gate.js +118 -0
- package/dist/src/i18n.js +88 -0
- package/dist/src/index.js +2305 -731
- package/dist/src/itinerary-deck.js +139 -0
- package/dist/src/itinerary-doc-shared.js +661 -0
- package/dist/src/itinerary-html.js +131 -0
- package/dist/src/journey.js +155 -108
- package/dist/src/lavish-tools.js +400 -0
- package/dist/src/ledger-repair-apply.js +538 -0
- package/dist/src/ledger-repair-plan.js +463 -0
- package/dist/src/loop.js +358 -162
- package/dist/src/memory-capture.js +180 -32
- package/dist/src/memory-decay.js +47 -0
- package/dist/src/memory-lifecycle.js +1310 -0
- package/dist/src/memory-utility.js +27 -40
- package/dist/src/mock-llm.js +36 -61
- package/dist/src/model.js +81 -36
- package/dist/src/realtime-pricing.js +103 -0
- package/dist/src/recall/card.js +74 -0
- package/dist/src/recall/evaluator.js +140 -0
- package/dist/src/recall/integration.js +17 -0
- package/dist/src/recall/tick.js +166 -0
- package/dist/src/session-link/plan-it-action.js +48 -0
- package/dist/src/session-link/session-link.js +248 -0
- package/dist/src/session-zones.js +507 -0
- package/dist/src/share/adapters.js +51 -0
- package/dist/src/share/share-consent.js +76 -0
- package/dist/src/share/share-deck.js +58 -0
- package/dist/src/share/share-token.js +146 -0
- package/dist/src/slot-spec.js +84 -106
- package/dist/src/state-ledger.js +767 -0
- package/dist/src/state-repair.js +299 -0
- package/dist/src/subagent-job-id-guard.js +58 -0
- package/dist/src/time-anchor.js +231 -33
- package/dist/src/tool-packet.js +20 -8
- package/dist/src/travel-slots.js +58 -35
- package/dist/src/travel-timeline.js +59 -0
- package/dist/src/turn-deadline.js +287 -0
- package/dist/src/turn-policy.js +118 -0
- package/dist/src/tz-resolver.js +143 -0
- package/dist/src/unified.js +538 -360
- package/dist/src/wish-pool.js +42 -12
- package/dist/src/write-gate.js +495 -0
- package/dist/src/z3-shared.js +284 -0
- package/extension/README.md +21 -0
- package/extension/README.zh-CN.md +21 -0
- package/extension/background.js +463 -0
- package/extension/content-bridge.js +270 -0
- package/extension/content-main.js +111 -0
- package/extension/manifest.json +60 -0
- package/package.json +407 -14
- package/schemas/booking.intent.schema.json +193 -0
- package/schemas/booking.surface.schema.json +2622 -0
- package/ts/capabilities/agent-reach-deep.ts +114 -0
- package/ts/capabilities/agent-reach.ts +198 -0
- package/ts/capabilities/anything.ts +255 -0
- package/ts/capabilities/artifacts.ts +428 -0
- package/ts/capabilities/fact-log.ts +54 -0
- package/ts/capabilities/flyai-config.ts +388 -0
- package/ts/capabilities/flyai.ts +1274 -0
- package/ts/capabilities/hbcli.ts +253 -71
- package/ts/capabilities/incident-log.ts +88 -59
- package/ts/capabilities/itinerary-artifact.ts +214 -0
- package/ts/capabilities/itinerary-deck-artifact.ts +218 -0
- package/ts/capabilities/itinerary-deck-export.ts +378 -0
- package/ts/capabilities/opensky.ts +121 -0
- package/ts/capabilities/session/action-cache.ts +148 -0
- package/ts/capabilities/session/adapters/ctrip-flight.ts +181 -0
- package/ts/capabilities/session/adapters/ctrip-hotel.ts +238 -0
- package/ts/capabilities/session/adapters/dida-portal.ts +338 -0
- package/ts/capabilities/session/adapters/meituan-local.ts +70 -0
- package/ts/capabilities/session/adapters/rail-12306.ts +392 -0
- package/ts/capabilities/session/benchmark.ts +276 -0
- package/ts/capabilities/session/bridge-ledger.ts +333 -0
- package/ts/capabilities/session/extension-bridge.ts +794 -0
- package/ts/capabilities/session/extension-channel.ts +144 -0
- package/ts/capabilities/session/extension-distribution.ts +266 -0
- package/ts/capabilities/session/extract.ts +54 -0
- package/ts/capabilities/session/golden-score.ts +139 -0
- package/ts/capabilities/session/health-watch.ts +264 -0
- package/ts/capabilities/session/read-guard.ts +141 -0
- package/ts/capabilities/session/static-flight-golden.ts +209 -0
- package/ts/capabilities/session/transport.ts +146 -0
- package/ts/capabilities/session/wizard.ts +140 -0
- package/ts/capabilities/session-consent.ts +211 -0
- package/ts/capabilities/session-login.ts +208 -0
- package/ts/capabilities/session-search.ts +893 -0
- package/ts/capabilities/weather.ts +330 -0
- package/ts/dsh-runtime/vendor/README.md +68 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/LICENSE +21 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/README.en.md +405 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/README.md +404 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/client/client.js +1584 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/cordis.patch.yml +5 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/icon.svg +5 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/amap.js +595 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/nominatim.js +63 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/osrm.js +58 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/photon.js +55 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/config-file.js +87 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/config-route.js +131 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/config.js +16 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/geo.js +232 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/index.js +120 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/settings-ns.js +40 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/staticmap-route.js +115 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/tools/geocode.js +127 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/tools/poi.js +84 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/tools/routes.js +267 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/amap.d.ts +90 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/nominatim.d.ts +17 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/osrm.d.ts +15 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/photon.d.ts +22 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/config-file.d.ts +33 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/config-route.d.ts +23 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/config.d.ts +23 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/geo.d.ts +61 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/index.d.ts +18 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/settings-ns.d.ts +14 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/staticmap-route.d.ts +31 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/tools/geocode.d.ts +11 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/tools/poi.d.ts +9 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/tools/routes.d.ts +75 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/types.d.ts +68 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types.js +16 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/package.json +97 -0
- package/ts/package.json +296 -3
- package/ts/scripts/async-collect.ts +91 -0
- package/ts/scripts/map-tools-vendor-package-proof.ts +404 -0
- package/ts/scripts/skeleton-check.ts +1 -1
- package/ts/scripts/skeleton-integration-test.ts +23 -1
- package/ts/scripts/state-cli.ts +568 -0
- package/ts/scripts/turn-handoff-collect.ts +178 -0
- package/ts/src/artifact-gate.ts +991 -0
- package/ts/src/benchmark-agent-conformance.ts +619 -0
- package/ts/src/benchmark-environment-bridge.ts +538 -0
- package/ts/src/benchmark-headless-child-diagnostics.ts +184 -0
- package/ts/src/benchmark-tool-isolation.ts +166 -0
- package/ts/src/bookable-facts.ts +837 -0
- package/ts/src/booking-saga.ts +133 -0
- package/ts/src/booking-surface/availability-policy.ts +522 -0
- package/ts/src/booking-surface/booking-intent.ts +86 -0
- package/ts/src/booking-surface/cancel-refund-commission.ts +488 -0
- package/ts/src/booking-surface/canonical-schema.js +116 -0
- package/ts/src/booking-surface/contracts.ts +475 -0
- package/ts/src/booking-surface/dsh-planner.ts +1949 -0
- package/ts/src/booking-surface/dsh-plugin.js +378 -0
- package/ts/src/booking-surface/dsh-worker.ts +110 -0
- package/ts/src/booking-surface/error-codes.ts +241 -0
- package/ts/src/booking-surface/index.ts +9 -0
- package/ts/src/booking-surface/managed-dsh-cleanup-diagnostic.ts +151 -0
- package/ts/src/booking-surface/managed-dsh-run-port.ts +273 -0
- package/ts/src/booking-surface/profile.ts +42 -0
- package/ts/src/booking-surface/recovery-chain.ts +409 -0
- package/ts/src/booking-surface/runtime.ts +1793 -0
- package/ts/src/booking-surface/server.ts +733 -0
- package/ts/src/booking-surface/startup.ts +201 -0
- package/ts/src/booking-surface/validation.ts +217 -0
- package/ts/src/companions.ts +113 -0
- package/ts/src/contracts.ts +13 -3
- package/ts/src/dsh-llm.ts +44 -11
- package/ts/src/flyai-setup-tool.ts +77 -0
- package/ts/src/index.ts +2107 -224
- package/ts/src/itinerary-deck.ts +189 -0
- package/ts/src/itinerary-doc-shared.ts +741 -0
- package/ts/src/itinerary-html.ts +171 -0
- package/ts/src/loop.ts +278 -40
- package/ts/src/memory-capture.ts +283 -0
- package/ts/src/memory-decay.ts +55 -0
- package/ts/src/memory-utility.ts +70 -0
- package/ts/src/mock-llm.ts +4 -8
- package/ts/src/model.ts +88 -2
- package/ts/src/recall/card.ts +106 -0
- package/ts/src/recall/evaluator.ts +170 -0
- package/ts/src/recall/integration.ts +35 -0
- package/ts/src/recall/tick.ts +213 -0
- package/ts/src/session-link/plan-it-action.ts +78 -0
- package/ts/src/session-link/session-link.ts +275 -0
- package/ts/src/share/adapters.ts +93 -0
- package/ts/src/share/share-consent.ts +105 -0
- package/ts/src/share/share-deck.ts +85 -0
- package/ts/src/share/share-token.ts +166 -0
- package/ts/src/slot-spec.ts +172 -0
- package/ts/src/state-ledger.ts +912 -0
- package/ts/src/subagent-job-id-guard.ts +72 -0
- package/ts/src/time-anchor.ts +338 -0
- package/ts/src/tool-packet.ts +32 -0
- package/ts/src/travel-slots.ts +219 -0
- package/ts/src/travel-timeline.ts +83 -0
- package/ts/src/turn-deadline.ts +366 -0
- package/ts/src/turn-policy.ts +154 -0
- package/ts/src/unified.ts +360 -89
- package/ts/src/wish-pool.ts +79 -0
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* state-ledger 数据修复控制面(issue #254)。
|
|
3
|
+
*
|
|
4
|
+
* 背景(D2/ADR-16 边界):legacy/v1 数据只安全归入默认 `local`;历史上被误写为
|
|
5
|
+
* `local` 的非 local tenant 事件无法无证据自动反推,必须走人工 data-repair。
|
|
6
|
+
* 本模块是那条人工通道的**控制面**:只读 inventory/dry-run、显式证据映射驱动的
|
|
7
|
+
* 迁移计划、带 backup/校验和/幂等日志/回滚的受限执行。真实产品数据的执行始终
|
|
8
|
+
* 是单独的 owner gate——本模块不读不写 `ts/dsh-runtime/gotry-state/`。
|
|
9
|
+
*
|
|
10
|
+
* 纪律:
|
|
11
|
+
* - inventory/dry-run 零写入(只读连接,integrity_check,输出 before/after 计划);
|
|
12
|
+
* - 迁移必须携带显式映射(逐行 from/to),无证据(无映射)的记录零迁移;
|
|
13
|
+
* - 执行前 backup(文件级拷贝 + SHA-256),逐行 UPDATE 带 from 守卫,追加式
|
|
14
|
+
* journal(幂等:重跑时已完成行自动跳过);回滚 = 从校验过的 backup 恢复;
|
|
15
|
+
* - 跨 tenant 同 `wish_id`/`idem_key` 冲突在 plan 阶段显式暴露,不静默。
|
|
16
|
+
*/
|
|
17
|
+
import Database from 'better-sqlite3';
|
|
18
|
+
import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync, appendFileSync } from 'node:fs';
|
|
19
|
+
import { createHash } from 'node:crypto';
|
|
20
|
+
import { join } from 'node:path';
|
|
21
|
+
import { ledgerDbPath } from './state-ledger.js';
|
|
22
|
+
export const REPAIR_TABLES = ['events', 'projection_docs', 'projection_items', 'workflow_runs'];
|
|
23
|
+
function sha256File(path) {
|
|
24
|
+
return createHash('sha256').update(readFileSync(path)).digest('hex');
|
|
25
|
+
}
|
|
26
|
+
function openReadonly(stateRoot) {
|
|
27
|
+
const path = ledgerDbPath(stateRoot);
|
|
28
|
+
if (!existsSync(path))
|
|
29
|
+
throw new Error(`state ledger not found: ${path}`);
|
|
30
|
+
const db = new Database(path, { readonly: true });
|
|
31
|
+
return db;
|
|
32
|
+
}
|
|
33
|
+
const TENANT_MARKERS = [
|
|
34
|
+
/"tenant_id"\s*:\s*"(?!local")[^"]+"/i,
|
|
35
|
+
/"tenant"\s*:\s*"(?!local")[^"]+"/i,
|
|
36
|
+
];
|
|
37
|
+
function evidenceIn(text) {
|
|
38
|
+
const hits = [];
|
|
39
|
+
for (const re of TENANT_MARKERS) {
|
|
40
|
+
const m = text.match(re);
|
|
41
|
+
if (m)
|
|
42
|
+
hits.push(m[0]);
|
|
43
|
+
}
|
|
44
|
+
if (/(^|[\s:@])tenant:[A-Za-z0-9_.-]+/i.test(text))
|
|
45
|
+
hits.push('actor tenant: prefix');
|
|
46
|
+
return hits;
|
|
47
|
+
}
|
|
48
|
+
/** 只读 inventory:扫描 local 行,列出带显式非 local 标记的候选与无法判定项。零写入。 */
|
|
49
|
+
export function inventoryRepair(stateRoot, options) {
|
|
50
|
+
const db = openReadonly(stateRoot);
|
|
51
|
+
try {
|
|
52
|
+
const integrity = db.pragma('integrity_check', { simple: true }) || 'unknown';
|
|
53
|
+
const candidates = [];
|
|
54
|
+
const localRowCounts = {
|
|
55
|
+
events: 0, projection_docs: 0, projection_items: 0, workflow_runs: 0,
|
|
56
|
+
};
|
|
57
|
+
const events = db.prepare("SELECT seq, tenant_id, ts, actor, kind, subject_id, payload, idem_key, run_id FROM events WHERE tenant_id = 'local' ORDER BY seq").all();
|
|
58
|
+
localRowCounts.events = events.length;
|
|
59
|
+
for (const r of events) {
|
|
60
|
+
const haystack = `${String(r.actor ?? '')} ${String(r.payload ?? '')}`;
|
|
61
|
+
const evidence = evidenceIn(haystack);
|
|
62
|
+
if (evidence.length > 0) {
|
|
63
|
+
candidates.push({
|
|
64
|
+
table: 'events', key: { seq: Number(r.seq) }, kind: String(r.kind ?? ''),
|
|
65
|
+
actor: String(r.actor ?? ''), evidence, classification: 'candidate',
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const pdocs = db.prepare("SELECT tenant_id, subject, doc FROM projection_docs WHERE tenant_id = 'local'").all();
|
|
70
|
+
localRowCounts.projection_docs = pdocs.length;
|
|
71
|
+
for (const r of pdocs) {
|
|
72
|
+
const evidence = evidenceIn(String(r.doc ?? ''));
|
|
73
|
+
if (evidence.length > 0) {
|
|
74
|
+
candidates.push({
|
|
75
|
+
table: 'projection_docs', key: { subject: String(r.subject) }, kind: 'projection_doc',
|
|
76
|
+
actor: '', evidence, classification: 'candidate',
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const pitems = db.prepare("SELECT tenant_id, subject, item_id, doc FROM projection_items WHERE tenant_id = 'local'").all();
|
|
81
|
+
localRowCounts.projection_items = pitems.length;
|
|
82
|
+
for (const r of pitems) {
|
|
83
|
+
const evidence = evidenceIn(String(r.doc ?? ''));
|
|
84
|
+
if (evidence.length > 0) {
|
|
85
|
+
candidates.push({
|
|
86
|
+
table: 'projection_items', key: { subject: String(r.subject), item_id: String(r.item_id) }, kind: 'projection_item',
|
|
87
|
+
actor: '', evidence, classification: 'candidate',
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
const runs = db.prepare("SELECT tenant_id, id, goal, ticket_json, state_json FROM workflow_runs WHERE tenant_id = 'local'").all();
|
|
92
|
+
localRowCounts.workflow_runs = runs.length;
|
|
93
|
+
for (const r of runs) {
|
|
94
|
+
const haystack = `${String(r.ticket_json ?? '')} ${String(r.state_json ?? '')}`;
|
|
95
|
+
const evidence = evidenceIn(haystack);
|
|
96
|
+
if (evidence.length > 0) {
|
|
97
|
+
candidates.push({
|
|
98
|
+
table: 'workflow_runs', key: { id: String(r.id) }, kind: String(r.goal ?? ''),
|
|
99
|
+
actor: '', evidence, classification: 'candidate',
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
stateRoot,
|
|
105
|
+
dbPath: ledgerDbPath(stateRoot),
|
|
106
|
+
dbSha256: sha256File(ledgerDbPath(stateRoot)),
|
|
107
|
+
generatedAt: (options?.now ?? new Date()).toISOString(),
|
|
108
|
+
integrity,
|
|
109
|
+
localRowCounts,
|
|
110
|
+
candidates,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
finally {
|
|
114
|
+
db.close();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
function validateMappingShape(mapping) {
|
|
118
|
+
const errors = [];
|
|
119
|
+
for (const [table, rows] of Object.entries(mapping)) {
|
|
120
|
+
if (!REPAIR_TABLES.includes(table)) {
|
|
121
|
+
errors.push(`unknown table: ${table}`);
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if (!Array.isArray(rows)) {
|
|
125
|
+
errors.push(`${table}: mapping must be an array`);
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
for (const row of rows) {
|
|
129
|
+
if (!row.to || row.to === 'local' || /[^a-z0-9_.-]/i.test(String(row.to))) {
|
|
130
|
+
errors.push(`${table}: invalid target tenant ${JSON.stringify(row.to ?? null)}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return errors;
|
|
135
|
+
}
|
|
136
|
+
/** 只读 plan:校验映射,逐行核对当前 tenant(from 守卫),暴露跨 tenant 唯一键冲突。 */
|
|
137
|
+
export function planRepair(stateRoot, mapping) {
|
|
138
|
+
const errors = validateMappingShape(mapping);
|
|
139
|
+
const changes = [];
|
|
140
|
+
const collisions = [];
|
|
141
|
+
if (errors.length > 0)
|
|
142
|
+
return { changes, collisions, errors };
|
|
143
|
+
const db = openReadonly(stateRoot);
|
|
144
|
+
try {
|
|
145
|
+
for (const row of mapping.events ?? []) {
|
|
146
|
+
const cur = db.prepare("SELECT tenant_id FROM events WHERE seq = ?").get(row.seq);
|
|
147
|
+
if (!cur) {
|
|
148
|
+
errors.push(`events seq=${row.seq}: not found`);
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
// 重定向(from=当前租户)是 owner 显式意图:from 守卫在执行层按当前值强制
|
|
152
|
+
changes.push({ table: 'events', key: { seq: row.seq }, from: cur.tenant_id, to: row.to });
|
|
153
|
+
}
|
|
154
|
+
for (const row of mapping.projection_docs ?? []) {
|
|
155
|
+
const cur = db.prepare("SELECT tenant_id FROM projection_docs WHERE subject = ? AND tenant_id = 'local'").get(row.subject);
|
|
156
|
+
if (!cur) {
|
|
157
|
+
errors.push(`projection_docs subject=${row.subject}: not found under local`);
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
changes.push({ table: 'projection_docs', key: { subject: row.subject }, from: cur.tenant_id, to: row.to });
|
|
161
|
+
}
|
|
162
|
+
for (const row of mapping.projection_items ?? []) {
|
|
163
|
+
const cur = db.prepare("SELECT tenant_id FROM projection_items WHERE subject = ? AND item_id = ? AND tenant_id = 'local'").get(row.subject, row.item_id);
|
|
164
|
+
if (!cur) {
|
|
165
|
+
errors.push(`projection_items ${row.subject}/${row.item_id}: not found under local`);
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
changes.push({ table: 'projection_items', key: { subject: row.subject, item_id: row.item_id }, from: cur.tenant_id, to: row.to });
|
|
169
|
+
}
|
|
170
|
+
for (const row of mapping.workflow_runs ?? []) {
|
|
171
|
+
const cur = db.prepare("SELECT tenant_id FROM workflow_runs WHERE id = ? AND tenant_id = 'local'").get(row.id);
|
|
172
|
+
if (!cur) {
|
|
173
|
+
errors.push(`workflow_runs id=${row.id}: not found under local`);
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
changes.push({ table: 'workflow_runs', key: { id: row.id }, from: cur.tenant_id, to: row.to });
|
|
177
|
+
}
|
|
178
|
+
// 唯一键冲突:events (tenant_id, idem_key);projection 主键 (tenant_id, subject[/item_id]);workflow_runs (tenant_id, id)
|
|
179
|
+
for (const c of changes) {
|
|
180
|
+
if (c.table === 'events') {
|
|
181
|
+
const row = db.prepare("SELECT idem_key FROM events WHERE seq = ?").get(c.key.seq);
|
|
182
|
+
if (row.idem_key !== null && row.idem_key !== undefined) {
|
|
183
|
+
const dup = db.prepare("SELECT seq FROM events WHERE tenant_id = ? AND idem_key = ? AND seq != ?").get(c.to, row.idem_key, c.key.seq);
|
|
184
|
+
if (dup)
|
|
185
|
+
collisions.push({ ...c, reason: `UNIQUE (tenant_id, idem_key) collision: tenant ${c.to} already has idem_key ${row.idem_key}` });
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (c.table === 'projection_docs') {
|
|
189
|
+
const dup = db.prepare("SELECT subject FROM projection_docs WHERE tenant_id = ? AND subject = ?").get(c.to, c.key.subject);
|
|
190
|
+
if (dup)
|
|
191
|
+
collisions.push({ ...c, reason: `PRIMARY KEY collision: tenant ${c.to} already has subject ${c.key.subject}` });
|
|
192
|
+
}
|
|
193
|
+
if (c.table === 'projection_items') {
|
|
194
|
+
const k = c.key;
|
|
195
|
+
const dup = db.prepare("SELECT item_id FROM projection_items WHERE tenant_id = ? AND subject = ? AND item_id = ?").get(c.to, k.subject, k.item_id);
|
|
196
|
+
if (dup)
|
|
197
|
+
collisions.push({ ...c, reason: `PRIMARY KEY collision: tenant ${c.to} already has ${k.subject}/${k.item_id}` });
|
|
198
|
+
}
|
|
199
|
+
if (c.table === 'workflow_runs') {
|
|
200
|
+
const dup = db.prepare("SELECT id FROM workflow_runs WHERE tenant_id = ? AND id = ?").get(c.to, c.key.id);
|
|
201
|
+
if (dup)
|
|
202
|
+
collisions.push({ ...c, reason: `PRIMARY KEY collision: tenant ${c.to} already has workflow run ${c.key.id}` });
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return { changes, collisions, errors };
|
|
206
|
+
}
|
|
207
|
+
finally {
|
|
208
|
+
db.close();
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
function keyWhere(key) {
|
|
212
|
+
const parts = Object.entries(key).map(([k]) => `${k} = ?`);
|
|
213
|
+
return { clause: parts.join(' AND '), params: Object.values(key) };
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* 受限执行:backup → 逐行 UPDATE(from 守卫)+ 追加 journal(幂等)→ integrity_check。
|
|
217
|
+
* 显式映射之外零迁移;冲突行拒绝;任何 SQL 失败即抛出(已应用行留在 journal 中可审计)。
|
|
218
|
+
*/
|
|
219
|
+
export function executeRepair(stateRoot, mapping, options) {
|
|
220
|
+
const plan = planRepair(stateRoot, mapping);
|
|
221
|
+
if (plan.errors.length > 0)
|
|
222
|
+
throw new Error(`repair plan invalid: ${plan.errors.join('; ')}`);
|
|
223
|
+
const movable = plan.changes.filter(c => !plan.collisions.some(col => col.table === c.table && JSON.stringify(col.key) === JSON.stringify(c.key)));
|
|
224
|
+
const dbPath = ledgerDbPath(stateRoot);
|
|
225
|
+
const stamp = (options?.now ?? new Date()).toISOString().replace(/[:.]/g, '-');
|
|
226
|
+
const backupDir = options?.backupDir ?? join(stateRoot, 'state-repair-backup', stamp);
|
|
227
|
+
mkdirSync(backupDir, { recursive: true });
|
|
228
|
+
const backupPath = join(backupDir, 'gotry-state.db');
|
|
229
|
+
copyFileSync(dbPath, backupPath);
|
|
230
|
+
const backupSha256 = sha256File(backupPath);
|
|
231
|
+
writeFileSync(join(backupDir, 'backup-sha256.txt'), backupSha256, 'utf8');
|
|
232
|
+
// journal 挂 stateRoot 稳定路径(幂等跨执行可见);backup 目录仅存快照与校验和
|
|
233
|
+
const journalPath = join(stateRoot, 'gotry-state', 'state-repair-journal.jsonl');
|
|
234
|
+
const db = new Database(dbPath);
|
|
235
|
+
const applied = [];
|
|
236
|
+
let skipped = 0;
|
|
237
|
+
try {
|
|
238
|
+
// 已完成行(幂等):journal 里已记录的 (table,key,to) 跳过
|
|
239
|
+
const done = new Set();
|
|
240
|
+
if (existsSync(journalPath)) {
|
|
241
|
+
for (const line of readFileSync(journalPath, 'utf8').split('\n')) {
|
|
242
|
+
if (!line.trim())
|
|
243
|
+
continue;
|
|
244
|
+
try {
|
|
245
|
+
const e = JSON.parse(line);
|
|
246
|
+
done.add(`${e.table}:${JSON.stringify(e.key)}:${e.to}`);
|
|
247
|
+
}
|
|
248
|
+
catch { /* 尾部半行忽略 */ }
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
const update = db.prepare('UPDATE events SET tenant_id = ? WHERE seq = ? AND tenant_id = ?'); // 守卫参数用 c.from
|
|
252
|
+
const updatePd = db.prepare('UPDATE projection_docs SET tenant_id = ? WHERE subject = ? AND tenant_id = ?');
|
|
253
|
+
const updatePi = db.prepare('UPDATE projection_items SET tenant_id = ? WHERE subject = ? AND item_id = ? AND tenant_id = ?');
|
|
254
|
+
const updateWr = db.prepare('UPDATE workflow_runs SET tenant_id = ? WHERE id = ? AND tenant_id = ?');
|
|
255
|
+
for (const c of movable) {
|
|
256
|
+
const idem = `${c.table}:${JSON.stringify(c.key)}:${c.to}`;
|
|
257
|
+
if (done.has(idem) || c.from === c.to) {
|
|
258
|
+
skipped += 1;
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
const k = c.key;
|
|
262
|
+
let info;
|
|
263
|
+
if (c.table === 'events')
|
|
264
|
+
info = update.run(c.to, k.seq, c.from);
|
|
265
|
+
else if (c.table === 'projection_docs')
|
|
266
|
+
info = updatePd.run(c.to, k.subject, c.from);
|
|
267
|
+
else if (c.table === 'projection_items')
|
|
268
|
+
info = updatePi.run(c.to, k.subject, k.item_id, c.from);
|
|
269
|
+
else
|
|
270
|
+
info = updateWr.run(c.to, k.id, c.from);
|
|
271
|
+
if (info.changes !== 1)
|
|
272
|
+
throw new Error(`repair row changed ${info.changes} rows (expected 1): ${c.table} ${JSON.stringify(c.key)}`);
|
|
273
|
+
const entry = { at: (options?.now ?? new Date()).toISOString(), table: c.table, key: c.key, from: c.from, to: c.to };
|
|
274
|
+
appendFileSync(journalPath, JSON.stringify(entry) + '\n', 'utf8');
|
|
275
|
+
applied.push(entry);
|
|
276
|
+
}
|
|
277
|
+
const integrity = db.pragma('integrity_check', { simple: true }) || 'unknown';
|
|
278
|
+
return { backupDir, backupSha256, journalPath, applied, skipped, changes: plan.changes, collisions: plan.collisions, errors: plan.errors, integrity };
|
|
279
|
+
}
|
|
280
|
+
finally {
|
|
281
|
+
db.close();
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
/** 回滚:用校验过的 backup 覆盖当前账本文件。调用方必须保证无打开的账本连接。 */
|
|
285
|
+
export function rollbackRepair(stateRoot, backupDir) {
|
|
286
|
+
const backupPath = join(backupDir, 'gotry-state.db');
|
|
287
|
+
if (!existsSync(backupPath))
|
|
288
|
+
throw new Error(`backup not found: ${backupPath}`);
|
|
289
|
+
const expected = sha256File(backupPath);
|
|
290
|
+
const recorded = join(backupDir, 'backup-sha256.txt');
|
|
291
|
+
if (existsSync(recorded) && readFileSync(recorded, 'utf8').trim() !== expected) {
|
|
292
|
+
throw new Error('backup checksum mismatch: recorded SHA-256 does not match backup file');
|
|
293
|
+
}
|
|
294
|
+
const dbPath = ledgerDbPath(stateRoot);
|
|
295
|
+
if (!existsSync(dbPath))
|
|
296
|
+
throw new Error(`state ledger not found: ${dbPath}`);
|
|
297
|
+
copyFileSync(backupPath, dbPath);
|
|
298
|
+
return { restoredSha256: sha256File(dbPath), verified: sha256File(dbPath) === expected };
|
|
299
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
const JOB_TOOLS = new Set(['job_output', 'job_kill']);
|
|
2
|
+
function subagentsOf(ctx) {
|
|
3
|
+
try {
|
|
4
|
+
return ctx.subagents;
|
|
5
|
+
}
|
|
6
|
+
catch {
|
|
7
|
+
// Minimal hosts and benchmark contexts may not mount the optional service.
|
|
8
|
+
return undefined;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
function jobIdOf(exec) {
|
|
12
|
+
if (!exec.arguments || typeof exec.arguments !== 'object')
|
|
13
|
+
return undefined;
|
|
14
|
+
const jobId = exec.arguments.job_id;
|
|
15
|
+
return typeof jobId === 'string' && jobId.length > 0 ? jobId : undefined;
|
|
16
|
+
}
|
|
17
|
+
function isContinuableChild(entry, jobId) {
|
|
18
|
+
return entry.mode === 'continuable' && entry.id === jobId;
|
|
19
|
+
}
|
|
20
|
+
function recoveryReason(toolName, jobId) {
|
|
21
|
+
const stopHint = toolName === 'job_kill'
|
|
22
|
+
? '; use interrupt_agent to stop its current turn.'
|
|
23
|
+
: '.';
|
|
24
|
+
return [
|
|
25
|
+
`SUBAGENT_ID_IS_NOT_JOB_ID: ${JSON.stringify(jobId)} is a continuable subagent durable id, not a background job id.`,
|
|
26
|
+
'Its completion arrives as a completion notice; use list_agents to inspect it and send_message to continue it',
|
|
27
|
+
stopHint,
|
|
28
|
+
].join(' ');
|
|
29
|
+
}
|
|
30
|
+
/** Install the GoTry-owned safety net around dsh's jobs tools. */
|
|
31
|
+
export function installSubagentJobIdGuard(ctx) {
|
|
32
|
+
const ctxOn = ctx.on;
|
|
33
|
+
if (typeof ctxOn !== 'function')
|
|
34
|
+
return;
|
|
35
|
+
ctx.on('tools/pre-execute', async (exec, next) => {
|
|
36
|
+
if (!JOB_TOOLS.has(exec.name))
|
|
37
|
+
return next();
|
|
38
|
+
const jobId = jobIdOf(exec);
|
|
39
|
+
const agent = exec.agent;
|
|
40
|
+
const subagents = subagentsOf(ctx);
|
|
41
|
+
if (!jobId || !agent || !subagents)
|
|
42
|
+
return next();
|
|
43
|
+
let children;
|
|
44
|
+
try {
|
|
45
|
+
children = await subagents.listChildren(agent.id, exec.signal);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
// The guard is diagnostic, not an alternate ownership or availability
|
|
49
|
+
// path. Preserve cancellation; otherwise retain dsh's native job error.
|
|
50
|
+
if (exec.signal.aborted)
|
|
51
|
+
throw error;
|
|
52
|
+
return next();
|
|
53
|
+
}
|
|
54
|
+
if (!children.some(entry => isContinuableChild(entry, jobId)))
|
|
55
|
+
return next();
|
|
56
|
+
return { kind: 'deny', reason: recoveryReason(exec.name, jobId) };
|
|
57
|
+
}, { prepend: true });
|
|
58
|
+
}
|