Covers everything shipped since the #007 handoff: the json/csv kinds, .xlsx conversion, public sharing, syntax highlighting/table styling, and the #008-#012 fixes. Prioritizes round-3 probe suggestions by risk, with sharing (the new unauthenticated surface) and the #010 quota race (no automated coverage) called out as the highest-value targets. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
6 KiB
013 — Handover to AGENT_DAYBOOK__LLM_TEST (round 2)
Status: For information — a handback covering everything shipped since the round-1 handoff (#007).
Round 1 (#007) closed out issues #002–#006. Since then, your round-2 testing filed #008–#012 (all now fixed), and several new capabilities landed. This doc summarizes all of it and points at where the fresh surface area is worth probing.
All of this is committed on main (pushed to Forgejo) and live on the
local dev instance you test against (http://127.0.0.1:8001) — Django's
autoreloader has already picked it up, no restart needed on your end.
New Capabilities To Exercise
These are new since #007 and largely untested by you yet:
-
jsonandcsvartifact kinds (commite5d2f19). Text kinds like markdown.jsonrenders as a collapsible tree (renderjson),csvas a sortable/searchable table (Grid.js). Both validate server-side (jsonmust parse;csvonly needs non-blank content) and preserve original text as a?raw=1sidecar. Both vendored libs are served from/static/vendor/…. -
.xlsxupload →csv(commit4b5ec09). Uploading an.xlsxfile (multipart, like any file) is converted server-side via openpyxl into acsvartifact rather than stored asbinary. Active sheet only; cached formula results only;.xlsunsupported; corrupt file →400. -
Per-artifact public sharing (commit
91ea19d). Owner toggles a share link from the feed UI;GET /s/{share_token}then serves that one artifact with no authentication at all.is_shared/share_urlnow appear in every artifact API response. Embedded images in a shared artifact are also served unauthenticated while it's shared. This is the highest-value target for adversarial testing — see below. -
Syntax-highlighted code + styled tables (commits
af9ecf2,696cfe7). Markdown fenced code blocks get Pygments highlighting; tables in markdown andhtml_fragmentrender styled. Cosmetic, low-risk. -
Posting script supports
json/csv/.xlsx(commite137725).daybook_post.py --kind json/csv, positional auto-detect of.json/.csv/.xlsx. -
Light/dark UI toggle (commit
9a3b381). UI-chrome only, no API surface — not relevant to API testing.
Fixes Since #007 (issues you filed)
- #008 —
source_name/source_id/source_promptnow reject non-string values with400instead of silently mangling them. - #009 — the
html_fragmentcontent-shape check is substring-based; documented as a known limitation rather than switched to real HTML parsing (deliberate — matches the client helper's own approach). - #010 — concurrent posts could race past quota; fixed with a write-lock-before-read + atomic transaction. Verified live but not covered by an automated test (SQLite shared-cache test DB behaves differently — see the issue). Worth re-probing.
- #011 — CDN snippets documented for
html_full;--themehelp typo fixed. - #012 — posting script gained
json/csvsupport.
Suggested Round-3 Probes
Prioritized by where the new surface area is riskiest.
Sharing (#91ea19d) — security boundary, probe hardest
- Can an unshared artifact ever be reached via
/s/<token>? Brute/ guessed/empty/malformed tokens should all404. - Does unsharing immediately kill the old link? (Confirmed manually, but re-verify — and try racing an unshare against an in-flight request.)
- Is
share_tokenever leaked in a response for an artifact you don't own, or in the list endpoint, or anywhere a non-owner could see it? - Can a shared artifact's embedded assets be reached unauthenticated — and, importantly, can an unshared artifact's assets be reached that way (they must not)? Also: does an orphaned/unattached asset stay private even when some unrelated artifact is shared?
- Does
?raw=1on/s/<token>correctly serve raw source for the kinds that support it, and not leak anything for kinds that don't? - Cross-user: user A shares an artifact; can user B toggle/unshare it, or only view it?
json / csv (#e5d2f19)
json: valid-but-not-an-object payloads (bare array, string, number,null); deeply nested / very large; unicode; the</script>injection vector (confirmed handled for json — verify csv escapes its embedded data block the same way, it's a separate code path).csv: ragged rows (fewer/more columns than the header), embedded commas/ quotes/newlines, duplicate column names, header-only, empty, a single giant cell, BOM/encoding oddities.- Quota accounting: json/csv now write a sidecar file — confirm size accounting and eviction include/delete the sidecar (this generalized the markdown-only logic; worth verifying it didn't regress markdown either).
.xlsx conversion (#4b5ec09)
- Multi-sheet workbook — verify only the active sheet survives and the others are silently dropped (documented behavior, confirm it's true).
- Formula cells never calculated by a real spreadsheet app (openpyxl doesn't evaluate) → should be blank, not error.
- A non-
.xlsxfile renamed to.xlsx; a real.xlsxsent with a wrong/ generic content type; a huge sheet; empty workbook;.xls(must not convert). - Field mangling regression: this path rebuilds the payload dict manually
because multipart
QueryDict+{**data}was silently list-wrapping values (the bug that made this a multi-fix). Re-probe that title/tags/ source_* all come through correctly on.xlsxposts specifically.
#010 quota race (no automated coverage)
- Fire N truly-concurrent posts at a tight quota; confirm final usage never exceeds quota and no artifact is left half-created (row without files or files without row).
As always: use the test / testpwd account, clean up what you create,
check artifacts/views.py before calling a surprise a bug (some, like
#009, are documented-by-design), and file anything real as a new numbered
issue (next is #014), linking back if it's a variant of a closed one.