common-memory-core 0.2.0
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/.env.sample +3 -0
- package/CHANGELOG.md +39 -0
- package/LICENSE +21 -0
- package/README.md +120 -0
- package/SECURITY.md +48 -0
- package/dist/cli/codex/transcript-0.153.4.d.ts +20 -0
- package/dist/cli/codex/transcript-0.153.4.d.ts.map +1 -0
- package/dist/cli/codex/transcript-0.153.4.js +78 -0
- package/dist/cli/codex/transcript-0.153.4.js.map +1 -0
- package/dist/cli/codex-config.d.ts +2 -0
- package/dist/cli/codex-config.d.ts.map +1 -0
- package/dist/cli/codex-config.js +5 -0
- package/dist/cli/codex-config.js.map +1 -0
- package/dist/cli/codex-hook.d.ts +18 -0
- package/dist/cli/codex-hook.d.ts.map +1 -0
- package/dist/cli/codex-hook.js +140 -0
- package/dist/cli/codex-hook.js.map +1 -0
- package/dist/cli/codex-session.d.ts +3 -0
- package/dist/cli/codex-session.d.ts.map +1 -0
- package/dist/cli/codex-session.js +3 -0
- package/dist/cli/codex-session.js.map +1 -0
- package/dist/cli/flush-command.d.ts +6 -0
- package/dist/cli/flush-command.d.ts.map +1 -0
- package/dist/cli/flush-command.js +30 -0
- package/dist/cli/flush-command.js.map +1 -0
- package/dist/cli/host-launch.d.ts +28 -0
- package/dist/cli/host-launch.d.ts.map +1 -0
- package/dist/cli/host-launch.js +16 -0
- package/dist/cli/host-launch.js.map +1 -0
- package/dist/cli/host-process.d.ts +3 -0
- package/dist/cli/host-process.d.ts.map +1 -0
- package/dist/cli/host-process.js +35 -0
- package/dist/cli/host-process.js.map +1 -0
- package/dist/cli/host-session.d.ts +22 -0
- package/dist/cli/host-session.d.ts.map +1 -0
- package/dist/cli/host-session.js +204 -0
- package/dist/cli/host-session.js.map +1 -0
- package/dist/cli/import-command.d.ts +20 -0
- package/dist/cli/import-command.d.ts.map +1 -0
- package/dist/cli/import-command.js +98 -0
- package/dist/cli/import-command.js.map +1 -0
- package/dist/cli/interactive-process.d.ts +3 -0
- package/dist/cli/interactive-process.d.ts.map +1 -0
- package/dist/cli/interactive-process.js +15 -0
- package/dist/cli/interactive-process.js.map +1 -0
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.d.ts.map +1 -0
- package/dist/cli/main.js +151 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/mcp-config.d.ts +16 -0
- package/dist/cli/mcp-config.d.ts.map +1 -0
- package/dist/cli/mcp-config.js +108 -0
- package/dist/cli/mcp-config.js.map +1 -0
- package/dist/cli/network-test.d.ts +4 -0
- package/dist/cli/network-test.d.ts.map +1 -0
- package/dist/cli/network-test.js +28 -0
- package/dist/cli/network-test.js.map +1 -0
- package/dist/cli/operations.d.ts +26 -0
- package/dist/cli/operations.d.ts.map +1 -0
- package/dist/cli/operations.js +55 -0
- package/dist/cli/operations.js.map +1 -0
- package/dist/cli/session-drain.d.ts +3 -0
- package/dist/cli/session-drain.d.ts.map +1 -0
- package/dist/cli/session-drain.js +34 -0
- package/dist/cli/session-drain.js.map +1 -0
- package/dist/cli/storage-paths.d.ts +4 -0
- package/dist/cli/storage-paths.d.ts.map +1 -0
- package/dist/cli/storage-paths.js +15 -0
- package/dist/cli/storage-paths.js.map +1 -0
- package/dist/cli/tui-integrations.d.ts +4 -0
- package/dist/cli/tui-integrations.d.ts.map +1 -0
- package/dist/cli/tui-integrations.js +143 -0
- package/dist/cli/tui-integrations.js.map +1 -0
- package/dist/cli/tui-prompts.d.ts +22 -0
- package/dist/cli/tui-prompts.d.ts.map +1 -0
- package/dist/cli/tui-prompts.js +64 -0
- package/dist/cli/tui-prompts.js.map +1 -0
- package/dist/cli/tui-settings.d.ts +21 -0
- package/dist/cli/tui-settings.d.ts.map +1 -0
- package/dist/cli/tui-settings.js +198 -0
- package/dist/cli/tui-settings.js.map +1 -0
- package/dist/cli/tui.d.ts +4 -0
- package/dist/cli/tui.d.ts.map +1 -0
- package/dist/cli/tui.js +292 -0
- package/dist/cli/tui.js.map +1 -0
- package/dist/cli/work-config.d.ts +24 -0
- package/dist/cli/work-config.d.ts.map +1 -0
- package/dist/cli/work-config.js +147 -0
- package/dist/cli/work-config.js.map +1 -0
- package/dist/config/config.d.ts +41 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +193 -0
- package/dist/config/config.js.map +1 -0
- package/dist/config/private-env.d.ts +8 -0
- package/dist/config/private-env.d.ts.map +1 -0
- package/dist/config/private-env.js +38 -0
- package/dist/config/private-env.js.map +1 -0
- package/dist/config/runtime.d.ts +32 -0
- package/dist/config/runtime.d.ts.map +1 -0
- package/dist/config/runtime.js +85 -0
- package/dist/config/runtime.js.map +1 -0
- package/dist/core/contracts/errors.d.ts +10 -0
- package/dist/core/contracts/errors.d.ts.map +1 -0
- package/dist/core/contracts/errors.js +23 -0
- package/dist/core/contracts/errors.js.map +1 -0
- package/dist/core/safety/external-preflight.d.ts +7 -0
- package/dist/core/safety/external-preflight.d.ts.map +1 -0
- package/dist/core/safety/external-preflight.js +47 -0
- package/dist/core/safety/external-preflight.js.map +1 -0
- package/dist/core/safety/redaction.d.ts +2 -0
- package/dist/core/safety/redaction.d.ts.map +1 -0
- package/dist/core/safety/redaction.js +4 -0
- package/dist/core/safety/redaction.js.map +1 -0
- package/dist/core/safety/rules.d.ts +6 -0
- package/dist/core/safety/rules.d.ts.map +1 -0
- package/dist/core/safety/rules.js +14 -0
- package/dist/core/safety/rules.js.map +1 -0
- package/dist/core/safety/scanner.d.ts +11 -0
- package/dist/core/safety/scanner.d.ts.map +1 -0
- package/dist/core/safety/scanner.js +18 -0
- package/dist/core/safety/scanner.js.map +1 -0
- package/dist/core/transaction/fsync.d.ts +6 -0
- package/dist/core/transaction/fsync.d.ts.map +1 -0
- package/dist/core/transaction/fsync.js +41 -0
- package/dist/core/transaction/fsync.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/ingress.d.ts +61 -0
- package/dist/mcp/ingress.d.ts.map +1 -0
- package/dist/mcp/ingress.js +134 -0
- package/dist/mcp/ingress.js.map +1 -0
- package/dist/mcp/server.d.ts +4 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +92 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/stdio.d.ts +5 -0
- package/dist/mcp/stdio.d.ts.map +1 -0
- package/dist/mcp/stdio.js +115 -0
- package/dist/mcp/stdio.js.map +1 -0
- package/dist/memory-manager/contracts/diagnostic.d.ts +14 -0
- package/dist/memory-manager/contracts/diagnostic.d.ts.map +1 -0
- package/dist/memory-manager/contracts/diagnostic.js +17 -0
- package/dist/memory-manager/contracts/diagnostic.js.map +1 -0
- package/dist/memory-manager/contracts/disclosure.d.ts +12 -0
- package/dist/memory-manager/contracts/disclosure.d.ts.map +1 -0
- package/dist/memory-manager/contracts/disclosure.js +8 -0
- package/dist/memory-manager/contracts/disclosure.js.map +1 -0
- package/dist/memory-manager/contracts/errors.d.ts +15 -0
- package/dist/memory-manager/contracts/errors.d.ts.map +1 -0
- package/dist/memory-manager/contracts/errors.js +25 -0
- package/dist/memory-manager/contracts/errors.js.map +1 -0
- package/dist/memory-manager/contracts/model-port.d.ts +38 -0
- package/dist/memory-manager/contracts/model-port.d.ts.map +1 -0
- package/dist/memory-manager/contracts/model-port.js +2 -0
- package/dist/memory-manager/contracts/model-port.js.map +1 -0
- package/dist/memory-manager/network/client.d.ts +13 -0
- package/dist/memory-manager/network/client.d.ts.map +1 -0
- package/dist/memory-manager/network/client.js +122 -0
- package/dist/memory-manager/network/client.js.map +1 -0
- package/dist/memory-manager/network/route.d.ts +31 -0
- package/dist/memory-manager/network/route.d.ts.map +1 -0
- package/dist/memory-manager/network/route.js +148 -0
- package/dist/memory-manager/network/route.js.map +1 -0
- package/dist/memory-manager/openai/abort.d.ts +4 -0
- package/dist/memory-manager/openai/abort.d.ts.map +1 -0
- package/dist/memory-manager/openai/abort.js +19 -0
- package/dist/memory-manager/openai/abort.js.map +1 -0
- package/dist/memory-manager/openai/bounded-body.d.ts +2 -0
- package/dist/memory-manager/openai/bounded-body.d.ts.map +1 -0
- package/dist/memory-manager/openai/bounded-body.js +49 -0
- package/dist/memory-manager/openai/bounded-body.js.map +1 -0
- package/dist/memory-manager/openai/openai-chat-adapter.d.ts +16 -0
- package/dist/memory-manager/openai/openai-chat-adapter.d.ts.map +1 -0
- package/dist/memory-manager/openai/openai-chat-adapter.js +51 -0
- package/dist/memory-manager/openai/openai-chat-adapter.js.map +1 -0
- package/dist/memory-manager/openai/openai-responses-adapter.d.ts +15 -0
- package/dist/memory-manager/openai/openai-responses-adapter.d.ts.map +1 -0
- package/dist/memory-manager/openai/openai-responses-adapter.js +14 -0
- package/dist/memory-manager/openai/openai-responses-adapter.js.map +1 -0
- package/dist/memory-manager/openai/options.d.ts +14 -0
- package/dist/memory-manager/openai/options.d.ts.map +1 -0
- package/dist/memory-manager/openai/options.js +29 -0
- package/dist/memory-manager/openai/options.js.map +1 -0
- package/dist/memory-manager/openai/remote-http.d.ts +33 -0
- package/dist/memory-manager/openai/remote-http.d.ts.map +1 -0
- package/dist/memory-manager/openai/remote-http.js +207 -0
- package/dist/memory-manager/openai/remote-http.js.map +1 -0
- package/dist/memory-manager/openai/response-decoder.d.ts +3 -0
- package/dist/memory-manager/openai/response-decoder.d.ts.map +1 -0
- package/dist/memory-manager/openai/response-decoder.js +57 -0
- package/dist/memory-manager/openai/response-decoder.js.map +1 -0
- package/dist/memory-manager/openai/retry.d.ts +8 -0
- package/dist/memory-manager/openai/retry.d.ts.map +1 -0
- package/dist/memory-manager/openai/retry.js +18 -0
- package/dist/memory-manager/openai/retry.js.map +1 -0
- package/dist/pi-extension/extraction-runtime.d.ts +51 -0
- package/dist/pi-extension/extraction-runtime.d.ts.map +1 -0
- package/dist/pi-extension/extraction-runtime.js +87 -0
- package/dist/pi-extension/extraction-runtime.js.map +1 -0
- package/dist/pi-extension/index.d.ts +19 -0
- package/dist/pi-extension/index.d.ts.map +1 -0
- package/dist/pi-extension/index.js +172 -0
- package/dist/pi-extension/index.js.map +1 -0
- package/dist/v2/canonical.d.ts +53 -0
- package/dist/v2/canonical.d.ts.map +1 -0
- package/dist/v2/canonical.js +321 -0
- package/dist/v2/canonical.js.map +1 -0
- package/dist/v2/contract.d.ts +34 -0
- package/dist/v2/contract.d.ts.map +1 -0
- package/dist/v2/contract.js +53 -0
- package/dist/v2/contract.js.map +1 -0
- package/dist/v2/document-import.d.ts +100 -0
- package/dist/v2/document-import.d.ts.map +1 -0
- package/dist/v2/document-import.js +259 -0
- package/dist/v2/document-import.js.map +1 -0
- package/dist/v2/errors.d.ts +6 -0
- package/dist/v2/errors.d.ts.map +1 -0
- package/dist/v2/errors.js +29 -0
- package/dist/v2/errors.js.map +1 -0
- package/dist/v2/import.d.ts +26 -0
- package/dist/v2/import.d.ts.map +1 -0
- package/dist/v2/import.js +48 -0
- package/dist/v2/import.js.map +1 -0
- package/dist/v2/lock.d.ts +3 -0
- package/dist/v2/lock.d.ts.map +1 -0
- package/dist/v2/lock.js +47 -0
- package/dist/v2/lock.js.map +1 -0
- package/dist/v2/memory-maintainer.md +38 -0
- package/dist/v2/read-guidance.d.ts +3 -0
- package/dist/v2/read-guidance.d.ts.map +1 -0
- package/dist/v2/read-guidance.js +3 -0
- package/dist/v2/read-guidance.js.map +1 -0
- package/dist/v2/reader.d.ts +25 -0
- package/dist/v2/reader.d.ts.map +1 -0
- package/dist/v2/reader.js +38 -0
- package/dist/v2/reader.js.map +1 -0
- package/dist/v2/registry.d.ts +14 -0
- package/dist/v2/registry.d.ts.map +1 -0
- package/dist/v2/registry.js +46 -0
- package/dist/v2/registry.js.map +1 -0
- package/dist/v2/runtime.d.ts +133 -0
- package/dist/v2/runtime.d.ts.map +1 -0
- package/dist/v2/runtime.js +326 -0
- package/dist/v2/runtime.js.map +1 -0
- package/dist/v2/session-drain.d.ts +14 -0
- package/dist/v2/session-drain.d.ts.map +1 -0
- package/dist/v2/session-drain.js +16 -0
- package/dist/v2/session-drain.js.map +1 -0
- package/dist/v2/session.d.ts +54 -0
- package/dist/v2/session.d.ts.map +1 -0
- package/dist/v2/session.js +158 -0
- package/dist/v2/session.js.map +1 -0
- package/dist/v2/writer.d.ts +40 -0
- package/dist/v2/writer.d.ts.map +1 -0
- package/dist/v2/writer.js +327 -0
- package/dist/v2/writer.js.map +1 -0
- package/docs/00-index.md +19 -0
- package/docs/03-target-architecture.md +49 -0
- package/docs/init-v0.1-closeout.md +152 -0
- package/docs/init-v0.1-design.md +237 -0
- package/docs/init-v0.1-verification.md +303 -0
- package/docs/outbound-network-design.md +100 -0
- package/docs/outbound-network-verification.json +300 -0
- package/docs/provider-verification.md +94 -0
- package/docs/releasing.md +138 -0
- package/docs/session-integration.md +134 -0
- package/docs/tui-workbench.md +173 -0
- package/docs/usage.md +815 -0
- package/docs/v2-ablation-results.json +12035 -0
- package/docs/v2-ablation.md +117 -0
- package/docs/v2-evaluation-repeat-results.json +7 -0
- package/docs/v2-evaluation-scripted-results.json +67 -0
- package/docs/v2-evaluation.md +35 -0
- package/docs/v2-optimization-plan.md +23 -0
- package/docs/v2-performance-baseline-runtime.js.txt +231 -0
- package/docs/v2-performance-baseline.json +338 -0
- package/docs/v2-performance-behavior-equivalence.json +17 -0
- package/docs/v2-performance-results.json +585 -0
- package/docs/v2-performance.md +88 -0
- package/docs/v2-replacement-test-map.md +14 -0
- package/docs/v2-verification.md +49 -0
- package/package.json +87 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Common Memory outbound network — research and reviewed design
|
|
2
|
+
|
|
3
|
+
2026-09-08. Node 24.20.0 (bundled Undici 7.29.0); independently installed and inspected **Undici 8.10.2**. Existing Init changes are retained. Network ownership applies uniformly to CLI, MCP and Pi, not host-specific launch patches.
|
|
4
|
+
|
|
5
|
+
## Evidence and decisions
|
|
6
|
+
|
|
7
|
+
Primary sources: [Node 24 util.parseEnv](https://github.com/nodejs/node/blob/v24.20.0/doc/api/util.md#utilparseenvcontent), [Node TLS CA APIs](https://github.com/nodejs/node/blob/v24.20.0/doc/api/tls.md#tlsgetcacertificatestype), [Undici env agent](https://github.com/nodejs/undici/blob/main/docs/docs/api/EnvHttpProxyAgent.md), [ProxyAgent](https://github.com/nodejs/undici/blob/main/docs/docs/api/ProxyAgent.md), [SOCKS5](https://github.com/nodejs/undici/blob/main/docs/docs/api/Socks5ProxyAgent.md). The npm 8.10.2 package source was inspected directly; fetching its GitHub tag through the browser returned a cache miss. Do not substitute main-branch claims for the installed-version tests.
|
|
8
|
+
|
|
9
|
+
Local research scripts are in `/tmp/cm-network-research-58C9ty/`: `behavior.cjs`, `transport.cjs`, `connect-status.cjs`, `socks.cjs`. They use synthetic data/local servers, not personal Memory or real API keys.
|
|
10
|
+
|
|
11
|
+
| Tested native behavior | Product decision |
|
|
12
|
+
| --- | --- |
|
|
13
|
+
| EnvHttpProxyAgent does not read ALL_PROXY; HTTPS falls back to HTTP_PROXY | Own pure resolver implements HTTPS → HTTP → ALL and HTTP → ALL |
|
|
14
|
+
| Lowercase empty values mask uppercase values | Presence-based lowercase precedence, including explicit empty values |
|
|
15
|
+
| NO_PROXY is dynamically reread by native env agent | Freeze input and route when creating the model client; retries reuse it |
|
|
16
|
+
| example.com and .example.com match apex and subdomains, with label boundaries | Retain this explicitly tested semantic; `*.example.com` is the same suffix form |
|
|
17
|
+
| Native `localhost,*` and ` * ` do not act like a standalone `*` | Product treats any trimmed standalone `*` token as bypass-all |
|
|
18
|
+
| Expanded IPv6 does not match compressed IPv6 in the native agent | Normalize IP literals with WHATWG URL before comparing |
|
|
19
|
+
| Default and explicit :443 match HTTPS; other ports do not | Compare effective ports (HTTP 80 / HTTPS 443) |
|
|
20
|
+
| localhost does not match 127.0.0.1; CIDR is not implemented | No DNS lookup/loopback aliases; reject unsupported CIDR/glob syntax in an applicable bypass list |
|
|
21
|
+
| util.parseEnv preserves Windows backslashes without changing process.env | Local parsing for all new network modes; no process.loadEnvFile for new clients |
|
|
22
|
+
| Own Agent bypasses hostile global dispatcher; closing it leaves host dispatcher alive | Per-client owned Agent/ProxyAgent, never setGlobalDispatcher |
|
|
23
|
+
| Provider HTTP 401 is a response; HTTP proxy 407 is UND_ERR_INVALID_ARG; CONNECT 407 is deeper UND_ERR_ABORTED in fetch.cause | Bounded cause traversal, known code plus complete library-generated message format; persist only local enum/status |
|
|
24
|
+
| SOCKS5 returns HTTP 200 through a local proxy and sends target hostname to proxy; constructor emits ExperimentalWarning | Experimental SOCKS5 support, remote DNS; not formal cross-platform/real-proxy verification |
|
|
25
|
+
|
|
26
|
+
Earlier real DeepSeek probes showed default Node connecting then resetting while the same request via an explicit environment proxy completed in ~1.9 seconds. This establishes a route problem in that environment, not a rule that all users need proxies. Valid ignore and occasional invalid model JSON remain separate from transport success.
|
|
27
|
+
|
|
28
|
+
## Configuration and compatibility
|
|
29
|
+
|
|
30
|
+
Keep schemaVersion 2. Add exact-validated optional `remote.proxy`: `{mode:'direct'}`, `{mode:'env'}`, or `{mode:'custom',urlEnv:string,noProxy?:string}`. Add optional `remote.caFileEnv` only with an explicit proxy mode. New `defaultConfig()` writes `{mode:'env'}`. Reading and saving an old config preserves field absence; it means internal **legacy / host-managed / unknown**, never direct. Non-network settings must not migrate it. `config --network` is the explicit migration boundary.
|
|
31
|
+
|
|
32
|
+
Legacy borrows the old global fetch and preserves old private-env fill-if-undefined behavior, including existing HTTP_PROXY/NO_PROXY interactions with a host dispatcher. The legacy loader uses the same Node parser and excludes the newly reserved `COMMON_MEMORY_PROXY_URL` and `COMMON_MEMORY_CA_FILE`; these secrets must never be exported by a stale legacy instance. The network wizard persists only these reserved names. Other custom secret variable names are external-process-env-only. This is a deliberate legacy compatibility exception, not isolation for legacy hosts. Existing host implementations/Node flags remain authoritative; status cannot infer their actual route.
|
|
33
|
+
|
|
34
|
+
New modes parse private env locally. For standard proxy variables, choose the process source first for each case-insensitive semantic group, then private source; within a source a present lowercase key wins even when empty. Empty means cleared, not permission to recover a private/uppercase value. Custom bypass rules never inherit NO_PROXY. Custom proxy URI must be valid even when its explicit bypass matches; env mode validates only the selected proxy URI when it will be used. No applicable proxy means direct. No failed proxy fallback.
|
|
35
|
+
|
|
36
|
+
NO_PROXY accepts comma/whitespace-separated names, apex/domain suffixes, IPv4, IPv6 (brackets required for a port), optional ports, and standalone `*`. Normalize case, trailing dot, IDNA and IP spelling. Match suffixes only on domain-label boundaries; IPs exactly. Reject CIDR, URL/path syntax, malformed ports and other wildcard forms. Do not guess loopback aliases or WSL host addresses.
|
|
37
|
+
|
|
38
|
+
HTTP/HTTPS proxies are formal targets. SOCKS5 (`socks5:` / `socks:`) is experimental and uses remote DNS. SOCKS4, PAC/WPAD and integrated enterprise authentication are unsupported. CA input is a bounded PEM file, merged into a snapshot of Node's default trust store and applied only to the owned client. Certificate/hostname checks stay enabled.
|
|
39
|
+
|
|
40
|
+
## Ownership and failure handling
|
|
41
|
+
|
|
42
|
+
One small resolver, one owned network client, and local secret parsing; no routing framework. Resolved routes contain a private URL and a separate safe description. New modes use installed Undici fetch with an explicit owned dispatcher, reject redirects, and cannot escape to another origin. Legacy/injected fetch is borrowed and never closed.
|
|
43
|
+
|
|
44
|
+
MemoryModelPort stays analysis-only. Concrete remote models expose idempotent async close, abort their own requests and destroy only owned connections. The configured Writer owns its configured model; it blocks new work during close, aborts and awaits current work, closes SQLite after Writer cleanup, then closes its model. A plain Writer continues to borrow a model. CLI/MCP/Pi await cleanup, including construction failure and reload. No dispatcher switch within retries.
|
|
45
|
+
|
|
46
|
+
Network configuration, proxy authentication/availability, TLS validation, DNS, endpoint connection errors, provider API authentication, HTTP status errors and model-output failures have distinct controlled diagnostics. HTTP status from CONNECT is `proxyStatus`, not a provider `httpStatus`. First cancellation/deadline reason remains authoritative. Unknown errors remain unknown; do not infer proxy blame solely from configured mode. No raw exception, credentials, CA contents or provider body is persisted.
|
|
47
|
+
|
|
48
|
+
## Review and acceptance
|
|
49
|
+
|
|
50
|
+
Independent design review confirmed the legacy NO_PROXY compatibility trap, reserved-secret filtering, source-before-case precedence, async ownership cleanup, and bounded CONNECT error matching. Research and review preceded product changes.
|
|
51
|
+
|
|
52
|
+
Required regressions: old config round-trip/route preservation; reserved secrets not injected even by legacy loader; route matching matrix; per-instance/global isolation; HTTP/HTTPS proxy authentication and CA; experimental SOCKS5; cancellation and closure races; retries retain route; read-only MCP creates no network client. After implementation run the full Node 24 verify gate and built Linux consumer, then independent implementation review and necessary rechecks. Real smoke remains synthetic, isolated, fixed to deepseek-v4-flash-vision-exp/Responses/4096/60s with explicit reasoning none. Three independent runs must report every attempt and require real Writer receipts plus restarted key-free read for retention; never count ignore or adapter-only success as retained memory. Windows/macOS/WSL and desktop live results are reported separately.
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
## Implemented result and verification
|
|
56
|
+
|
|
57
|
+
The implementation follows this design. Exact-key optional fields stay in schemaVersion 2;
|
|
58
|
+
new defaults are env, while old field absence remains legacy. `no_proxy_invalid` is a
|
|
59
|
+
separate controlled configuration reason so unsupported lists are actionable. Legacy
|
|
60
|
+
reserved-name filtering is case-insensitive, including Windows aliases. Three concrete
|
|
61
|
+
review findings were fixed and independently rechecked: capture legacy fetch at creation,
|
|
62
|
+
do not blame the proxy for an endpoint reset after CONNECT, and always cancel/close Pi
|
|
63
|
+
resources even when requesting flush fails.
|
|
64
|
+
|
|
65
|
+
Final full verification: Node 24.20.0, Linux, **26 files / 341 tests**, typecheck, boundary
|
|
66
|
+
checks and clean build passed (`/tmp/cm-network-verify-final.log`). Built packed consumer
|
|
67
|
+
passed (`/tmp/cm-network-consumer-final.log`). Tests use local real HTTP/HTTPS/SOCKS5
|
|
68
|
+
servers for routing, 407 vs API 401, CONNECT, separate origin/proxy credentials, local CA
|
|
69
|
+
and both endpoint/proxy hostname verification, direct/global/two-instance isolation,
|
|
70
|
+
retry route retention, cancellation and cleanup. NO_PROXY semantics have their own
|
|
71
|
+
contract matrix. CA reads reject non-files and are bounded even if the file grows.
|
|
72
|
+
|
|
73
|
+
Three independent real DeepSeek Init + Markdown → actual Writer validation/commit →
|
|
74
|
+
durable receipts → restarted key-free MCP read runs passed. One needed Runtime retries
|
|
75
|
+
for a Core-rejected decision and invalid model JSON; two passed on first attempts.
|
|
76
|
+
[Safe machine-readable evidence](outbound-network-verification.json) and
|
|
77
|
+
[full Init acceptance history](init-v0.1-closeout.md) retain all results, including an
|
|
78
|
+
initial failed Markdown attempt. The old duplicate Rust fixture's lawful ignore is
|
|
79
|
+
separate from the new nonduplicate Fedora/fish retention fixture.
|
|
80
|
+
|
|
81
|
+
The real tests explicitly cleared both NO_PROXY spellings **inside isolated child env**.
|
|
82
|
+
The current host has unsupported CIDR entries, so its env configuration does not work
|
|
83
|
+
unchanged. This is an explicit remaining compatibility limit, not a successful test of
|
|
84
|
+
the original host environment. Choose a supported bypass list or custom network mode;
|
|
85
|
+
Common Memory never silently removes those rules or switches a failed proxy to direct.
|
|
86
|
+
|
|
87
|
+
| Environment / protocol | Evidence and limit |
|
|
88
|
+
| --- | --- |
|
|
89
|
+
| Node 24 on Linux, owned direct / env / custom HTTP(S) | Local real-server matrix and built consumer passed; selected DeepSeek env route passed live |
|
|
90
|
+
| Legacy host fetch / Node --use-env-proxy | Isolated child regression preserves old NO_PROXY loading and captured host fetch; route remains host-managed |
|
|
91
|
+
| SOCKS5 | Local remote-DNS and authentication tests passed; Undici marks it experimental; no real third-party SOCKS service tested |
|
|
92
|
+
| Windows / macOS native | Portable path handling and reserved-name casing covered by code/contracts; no OS execution or CI result claimed |
|
|
93
|
+
| WSL NAT / mirrored, GUI host env | [Microsoft networking documentation](https://learn.microsoft.com/en-us/windows/wsl/networking) informs explicit-address design; no live WSL or desktop-client acceptance |
|
|
94
|
+
| VPN / TUN | OS routing remains authoritative; not detected, changed or separately verified |
|
|
95
|
+
| CIDR, SOCKS4, PAC/WPAD, NTLM/Kerberos | Unsupported this round; no silent approximation |
|
|
96
|
+
|
|
97
|
+
OpenAI Responses has fake-contract preservation only; Qwen and GLM Chat are documentation
|
|
98
|
+
candidates without live calls; Hunyuan's exact json_object/model combination is unverified.
|
|
99
|
+
No brand-wide compatibility claim, package publication or personal configuration migration
|
|
100
|
+
was performed. Package remains 0.2.0/private:true.
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
{
|
|
2
|
+
"date": "2026-09-08",
|
|
3
|
+
"node": "24.20.0",
|
|
4
|
+
"undici": "8.10.2",
|
|
5
|
+
"platformTested": "Linux",
|
|
6
|
+
"endpoint": "https://api.deepseek.com/responses",
|
|
7
|
+
"model": "deepseek-v4-flash-vision-exp",
|
|
8
|
+
"api": "responses",
|
|
9
|
+
"reasoningEffort": "none",
|
|
10
|
+
"maxOutputTokens": 4096,
|
|
11
|
+
"writerDeadlineMs": 60000,
|
|
12
|
+
"network": {
|
|
13
|
+
"mode": "env",
|
|
14
|
+
"no_proxy": "",
|
|
15
|
+
"NO_PROXY": "",
|
|
16
|
+
"note": "Explicit isolated child-env bypass override; original host CIDR lists remain unsupported. Proxy URL and API key omitted."
|
|
17
|
+
},
|
|
18
|
+
"verify": {
|
|
19
|
+
"testFiles": 26,
|
|
20
|
+
"tests": 341,
|
|
21
|
+
"log": "/tmp/cm-network-verify-final.log"
|
|
22
|
+
},
|
|
23
|
+
"consumerLog": "/tmp/cm-network-consumer-final.log",
|
|
24
|
+
"formalMemoryDigest": "c4e1a57b4617869cc30b69d1c4e93c76bb0112985bedde2b4f9662ba17ac75a7",
|
|
25
|
+
"preliminaryReport": {
|
|
26
|
+
"path": "/tmp/cm-deepseek-smoke-oz5Ux7/report.json",
|
|
27
|
+
"passed": false,
|
|
28
|
+
"reason": "Init retained; first Markdown attempt HTTP 200 with invalid output JSON. This historical retry queue was not reset."
|
|
29
|
+
},
|
|
30
|
+
"runs": [
|
|
31
|
+
{
|
|
32
|
+
"reportPath": "/tmp/cm-deepseek-smoke-3MCAyv/report.json",
|
|
33
|
+
"passed": true,
|
|
34
|
+
"initJob": "64dcc0ba-a390-46ec-898a-9525bee8c3b3",
|
|
35
|
+
"initAttempts": 2,
|
|
36
|
+
"initHistory": [
|
|
37
|
+
{
|
|
38
|
+
"state": "pending",
|
|
39
|
+
"issue": null,
|
|
40
|
+
"retainedIn": [],
|
|
41
|
+
"jobId": null,
|
|
42
|
+
"jobState": null,
|
|
43
|
+
"attempts": 0,
|
|
44
|
+
"retryAt": null,
|
|
45
|
+
"diagnostic": null
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"state": "claimed",
|
|
49
|
+
"issue": null,
|
|
50
|
+
"retainedIn": [],
|
|
51
|
+
"jobId": "64dcc0ba-a390-46ec-898a-9525bee8c3b3",
|
|
52
|
+
"jobState": "running",
|
|
53
|
+
"attempts": 1,
|
|
54
|
+
"retryAt": null,
|
|
55
|
+
"diagnostic": null
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"state": "claimed",
|
|
59
|
+
"issue": "INVALID_DECISION",
|
|
60
|
+
"retainedIn": [],
|
|
61
|
+
"jobId": "64dcc0ba-a390-46ec-898a-9525bee8c3b3",
|
|
62
|
+
"jobState": "retry",
|
|
63
|
+
"attempts": 1,
|
|
64
|
+
"retryAt": 1788827088285,
|
|
65
|
+
"diagnostic": {
|
|
66
|
+
"stage": "core_validation",
|
|
67
|
+
"reason": "core_rejected",
|
|
68
|
+
"retryable": false
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"state": "claimed",
|
|
73
|
+
"issue": "INVALID_DECISION",
|
|
74
|
+
"retainedIn": [],
|
|
75
|
+
"jobId": "64dcc0ba-a390-46ec-898a-9525bee8c3b3",
|
|
76
|
+
"jobState": "running",
|
|
77
|
+
"attempts": 2,
|
|
78
|
+
"retryAt": null,
|
|
79
|
+
"diagnostic": {
|
|
80
|
+
"stage": "core_validation",
|
|
81
|
+
"reason": "core_rejected",
|
|
82
|
+
"retryable": false
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"state": "processed",
|
|
87
|
+
"issue": null,
|
|
88
|
+
"retainedIn": [
|
|
89
|
+
"preferences",
|
|
90
|
+
"profile"
|
|
91
|
+
],
|
|
92
|
+
"jobId": "64dcc0ba-a390-46ec-898a-9525bee8c3b3",
|
|
93
|
+
"jobState": "done",
|
|
94
|
+
"attempts": 2,
|
|
95
|
+
"retryAt": null,
|
|
96
|
+
"diagnostic": null
|
|
97
|
+
}
|
|
98
|
+
],
|
|
99
|
+
"markdownJob": "a2946e2b-a57a-4633-b882-c6206c26fbb6",
|
|
100
|
+
"markdownAttempts": 2,
|
|
101
|
+
"markdownHistory": [
|
|
102
|
+
{
|
|
103
|
+
"exitCode": 1,
|
|
104
|
+
"job": {
|
|
105
|
+
"id": "a2946e2b-a57a-4633-b882-c6206c26fbb6",
|
|
106
|
+
"state": "retry",
|
|
107
|
+
"attempts": 1,
|
|
108
|
+
"issue": "INVALID_RESPONSE",
|
|
109
|
+
"diagnostic": {
|
|
110
|
+
"stage": "model_output",
|
|
111
|
+
"reason": "invalid_json",
|
|
112
|
+
"retryable": false,
|
|
113
|
+
"httpStatus": 200
|
|
114
|
+
},
|
|
115
|
+
"retryAt": 1788827095636
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"exitCode": 0,
|
|
120
|
+
"job": {
|
|
121
|
+
"id": "a2946e2b-a57a-4633-b882-c6206c26fbb6",
|
|
122
|
+
"state": "done",
|
|
123
|
+
"attempts": 2,
|
|
124
|
+
"issue": "INVALID_RESPONSE",
|
|
125
|
+
"diagnostic": {
|
|
126
|
+
"stage": "model_output",
|
|
127
|
+
"reason": "invalid_json",
|
|
128
|
+
"retryable": false,
|
|
129
|
+
"httpStatus": 200
|
|
130
|
+
},
|
|
131
|
+
"retryAt": null
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
],
|
|
135
|
+
"durableReceiptIds": [
|
|
136
|
+
"64dcc0ba-a390-46ec-898a-9525bee8c3b3",
|
|
137
|
+
"a2946e2b-a57a-4633-b882-c6206c26fbb6"
|
|
138
|
+
],
|
|
139
|
+
"fileReceipts": 2,
|
|
140
|
+
"restartRead": {
|
|
141
|
+
"tools": [
|
|
142
|
+
"memory_read",
|
|
143
|
+
"memory_status"
|
|
144
|
+
],
|
|
145
|
+
"empty": false,
|
|
146
|
+
"hasQuillon": true,
|
|
147
|
+
"hasFedora": true,
|
|
148
|
+
"hasFish": true,
|
|
149
|
+
"sha256": "e6724c9470f305ae11976f7e4bb97c667d9ba38db2a0c60f9b78b163e8c7f8e4"
|
|
150
|
+
},
|
|
151
|
+
"formalMemoryUnchanged": true
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"reportPath": "/tmp/cm-deepseek-smoke-Zqd7hN/report.json",
|
|
155
|
+
"passed": true,
|
|
156
|
+
"initJob": "e4788af8-dcbf-4f19-bd6d-62cf6016c92f",
|
|
157
|
+
"initAttempts": 1,
|
|
158
|
+
"initHistory": [
|
|
159
|
+
{
|
|
160
|
+
"state": "pending",
|
|
161
|
+
"issue": null,
|
|
162
|
+
"retainedIn": [],
|
|
163
|
+
"jobId": null,
|
|
164
|
+
"jobState": null,
|
|
165
|
+
"attempts": 0,
|
|
166
|
+
"retryAt": null,
|
|
167
|
+
"diagnostic": null
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
"state": "claimed",
|
|
171
|
+
"issue": null,
|
|
172
|
+
"retainedIn": [],
|
|
173
|
+
"jobId": "e4788af8-dcbf-4f19-bd6d-62cf6016c92f",
|
|
174
|
+
"jobState": "running",
|
|
175
|
+
"attempts": 1,
|
|
176
|
+
"retryAt": null,
|
|
177
|
+
"diagnostic": null
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"state": "processed",
|
|
181
|
+
"issue": null,
|
|
182
|
+
"retainedIn": [
|
|
183
|
+
"preferences",
|
|
184
|
+
"profile"
|
|
185
|
+
],
|
|
186
|
+
"jobId": "e4788af8-dcbf-4f19-bd6d-62cf6016c92f",
|
|
187
|
+
"jobState": "done",
|
|
188
|
+
"attempts": 1,
|
|
189
|
+
"retryAt": null,
|
|
190
|
+
"diagnostic": null
|
|
191
|
+
}
|
|
192
|
+
],
|
|
193
|
+
"markdownJob": "3b18bfc0-2341-4d1d-95da-3920769f19e0",
|
|
194
|
+
"markdownAttempts": 1,
|
|
195
|
+
"markdownHistory": [
|
|
196
|
+
{
|
|
197
|
+
"exitCode": 0,
|
|
198
|
+
"job": {
|
|
199
|
+
"id": "3b18bfc0-2341-4d1d-95da-3920769f19e0",
|
|
200
|
+
"state": "done",
|
|
201
|
+
"attempts": 1,
|
|
202
|
+
"issue": null,
|
|
203
|
+
"diagnostic": null,
|
|
204
|
+
"retryAt": null
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
],
|
|
208
|
+
"durableReceiptIds": [
|
|
209
|
+
"3b18bfc0-2341-4d1d-95da-3920769f19e0",
|
|
210
|
+
"e4788af8-dcbf-4f19-bd6d-62cf6016c92f"
|
|
211
|
+
],
|
|
212
|
+
"fileReceipts": 2,
|
|
213
|
+
"restartRead": {
|
|
214
|
+
"tools": [
|
|
215
|
+
"memory_read",
|
|
216
|
+
"memory_status"
|
|
217
|
+
],
|
|
218
|
+
"empty": false,
|
|
219
|
+
"hasQuillon": true,
|
|
220
|
+
"hasFedora": true,
|
|
221
|
+
"hasFish": true,
|
|
222
|
+
"sha256": "bb3b530b0b88b0e5911f284a3fb352a0d45691dabc7ebba3e579a84433453810"
|
|
223
|
+
},
|
|
224
|
+
"formalMemoryUnchanged": true
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
"reportPath": "/tmp/cm-deepseek-smoke-FSvXWo/report.json",
|
|
228
|
+
"passed": true,
|
|
229
|
+
"initJob": "1768eb75-4d9e-45bf-87a8-f66eec685afe",
|
|
230
|
+
"initAttempts": 1,
|
|
231
|
+
"initHistory": [
|
|
232
|
+
{
|
|
233
|
+
"state": "pending",
|
|
234
|
+
"issue": null,
|
|
235
|
+
"retainedIn": [],
|
|
236
|
+
"jobId": null,
|
|
237
|
+
"jobState": null,
|
|
238
|
+
"attempts": 0,
|
|
239
|
+
"retryAt": null,
|
|
240
|
+
"diagnostic": null
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
"state": "claimed",
|
|
244
|
+
"issue": null,
|
|
245
|
+
"retainedIn": [],
|
|
246
|
+
"jobId": "1768eb75-4d9e-45bf-87a8-f66eec685afe",
|
|
247
|
+
"jobState": "running",
|
|
248
|
+
"attempts": 1,
|
|
249
|
+
"retryAt": null,
|
|
250
|
+
"diagnostic": null
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
"state": "processed",
|
|
254
|
+
"issue": null,
|
|
255
|
+
"retainedIn": [
|
|
256
|
+
"preferences",
|
|
257
|
+
"profile"
|
|
258
|
+
],
|
|
259
|
+
"jobId": "1768eb75-4d9e-45bf-87a8-f66eec685afe",
|
|
260
|
+
"jobState": "done",
|
|
261
|
+
"attempts": 1,
|
|
262
|
+
"retryAt": null,
|
|
263
|
+
"diagnostic": null
|
|
264
|
+
}
|
|
265
|
+
],
|
|
266
|
+
"markdownJob": "3f6e1e7c-f9a2-4571-80aa-62d7a1f4bbe1",
|
|
267
|
+
"markdownAttempts": 1,
|
|
268
|
+
"markdownHistory": [
|
|
269
|
+
{
|
|
270
|
+
"exitCode": 0,
|
|
271
|
+
"job": {
|
|
272
|
+
"id": "3f6e1e7c-f9a2-4571-80aa-62d7a1f4bbe1",
|
|
273
|
+
"state": "done",
|
|
274
|
+
"attempts": 1,
|
|
275
|
+
"issue": null,
|
|
276
|
+
"diagnostic": null,
|
|
277
|
+
"retryAt": null
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
],
|
|
281
|
+
"durableReceiptIds": [
|
|
282
|
+
"1768eb75-4d9e-45bf-87a8-f66eec685afe",
|
|
283
|
+
"3f6e1e7c-f9a2-4571-80aa-62d7a1f4bbe1"
|
|
284
|
+
],
|
|
285
|
+
"fileReceipts": 2,
|
|
286
|
+
"restartRead": {
|
|
287
|
+
"tools": [
|
|
288
|
+
"memory_read",
|
|
289
|
+
"memory_status"
|
|
290
|
+
],
|
|
291
|
+
"empty": false,
|
|
292
|
+
"hasQuillon": true,
|
|
293
|
+
"hasFedora": true,
|
|
294
|
+
"hasFish": true,
|
|
295
|
+
"sha256": "9c9585fd6ac1b277d336b5b0b1a780c23660f5406d6fe86f897caea3cb8c84a7"
|
|
296
|
+
},
|
|
297
|
+
"formalMemoryUnchanged": true
|
|
298
|
+
}
|
|
299
|
+
]
|
|
300
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Provider 验证复用 — 2026-09-08
|
|
2
|
+
|
|
3
|
+
结论:把现有 DeepSeek smoke 的输入改为现有 `remote` 配置,复用原来的一个留存场景。主要重复成本在隔离目录、真实 CLI/MCP/Writer 调用、退避等待、回执核对、重启读取和结果整理;Responses / Chat adapter 与统一网络层已经可以复用。本轮不修改生产 adapter、配置契约、网络层、Core 或提示,不建立 provider registry、preset 或 capability framework。
|
|
4
|
+
|
|
5
|
+
## 搜索证据与设计决定
|
|
6
|
+
|
|
7
|
+
核对了当前两个 adapter、config/network、fake-provider 合约测试,以及 [DeepSeek 最新闭环记录](init-v0.1-closeout.md)。下列官方资料于 2026-09-08 查阅;文档支持只建立候选条件,不能代替具体账户、模型和端点的真实验收。
|
|
8
|
+
|
|
9
|
+
| 官方证据 | 对设计的实际影响 |
|
|
10
|
+
| --- | --- |
|
|
11
|
+
| [OpenAI Structured Outputs](https://developers.openai.com/api/docs/guides/structured-outputs):JSON mode 不保证 schema,strict 只支持 JSON Schema 子集 | 保持两条现有请求路径及完整 Core 校验。HTTP 200 或 JSON 可解析不能成为留存通过条件;不转换 schema 来隐藏拒绝 |
|
|
12
|
+
| [DeepSeek Responses](https://api-docs.deepseek.com/api/create-response/) / [指南](https://api-docs.deepseek.com/guides/responses_api/):支持指定 vision-exp 模型;`developer` 按 user 处理;`reasoning.effort=none` 可显式关闭思考 | 现有 system 提示和 `reasoningEffort` 已够用。保留原模型及对照入口,不增加品牌分支或默认思考参数 |
|
|
13
|
+
| [Qwen 结构化输出](https://help.aliyun.com/zh/model-studio/qwen-structured-output) / [Chat API](https://help.aliyun.com/zh/model-studio/qwen-api-via-openai-chat-completions):JSON 能力受模型与思考模式限制;端点按地域/工作空间变化,旧 DashScope 域名仍可用 | 候选 Chat 请求可以使用现有 `enableThinking:false`;端点必须由验证者明确提供,不固化品牌 preset。[Qwen Responses 文档](https://help.aliyun.com/zh/model-studio/qwen-api-via-openai-responses)也已存在,不据此推断某个 Chat 候选模型支持 Responses |
|
|
14
|
+
| [GLM 对话补全](https://docs.bigmodel.cn/api-reference/模型-api/对话补全) / [结构化输出](https://docs.bigmodel.cn/cn/guide/capabilities/struct-output):`json_object` 配合提示定义结构,仍需本地校验;支持显式 thinking 配置 | 现有 Chat adapter 的完整 system schema + Core 校验已经覆盖这项差异。当前结构化输出示例使用 `glm-5.2`,不能证明历史候选 `glm-4.5` 仍可用,也不自动替换候选 |
|
|
15
|
+
| [Hunyuan 直接兼容接口](https://cloud.tencent.com/document/product/1729/111007):列出旧端点和 `hunyuan-turbos-latest`,同时公告向 TokenHub 迁移;旧平台不再新增模型能力,已购服务暂不受影响 | 不把 TokenHub 的另一个端点能力套到旧接口。此页未确认该组合的 `json_object`,保留未验证;不添加所谓 Hunyuan 特殊处理 |
|
|
16
|
+
|
|
17
|
+
Hunyuan 页面经网页工具多次读取失败后,用 HTTPS 直接获取官方 HTML(HTTP 200)核对,页面标注更新于 2026-04-27。没有把读取失败当成 API 不支持。现有代码与上述证据已经确定了复用边界,未引入开源兼容框架。
|
|
18
|
+
|
|
19
|
+
## 最小实现
|
|
20
|
+
|
|
21
|
+
[`scripts/smoke-provider.mjs`](../scripts/smoke-provider.mjs) 接受一份**现有完整 schemaVersion 2 配置**,由现有 `validateConfig` 校验,只将其中 `remote` 复制到全新的临时 home / dataRoot。其余使用默认配置,并明确授权合成的 `agent_observation` 和 `document_import`。输入配置和原存储不被修改,原 Memory 只读取摘要。保留原 smoke 的固定场景与 Runtime 退避,不强制接管租约、不重置任务、不放大默认 60 秒 Writer 期限或 4096 输出预算。
|
|
22
|
+
|
|
23
|
+
测试配置必须明确指定 `remote.proxy`:`direct` / `env` / `custom`。旧配置在产品内继续保留 legacy 语义,但验收需要一条可说明的路线;可以仅在测试副本中选择网络模式。通用入口默认继承 NO_PROXY;只有显式 `--clear-no-proxy` 才清空子进程中的大小写变量,报告记录该条件。进程环境不被修改。custom/CA 仍由现有网络层处理。
|
|
24
|
+
|
|
25
|
+
API Key 从 `remote.apiKeyEnv` 指定的**进程环境**读取。个人私密 `.env` 不复制到临时 home;custom proxy 和 CA 所需的环境引用也应事先注入进程环境。配置与报告只包含环境变量名,不保存 Key、代理凭据或原始 Provider 错误正文。
|
|
26
|
+
|
|
27
|
+
报告绑定完整端点、模型、API、允许的输出/思考参数、Node/平台、配置路线描述、维护 schema 与提示的 SHA-256,并保存尝试状态、受控诊断、来源关联、回执 ID、重启读取标记及正式 Memory 前后摘要。路线字段描述配置选择,本身不证明连接成功。`report.json` 留在脚本打印的临时路径,临时测试数据不会自动删除。
|
|
28
|
+
|
|
29
|
+
成功必须同时满足:
|
|
30
|
+
|
|
31
|
+
1. Init 和 Markdown 每个分块均 processed,且 `retainedIn` 非空。
|
|
32
|
+
2. 每个来源对应的 job 都有匹配的 SQLite 回执和文件回执;不使用回执总数或 `job.state=done` 代替。
|
|
33
|
+
3. 两种导入在同一新库完成;移除所选 API Key 后启动新的 MCP read 进程,仍读到 Quillon、Fedora、fish。
|
|
34
|
+
4. 正式 Memory 摘要不变,流程没有失败步骤。
|
|
35
|
+
|
|
36
|
+
Init 失败时,仍沿用原 smoke 在第二个新库检查 Markdown 的行为,以保留诊断;两个库各自的局部成功不能合并为闭环通过。`ignore` 是合法处理结果,但本场景要求留存,因此判为留存未通过。
|
|
37
|
+
|
|
38
|
+
证据来源必须显式选择 `--live` 或 `--fixture`。只有 `--live` 且上述检查全部通过才记录 `retentionVerified:true`;fixture 完成完整流程也只记录 `passed:true, retentionVerified:false`。这个标记是运行者对远端性质的明确声明,不是自动识别或认证 Provider 品牌。退出码:通过 0、已执行但未通过 1、配置/构建等启动失败 2。
|
|
39
|
+
|
|
40
|
+
[`scripts/smoke-deepseek-init.mjs`](../scripts/smoke-deepseek-init.mjs) 已缩为兼容入口,调用同一实现。原命令、精确模型、env 路线及隔离清空 NO_PROXY 的测试条件保留;无参仍省略 reasoning,`--no-thinking` 才发送 `none`。没有添加依赖、任意请求参数透传、API/model fallback 或另一套配置 schema。
|
|
41
|
+
|
|
42
|
+
## 下一家 Provider 最少需要什么
|
|
43
|
+
|
|
44
|
+
1. 依据官方文档与账户权限,确定**端点 + 精确模型 + 请求模式**。复制一份有效配置,只在副本中调整 `remote.baseUrl`、`model`、`api`、`apiKeyEnv`、明确的网络模式和已有允许参数;不把 API Key 写入文件。
|
|
45
|
+
2. 将 Key 和必要的网络秘密安全注入当前进程环境。无需再写或复制一份 smoke 脚本。
|
|
46
|
+
3. 从源码 checkout 构建并执行:
|
|
47
|
+
|
|
48
|
+
```sh
|
|
49
|
+
npm run build
|
|
50
|
+
node scripts/smoke-provider.mjs --config /path/to/provider-config.json --live
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`--clear-no-proxy` 是有记录的显式测试条件,仅在确实要测试该路线时添加。不要为了让测试通过自动改变 endpoint、模型、模式或参数。若返回诊断失败,先记录原条件与失败,再一次改变一个有官方依据的参数重测。成功后归档打印的 `reportPath`,按精确组合更新下表;同品牌其他组合继续保持未验证。
|
|
54
|
+
|
|
55
|
+
这一个固定合成场景证明导入留存链路,不能替代所有记忆决策的语义评测、长文档测试或真实桌面客户端验收。
|
|
56
|
+
|
|
57
|
+
## 当前证据等级
|
|
58
|
+
|
|
59
|
+
区分“官方文档候选”“fake 合约/流程通过”“真实 API 或 adapter 成功”“真实留存闭环通过”。后三者不能互相冒充;本轮没有新增一个仅 API 成功的 Provider。
|
|
60
|
+
|
|
61
|
+
| Provider / 精确组合 | 当前证据 |
|
|
62
|
+
| --- | --- |
|
|
63
|
+
| OpenAI;Responses;未指定真实模型 | 通用 fake adapter 合约通过;没有该官方端点与真实模型的调用或留存证据 |
|
|
64
|
+
| DeepSeek;`https://api.deepseek.com/responses`;`deepseek-v4-flash-vision-exp`;strict / reasoning none / 4096 | **真实留存闭环通过**。此前三轮独立验收,本轮兼容入口重构后追加一轮成功;仅覆盖所记录的 Linux / env 代理 / 空 NO_PROXY 条件 |
|
|
65
|
+
| Qwen;历史候选 `https://dashscope.aliyuncs.com/compatible-mode/v1` + `qwen-plus`;Chat / json_object / enableThinking false | 官方文档候选;精确账户、地域端点、模型和留存尚未真实验证 |
|
|
66
|
+
| GLM;历史候选 `https://open.bigmodel.cn/api/paas/v4` + `glm-4.5`;Chat / json_object / thinking disabled | JSON 请求模式有官方依据;该历史精确模型的当前可用性与留存仍未验证。`glm-5.2` 只是本次查阅的官方示例,不是悄悄替换后的通过项 |
|
|
67
|
+
| Hunyuan;`https://api.hunyuan.cloud.tencent.com/v1` + `hunyuan-turbos-latest`;Chat | 官方直接接口候选;精确模型的 JSON object 支持、迁移后的账户可用性及留存均未验证 |
|
|
68
|
+
|
|
69
|
+
本轮新增的本地 Responses / Chat 完整 fake 流程只验证脚本和真实 Writer/Core 的连接,不提高上述任一品牌的验证等级。
|
|
70
|
+
|
|
71
|
+
## 本轮验收
|
|
72
|
+
|
|
73
|
+
Node `24.20.0` / Linux。重构后的真实 DeepSeek 命令:
|
|
74
|
+
|
|
75
|
+
```sh
|
|
76
|
+
node scripts/smoke-deepseek-init.mjs --no-thinking
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
运行时间 `2026-09-08T00:45:50.425Z` 至 `00:45:58.421Z`;报告 `/tmp/cm-provider-smoke-IECYBh/report.json`。Init 和 Markdown 各一次 Runtime 尝试成功,六项检查全部通过,`retentionVerified:true`。两个匹配的 DB/文件回执 ID 为 `7a7bbc7a-014a-4f9c-9898-8c1c42e1489e`、`85eed726-820d-4901-b4eb-6d62ae056bfc`。正式 Memory 前后 SHA-256 均为 `c4e1a57b4617869cc30b69d1c4e93c76bb0112985bedde2b4f9662ba17ac75a7`。
|
|
80
|
+
|
|
81
|
+
该次维护 schema SHA-256:`abba185086bf8ffac0a99a8415a15e98b92d7ab6101998bbb1a3aa12056a473d`;提示 SHA-256:`9a1bd9709694aba8803d350b83ff5d0b8f01d288768f7e05b16859428ea666fe`。
|
|
82
|
+
|
|
83
|
+
聚焦验收覆盖 CLI 参数、来源关联回执、部分处理、ignore、缺失读取标记、正式存储变化,以及构建产物上的 Responses / Chat 真实本地 HTTP → CLI/MCP → Writer/Core → 回执 → 重启读取。无需真实 Key 的构建产物回归单独执行:
|
|
84
|
+
|
|
85
|
+
```sh
|
|
86
|
+
npm run build
|
|
87
|
+
npm run test:provider-smoke
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
此命令采用 Node 内置 test runner,类似 `test:consumer`;需先构建,不隐式加入构建前的 Vitest gate。纯判断与参数测试包含在正常 Vitest suite 中。
|
|
91
|
+
|
|
92
|
+
本轮结果:2 个 Vitest 文件 / **44 项通过**(新增脚本判断 14 项 + 既有 Chat/诊断 30 项),构建产物集成 **3 项通过**,typecheck、构建、脚本语法、`git diff --check` 和本地文档链接检查通过。最终日志为 `/tmp/cm-provider-smoke-focused-final.log`、`/tmp/cm-provider-smoke-integration-final-2.log`、`/tmp/cm-provider-smoke-typecheck-2.log`、`/tmp/cm-provider-smoke-build.log`。新增参数表测试最初有 TypeScript 的 `it.each` 回调签名错误,原输出保留于 `/tmp/cm-provider-smoke-typecheck.log`;改为对象行后复验通过,未改产品类型。
|
|
93
|
+
|
|
94
|
+
按本轮修改范围,未重跑上一轮完整 341 项 gate 或 Linux consumer;本轮未改包导出及生产源码。Windows/macOS/WSL、桌面客户端及其他 Provider 的真实请求仍未执行。
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# 发布与用户安装
|
|
2
|
+
|
|
3
|
+
## 当前状态
|
|
4
|
+
|
|
5
|
+
v0.2 使用所有者确认的 MIT 许可证。npm 版本是 **0.2.0**,GitHub tag 是 **v0.2.0**,
|
|
6
|
+
包名 `common-memory-core`,可执行命令 `common-memory`,默认发布标签 `latest`。
|
|
7
|
+
这是面向早期使用者的版本,不声称已经完成全部真实客户端验收。
|
|
8
|
+
|
|
9
|
+
Linux、macOS 和 WSL 在 Node 24 环境使用同一行安装命令:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install -g common-memory-core@0.2.0
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
安装 Node / WSL 是前置要求,不包含在这个 npm 命令中。详细说明见 [README](../README.md)。
|
|
16
|
+
|
|
17
|
+
## 支持范围
|
|
18
|
+
|
|
19
|
+
| 路径 | 要求与证据边界 |
|
|
20
|
+
| --- | --- |
|
|
21
|
+
| Core、CLI、stdio MCP | Node **24.x**;Linux / macOS CI 覆盖完整 gate 和真实 tarball 隔离安装 |
|
|
22
|
+
| Pi | 精确 peer 版本 **0.84.4**;事件契约和包加载测试不等于所有真实交互组合已验证 |
|
|
23
|
+
| Codex / Work 会话捕获 | rollout 仅接受 **Codex 0.153.4**;未知版本拒绝而非猜测;真实 UI Hook 信任仍需验收 |
|
|
24
|
+
| Windows 用户 | 产品部署在 WSL;原生 Windows 是薄桥接,不是第二套 Core 部署。Windows CI 结果应单独查看 |
|
|
25
|
+
| macOS | 与 Linux 共用 npm 安装入口;macOS CI 覆盖代码及安装消费,真实 Desktop UI 验收仍独立 |
|
|
26
|
+
| 模型 | Responses 或 Chat Completions,必须满足所选协议;假模型测试不证明实际模型的记忆判断质量 |
|
|
27
|
+
|
|
28
|
+
Pi peer 暂时是**必需依赖**。即使只用 CLI/MCP,npm 也会安装对应的 Pi peer 依赖树;
|
|
29
|
+
当前版本不承诺无 Pi 的轻量安装。不要用 `--legacy-peer-deps` 掩盖不兼容的宿主版本。
|
|
30
|
+
不要把 Windows CI 的纯代码检查理解成 Windows 原生宿主支持。
|
|
31
|
+
|
|
32
|
+
## 版本和权限
|
|
33
|
+
|
|
34
|
+
- `package.json.version`、锁文件、README 安装版本、`test:published` 和 GitHub tag 必须一致。
|
|
35
|
+
- 仓库具有 `LICENSE` 和 `package.json.license: MIT`,不再设置 `private: true`。
|
|
36
|
+
- 用 Node 24 执行 `npm install --package-lock-only --ignore-scripts` 同步变更后的元数据。
|
|
37
|
+
- `npm run release:check` 检查发布元数据及许可证文件存在,不能代替贡献权利审查或 npm 权限检查。
|
|
38
|
+
- npm 包的同一个版本不能覆盖;发现问题时修复源码并发布新的补丁版本,不移动已有发布 tag。
|
|
39
|
+
|
|
40
|
+
## 发布前的完整检查
|
|
41
|
+
|
|
42
|
+
先停止修改这一份工作树,确认提交包含所有需要的源码和文档;不能仅提交已跟踪文件而
|
|
43
|
+
遗漏新加的 TUI 模块或测试。不要提交 `.env`、记忆目录、SQLite、个人会话、编辑器交换文件。
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
node --version # 24.x
|
|
47
|
+
npm ci
|
|
48
|
+
npm run release:check
|
|
49
|
+
node scripts/verify.mjs # typecheck → boundaries → full tests → build,各一次
|
|
50
|
+
npm run test:consumer # 使用刚构建的 tarball;隔离 npm 安装,需要 registry 网络
|
|
51
|
+
npm audit --omit=dev
|
|
52
|
+
npm pack --dry-run # 检查文件清单;prepack 会重新构建,避免陈旧 dist
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`test:consumer` 不再链接工作树的 `node_modules`:它在临时目录安装 tarball 和生产/peer
|
|
56
|
+
依赖(禁止安装脚本,不要求用户拥有 TypeScript),编译外部 TypeScript 消费者,并验证
|
|
57
|
+
打包 prompt、Writer 提交/重启读取、Pi entry、CLI 命令链接、无 Key 的只读 MCP 和 SQLite
|
|
58
|
+
不被只读端打开。它不调用真实模型,也不读取用户存储。
|
|
59
|
+
|
|
60
|
+
`core-ci` 在 Ubuntu、macOS 和 Windows 执行相同完整 gate;Ubuntu / macOS 追加隔离
|
|
61
|
+
tarball 测试。macOS 测试临时目录采用真实路径,避免系统 `/var` 别名与禁止符号链接的
|
|
62
|
+
存储约束冲突;不会放松产品的路径安全检查。发布者应检查本次提交对应的 CI,而不是沿用
|
|
63
|
+
历史通过记录。安装测试联网失败不是产品已经通过的证据。
|
|
64
|
+
|
|
65
|
+
`prepublishOnly` 依次执行发布锁检查、完整 gate 和隔离消费者检查;`prepack` 构建生产产物。
|
|
66
|
+
不要使用 `npm publish --ignore-scripts` 绕过检查。验证失败时保留原输出并修复原因。
|
|
67
|
+
|
|
68
|
+
## 首次 npm 发布(维护者手动执行)
|
|
69
|
+
|
|
70
|
+
完成上述检查、提交并推送经过验证的代码后,再进行账号认证和发布。README 先写好
|
|
71
|
+
正式版本的安装说明;发布完成后使用 registry 返回的产物验证,不用工作树构建冒充已发布包。
|
|
72
|
+
|
|
73
|
+
```sh
|
|
74
|
+
npm login
|
|
75
|
+
npm whoami
|
|
76
|
+
npm view common-memory-core versions --json
|
|
77
|
+
# 首次发布时 E404 可能是尚未存在,也可能是权限问题;不是名称预留证明。
|
|
78
|
+
npm publish --access public --tag latest
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
不要把 npm token/API Key 写入仓库。认证、账号 2FA、包名所有权、GitHub 仓库可见性和
|
|
82
|
+
Release/tag 都要由维护者在对应服务上完成。本文和本地验证不会自动推送或发布。
|
|
83
|
+
发布后从一个新目录安装并核对 registry 中的版本:
|
|
84
|
+
|
|
85
|
+
```sh
|
|
86
|
+
npm view common-memory-core@0.2.0 version dist.integrity
|
|
87
|
+
npm install -g common-memory-core@0.2.0
|
|
88
|
+
common-memory --version
|
|
89
|
+
common-memory --help
|
|
90
|
+
npm run test:published
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
npm 发布成功并完成本地 registry 检查后,创建 GitHub Release `v0.2.0`。它会触发
|
|
94
|
+
`published-package` 工作流:Ubuntu / macOS 实际执行上述一行全局安装,核对 CLI 版本,
|
|
95
|
+
然后从 npm 下载 tarball 验证类型导出、Writer 提交/重启、Pi 模块和无 Key 的只读 MCP。
|
|
96
|
+
也可通过 Actions 的 Run workflow 输入精确版本手动重跑。这个工作流**不发布包**,只有
|
|
97
|
+
只读仓库权限,不需要 npm 写 token。
|
|
98
|
+
|
|
99
|
+
必须查看这次 commit 的 `core-ci` 和这次 Release 的 `published-package` 结果。任何失败都
|
|
100
|
+
保留日志、定位原因并修复;网络失败也不能标成通过。Linux CI 不代表 WSL 桌面宿主,macOS
|
|
101
|
+
CI 也不代表真实 Desktop UI 信任和事件组合已验收。
|
|
102
|
+
|
|
103
|
+
未来如需自动发布,可以在 npm 包设置中配置 GitHub Actions trusted publisher;工作流
|
|
104
|
+
身份必须与设置一致。目前没有自动发布工作流,也不依赖未配置的 OIDC 权限。
|
|
105
|
+
参考:[npm 生命周期](https://docs.npmjs.com/cli/v11/using-npm/scripts)、
|
|
106
|
+
[trusted publishing](https://docs.npmjs.com/trusted-publishers)。
|
|
107
|
+
|
|
108
|
+
## 从 GitHub 使用(源码路径)
|
|
109
|
+
|
|
110
|
+
项目按 [MIT](../LICENSE) 分发。源码开发和贡献使用:
|
|
111
|
+
|
|
112
|
+
```sh
|
|
113
|
+
git clone https://github.com/Mr-remon219/common-memory.git
|
|
114
|
+
cd common-memory
|
|
115
|
+
npm ci
|
|
116
|
+
npm run build
|
|
117
|
+
node dist/cli/main.js
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
本版不承诺 `npm install github:...` 直接安装源码;使用上述 clone/build 路径或正式 npm
|
|
121
|
+
包。生成的 MCP/Hook 配置固定实际 Node、CLI 和 home 路径,移动安装或切换 Node 后需要重新
|
|
122
|
+
生成并审阅。安装的 CLI 与 Pi 宿主必须使用同一个 `COMMON_MEMORY_HOME`。
|
|
123
|
+
|
|
124
|
+
## 升级、备份和卸载
|
|
125
|
+
|
|
126
|
+
- **先停止所有写端**:Pi、MCP、Codex/Work hooks,以及已经脱离宿主的 `session-drain`
|
|
127
|
+
消费者。仅关闭终端不能证明消费者已退出。不同版本不能同时写同一个 dataRoot。
|
|
128
|
+
- 用 `common-memory status` 核对配置目录及真实 dataRoot。离线备份配置目录和**整个
|
|
129
|
+
dataRoot**(Markdown、runtime.sqlite、现存的 SQLite sidecar、registry、receipts 和
|
|
130
|
+
recovery 元数据);dataRoot 可以在 home 外,不能只备份 `~/.common-memory`。
|
|
131
|
+
- SQLite 是持久队列与来源链接存储,**不能删除后从 Markdown 重建**。备份中的 `.env`
|
|
132
|
+
和对话缓存同样敏感;使用私有权限和适当的加密存储。
|
|
133
|
+
- 安装新版本后重新生成受路径影响的集成,先检查 `status` / `show`,有待处理交接时显式
|
|
134
|
+
运行 `session-drain`。V1 或未知 schema 不自动迁移;不要尝试靠删除数据库完成升级。
|
|
135
|
+
- 回退前停止新版本所有写端,必要时恢复同一时点的完整离线备份;不保证旧程序可打开新
|
|
136
|
+
schema。恢复到新路径时需要更新配置及项目/宿主路径,不能假定路径自动迁移。
|
|
137
|
+
- `npm uninstall -g common-memory-core` 只卸载程序。先在宿主中移除对应 hooks、MCP 配置和
|
|
138
|
+
Pi 资源注册;用户数据不自动删除。不要把撤销宿主注册理解成删除远端已披露的内容。
|