Live-sync audit: compare metadata.json without its last-edited stamp #29

Merged
claude merged 4 commits from oss-oo/audit-metadata-stamp into main 2026-10-28 04:17:17 +00:00
Member

Owner request (Claudiu, 2026-10-28): the audits of all three applets compare metadata.json without Cinnamon's "last-edited" stamp, each through its repository's PR flow.

"last-edited" is Cinnamon's metadata key. On the station the Spices Update applet (SpicesUpdate@claudiux 7.12.0, hourly) writes Math.ceil(Date.now() / 1000) into the live metadata.json of every applet it guards and saves the file with JSON.stringify(data, null, 2) (no final newline). On 2026-10-28 at 04:21:01 it stamped all 16 live applets with 1793157662. The live-sync audit compared every manifest file byte for byte, so a stamped folder failed with FAIL metadata.json: hash mismatch until the next install.

Change

  • audit_deployment.py: when the bytes of metadata.json differ (this destination only), the installed file passes if it is a JSON object whose "last-edited" is an integer and whose other content equals the payload. The comparison is done as JSON text, so true is not 1 and key order doesn't count. The audit then prints OK metadata.json (last-edited stamp). Anything else stays FAIL metadata.json: hash mismatch:

    • another value or a missing key;
    • a layout change without the stamp;
    • a stamp that is a string, null, true, a float, NaN or Infinity (Python reads the last two, Cinnamon's JSON.parse rejects them);
    • broken or pathologically deep JSON, a non-object, or a file above 1 MiB.

    Every other file is still compared byte for byte; the symlink, missing-target and EXTRA checks are unchanged.

  • Tests for each case, and for where the note appears: never for a byte-identical file, only on the metadata.json line, and not for icons/metadata.json. 15 mutants of the check are all caught in each repo.

  • The skill and README texts name the exception and its writer; the post-sync checklists no longer require byte-equal hashes.

Live (read-only audits with this branch)

  • z-usage: EXPECTED=24 VALID=24 SYMLINKS=0 MISMATCHES=0 EXTRA=0 CACHE=2 (main: VALID=23 MISMATCHES=1)
  • claude-usage: EXPECTED=24 VALID=24 SYMLINKS=0 MISMATCHES=0 EXTRA=0 CACHE=0 (main: VALID=23 MISMATCHES=1)
  • chatgpt-usage: EXPECTED=25 VALID=25 SYMLINKS=0 MISMATCHES=0 EXTRA=0 CACHE=0 (installed after the 04:21 run, so not stamped yet)

No payload change (the audit is not in packaging/files.json), so no release.

Same change in all three applets: cinnamon-z-usage #29, cinnamon-claude-usage #17, cinnamon-chatgpt-usage #12.

🤖 Generated with Claude Code

Owner request (Claudiu, 2026-10-28): the audits of all three applets compare `metadata.json` without Cinnamon's `"last-edited"` stamp, each through its repository's PR flow. `"last-edited"` is Cinnamon's metadata key. On the station the **Spices Update applet** (`SpicesUpdate@claudiux` 7.12.0, hourly) writes `Math.ceil(Date.now() / 1000)` into the live `metadata.json` of every applet it guards and saves the file with `JSON.stringify(data, null, 2)` (no final newline). On 2026-10-28 at 04:21:01 it stamped all 16 live applets with `1793157662`. The live-sync audit compared every manifest file byte for byte, so a stamped folder failed with `FAIL metadata.json: hash mismatch` until the next install. ## Change - `audit_deployment.py`: when the bytes of `metadata.json` differ (this destination only), the installed file passes if it is a JSON object whose `"last-edited"` is an integer and whose other content equals the payload. The comparison is done as JSON text, so `true` is not `1` and key order doesn't count. The audit then prints `OK metadata.json (last-edited stamp)`. Anything else stays `FAIL metadata.json: hash mismatch`: - another value or a missing key; - a layout change without the stamp; - a stamp that is a string, `null`, `true`, a float, `NaN` or `Infinity` (Python reads the last two, Cinnamon's `JSON.parse` rejects them); - broken or pathologically deep JSON, a non-object, or a file above 1 MiB. Every other file is still compared byte for byte; the symlink, missing-target and EXTRA checks are unchanged. - Tests for each case, and for where the note appears: never for a byte-identical file, only on the `metadata.json` line, and not for `icons/metadata.json`. 15 mutants of the check are all caught in each repo. - The skill and README texts name the exception and its writer; the post-sync checklists no longer require byte-equal hashes. ## Live (read-only audits with this branch) - z-usage: `EXPECTED=24 VALID=24 SYMLINKS=0 MISMATCHES=0 EXTRA=0 CACHE=2` (main: `VALID=23 MISMATCHES=1`) - claude-usage: `EXPECTED=24 VALID=24 SYMLINKS=0 MISMATCHES=0 EXTRA=0 CACHE=0` (main: `VALID=23 MISMATCHES=1`) - chatgpt-usage: `EXPECTED=25 VALID=25 SYMLINKS=0 MISMATCHES=0 EXTRA=0 CACHE=0` (installed after the 04:21 run, so not stamped yet) No payload change (the audit is not in `packaging/files.json`), so no release. Same change in all three applets: [cinnamon-z-usage #29](https://oss-oo.io/OSS-Singularity/cinnamon-z-usage/pulls/29), [cinnamon-claude-usage #17](https://oss-oo.io/OSS-Singularity/cinnamon-claude-usage/pulls/17), [cinnamon-chatgpt-usage #12](https://oss-oo.io/OSS-Singularity/cinnamon-chatgpt-usage/pulls/12). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
claude agent added 1 commit 2026-10-28 03:34:59 +00:00
Live-sync audit: compare metadata.json without Cinnamon's last-edited stamp
All checks were successful
Checks / Functional checks (pull_request) Successful in 47s
c508a179ca
Cinnamon writes a "last-edited" key into the installed metadata.json after
it (re)loads the applet and rewrites the file in its own layout, so the
audit's byte check flagged metadata.json as a hash mismatch until the next
install. The audit now compares metadata.json by content without that one
key (and reports "OK   metadata.json (Cinnamon's last-edited stamp)");
every other key must still match, unreadable JSON or a non-object still
fails, and every other file is still compared byte for byte.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Live-sync audit: only Cinnamon's stamp may differ in metadata.json
All checks were successful
Checks / Functional checks (pull_request) Successful in 43s
ad621ab522
The exception to the byte check now needs the "last-edited" key in the
installed metadata.json, and everything else is compared as JSON text: true
is no longer taken for 1, key order is no content. A layout change without
the stamp, a JSON array naming the key and pathologically deep JSON fail
cleanly. The texts say only what is verified on the station: the stamp shows
up in the live file some time after an install, with the file rewritten in
another JSON layout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Live-sync audit: an integer stamp, named after its writer
All checks were successful
Checks / Functional checks (pull_request) Successful in 41s
4fd2a26776
Review fixes. The stamp must be whole epoch seconds (type int): NaN or
Infinity, which Python reads but Cinnamon's JSON.parse rejects, a string,
null and true no longer pass. A metadata.json above 1 MiB is not read into
memory. The note reads "(last-edited stamp)", and tests pin where it
appears: not for a byte-identical file, only on the metadata.json line, and
not for icons/metadata.json.

The writer is now known: the Spices Update applet (SpicesUpdate@claudiux
7.12.0) writes Math.ceil(Date.now() / 1000) into the metadata.json of every
applet it guards and saves it with JSON.stringify(data, null, 2); on the
station it ran at 04:21:01 over all 16 live applets. The texts say so, and
the post-sync checklists no longer require byte-equal hashes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Live-sync texts: the stamp's layout and integer condition
All checks were successful
Checks / Functional checks (pull_request) Successful in 46s
968ef19a82
Re-review nits: the claude skill says metadata.json may carry the stamp in
another JSON layout, and both tool READMEs name the integer condition.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude agent changed title from Live-sync audit: compare metadata.json without Cinnamon's last-edited stamp to Live-sync audit: compare metadata.json without its last-edited stamp 2026-10-28 04:16:56 +00:00
claude agent merged commit a6e1c02aa9 into main 2026-10-28 04:17:17 +00:00
claude agent deleted branch oss-oo/audit-metadata-stamp 2026-10-28 04:17:17 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
OSS-Singularity/cinnamon-z-usage!29
No description provided.