@danceiny/gotry 0.0.1-rc.17 → 0.0.1-rc.18

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 CHANGED
@@ -2,95 +2,74 @@
2
2
 
3
3
  # GoTry
4
4
 
5
- [![CI](https://github.com/Danceiny/gotry/actions/workflows/ci.yml/badge.svg)](https://github.com/Danceiny/gotry/actions/workflows/ci.yml)
6
-
7
5
  > **Body and soul — more travel, less tourism.**
8
6
  > *身体和灵魂,更多旅行,更少旅游。*
9
7
 
10
- **GoTry is an AI travel agent for "departure to next departure."** You say where you want to go and why; it asks about your working hours and existing bookings, then hands you a **formally verified itinerary** — computed by a solver, not guessed by a model.
8
+ GoTry is an AI travel agent for **"departure to next departure."** You tell it where you want to go and why; it interviews you about your working hours and existing bookings, then hands you a **formally verified itinerary** — computed by a Z3 solver, not guessed by a model.
11
9
 
12
- | | |
13
- |---|---|
14
- | **Version** | `v0.0.1-rc.13+` (npm `latest`; [release notes](docs/release-notes.md)) |
15
- | **Runtime** | DeepSeek Harness **0.1.2-alpha.3** (root-pinned; [upstream](https://github.com/deepseek-ai/DeepSeek-Harness)) · Z3 WASM · Cordis |
16
- | **License** | **MIT** ([LICENSE](LICENSE)) |
17
- | **Docs** | English (this file) · [简体中文 README](README.zh-CN.md) · deep engineering docs are Chinese-first ([docs/architecture.md](docs/architecture.md)) |
10
+ [![CI](https://github.com/Danceiny/gotry/actions/workflows/ci.yml/badge.svg)](https://github.com/Danceiny/gotry/actions/workflows/ci.yml)
11
+ [![npm](https://img.shields.io/npm/v/@danceiny/gotry)](https://www.npmjs.com/package/@danceiny/gotry)
12
+ [![License: MIT](https://img.shields.io/badge/License-MIT-informational)](LICENSE)
13
+ [![Node](https://img.shields.io/badge/node-%E2%89%A5%2022.15-blue)](https://www.npmjs.com/package/@danceiny/gotry)
14
+ [![Docs](https://img.shields.io/badge/docs-architecture.md-blue)](docs/architecture.md)
18
15
 
19
- ---
16
+ **[What GoTry Does](#what-gotry-does)** · **[How It Works](#how-it-works)** · **[Tools](#tools)** · **[Demo](#demo)** · **[Quick Start](#quick-start)** · **[Consent and Privacy](#consent-and-privacy)** · **[Trustworthy by Construction](#trustworthy-by-construction)** · **[Project Status](#project-status)** · **[Roadmap](#roadmap)** · **[For AI Agents](#for-ai-agents)** · **[Documentation](#documentation)** · **[License](#license)**
20
17
 
21
- ## 30-second start
18
+ > **Tip for newcomers:** one command is enough to feel the difference — `npx @danceiny/gotry web`, open `http://127.0.0.1:3080`, and say *"I want three relaxing days in Dali."* The agent interviews you first; then the solver, not the model, decides what is feasible. Full walkthrough: [`docs/user-guide.md`](docs/user-guide.md).
22
19
 
23
- ```bash
24
- npx @danceiny/gotry web
25
- # First run creates .env: LLM_API_KEY=<DeepSeek key, or OpenAI-compatible key>
26
- # Not using DeepSeek directly? Also set LLM_BASE_URL=<your endpoint, usually ending in /v1>
27
- # Need a specific model (relays often do)? Set LLM_MODEL=<model name> — it drives the
28
- # dsh chat face (web/headless) and overrides any model picked in the dsh web settings.
29
- # → open http://127.0.0.1:3080 and chat: "I want three relaxing days in Dali"
30
- ```
20
+ ## What GoTry Does
31
21
 
32
- > **Switching models / providers?** The price table (`ts/data/llm-price-table.json`, schema `gotry_llm_price_table_v2`) is the single source of truth for `gotry_m3_nightly_run_v1.cost_usd`. Adding a new model or switching relay = update this file via PR (ADR-11, peak-conservative upper bound only)
33
- - . Unknown models **fail-closed** — no guessed prices. Drift monitor: `npx tsx ts/scripts/price-drift-watch.ts` (offline baseline diff;
34
- - `--fetch` for live official pages). Never auto-applies changes.
22
+ GoTry turns "I want to go somewhere" into "can I and how, at what true cost?" When the answer is "not this weekend," the destination is caught in a wish pool with its conditions instead of being dropped.
35
23
 
36
- | You want | Command |
37
- |---|---|
38
- | 🖥️ Conversational planner (recommended) | `npx @danceiny/gotry web` chat UI on :3080 |
39
- | 🤖 Scripted / one-shot answer | `npx @danceiny/gotry "Two recovery days from Shenzhen, budget 3000"` |
40
- | 🛠️ Developer: run from source | see [source install](#%EF%B8%8F-developer-source-install) below |
24
+ - **For travelers** a conversational planner that asks the questions that actually matter (working window, booked resources, departure city, budget), then returns a verdict per destination: feasible or not, why, and the **smallest change that makes it feasible**.
25
+ - **For agent builders** — a working example of an agent where the LLM only listens, translates, and explains. Decisions and arithmetic live in a Z3 solver; every deliverable number carries a provenance tag; write operations are gated by design.
26
+ - **Evidence built in** an estimate never poses as realtime. Tags are attached by the render layer, never by the model, and switch honestly on degradation. Bookable claims that cannot trace to an exact-date tool result are blocked before delivery.
41
27
 
42
- - Requires Node 22.15+ and one LLM API key. Any OpenAI-compatible endpoint (MiniMax / relays / self-hosted gateways) works too — add `LLM_BASE_URL` to `.env` (usually ends with `/v1`, e.g. `https://api.minimax.io/v1`) and requests follow it instead of the DeepSeek default. To pin the model,
43
- - set `LLM_MODEL` (e.g. `MiniMax-M2`): it applies to both the dsh chat face and the repo scripts, and beats the model selection persisted in the dsh web UI;
44
- - unset, the dsh built-in default (`deepseek-v4-flash`) or your web-UI choice is used. Zero-config startup — the dsh runtime is mounted automatically via a cordis patch.
28
+ ## How It Works
45
29
 
46
- ---
47
-
48
- ## ✨ What it does
49
-
50
- GoTry turns "I want to go somewhere" into "can I, how, and at what true cost":
30
+ One planning pass is a pipeline. The model owns the two language-heavy ends; the solver owns everything numeric:
51
31
 
52
32
  | Stage | Who | Output |
53
33
  |---|---|---|
54
- | **Motivation interview** | LLM | Mandatory questions: working window / booked resources / departure city |
55
- | **Fact extraction** | LLM | Working hours semantics, leave semantics |
56
- | **Feasibility verdict** | **Z3 solver** | Which destinations are feasible / infeasible, why, and the **smallest change that makes them feasible** |
57
- | **Door-to-door true cost** | Solver | Real flight duration (incl. time zones) + early-wake penalty + transfer cost + arrival energy % |
58
- | **Evidence chain** | Render layer | Every number carries a **source tag**: `[骨架:openflights]` = route existence verified against the public route database; `[实时API:flyai]` = pulled live from an API seconds ago; `[静态包:估算]` = a researched estimate (**not realtime — verify before booking**). On degradation the tag switches honestly — an estimate never poses as realtime |
34
+ | Motivation interview | LLM | Mandatory questions: working window / booked resources / departure city |
35
+ | Fact extraction | LLM | Working-hours semantics, leave semantics |
36
+ | Feasibility verdict | **Z3 solver** | Which destinations are feasible / infeasible, why, and the smallest change that makes them feasible |
37
+ | Door-to-door true cost | Solver | Real flight duration (incl. time zones) + early-wake penalty + transfer cost + arrival energy |
38
+ | Evidence chain | Render layer | Every number carries a source tag |
39
+ | Delivery gate | Fact gate | Bookable claims must trace to exact-date tool results, or the artifact is blocked |
40
+ | Memory | Domain layer | Infeasible today → wish pool, with explicit recall conditions |
59
41
 
60
- **Unlike a regular AI chat**, the LLM only translates and explains. **Decisions and arithmetic are computed by a Z3 solver**, not guessed.
42
+ Vocabulary you will meet in a GoTry answer:
61
43
 
62
- ---
44
+ - **Evidence tag** — `[skeleton:openflights]` route existence verified against the public route database; `[realtime:...]` pulled live from an API seconds ago; `[static-pack:estimate]` a researched estimate — not realtime, verify before booking. On degradation the tag switches honestly.
45
+ - **Door-to-door true cost** — the ticket price plus what the trip actually takes from you: real duration across time zones, the early-wake penalty, transfers, and the energy you land with.
46
+ - **Wish pool** — "next departure" storage. An infeasible dream is saved with explicit conditions (e.g. "5+ days, off-season") and recalled when they can be met.
47
+ - **Fact gate** — pre-delivery check on itinerary artifacts: every bookable claim (flight no. / time / airport / price / policy) must trace to an exact-date tool result; unverifiable means blocked — never presented as a verified plan.
63
48
 
64
- ## 🚀 Quick start
49
+ Architecture, five layers:
65
50
 
66
- ### One-liner (npm, recommended)
67
-
68
- ```bash
69
- npx @danceiny/gotry web
70
51
  ```
71
-
72
- That's it — the dsh chat UI on `:3080` with the GoTry persona mounted. First cold start is 6–15 s; if port `:3080` is taken, free it first; unexpected exits leave evidence in `gotry-state/incidents.jsonl` (nothing silent).
73
-
74
- ### Developer source install
75
-
76
- ```bash
77
- git clone https://github.com/Danceiny/gotry && cd gotry
78
- npm ci && npm --prefix ts ci # ① install the pinned root/TS closure
79
- node scripts/build-dist.mjs # ② build the source checkout's JS runtime
80
- cp .env.example .env # ③ set LLM_API_KEY (+ LLM_BASE_URL if not on DeepSeek; + LLM_MODEL to pin the model)
81
- ./gotry web # ④ in-repo entry, same UX
52
+ ┌──────────────────────────────────────────────────────────────┐
53
+ L1 chat-as-interface; gates are in-message choice cards │
54
+ │ L2 orchestration dsh runtime + GoTry plugin (ReAct); 21 tools│
55
+ L3 domain unified itinerary model + Z3 feasibility engine │
56
+ │ L4 data static packs + hotelbyte-cli bridge + OpenFlights │
57
+ │ L5 governance LoopX (objective / gates / evidence / quota) │
58
+ └──────────────────────────────────────────────────────────────┘
82
59
  ```
83
60
 
84
- | Entry | Command | When |
61
+ | Layer | Module | Role |
85
62
  |---|---|---|
86
- | dsh Web chat (recommended) | `./gotry web` | multi-turn planning with visualized reasoning :3080 |
87
- | headless one-shot | `./gotry "one full task"` | scripts / CI / targeted debugging stdout |
63
+ | L2 | `ts/src/index.ts` (dsh plugin) | 21 tools, time-anchor & memory-brief variables; execute isolation + consent gate + per-turn tool budget + process guards |
64
+ | L3 | `ts/src/unified.ts` · `py/gotry_feasibility/` | single solving entry (candidate enumeration + flight-chain Z3) |
65
+ | L4 | `ts/capabilities/effect.ts` · `hbcli.ts` · `skeleton-check.ts` | effect interpreter (backoff retry / circuit breaker / mock interpreter) + realtime inventory bridge + OpenFlights skeleton (three-valued semantics) |
66
+ | L5 | loopx governance | objective / gates / evidence / quota |
88
67
 
89
- The source entry and npm package both resolve one 216-package DSH `0.1.2-alpha.3` closure declared as exact direct dependencies. The manifest, package lock, and root pnpm importer must expose the same 216-name set; publish preverify rejects omissions, mixed versions, and ranges. Source checkout runs dsh from `ts/dsh-runtime/` in normal mode so `gotry-state/` continuity is preserved; benchmark opt-in and npm-package runs use the invocation directory for isolation. The old `ts/dsh-runtime/` vendor tree remains a non-benchmark legacy resolution fallback, not a promised runnable path or the recommended install path.
68
+ > Full ADRs / evolution / debt ledger: [`docs/architecture.md`](docs/architecture.md) (Chinese English versions planned for v0.1.0).
90
69
 
91
- ---
70
+ ## Tools
92
71
 
93
- ## 🧰 21 tools
72
+ 21 tools in six groups:
94
73
 
95
74
  | Group | Tool | What it does |
96
75
  |---|---|---|
@@ -107,26 +86,10 @@ The source entry and npm package both resolve one 216-package DSH `0.1.2-alpha.3
107
86
  | | `gotry_wish_pool_add` / `gotry_wish_pool_list` | "next departure" wish pool + 0..1 conditional recall |
108
87
  | | `gotry_companion_save` · `gotry_trip_log` | companion profile / travel timeline |
109
88
  | **Artifacts** | `gotry_artifacts_list` / `gotry_artifacts_read` | Discover & view generated artifacts (async deliverables + working-dir markdown) as a line-numbered file view (read-only) |
110
- | **Factuality gate** | `gotry_fact_gate` | Pre-delivery gate for itinerary artifacts: every bookable claim (flight no./time/airport/price/policy) must trace to an exact-date tool result (hit AND miss recorded); unverifiable ⇒ blocked — never present as a verified plan |
89
+ | **Factuality gate** | `gotry_fact_gate` | Pre-delivery gate for itinerary artifacts see [fact gate](#how-it-works) above |
111
90
  | **General external** | `gotry_web_search` · `gotry_video_subtitle` · `gotry_github_search` · `gotry_agent_reach` | web / subtitles / GitHub / all-channel external info (via Agent-Reach) |
112
91
 
113
- ---
114
-
115
- ## 🔐 Account session: consent & privacy
116
-
117
- The account session channel reads realtime hotel/flight data from **the user's own logged-in Chrome**, under four hard rules:
118
-
119
- 1. **Login happens on the external website.** GoTry never offers, fills, or collects any password / SMS code / cookie value. It only answers one boolean question: "does a login-ticket cookie exist" (reads cookie **names** only — zero values touched).
120
- 2. **Consent card, once per session.** The first account-session use pops a runtime approval card; approval holds for the session, a refusal revokes it for the session (no repeat prompting). Master switch `sessionAccess: ask|allow|off` at any time.
121
- 3. **Physically read-only.** A ReadGuard aborts all write requests at the network layer (ordering/payment is unreachable in transport); the agent never touches credentials or captchas — on a captcha it stops and hands control back.
122
- 4. **Never hijacks your browser.** Retrieval/login always open their own dedicated tab; the login page is brought to front and stays with you; routine test runs never open browser windows.
123
-
124
- > One-time prerequisite: install the [GoTry Session Bridge](https://chromewebstore.google.com/detail/gotry-session-bridge/oeajpiccmonococjcegddlooeeohlbgd) Chrome extension from the Chrome Web Store (one click, auto-updates) — done in the browser, not by gotry. Review-free GitHub-channel fallback is optional; for that variant see [`docs/extension-webstore-submission.md`](docs/extension-webstore-submission.md). Zero Chrome system dialogs afterwards — the extension passively forwards the site's own search responses (read-only by construction;
125
- - cookies are read by NAME only, values never leave the browser). Until installed, tools return `needs-extension` with the store URL as a clickable link and spend nothing. (A `cdp` fallback via `chrome://inspect` remote debugging still exists for diagnostics: `GOTRY_SESSION_TRANSPORT=cdp` — note Chrome 144+ shows a permission box on every connection.)
126
-
127
- ---
128
-
129
- ## 🎬 A conversation — Demo
92
+ ## Demo
130
93
 
131
94
  ```
132
95
  > Two or three days staring at Erhai Lake, leaving from Shanghai, budget 3000, annual leave — no work.
@@ -146,105 +109,153 @@ Engine verdict:
146
109
  [static-pack:estimate] G7315/G7316 priced on Jul–Aug off-season rates
147
110
  ```
148
111
 
149
- > Tag guide: `[骨架:openflights]` means "this route can be flown" was verified against the public route database; `[实时API:*]` marks data pulled live seconds ago; `[静态包:估算]` flags an off-season estimate — **verify before booking**. Tags are attached by the render layer, never by the model.
112
+ > Tag guide: `[skeleton:openflights]` means "this route can be flown" was verified against the public route database; `[realtime:...]` marks data pulled live seconds ago; `[static-pack:estimate]` flags an off-season estimate — **verify before booking**. Tags are attached by the render layer, never by the model.
150
113
 
151
- ---
114
+ ## Quick Start
152
115
 
153
- ## 🏛️ Architecture
116
+ ### npm (recommended)
154
117
 
155
- ```
156
- ┌──────────────────────────────────────────────────────────────┐
157
- L1 chat-as-interface; gates are in-message choice cards │
158
- L2 orchestration dsh runtime + GoTry plugin (ReAct); 21 tools│
159
- │ L3 domain unified itinerary model + Z3 feasibility engine │
160
- │ L4 data static packs + hotelbyte-cli bridge + OpenFlights │
161
- │ L5 governance LoopX (objective / gates / evidence / quota) │
162
- └──────────────────────────────────────────────────────────────┘
118
+ ```bash
119
+ npx @danceiny/gotry web
120
+ # → open http://127.0.0.1:3080 and chat: "I want three relaxing days in Dali"
121
+ # LLM key & model: handled by the dsh host UI; nothing for gotry to ask on the CLI
163
122
  ```
164
123
 
165
- | Layer | Module | Role |
124
+ | Entry | Command | When |
166
125
  |---|---|---|
167
- | L2 | `ts/src/index.ts` (dsh plugin) | 21 tools, time-anchor & memory-brief variables; execute isolation + consent gate + per-turn tool budget + process guards |
168
- | L3 | `ts/src/unified.ts` · `py/gotry_feasibility/` | single solving entry (candidate enumeration + flight-chain Z3) |
169
- | L4 | `ts/capabilities/effect.ts` · `hbcli.ts` · `skeleton-check.ts` | effect interpreter (backoff retry / circuit breaker / mock interpreter, issue #16) + realtime inventory bridge + OpenFlights skeleton (three-valued semantics) |
170
- | L5 | loopx governance | objective / gates / evidence / quota |
126
+ | Web chat (recommended) | `npx @danceiny/gotry web` | multi-turn planning with visualized reasoning `:3080` |
127
+ | Headless one-shot | `npx @danceiny/gotry "Two recovery days from Shenzhen, budget 3000"` | scripts / CI / targeted debugging stdout |
171
128
 
172
- > 📖 Full ADRs / evolution / debt ledger: [`docs/architecture.md`](docs/architecture.md) (Chinese English versions planned for v0.1.0)
129
+ Requires Node 22.15. LLM credentials are managed by your dsh host UI — gotry itself never asks for or echoes them. OpenAI-compatible endpoints (MiniMax / relays / self-hosted gateways) are handled by the dsh model configuration. First cold start takes 6–15 s; if port `:3080` is taken, free it first; unexpected exits leave evidence in `gotry-state/incidents.jsonl` (nothing silent).
173
130
 
174
- ---
131
+ > **Cost accounting** — `ts/data/llm-price-table.json` (schema `gotry_llm_price_table_v2`) is the single source of truth for nightly run cost. Adding a model or switching relays = a PR against this file (peak-conservative upper bounds only); unknown models **fail closed** — no guessed prices. Drift monitor: `npx tsx ts/scripts/price-drift-watch.ts` (offline baseline diff; `--fetch` for live official pages). It never auto-applies changes.
175
132
 
176
- ## ⚠️ Status & limitations
133
+ ### Developer source install
134
+
135
+ ```bash
136
+ git clone https://github.com/Danceiny/gotry && cd gotry
137
+ npm ci && npm --prefix ts ci # pinned root/TS closure
138
+ node scripts/build-dist.mjs # build the JS runtime
139
+ ./gotry web # in-repo entry, same UX
140
+ ```
141
+
142
+ The source entry and the npm package resolve the same 216-package DeepSeek Harness `0.1.2-alpha.3` closure (exact direct dependencies; publish preverify rejects omissions, mixed versions, and ranges). Source normal runs keep their state under `ts/dsh-runtime/gotry-state/`; benchmark opt-in and npm-package runs use the invocation directory for isolation.
143
+
144
+ ## Consent and Privacy
145
+
146
+ The account-session channel reads realtime hotel/flight data from **your own logged-in Chrome**, under four hard rules:
147
+
148
+ 1. **Login happens on the external website.** GoTry never offers, fills, or collects any password / SMS code / cookie value. It only answers one boolean question — "does a login-ticket cookie exist" (reads cookie **names** only, zero values touched). Existing logins are auto-detected with zero popups.
149
+ 2. **Consent card, once per session.** The first account-session use pops a runtime approval card; approval holds for the session, a refusal revokes it (no repeat prompting). Master switch `sessionAccess: ask|allow|off` at any time.
150
+ 3. **Physically read-only.** A ReadGuard aborts all write requests at the network layer — ordering/payment is unreachable in transport. The agent never touches credentials or captchas; on a captcha it stops and hands control back to you.
151
+ 4. **Never hijacks your browser.** Retrieval/login always open their own dedicated tab; the login page is brought to front and stays with you; routine test runs never open browser windows.
152
+
153
+ One-time prerequisite: the [GoTry Session Bridge](https://chromewebstore.google.com/detail/gotry-session-bridge/oeajpiccmonococjcegddlooeeohlbgd) Chrome extension — handled by the dsh host UI when an account-session tool first needs it (`gotry_session_search` surfaces the install URL as a clickable link in the verdict). The extension itself is one-click on the Chrome Web Store, auto-updates, and the gotry side never asks the user to load unpacked or to run a setup wizard. Zero Chrome system dialogs afterwards — the extension passively forwards the site's own search responses (read-only by construction; cookies are read by NAME only, values never leave the browser). A background health-watch auto-replays your query once the extension is connected. Until installed, tools return `needs-extension` with the store URL and spend nothing.
177
154
 
178
- Evaluation Phase 0 foundation boundary: contracts/registry/validators/unmatched diagnostic fixtures/test-only aggregate admission plus a deterministic PR/nightly/weekly/milestone cadence policy/planner. It returns admission, `pass^k`, budgets, calibration, failure-registry, and cross-benchmark synthesis obligations only; it does not schedule or launch adapters, spend, generate a benchmark score, create an Agent optimization round, or support an uplift claim. No external runner, Python runtime dependency, baseline, or matched production evidence is included.
155
+ ## Trustworthy by Construction
179
156
 
180
- **Working today** (full-stack regression §1–§34 green; every item has deterministic tests):
157
+ 1. **The model translates; the solver decides.** The LLM never produces feasibility verdicts or arithmetic — those are computed by Z3 against the extracted facts.
158
+ 2. **Every number carries a source tag** — attached by the render layer, never the model. Tags switch honestly on degradation; an estimate never poses as realtime.
159
+ 3. **No write path exists.** Booking/payment-class tools must pass WriteGate before any implementation ships; the future booking seam is already pinned by the `booking_saga_fsm.v1` edge table.
160
+ 4. **Login never touches credentials.** Login happens on the external website; GoTry reads cookie names only; consent is asked once per session and revocable.
161
+ 5. **Retrieval is physically read-only.** A ReadGuard aborts write requests at the network layer; a captcha stops the agent and hands control back to you.
162
+ 6. **Unverifiable means blocked.** The fact gate refuses to deliver any itinerary whose bookable claims cannot trace to exact-date tool results — it is never presented as a verified plan.
163
+ 7. **Prices fail closed.** Unknown models get no guessed price; the price table changes only by PR; the drift monitor reports, never auto-applies.
164
+ 8. **Your data is yours.** Product state lives under `gotry-state/`; automated tests and smoke runs use isolated state roots and never write the founder's real product data.
181
165
 
182
- - **Z3 solving engine** — feasibility verdicts + door-to-door whole-cost; the historical concurrency race is fixed (§30 regression gate)
183
- - **Realtime retrieval** — flight/train/hotel (Fliggy official channel), destination/hotel catalogs, weather, live flight observation, route connectivity; realtime prices can overwrite solver prices (`GOTRY_REALTIME_PRICING=1`)
184
- - **Account session search** — Ctrip flights on your own logged-in Chrome; consent & privacy rules above (see 🔐 **Account session: consent & privacy**)
185
- - **One-time browser extension setup** — install [GoTry Session Bridge](https://chromewebstore.google.com/detail/gotry-session-bridge/oeajpiccmonococjcegddlooeeohlbgd) from the Chrome Web Store (a browser concern, not a gotry one — one click on "Add to Chrome"). When `gotry_session_search` returns `needs-extension`, the verdict surfaces the store URL as a clickable link in the dsh UI; the background health-watch auto-replays your query once the extension is connected — no manual retry needed.
186
- - **Extension distribution (issue #21, ADR-21)** — three channels, same extension: the [Chrome Web Store](https://chromewebstore.google.com/detail/gotry-session-bridge/oeajpiccmonococjcegddlooeeohlbgd) (recommended: one-click install + auto-update; live since 2026-09-02) is what dsh users should rely on; the review-free GitHub Releases channel is an opt-in escape hatch; the npm-bundled copy stays the offline-deterministic fallback;
187
- - any GitHub-channel failure falls back to the bundled copy. The store re-signs with its own key, so the store build's extension ID differs from the fixed-key unpacked ID — the local bridge trusts both origins (§38 regression).
188
- - **Session data cross-verification (issues #21 / #67)** — 8 benchmark queries (sf-01..sf-08) verified end-to-end: 7/8 verdict=hit, 6/6 manual-golden soft-score 100%, all hits <15s, zero ReadGuard writes. The comparator is pluggable: `--golden=manual` (default), `--golden=flyai`,
189
- - or `--golden=static`. Static mode pins an ODbL OpenFlights route/carrier snapshot and combines it with manual time/price bands;
190
- - evidence records requested vs effective source, provenance, estimated fields, and fallback reason. Snapshot/route failure prints a warning to stderr and falls back to manual. Static mode is deterministic benchmark data, **not live schedule, fare, or availability**.
191
- - **Observed static-source runs (2026-08-30, logged-in Chrome)** — two consecutive runs produced static official 8/8 with zero fallback each time;
192
- - Ctrip session hits varied from 3/8 to 5/8, while every scored hit across both runs (3+5 records) passed 13/13 (100%). Non-hits remain explicit `miss` records,
193
- - so the ≥90% field score is not presented as 8/8 live availability. The same runs exposed and fixed an online-extension lifecycle bug: idle parked timers/sockets no longer pin the default CLI bridge, while wizardless `keepBridge` behavior remains unchanged (§38: 24/24, §40: 9/9).
194
- - **Memory & reachability** — motivation profile / wish pool / companions / travel timeline; English output via `GOTRY_LOCALE=en`
195
- - **Bounded agent tool loops** — a soft convergence context is injected after real dispatch 16; dispatch 18 is the last tool body, already-prepared calls 19+ receive structured `TOOL_BUDGET_EXHAUSTED` failures without entering the body, and inherited native tool schemas are suppressed at `step/end` for a text-only next step. The boundary is exercised through the packaged `dist` entry and a real dsh headless loop against an offline relay; CI packs the current SHA and repeats the E2E from an isolated pnpm consumer install rather than the root development tree. Direct/programmatic calls are outside this per-turn budget.
166
+ ## Project Status
196
167
 
197
- **Open limitations** (as of 2026-08-29, honest list):
168
+ Current release: **v0.0.1-rc.17** (npm dist-tag `rc`; `latest` stays on rc.16 per the dsh-as-LLM-host install convention). Evaluation is at Phase 0 foundation — deterministic contracts, validators, and a cadence policy; no external benchmark scores, no spend, no uplift claims.
198
169
 
199
- - ⏳ **M3 Exit not closed** — engineering & distribution ready, but real seed-user evidence (50–200 person cohort) not yet accumulated; automated tests prove contracts and formulas, not business pass
200
- - ⏳ **Ctrip-hotel / Meituan logged-in adapters** — flights done; hotel session surfaces await real login-state backfill (next tick)
201
- - **Interface language** — English currently covers the deterministic solve-output layer only; the dsh host UI and dialogue surface belong to the host / calibration samples
202
- - **External benchmark generalization / Phase 1 bridge** — Round 1's exact DeepSeek treatment was environment-unavailable/schema-invalid (score 0), while GLM timed out at 300 s. Round 2 added the default-off owner-local bridge; its frozen treatment remained diagnostic-only because no structured native bridge call or tagged JSON reached the evaluator. Round 3 added provider-neutral native-call/result/terminal conformance, but its new frozen treatment still stopped after one runner spawn with planner/runner exit 1, zero released terminal bytes, no evaluator entry, and null official scores. Round 4's treatment at SHA `5ebddb2` had primary preflight pass, but planner/runner both exited 1 after 30.968 s, released 0 bytes, the evaluator was not entered, and official scores were null. The product Node gate was v24.20.0 while that treatment used v26.3.0, so the result remains diagnostic-only with no uplift claim. GitHub Node 22/24 §48 separately exposed a source default-off 30 s lifecycle hang. Round 5 is limited to removing the timer/keepalive preload, pinning the root/package DSH closure to alpha.3, making source checkout resolve that locked runtime before the legacy vendored fallback, preserving source normal-mode state under `ts/dsh-runtime/gotry-state/` while benchmark/package runs use the invocation directory for isolation, rejecting a non-alpha.3 benchmark runtime before spawn, enforcing Node 22.15+, and adding a benchmark-only structured diagnostic pipe with allowlisted redacted reason codes while stdout remains fail-closed. Its frozen treatment at code SHA `752e54c` stopped after 140.715 s with `child_nonzero_exit`, zero terminal bytes, and null evaluator/official scores, so it remains diagnostic-only; the lock-consistency successor does not rewrite that UID attribution. Cross-benchmark evidence remains open. See [`docs/benchmark-environment-bridge.md`](docs/benchmark-environment-bridge.md).
203
- - **Round 6 structured terminal diagnostics** — benchmark mode maps only the final structured `turn/end` into closed, redacted model/runtime reason families. A per-session arbiter emits at most once and preserves a specific bridge/conformance reason over a later generic runtime reason; recovered transient retries emit no failure. Free-form messages, raw stderr, paths, prompts, request IDs, and credentials never cross the control pipe. The frozen ChinaTravel treatment at code SHA `c61600b` (`..._00001`, `deepseek-v4-flash`) stopped after 49.546 s with `child_runtime_error`, zero terminal bytes, and null evaluator/official scores; leakage and local credential/endpoint scans were zero. This is diagnostic evidence only and creates no score/uplift claim; later documentation-only successors do not rewrite the treatment attribution.
204
- - **Round 7 minimal benchmark kernel** — at code SHA `edb9392896625adbb48abae4a2ecf968dbfc0349`, benchmark opt-in retains only tool budget, model override, one bridge, and isolation/conformance; product prompt variables, process guards, consent hooks, and ordinary GoTry tools are not installed, while the default path is unchanged. The CLI projects a stable task-agnostic persona and accepts only canonical `insert` and `system-prompt` root items, failing closed on missing, duplicate, quoted, reordered, flow, or noncanonical items. ChinaTravel frozen treatment UID `e20241028160248698752` (`easy`, `deepseek-v4-flash`) passed preflight without fallback, then ended after 80.463 s with runner exit 1 and zero/invalid terminal bytes; the evaluator was not entered, official score is null, and the case is not countable. The allowlisted attribution is `child_bridge_runner_failed`; no uplift or external benchmark closure is claimed. The next problem is a generic bridge-tool schema and recoverable domain-error contract.
170
+ **Working today** (full-stack regression green; every item has deterministic tests):
171
+
172
+ - **Z3 solving engine** — feasibility verdicts + door-to-door whole-cost; the historical concurrency race is fixed and regression-gated
173
+ - **Realtime retrieval** — flights/trains/hotels (Fliggy official channel), destination/hotel catalogs, weather, live flight observation, route connectivity; realtime prices can overwrite solver prices (`GOTRY_REALTIME_PRICING=1`)
174
+ - **Account-session search** — Ctrip flights on your logged-in Chrome; observed runs scored every landed hit 13/13 with zero write attempts, while non-hits stay explicit `miss` records no live-availability claim beyond that
175
+ - **Extension install on demand** — `[GoTry Session Bridge](https://chromewebstore.google.com/detail/gotry-session-bridge/oeajpiccmonococjcegddlooeeohlbgd)` is offered as a clickable link in the dsh UI when an account-session tool first needs it (one-click install + auto-update); the gotry side never runs a setup wizard
176
+ - **Memory & reachability** — motivation profile / wish pool / companions / travel timeline; English solve output via `GOTRY_LOCALE=en`
177
+ - **Bounded agent tool loops** — soft convergence after 16 dispatches, structured `TOOL_BUDGET_EXHAUSTED` refusals beyond 18, exercised end-to-end through a packaged consumer install in CI
178
+
179
+ **Open limitations** (honest list):
180
+
181
+ - **M3 Exit not closed** — engineering & distribution are ready, but real seed-user evidence (50–200 person cohort) has not been accumulated; automated tests prove contracts and formulas, not business pass
182
+ - **Hotel session adapters** — Ctrip-hotel / Meituan logged-in surfaces await real login-state backfill; flights are done
183
+ - **Interface language** — English covers the deterministic solve-output layer; the dsh host UI and dialogue surface belong to the host / calibration samples
184
+ - **External benchmark generalization** — every frozen external run to date remains diagnostic-only (no score, no uplift claim); the round-by-round engineering ledger lives in [`docs/benchmark-environment-bridge.md`](docs/benchmark-environment-bridge.md)
185
+ - **Booking** — nothing bookable ships today; M5 opens only through WriteGate and the booking-saga FSM
205
186
 
206
187
  <details>
207
- <summary>📖 Deeper engineering state (ledger contracts / evidence contracts / milestone stance)</summary>
188
+ <summary>Deeper engineering state (ledger contracts / evidence contracts / milestone stance)</summary>
208
189
 
209
- The authoritative state lives in the docs, not this README: transactional state ledger (ADR-15) + dual-form freeze (ADR-16: one ledger semantics for local+web); the M3 real-cohort evidence contract stands (fixtures don't count toward Exit; 50–200 real samples open the gate);
210
- - the M4 paired-cohort value evidence contract (run-all §34 — synthetic data is never Exit evidence);
211
- - async work-order terminal contract (`gotry_async_terminal.v1`: 4/4 → succeeded / ledger settled / exit 0). Details: [`docs/roadmap.md`](docs/roadmap.md) / [`docs/architecture.md`](docs/architecture.md) §1 and issues #19–#22.
190
+ The authoritative state lives in the docs, not this README: transactional state ledger (ADR-15) + dual-form freeze (ADR-16: one ledger semantics for local+web); the M3 real-cohort evidence contract stands (fixtures don't count toward Exit; 50–200 real samples open the gate); the M4 paired-cohort value evidence contract (synthetic data is never Exit evidence); the async work-order terminal contract (`gotry_async_terminal.v1`: 4/4 → succeeded / ledger settled / exit 0). Details: [`docs/roadmap.md`](docs/roadmap.md) / [`docs/architecture.md`](docs/architecture.md) §1 and issues #19–#22.
212
191
 
213
192
  </details>
214
193
 
215
- ---
194
+ ## Roadmap
195
+
196
+ | # | Milestone | Scope | Status |
197
+ |---|---|---|---|
198
+ | M0 | Deterministic pipeline | dual engine implementations + real data packs + reconciliation | ✅ |
199
+ | M1 | Agent form established | LLM in the loop; chat as interface; gates as choice cards | ✅ 2026-08-22 |
200
+ | M2 | Realtime data | hotelbyte bridge + flight sources; evidence chain switches to realtime tags | ✅ 2026-08-22 |
201
+ | M3 | MVP | minimal web face + 50–200 seed users (Erhai / Phuket scenarios) | **← current — evidence open** |
202
+ | M4 | Memory & "next departure" | six-layer memory C-end domain; paired-cohort value evidence | founder-authorized parallel |
203
+ | M5 | Transaction loop | WriteGate in production; booking / payment / refunds | entry-gated |
204
+ | M6 | B2B embedding | principal/sponsor plugin with zero kernel changes | entry-gated |
216
205
 
217
- ## 🧪 Verify
206
+ The single authoritative timeline — entry/exit conditions, deliverables, and gates per milestone — is [`docs/roadmap.md`](docs/roadmap.md).
207
+
208
+ ## Verify
218
209
 
219
210
  ```bash
220
- ./scripts/run-all-tests.sh
221
- # Evaluation Phase 0 diagnostic contracts and deterministic cadence planner
222
- # (offline; no adapter/scheduler/runner/spend/score/Python)
211
+ ./scripts/run-all-tests.sh # full-stack suite (pure TS, no Python needed)
223
212
  cd ts
224
- npx tsx scripts/evaluation-contract-tests.ts
225
- npx tsx scripts/evaluation-cadence-tests.ts
213
+ npx tsx scripts/evaluation-contract-tests.ts # evaluation Phase 0 contracts (offline)
214
+ npx tsx scripts/evaluation-cadence-tests.ts # deterministic cadence policy/planner
226
215
  ```
227
216
 
228
- One-shot full-stack green (pure TS, no Python needed): golden engines · dialogue replay · cross-process async work-orders · plugin smoke · hbcli · process guards · weather · flights · Anything · probePoi · agent-reach · dual-path stability · time-awareness eval · memory domain · **Z3 race (§30)
229
- - · realtime pricing (§31) · i18n catalog (§32) · M3 cohort evidence contract (§33) · M4 value evidence contract (§34) · M3 nightly evidence producer contract (§35) · session transport extension bridge (§38) · extension onboarding pre-check (§40) · bookable-fact gate (§39)
230
- - · extension distribution channel (§43) · sf-live static-golden offline contracts (§44) · evaluation foundation and cadence policy (§45–§46) · agent tool-budget Cordis integration + dsh headless E2E (§47)**. The live runner remains `cd ts && npx tsx scripts/sf-live-benchmark.ts --golden=static` and requires the user's connected Chrome session.
217
+ The suite covers golden engines, dialogue replay, cross-process async work-orders, plugin smoke, realtime bridges, process guards, i18n, memory domain, the Z3 concurrency gate, the fact gate, and a packaged-consumer tool-budget E2E, among others; the authoritative section list is whatever `scripts/run-all-tests.sh` enumerates. The live session benchmark (`npx tsx scripts/sf-live-benchmark.ts --golden=static`) is opt-in, requires your connected Chrome session, and never runs in CI.
231
218
 
232
- ---
219
+ ## Contributing
233
220
 
234
- ## 🤝 Contributing
221
+ Branch off latest `main` (`feat/ · fix/ · docs/ · chore/`), full suite green locally, open a Pull Request — `main` never takes direct pushes. CI (Node 22/24, typecheck + all suites) plus maintainer review, then squash-merge. **Red tests never merge.** Full guide: [CONTRIBUTING.md](CONTRIBUTING.md). Bug reports / feature suggestions: use the issue templates (search existing issues first).
235
222
 
236
- > *PR-based flow: branch off the latest `main`, full suite green, open a Pull Request — `main` never takes direct pushes. Full guide: [CONTRIBUTING.md](CONTRIBUTING.md).*
223
+ ## For AI Agents
237
224
 
238
- Standard open-source flow: branch off latest `main` (`feat/ · fix/ · docs/ · chore/`), full suite green locally, open a PR; CI (Node 22/24, typecheck + all suites) plus maintainer review, then squash-merge. **Red tests never merge.**
225
+ If you are an agent working in this repository, [`AGENTS.md`](AGENTS.md) is the binding contract read it first. In brief:
239
226
 
240
- ---
227
+ - **Sweep async work orders on entry**: `ts/gotry-state/async/*.json` without a matching `.deliverable.md` → `cd ts && npx tsx scripts/async-collect.ts <id>`.
228
+ - **Layer discipline**: arithmetic only in the evaluate layer of `model.ts` / `unified.py`; solving only in `unified.ts` / `unified.py`; `engine.*` / `journey.*` are deprecated compatibility layers — new code must not call them. Any side change requires the full-stack regression.
229
+ - **Never write shared state**: `ts/dsh-runtime/gotry-state/` is the founder's real product data; validate write paths with an isolated `stateRoot` only.
230
+ - **State-sync discipline**: any commit changing the system's shape/state/debt must sync the six state faces of `architecture.md` §11 in the same commit; stage only named files — never `git add -A`.
241
231
 
242
- ## 📜 License
232
+ Program-level context: [`docs/gotry-master-outline.md`](docs/gotry-master-outline.md). Technical authority: [`docs/architecture.md`](docs/architecture.md).
243
233
 
244
- **MIT** (2026-08-23) — same as upstream dsh. See [LICENSE](LICENSE).
234
+ ## Documentation
235
+
236
+ | Document | Purpose |
237
+ |---|---|
238
+ | [`docs/architecture.md`](docs/architecture.md) | System, ADRs, evolution, debt ledger (Chinese, authoritative) |
239
+ | [`docs/gotry-master-outline.md`](docs/gotry-master-outline.md) | Program master outline & reuse matrix |
240
+ | [`docs/gotry-product-design.md`](docs/gotry-product-design.md) | Product design: main loop, transparency, whole-cost model |
241
+ | [`docs/roadmap.md`](docs/roadmap.md) | M0–M6 timeline & current position |
242
+ | [`docs/user-guide.md`](docs/user-guide.md) | End-user guide |
243
+ | [`docs/data-sources.md`](docs/data-sources.md) | Data sources & evidence-chain policy |
244
+ | [`docs/extension-privacy.md`](docs/extension-privacy.md) | Session Bridge extension privacy |
245
+ | [`docs/benchmark-environment-bridge.md`](docs/benchmark-environment-bridge.md) | External benchmark bridge — engineering ledger |
246
+ | [`docs/evaluation-foundation.md`](docs/evaluation-foundation.md) | Evaluation Phase 0 foundation |
247
+ | [`docs/booking-saga-fsm.md`](docs/booking-saga-fsm.md) | Booking saga FSM (the M5 seam vocabulary) |
248
+ | [`docs/kimi-postmortem.md`](docs/kimi-postmortem.md) | A real AI-travel-planning failure postmortem (cautionary tale) |
249
+ | [`docs/release-notes.md`](docs/release-notes.md) | Release decisions per version (the "why") |
250
+ | [`CHANGELOG.md`](CHANGELOG.md) | Machine-derived changelog (Keep a Changelog + Conventional Commits) |
251
+ | [`docs/tokens.md`](docs/tokens.md) | npm 2FA / release mechanics |
252
+
253
+ ## License
254
+
255
+ **MIT** — same as upstream dsh. See [LICENSE](LICENSE).
245
256
 
246
257
  ---
247
258
 
248
- **Built with**: DeepSeek Harness 0.1.2-alpha.3 (root-pinned) · Cordis · Z3 (WASM) · loopx (pipx) · hotelbyte-cli · Agent-Reach v1.5.0 (`.venv/`) · OpenFlights · TypeScript
259
+ **Built with**: DeepSeek Harness 0.1.2-alpha.3 (root-pinned) · Cordis · Z3 (WASM) · loopx (pipx) · hotelbyte-cli · Agent-Reach v1.5.0 · OpenFlights · TypeScript
249
260
 
250
- **Version baseline: `v0.0.1-rc.16` (2026-08-30).** The current checkout's authoritative verification gates are enumerated by `scripts/run-all-tests.sh` (release flow: `scripts/publish-npm.sh`).
261
+ **Version baseline: `v0.0.1-rc.16` (npm `latest`).** The authoritative verification gates for the current checkout are enumerated by `scripts/run-all-tests.sh`; release flow: `scripts/publish-npm.sh`.
package/README.zh-CN.md CHANGED
@@ -1,90 +1,101 @@
1
- # GoTry
2
-
3
1
  [English](README.md) | [简体中文](README.zh-CN.md)
4
2
 
5
- [![CI](https://github.com/Danceiny/gotry/actions/workflows/ci.yml/badge.svg)](https://github.com/Danceiny/gotry/actions/workflows/ci.yml)
3
+ # GoTry
6
4
 
7
5
  > **身体和灵魂,更多旅行,更少旅游。**
8
6
  > *Body and soul — more travel, less tourism.*
9
7
 
10
- **GoTry 是「从出发到下一次出发」的 AI 旅行 Agent**:你用一句话说想去哪、为什么想出发;它先问清楚你的工作时间和已订资源,再用**数学求解器**给你一份经过验证的行程方案。
8
+ **GoTry 是「从出发到下一次出发」的 AI 旅行 Agent**:你用一句话说想去哪、为什么想出发;它先问清楚你的工作窗口和已订资源,再用 **Z3 数学求解器**给你一份经过形式化验证的行程方案——是算出来的,不是模型猜的。
11
9
 
12
- **GoTry is an AI travel agent for departure-to-next-departure.** Tell it where you want to go and why. It asks what's missing, then hands you a **formally verified itinerary** — not vibes.
10
+ [![CI](https://github.com/Danceiny/gotry/actions/workflows/ci.yml/badge.svg)](https://github.com/Danceiny/gotry/actions/workflows/ci.yml)
11
+ [![npm](https://img.shields.io/npm/v/@danceiny/gotry)](https://www.npmjs.com/package/@danceiny/gotry)
12
+ [![License: MIT](https://img.shields.io/badge/License-MIT-informational)](LICENSE)
13
+ [![Node](https://img.shields.io/badge/node-%E2%89%A5%2022.15-blue)](https://www.npmjs.com/package/@danceiny/gotry)
14
+ [![Docs](https://img.shields.io/badge/docs-architecture.md-blue)](docs/architecture.md)
13
15
 
14
- ---
16
+ **[它做什么](#它做什么)** · **[工作原理](#工作原理)** · **[工具](#工具)** · **[一段对话](#一段对话)** · **[快速开始](#快速开始)** · **[账号会话:授权与隐私](#账号会话授权与隐私)** · **[构造上可信](#构造上可信)** · **[状态与限制](#状态与限制)** · **[路线图](#路线图)** · **[给 AI Agent](#给-ai-agent)** · **[文档](#文档)** · **[License](#license)**
15
17
 
16
- ## 🚀 30 秒上手
18
+ > **新读者提示**:一条命令就能感受差别——`npx @danceiny/gotry web`,打开 `http://127.0.0.1:3080`,说一句「我想去大理躺三天」。Agent 会先访谈你;然后由求解器(而非模型)判定什么可行。完整走查见 [`docs/user-guide.md`](docs/user-guide.md)。
17
19
 
18
- ```bash
19
- npx @danceiny/gotry web
20
- # 首跑会提示建 .env:LLM_API_KEY=<DeepSeek key 或 OpenAI 兼容 key>
21
- # 不走 DeepSeek 官方?再配一行 LLM_BASE_URL=<你的端点,一般以 /v1 结尾>
22
- # 要指定模型(中转而常需要)?配 LLM_MODEL=<模型名>——同时驱动 dsh 会话面
23
- # (web/headless)与仓内脚本,并压过你在 dsh web 设置里选过的模型。
24
- # → 浏览器打开 http://127.0.0.1:3080,像聊天一样说「我想去大理三天」
25
- ```
20
+ ## 它做什么
26
21
 
27
- > **换模型 / 换中转?** 价表(`ts/data/llm-price-table.json`,schema `gotry_llm_price_table_v2`)是 `gotry_m3_nightly_run_v1.cost_usd` 唯一事实源(ADR-11)。新增模型或换中转=改本文件走 PR(peak 保守上界只高不低),未知模型 → **fail-closed 不猜价**。漂移监测:`npx tsx ts/scripts/price-drift-watch.ts`(默认离线对照 baseline 比对输出 PR-就绪 Markdown diff;`--fetch` 拉取官方页 + 首次写 fixture)。**永不自动 apply 价格**。
22
+ GoTry 把「想去哪」变成「能不能——怎么去、真实代价是多少」。当答案是「这周末不行」时,目的地连同成行条件进愿望池接住,而不是被丢掉。
28
23
 
29
- | 你想要的 | 命令 |
30
- |---|---|
31
- | 🖥️ 对话规划(推荐) | `npx @danceiny/gotry web` → :3080 对话界面 |
32
- | 🤖 脚本/一次性问答 | `npx @danceiny/gotry "我想从深圳休整两天,预算 3000"` |
33
- | 🛠️ 开发者:仓内运行 | 见下方[源码安装](#-快速开始) |
24
+ - **给旅行者** —— 一个先问对人问题(工作窗口/已订资源/出发城市/预算)的对话规划器,然后逐目的地给判决:可行/不可行、为什么、以及**让它可行的最小改动**。
25
+ - **给 Agent 工程师** —— 一个「LLM 只负责听懂、翻译、解释」的落地样本:判定与算术在 Z3 求解器里,交付物里每个数字都带来源标签,写操作从设计上就是被闸住的。
26
+ - **证据内建** —— 估算绝不冒充实时。标签由渲染层附加、模型无权染指;降级时标签如实更换。回溯不到 exact-date 工具结果的可下单 claim,交付前就被拦下。
34
27
 
35
- - 前置:Node 22.15+;一个 LLM API key。任何 OpenAI 兼容端点(MiniMax/中转/自建网关)也可——在 `.env` 另配 `LLM_BASE_URL`(一般以 `/v1` 结尾,如 `https://api.minimax.io/v1`),请求即走它而非 DeepSeek 默认端点。要锁定模型就配 `LLM_MODEL`(如 `MiniMax-M2`):对 dsh 会话面与仓内脚本同时生效,并压过 dsh web 设置里持久化的模型选择;不配则用 dsh 内置默认(`deepseek-v4-flash`)或你在 web 界面的选择。零成本启动——dsh 运行时以 cordis patch 自动挂载,无额外配置。
36
- - 例外提示:`:3080` 端口被占时先 `kill <PID>`;首启 6–15 秒属正常冷启动;异常退出会留证据到 `gotry-state/incidents.jsonl`(不静默)。
28
+ ## 工作原理
37
29
 
38
- <details>
39
- <summary>🛠️ 开发者:源码安装(仓内运行)</summary>
30
+ 一次规划是一条流水线:模型只占语言密集的两端,数值全部归求解器:
40
31
 
41
- ```bash
42
- git clone https://github.com/Danceiny/gotry && cd gotry
43
- npm ci && npm --prefix ts ci # ① 安装 root/TS 锁定依赖闭包
44
- node scripts/build-dist.mjs # ② 构建源码检出的 JS runtime
45
- cp .env.example .env # ③ 填 LLM_API_KEY(非 DeepSeek 官方另配 LLM_BASE_URL;锁定模型另配 LLM_MODEL)
46
- ./gotry web # ④ 仓内入口,同 npm 形态
47
- ```
48
-
49
- | 入口 | 命令 | 什么时候用 |
32
+ | 阶段 | 由谁做 | 给你什么 |
50
33
  |---|---|---|
51
- | dsh Web 对话(推荐) | `./gotry web` | 持续多轮规划,看推理可视化 :3080 |
52
- | headless 一问一答 | `./gotry "一句任务"` | 脚本 / CI / 定向调试 → stdout |
53
- | help | `./gotry help` | 三行帮助 |
54
-
55
- 为什么源码模式先装 root/TS 闭包并构建 dist:源码入口与 npm 包都解析同一组 216 个精确直接依赖的 DSH `0.1.2-alpha.3` closure;manifest、package-lock 与 root pnpm importer 必须暴露同一 216 项名称集合,publish preverify 会拒绝漏钉、混版和 range;源码普通运行的 dsh cwd 仍是 `ts/dsh-runtime/`,因此状态继续落 `ts/dsh-runtime/gotry-state/`;benchmark opt-in 与 npm 包运行使用调用目录隔离。`ts/dsh-runtime/` 的旧 vendored runtime 只保留为非 benchmark legacy 解析兼容,不承诺可运行,也不再是推荐安装路径。
34
+ | 动机访谈 | LLM | 必问项:工作窗口 / 已订资源 / 出发城市 |
35
+ | 事实抽取 | LLM | 工作窗口生效 + 休假语义识别 |
36
+ | 可行性判决 | **Z3 求解器** | 哪些候选可行/不可行、为什么、**最小改动让它可行** |
37
+ | 门到门全成本 | 求解器 | 真实飞行时长(含时差)+ 早起惩罚 + 接驳代价 + 到达精力 % |
38
+ | 证据链 | 渲染层 | 每个数字都带来源标签 |
39
+ | 交付闸 | 事实闸 | 可下单 claim 必须回溯到 exact-date 工具结果,否则产物 blocked |
40
+ | 记忆 | 领域层 | 当下不可行 → 愿望池,附显式召回条件 |
56
41
 
57
- </details>
42
+ 在 GoTry 的回答里会遇到的词汇:
58
43
 
59
- ---
44
+ - **证据标签** —— `[骨架:openflights]` 航线存在性经公开航线库校验;`[实时API:...]` 刚从实时接口拉回数秒;`[静态包:估算]` 调研估算——非实时,下单前请核实。降级时标签如实更换。
45
+ - **门到门全成本** —— 票价之外,这段旅程真正从你身上拿走的东西:跨时区的真实时长、早起惩罚、接驳、落地时的精力余额。
46
+ - **愿望池** —— 「下一次出发」的存储。装不下的憧憬带显式条件(如「5 天+、淡季」)入池,条件满足时被召回。
47
+ - **事实闸** —— 行程产物交付前闸:每条可下单 claim(航班号/时刻/机场/价格/政策)必须回溯到 exact-date 工具结果;回溯不到即 blocked——绝不宣称「已验证方案」。
60
48
 
61
- ## ✨ 它做什么 — What it does
49
+ 架构五层:
62
50
 
63
- GoTry 把「想去哪」变成「能不能、怎么去」:
51
+ ```
52
+ ┌──────────────────────────────────────────────────────────────┐
53
+ │ L1 对话即界面 chat-as-UI; gates 是消息内选择题 │
54
+ │ L2 编排 dsh 运行时 + GoTry 插件(ReAct);21 个工具 │
55
+ │ L3 领域 统一行程模型 + Z3 可行性引擎 │
56
+ │ L4 数据 静态数据包 + hotelbyte-cli 实时桥 + OpenFlights 骨架 │
57
+ │ L5 治理 LoopX(objective / gates / evidence / quota) │
58
+ └──────────────────────────────────────────────────────────────┘
59
+ ```
64
60
 
65
- | 阶段 | 由谁做 | 给你什么 |
61
+ | | 模块 | 角色 |
66
62
  |---|---|---|
67
- | **动机访谈** | LLM | 必问项:工作窗口 / 已订资源 / 出发城市 |
68
- | **事实抽取** | LLM | 工作窗口生效 + 休假语义识别 |
69
- | **可行性判定** | **Z3 求解器** | 哪些候选可行、哪些不可行、为什么、**最小改动让它可行** |
70
- | **门到门全成本** | 求解器 | 真实飞行时长(含时差)+ 醒来起夜惩罚 + 接驳代价 + 到达精力 % |
71
- | **证据链** | 渲染层 | 每个数字都带**来源标签**:`[骨架:openflights]`=公开航线数据校验过"这条线能飞";`[实时API:flyai]`=刚从实时接口拉的现价现况;`[静态包:估算]`=非实时的调研估算(**下单前请核实**)。降级时标签如实更换,估算绝不冒充实时 |
63
+ | L2 | `ts/src/index.ts`(dsh 插件) | 注册 21 工具,挂时间锚点/记忆 brief 变量;execute 异常隔离 + 授权闸 + 每轮工具预算 + 进程护栏 |
64
+ | L3 | `ts/src/unified.ts` · `py/gotry_feasibility/` | 唯一求解入口(候选枚举 + 航班链 Z3) |
65
+ | L4 | `ts/capabilities/effect.ts` · `hbcli.ts` · `skeleton-check.ts` | 效应解译层(退避重试/断路器/mock 解译器)+ 实时库存桥 + OpenFlights 骨架(三值语义) |
66
+ | L5 | loopx 治理面 | objective / gates / evidence / quota |
72
67
 
73
- **不像普通 AI 聊天**——LLM 只做理解和解释,**判定与算术是数学求解器**算的。
68
+ > 完整 ADR / 演进 / 债务清单:[`docs/architecture.md`](docs/architecture.md)(英文版计划 v0.1.0)。
74
69
 
75
- > **Unlike a regular AI chat**, the LLM only translates and explains. **Decisions and arithmetic are computed by a Z3 solver**, not guessed.
70
+ ## 工具
76
71
 
77
- ---
72
+ 六组共 21 个:
78
73
 
79
- ## 🎬 一段对话 Demo
74
+ | | 工具 | 干什么 |
75
+ |---|---|---|
76
+ | **实时检索(OTA/官方只读)** | `gotry_flyai_search` | 机票/火车/酒店实时报价(飞猪官方通道;酒店价格为上游打码展示,真实价以 jumpUrl 为准) |
77
+ | | `gotry_session_search` | 在**用户本人登录态**里查携程机票(授权后,只读) |
78
+ | | `gotry_session_login` | 登录引导:自动检测已登录与否,未登录才在用户 Chrome 弹登录入口(**零终端**) |
79
+ | | `gotry_weather_check` | Open-Meteo 预报≤16 天 + 历史气候基线 |
80
+ | | `gotry_flight_verify` | OpenSky ADS-B 航班实时观测(三值) |
81
+ | | `gotry_skeleton_check` | OpenFlights 168 对枢纽通航性(三值) |
82
+ | **库存与目录** | `gotry_hotel_search` | hotel-byte 实时桥,降级静态包(证据标注) |
83
+ | | `gotry_anything_search` | 城市/酒店/地标混合目录(hotel-be Anything) |
84
+ | **判定引擎** | `gotry_feasibility_check` | 门到门真成本可行性(Z3),逐候选判定 |
85
+ | **记忆与触达** | `gotry_motivation_save` | 动机画像落盘(evidence 强制,反幻觉) |
86
+ | | `gotry_wish_pool_add` / `gotry_wish_pool_list` | 「下一次出发」愿望池 + 0..1 条件召回 |
87
+ | | `gotry_companion_save` · `gotry_trip_log` | 同行人档案 / 旅行时间线 |
88
+ | **产物** | `gotry_artifacts_list` / `gotry_artifacts_read` | 发现与查看已生成的产物(异步交付 + 工作目录 markdown),行号文件视图,只读 |
89
+ | **事实闸** | `gotry_fact_gate` | 行程产物交付前闸——见上文[工作原理](#工作原理)中的定义 |
90
+ | **通用外部** | `gotry_web_search` · `gotry_video_subtitle` · `gotry_github_search` · `gotry_agent_reach` | 网页/字幕/GitHub/全渠道外部信息(经 Agent-Reach) |
80
91
 
81
- 输入 → 引擎判定 → 输出(真实输出,milliseconds 保留原味):
92
+ ## 一段对话
82
93
 
83
94
  ```
84
95
  > 我想去洱海边发呆两三天,上海出发,预算 3000,年假别让我办公。
85
96
 
86
97
  GoTry: 收到。先把约束记下来——
87
- • 窗口: 2 天(2026 年窗口) • 出发: 上海 • 预算: ¥3000 全含
98
+ • 窗口: 2 天 • 出发: 上海 • 预算: ¥3000 全含
88
99
  • 动机: 休整 / [escape_rest: 0.7] • 还没订任何东西
89
100
 
90
101
  引擎判定:
@@ -98,152 +109,160 @@ GoTry: 收到。先把约束记下来——
98
109
  [静态包:估算] G7315/G7316 价格按 7-8 月淡季估算
99
110
  ```
100
111
 
101
- > 标签导读:`[骨架:openflights]` 说的是"这条航线能飞"已被公开航线数据校验;`[实时API:*]` 说的是刚从实时接口拉回的当下数据;`[静态包:估算]` 提醒价格是淡季档估算——**订前核实**。
112
+ > 标签导读:`[骨架:openflights]` 说的是"这条航线能飞"已被公开航线数据校验;`[实时API:*]` 说的是刚从实时接口拉回的当下数据;`[静态包:估算]` 提醒价格是淡季档估算——**订前核实**。标签由渲染层附加,模型无权染指。
102
113
 
103
- > **Brief English summary**: input → engine verdicts (feasibility + whole-cost) → recommendation + wish-pool entry for infeasible candidates. Every numeric carries an evidence tag. See the 证据链 row above for what each tag means.
114
+ ## 快速开始
104
115
 
105
- ---
116
+ ### npm(推荐)
106
117
 
107
- ## 🧰 21 个工具 — Tools
118
+ ```bash
119
+ npx @danceiny/gotry web
120
+ # → 浏览器打开 http://127.0.0.1:3080,说「我想去大理躺三天」
121
+ # LLM key & 模型:由 dsh 宿主 UI 配;gotry 在 CLI 层完全不出声,不要求也不回显任何凭证
122
+ ```
108
123
 
109
- | | 工具 | 干什么 |
124
+ | 入口 | 命令 | 什么时候用 |
110
125
  |---|---|---|
111
- | **实时检索(OTA/官方只读)** | `gotry_flyai_search` | 机票/火车/酒店实时报价(飞猪官方通道;酒店价格为上游打码展示,真实价以 jumpUrl 为准) |
112
- | | `gotry_session_search` | 在**用户本人登录态**里查携程机票(授权后,只读) |
113
- | | `gotry_session_login` | 登录引导:自动检测已登录与否,未登录才在用户 Chrome 弹登录入口(**零终端**) |
114
- | | `gotry_weather_check` | Open-Meteo 预报≤16 天 + 历史气候基线 |
115
- | | `gotry_flight_verify` | OpenSky ADS-B 航班实时观测(三值) |
116
- | | `gotry_skeleton_check` | OpenFlights 168 对枢纽通航性(三值) |
117
- | **库存与目录** | `gotry_hotel_search` | hotel-byte 实时桥,降级静态包(证据标注) |
118
- | | `gotry_anything_search` | 城市/酒店/地标混合目录(hotel-be Anything) |
119
- | **判定引擎** | `gotry_feasibility_check` | 门到门真成本可行性(Z3),逐候选判定 |
120
- | **记忆与触达** | `gotry_motivation_save` | 动机画像落盘(evidence 强制,反幻觉) |
121
- | | `gotry_wish_pool_add` / `gotry_wish_pool_list` | 「下一次出发」愿望池 + 0..1 条件召回 |
122
- | | `gotry_companion_save` · `gotry_trip_log` | 同行人档案 / 旅行时间线 |
123
- | **产物** | `gotry_artifacts_list` / `gotry_artifacts_read` | 发现与查看已生成的产物(异步交付 + 工作目录 markdown),行号文件视图,只读 |
124
- | **事实闸** | `gotry_fact_gate` | 行程产物交付前闸:每条可下单 claim(航班号/时刻/机场/价格/政策)必须回溯到 exact-date 工具结果(hit/miss 均落账);无法回溯 ⇒ blocked——不得宣称「已验证方案」 |
125
- | **通用外部** | `gotry_web_search` · `gotry_video_subtitle` · `gotry_github_search` · `gotry_agent_reach` | 网页/字幕/GitHub/全渠道外部信息(经 Agent-Reach) |
126
+ | Web 对话(推荐) | `npx @danceiny/gotry web` | 持续多轮规划,看推理可视化 `:3080` |
127
+ | headless 一问一答 | `npx @danceiny/gotry "我想从深圳休整两天,预算 3000"` | 脚本 / CI / 定向调试 → stdout |
126
128
 
127
- ---
129
+ 前置:Node ≥ 22.15。LLM 凭证由 dsh 宿主 UI 配,OpenAI 兼容端点(MiniMax/中转/自建网关)走 dsh 的模型设置。首启 6–15 秒属正常冷启动;`:3080` 被占先腾端口;异常退出会留证据到 `gotry-state/incidents.jsonl`(不静默)。
128
130
 
129
- ## 🔐 账号会话:授权与隐私 Account consent
131
+ > **成本核算** —— `ts/data/llm-price-table.json`(schema `gotry_llm_price_table_v2`)是 nightly 成本核算的唯一事实源。新增模型或换中转=对该文件提 PR(peak 保守上界只高不低);未知模型 **fail-closed 不猜价**。漂移监测:`npx tsx ts/scripts/price-drift-watch.ts`(默认离线对照 baseline;`--fetch` 拉官方页)。**永不自动 apply 价格**。
130
132
 
131
- 会话检索使用**你本人已登录的 Chrome**读取酒店/机票实时数据,为此立了四条 hard 规则:
133
+ ### 开发者源码安装
132
134
 
133
- 1. **登录在外部网站完成** —— gotry 从不提供、不代填、不收集任何密码/验证码/cookie 值。它只回答一个布尔问题:"登录票据 cookie 存在吗"(只读**名字**,0 值过手)。
134
- 2. **授权卡,每会话一次** —— 首次动用账号会话会弹运行时审批卡;批准后会话内记住,拒绝即本会话吊销,不再打扰。总闸 `sessionAccess: ask|allow|off` 随时可关。
135
- 3. **物理只读** —— ReadGuard 在网络层中止一切写请求(下单/支付在传输层不可达),agent 永不接触凭证与验证码;遇到验证码立即停,交还给你。
136
- 4. **绝不劫持你的浏览器** —— 检索/登录只开自己的独立标签页,登录页置前台、留在你那;例行动测试永不自动开浏览器窗。
135
+ ```bash
136
+ git clone https://github.com/Danceiny/gotry && cd gotry
137
+ npm ci && npm --prefix ts ci # 锁定的 root/TS 依赖闭包
138
+ node scripts/build-dist.mjs # 构建 JS runtime
139
+ ./gotry web # 仓内入口,与 npm 形态同 UX
140
+ ```
137
141
 
138
- > 前置(一次性):去 [Chrome 应用商店](https://chromewebstore.google.com/detail/gotry-session-bridge/oeajpiccmonococjcegddlooeeohlbgd) 点「添加至 Chrome」——这是浏览器的事,不由 gotry 兜(`gotry setup wizard` 不复存在);想用免审核/更新更快的 GitHub 通道见 [docs/extension-webstore-submission.md](docs/extension-webstore-submission.md)。装完**零系统弹窗**——扩展只被动转发站点自己发出的检索响应(构造上只读;cookie 只读名字,值永不离开浏览器)。未安装时工具返回 `needs-extension` 并把商店 URL 作为 dsh UI 的可点链接给出,不消耗执行配额。(诊断后备:cdp 车道经 `chrome://inspect` 远程调试,`GOTRY_SESSION_TRANSPORT=cdp` 显式开启——注意 Chrome 144+ 每次连接都会弹权限框。)
142
+ 源码入口与 npm 包解析同一组 216 个精确直接依赖的 DSH `0.1.2-alpha.3` closure(publish preverify 拒绝漏钉、混版和 range)。源码普通运行状态落在 `ts/dsh-runtime/gotry-state/`;benchmark opt-in npm 包运行用调用目录隔离。
139
143
 
140
- ---
144
+ ## 账号会话:授权与隐私
141
145
 
142
- ## 🏛️ 架构 — Architecture
146
+ 账号会话通道用**你本人已登录的 Chrome**读酒店/机票实时数据,为此立了四条 hard 规则:
143
147
 
144
- ```
145
- ┌──────────────────────────────────────────────────────────────┐
146
- L1 对话即界面 chat-as-UI; gates 是消息内选择题 │
147
- L2 编排 dsh 运行时 + GoTry 插件(ReAct);21 个工具 │
148
- │ L3 领域 统一行程模型 + Z3 可行性引擎(枚举/Z3 双形态) │
149
- │ L4 数据 静态数据包 + hotelbyte-cli 实时桥 + OpenFlights 骨架 │
150
- │ L5 治理 LoopX(objective / gates / evidence / quota) │
151
- └──────────────────────────────────────────────────────────────┘
152
- ```
148
+ 1. **登录在外部网站完成** —— gotry 从不提供、不代填、不收集任何密码/验证码/cookie 值。它只回答一个布尔问题:"登录票据 cookie 存在吗"(只读**名字**,0 值过手)。已登录会被自动识别,零弹窗。
149
+ 2. **授权卡,每会话一次** —— 首次动用账号会话弹运行时审批卡;批准后会话内记住,拒绝即本会话吊销,不再打扰。总闸 `sessionAccess: ask|allow|off` 随时可关。
150
+ 3. **物理只读** —— ReadGuard 在网络层中止一切写请求(下单/支付在传输层不可达);agent 永不接触凭证与验证码,遇验证码立即停、交还给你。
151
+ 4. **绝不劫持你的浏览器** —— 检索/登录只开自己的独立标签页,登录页置前台、留在你那;例行动测试永不自动开浏览器窗。
153
152
 
154
- | | 模块 | 角色 |
155
- |---|---|---|
156
- | L2 | `ts/src/index.ts`(dsh 插件) | 注册 21 工具,挂时间锚点/记忆 brief 变量;execute 异常隔离 + 授权闸 + 进程护栏 |
157
- | L3 | `ts/src/unified.ts` · `py/gotry_feasibility/` | 唯一求解入口(候选枚举 + 航班链 Z3) |
158
- | L4 | `ts/capabilities/effect.ts` · `hbcli.ts` · `skeleton-check.ts` | 效应解译层(退避重试/断路器/mock 解译器,issue #16)+ 实时库存桥 + OpenFlights 骨架(三值语义) |
159
- | L5 | loopx 治理面 | objective / gates / evidence / quota |
153
+ 前置(一次性):[GoTry Session Bridge](https://chromewebstore.google.com/detail/gotry-session-bridge/oeajpiccmonococjcegddlooeeohlbgd) Chrome 应用商店一键装(自动更新)。账号会话工具首次需要扩展时,**由 dsh 宿主 UI 把商店 URL 作为可点链接渲染**;gotry 这边不会跑任何 setup wizard、也不会让你手动加载已解压扩展。装完**零系统弹窗**——扩展只被动转发站点自己发出的检索响应(构造上只读;cookie 只读名字,值永不离开浏览器);后台 health-watch 探活,扩展一就位自动重放你的检索。未安装时工具返回 `needs-extension` 并把商店链接置于 verdict,不消耗执行配额。
160
154
 
161
- > 📖 完整 ADR / 演进 / 债务清单: [`docs/architecture.md`](docs/architecture.md)
155
+ ## 构造上可信
162
156
 
163
- ---
157
+ 1. **模型只翻译,求解器才判决** —— LLM 永远不产出可行性判决与算术;那些由 Z3 基于抽取事实计算。
158
+ 2. **每个数字带来源标签** —— 由渲染层附加,模型无权染指;降级时如实更换,估算绝不冒充实时。
159
+ 3. **不存在写路径** —— 预订/支付类工具必须先过 WriteGate 才允许实现;未来的预订缝已被 `booking_saga_fsm.v1` 边表钉住。
160
+ 4. **登录永不碰凭证** —— 登录发生在外部网站;gotry 只读 cookie 名;授权每会话问一次、可吊销。
161
+ 5. **检索物理只读** —— ReadGuard 在网络层中止写请求;验证码让 agent 停下、把控制权交还给你。
162
+ 6. **回溯不到就是 blocked** —— 事实闸拒绝交付任何可下单 claim 无法回溯到 exact-date 工具结果的行程——绝不宣称「已验证方案」。
163
+ 7. **价格 fail-closed** —— 未知模型不猜价;价表只经 PR 变更;漂移监测只报告、永不自动 apply。
164
+ 8. **你的数据是你的** —— 产品状态在 `gotry-state/`;自动化测试与 smoke 用隔离 state root,永不写创始人的真实产品数据。
165
+
166
+ ## 状态与限制
164
167
 
165
- ## ⚠️ 状态与限制 Status & limitations
168
+ 当前版本:**v0.0.1-rc.17**(npm dist-tag `rc`;`latest` 仍指 rc.16,沿用 dsh-管-LLM 安装口径)。评测处于 Phase 0 基座——确定性合同、校验器与节奏策略;无外部 benchmark 分数、无花费、无 uplift 声明。
166
169
 
167
- **今天可用的能力**(全栈回归 §1–§34 全绿,每项都有确定性测试):
170
+ **今天可用**(全栈回归全绿;每项都有确定性测试):
168
171
 
169
- - **Z3 求解引擎** —— 可行性判定 + 门到门全成本;历史并发竞态已根治(§30 并发回归闸)
170
- - **实时检索**:机票/火车/酒店(飞猪官方通道)、目的地/酒店目录、天气、航班观测、通航性校验;可选让实时票价覆写进求解(`GOTRY_REALTIME_PRICING=1`)
171
- - **账号会话检索**:你本人登录态查携程机票,授权与隐私规则见上方 **🔐 账号会话:授权与隐私** 小节
172
- - **一次性浏览器扩展安装**:去 [Chrome 应用商店](https://chromewebstore.google.com/detail/gotry-session-bridge/oeajpiccmonococjcegddlooeeohlbgd) 点「添加至 Chrome」(浏览器的事,gotry 不介入);扩展未装时 `gotry_session_search` 返回的 `needs-extension` dsh UI 把商店 URL 渲成可点链接;后台 health-watch 探活,扩展一就位自动重放你的检索,**无需你手动重跑命令**
173
- - **扩展分发三通道(issue #21,ADR-21)**:同一扩展三个通道——[Chrome 应用商店](https://chromewebstore.google.com/detail/gotry-session-bridge/oeajpiccmonococjcegddlooeeohlbgd)(dsh 用户就走这条:一键装 + 自动更新,2026-09-02 上架);GitHub Releases 通道(免审核、版本更新更快,见 docs/extension-webstore-submission.md);包内副本保离线兜底。商店用自己签名 key 重签,商店版扩展 ID 与 unpacked 固定 ID 不同,本机桥双 Origin 白名单同信(§38 回归)
174
- - **会话数据交叉验证(issue #21 / #67)**:8 条 sf-01..sf-08 benchmark query 端到端验证 —— 7/8 verdict=hit / 6/6 manual-golden 软命中 100% / hit 全部 <15s / ReadGuard 零写。对照源可插拔:`--golden=manual`(默认)、`--golden=flyai`、`--golden=static`。static 模式以 OpenFlights ODbL 固定修订提供航线/承运人,叠加手工时刻与价格带;evidence 分开记录请求源/实际源、provenance、estimated fields 与 fallback reason。快照/路由异常会向 stderr 告警后回退 manual。static 是确定性 benchmark 数据,**不是实时班期、票价或库存**。
175
- - **static 源登录态观测(2026-08-30)**:连续两轮 static official 均 8/8 hit、零 fallback;携程 session hit 从 3/8 波动到 5/8,两轮所有可评分 hit(3+5 条)全部 13/13(100%)。非 hit 均是显式 `miss`,因此 ≥90% 字段分不表述为 8/8 实时可售。同轮修复扩展在线时空闲 parked timer/socket 钉住默认 CLI 桥的生命周期缺口,wizardless `keepBridge` 语义不变(§38:24/24,§40:9/9)。
176
- - **记忆与触达**:动机画像 / 愿望池 / 同行人 / 旅行时间线;英文输出一键切换(`GOTRY_LOCALE=en`)
172
+ - **Z3 求解引擎** —— 可行性判决 + 门到门全成本;历史并发竞态已根治并进回归闸
173
+ - **实时检索** —— 机票/火车/酒店(飞猪官方通道)、目的地/酒店目录、天气、航班观测、通航性校验;实时票价可覆写求解价(`GOTRY_REALTIME_PRICING=1`)
174
+ - **账号会话检索** —— 你本人登录态查携程机票;观测轮次中所有可评分 hit 全过、ReadGuard 零写,非 hit 保持显式 `miss` 记录——不作超出此口径的实时可售声明
175
+ - **扩展按需装** —— `[GoTry Session Bridge](https://chromewebstore.google.com/detail/gotry-session-bridge/oeajpiccmonococjcegddlooeeohlbgd)` dsh 宿主 UI 在账号会话工具首次需要时以可点链接给出(Chrome 商店一键装 + 自动更新);gotry 这边不跑 setup wizard、不开 chrome://extensions、不动剪贴板
176
+ - **记忆与触达** —— 动机画像 / 愿望池 / 同行人 / 旅行时间线;英文输出一键切换(`GOTRY_LOCALE=en`)
177
+ - **有界的工具循环** —— 16 次派发后注入软收敛,18 次后结构化 `TOOL_BUDGET_EXHAUSTED` 拒绝;经打包消费者安装的 E2E CI 里实测
177
178
 
178
- **已知限制**(截至 2026-08-29,诚实清单):
179
+ **已知限制**(诚实清单):
179
180
 
180
- - **M3 Exit 未关闭** —— 工程与分发面就绪,但"真实种子用户"证据(50–200 人 cohort)尚未积累;自动化测试证明的是合同与公式,不是 business pass
181
- - **携程酒店 / 美团的登录态会话适配** —— 机票已通,酒店面等登录态实测回填(下一个 tick)
182
- - **界面语言** —— 英文界面仅覆盖求解确定性输出层;dsh 宿主界面与对话面属宿主/校准件
183
- - **外部 benchmark 泛化 / Phase 1 bridge** —— Round 1 的 exact DeepSeek treatment 为 environment unavailable/schema-invalid(score 0),GLM 为 300 秒超时。Round 2 建立 default-off owner-local bridge;其冻结 treatment 因没有 structured native bridge call 与 tagged JSON,只到 diagnostic-only。Round 3 增加 provider-neutral 的 native call/result/terminal conformance,但新冻结 treatment 仍在 runner 仅派发一次后以 planner/runner exit 1 停止,parent 释放 0 字节终态,evaluator 未进入,official scores 全为 null。Round 4 treatment(SHA `5ebddb2`)primary preflight=pass,但 planner/runner 均在 30.968s 以 exit 1 结束,释放 0 字节,evaluator 未进入,official scores 全为 null。产品 gate 使用 Node v24.20.0,而该 treatment 使用 v26.3.0,因此该结果仅 diagnostic-only,不产生 uplift。GitHub Node 22/24 §48 另暴露 source default-off 30s lifecycle hang。Round 5 仅限移除 timer/keepalive preload、将 root/package DSH closure 锁定为 alpha.3、让 source checkout 优先解析该锁定 runtime、保留源码普通运行的 `ts/dsh-runtime/gotry-state/` 状态连续性、让 benchmark/package 用调用目录隔离、在 spawn 前拒绝非 alpha.3 benchmark runtime、强制 Node 22.15+,并增加 benchmark-only 结构化诊断 pipe(allowlisted redacted reason codes),stdout 继续 fail-closed;其 frozen treatment(代码 SHA `752e54c`)在 140.715 秒后以 `child_nonzero_exit`、0 terminal bytes、evaluator/official scores null 停止,仅 diagnostic-only,后续纯 lock-consistency 提交不改写该 UID 归属。跨 benchmark 证据仍待运行,不声称 external benchmark closure。详见 [`docs/benchmark-environment-bridge.md`](docs/benchmark-environment-bridge.md)
184
- - **Round 6 结构化终态诊断** —— benchmark 模式只把最终结构化 `turn/end` 投影为闭合、脱敏的模型/运行时原因族;per-session 仲裁最多写一次,且 bridge/conformance 专项原因优先于后续 generic runtime。恢复成功的 transient retry 不写失败;message、raw stderr、路径、prompt、request id 与凭证不跨控制通道。代码 SHA `c61600b` 的 ChinaTravel 冻结 treatment(`..._00001`,`deepseek-v4-flash`)在 49.546 秒后以 `child_runtime_error`、0 terminal bytes、evaluator/official scores null 停止;leakage 与本地凭证/端点扫描均为 0。该证据只改善归因,不产生 score/uplift 结论;后续纯文档 successor 不改写 treatment 归属。
185
- - ⏳ **Round 7 minimal kernel** —— 代码 SHA `edb9392896625adbb48abae4a2ecf968dbfc0349` 的 benchmark opt-in 仅保留 tool budget、model override、唯一 bridge、isolation/conformance;不装产品 prompt variables、process guards、consent hooks 与普通 GoTry tools,默认路径不变。CLI 将系统人格投影为稳定、task-agnostic persona,root patch 只接受 canonical `insert` 与 `system-prompt` 各一,缺失、重复、quoted、reordered、flow 或其他非 canonical root item 均 fail-closed。ChinaTravel 冻结 treatment UID `e20241028160248698752`(`easy`,`deepseek-v4-flash`)preflight pass 且未回退,80.463 秒后 runner exit 1、terminal 0 bytes/invalid,evaluator 未进入、official null、不可计分;白名单归因为 `child_bridge_runner_failed`,不产生 uplift 或 external benchmark closure。下一轮聚焦 generic bridge tool schema 与可恢复 domain-error contract。
181
+ - **M3 Exit 未关闭** —— 工程与分发面就绪,但真实种子用户证据(50–200 人 cohort)尚未积累;自动化测试证明的是合同与公式,不是 business pass
182
+ - **酒店会话适配** —— 携程酒店/美团登录态面等实测回填;机票已通
183
+ - **界面语言** —— 英文仅覆盖求解确定性输出层;dsh 宿主界面与对话面属宿主/校准件
184
+ - **外部 benchmark 泛化** —— 迄今所有冻结外部运行均仅 diagnostic(无分数、无 uplift 声明);逐轮工程台账见 [`docs/benchmark-environment-bridge.md`](docs/benchmark-environment-bridge.md)
185
+ - **预订** —— 今天没有任何可下单路径;M5 只经 WriteGate booking-saga 状态机启封
186
186
 
187
187
  <details>
188
- <summary>📖 更深的工程状态(账本合同 / 证据合同 / 里程碑口径)</summary>
188
+ <summary>更深的工程状态(账本合同 / 证据合同 / 里程碑口径)</summary>
189
189
 
190
- 状态权威面在这里,README 不展开:事务化状态账本(ADR-15)+ 双形态冻结(ADR-16:本地+Web 一套账本语义);M3 真实 cohort 证据合同已立(fixture 不充当 Exit,真实 50–200 人样本即开 Exit);M4 paired-cohort 价值证据合同(run-all §34)合成数据不充当 Exit 证据;异步工单终态合同(`gotry_async_terminal.v1`:4/4→succeeded/ledger settled/exit 0)。细则见 [`docs/roadmap.md`](docs/roadmap.md) / [`docs/architecture.md`](docs/architecture.md) §1 与 #19–#22。
190
+ 状态权威面在文档,不在 README:事务化状态账本(ADR-15)+ 双形态冻结(ADR-16:本地+Web 一套账本语义);M3 真实 cohort 证据合同已立(fixture 不充当 Exit,真实 50–200 人样本即开 Exit);M4 paired-cohort 价值证据合同(合成数据不充当 Exit 证据);异步工单终态合同(`gotry_async_terminal.v1`:4/4 succeeded / ledger settled / exit 0)。细则见 [`docs/roadmap.md`](docs/roadmap.md) / [`docs/architecture.md`](docs/architecture.md) §1 与 #19–#22。
191
191
 
192
192
  </details>
193
193
 
194
- ---
195
-
196
- ## 📚 文档 — Docs
194
+ ## 路线图
197
195
 
198
- | 文档 | 适合谁 |
199
- |---|---|
200
- | [本 README](README.md) | **所有人**:是什么 · 怎么用 · 限制 |
201
- | [`docs/architecture.md`](docs/architecture.md) | 工程师:分层 · ADR · 演进 · 债务 |
202
- | [`docs/roadmap.md`](docs/roadmap.md) | 项目管理:M0–M6 与当前位置 |
203
- | [`docs/user-guide.md`](docs/user-guide.md) | 终端用户:详细使用文档 |
204
- | [`docs/gotry-product-design.md`](docs/gotry-product-design.md) | 产品:主循环 · 透明机制 · 全成本模型 |
205
- | [`docs/gotry-master-outline.md`](docs/gotry-master-outline.md) | 决策者:工作分解 · 复用矩阵 |
206
- | [`docs/kimi-postmortem.md`](docs/kimi-postmortem.md) | 所有人:真实 AI 旅行规划失败复盘(反面教材) |
207
- | [`docs/release-notes.md`](docs/release-notes.md) | 历史:每个 tag 的发布闸勾稽 |
196
+ | # | 里程碑 | 范围 | 状态 |
197
+ |---|---|---|---|
198
+ | M0 | 确定性管道 | 引擎双实现 + 真实数据包 + 对账框架 | ✅ |
199
+ | M1 | Agent 形态成立 | LLM 进环;对话即界面;gates 选择题 | ✅ 2026-08-22 |
200
+ | M2 | 实时数据 | hotelbyte 桥 + 航班源;证据链换实时标签 | ✅ 2026-08-22 |
201
+ | M3 | 最小可用产品 | 最小 Web 面 + 50–200 种子用户(洱海/普吉场景) | **← 当前 —— evidence 未收口** |
202
+ | M4 | 记忆与「下一次出发」 | 六层记忆 C 端域;paired-cohort 价值证据 | founder 授权并行 |
203
+ | M5 | 交易闭环 | WriteGate 上生产;预订 / 支付 / 退改 | entry gate 启封 |
204
+ | M6 | B2B 包裹 | principal/sponsor 插件,内核零改动 | entry gate 启封 |
208
205
 
209
- ---
206
+ 唯一权威时间线(逐里程碑的进入/退出条件、交付物与 gate):[`docs/roadmap.md`](docs/roadmap.md)。
210
207
 
211
- ## 🧪 跑测试 — Verify
208
+ ## 跑测试
212
209
 
213
210
  ```bash
214
- ./scripts/run-all-tests.sh
211
+ ./scripts/run-all-tests.sh # 全栈套件(纯 TS,无 Python 依赖)
212
+ cd ts
213
+ npx tsx scripts/evaluation-contract-tests.ts # 评测 Phase 0 合同(离线)
214
+ npx tsx scripts/evaluation-cadence-tests.ts # 确定性节奏策略/planner
215
215
  ```
216
216
 
217
- 全栈一次性绿(纯 TS,无 Python 依赖):engine/journey/unified 金标准 · 对话重放 · 异步工单跨进程 · 插件 smoke · hbcli · 进程护栏(含工具异常隔离)· 天气 · 航班 · Anything · probePoi · agent-reach(web/deep/wrapper)· 双路径稳定性 · 时间感评测(锚点卡/槽位过期校验/评分器/mock 回放;真模型巡检 `time-eval-tests.ts --real` 记忆域(动机合并守门/效用 sidecar/只读指标投影)· **Z3 并发竞态(§30)· 实时票价桥(§31)· i18n 目录(§32)· M3 cohort 证据合同(§33)· M4 价值证据合同(§34)· 会话传输扩展桥(§38)· 扩展 onboarding 静态预检(§40)· 可下单事实闸(§39)· 扩展分发通道(§43)· sf-live static-golden 离线合同(§44)**。真实 runner 为 `cd ts && npx tsx scripts/sf-live-benchmark.ts --golden=static`,仍需用户 Chrome 会话扩展在线。
217
+ 套件覆盖金标准引擎、对话重放、跨进程异步工单、插件 smoke、实时桥、进程护栏、i18n、记忆域、Z3 并发闸、事实闸、打包消费者工具预算 E2E 等;权威分节以 `scripts/run-all-tests.sh` 实际枚举为准。真实会话 benchmark(`npx tsx scripts/sf-live-benchmark.ts --golden=static`)为 opt-in,需你的 Chrome 会话扩展在线,永不进 CI。
218
218
 
219
- ---
219
+ ## 参与开发
220
220
 
221
- ## 🤝 参与开发 Contributing
221
+ 从最新 `main` 切出 `feat/ · fix/ · docs/ · chore/` 分支,本地全栈绿后开 Pull Request——`main` 不直接推。CI(Node 22/24,typecheck + 全部套件)与维护者 review 双绿后 squash 合入。**测试红着不许合。** 完整指南:[CONTRIBUTING.md](CONTRIBUTING.md)。Bug/功能建议:用 issue 模板(先搜既有 issue)。
222
222
 
223
- > *PR-based flow: branch off the latest `main`, full suite green, open a Pull Request — `main` never takes direct pushes; merge after review. Full guide: [CONTRIBUTING.md](CONTRIBUTING.md).*
223
+ ## AI Agent
224
224
 
225
- 标准开源流程:**`main` 不直接推**——从最新 `main` 切出 `feat/ · fix/ · docs/ · chore/` 分支,本地全栈绿后开 Pull Request,CI(Node 22/24,typecheck + 全部套件)与维护者 review 双绿后 squash 合入。**测试红着不许合。**
225
+ 如果你是在本仓工作的 agent,[`AGENTS.md`](AGENTS.md) 是绑定契约,先读它。要点:
226
226
 
227
- - 完整贡献指南(环境搭建 · 测试 · 分支与提交约定 · PR 流程): **[CONTRIBUTING.md](CONTRIBUTING.md)**
228
- - Bug / 功能建议:[issue 模板](.github/ISSUE_TEMPLATE/bug_report.yml)(搜过既有 issue 再提)
229
- - 行为或架构改动先立 ADR(`docs/architecture.md` §8);多 agent 协作契约见 [`AGENTS.md`](AGENTS.md)
227
+ - **入场先清扫异步工单**:`ts/gotry-state/async/*.json` 无同名 `.deliverable.md` `cd ts && npx tsx scripts/async-collect.ts <id>`。
228
+ - **分层纪律**:算术只在 `model.ts` / `unified.py` 的 evaluate 层;求解只在 `unified.ts` / `unified.py`;`engine.*` / `journey.*` 是 deprecated 兼容层,新代码不得调用。改任何一侧必须跑全栈回归。
229
+ - **绝不写共享状态**:`ts/dsh-runtime/gotry-state/` 是创始人真实产品数据;验证写路径只用隔离 `stateRoot`。
230
+ - **状态同步纪律**:任何改变系统形态/状态/债务的提交,必须在同一提交内同步 `architecture.md` §11 六状态面;只暂存具名文件——禁止 `git add -A`。
230
231
 
231
- ---
232
+ 程序层语境:[`docs/gotry-master-outline.md`](docs/gotry-master-outline.md)。技术权威面:[`docs/architecture.md`](docs/architecture.md)。
232
233
 
233
- ## 📜 License
234
+ ## 文档
234
235
 
235
- **MIT**(2026-08-23 落定)。与上游 dsh(MIT)/ loopx 一致——宽松、可商用、可闭源分叉。文本见 [LICENSE](LICENSE)。
236
+ | 文档 | 内容 |
237
+ |---|---|
238
+ | [`docs/architecture.md`](docs/architecture.md) | 系统 / ADR / 演进 / 债务清单(中文,权威) |
239
+ | [`docs/gotry-master-outline.md`](docs/gotry-master-outline.md) | 总纲:工作分解 · 复用矩阵 |
240
+ | [`docs/gotry-product-design.md`](docs/gotry-product-design.md) | 产品设计:主循环 · 透明机制 · 全成本模型 |
241
+ | [`docs/roadmap.md`](docs/roadmap.md) | M0–M6 时间线与当前位置 |
242
+ | [`docs/user-guide.md`](docs/user-guide.md) | 终端用户使用指南 |
243
+ | [`docs/data-sources.md`](docs/data-sources.md) | 数据源与证据链政策 |
244
+ | [`docs/extension-privacy.md`](docs/extension-privacy.md) | Session Bridge 扩展隐私 |
245
+ | [`docs/benchmark-environment-bridge.md`](docs/benchmark-environment-bridge.md) | 外部 benchmark 桥——工程台账 |
246
+ | [`docs/evaluation-foundation.md`](docs/evaluation-foundation.md) | 评测 Phase 0 基座 |
247
+ | [`docs/booking-saga-fsm.md`](docs/booking-saga-fsm.md) | 预订 saga 状态机(M5 缝词汇) |
248
+ | [`docs/kimi-postmortem.md`](docs/kimi-postmortem.md) | 一次真实 AI 旅行规划失败复盘(反面教材) |
249
+ | [`docs/release-notes.md`](docs/release-notes.md) | 逐版本发布决策(「为什么」) |
250
+ | [`CHANGELOG.md`](CHANGELOG.md) | 机器衍生的变更日志(Keep a Changelog + Conventional Commits) |
251
+ | [`docs/tokens.md`](docs/tokens.md) | npm 2FA / 发布机制 |
252
+
253
+ ## License
254
+
255
+ **MIT**——与上游 dsh 一致。文本见 [LICENSE](LICENSE)。
236
256
 
237
257
  ---
238
258
 
239
- ## 🌐 中英版 Locales
259
+ **Built with**: DeepSeek Harness 0.1.2-alpha.3 (root-pinned) · Cordis · Z3 (WASM) · loopx (pipx) · hotelbyte-cli · Agent-Reach v1.5.0 · OpenFlights · TypeScript
240
260
 
241
- - 本文件(main)**英文版独立成文**:[README.md](README.md)——两文件各自完整,常见开源双语布局。
242
- - 深 README(中文)面向中国出境首发种子用户群;英文版是它的完整镜像(不含深度工程文档)。
243
- - `docs/` 深度工程文档当前中文先行,英文版计划 v0.1.0 同步。
261
+ **版本基线:`v0.0.1-rc.17`(npm dist-tag `rc`;`latest` 沿用 rc.16)。** 当前 checkout 的权威验证闸以 `scripts/run-all-tests.sh` 实际枚举为准;发布流程见 `scripts/publish-npm.sh`。
244
262
 
245
263
  ---
246
264
 
247
- **Built with**: DeepSeek Harness 0.1.2-alpha.3 (root-pinned) · Cordis · Z3 (WASM) · loopx (pipx) · hotelbyte-cli · Agent-Reach v1.5.0 (`.venv/`) · OpenFlights · TypeScript
265
+ ## 中英版说明
248
266
 
249
- **版本基线:`v0.0.1-rc.16`(2026-08-30)。** 当前 checkout 的权威验证闸以 `scripts/run-all-tests.sh` 实际分节为准(发布流程见 `scripts/publish-npm.sh`)。
267
+ - 本文件与 [README.md](README.md) 各自完整自含、结构互为镜像(常见开源双语布局)
268
+ - `docs/` 深度工程文档当前中文先行,英文版计划 v0.1.0 同步。
@@ -440,12 +440,10 @@ async function runInlineHealthWatch(timeoutMs) {
440
440
  }
441
441
 
442
442
  async function main() {
443
- // wizard 子命令(2026-09-02 商店上架后退化):**只走 stdout 提示 + 健康探活等待**;
444
- // 不 spawn 任何 GUI 工具(不动 pbcopy / osascript / open / xdg-open / zenity),
445
- // 不打开 chrome://extensions,不动扩展路径——浏览器自己当安装器,gotry 不越界。
446
- // 期望用户路径:`npx gotry web` → dsh UI → 调 gotry_session_search 遇 needs-extension
447
- // → dsh UI 渲商店 URL → 用户点链接 → 装好 → 同会话内自动 retry(health-watch)。
448
- if (WIZARD) {
443
+ // wizard 子命令(2026-09-02 商店上架后退化):**只走 stdout 提示 + 健康探活等待**;
444
+ // 不 spawn 任何 GUI 工具(不动 pbcopy / osascript / open / xdg-open / zenity),
445
+ // 不打开 chrome://extensions,不动扩展路径——浏览器自己当安装器,gotry 不越界。
446
+ if (WIZARD) {
449
447
  if (WIZARD_DRY_RUN) {
450
448
  say('[gotry-wizard] dry-run(零网络零浏览器零剪贴板;run-all §40 走这条)')
451
449
  say(' 步骤: ensure-extension-files → watch-extension-ready(2 步纯 Node 端)')
@@ -467,44 +465,33 @@ async function main() {
467
465
  const watchResult = await runHealthWatch()
468
466
  if (watchResult.ready) {
469
467
  say(`[gotry-wizard] ✅ 扩展就绪(${watchResult.attempts} 次探活,等待 ${watchResult.waitedMs}ms)`)
470
- say('[gotry-wizard] 现在 `npx gotry web` → dsh UI → 调 gotry_session_search 即可拿到结果。')
471
468
  process.exit(0)
472
469
  } else {
473
470
  say(`[gotry-wizard] ✗ ${watchResult.reason}——未在 ${watchResult.timeoutMs}ms 内就绪`)
474
- say('[gotry-wizard] dsh UI 中 `gotry_session_search` 的 needs-extension 仍带商店链接;无需重跑,wizard 完全幂等。')
471
+ say('[gotry-wizard] 不需重跑;扩展未装时 dsh UI 中 gotry_session_search 的 needs-extension 会带商店链接,wizard 完全幂等。')
475
472
  process.exit(1)
476
473
  }
477
474
  }
478
475
 
479
476
  if (process.platform === 'win32') {
480
- say('[gotry-setup] Windows 暂不支持自动安装(hbcli 上游仅 darwin/linux)。手动指引:')
481
- say(` hbcli: ${HBCLI_INSTALL_CMD}(WSL);agent-reach: python -m venv .venv && .venv/Scripts/pip install ${REACH_INSTALL_URL}`)
482
- say(' dsh-better-sidebar: npx -y --package @deepseek-ai/dsh dsh plugin --profile web add dsh-better-sidebar@latest')
483
- say(' GoTry Session Bridge 扩展:推荐 Chrome 应用商店一键安装 https://chromewebstore.google.com/detail/gotry-session-bridge/oeajpiccmonococjcegddlooeeohlbgd ;本地通道:手动把包内 extension/ 目录拷到 %USERPROFILE%\\.gotry\\extension,再在 chrome://extensions 开发者模式「加载已解压的扩展程序」')
477
+ say('[gotry-setup] GoTry Session Bridge 扩展:推荐 Chrome 应用商店一键安装 https://chromewebstore.google.com/detail/gotry-session-bridge/oeajpiccmonococjcegddlooeeohlbgd ;本地通道:手动把包内 extension/ 目录拷到 %USERPROFILE%\\.gotry\\extension,再在 chrome://extensions 开发者模式「加载已解压的扩展程序」')
484
478
  process.exit(AUTO ? 0 : 1)
485
479
  }
486
480
  if (AUTO && (process.env.CI || process.env.GOTRY_SETUP_SKIP === '1')) {
487
- say('[gotry-setup] CI/GOTRY_SETUP_SKIP 检测——跳过外部依赖自举(可随时手动: npx gotry setup)')
488
- say('GoTry installed. Run: npx gotry web (dsh Web UI on :3080)')
481
+ say('[gotry-setup] CI/GOTRY_SETUP_SKIP 检测——跳过')
489
482
  process.exit(0)
490
483
  }
491
484
  if (!AUTO && process.env.GOTRY_SETUP_SKIP === '1') { say('[gotry-setup] GOTRY_SETUP_SKIP=1——跳过'); process.exit(0) }
492
485
  const results = []
493
- if (process.env.GOTRY_SETUP_HBCLI !== '0') results.push(await setupHbcli())
494
- else say('[gotry-setup] hbcli:GOTRY_SETUP_HBCLI=0 跳过')
495
- if (process.env.GOTRY_SETUP_REACH !== '0') results.push(await setupReach())
496
- else say('[gotry-setup] agent-reach:GOTRY_SETUP_REACH=0 跳过')
497
- if (process.env.GOTRY_SETUP_SIDEBAR !== '0') results.push(await setupSidebar())
498
- else say('[gotry-setup] dsh-better-sidebar:GOTRY_SETUP_SIDEBAR=0 跳过')
486
+ // gotry 自留面只剩扩展是否就位;hbcli/agent-reach/dsh-better-sidebar 由各自宿主生态自管。
499
487
  if (process.env.GOTRY_SETUP_EXTENSION !== '0') results.push(await (EXTENSION_FROM === 'github' ? setupExtensionFromGithub() : setupExtension()))
500
488
  else say('[gotry-setup] GoTry Session Bridge 扩展:GOTRY_SETUP_EXTENSION=0 跳过')
501
- say('[gotry-setup] flyai:无需安装(npx 每次自拉 @fly-ai/flyai-cli,免 key)')
502
489
  const failed = results.filter((r) => !r.ok).length
503
490
  if (failed > 0) {
504
- say(`[gotry-setup] ${failed} 项未就绪——gotry 本体不受影响(各能力均有降级路径);可稍后重跑: npx gotry setup`)
491
+ say(`[gotry-setup] ${failed} 项未就绪——gotry 本体不受影响;可稍后重跑: npx gotry setup`)
505
492
  process.exit(AUTO ? 0 : 1)
506
493
  }
507
- say('[gotry-setup] 全部就绪。Run: npx gotry web')
494
+ say('[gotry-setup] 扩展就绪检查完成。')
508
495
  process.exit(0)
509
496
  }
510
497
 
@@ -86,10 +86,6 @@ Usage:
86
86
  gotry "一段完整任务..." # headless 一问一答
87
87
  gotry help # this help
88
88
 
89
- Prerequisites:
90
- • Node 22.15+
91
- • \`.env\` 里 LLM_API_KEY (DeepSeek / OpenAI 兼容均可;自定义端点另配 LLM_BASE_URL,一般以 /v1 结尾;指定模型另配 LLM_MODEL,同时驱动 dsh 会话面与仓内脚本)
92
-
93
89
  Detail: https://github.com/Danceiny/gotry — README
94
90
  `)
95
91
  process.exit(0)
@@ -450,20 +446,8 @@ const terminateOnSignal = (signal, listener) => {
450
446
  process.off(signal, listener)
451
447
  process.kill(process.pid, signal)
452
448
  }
453
- const onSigint = () => terminateOnSignal('SIGINT', onSigint)
454
- const onSigterm = () => terminateOnSignal('SIGTERM', onSigterm)
455
- process.once('SIGINT', onSigint)
456
- process.once('SIGTERM', onSigterm)
457
- if (!process.env.DEEPSEEK_API_KEY && mode !== 'help') {
458
- console.error('[gotry] 缺少 LLM API key —— 两种方式任选其一后重跑:')
459
- console.error(` 1) 在当前目录创建 .env 写入一行: LLM_API_KEY=<你的 DeepSeek key>(key 从 https://platform.deepseek.com 获取)`)
460
- console.error(' 2) 或临时环境变量: export LLM_API_KEY=<key>')
461
- cleanupPatch()
462
- process.exit(1)
463
- }
464
-
465
- // --- 调 vendored dsh 二进制(不走 npx)---
466
- // headless: 第一个非 -- 之后的参数是 task —— gotry argv 0 是 headless 触发,其余都算 task;
449
+ // LLM key dsh 宿主管理(凭证是用户资产,UI 在 dsh 里;gotry 不拦截启动期,
450
+ // 不在用户面前展示任何 key 配置引导),此处直接放手 spawn dsh。
467
451
  const binJs = mode === 'web'
468
452
  ? ['web', '--patch', patchPath, ...(process.argv.includes('--no-open') ? ['--no-open'] : [])]
469
453
  : ['--profile', 'headless', '--patch', patchPath, ...rest]
@@ -32,20 +32,19 @@ const c1 = runBootstrap([
32
32
  '--check-only'
33
33
  ], {});
34
34
  assert.equal(c1.code, 0, `--check-only 应 exit 0,实际 ${c1.code}\n${c1.out}`);
35
- assert.ok(c1.out.includes('hbcli'), '报告应含 hbcli ');
36
- assert.ok(c1.out.includes('agent-reach'), '报告应含 agent-reach ');
37
- assert.ok(c1.out.includes('flyai'), '报告应含 flyai(无需安装)');
38
- assert.ok(c1.out.includes('dsh-better-sidebar'), '报告应含 dsh-better-sidebar(issue #25 产物查看面)');
39
- assert.ok(c1.out.includes('Session Bridge'), '报告应含会话扩展节(issue #21 传输层方案 C)');
40
- console.log('1. --check-only 探测报告 exit 0(hbcli/agent-reach/flyai/dsh-better-sidebar/会话扩展 五节齐)OK');
35
+ assert.ok(c1.out.includes('Session Bridge'), '报告应含扩展就位节(issue #21 传输层方案 C)');
36
+ assert.ok(!c1.out.includes('hbcli'), 'setup 不再替用户管 hbcli(已让出)');
37
+ assert.ok(!c1.out.includes('agent-reach'), 'setup 不再替用户管 agent-reach(已让出)');
38
+ assert.ok(!c1.out.includes('dsh-better-sidebar'), 'setup 不再替用户管 dsh-better-sidebar(已让出)');
39
+ console.log('1. --check-only 探测报告 exit 0(扩展就位 + 让出 hbcli/agent-reach/sidebar)OK');
41
40
  const c2 = runBootstrap([
42
41
  '--auto'
43
42
  ], {
44
43
  GOTRY_SETUP_SKIP: '1'
45
44
  });
46
- assert.equal(c2.code, 0, '--auto 跳过态应 exit 0(永不挡 npm install)');
45
+ assert.equal(c2.code, 0, '--auto 跳过态应 exit 0');
47
46
  assert.ok(c2.out.includes('跳过'), '应输出跳过说明');
48
- console.log('2. --auto + GOTRY_SETUP_SKIP=1 → exit 0(安装永不失败)OK');
47
+ console.log('2. --auto + GOTRY_SETUP_SKIP=1 → exit 0(永不挡 npm install)OK');
49
48
  const c3 = runBootstrap([], {
50
49
  GOTRY_SETUP_SKIP: '1'
51
50
  });
@@ -55,45 +54,32 @@ console.log('3. 显式模式 + GOTRY_SETUP_SKIP=1 → exit 0 OK');
55
54
  const c4 = runBootstrap([
56
55
  '--check-only'
57
56
  ], {
58
- GOTRY_SETUP_SIDEBAR: '0'
57
+ GOTRY_SETUP_EXTENSION: '0'
59
58
  });
60
59
  assert.equal(c4.code, 0, '单项跳过态应 exit 0');
61
- assert.ok(c4.out.includes('GOTRY_SETUP_SIDEBAR=0 跳过'), '应输出侧栏单项跳过说明');
62
- assert.ok(c4.out.includes('hbcli'), '其余节不受单项开关影响');
63
- console.log('4. GOTRY_SETUP_SIDEBAR=0 单项跳过(其余节照常)OK');
60
+ assert.ok(c4.out.includes('GOTRY_SETUP_EXTENSION=0 跳过'), '应输出扩展单项跳过说明');
61
+ console.log('4. GOTRY_SETUP_EXTENSION=0 单项跳过 OK');
64
62
  const c5 = runBootstrap([
65
- '--check-only'
66
- ], {});
67
- assert.ok(c5.out.includes('.gotry/extension'), '扩展报告应含落位路径 ~/.gotry/extension(绝对路径形态)');
68
- const c5b = runBootstrap([
69
- '--check-only'
70
- ], {
71
- GOTRY_SETUP_EXTENSION: '0'
72
- });
73
- assert.equal(c5b.code, 0, '扩展单项跳过态应 exit 0');
74
- assert.ok(c5b.out.includes('GOTRY_SETUP_EXTENSION=0 跳过'), '应输出扩展单项跳过说明');
75
- console.log('5. 会话扩展节(check-only 报告 + GOTRY_SETUP_EXTENSION=0 单项跳过)OK');
76
- const c6 = runBootstrap([
77
63
  'wizard',
78
64
  '--dry-run'
79
65
  ], {});
80
- assert.equal(c6.code, 0, `wizard --dry-run 应 exit 0,实际 ${c6.code}\n${c6.out}`);
81
- assert.ok(c6.out.includes('dry-run'), '应输出 dry-run 字样');
82
- assert.ok(c6.out.includes('gotry-wizard'), '应输出 [gotry-wizard] 标签');
83
- assert.ok(c6.out.includes('ensure-extension-files'), 'dry-run 应列 ensure-extension-files');
84
- assert.ok(c6.out.includes('watch-extension-ready'), 'dry-run 应列 watch-extension-ready');
85
- console.log('6. wizard 子命令(--dry-run 零网络,2 步齐全 + 极简 stdout)OK');
86
- const c7 = runBootstrap([
66
+ assert.equal(c5.code, 0, `wizard --dry-run 应 exit 0,实际 ${c5.code}\n${c5.out}`);
67
+ assert.ok(c5.out.includes('dry-run'), '应输出 dry-run 字样');
68
+ assert.ok(c5.out.includes('gotry-wizard'), '应输出 [gotry-wizard] 标签');
69
+ assert.ok(c5.out.includes('ensure-extension-files'), 'dry-run 应列 ensure-extension-files');
70
+ assert.ok(c5.out.includes('watch-extension-ready'), 'dry-run 应列 watch-extension-ready');
71
+ console.log('5. wizard 子命令(--dry-run 零网络,2 步齐全 + 极简 stdout)OK');
72
+ const c6 = runBootstrap([
87
73
  'wizard'
88
74
  ], {
89
75
  GOTRY_SETUP_EXTENSION: '0',
90
76
  GOTRY_ONBOARDING_TIMEOUT_MS: '600',
91
77
  GOTRY_ONBOARDING_INTERVAL_MS: '200'
92
78
  });
93
- assert.equal(c7.code, 1, `wizard(超时)应 exit 1,实际 ${c7.code}\n${c7.out}`);
94
- assert.ok(c7.out.includes('gotry-wizard'), '应输出 [gotry-wizard] 标签');
95
- console.log('7. wizard 真实路径(扩展未就绪,exit 1 + 引导标题 + 心跳)OK');
96
- const c8 = runBootstrap([
79
+ assert.equal(c6.code, 1, `wizard(超时)应 exit 1,实际 ${c6.code}\n${c6.out}`);
80
+ assert.ok(c6.out.includes('gotry-wizard'), '应输出 [gotry-wizard] 标签');
81
+ console.log('6. wizard 真实路径(扩展未就绪,exit 1 + 心跳)OK');
82
+ const c7 = runBootstrap([
97
83
  '--check-only',
98
84
  '--extension-from=github'
99
85
  ], {
@@ -102,10 +88,10 @@ const c8 = runBootstrap([
102
88
  GOTRY_SETUP_SIDEBAR: '0',
103
89
  GOTRY_EXTENSION_RELEASE_BASE: 'http://127.0.0.1:1/releases'
104
90
  });
105
- assert.equal(c8.code, 0, `github 通道降级应 exit 0,实际 ${c8.code}\n${c8.out}`);
106
- assert.ok(c8.out.includes('GitHub Releases 下载通道'), '应打印 github 通道标题');
107
- assert.ok(c8.out.includes('降级包内副本'), '失败应显式降级 bundled');
108
- const c8b = runBootstrap([
91
+ assert.equal(c7.code, 0, `github 通道降级应 exit 0,实际 ${c7.code}\n${c7.out}`);
92
+ assert.ok(c7.out.includes('GitHub Releases 下载通道'), '应打印 github 通道标题');
93
+ assert.ok(c7.out.includes('降级包内副本'), '失败应显式降级 bundled');
94
+ const c7b = runBootstrap([
109
95
  '--check-only',
110
96
  '--extension-from=不合法值'
111
97
  ], {
@@ -113,10 +99,10 @@ const c8b = runBootstrap([
113
99
  GOTRY_SETUP_REACH: '0',
114
100
  GOTRY_SETUP_SIDEBAR: '0'
115
101
  });
116
- assert.equal(c8b.code, 0, `非法 --extension-from 值应回落 bundled 且 exit 0,实际 ${c8b.code}\n${c8b.out}`);
117
- assert.ok(!c8b.out.includes('下载通道'), '非法值不应进入 github 通道');
118
- console.log('8. 扩展分发 github 通道(不可达基址即时降级 + 非法值回落 bundled)OK');
119
- console.log('BOOTSTRAP TESTS: 8/8 OK(探测报告/跳过开关/单项开关/postinstall 非致命/会话扩展/wizard --dry-run/wizard 真实/扩展分发通道)');
102
+ assert.equal(c7b.code, 0, `非法 --extension-from 值应回落 bundled 且 exit 0,实际 ${c7b.code}\n${c7b.out}`);
103
+ assert.ok(!c7b.out.includes('下载通道'), '非法值不应进入 github 通道');
104
+ console.log('7. 扩展分发 github 通道(不可达基址即时降级 + 非法值回落 bundled)OK');
105
+ console.log('BOOTSTRAP TESTS: 7/7 OK(扩展就位 + 跳过开关 / wizard --dry-run / wizard 真实 / 扩展分发通道 / 显式跳过 + auto 跳过 + 单项跳过)');
120
106
 
121
107
 
122
108
  //# sourceURL=ts/scripts/bootstrap-tests.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danceiny/gotry",
3
- "version": "0.0.1-rc.17",
3
+ "version": "0.0.1-rc.18",
4
4
  "description": "GoTry — 从出发到下一次出发的 AI 旅行 Agent(dsh 插件)。npm/源码入口共用锁定的 dsh runtime + README 安装路径。",
5
5
  "type": "module",
6
6
  "main": "ts/src/index.ts",