Repository navigation
Fold canonical equivalents into the three identity keys that bypassed the name rule - #2696
Conversation
… the name rule Fixes #2692 A sibling Bot name, a role label and a memory topic compared with their own trim().toLowerCase(), so either canonical spelling of one visible name was two identities. They now use the name key #2691 put in core/src/shared/identity.js, and a topic file keeps the spelling it was written with so nothing already saved is lost.
|
Verdict: PASS at bb4a4bc Ran at this tip: Review points.
|
Written-by: Dev
Fixes #2692
Owner: Dev
Reviewer: Reviewer
What changed
Three identity keys still compared with their own
trim().toLowerCase()— #2691 fixed the Bot and room name key only — so either Unicode canonical spelling of one visible name was two identities at each of them. All three now use that key, which this change moves tocore/src/shared/identity.jsasnameKey(host/text.js'snormalizeis that function, so the host, a shared module and the browser bundle cannot drift apart).checkCreate(the duplicate guardcreate_child_botasks),findBotByName, andmoveBot's sibling check: a child namedCafe+U+0301 is refused while the siblingCafé(NFC) exists, and the name lookup resolves either spelling to that one Bot. The plugin ships as its own package, soplugins/tree/src/identity.jsis the same function;plugins/tree/test/identity.test.jsfails when the two copies answer differently.shared/task-board.jssameRole, so a queued card reaches the member whose label spells the same role the other way instead of staying in the pool.memory.jscleanTopic, where the key is also the file stem. A topic file already on disk keeps the spelling it was written with: the key is computed from the name on disk, so가.md(written before this change) is still topic[[가]],recallreads it andrememberappends to that same file; when both spellings exist the file already in key form wins, and the other is left on disk untouched rather than merged. The## Indexlink check and the link a delete removes compare by key, so no second link is written. A decomposed Latin topic, refused while U+0301 was not a\p{L}, is now accepted as its NFC form.core/client.jsis rebuilt (npm run build) becausetask-board.jsis in the bundle, andpatches/ds-bot/is regenerated fromcore/.CI at this tip:
tests-okgreen, withplugins (social|tree|workflow|timeline),package,merge-gate,ubuntu-latest · Node 24 · DSH 0.2.0-rc.2andmock · ubuntu · scripted modelgreen too.enqueue-guardis red for the one expected reason,no Verifier report names the tip bb4a4bc5bec5.Verification at the tip
Tip SHA: bb4a4bc
Ran (from the tip's working tree, TZ=UTC):
node --import ./test/harness-resolve.mjs --test test/memory.test.js test/memory-empty.test.js test/memory-count-read-failure.test.js test/memory-panel-readonly.test.js test/memory-search.test.js test/memory-search-edge.test.js test/name-identity.test.js test/bot-tasks.test.js test/kanban.test.js test/inbox-task-status.test.js— 184 tests, 0 failednode --import ./test/harness-resolve.mjs --test test/task-handoff*.test.js test/project-board*.test.js test/bot-tasks.test.js test/readonly-window-reads.test.js test/tasks*.test.js— 191 tests, 0 failedcd plugins/tree && npm test— 139 tests, 0 failednode scripts/ds-bot-patches.mjs check— pin ok, 10 patches apply,core/equalsds-bot/+ patchesnode scripts/ds-bot-patches.mjs canonical—patches/ds-bot/is what generate writes (generate is a no-op)node core/scripts/build-client.mjs --check— client.js matchessrc/clientcd core && npm run lint— oxlint 0 errors,arch-docs: OK (21 changed file(s))node scripts/lint-plugins.mjs— 0 errors, all four plugins packed and importednode .github/scripts/changelog.mjs check,node .github/scripts/check-mojibake.mjs --check— okNot run (and why): the full
npm run verifyand the wholecore/testsuite — this change does not ask for them, and the affected files' suites were run file by file above; no smoke test (nothing undercore/index.jsorcore/src/host/that the smoke test drives changed beyondmemory.js's topic key).Red first
The three new tests were written and run against the base blobs before anything was implemented; the exact commands and output are in the Dev run's evidence (
red.txt), summarized:not ok 2 - #2692 a sibling name is one identity…→error: 'no bot named "Café"'atfindBotByName(src/tree.js:239), plus the missingsrc/identity.js;'가' !== '가'fromcleanTopic, andrecallansweringNo topic [[가]] there. Topics: [[가]] (yours).;sameRole('Café' NFC, 'Cafe'+U+0301)→false !== true.Checkpoint
{ "pr": 2696, "claim": "Dev", "issue": 2692, "summary": "Three identity keys that compared raw text now use the name key #2691 introduced, moved to core/src/shared/identity.js. A tree sibling name, a member role label and a memory topic are each one identity in either Unicode canonical form, and a topic file written under an older spelling is still that topic's file. The tree plugin keeps its own copy of the function because it ships alone, pinned by a test.", "files": [ "core/src/shared/identity.js", "core/src/host/memory.js", "core/src/host/text.js", "core/src/shared/task-board.js", "plugins/tree/src/identity.js", "plugins/tree/src/limits.js", "plugins/tree/src/tree.js", "core/client.js" ], "checks": { "ran": "node scripts/ds-bot-patches.mjs check; node scripts/ds-bot-patches.mjs canonical; npm test (plugins/tree); node core/scripts/build-client.mjs --check", "result": "green", "at": "bb4a4bc5bec57fafd78a3dc135359eedf5b6949c" }, "next": "none — ready for review" }