rdmsm4x-changelog-20260922-1200-notes-changelog-create-before-delete-and-prefix-collision
rdmsm4x Changelog: notes_changelog.zsh create-before-delete and prefix collision remediation
Date: 2026-09-22 12:00 EDT
Host: rdmsm4x (fleet-wide
deployment)
Agent: agy@rdmsm4x
Issues Resolved: ISSUE-20260922-01,
ISSUE-20260922-02
Commits:
1. Summary
Resolved two critical defects in
~/scripts/notes_changelog.zsh (Rule 26 durable note
publisher used across the fleet by all agents):
- Prefix Substring Collisions
(
ISSUE-20260922-01): Replaced 50-character unbounded substring matching with boundary-delimited prefix matching (MATCH_PREFIX="... - ") and ending timestamp verification (END_STAMP=" - <when>"), preventing notes whose summary is a prefix of another summary (e.g.statementdl-portalvsstatementdl-portal-probe) or notes sharing summaries across different runs from being erroneously deleted. - Delete-Before-Create Order & Missing Deletion Log
(
ISSUE-20260922-02): Reordered operations to create the new note first, verify its folder-scoped existence by note ID inllmlog, and only then delete matching prior revisions of that exact changelog (excludingnewId). All deleted notes are now logged with timestamp, note ID, title, and source file to~/.local/state/claude-notes-autopublish/deletions.logand~/.local/state/notes-changelog/deleted.tsv.
2. Root Cause Analysis
- Prefix Collision:
notes_changelog.zshextracted candidate note IDs matching the first 35 chars ofMATCH_SUBSTRING, and deleted them iffirstLine contains matchSub, wherematchSubwas the first 50 characters of<host> - <type> - <summary>. When one summary was a prefix of another,firstLine contains matchSubevaluated to true for the longer note, deleting an entirely different changelog note into Recently Deleted. - Delete-Before-Create: Notes were deleted prior to
invoking
make new note. If creation timed out or failed, the original record was lost. Additionally, absence of a deletion state log made diagnosing vanished notes difficult.
3. Remediation Details
notes_changelog.zshv1.3:MATCH_PREFIX="$(sane "$HOSTNAME_NOW") - $(sane "$NOTE_TYPE") - $(sane "$NOTE_SUMMARY") - "(includes trailing delimiter).END_STAMP=" - ${NOTE_WHEN}".- Create First: Calls
make new notefirst, storesnewId, and runs a folder-scoped verification loop (count of (every note of tgt whose id is newId) > 0). - Safe Replacement: Only deletes candidate notes
where
cid is not newIdand(firstLine is noteTitle) or (candTitle is noteTitle) or ((firstLine starts with matchPrefix) and (firstLine ends with endStamp)). - Audit Logging: Returns
OK:<newId>\n<delId>\t<delTitle>\n...to zsh, which logs to console and appends to~/.local/state/claude-notes-autopublish/deletions.logand~/.local/state/notes-changelog/deleted.tsv. - Committed to
fleetatfe5bed9underops/notes-publish/notes_changelog.zsh. - Deployed byte-identical script across all 6 fleet hosts
(
rdmsm4x,rdmbair13m5,rdmbair15m5,rdmpw3265m,rdmpw3275m,jdmbair13m5).
4. Verification Evidence
- Prefix Collision Probe:
- Created test notes
test-prefix-baseandtest-prefix-base-longerextension. - Re-published
test-prefix-base. - Verified probe output:
newAAlive: true, oldAGone: true, bAlive: true, deletedCount: 1. The longer prefix note was completely preserved.
- Created test notes
- End-to-End Replacement & Audit Logging:
- Published
rdmsm4x-changelog-20260922-1200-testprefixlonger.mdandrdmsm4x-changelog-20260922-1200-testprefix.md. - Re-published
testprefix: old notep76547was replaced byp76548,testprefixlonger(p76546) remained alive (count: 1). - Audit record confirmed in
~/.local/state/claude-notes-autopublish/deletions.log:2026-09-22 11:57:27 EDT x-coredata://0633F37F-D856-467D-B0FF-5AACA70D027C/ICNote/p76547 rdmsm4x - changelog - testprefix - claude - unspecified - general - 20260922-1200 rdmsm4x-changelog-20260922-1200-testprefix.md
- Published
- Fleet Deployment Verification:
- Target SHA256:
1fa0b76dc81f07a96599360a1cb26cd390a6771453b46aba267b813fbec8d8b2. - Confirmed byte-identical on:
rdmsm4x:1fa0b76dc81f07a96599360a1cb26cd390a6771453b46aba267b813fbec8d8b2rdmbair13m5:1fa0b76dc81f07a96599360a1cb26cd390a6771453b46aba267b813fbec8d8b2rdmbair15m5:1fa0b76dc81f07a96599360a1cb26cd390a6771453b46aba267b813fbec8d8b2rdmpw3265m:1fa0b76dc81f07a96599360a1cb26cd390a6771453b46aba267b813fbec8d8b2rdmpw3275m:1fa0b76dc81f07a96599360a1cb26cd390a6771453b46aba267b813fbec8d8b2jdmbair13m5:1fa0b76dc81f07a96599360a1cb26cd390a6771453b46aba267b813fbec8d8b2
- Target SHA256:
- Ticket Resolution:
ticket resolve ISSUE-20260922-01ticket resolve ISSUE-20260922-02- Committed
85bde51inissuesand pushed tofleetandbackup.