Add round-2 handover doc for the LLM test project
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>
This commit is contained in:
parent
9a3b381f39
commit
292c386209
1 changed files with 121 additions and 0 deletions
121
issues/013-handover-to-llm-test-round-2.md
Normal file
121
issues/013-handover-to-llm-test-round-2.md
Normal file
|
|
@ -0,0 +1,121 @@
|
||||||
|
# 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:
|
||||||
|
|
||||||
|
1. **`json` and `csv` artifact kinds** (commit `e5d2f19`). Text kinds like
|
||||||
|
markdown. `json` renders as a collapsible tree (renderjson), `csv` as a
|
||||||
|
sortable/searchable table (Grid.js). Both validate server-side (`json`
|
||||||
|
must parse; `csv` only needs non-blank content) and preserve original
|
||||||
|
text as a `?raw=1` sidecar. Both vendored libs are served from
|
||||||
|
`/static/vendor/…`.
|
||||||
|
|
||||||
|
2. **`.xlsx` upload → `csv`** (commit `4b5ec09`). Uploading an `.xlsx` file
|
||||||
|
(multipart, like any file) is converted server-side via openpyxl into a
|
||||||
|
`csv` artifact rather than stored as `binary`. Active sheet only; cached
|
||||||
|
formula results only; `.xls` unsupported; corrupt file → `400`.
|
||||||
|
|
||||||
|
3. **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_url` now
|
||||||
|
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.
|
||||||
|
|
||||||
|
4. **Syntax-highlighted code + styled tables** (commits `af9ecf2`,
|
||||||
|
`696cfe7`). Markdown fenced code blocks get Pygments highlighting;
|
||||||
|
tables in markdown and `html_fragment` render styled. Cosmetic, low-risk.
|
||||||
|
|
||||||
|
5. **Posting script supports `json`/`csv`/`.xlsx`** (commit `e137725`).
|
||||||
|
`daybook_post.py --kind json/csv`, positional auto-detect of
|
||||||
|
`.json`/`.csv`/`.xlsx`.
|
||||||
|
|
||||||
|
6. **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_prompt` now reject
|
||||||
|
non-string values with `400` instead of silently mangling them.
|
||||||
|
- **#009** — the `html_fragment` content-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`; `--theme` help typo
|
||||||
|
fixed.
|
||||||
|
- **#012** — posting script gained `json`/`csv` support.
|
||||||
|
|
||||||
|
## 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 all `404`.
|
||||||
|
- Does **unsharing immediately** kill the old link? (Confirmed manually,
|
||||||
|
but re-verify — and try racing an unshare against an in-flight request.)
|
||||||
|
- Is `share_token` ever 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 *un*shared 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=1` on `/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-`.xlsx` file renamed to `.xlsx`; a real `.xlsx` sent 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 `.xlsx` posts 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.
|
||||||
Loading…
Add table
Add a link
Reference in a new issue