Login
Check-in [211a7d966b]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:A write that meets a writer outside OCX waits for it outside OCX's own lock beside the repository, which each run of the write takes alone, so OCX's pages read on while it waits; and a run again after a wait that ended as the writer let go counts against a stated cap of eight, not the four tries

Intent: the adversarial review of 3c4c65c090 (scratchpad rv3c, rv3c-fix, rv3c-e) found: (1) confirmed, a write waiting for a writer outside OCX to let go held OCX's own lock beside the repository, since Place#run wrapped all of hosted, its waits included, in Fossil.turn, so every OCX page stalled while such a writer held the repository, against that lock's own rule, "never held while waiting on another lock": a /ext/ocx2-cgi/questions page took 9.13 s while one report write waited on a writer holding the repository 10 s, and 0.03 s otherwise; (2) plausible, the wait gives the lock back before the write runs again, so a writer starting in that moment, about 10 ms in the review's trial, used up one of the four runs, and a run was lost after 4.5 s of writes outside OCX, against the 45 s HISTORY.md decision 112 stated. The maintainer, 2026-10-18: "please don't go down any path with a possible race condition". Fossil 2.27 has no write from its command line that waits for the lock and keeps it, so (1) is fixed and (2) narrowed: only a wait that ended with the writer still holding counts toward the tries, a run again after one that went through counts against a cap of its own, and the claims that nothing depends on timing now say what remains; the full fix is a design question in docs/backlog.md.

Expression: src/ocx/fossil.cr: Place#run takes the lock beside the repository (Fossil.turn) around a confined command alone; Place#hosted takes it around each run of a command and waits (LET_GO) outside it, counting each run as it starts, a try, the first and each after a wait that did not go through, the writer still holding once BUSY had passed, or a run again, after a wait that went through as the writer let go, and fails (Locked) at the TRIES-th try, four as before, or the RERUNS-th run again, RERUNS new, eight; Locked's message says how many runs it made and how each wait ended; the comments of Locked, LET_GO, TRIES, RERUNS, turn, run and hosted say so, and what remains: a writer starting between a wait and the next run takes the repository first, another of OCX's waits among them, and the check's mend, holding the lock across its commands, waits within it. spec/support/stand_in_fossil.cr: holding_once takes gaps, after each of that many of OCX's waits another writer taking the repository before the write runs again; holding_past, a writer holding the repository until the block ends, each of OCX's waits the real one made with no time to wait, ending as one past BUSY does; holding_until, a writer holding it until the spec lets it go, telling the spec once OCX waits; a private holding serving the three, whose writer, let go, the stand-in waits for as OCX waits. Docs: HISTORY.md decision 113, amending decision 112 and naming the review; docs/backlog.md, two rows, a write path that begins with BEGIN IMMEDIATE, and what still waits behind such a writer, status under the node's lock and the check's mend; docs/fossil.md, "Forum posts", what a wait past its .timeout says, tried at once under .timeout 0 and after 2 s under .timeout 2000, and the two bounds; docs/protocol-v1-fossil.md, section 5, docs/protocol-v1-failures.md, case 35, and docs/interfaces.md, fossil sql's row, the two bounds and reads going on while a write waits; docs/design/modules.json and its generated docs/design/modules.md, src/ocx/fossil.cr's purpose, and docs/survey/functionality.json, the shape of Fossil's operations, each saying four runs at most no more.

Review: Gemma (gemma4:31b) read the change five times (scratchpad gemma-turn-1.txt to -5.txt, the whole diff but the generated docs/design/modules.md). Held: none. Misread, each a clarity finding, the code changed and asked again: first round, that a write a writer holds past each wait fails after three runs, reading the bound's check as made before the fourth run: the tries now count from the first run, the check reading tries == TRIES; second and third rounds, that the eighth run again is never made after the eighth wait, though its own trace counted nine runs and its corrected loop was the one written: each run now counts as it starts, a try or a run again, so at the check the counts are the runs made. Wrong: fourth round, after taking back two candidates itself, that the wait made outside OCX's lock may break that lock's rule: the lock keeps two of OCX's commands from meeting, and the wait writes nothing; it led hosted's comment, HISTORY.md and docs/backlog.md to say that another of OCX's waits, holding the write lock as it takes it and gives it back, counts as a writer between a wait and a run; fifth round, that Locked's message conflates the two bounds and that tries - 1 may be wrong: it names the runs in all and each kind of wait, as Gemma's own example shows, and tries is at least 1, the first run counting as one.

Demonstrates: spec/ocx/writers_spec.cr (a read through the fossil program, as OCX's pages read the served repository, answering within a second while a report waits for a writer outside OCX to let go, and the report stored and tagged once it does, which failed with the lock held across the wait; a watcher's run whose started meets a writer at each of RERUNS runs, each after a wait that ended as one let go, ending exited, each report stored once, which ended lost under four runs; case 35 as before), spec/ocx/fossil_spec.cr (a writer holding the repository past each wait failing the write after TRIES runs, as before, and one at each run, letting go after it, failing it after RERUNS + 1, each message naming the command, the repository and how each wait ended, storing nothing), spec/ocx/create_spec.cr (a run held past each wait of its write stores nothing, written again whole), spec/ocx/post_spec.cr, spec/ocx/remote_node_spec.cr, spec/ocx/verdict_spec.cr, spec/ocx/sync_spec.cr and spec/ocx/checkout_tools_spec.cr (a push held at each run names what the clone holds), spec/support/stand_in_fossil.cr (holding_once's gaps, holding_past, holding_until), src/ocx/fossil.cr, spec/guards/size_spec.cr (each file at most 400 lines), spec/guards/causation_spec.cr (no timer added), spec/guards/derivation_spec.cr (docs/design/modules.md as docs/design/modules.json generates it), spec/guards/interfaces_spec.cr and spec/guards/documents_spec.cr (the edited documents rendering with their links), spec/coverage/run.cr (every statement still covered). crystal run ci.cr green: 493 examples, 0 failures.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QVpmCsBwVF3d4zhMHHDAxs

Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | agent-tools
Files: files | file ages | folders
SHA3-256: 211a7d966b3edef87d42a018f35a659842d0feef0a441f4d2e1a38f4f7e85929
User & Date: opus-ocx2 2026-10-23 03:42:04.973
Context
2026-10-23
04:35
OCX's wait for those outside OCX holding what a write writes waits for readers as well as writers, BEGIN EXCLUSIVE in place of BEGIN IMMEDIATE, and, for a command in a checkout, on the checkout's own database as well as its repository

Intent: the adversarial review of 211a7d966b (scratchpad rv211, rv211-fix, rv211-e) found two things, each confirmed on Fossil 2.27: (1) a reader outside OCX, an open read transaction on the repository held on past 15 s, with no writer anywhere, lost a report write after 9 runs and 135 s: each run's COMMIT waited Fossil's 15 s for the reader and failed, "database is locked: {COMMIT}", but no reader holds back BEGIN IMMEDIATE, so each of OCX's waits went through at once and counted as one that ended as a writer let go, until the eight runs again were used up; (2) a writer outside OCX holding a checkout's own database, .fslckout, as a person's own fossil command there does, lost an add OCX made there in 0.19 s with no wait, since the wait named the repository alone, by -R, which no one held. With BEGIN EXCLUSIVE, in the review's trials, a reader holding 20 s let the write store after 19.69 s and one holding 150 s failed it after 105.19 s and four runs, the bound HISTORY.md decision 113 states, and an add in a checkout whose database a writer held 5 s waited 4.77 s and went through.

Expression: src/ocx/fossil.cr: LET_GO is ".timeout 15000" "BEGIN EXCLUSIVE; ROLLBACK;", which waits for readers and writers both and, past its .timeout, says what BEGIN IMMEDIATE said, so such a wait counts as a try; Place#run tells Place#hosted whether a command is in a checkout (in_checkout: neither `on` nor `repository` names its repository, so its repository file came from the checkout `dir` is in), and hosted makes such a command's wait with no -R, in the checkout, where fossil sql opens the checkout's own database with its repository and waits on both; Locked's message says writers or a reader outside OCX held the repository, and, for a command in a checkout, or the checkout's own database, which of the two neither Fossil nor the wait says; the comments of Locked, LOCKED, LET_GO, TRIES, RERUNS, turn, run and hosted say so, and that while the wait waits for a reader new reads wait behind it, up to BUSY, as they did behind a COMMIT waiting for that reader. spec/support/stand_in_fossil.cr: Holder, who holds a database outside OCX: Writer, an open BEGIN IMMEDIATE on the repository, as before; Reader, an open read transaction on it, a command meeting it failed by the stand-in at once, in Fossil's words, in place of its COMMIT's wait of 15 s; Checkout, an open write on a checkout's own database alone; holding_past and holding_until take `by`; OCX's wait known as its last argument is LET_GO's last, as one in a checkout has no -R; holding_past's wait the real one with .timeout 0 in place of LET_GO's .timeout, whatever names the database. spec/ocx/create_spec.cr, spec/ocx/post_spec.cr, spec/ocx/remote_node_spec.cr and spec/ocx/fossil_spec.cr follow Locked's new words. Docs: HISTORY.md decision 114, amending decision 113 and naming the review; docs/fossil.md, "Forum posts", what was tried: a reader fails a write at its COMMIT after 15 s, BEGIN IMMEDIATE goes through at once past it, BEGIN EXCLUSIVE waits for it, returning as it let go at 1 s and saying "Error: stepping, database is locked (5)" after 2 s under .timeout 2000, and a read starting while it waits answers once it goes through; and a checkout's own database is locked apart from its repository: add and commit there failed at once while a wait by -R went through, and fossil sql in the checkout with no -R waits on both; docs/interfaces.md, fossil sql's row, and docs/backlog.md, its first row, name the new wait. The protocol's definitions are unchanged: failure case 35 and section 5 speak of writers, which stays true.

Review: Gemma (gemma4:31b) read the change five times (scratchpad gemma-exclusive-1.txt to -5.txt, the whole diff). Held: first round, that Locked's message named a checkout's own database for a command with no repository file at all: it now does so only for a command in a checkout. Misread, each a clarity finding, the code changed and asked again: third round, that a directory holding a repository file but no checkout would read as a checkout: the -R arguments hosted was given, from which it inferred a checkout, became an explicit in_checkout, run's comment saying a command naming no repository has a repository file only from the checkout `dir` is in; fourth round, that LET_GO gaining a trailing argument would defeat the stand-in's match for OCX's wait: its comments now say it compares the last argument with LET_GO's last, which Place#hosted puts after whatever names the database. Wrong: first and fourth rounds, that matching the last argument is fragile: a wait the stand-in did not know would make the holding specs fail, not pass; second round, that "the repository or the checkout's own database" is imprecise: neither Fossil's error nor the wait says which of the two was held, and its proposed check was the same condition; fourth round, that the message conflates the two bounds: it names the runs in all and how each wait ended, unchanged here, as the review of 211a7d966b's own fifth round found; fifth round, that the message contradicts the specs: each spec's words match it, and each checks the part it names, the rest being what Fossil said.

Demonstrates: spec/ocx/writers_spec.cr (a reader holding the repository while a report write runs: the report stored once the reader lets go during OCX's wait; a write failed after TRIES runs, three waits ending with it still held, storing nothing, while the reader holds on past each wait, which with BEGIN IMMEDIATE failed after RERUNS + 1 runs, each wait going through at once), spec/ocx/fossil_spec.cr (a writer holding a checkout's own database while add and then commit run there: each waits and goes through, the file committed; an add failed after TRIES runs, storing nothing, while it holds on past each wait, which with the wait by -R failed after RERUNS + 1; and Locked's new words), spec/ocx/create_spec.cr, spec/ocx/post_spec.cr and spec/ocx/remote_node_spec.cr (Locked's new words, a push in a checkout naming the checkout's own database), spec/support/stand_in_fossil.cr (Holder; holding_past and holding_until by a holder; OCX's wait known by its last argument), src/ocx/fossil.cr, spec/guards/size_spec.cr (each file at most 400 lines), spec/guards/causation_spec.cr (no timer added), spec/guards/interfaces_spec.cr and spec/guards/documents_spec.cr (the edited documents rendering with their links), spec/coverage/run.cr (every statement still covered). crystal run ci.cr green: 495 examples, 0 failures.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QVpmCsBwVF3d4zhMHHDAxs check-in: 39c646f7ad user: opus-ocx2 tags: agent-tools

03:42
A write that meets a writer outside OCX waits for it outside OCX's own lock beside the repository, which each run of the write takes alone, so OCX's pages read on while it waits; and a run again after a wait that ended as the writer let go counts against a stated cap of eight, not the four tries

Intent: the adversarial review of 3c4c65c090 (scratchpad rv3c, rv3c-fix, rv3c-e) found: (1) confirmed, a write waiting for a writer outside OCX to let go held OCX's own lock beside the repository, since Place#run wrapped all of hosted, its waits included, in Fossil.turn, so every OCX page stalled while such a writer held the repository, against that lock's own rule, "never held while waiting on another lock": a /ext/ocx2-cgi/questions page took 9.13 s while one report write waited on a writer holding the repository 10 s, and 0.03 s otherwise; (2) plausible, the wait gives the lock back before the write runs again, so a writer starting in that moment, about 10 ms in the review's trial, used up one of the four runs, and a run was lost after 4.5 s of writes outside OCX, against the 45 s HISTORY.md decision 112 stated. The maintainer, 2026-10-18: "please don't go down any path with a possible race condition". Fossil 2.27 has no write from its command line that waits for the lock and keeps it, so (1) is fixed and (2) narrowed: only a wait that ended with the writer still holding counts toward the tries, a run again after one that went through counts against a cap of its own, and the claims that nothing depends on timing now say what remains; the full fix is a design question in docs/backlog.md.

Expression: src/ocx/fossil.cr: Place#run takes the lock beside the repository (Fossil.turn) around a confined command alone; Place#hosted takes it around each run of a command and waits (LET_GO) outside it, counting each run as it starts, a try, the first and each after a wait that did not go through, the writer still holding once BUSY had passed, or a run again, after a wait that went through as the writer let go, and fails (Locked) at the TRIES-th try, four as before, or the RERUNS-th run again, RERUNS new, eight; Locked's message says how many runs it made and how each wait ended; the comments of Locked, LET_GO, TRIES, RERUNS, turn, run and hosted say so, and what remains: a writer starting between a wait and the next run takes the repository first, another of OCX's waits among them, and the check's mend, holding the lock across its commands, waits within it. spec/support/stand_in_fossil.cr: holding_once takes gaps, after each of that many of OCX's waits another writer taking the repository before the write runs again; holding_past, a writer holding the repository until the block ends, each of OCX's waits the real one made with no time to wait, ending as one past BUSY does; holding_until, a writer holding it until the spec lets it go, telling the spec once OCX waits; a private holding serving the three, whose writer, let go, the stand-in waits for as OCX waits. Docs: HISTORY.md decision 113, amending decision 112 and naming the review; docs/backlog.md, two rows, a write path that begins with BEGIN IMMEDIATE, and what still waits behind such a writer, status under the node's lock and the check's mend; docs/fossil.md, "Forum posts", what a wait past its .timeout says, tried at once under .timeout 0 and after 2 s under .timeout 2000, and the two bounds; docs/protocol-v1-fossil.md, section 5, docs/protocol-v1-failures.md, case 35, and docs/interfaces.md, fossil sql's row, the two bounds and reads going on while a write waits; docs/design/modules.json and its generated docs/design/modules.md, src/ocx/fossil.cr's purpose, and docs/survey/functionality.json, the shape of Fossil's operations, each saying four runs at most no more.

Review: Gemma (gemma4:31b) read the change five times (scratchpad gemma-turn-1.txt to -5.txt, the whole diff but the generated docs/design/modules.md). Held: none. Misread, each a clarity finding, the code changed and asked again: first round, that a write a writer holds past each wait fails after three runs, reading the bound's check as made before the fourth run: the tries now count from the first run, the check reading tries == TRIES; second and third rounds, that the eighth run again is never made after the eighth wait, though its own trace counted nine runs and its corrected loop was the one written: each run now counts as it starts, a try or a run again, so at the check the counts are the runs made. Wrong: fourth round, after taking back two candidates itself, that the wait made outside OCX's lock may break that lock's rule: the lock keeps two of OCX's commands from meeting, and the wait writes nothing; it led hosted's comment, HISTORY.md and docs/backlog.md to say that another of OCX's waits, holding the write lock as it takes it and gives it back, counts as a writer between a wait and a run; fifth round, that Locked's message conflates the two bounds and that tries - 1 may be wrong: it names the runs in all and each kind of wait, as Gemma's own example shows, and tries is at least 1, the first run counting as one.

Demonstrates: spec/ocx/writers_spec.cr (a read through the fossil program, as OCX's pages read the served repository, answering within a second while a report waits for a writer outside OCX to let go, and the report stored and tagged once it does, which failed with the lock held across the wait; a watcher's run whose started meets a writer at each of RERUNS runs, each after a wait that ended as one let go, ending exited, each report stored once, which ended lost under four runs; case 35 as before), spec/ocx/fossil_spec.cr (a writer holding the repository past each wait failing the write after TRIES runs, as before, and one at each run, letting go after it, failing it after RERUNS + 1, each message naming the command, the repository and how each wait ended, storing nothing), spec/ocx/create_spec.cr (a run held past each wait of its write stores nothing, written again whole), spec/ocx/post_spec.cr, spec/ocx/remote_node_spec.cr, spec/ocx/verdict_spec.cr, spec/ocx/sync_spec.cr and spec/ocx/checkout_tools_spec.cr (a push held at each run names what the clone holds), spec/support/stand_in_fossil.cr (holding_once's gaps, holding_past, holding_until), src/ocx/fossil.cr, spec/guards/size_spec.cr (each file at most 400 lines), spec/guards/causation_spec.cr (no timer added), spec/guards/derivation_spec.cr (docs/design/modules.md as docs/design/modules.json generates it), spec/guards/interfaces_spec.cr and spec/guards/documents_spec.cr (the edited documents rendering with their links), spec/coverage/run.cr (every statement still covered). crystal run ci.cr green: 493 examples, 0 failures.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QVpmCsBwVF3d4zhMHHDAxs check-in: 211a7d966b user: opus-ocx2 tags: agent-tools

02:31
Every write OCX makes on a repository is one Fossil command that stores all it writes or nothing, run again once a writer outside OCX holding the repository lets go, so no report is ever stored without its index and its ocx-message tag

Intent: the live test on the server, 2026-10-23 at 00:32 UTC, release 3869da228e7d: a Codex task, run eabbfe740e in thread 682044729e, exited 0, and its watcher's kept-log post was stored by fossil test-content-put, but its index, fossil test-crosslink, a second command, met "database is locked" from a writer outside OCX, and the watcher ended the run lost before sharing its patch. d9dd05e7dd kept such a report as written and went on; its adversarial review found that made things worse: (1) a stop after an ended left unindexed got a second ended, since rounds find runs and endeds by their tags and the next post indexed the leftover but tagged nothing, and a stop written outside OCX got lost written again; (2) the hook listed an ended while it was unindexed and no round read it, and Fossil's backoffice runs after any page that answers 200, so starting none did not help; (3) a write that stored nothing, a put, a uv add, the verdict's tag or a started, still ended the run lost or left it unanswered, and the user's waiting runs were not handed on; (4) a round whose own tag, reply or answer met the writer raised Fossil::Locked, so the hook handed no run; (5) a control artifact of tags tag_messages left unindexed was never indexed. The maintainer, 2026-10-22: "Let me know when one click on `accept` is going to give me the functionality I'm seeking", and "the contract on this box is as long as the development doesn't disrupt the server, let the agents go a bit nuts"; 2026-10-18: "please don't go down any path with a possible race condition". So every write either goes through whole or stores nothing, one that meets another writer runs again until it goes through, within a stated bound, four runs, after which it fails as before, and nothing depends on timing: what a run waits for is the writer's lock, never a time. Tried on this host with Fossil 2.27 first (docs/fossil.md, "Forum posts"): fossil bundle import B --publish --force --user U stores a post and the control artifact tagging it, or a ticket change and its tag, indexes and tags them, with the receipt's user and no address, needing no checkout, and run again imports nothing more and succeeds; under an open BEGIN IMMEDIATE it, tag add and uv add each fail within 10 ms, storing nothing; fossil bundle append names by SHA1 whatever the hash policy, so OCX writes the bundle itself, naming each artifact as fossil hash-policy says; fossil test-xfer, the server's sync handler, whose transaction begins BEGIN IMMEDIATE and so would wait itself, crashed with a segmentation fault, a writer holding or not; and fossil sql -R REPOSITORY ".timeout 15000" "BEGIN IMMEDIATE; ROLLBACK;" waits, by SQLite's own busy handling, until such a writer lets go, returning as it let go at 3 s and at 12 s, writing nothing, while uv add on a repository with no unversioned table yet, and push on a clone so held, each waited Fossil's 15 s on their first lock and then failed.

Expression: src/ocx/fossil/stored.cr, new: Fossil.bundle writes a bundle file as Fossil's bundle append makes one, its bblob rows each named, sized and compressed as Fossil compresses an artifact; Place#stored stores a post or a ticket change and, when it holds an OCX message, the control artifact tagging it, answering its name; Place#store stores artifacts by one fossil bundle import, made public, received as the user given; Place#digest_named reads fossil hash-policy, SHA1 under sha1 or auto, SHA3-256 otherwise. src/ocx/fossil.cr: Place#hosted runs a command that met a writer outside OCX, which stored nothing, again once LET_GO, Fossil's sql shell taking and giving back the write lock with .timeout BUSY, has waited for that writer to let go, however that wait ended, TRIES, four, runs in all, then raises Locked as before, a command on no repository file once; Place#launched holds the file's one Process.run; Unfinished, and PRIVATE, which only the removed checkout used, go; the comments of Locked, LOCKED, turn and run say so. src/ocx/fossil/forum.cr: reply and new_thread store through stored; put_post, indexed, indexing, tagged, same_post?, POST_LEFT and stored_posts go; index_stored_posts, as before d9dd05e7dd, stays for the node's check alone, to mend what an older release left. src/ocx/fossil/tickets.cr: comment_on_ticket composes the change fossil ticket change writes and stores it with its tag, its text in a file, so no 128 KiB argument limit; held_as goes. src/ocx/fossil/message_tags.cr: tag_messages stores a control artifact of several tags the same way, one still by fossil tag add. src/ocx/fossil/sync.cr: Fossil.checked_out, its close and Place#close, and open's empty flag go, as no write needs a checkout now. src/ocx/node.cr: reply and report as before d9dd05e7dd, Fossil's backoffice after every ended again; mend's comment names an older release's leftover. src/ocx/hook.cr: the comment on the hook's first write says it runs again once Fossil's write transaction ends. spec/support/stand_in_fossil.cr: holding_once, a writer outside OCX, an open BEGIN IMMEDIATE, holding the repository across the first run of each write whose command is listed and letting go only once OCX waits for it, so a run again that did not wait would meet it still; failing's onward. Docs: docs/fossil.md, "Forum posts", what was tried; docs/protocol-v1-fossil.md, section 2, the tag stored by the command that stores its message, and section 5, the writes and their failures; docs/protocol-v1-failures.md, case 35 rewritten; docs/interfaces.md, the ocx-message tag's, ticket changes', the push's, the post's, fossil sql's, the node's and the fossil CLI's rows; docs/design/modules.json and its generated docs/design/modules.md, the purposes of src/ocx/fossil.cr, src/ocx/fossil/tickets.cr, src/ocx/fossil/forum.cr, src/ocx/fossil/message_tags.cr, src/ocx/fossil/sync.cr and src/ocx/node.cr, and src/ocx/fossil/stored.cr's; docs/survey/functionality.json, the shapes and couplings of Fossil's operations, a node's runs, a plain post, create, stop and tag_messages, src/ocx/fossil/stored.cr among Fossil's parts and spec/ocx/writers_spec.cr among a node's specs; docs/backlog.md, d9dd05e7dd's row and the row "A kept log over about 128K on a ticket run is not posted" removed, as each is resolved, and the row on the mend's reads narrowed to the check; HISTORY.md decision 112, naming the live test and both reviews, amending decision 110 where it no longer holds.

Review: Gemma (gemma4:31b) read the change four times (scratchpad gemma-atomic-1.txt to -4.txt; the first the whole diff but the generated docs/design/modules.md, docs/design/modules.json and docs/survey/functionality.json, the others its source and specs). Held: none. Misread, each a clarity finding, the code changed and asked again: second round, that fossil sql's BEGIN IMMEDIATE fails at once while the writer holds the repository, so no wait happens: it waits, as tried, and the writer of spec/ocx/writers_spec.cr lets go only once OCX waits, so LET_GO's comment now says BEGIN IMMEDIATE asks for the lock before reading anything, which SQLite waits for, and not repeated after; third round, that index_stored_posts's test-crosslink is not run through hosted: every command is, so run's comment now says it, and not repeated after. Wrong: first and fourth rounds, that the bundle file may be read before it is flushed to disk: Fossil.bundle's DB.open block has closed the connection, each insert committed, before run starts fossil, and another process reads what a write(2) returned through the one page cache, no flush needed; second round, that a hash policy read otherwise makes the import fail: Fossil checks each name by the digest its length says, so either name imports, and the five policy names are Fossil's own, which digest_named's comment now says; third round, that bundle import may store part of a bundle: it imports in one transaction (its bundle.c), tried under the writer storing nothing, and skips an artifact already present; and that hash-policy should be cached: the policy changes, auto promoting itself to sha3, a cache OCX invents is against the project's rule, and the read is one process per write.

Demonstrates: spec/ocx/writers_spec.cr (case 35, the review's five cases, a writer outside OCX, an open BEGIN IMMEDIATE, holding the served repository across the first run of each write and letting go once OCX waits: a build's started, kept logs, share and its reply, verdict and ended each meet it once, and the run ends exited 0 once, its file shared and its check-in judged, each report indexed and tagged as it is stored, its user's next run handed on, a round given its ended answering nothing, a stop then answered nothing and the check writing no other; a round whose tag of an untagged run and whose refusal's ended each meet it hands its run and refuses the other; tag_messages's control artifact of two tags meeting it is stored and indexed, one entry; the node's check indexes a report an older release left stored and not indexed before it decides, answering nothing), spec/ocx/fossil_spec.cr (a post with its index and tag stored by one command, the writer waiting next finding it whole; a write failing once goes through on its next run; one a writer holds the repository against at each run fails after four, naming the command and the repository, storing nothing; a ticket change of 200,000 bytes), spec/ocx/create_spec.cr (a run held at each run of its write stores nothing, written again whole, tagged and acted on), spec/ocx/post_spec.cr (a post in a clone held at its first run written whole and pushed once; a push held at each run names what the clone holds), spec/ocx/remote_node_spec.cr (a node on a clone whose reports' pushes are held at each run logs why and its check sends each, writing no second), spec/ocx/hook_spec.cr (case 33 from a write failing as on a full disk), spec/ocx/watcher_spec.cr (case 30's started failing as on a full disk launches nothing), spec/ocx/sync_spec.cr, spec/ocx/verdict_spec.cr and spec/ocx/checkout_tools_spec.cr (a push held at each run names what the clone holds), spec/support/stand_in_fossil.cr (holding_once, failing's onward), src/ocx/fossil.cr, src/ocx/fossil/stored.cr, src/ocx/fossil/forum.cr, src/ocx/fossil/tickets.cr, src/ocx/fossil/message_tags.cr, src/ocx/fossil/sync.cr, src/ocx/node.cr and src/ocx/hook.cr, spec/guards/external_programs_spec.cr (one Process.run in src/ocx/fossil.cr, Fossil's SQL in its module), spec/guards/causation_spec.cr (no timer added), spec/guards/size_spec.cr (each file at most 400 lines), spec/guards/derivation_spec.cr (docs/design/modules.md as docs/design/modules.json generates it), spec/guards/survey_spec.cr (src/ocx/fossil/stored.cr and spec/ocx/writers_spec.cr owned), spec/guards/interfaces_spec.cr and spec/guards/documents_spec.cr (the edited documents rendering with their links), spec/coverage/run.cr (every statement still covered, src/ocx/fossil/forum.cr's mend by spec/ocx/writers_spec.cr). crystal run ci.cr green: 491 examples, 0 failures.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QVpmCsBwVF3d4zhMHHDAxs check-in: 3c4c65c090 user: opus-ocx2 tags: agent-tools

Changes
Unified Diff Side-by-Side Diff Patch
Changes to HISTORY.md.
Changes to docs/backlog.md.
Changes to docs/design/modules.json.
Changes to docs/design/modules.md.
Changes to docs/fossil.md.
Changes to docs/interfaces.md.
Changes to docs/protocol-v1-failures.md.
Changes to docs/protocol-v1-fossil.md.
Changes to docs/survey/functionality.json.
Changes to spec/ocx/create_spec.cr.
Changes to spec/ocx/fossil_spec.cr.
Changes to spec/ocx/writers_spec.cr.
Changes to spec/support/stand_in_fossil.cr.
Changes to src/ocx/fossil.cr.