* fix(logs): Clear all logs deletes and empties only what its confirmation showed (#389)
- /logs/files rows carry an identity string (size:mtime_ns:ino); the
workspace sends back the active and rotated rows its dialog was built
from. Under the files and handler locks every listed copy is re-checked
with _matches_review and the listed active log's inode; any difference
refuses with nothing changed (409 logs-changed). A copy that appeared
after the confirmation is kept.
- A second writer of the active log (our flushed stream is behind the
file's size, or our file is now a rotated copy) refuses first (409
logs-foreign-writer); each unlink is preceded by a fresh identity check
and the active log is emptied last.
- An active log with a hard link (st_nlink > 1) is never truncated (409
logs-hard-link), also on the file-logging-off path.
- The legacy admin page's POST without a body keeps clearing what is
there, with the foreign-writer and hard-link refusals.
- The browser fixture grows the active log through the handler's stream.
* fix(logs): accept pre-1970 identities, refuse duplicate rows, say the foreign-writer check is best effort (#389)
Review follow-ups: a negative mtime_ns no longer makes every workspace
clear 400; a name listed twice is a malformed list; the confirmed-row cap
is 10000; the hard-link refusal says how to recover; the hard-link and
foreign-append tests assert the kept bytes before the refusal code, so on
the old code they fail on lost data.
* fix(logs): declare the compressed length so a log download finishes
The gzip middleware compressed a text body but kept the handler's declared
Content-Length (the uncompressed size), so a browser waited for bytes that
never came: downloading any log over 1 KB hung, in the workspace and on the
admin page. The middleware now drops a declared length before compressing.
Part of #329
* feat(system): show Diagnostics & logs natively and retire the hand-off panel
System › Diagnostics & logs is native (D109, D110): the concept's
Diagnostics surface with the live database, source, Viewer.js and renderer
lines, Run checks (the shared Health report), the diagnostic report, Inspect
and the confirmed test link; and the Logs surface with the minimum-level
viewer, Lines 1-500, statistics, the log download, the runtime level and
console setting saved by Save preferences, the log files with their
downloads, Review log cleanup (the rotated_logs maintenance plan, no backup
box, Listed files) and a confirmed Clear all logs.
D94's hand-off panel, SECTION_HANDOFFS and the undelivered runtime adapter
are gone. The browser server logs into its own temporary root.
Part of #329
* fix(system): confirm Clear all logs on a fresh file list and record coverage
Review fixes for the Diagnostics & logs section:
- Clear all logs reads the log files again before it confirms, so the
dialog names the copies it deletes now (a list it cannot read gives the
general sentence, never an old count); Refresh reads the files too.
- Runtime values that cannot be read stay disabled and say so.
- Create test link holds its button until the write answered, so a second
press cannot write a second record.
- The Lines field names its range.
- The browser server builds its logger in its own root, so no log file is
ever opened in another folder; the fixture closes every directory scan
and replaces a link instead of writing through it.
- system.mjs drops the unused section fallback; frontend coverage floors
recorded with coverage:update (system-diagnostics.mjs 97.5% lines).
Part of #329
* fix(system): read the database size the report sends
The Database line read database_info.size_bytes, a key the report does
not have (get_database_info answers database_size_bytes), so it always
read "Readable · 0 bytes · N images". The browser test now requires a
non-zero size. Found by PR 3's concept comparison.
Part of #329