Repository navigation
refactor: one owner for shared values, wire types and sync checks - #426
Merged
Merged
Conversation
…eir contracts The Host kept its own copies of values two Sources own: - protocol.ts declared Memory Spaces' categories, sources, edge types, intents and embedding defaults. Since #421 no client code reads them, so protocol.ts stops declaring them: the named tools build their enums from Memory Spaces' ./contracts and config-values.ts re-exports the embedding defaults from there. Nothing is added to the client build's bundled list. - config-values.ts copied the Runtime limits. The defaults now come from RUNTIME_MEMORY_LIMITS, and the ceiling from RUNTIME_MEMORY_LIMIT_MAX_BYTES, a new export of the Runtime contracts. - The placement capabilities were listed in config.ts, in Memory Spaces' contracts (as a type) and in its config.ts. Memory Spaces' contracts now export MEMORY_PLACEMENT_CAPABILITIES and derive the type from it; both schemas take it. Memory Spaces' Source also builds its own category, source, intent and edge checks from its contract lists. The timeout bounds stay as they were in both places (100..120,000 ms in the Host, 1..600,000 ms in Memory Spaces); a comment at each names the other and the roadmap item that will align them. Tests: the Starter patch writes only the code's defaults into the mnemon Entry (the schema's and resolveConfig's); the Host bounds the Runtime limits as the Runtime Source does; both schemas take exactly the listed placement capabilities. The model-visible tool fixture is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ocol CONTRIBUTING makes src/host/protocol.ts the browser-safe source of the Client and Host wire DTOs. Three results that cross the RPC boundary were still declared in the coordinator (subagent.ts): DelegatedAnswerResult (agent-search), CoordinatedDocumentResult (Document writes and archives) and CoordinatedRuntimeMemoryResult (runtime memory writes, as a management result's value). They move into protocol.ts; subagent.ts re-exports them as it does DelegatedWriteResult. RecallResult stays: it is a tool result the model reads, not an RPC answer. The endpoint names were free strings on both sides. protocol.ts now lists every endpoint the Host serves, by channel (MNEMON_RPC_ENDPOINTS), with the same names. callMnemonRpc, MnemonClient's calls, its component operations and the operations a page lends a component are typed against it, so a misspelled name or one sent on the wrong channel no longer compiles. The View handler and the remote settings guard read their names from it instead of their own literal lists. No name, message or dispatch order changes. tests/rpc-endpoints.spec.ts registers the Host's handlers and checks that, against every name the list holds and every word the handler modules spell, each channel serves exactly the listed endpoints; it then records what the client sends from each of its callers and checks that every call is listed, and that the listed endpoints it never calls are exactly the 28 the Host keeps for other callers (the direct paths the workbench left in September 2026, the single-turn activity read and the View preview and plugin install). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…and the Host src/client/sync-view.ts re-implemented, "as the Host checks it", the rules in src/host/sync-config.ts, and the machine name and GitHub repository name rules of machine-identity.ts and github-auth.ts. The rules move into src/host/sync-rules.ts, which imports nothing and which protocol.ts re-exports, with MNEMON_MACHINE_LABEL_MAX. Both sides call them; every message stays where it was, word for word. Where the two sides differed, each keeps what it did: - A local repository path: the form, which cannot know the Host's platform, takes portableAbsolutePath (a POSIX path, a Windows path on a drive or a UNC share); the Host passes its own platform's path.isAbsolute, so the same values validate on each platform as before. - A NUL byte in a repository address or a directory: only the Host refuses it, as before. The rest were the same rules: the branch checks the Host alone spelled out follow from the shared pattern, and an empty author address keeps meaning this machine's Git identity on the Host. tests/sync-rules.spec.ts pins both sides' verdicts and where they differ, and the browser boundary test now follows every module protocol.ts takes values from, sync-rules.ts included, for Node imports. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…to the endpoint list Two places the endpoint list typed loosely: - MnemonClient.componentOperation took any read or write endpoint in either mode. Its endpoint is now typed by the mode it is given, so a read operation named after a write endpoint no longer compiles. The page's lent operations, which pass either mode, compile as before. - The API Gateway's settings guard let through any name in the shared settings list and asked for the trusted-host grant only for mutate, so a settings endpoint added later would have been reachable remotely without a decision. It now keeps what a remote page needs for each settings endpoint (get: read, mutate: management) in a map typed against the list, which does not compile until a new endpoint is given one. Nothing a page receives changes: get and mutate answer as before, and any other name, constructor and __proto__ included, gets the same unknown endpoint answer, which a new test in tests/remote-rpc.spec.ts pins. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The endpoint test now also counts a View endpoint the list names but nothing dispatches, which passes the View guard and meets "Unknown View operation", as refused, so such a name fails it as it does on the other channels. - The configuration tests pin the literal runtime limits (10,240, 4,096 and 1,048,576 bytes) that stored settings are checked against, and the schema messages for a limit over the ceiling and for an unknown placement capability. - The sync rule test checks the GitHub repository names through GitHub sign-in's own create(), with a stand-in credential store and GitHub, so it compares the form with the Host rather than with the shared rule. All three pass with main's Host and client modules swapped in. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…owner Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ync checks The record lists what moved where, where the settings form and the Host still differ and why each keeps its rule, what stays as it is (the 28 endpoints only other callers use among them), the bundle and package comparison with main 7a7e1ae, and a harness that runs both sides' sync checks over 4,650 inputs with the same output on main's modules and this branch's. Its results are those of the merge with main 7a7e1ae (#424, #425). The changeset covers dsh-mnemon and the two Sources whose contracts gain an export, MEMORY_PLACEMENT_CAPABILITIES and RUNTIME_MEMORY_LIMIT_MAX_BYTES. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… before The remote settings map (3dd8b72) looked a name up with Object.hasOwn, which reads its key as text, so a malformed endpoint from a paired remote page such as ["get"] or ["mutate"] reached the settings handler or the trusted-host refusal. Before the map, any name other than the strings get and mutate got "unknown remote Mnemon settings endpoint" without the handler being asked. Only a string is looked up now, so it does again. No authority changed either way. The new test sends ["get"], ["mutate"], 7 and null with and without the grant; it fails without the check and passes with main's remote-rpc.ts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… READMEs As #416 did for its contracts exports, each package README now names what this branch adds to its ./contracts entry: RUNTIME_MEMORY_LIMIT_MAX_BYTES, beside the existing RUNTIME_MEMORY_LIMITS, in the runtime Source's, and MEMORY_PLACEMENT_CAPABILITIES, from which MemoryPlacementCapability is derived, in Memory Spaces'. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…w channel The channel table in the Interfaces reference said remote pages may read /dsh-mnemon-review and need remoteAccess: trusted-host only for reconcile and apply. MnemonRemoteService.review refuses every review endpoint without the grant, as the paragraph below the table already says, so the row now says that too, in English and Chinese. A test pins the refusal for each of the six review endpoints. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The record now says what the types prove about channels and modes: a call that names its channel or mode itself cannot send a name that channel does not serve, while one that picks it at run time, as assistSource and the page's lent operations do, takes any name one of its channels serves. It lists the string check in the remote settings guard, the two README mentions and the corrected review row of the Interfaces reference, and the checks run after them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 17, 2026
11 of 28 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
摘要 / Summary
技术债审查(M2、M3)发现:Starter 的 Host 复制了 Source 中的取值,部分 wire 结果类型声明在浏览器安全的协议之外,RPC 端点名在两端各写一份,设置表单重新实现了 Host 的 Git 同步校验。本次让它们各自只有一个归属:Host 直接从各 Source 的 contracts 取值;结果类型移入
protocol.ts;MNEMON_RPC_ENDPOINTS列出 Host 提供的全部 75 个端点并为客户端调用加上类型;Git 同步校验规则放进浏览器安全的sync-rules.ts,前后端共用。用户和模型看到的内容不变,已保存的配置照旧通过校验,超时范围不变(路线图第 4 项)。The technical-debt review (M2, M3) found values the Starter's Host copied from the Sources, wire result types declared outside the browser-safe protocol, RPC endpoint names spelled freely on both sides, and a settings form that re-implemented the Host's Git sync checks. Each now has one owner: the Host takes the values from the Sources' contracts, the result types live in
protocol.ts,MNEMON_RPC_ENDPOINTSlists the 75 endpoints the Host serves and types the client's calls, and one browser-safesync-rules.tsholds the Git sync checks both sides run. Nothing users or the model see changes, every stored configuration validates as before, and the timeout bounds stay (roadmap item 4).关联 Issue 或背景 / Related Issue or Context
Items M2 and M3 of the technical-debt review after v0.5.31 (#413).
涉及区域 / Affected Areas
PR 类型 / PR Type
变更内容 / Changes
protocol.tsdrops its copies of the memory categories, sources, edge types, intents and embedding defaults;tools.ts(the named tools' enums) andconfig-values.tstake them fromdsh-mnemon-source-memory-spaces/contracts. Runtime limit defaults come fromRUNTIME_MEMORY_LIMITSand the ceiling from a newRUNTIME_MEMORY_LIMIT_MAX_BYTES; the placement capabilities from a newMEMORY_PLACEMENT_CAPABILITIES. A test keeps themnemonEntry incordis.patch.ymlequal to the schema andresolveConfigdefaults. The two timeout bounds stay, each with a comment naming the other.DelegatedAnswerResult,CoordinatedDocumentResultandCoordinatedRuntimeMemoryResultmove intoprotocol.ts(re-exported bysubagent.ts).MNEMON_RPC_ENDPOINTSlists the 75 endpoints on 9 channels; the client's calls, component operations by mode and the remote settings guard (a typed map that fails closed) are typed against it, and a test keeps it equal to what the Host dispatches.src/host/sync-rules.ts(browser-safe, no imports, re-exported byprotocol.ts) holds the branch, directory, repository, author email, machine name and GitHub repository rules both sides call; messages are byte-identical, and where the two sides disagreed each keeps its old behavior (listed on the roadmap candidates in the record).interfaces.md(both languages) now says the review channel needs a trusted host, as the code does. Recorddocs/pr-assets/contracts-one-ownerwith an equivalence harness. Changeset:dsh-mnemon,dsh-mnemon-source-memory-spaces,dsh-mnemon-source-runtimepatch.最新代码确认 / Latest Codebase Confirmation
main分支开发,或在提交前已 rebase 或合并最新main。 / I developed from the latestmain, or rebased or merged the latestmainbefore submitting.同步命令 / Sync command:
Branched from
03dd40a4(#423);main7a7e1ae1(#424, #425) merged in5aa86e40.AI 编码披露 / AI Coding Disclosure
使用的 AI 模型 / AI model used: Claude Opus 5.5 (
claude-opus-5-5)使用的编码 Agent 工具 / Coding Agent tool used: Claude Code
仓库规范检查 / Repository Rules
@deepseek-ai/*NPM 契约。 / I did not modify DSH source or point tsconfig at a DSH source checkout, and used only published@deepseek-ai/*NPM contracts.src/host/protocol.ts为准,没有在两侧重复定义 wire DTO。 / The Client and Host boundary still uses browser-safesrc/host/protocol.tsas the source for wire DTOs.lib/文件。 / I did not commit tokens, credentials, private memory, unredacted logs, or generatedlib/files.兼容性与数据安全 / Compatibility and Data Safety
Config({}),resolveConfig({})and the config-values exports are byte-identical; every endpoint keeps its name, channel and authority; a malformed remote settings endpoint is refused exactly as on main (with a test); sync check messages are identical (a harness over 4,650 inputs gives the same digest on main and the branch).lib/index.jschanges among the Starter's entries, so Sources importingdsh-mnemon/*are unaffected.本地验证 / Local Validation
执行的命令 / Commands run:
结果摘要 / Result summary:
5aa86e40and ona8c40265:verifypassed (root tests 2,108 passed, 7 skipped in 151 files; plugin tests 593 passed, 3 skipped; deterministic build; Headless; package with publint and attw);verify:pluginspassed; installed DSH 0.2.0-rc.2: 2,105 passed, 10 skipped; Git sync 64/64 on 0.2.1-rc.2 and on 0.2.0-rc.2. After the review follow-ups: typecheck, the affected specs (78 tests in 7 files), the root tests (2,109 passed, 7 skipped),verify:docsandrelease:intent(all three packages) pass.interfaces.mderror are fixed in1928b1ab..6e928b30.用户可见变更证据 / Local Feature Evidence
证据 / Evidence: N/A, nothing users see changes; the record has the equivalence harness and the checks.
🤖 Generated with Claude Code