@danceiny/gotry 0.0.1-rc.21 → 0.0.1-rc.24
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 +102 -194
- package/README.zh-CN.md +115 -210
- package/bin/gotry-backend.js +53 -0
- package/bin/gotry-bootstrap.js +466 -35
- package/bin/gotry-inner.js +255 -36
- package/bin/gotry-process-liveness.d.ts +27 -0
- package/bin/gotry-process-liveness.js +97 -0
- package/bin/gotry-runtime-resolution.d.ts +1 -1
- package/bin/gotry-runtime-resolution.js +2 -2
- package/client/client.js +174 -0
- package/cordis.gotry-patch.yml +70 -93
- package/dist/capabilities/agent-reach-deep.js +45 -122
- package/dist/capabilities/agent-reach.js +63 -148
- package/dist/capabilities/anything.js +89 -75
- package/dist/capabilities/artifacts.js +123 -104
- package/dist/capabilities/channel-health.js +65 -45
- package/dist/capabilities/channel-registry.js +108 -87
- package/dist/capabilities/doctor.js +357 -235
- package/dist/capabilities/effect.js +223 -309
- package/dist/capabilities/fact-log.js +28 -14
- package/dist/capabilities/flyai.js +245 -156
- package/dist/capabilities/ground-transfer.js +509 -0
- package/dist/capabilities/hbcli.js +144 -148
- package/dist/capabilities/hotelbyte-transaction.js +194 -0
- package/dist/capabilities/incident-log.js +131 -61
- package/dist/capabilities/model-override.js +30 -10
- package/dist/capabilities/opensky.js +54 -43
- package/dist/capabilities/resilience.js +50 -32
- package/dist/capabilities/session/action-cache.js +50 -44
- package/dist/capabilities/session/adapters/ctrip-flight.js +119 -62
- package/dist/capabilities/session/adapters/ctrip-hotel.js +125 -110
- package/dist/capabilities/session/adapters/dida-portal.js +206 -0
- package/dist/capabilities/session/adapters/meituan-local.js +35 -54
- package/dist/capabilities/session/adapters/rail-12306.js +169 -112
- package/dist/capabilities/session/benchmark.js +85 -149
- package/dist/capabilities/session/extension-bridge.js +320 -259
- package/dist/capabilities/session/extension-channel.js +57 -76
- package/dist/capabilities/session/extension-distribution.js +115 -119
- package/dist/capabilities/session/extract.js +31 -21
- package/dist/capabilities/session/golden-score.js +55 -33
- package/dist/capabilities/session/health-watch.js +146 -154
- package/dist/capabilities/session/read-guard.js +55 -47
- package/dist/capabilities/session/static-flight-golden.js +49 -36
- package/dist/capabilities/session/transport.js +54 -61
- package/dist/capabilities/session/wizard.js +63 -93
- package/dist/capabilities/session-consent.js +143 -47
- package/dist/capabilities/session-login.js +95 -126
- package/dist/capabilities/session-search.js +391 -253
- package/dist/capabilities/sponsor-plugin.js +341 -0
- package/dist/capabilities/visa-policy.js +87 -73
- package/dist/capabilities/weather.js +163 -235
- package/dist/scripts/action-cache-tests.js +24 -59
- package/dist/scripts/agent-planning-turn-deadline-e2e.js +91 -142
- package/dist/scripts/agent-planning-turn-deadline-tests.js +80 -176
- package/dist/scripts/agent-reach-deep-tests.js +30 -40
- package/dist/scripts/agent-reach-tests.js +26 -18
- package/dist/scripts/agent-reach-wrapper-tests.js +46 -50
- package/dist/scripts/anything-tests.js +58 -62
- package/dist/scripts/artifact-client-contract-tests.js +69 -0
- package/dist/scripts/artifacts-capability-tests.js +235 -0
- package/dist/scripts/async-collect.js +26 -15
- package/dist/scripts/benchmark-environment-bridge-e2e.js +287 -684
- package/dist/scripts/benchmark-environment-bridge-tests.js +818 -3123
- package/dist/scripts/booking-copilot-availability-ledger-binding-tests.js +66 -279
- package/dist/scripts/booking-copilot-availability-policy-tests.js +153 -1257
- package/dist/scripts/booking-copilot-bin-proof-tests.js +22 -45
- package/dist/scripts/booking-copilot-crossrepo-fixture-server.js +64 -76
- package/dist/scripts/booking-copilot-dsh-core-proof-tests.js +69 -199
- package/dist/scripts/booking-copilot-dsh-planner-proof-tests.js +393 -759
- package/dist/scripts/booking-copilot-dsh-plugin-proof-tests.js +33 -75
- package/dist/scripts/booking-copilot-event-sequence-concurrency-proof-tests.js +60 -110
- package/dist/scripts/booking-copilot-gap-code-contract-proof-tests.js +28 -66
- package/dist/scripts/booking-copilot-operation-ledger-concurrency-proof-tests.js +72 -271
- package/dist/scripts/booking-copilot-receipt-ledger-concurrency-proof-tests.js +73 -275
- package/dist/scripts/booking-copilot-runtime-proof-tests.js +784 -3398
- package/dist/scripts/booking-copilot-server-proof-tests.js +63 -168
- package/dist/scripts/booking-copilot-startup-proof-tests.js +38 -124
- 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 +61 -123
- package/dist/scripts/booking-surface-contract-proof-tests.js +152 -1167
- package/dist/scripts/bootstrap-tests.js +1383 -128
- package/dist/scripts/build-changelog.js +89 -130
- package/dist/scripts/build-metrics-report.js +135 -143
- package/dist/scripts/changelog-tests.js +35 -82
- package/dist/scripts/channel-probe-tests.js +44 -116
- package/dist/scripts/channel-probe.js +84 -167
- package/dist/scripts/channel-registry-tests.js +97 -185
- package/dist/scripts/companion-tests.js +25 -70
- package/dist/scripts/dida-cookie-probe.js +87 -0
- package/dist/scripts/dida-sw-probe.js +114 -0
- package/dist/scripts/diff-test.js +17 -12
- package/dist/scripts/doctor-tests.js +428 -120
- package/dist/scripts/dsh-artifact-e2e.js +150 -0
- package/dist/scripts/dsh-artifact-web-e2e.js +443 -0
- package/dist/scripts/dsh-http-proxy-sse-proof.js +90 -0
- package/dist/scripts/dsh-runtime-closure-tests.js +110 -153
- package/dist/scripts/dsh-runtime-closure.js +75 -63
- package/dist/scripts/dsh-session-v3-migration-proof.js +106 -0
- package/dist/scripts/dsh-subprocess-local-proof.js +149 -0
- package/dist/scripts/dsh-target-closure-proof.js +178 -0
- package/dist/scripts/effect-tests.js +165 -552
- package/dist/scripts/engine-run.js +1 -3
- package/dist/scripts/engine-tests.js +16 -10
- package/dist/scripts/evaluation-cadence-tests.js +69 -242
- package/dist/scripts/evaluation-contract-tests.js +193 -499
- package/dist/scripts/extension-distribution-cli.js +19 -15
- package/dist/scripts/extension-distribution-tests.js +98 -211
- package/dist/scripts/extension-tests.js +366 -389
- package/dist/scripts/fact-gate-tests.js +725 -263
- 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-tests.js +325 -68
- 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/gotry-backend-kernel-tests.js +79 -0
- package/dist/scripts/ground-transfer-tests.js +956 -0
- package/dist/scripts/hbcli-e2e-tests.js +71 -90
- 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 +41 -115
- package/dist/scripts/health-watch-cli.js +42 -28
- 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 +16 -9
- 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 +547 -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/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/ledger-repair-apply-tests.js +316 -0
- package/dist/scripts/ledger-repair-plan-tests.js +375 -0
- package/dist/scripts/ledger-tests.js +325 -340
- package/dist/scripts/ledger-workflow-crash.js +10 -20
- package/dist/scripts/map-tools-vendor-package-proof.js +206 -134
- package/dist/scripts/memory-capture-tests.js +242 -61
- package/dist/scripts/memory-decay-tests.js +18 -52
- package/dist/scripts/memory-lifecycle-tests.js +657 -0
- package/dist/scripts/memory-lifecycle.js +196 -0
- package/dist/scripts/memory-metrics.js +24 -12
- package/dist/scripts/memory-value-report.js +474 -222
- package/dist/scripts/memory-value-tests.js +328 -0
- package/dist/scripts/metrics-report-tests.js +62 -199
- package/dist/scripts/model-override-e2e.js +66 -105
- package/dist/scripts/nightly-evidence-tests.js +64 -89
- package/dist/scripts/nightly-evidence.js +108 -111
- package/dist/scripts/nudge-digest.js +39 -28
- package/dist/scripts/onboarding-tests.js +63 -88
- package/dist/scripts/opensky-check.js +18 -13
- package/dist/scripts/opensky-tests.js +28 -28
- package/dist/scripts/persona-surface-guard-tests.js +37 -12
- package/dist/scripts/pnpm-dsh-closure-proof.js +2 -5
- package/dist/scripts/policy-anchor-359-registered-e2e.js +214 -0
- package/dist/scripts/price-drift-tests.js +126 -227
- package/dist/scripts/price-drift-watch.js +209 -253
- package/dist/scripts/probe-poi-tests.js +52 -45
- package/dist/scripts/product-metrics.js +187 -273
- package/dist/scripts/publish-preverify.js +47 -41
- package/dist/scripts/realtime-pricing-tests.js +37 -76
- package/dist/scripts/replay-async.js +20 -18
- package/dist/scripts/replay-real.js +16 -18
- package/dist/scripts/replay.js +52 -82
- package/dist/scripts/session-attach-diagnose.js +16 -12
- package/dist/scripts/session-attach-poc.js +34 -37
- package/dist/scripts/session-benchmark.js +66 -147
- package/dist/scripts/session-dida-live-e2e.js +151 -0
- package/dist/scripts/session-extract-tests.js +14 -35
- package/dist/scripts/session-login.js +14 -13
- package/dist/scripts/session-tests.js +545 -583
- package/dist/scripts/sf-live-benchmark.js +92 -110
- package/dist/scripts/sf-live-cli-tests.js +2 -9
- package/dist/scripts/sf-soft-score-tests.js +19 -60
- package/dist/scripts/sf-summary-tests.js +149 -0
- package/dist/scripts/sf-summary.js +466 -84
- package/dist/scripts/skeleton-check.js +16 -14
- package/dist/scripts/skeleton-integration-test.js +11 -10
- package/dist/scripts/skills-contract-tests.js +51 -46
- package/dist/scripts/smoke-session-gate-tests.js +12 -20
- package/dist/scripts/smoke.js +541 -422
- package/dist/scripts/sponsor-reuse-tests.js +262 -0
- package/dist/scripts/state-cli-tests.js +226 -101
- package/dist/scripts/state-cli.js +549 -212
- package/dist/scripts/static-golden-tests.js +46 -180
- package/dist/scripts/time-eval-tests.js +210 -192
- package/dist/scripts/travel-timeline-tests.js +29 -93
- package/dist/scripts/turn-handoff-collect-tests.js +46 -93
- package/dist/scripts/turn-handoff-collect.js +71 -99
- package/dist/scripts/turn-policy-tests.js +28 -29
- package/dist/scripts/typed-contract-canary.js +77 -162
- 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 +31 -44
- package/dist/scripts/weather-tests.js +121 -543
- package/dist/scripts/wish-channel-gate-tests.js +29 -86
- 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 +18 -12
- package/dist/src/artifact-gate.js +652 -221
- package/dist/src/backend/kernel.js +91 -0
- package/dist/src/backend/modules/booking-copilot.js +55 -0
- package/dist/src/backend/modules/booking-executor.js +124 -0
- package/dist/src/backend/modules/session-search.js +194 -0
- package/dist/src/benchmark-agent-conformance.js +296 -262
- package/dist/src/benchmark-environment-bridge.js +298 -413
- package/dist/src/benchmark-headless-child-diagnostics.js +93 -100
- package/dist/src/benchmark-tool-isolation.js +94 -67
- package/dist/src/bookable-facts.js +299 -174
- package/dist/src/booking-saga.js +64 -120
- package/dist/src/booking-surface/availability-policy.js +443 -576
- package/dist/src/booking-surface/cancel-refund-commission.js +379 -0
- package/dist/src/booking-surface/contracts.js +24 -80
- package/dist/src/booking-surface/dsh-planner.js +510 -281
- package/dist/src/booking-surface/dsh-plugin.js +17 -1
- package/dist/src/booking-surface/error-codes.js +82 -10
- package/dist/src/booking-surface/index.js +0 -3
- package/dist/src/booking-surface/profile.js +10 -54
- package/dist/src/booking-surface/recovery-chain.js +367 -0
- package/dist/src/booking-surface/runtime.js +765 -891
- package/dist/src/booking-surface/server.js +200 -251
- package/dist/src/booking-surface/startup.js +58 -54
- package/dist/src/booking-surface/validation.js +150 -218
- package/dist/src/bridge.js +20 -13
- package/dist/src/companions.js +48 -74
- package/dist/src/contracts.js +21 -43
- package/dist/src/dsh-llm.js +82 -120
- package/dist/src/engine.js +253 -239
- package/dist/src/evaluation-cadence.js +72 -209
- package/dist/src/evaluation-contracts.js +220 -843
- package/dist/src/flight-pack-adapter.js +54 -0
- package/dist/src/flight-pack-contract.js +2 -0
- package/dist/src/gotry-backend.js +70 -0
- package/dist/src/hotel-date-gate.js +118 -0
- package/dist/src/i18n.js +18 -7
- package/dist/src/index.js +1425 -1629
- package/dist/src/journey.js +132 -81
- package/dist/src/ledger-repair-apply.js +538 -0
- package/dist/src/ledger-repair-plan.js +463 -0
- package/dist/src/loop.js +257 -166
- package/dist/src/memory-capture.js +180 -32
- package/dist/src/memory-decay.js +30 -14
- 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 +63 -72
- package/dist/src/slot-spec.js +84 -106
- package/dist/src/state-ledger.js +310 -471
- 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 +44 -63
- package/dist/src/turn-deadline.js +121 -127
- package/dist/src/turn-policy.js +61 -89
- package/dist/src/tz-resolver.js +143 -0
- package/dist/src/unified.js +504 -381
- package/dist/src/wish-pool.js +39 -14
- package/dist/src/write-gate.js +495 -0
- package/dist/src/z3-shared.js +273 -7
- package/extension/README.md +4 -3
- package/extension/background.js +125 -14
- package/extension/content-bridge.js +23 -1
- package/extension/content-main.js +15 -4
- package/extension/manifest.json +16 -8
- package/package.json +251 -220
- package/ts/capabilities/agent-reach.ts +4 -4
- package/ts/capabilities/anything.ts +1 -1
- package/ts/capabilities/artifacts.ts +46 -9
- package/ts/capabilities/flyai.ts +156 -37
- package/ts/capabilities/hbcli.ts +1 -1
- package/ts/capabilities/incident-log.ts +88 -59
- package/ts/capabilities/session/adapters/ctrip-flight.ts +99 -36
- package/ts/capabilities/session/adapters/dida-portal.ts +250 -0
- package/ts/capabilities/session/adapters/rail-12306.ts +123 -24
- package/ts/capabilities/session/extension-bridge.ts +226 -101
- package/ts/capabilities/session/extension-channel.ts +22 -9
- package/ts/capabilities/session/wizard.ts +2 -2
- package/ts/capabilities/session-consent.ts +98 -14
- package/ts/capabilities/session-login.ts +1 -0
- package/ts/capabilities/session-search.ts +315 -31
- package/ts/dsh-runtime/vendor/README.md +8 -4
- package/ts/dsh-runtime/vendor/dsh-map-tools/README.en.md +7 -1
- package/ts/dsh-runtime/vendor/dsh-map-tools/README.md +5 -3
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/settings-ns.js +1 -1
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/settings-ns.d.ts +1 -1
- package/ts/dsh-runtime/vendor/dsh-map-tools/package.json +6 -6
- package/ts/package.json +236 -16
- package/ts/scripts/map-tools-vendor-package-proof.ts +152 -31
- package/ts/scripts/state-cli.ts +418 -51
- package/ts/src/artifact-gate.ts +561 -15
- package/ts/src/benchmark-environment-bridge.ts +37 -20
- package/ts/src/bookable-facts.ts +183 -7
- package/ts/src/booking-surface/cancel-refund-commission.ts +488 -0
- package/ts/src/booking-surface/dsh-planner.ts +240 -32
- package/ts/src/booking-surface/dsh-plugin.js +17 -1
- package/ts/src/booking-surface/error-codes.ts +75 -0
- package/ts/src/booking-surface/recovery-chain.ts +409 -0
- package/ts/src/booking-surface/server.ts +84 -51
- package/ts/src/booking-surface/validation.ts +2 -0
- package/ts/src/contracts.ts +12 -2
- package/ts/src/dsh-llm.ts +4 -8
- package/ts/src/index.ts +609 -90
- package/ts/src/loop.ts +116 -7
- package/ts/src/memory-capture.ts +227 -3
- package/ts/src/mock-llm.ts +4 -8
- package/ts/src/model.ts +88 -2
- package/ts/src/state-ledger.ts +47 -29
- package/ts/src/subagent-job-id-guard.ts +72 -0
- package/ts/src/time-anchor.ts +217 -13
- package/ts/src/unified.ts +316 -54
|
@@ -1,162 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* onboarding UX 测试(issue #21 onboarding UX,§3.3 ADR-21 上架后重设,run-all §40)。
|
|
3
|
+
*
|
|
4
|
+
* 4 段全离线断言(wizard 2026-09-02 缩为 2 步纯 Node 端:扩展落位 + watch precheck):
|
|
5
|
+
* 1. wizard --dry-run:零网络零浏览器零 GUI spawn,exit 0,2 步齐全
|
|
6
|
+
* 2. health-watch 三时序:0ms ready(立即 timeout)/ 5s ready(中途 ready)/ 120s+1ms 超时
|
|
7
|
+
* 3. retry-after-watch:needs-extension → watch ready → 自动重放同 query_id 同参数
|
|
8
|
+
* 4. wizard 无强制 spawn:forcePlatform 参数彻底消失(GUI 跨平台降级退役)
|
|
9
|
+
*
|
|
10
|
+
* 离线纪律:不打真 Chrome、不发真请求;wizard 不需要 spawn 注入(stub 注入路径仍在但 dry-run 路径不调)。
|
|
11
|
+
*/
|
|
1
12
|
import assert from 'node:assert/strict';
|
|
2
|
-
import { runOnboardingWizard, defaultExtensionDir, describeExtensionDir } from '../capabilities/session/wizard.js';
|
|
3
|
-
import { startExtensionHealthWatch, withAutoRetryOnExtension, HEALTH_WATCH_INTERVAL_FLOOR_MS, HEALTH_WATCH_INTERVAL_CEIL_MS } from '../capabilities/session/health-watch.js';
|
|
13
|
+
import { runOnboardingWizard, defaultExtensionDir, describeExtensionDir, } from '../capabilities/session/wizard.js';
|
|
14
|
+
import { startExtensionHealthWatch, withAutoRetryOnExtension, HEALTH_WATCH_INTERVAL_FLOOR_MS, HEALTH_WATCH_INTERVAL_CEIL_MS, } from '../capabilities/session/health-watch.js';
|
|
4
15
|
let passed = 0;
|
|
5
16
|
function check(label, fn) {
|
|
6
|
-
return Promise.resolve()
|
|
7
|
-
|
|
8
|
-
console.log(` ok - ${label}`);
|
|
9
|
-
});
|
|
17
|
+
return Promise.resolve()
|
|
18
|
+
.then(fn)
|
|
19
|
+
.then(() => { passed += 1; console.log(` ok - ${label}`); });
|
|
10
20
|
}
|
|
11
21
|
function noopSpawn() {
|
|
12
22
|
const { EventEmitter } = require('node:events');
|
|
13
23
|
const child = new EventEmitter();
|
|
24
|
+
// 流对象 stub
|
|
14
25
|
const stream = new EventEmitter();
|
|
15
26
|
child.stdin = stream;
|
|
16
27
|
child.stdout = null;
|
|
17
28
|
child.stderr = null;
|
|
18
|
-
child.unref = ()=>undefined;
|
|
29
|
+
child.unref = () => undefined;
|
|
19
30
|
return child;
|
|
20
31
|
}
|
|
21
32
|
function captureSpawn() {
|
|
22
33
|
const calls = [];
|
|
23
|
-
const spawn = (bin, args = [])=>{
|
|
24
|
-
calls.push({
|
|
25
|
-
bin,
|
|
26
|
-
args
|
|
27
|
-
});
|
|
34
|
+
const spawn = ((bin, args = []) => {
|
|
35
|
+
calls.push({ bin, args });
|
|
28
36
|
return noopSpawn();
|
|
29
|
-
};
|
|
30
|
-
return {
|
|
31
|
-
spawn,
|
|
32
|
-
calls
|
|
33
|
-
};
|
|
37
|
+
});
|
|
38
|
+
return { spawn, calls };
|
|
34
39
|
}
|
|
35
40
|
async function asyncSleep(ms) {
|
|
36
|
-
if (ms <= 0)
|
|
37
|
-
|
|
41
|
+
if (ms <= 0)
|
|
42
|
+
return;
|
|
43
|
+
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
38
44
|
}
|
|
39
45
|
console.log('ONBOARDING UX (§40)');
|
|
40
|
-
await check('1. wizard --dry-run 零网络零浏览器零 GUI spawn,exit 0,2 步齐全', async ()=>{
|
|
41
|
-
const result = await runOnboardingWizard({
|
|
42
|
-
dryRun: true
|
|
43
|
-
});
|
|
46
|
+
await check('1. wizard --dry-run 零网络零浏览器零 GUI spawn,exit 0,2 步齐全', async () => {
|
|
47
|
+
const result = await runOnboardingWizard({ dryRun: true });
|
|
44
48
|
assert.equal(result.ok, true, `wizard ok 应 true,实际 ${JSON.stringify(result.steps)}`);
|
|
45
49
|
assert.equal(result.steps.length, 2, `应有 2 步,实际 ${result.steps.length}`);
|
|
46
|
-
const expected = [
|
|
47
|
-
|
|
48
|
-
'watch-extension-ready'
|
|
49
|
-
];
|
|
50
|
-
for(let i = 0; i < expected.length; i++){
|
|
50
|
+
const expected = ['ensure-extension-files', 'watch-extension-ready'];
|
|
51
|
+
for (let i = 0; i < expected.length; i++) {
|
|
51
52
|
assert.equal(result.steps[i].step, expected[i]);
|
|
52
53
|
assert.equal(result.steps[i].status, 'skip', `dry-run 每步应为 skip,${result.steps[i].step} 实为 ${result.steps[i].status}`);
|
|
53
54
|
}
|
|
54
55
|
});
|
|
55
|
-
await check('2. health-watch 三时序:0ms / 中途 / 120s+1ms', async ()=>{
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
intervalMs: 10
|
|
59
|
-
});
|
|
56
|
+
await check('2. health-watch 三时序:0ms / 中途 / 120s+1ms', async () => {
|
|
57
|
+
// (a) timeoutMs=0 → 立即 timeout
|
|
58
|
+
const w0 = startExtensionHealthWatch({ timeoutMs: 0, intervalMs: 10 });
|
|
60
59
|
const o0 = await w0.waitReady();
|
|
61
60
|
assert.equal(o0.ready, false);
|
|
62
61
|
assert.equal(o0.reason, 'timeout');
|
|
62
|
+
// (b) 中途 ready:第一次 probe false,第二次 true(30ms 后)
|
|
63
63
|
let probeCalls = 0;
|
|
64
64
|
const wMid = startExtensionHealthWatch({
|
|
65
65
|
timeoutMs: 500,
|
|
66
66
|
intervalMs: 30,
|
|
67
|
-
probe: async ()=>{
|
|
68
|
-
probeCalls += 1;
|
|
69
|
-
return probeCalls >= 2;
|
|
70
|
-
}
|
|
67
|
+
probe: async () => { probeCalls += 1; return probeCalls >= 2; },
|
|
71
68
|
});
|
|
72
69
|
const oMid = await wMid.waitReady();
|
|
73
70
|
assert.equal(oMid.ready, true, `中途 ready 实为 ${JSON.stringify(oMid)}`);
|
|
74
71
|
assert.ok(oMid.attempts >= 2);
|
|
72
|
+
// (c) 永不 ready → timeout(用极小 timeoutMs+全 false probe 模拟)
|
|
75
73
|
const wTimeout = startExtensionHealthWatch({
|
|
76
74
|
timeoutMs: 60,
|
|
77
75
|
intervalMs: 20,
|
|
78
|
-
probe: async ()=>false
|
|
76
|
+
probe: async () => false,
|
|
79
77
|
});
|
|
80
78
|
const oTimeout = await wTimeout.waitReady();
|
|
81
79
|
assert.equal(oTimeout.ready, false);
|
|
82
80
|
assert.equal(oTimeout.reason, 'timeout');
|
|
83
81
|
});
|
|
84
|
-
await check('3. wizard 完全不调 spawn(GUI 面板/剪贴板/直开浏览器均已退役)', async ()=>{
|
|
82
|
+
await check('3. wizard 完全不调 spawn(GUI 面板/剪贴板/直开浏览器均已退役)', async () => {
|
|
83
|
+
// 2026-09-02 上架后:wizard 缩为 2 步纯 Node 端职责(扩展落位 + watch precheck),
|
|
84
|
+
// 不弹 osascript/zenity、不动 pbcopy/xclip/clip、不 open 浏览器。
|
|
85
|
+
// 这里只校验 dry-run 与无源目录 fail 路径都不产生 spawn 调用。
|
|
85
86
|
const dry = captureSpawn();
|
|
86
|
-
await runOnboardingWizard({
|
|
87
|
-
dryRun: true,
|
|
88
|
-
sourceDir: '/',
|
|
89
|
-
extensionDir: '/tmp/none'
|
|
90
|
-
});
|
|
87
|
+
await runOnboardingWizard({ dryRun: true, sourceDir: '/', extensionDir: '/tmp/none' });
|
|
91
88
|
assert.equal(dry.calls.length, 0, `dry-run 不应 spawn 任何命令(实调 ${dry.calls.length})`);
|
|
92
89
|
const fail = captureSpawn();
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
sourceDir: '/nonexistent-source-dir-for-onboarding-tests',
|
|
96
|
-
extensionDir: '/tmp/none-fail'
|
|
97
|
-
});
|
|
90
|
+
// dryRun=false + 不存在的源目录 → ensure 会 fail,但应仍不产生 spawn 调用
|
|
91
|
+
await runOnboardingWizard({ dryRun: false, sourceDir: '/nonexistent-source-dir-for-onboarding-tests', extensionDir: '/tmp/none-fail' });
|
|
98
92
|
assert.equal(fail.calls.length, 0, `fail 路径也不应 spawn(实调 ${fail.calls.length})`);
|
|
99
93
|
});
|
|
100
|
-
await check('4. retry-after-watch:needs-extension → watch ready → 自动重放同 query_id', async ()=>{
|
|
94
|
+
await check('4. retry-after-watch:needs-extension → watch ready → 自动重放同 query_id', async () => {
|
|
101
95
|
let fetchCalls = 0;
|
|
102
96
|
const queryId = 'sf-01';
|
|
103
|
-
const fetch = async ()=>{
|
|
97
|
+
const fetch = async () => {
|
|
104
98
|
fetchCalls += 1;
|
|
105
|
-
return {
|
|
106
|
-
query_id: queryId,
|
|
107
|
-
verdict: 'needs-extension',
|
|
108
|
-
needsExt: fetchCalls === 1
|
|
109
|
-
};
|
|
99
|
+
return { query_id: queryId, verdict: 'needs-extension', needsExt: fetchCalls === 1 };
|
|
110
100
|
};
|
|
101
|
+
// 第一次 → needs-extension,启 watch
|
|
111
102
|
const first = await fetch();
|
|
112
103
|
assert.equal(first.verdict, 'needs-extension');
|
|
113
104
|
let probeCount = 0;
|
|
114
105
|
const watch = startExtensionHealthWatch({
|
|
115
106
|
timeoutMs: 1_000,
|
|
116
107
|
intervalMs: 20,
|
|
117
|
-
probe: async ()=>{
|
|
118
|
-
probeCount += 1;
|
|
119
|
-
return probeCount >= 2;
|
|
120
|
-
}
|
|
108
|
+
probe: async () => { probeCount += 1; return probeCount >= 2; },
|
|
121
109
|
});
|
|
122
110
|
const outcome = await watch.waitReady();
|
|
123
111
|
assert.equal(outcome.ready, true);
|
|
112
|
+
// watch ready → 自动重放同 query_id
|
|
124
113
|
const retry = await fetch();
|
|
125
114
|
assert.equal(retry.query_id, queryId, '同 query_id 必须保持');
|
|
126
115
|
assert.equal(fetchCalls, 2, `应调用 fetch 两次(首次 + 重放),实 ${fetchCalls}`);
|
|
127
116
|
});
|
|
128
|
-
await check('5. wizard 不依赖 platform/panel 参数(GUI 跨平台降级退役)', async ()=>{
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
});
|
|
117
|
+
await check('5. wizard 不依赖 platform/panel 参数(GUI 跨平台降级退役)', async () => {
|
|
118
|
+
// 2026-09-02 上架后:wizard 不再接 forcePlatform/spawn panel 参数,
|
|
119
|
+
// 任何对 wizard 的调用都是 2 步(ensure + watch precheck)。
|
|
120
|
+
const result = await runOnboardingWizard({ dryRun: true, extensionDir: '/tmp/gotry-test-ext-2' });
|
|
133
121
|
assert.equal(result.steps.length, 2, `应 2 步,实 ${result.steps.length}`);
|
|
134
122
|
assert.equal(result.steps[0].step, 'ensure-extension-files');
|
|
135
123
|
assert.equal(result.steps[1].step, 'watch-extension-ready');
|
|
136
124
|
assert.equal(result.platform, undefined, 'platform 字段应不再存在');
|
|
137
125
|
});
|
|
138
|
-
await check('6. withAutoRetryOnExtension 端到端:首次 needs-ext → 自动重放', async ()=>{
|
|
126
|
+
await check('6. withAutoRetryOnExtension 端到端:首次 needs-ext → 自动重放', async () => {
|
|
139
127
|
let callCount = 0;
|
|
140
128
|
let ready = false;
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}, 30);
|
|
129
|
+
// watch 第一次 probe 后 30ms 标记 ready(模拟用户装完扩展)
|
|
130
|
+
setTimeout(() => { ready = true; }, 30);
|
|
144
131
|
const args = {
|
|
145
|
-
fetch: async ()=>{
|
|
132
|
+
fetch: async () => {
|
|
146
133
|
callCount += 1;
|
|
147
|
-
return callCount === 1 ? {
|
|
148
|
-
needsExt: true
|
|
149
|
-
} : {
|
|
150
|
-
needsExt: false,
|
|
151
|
-
hit: true
|
|
152
|
-
};
|
|
134
|
+
return callCount === 1 ? { needsExt: true } : { needsExt: false, hit: true };
|
|
153
135
|
},
|
|
154
|
-
isExtensionNeeded: (r)=>r.needsExt === true,
|
|
155
|
-
watch: {
|
|
156
|
-
timeoutMs: 1_000,
|
|
157
|
-
intervalMs: 20,
|
|
158
|
-
probe: async ()=>ready
|
|
159
|
-
}
|
|
136
|
+
isExtensionNeeded: (r) => r.needsExt === true,
|
|
137
|
+
watch: { timeoutMs: 1_000, intervalMs: 20, probe: async () => ready },
|
|
160
138
|
};
|
|
161
139
|
const out = await withAutoRetryOnExtension(args);
|
|
162
140
|
assert.equal(out.retried, true, `应触发重放,实 retried=${out.retried}`);
|
|
@@ -165,15 +143,15 @@ await check('6. withAutoRetryOnExtension 端到端:首次 needs-ext → 自动
|
|
|
165
143
|
assert.equal(out.result.hit, true);
|
|
166
144
|
assert.equal(callCount, 2, `withAutoRetry 应调 2 次 fetch,实 ${callCount}`);
|
|
167
145
|
});
|
|
168
|
-
await check('7. health-watch interval 边界常量与 watch 契约对齐', ()=>{
|
|
146
|
+
await check('7. health-watch interval 边界常量与 watch 契约对齐', () => {
|
|
169
147
|
assert.ok(HEALTH_WATCH_INTERVAL_FLOOR_MS >= 1_000, '下界不应让 watch 风暴');
|
|
170
148
|
assert.ok(HEALTH_WATCH_INTERVAL_CEIL_MS <= 44_000, '上界应 < EXTENSION_CONNECTED_WINDOW_MS');
|
|
171
149
|
});
|
|
172
|
-
await check('8. defaultExtensionDir = ~/.gotry/extension(契约对齐 bootstrap 节)', ()=>{
|
|
150
|
+
await check('8. defaultExtensionDir = ~/.gotry/extension(契约对齐 bootstrap 节)', () => {
|
|
173
151
|
const dir = defaultExtensionDir();
|
|
174
152
|
assert.match(dir, /\.gotry[\\/]extension$/, `扩展目录形态应是 ~/.gotry/extension,实 ${dir}`);
|
|
175
153
|
});
|
|
176
|
-
await check('9. describeExtensionDir:不存在的目录不抛错,返回 exists:false', ()=>{
|
|
154
|
+
await check('9. describeExtensionDir:不存在的目录不抛错,返回 exists:false', () => {
|
|
177
155
|
const desc = describeExtensionDir('/nonexistent/zzz');
|
|
178
156
|
assert.equal(desc.exists, false);
|
|
179
157
|
assert.equal(desc.fileCount, 0);
|
|
@@ -181,6 +159,3 @@ await check('9. describeExtensionDir:不存在的目录不抛错,返回 exists:f
|
|
|
181
159
|
});
|
|
182
160
|
await asyncSleep(0);
|
|
183
161
|
console.log(`ONBOARDING UX (§40): ${passed} pass`);
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
//# sourceURL=ts/scripts/onboarding-tests.ts
|
|
@@ -1,20 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenSky 校验桥(M2 段 3 第一件,§7-1 免费路线的校验层):验证某航班真实执飞。
|
|
3
|
+
* 零新依赖:匿名 REST(400 credits/天),失败降级为「校验不可用」而非阻塞规划。
|
|
4
|
+
* 证据链:[实时API:opensky] + 抓取时间;查不到≠不存在(ADS-B 覆盖有限),只作正向印证。
|
|
5
|
+
* 运行:cd ts && npx tsx scripts/opensky-check.ts EK329
|
|
6
|
+
*/
|
|
1
7
|
const BASE = 'https://opensky-network.org/api';
|
|
2
8
|
async function checkArrival(callsign, airport) {
|
|
9
|
+
// 匿名窗口只支持近 7 天;演示用最近的到达查询验证桥通不通
|
|
3
10
|
const now = Math.floor(Date.now() / 1000);
|
|
4
|
-
const url = airport
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
const hit = data.find((a)=>(a.callsign ?? '').trim().toUpperCase().includes(callsign.toUpperCase()));
|
|
11
|
+
const url = airport
|
|
12
|
+
? `${BASE}/arrivals?airport=${airport}&begin=${now - 7 * 86400}&end=${now}`
|
|
13
|
+
: `${BASE}/arrivals?airport=OMDB&begin=${now - 7 * 86400}&end=${now}`;
|
|
14
|
+
const res = await fetch(url, { headers: { Accept: 'application/json' } });
|
|
15
|
+
if (!res.ok)
|
|
16
|
+
return `[校验不可用:opensky ${res.status}]`;
|
|
17
|
+
const data = (await res.json());
|
|
18
|
+
const hit = data.find(a => (a.callsign ?? '').trim().toUpperCase().includes(callsign.toUpperCase()));
|
|
13
19
|
const ts = new Date().toISOString();
|
|
14
|
-
return hit
|
|
20
|
+
return hit
|
|
21
|
+
? `[实时API:opensky@${ts}] ✅ ${callsign} 近 7 天执飞记录:到达 ${hit.arrivalAirport ?? '?'}(callsign ${hit.callsign?.trim()})`
|
|
22
|
+
: `[实时API:opensky@${ts}] ○ 近 7 天 ${airport ?? 'OMDB'} 到达列表未见 ${callsign}(ADS-B 覆盖有限,不作否定结论)`;
|
|
15
23
|
}
|
|
16
24
|
const target = process.argv[2] ?? 'EK329';
|
|
17
25
|
console.log(await checkArrival(target, process.argv[3] ?? null));
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
//# sourceURL=ts/scripts/opensky-check.ts
|
|
@@ -1,52 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* opensky 能力层测试(免费匿名 API):
|
|
3
|
+
* 1. 真实航班号(可能不是当前在飞)→ 命中时 observed,查空时 not_observed(三值语义)
|
|
4
|
+
* 2. 完全不在飞的小众号 → not_observed
|
|
5
|
+
* 3. 网络超时 → unavailable(降级不抛错)
|
|
6
|
+
* 4. 证据链:各 verdict 正确标注
|
|
7
|
+
*
|
|
8
|
+
* 注:OpenSky 当前 ADS-B 全球观测并非同一时间覆盖所有航班——EK329 一天
|
|
9
|
+
* 飞数十次但中间有「不在飞」的窗口。所以验 not_observed 也是有效路径。
|
|
10
|
+
*
|
|
11
|
+
* 运行: cd ts && npx tsx scripts/opensky-tests.ts
|
|
12
|
+
*/
|
|
1
13
|
import assert from 'node:assert/strict';
|
|
2
14
|
import { verifyFlight } from '../capabilities/opensky.js';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
});
|
|
15
|
+
// 1. 真实航班号 + 明确目的地机场(机场能筛掉部分不命中)
|
|
16
|
+
// EK329 是 LHR-DXB 路径。观察时段不命中时 verdict='not_observed',不是错误。
|
|
17
|
+
const live = await verifyFlight({ callsign: 'EK329', airport: 'OMDB' });
|
|
7
18
|
assert.ok(live.sampleSize >= 0, 'sampleSize ≥ 0(空数组也合法)');
|
|
8
|
-
assert.ok([
|
|
9
|
-
'observed',
|
|
10
|
-
'not_observed',
|
|
11
|
-
'unavailable'
|
|
12
|
-
].includes(live.verdict), `verdict 三值之一:${live.verdict}`);
|
|
19
|
+
assert.ok(['observed', 'not_observed', 'unavailable'].includes(live.verdict), `verdict 三值之一:${live.verdict}`);
|
|
13
20
|
if (live.verdict === 'observed') {
|
|
14
21
|
assert.ok((live.hits?.length ?? 0) > 0, 'observed 必须配 hits');
|
|
15
22
|
const h = live.hits[0];
|
|
16
23
|
assert.ok(typeof h.icao24 === 'string' && h.icao24.length > 0, 'icao24 存在');
|
|
17
24
|
assert.match(live.evidence, /\[实时API:opensky@/, '证据链标注');
|
|
18
25
|
console.log(`1. EK329 OMDB → ${live.verdict} (sample=${live.sampleSize}, hits=${live.hits?.length}) OK`);
|
|
19
|
-
}
|
|
26
|
+
}
|
|
27
|
+
else if (live.verdict === 'not_observed') {
|
|
20
28
|
assert.match(live.evidence, /○|not_observed|未见/, 'not_observed 标注 ○');
|
|
21
29
|
console.log(`1. EK329 OMDB → not_observed 当前观测窗没飞 (o) OK`);
|
|
22
|
-
}
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
// unavailable = API 限流/不可达,失败也合法
|
|
23
33
|
assert.match(live.evidence, /error/, 'unavailable 标注 error');
|
|
24
34
|
console.log(`1. EK329 OMDB → unavailable (API 异常,降级合法) OK`);
|
|
25
35
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
});
|
|
30
|
-
assert.ok([
|
|
31
|
-
'not_observed',
|
|
32
|
-
'unavailable'
|
|
33
|
-
].includes(fake.verdict), `期望 not_observed/unavailable,实际 ${fake.verdict}`);
|
|
36
|
+
// 2. 完全不存在的航班号 → not_observed 或 unavailable(API 限流 429 时走 unavailable)
|
|
37
|
+
const fake = await verifyFlight({ callsign: 'XXDODO1234', airport: 'OMDB' });
|
|
38
|
+
assert.ok(['not_observed', 'unavailable'].includes(fake.verdict), `期望 not_observed/unavailable,实际 ${fake.verdict}`);
|
|
34
39
|
if (fake.verdict === 'not_observed') {
|
|
35
40
|
assert.match(fake.evidence, /○/, 'not_observed 标 ○');
|
|
36
41
|
console.log('2. XXDODO1234 OMDB → not_observed (○) OK');
|
|
37
|
-
}
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
38
44
|
console.log('2. XXDODO1234 OMDB → unavailable (API 限流 OK) OK');
|
|
39
45
|
}
|
|
46
|
+
// 3. 网络超时 → unavailable
|
|
40
47
|
import { verifyFlight as vf } from '../capabilities/opensky.js';
|
|
41
|
-
const to = await vf({
|
|
42
|
-
callsign: 'EK329',
|
|
43
|
-
airport: 'OMDB',
|
|
44
|
-
timeoutMs: 1
|
|
45
|
-
});
|
|
48
|
+
const to = await vf({ callsign: 'EK329', airport: 'OMDB', timeoutMs: 1 });
|
|
46
49
|
assert.equal(to.verdict, 'unavailable', `timeout 应 unavailable,实际 ${to.verdict}`);
|
|
47
50
|
assert.match(to.evidence, /error/, 'unavailable 证据带 error');
|
|
48
51
|
console.log('3. timeout → unavailable OK');
|
|
49
52
|
console.log('\nOPEN-SKY TESTS: 3/3 OK(免费匿名 OpenSky API)');
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
//# sourceURL=ts/scripts/opensky-tests.ts
|
|
@@ -1,24 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* persona 表层护栏测试(issue #192/#2/#194 回归锚;2026-09-11 契约瘦身改锚,
|
|
3
|
+
* 全离线,只读仓根 patch):
|
|
4
|
+
* 1. (10) 域边界含表层规则句——gotry 能力一律是工具调用,绝不把 gotry_* 传给
|
|
5
|
+
* skill 加载器(dsh skill 面名合法域 ^[a-z0-9]+(-[a-z0-9]+)*$,下划线必抛
|
|
6
|
+
* invalid skill name,rc18 真实用户踩坑);
|
|
7
|
+
* 2. 行为契约 13 条编号完整(2026-09-11 瘦身 23→13,防后续编辑吞条目;窄域
|
|
8
|
+
* 细则归位工具描述/路由卡,persona 只留跨场景行为契约);
|
|
9
|
+
* 3. skill 失败后的行为指引存在(改回 tool call,不换名重试 skill);
|
|
10
|
+
* 4. (4) 候选时段示例枚举绑定锚点卡——澄清卡/访谈/选项不列已过节日
|
|
11
|
+
* (#2 rc18 真实复发:卡把已过的春节/清明/五一当「想用的时候」示例);
|
|
12
|
+
* 5. (13) 后台协作——子任务等待纪律(#194 rc19 实踩:子代理回执 id 不是
|
|
13
|
+
* job id,job_output 轮询子代理 = unknown job 硬错误)+ 永不宣称「工具
|
|
14
|
+
* 预算已耗尽」(ADR-24 v2:唯一边界是运行时时间闸);
|
|
15
|
+
* 6. 动态变量注入面完整——current_date/time_anchor_card/motivation_brief/
|
|
16
|
+
* channel_routing_card 四个引用缺一不可(瘦身不得吞注入面)。
|
|
17
|
+
*
|
|
18
|
+
* 运行: cd ts && npx tsx scripts/persona-surface-guard-tests.ts
|
|
19
|
+
*/
|
|
1
20
|
import assert from 'node:assert/strict';
|
|
2
21
|
import { readFileSync } from 'node:fs';
|
|
3
22
|
import { join } from 'node:path';
|
|
4
23
|
const patch = readFileSync(join(process.cwd(), '..', 'cordis.gotry-patch.yml'), 'utf-8');
|
|
24
|
+
// 1. 表层规则句存在且仅一次
|
|
5
25
|
const guard = '表层规则:gotry 的全部能力一律是【工具调用】';
|
|
6
26
|
assert.equal((patch.match(new RegExp(guard, 'g')) ?? []).length, 1, '表层规则句应恰好出现一次');
|
|
7
27
|
assert.ok(patch.includes('绝不把 gotry_* 名字传给 skill 加载器'), '应显式禁止 gotry_* 进 skill 加载器');
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
for(let i = 1; i <= 23; i += 1){
|
|
28
|
+
// 2. 行为契约 13 条编号完整(2026-09-11 瘦身 23→13)
|
|
29
|
+
const markers = new Set([...patch.matchAll(/\((\d{1,2})\)/g)].map((m) => Number(m[1])));
|
|
30
|
+
for (let i = 1; i <= 13; i += 1) {
|
|
12
31
|
assert.ok(markers.has(i), `行为契约 (${i}) 应存在`);
|
|
13
32
|
}
|
|
14
|
-
assert.equal(markers.size,
|
|
33
|
+
assert.equal(markers.size, 13, `契约条目应恰为 13 条,实际 ${markers.size}`);
|
|
34
|
+
// 3. skill 用错面后的行为指引
|
|
15
35
|
assert.ok(patch.includes('改回 tool call'), '应指引失败后改回 tool call');
|
|
16
|
-
|
|
36
|
+
// 4. #2 复发回归锚:澄清卡示例枚举同样过锚点卡(契约 (4) 内部澄清)
|
|
37
|
+
assert.ok(patch.includes('候选时段示例'), '#2 回归:候选时段示例条款应存在');
|
|
17
38
|
assert.ok(patch.includes('已过的节日不进示例枚举'), '应禁止已过节日进澄清卡示例枚举');
|
|
18
|
-
|
|
39
|
+
// 5. #194 回归锚:子任务等待纪律((13) 后台协作)
|
|
40
|
+
assert.ok(patch.includes('(13)后台协作'), '#194 回归:后台协作条款应存在');
|
|
19
41
|
assert.ok(patch.includes('对子代理绝不调用 job_output/job_kill'), '应禁止对子代理调用 job_output/job_kill');
|
|
20
|
-
assert.ok(patch.includes(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
42
|
+
assert.ok(patch.includes('job_output/job_kill 只用于'), '应限定 job_output/job_kill 的适用面');
|
|
43
|
+
// ADR-24 v2:工具循环唯一边界是运行时时间闸
|
|
44
|
+
assert.ok(patch.includes('工具预算已耗尽'), 'ADR-24 v2:永不宣称工具预算耗尽的指引应存在');
|
|
45
|
+
// 6. 动态变量注入面完整(瘦身不得吞注入面)
|
|
46
|
+
for (const v of ['{{current_date}}', '{{time_anchor_card}}', '{{motivation_brief}}', '{{channel_routing_card}}']) {
|
|
47
|
+
assert.ok(patch.includes(v), `persona 应保留动态变量引用 ${v}`);
|
|
48
|
+
}
|
|
49
|
+
console.log('PERSONA SURFACE GUARD TESTS: 6/6 OK(表层规则句 / 13 条契约完整 / skill 失败行为指引 / 澄清卡示例过锚点卡 / 子任务等待纪律+预算话术 / 动态变量注入面)');
|
|
@@ -2,7 +2,7 @@ import assert from 'node:assert/strict';
|
|
|
2
2
|
import { readFileSync } from 'node:fs';
|
|
3
3
|
import { resolve } from 'node:path';
|
|
4
4
|
import { REQUIRED_BENCHMARK_DSH_VERSION } from '../../bin/gotry-runtime-resolution.js';
|
|
5
|
-
import { parsePnpmDshLock, REQUIRED_DSH_RUNTIME_PACKAGE_COUNT, validateDshRuntimeClosure } from './dsh-runtime-closure.js';
|
|
5
|
+
import { parsePnpmDshLock, REQUIRED_DSH_RUNTIME_PACKAGE_COUNT, validateDshRuntimeClosure, } from './dsh-runtime-closure.js';
|
|
6
6
|
const consumerRoot = process.argv[2];
|
|
7
7
|
assert.ok(consumerRoot, 'usage: pnpm-dsh-closure-proof.ts <clean-consumer-root>');
|
|
8
8
|
const installedPackage = JSON.parse(readFileSync(resolve(consumerRoot, 'node_modules/@danceiny/gotry/package.json'), 'utf8'));
|
|
@@ -11,10 +11,7 @@ const closure = validateDshRuntimeClosure({
|
|
|
11
11
|
dependencies: installedPackage.dependencies ?? {},
|
|
12
12
|
lockPackages,
|
|
13
13
|
runtimeVersion: REQUIRED_BENCHMARK_DSH_VERSION,
|
|
14
|
-
expectedPackageCount: REQUIRED_DSH_RUNTIME_PACKAGE_COUNT
|
|
14
|
+
expectedPackageCount: REQUIRED_DSH_RUNTIME_PACKAGE_COUNT,
|
|
15
15
|
});
|
|
16
16
|
assert.equal(closure.names.length, REQUIRED_DSH_RUNTIME_PACKAGE_COUNT, 'clean pnpm consumer must resolve the complete Round 5 DSH closure');
|
|
17
17
|
console.log(`PNPM DSH CLOSURE PROOF: ${closure.names.length} packages at ${closure.version}`);
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
//# sourceURL=ts/scripts/pnpm-dsh-closure-proof.ts
|