Epic: CannObserv/archiver#137 · Step 2 — info_source_id on the wire
Contract: CannObserv/cannobserv (co-core info_source_id on the content contracts)
Context
#137 reverses cannobserv#266's exclusion of info_source_id from the content contracts. The rationale was that content contracts should stay domain-agnostic; co-core is in fact the Cannabis Observer domain library (legislation.py, person.py, jurisdiction.py, information.py, source.py, replication.py all live beside changes.py), so the purity rule was applied in the one place it costs us.
Replicator's part is mechanical: echo the field, interpret nothing.
Scope
- Bump co-core to the release carrying
info_source_id.
- Copy
command.info_source_id verbatim onto BlobAvailableEvent and FetchFailedEvent at emit time. No validation, no parsing, no use in dedupe, no use in the envelope key, no participation in any routing or policy decision. Replicator holds no domain state and this does not change that.
None in → None out (a seed-harness emit with no info_source_id stays legal, same as command_id).
Contract doc updates
docs/contracts/content-fetch-issuer-contract.md needs revision in three places:
- MUST-2 — soften from a correctness requirement to bookkeeping. The bus now does carry something that reconstructs the mapping, so the crash-between-mint-and-record window no longer loses the fact permanently. The issuer still wants a durable record for request options, audit, and the MUST-6 reaper; it is no longer the only thing standing between a fetch and an orphaned blob.
- MUST-3 — leave the rule intact, add a sentence that the correct key is now on the fact directly, so there is no longer any reason to reach for
url. The one-to-many argument (quoting Archiver's non-unique url) still stands and is still the reason url is not a key.
- The success/failure fact tables — add the field.
Also update docs/contracts/content-fetch-issuer-reference.md if it enumerates payload fields.
Note on #118
CannObserv/archiver#118 asked Replicator whether Archiver or Watcher would own a content.blobs consumer group. The answer settled in #137 is neither is new — Archiver does not consume content.blobs; Watcher stays the correlator it already is. The blob TTL confirmation (7 days is ample) is answered on #118 directly.
Done when
- Both facts carry
info_source_id, echoed verbatim
- Round-trip test: command with the field → fact carries it; command without → fact has
None
- Issuer contract + reference docs updated
Epic: CannObserv/archiver#137 · Step 2 —
info_source_idon the wireContract: CannObserv/cannobserv (co-core
info_source_idon the content contracts)Context
#137 reverses cannobserv#266's exclusion of
info_source_idfrom the content contracts. The rationale was that content contracts should stay domain-agnostic; co-core is in fact the Cannabis Observer domain library (legislation.py,person.py,jurisdiction.py,information.py,source.py,replication.pyall live besidechanges.py), so the purity rule was applied in the one place it costs us.Replicator's part is mechanical: echo the field, interpret nothing.
Scope
info_source_id.command.info_source_idverbatim ontoBlobAvailableEventandFetchFailedEventat emit time. No validation, no parsing, no use in dedupe, no use in the envelope key, no participation in any routing or policy decision. Replicator holds no domain state and this does not change that.Nonein →Noneout (a seed-harness emit with noinfo_source_idstays legal, same ascommand_id).Contract doc updates
docs/contracts/content-fetch-issuer-contract.mdneeds revision in three places:url. The one-to-many argument (quoting Archiver's non-uniqueurl) still stands and is still the reasonurlis not a key.Also update
docs/contracts/content-fetch-issuer-reference.mdif it enumerates payload fields.Note on #118
CannObserv/archiver#118 asked Replicator whether Archiver or Watcher would own a
content.blobsconsumer group. The answer settled in #137 is neither is new — Archiver does not consumecontent.blobs; Watcher stays the correlator it already is. The blob TTL confirmation (7 days is ample) is answered on #118 directly.Done when
info_source_id, echoed verbatimNone