Repository navigation
ldh-CreateContainer and ldh-CreateItem only create: If-None-Match: *, and if_absent to accept an existing document - #68
Merged
Conversation
… and if_absent to accept an existing document They PUT through the client's conditional write, which reads the document's entity tag and quotes it in If-Match, so a create on an existing URI replaced the document whole, content blocks and all. They now send If-None-Match: * and no If-Match, as the LinkedDataHub CLI's create commands and its client's create forms do; the server refuses that 412 where a document exists and leaves it as it is. That fails the operation, unless if_absent is true, which takes the existing document as the result, like mkdir -p, and does not report it as a write to an enclosing ForEach's iteration gate. Their kind is write. The system prompt said a create replaces; it says it only creates. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ldh-CreateContainerandldh-CreateItemwrote through the client's conditional write. That HEADs the target for its entity tag and quotes it inIf-Match, so on a URI that already held a document, a create replaced it whole, content blocks included. The system prompt even said so ("A document that already exists at that URL is replaced"). Pipelines that "make sure" a container exists on every run were wiping whatever had been added to it since. The case that surfaced this: a nightly importer replaced/messages/and the view installed on it.This brings the operations in line with LinkedDataHub's client (its Container/Item modals) and with the CLI change in AtomGraph/LinkedDataHub#505:
client.create()PUTs withIf-None-Match: *, no HEAD and noIf-Match. On an existing document the server answers 412 under the document's write lock and leaves it as it was. The operation raisesWriteRefusedError(412), whose reason says a document already exists.if_absent(xsd:boolean) is the counterpart of--if-absent, and works likemkdir -p. An existing document is the result: the singlestatus/urlrow, status 412, writing nothing. That URL is not reported to an enclosingForEach's iteration gate (§3.6), since nothing was written. So a loop can make sure of the same container on every iteration.write, no longerdestructive: a create can't remove anything now.PUTis unchanged: it still replaces, quoting the tag.Behaviour change for callers:
PUTit instead.ldh-GenerateClassContainerscreates throughldh-CreateItem, so on a re-run it now stops at the first class whose item already exists, instead of replacing it.if_absentisn't right there either: it would keep the item and append a second set of blocks.Tests
tests/unit/test_ldh_create_if_absent.py, offline againsthttp_stub. The stub tags every resource, so a create that quoted the tag would show. It covers both operations:If-None-Match: *, no HEAD, noIf-Match;if_absentreturns the existing URL after one request;if_absentstill creates when nothing is there;if_absentdoesn't swallow other refusals (403);if_absentmust be a boolean;PUTstill sendsIf-Match;ForEachcan make sure of the same container on every iteration;client.createreading and quoting the tag again, 7 of the new tests fail;if_absentpath reporting a write, theForEachtest fails.WRITE), andtest_write_contract'sIf-Matchtable, which no longer listsldh-CreateItem.pytest: 1109 passed, 7 skipped.test_ldh_cli_parity(it needs a LinkedDataHub). Once #505 is in, anif_absent↔--if-absentcase belongs there.🤖 Generated with Claude Code