Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/omnimarket/events/occ_companion.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,20 @@ class ModelOccContractState(BaseModel):
default="",
description="The current committed contract YAML (empty if absent).",
)
merged_receipt_paths: tuple[str, ...] = Field(
default=(),
description="Repo-relative receipt paths under "
"``drift/dod_receipts/<ticket>/`` that ALREADY EXIST on the OCC "
"governance ref — i.e. bytes the Append-Only Gate treats as immutable "
"(OMN-16071). Without this the pure producer knows only which "
"dod_evidence ids exist (``existing_entry_ids``, a set of "
"DIRECTORIES) and has no way to tell a first correction from a re-mint "
"of an already-merged one, which is exactly how the supersede-shaped "
"filename became an unconditional exemption in "
"``assert_append_only_emissions``. Defaults to ``()``, which reproduces "
"the prior semantics byte-for-byte, so a read-EFFECT that cannot list "
"the tree degrades to the shipped behavior rather than to a refusal.",
)


class ModelOccCompanionRequest(BaseModel):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,55 @@ def _supersede_file(
return content


def _next_supersede_path(
*,
ticket: str,
prior_entry: str,
check_type: str,
pr_number: int,
occ_pr_number: int | None,
merged_receipt_paths: Sequence[str],
) -> str | None:
"""The supersede path this pass may ADD, or ``None`` when none is derivable.

OMN-16071. The natural name is ``<check_type>.supersede.<pr_number>.yaml``,
keyed to the PRODUCT PR — deliberately, because that is the consumer the
rebind targets. It is also constant across every authoring pass for that
same product PR, so the 2nd pass renders a path the 1st pass already merged.
Live: OCC#6616 re-rendered eight ``.supersede.925.yaml`` files an earlier
pass for PR#925 had merged, bumping ``created_at`` in place.

When the natural name is free this returns it unchanged, so no shape in the
merged corpus moves. When it is taken, a fresh generation is keyed to the
OCC companion PR authoring the rebind. That suffix stays a SINGLE integer
on purpose: both ``_SUPERSEDE_FILENAME_RE`` here and
``validator_receipt_supersession``'s ``_SUPERSEDE_SUFFIX_RE`` parse
``.supersede.<NNNN>.yaml`` strictly, so a compound suffix such as
``.supersede.925.6616.yaml`` would be filed where nothing resolves it. The
record's ``replacement.pr_number`` still names the PRODUCT PR, which is what
``resolve_supersession``'s tier-1 selection actually keys on — the filename
generation is provenance, never the binding.

``None`` means the natural path is taken and no OCC PR number is known yet
(pass 1). The caller omits the emission rather than opening merged bytes for
write; the merged record already binds this same product PR.
"""
directory = f"{_RECEIPT_DIR_PREFIX}/{ticket}/{prior_entry}"
merged = frozenset(merged_receipt_paths)
natural = f"{directory}/{check_type}.supersede.{pr_number}.yaml"
if natural not in merged:
return natural
if occ_pr_number is None:
return None
regenerated = f"{directory}/{check_type}.supersede.{occ_pr_number}.yaml"
if regenerated in merged:
# Both generations already merged: this key has nothing left to say
# that is not already on the ref, and inventing a third integer that
# names no real artifact would be provenance theatre.
return None
return regenerated


class AppendOnlyEmissionError(ValueError):
"""The producer would rewrite an already-merged OCC artifact (OMN-15485).

Expand Down Expand Up @@ -521,6 +570,25 @@ def assert_append_only_emissions(
receipt directory IS that ``M`` unless it is a supersede add. Enforced per
merged entry directory, not just the exact ``command.yaml``, so a future
emitter using a different ``check_type`` filename cannot slip through.
* **Already-merged paths (OMN-16071).** The supersede exemption above used
to be unconditional, which asked *"is this filename shaped like a
correction?"* rather than *"is this path already merged?"* — and filename
shape is not evidence of novelty. The merged path files every rebind at
``<check_type>.supersede.<pr_number>.yaml``, keyed to the PRODUCT PR
number, which is CONSTANT across every authoring pass for that same
product PR; so the 2nd, 3rd ... pass renders the identical paths and this
mechanism waved every one of them through while they were already merged
bytes on ``dev``. Live: OCC#6616 (companion for ``omninode_infra#925``)
re-rendered eight ``.supersede.925.yaml`` files minted by an earlier pass
for that same PR, bumping their ``created_at`` in place. An emission at
any path in ``state.merged_receipt_paths`` is now refused regardless of
its filename — the same judgment the gate makes off git status.

``merged_receipt_paths`` defaults to ``()``, in which case this reduces
exactly to the pre-OMN-16071 semantics: a read-EFFECT that cannot list the
receipt tree degrades to the shipped behavior rather than to a refusal, and
the write-EFFECT's own pre-push ``_assert_append_only`` remains fail-closed
on git status behind it.
* **Contracts.** The gate flags a merged ``dod_evidence`` entry that is
removed or edited (per-entry hash change) and allows appends. The merged
path is append-only BY CONSTRUCTION today (``merged_text +
Expand All @@ -541,6 +609,24 @@ def assert_append_only_emissions(
# path is an add relative to the merge base, which the gate allows.
continue

# OMN-16071: file-level truth, checked BEFORE the directory rule so a
# supersede-shaped filename can never buy an exemption for bytes that
# are already on the governance ref.
merged_paths = frozenset(state.merged_receipt_paths)
for companion in files:
if companion.path not in merged_paths:
continue
raise AppendOnlyEmissionError(
f"refusing to author {companion.path!r}: that path is ALREADY "
f"MERGED on the OCC governance ref for {state.ticket_id}, so "
"writing it is an in-place rewrite the required OCC "
"Append-Only Gate rejects as 'receipt_file_mutated' "
"(OMN-16071). A '.supersede.<NNNN>.yaml' filename does not "
"make an emission an add — only a path nothing has merged "
"does. Express this correction as a NEW supersession "
"generation keyed to the OCC companion PR authoring it."
)

frozen_dirs = {
f"{_RECEIPT_DIR_PREFIX}/{state.ticket_id}/{entry}": entry
for entry in state.existing_entry_ids
Expand Down Expand Up @@ -1568,6 +1654,54 @@ def _plan(**kw: object) -> ModelOccCompanionPlan:
"in the contract instead."
)
prior_check_type = declared[0]
# OMN-16071: the natural supersede name is keyed to the PRODUCT
# PR, which is constant across every authoring pass for that
# same PR — so a 2nd pass renders the path a 1st pass already
# merged. Allocate a fresh generation keyed to the OCC
# companion PR doing the rebind (still a single integer, so the
# strict ``.supersede.<NNNN>.yaml`` shape both this producer's
# guard and ``resolve_supersession``'s glob require still
# holds), and only for the keys that actually collide.
supersede_path = _next_supersede_path(
ticket=ticket,
prior_entry=prior_entry,
check_type=prior_check_type,
pr_number=pr_number,
occ_pr_number=request.occ_pr_number,
merged_receipt_paths=state.merged_receipt_paths,
)
if supersede_path is None:
# No fresh generation is derivable. Emitting nothing is the
# honest answer, not a silent one: the already-merged record
# for this SAME product PR carries the same pr_number /
# branch / commit_sha / probe provenance, so suppressing the
# re-mint loses no evidence — whereas opening it for write
# is the exact defect.
#
# ``_next_supersede_path`` returns ``None`` for two distinct
# reasons and they call for different operator responses, so
# the log names which one fired rather than asserting the
# first unconditionally: claiming "no OCC PR number yet" when
# one IS set would send a reader hunting for a number that
# exists, and would promise a pass 2 that will never emit.
skip_cause = (
"no OCC PR number is available yet to key a fresh "
"generation, so pass 2 of this same mint files it"
if request.occ_pr_number is None
else "both the product-PR-keyed and the OCC-PR-keyed "
"generations are ALREADY merged, so this key has "
"nothing left to add and no later pass will emit it"
)
logger.info(
"occ_companion_compute: skipping supersession for "
"%s/%s — its product-PR-keyed path is already merged "
"and %s; the merged record already binds this product "
"PR (OMN-16071 add-only writer).",
ticket,
prior_entry,
skip_cause,
)
Comment thread
coderabbitai[bot] marked this conversation as resolved.
continue
supersede_checks[prior_entry] = prior_check
content = _supersede_file(
request=request,
Expand All @@ -1581,10 +1715,7 @@ def _plan(**kw: object) -> ModelOccCompanionPlan:
)
files.append(
ModelCompanionFile(
path=(
f"drift/dod_receipts/{ticket}/{prior_entry}/"
f"{prior_check_type}.supersede.{pr_number}.yaml"
),
path=supersede_path,
content=content,
kind=EnumCompanionFileKind.SUPERSEDE_RECEIPT,
ticket_id=ticket,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -334,8 +334,63 @@ def _occ_contract_state(
existing_entry_ids=entry_ids,
whole_file_sha256=whole_hash,
raw_contract_text=content,
merged_receipt_paths=self._merged_receipt_paths(
occ_repo, ticket_id, entry_ids, token
),
)

def _merged_receipt_paths(
self,
occ_repo: str,
ticket_id: str,
entry_ids: tuple[str, ...],
token: str,
) -> tuple[str, ...]:
"""List the receipt files ALREADY on the OCC governance ref (OMN-16071).

The pure producer previously knew only which dod_evidence ids exist —
a set of DIRECTORIES — and therefore could not tell a first correction
from a re-mint of an already-merged one. That is why
``assert_append_only_emissions`` had to exempt every
``.supersede.<NNNN>.yaml`` filename unconditionally, and why a second
authoring pass for the same product PR re-rendered, in place, the exact
supersede paths its first pass had merged (live: OCC#6616, eight
``.supersede.925.yaml`` files). Reading the file list here is what lets
that exemption become conditional.

Scoped to ``entry_ids`` — the only directories the guard can freeze —
so this is bounded by the merged contract's item count (in practice
1-10), not by the ticket's whole receipt tree.

FAILS SOFT, deliberately: a listing error yields ``()``, which
reproduces the pre-OMN-16071 semantics exactly rather than refusing a
mint over an unrelated API hiccup. Nothing that was previously caught
stops being caught — the write-EFFECT's pre-push ``_assert_append_only``
is still fail-closed on git status behind this, and the hosted OCC
Append-Only Gate is fail-closed behind that.
"""
owner, repo_name = split_repo(occ_repo)
paths: list[str] = []
for entry_id in entry_ids:
directory = f"drift/dod_receipts/{ticket_id}/{entry_id}"
encoded = urllib.parse.quote(directory, safe="/")
try:
listing = rest_json_array(
"GET",
f"/repos/{owner}/{repo_name}/contents/{encoded}"
f"?ref={_OCC_DEFAULT_TARGET_BRANCH}",
token=token,
)
except GitHubApiError:
continue
for item in listing:
if item.get("type") != "file":
continue
name = item.get("name")
if isinstance(name, str) and name.endswith(".yaml"):
paths.append(f"{directory}/{name}")
return tuple(sorted(paths))

def _resolve_red_ref_live(
self, owner: str, repo_name: str, pr: dict[str, object], token: str
) -> str | None:
Expand Down
Loading
Loading