Skip to content

Bound messaging canary routes and retention - #259

Merged
sodejm merged 4 commits into
mainfrom
codex/issue-213-messaging-bounds
Oct 11, 2026
Merged

sodejm merged 4 commits into
mainfrom
codex/issue-213-messaging-bounds

Conversation

@sodejm

@sodejm sodejm commented Oct 11, 2026

Copy link
Copy Markdown
Owner

Summary

  • Require an explicit canary policy with allowed delivery destinations, SMTP recipients, a bounded retention window, and a positive message budget for synthetic mail, mailbox, queue, and broker canaries.
  • Validate fixture delivery and cleanup evidence against the requested route, identifier, budget, and retention window. Hash the synthetic cleanup receipt with its delivery and retention fields, and recheck imported reports.
  • Keep TCP reachability evidence separate from canary delivery or cleanup claims. Update the messaging guidance, feature specification, package documentation, and threat model.

Acceptance evidence

  • Unauthorized recipients and destinations, expired or future-dated evidence, exhausted budgets, and unconfirmed cleanup are rejected by inert/contained fixtures.
  • The accepted synthetic fixture path emits a bounded cleanup receipt; it does not claim an external service was purged.
  • Existing collector subclasses retain their no-policy behavior.

Validation

  • Focused messaging, packaged skill, and BDD tests passed.
  • make check passed in the issue worktree.
  • The repository pre-push gate passed before publication.
  • Staged and outgoing secret scans found no leaks; private-information pattern scans found no matches.

Critique and residual risk

  • Independent automated review found no material implementation issues. Final review covers the lint and formatting follow-ups.
  • Fixture evidence does not prove live delivery, external retention, or external deletion. No live canary was sent.
  • Required human review remains pending before merge.

Closes #213

…ging-bounds

# Conflicts:
#	cops/discovery/cli.py
#	docs/THREAT_MODEL.md
@sodejm
sodejm marked this pull request as ready for review October 11, 2026 16:09
@sodejm
sodejm merged commit 5c6100b into main Oct 11, 2026
18 checks passed
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-11T16:15:48.516666Z ddeaa55 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ddeaa55547

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

fixture_evidence = svc_data.get("canary_evidence")
if not isinstance(fixture_evidence, dict):
fixture_evidence = {}
raw_messages = fixture_evidence.get("messages_sent", svc_data.get("messages_sent", 0))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Require the canary count inside its evidence block

When canary_evidence omits messages_sent but the service has the legacy top-level messages_sent, this fallback treats that unrelated count as canary evidence; with matching route and timestamps, the assessment sets canary_validated and can emit a cleanup receipt despite the canary record lacking its own count. Require messages_sent within canary_evidence rather than borrowing the service-level value.

AGENTS.md reference: AGENTS.md:L95-L99

Useful? React with 👍 / 👎.

Comment thread cops/discovery/cli.py
created_at = getattr(args, "canary_created_at_utc", None)
if created_at is not None:
policy_args["created_at_utc"] = created_at
policy = CanaryDeliveryPolicy(**policy_args)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Require a creation time for pre-recorded fixtures

When a synthetic canary route omits --canary-created-at-utc, the policy defaults its creation time to this invocation, which is later than the delivery timestamp in any normally pre-recorded fixture. The subsequent created_at <= delivered_at check therefore rejects the documented optional/default path and produces neither validation nor a receipt; require the actual policy creation time for synthetic fixtures instead of silently defaulting it to now.

Useful? React with 👍 / 👎.

Comment on lines +287 to +291
"receipt_id": self.receipt_id,
"target_host": self.target_host,
"service_type": self.service_type,
"artifact_type": self.artifact_type,
"artifact_identifier": self.artifact_identifier,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Bind cleanup receipts to the authorized route

When the same canary identifier is reused on one target and service for different allowed destinations or recipients, the receipt payload contains neither the selected route nor a policy digest; with equal timestamps, both runs produce the same receipt ID and hash. Downstream report and cleanup consumers therefore cannot determine which mailbox, queue, or topic the cleanup evidence covers, so include the destination and applicable recipient—or a privacy-preserving policy digest—in the receipt hash.

AGENTS.md reference: AGENTS.md:L95-L99

Useful? React with 👍 / 👎.

@sodejm
sodejm deleted the codex/issue-213-messaging-bounds branch October 18, 2026 15:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bound messaging recipients, destinations, and retention

1 participant