Skip to content

fix(runtime): declare the missing multi-owner and exactly-once nonclaims - #1444

Open
doublewhy wants to merge 5 commits into
devfrom
8-stronger-claim-exclusions
Open

doublewhy wants to merge 5 commits into
devfrom
8-stronger-claim-exclusions

Conversation

@doublewhy

@doublewhy doublewhy commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Builds on #1431. The first three commits on this branch are #1431's. They leave the diff once this branch is rebased onto dev after #1431 merges. The evidence is then re-checked against dev and regenerated if #1431 changed before merging or dev gained another evidence release. This PR adds two commits: the declaration change and its evidence republish.

#8 asks that documentation and capability declarations exclude multi-owner operation, high availability, exactly-once external effects, and deployment TLS guarantees. API-404-C4 already says that P0, P1 and P2 must not imply any of them, and the #1185 decision asks for these exclusions to be "explicit where applicable". Two declarations each left one out:

  • P0 named multi-owner and high-availability but not exactly-once-effects, though its deduplication ends with its process. test_p0_process_loss_loses_run_and_claim_even_when_external_effect_survives resubmits after process loss and records the backend effect twice. Its own comment says P0 "cannot promise exactly-once effects".
  • P2 named multi-worker but not multi-owner, though it serves exactly one P1 core and P1 names multi-owner.

This PR adds those two nonclaims and mirrors them in the runtime architecture table. It also adds a paragraph to the P2 deployment guide on what the adapter does not provide. TLS stays a P2-only nonclaim (tls-proxy-deployment), because P0 and P1 declare no transport. Because this changes source bound by the research evidence, both captures are republished one release above #1431's (specification coverage 70.0.0, formal validation 71.0.0). Retained outcomes, classifications and claim limits are unchanged.

Together with #1431 (the request-boundary cases) and #1443 (the clause-to-profile map, the run-binding cases and the traceability), this covers #8's done-when list. #8 has a Requirements section, so it is referenced, not closed, and stays open for post-merge requirement verification.

Requirement UIDs

  • API-404

Related Issues

Refs #8

ADR Impact

  • ADR-104: its profile nonclaims become explicit for P0 and P2. No ADR text changes.
  • The feat(runtime): declare control-plane profiles and capabilities #1189 preflight's "Canonical profile matrix" (docs/decisions/issue-1189-control-plane-profile-declaration-preflight.md, lines 49 and 51) still lists P0's nonclaims without exactly-once effects and P2's without multi-owner or multi-process ownership. That decision makes the runtime catalog the canonical owner of nonclaim identifiers (lines 10-15). The docs(runtime): align API-404 with control-plane profiles #1185 decision's "explicit where applicable" row for excluded stronger claims (docs/decisions/issue-1185-api-404-profile-alignment-preflight.md, line 47) and API-404-C4 authorize the two additions. The dated decision record stays unedited.

Changes

  • raes_runtime/control_plane_profiles.py: the P0 declaration gains exactly-once-effects ("External backend effects are not exactly once.") and the P2 declaration gains multi-owner ("No concurrent process ownership is promised."). Both reuse the identifiers and descriptions P1 already declares, now held in shared constants. No guarantee, capability, actor boundary or availability changes.
  • tests/test_issue_1189_control_plane_profile_declarations.py: the canonical matrix expects the two added nonclaims.
  • docs/explain/sdl/runtime-architecture.md: the profile table's P0 and P2 nonclaim cells match the declarations. test_explain_profile_identifiers_match_canonical_catalog checks them.
  • docs/public/guides/control-plane.md: a paragraph at the end of "Deploy the adapter". The adapter is one process that owns one store, with no high availability and no operation by several owners or workers. RAES does not guarantee that a backend effect happens exactly once, and it never replays one (P2's retained-idempotency and startup-reconciliation guarantees). After a crash, an operation whose effect cannot be established becomes INDETERMINATE and keeps that state. POST /operations/{operation_id}/resolution records a separate linked operation and leaves the original unchanged: resolve_indeterminate_operation claims an INDETERMINATE_RESOLUTION child and never rewrites the parent, as docs/explain/sdl/control-plane-operations.md also states. TLS and proxy correctness belong to the deployment.
  • Specification-coverage release 70.0.0 (execution-snapshot-v70.json, analysis-v70.json, issue-8 bundle) replays the retained matrix against this branch's source.
  • Formal-validation release 71.0.0 (execution-snapshot-v71.json, analysis-v71.json, retest-v71.json) replays the retained formal cases with baseline 70.0.0 and no deviation.
  • Revision pins advanced in tools/check_specification_coverage.py, tools/formal_semantic_validation/, and the three evidence test modules. Both research indexes record the new releases.

Test Plan

  • Unit tests pass
  • Integration tests pass if applicable
  • Full completion suite required in CI before merge
  • No coverage regression

The SonarCloud quality gate passed on canonical run 37932071922: new-code coverage 100.0%, 0 new violations and 0.0% duplication.

pytest on test_issue_1189_control_plane_profile_declarations.py, test_issue_1185_api_404_profile_alignment.py, test_issue_1151_runtime_control_plane_design.py and test_issue_1187_control_plane_profiles.py passed (37 passed). Under -m integration the four modules select nothing (37 deselected). With only control_plane_profiles.py restored to the base branch, two 1189 cases fail: the canonical matrix and the runtime architecture table check.

The guide's sentences on recovery and resolution rest on existing cases in test_issue_1179_startup_reconciliation.py, which passes (22 passed; nothing selected under -m integration). test_running_claim_without_observer_is_indeterminate_and_retry_never_replays shows that an interrupted claim with no observer becomes INDETERMINATE and that a same-key retry applies nothing. test_resolution_creates_fresh_linked_operation_and_unblocks_mutation_without_rewriting_parent shows that the parent record is unchanged after resolution and that the child is a linked INDETERMINATE_RESOLUTION operation. test_http_resolution_is_operator_only_and_returns_stable_errors shows that the HTTP route refuses a backend identity with 403 and returns the linked child's receipt to an operator.

Evidence: the republish ran against origin/1091-request-limit-boundary at 11854670, so this branch's releases sit one above #1431's. It was regenerated after the guide fix and the rebase onto that tip, because the captures bind the last code commit (e16330e9). The declaration change moves the implementation digest from #1431's 93a03cee to d4356954. The later guide fix did not change it, because docs are outside the digest. Both evidence checker CLIs pass (integrity and replay). The three evidence modules pass with default markers (209 passed, 19 deselected) and with -m integration (19 passed, 209 deselected). The formal retest records no deviation and no spec artifact pin changed. The helper's --check reports "evidence is current".

nox -s verify-fast-feedback -- --base-rev origin/dev passed. Its changed-module stage ran 377 passed and 19 deselected, including #1431's modules. nox -s lint passed. make policy passed; requirement governance is skipped there because the branch selects no UID. tools/check_requirement_governance.py --base-rev origin/dev --requirement-uid API-404 also exits 0. nox -s contracts -- --base-rev origin/dev, the command of CI's "Run governed contract graph" step, passed all 14 steps, including both evidence steps. nox -s docs-local passed: Vale reported 0 errors in 22 files, and the Sphinx -W HTML build and the public output inventory passed.

Ground Control Checks

  • Repository policy command passes
  • The updated declaration tests fail on the pre-change declarations and pass after
  • Pre-push code review and test-quality review completed, or not run for this lane: an independent review of 01ce1b82 returned one blocking finding and two minor ones, and this revision addresses all three. The blocking finding was the guide's wording, which implied that resolution changes an INDETERMINATE operation's state and could be read as allowing a backend effect to be applied twice. The minor ones were the Summary's stack sentence and the feat(runtime): declare control-plane profiles and capabilities #1189 preflight matrix, now covered under ADR Impact.

Traceability

  • IMPLEMENTS: API-404 ← implementations/python/packages/raes_runtime/control_plane_profiles.py
  • TESTS: API-404 ← implementations/python/tests/test_issue_1189_control_plane_profile_declarations.py, API-404 ← implementations/python/tests/test_specification_coverage.py, API-404 ← implementations/python/tests/test_formal_semantic_validation.py, API-404 ← implementations/python/tests/test_issue_989_versioned_evidence.py
  • DOCUMENTS: API-404 ← docs/explain/sdl/runtime-architecture.md, API-404 ← docs/public/guides/control-plane.md

Checklist

  • Code follows the project coding standards
  • FM0: two added nonclaim entries in a static declaration table, covered by the declaration tests. No guarantee, admission rule or runtime behavior changes, and no executable or runtime adoption is claimed.
  • No published contract schema or model changed, so nothing is regenerated
  • PR title is a Conventional Commit; fix(runtime) because profile_declaration() returns the added nonclaims
  • Architectural docs updated if applicable: the runtime architecture table and the P2 guide; ADR-104 is unchanged

Documentation

Updated: docs/explain/sdl/runtime-architecture.md (profile table) and docs/public/guides/control-plane.md ("Deploy the adapter").

…e their body completes

Complete the #1091 request-boundary acceptance cases and document the bounded HTTP admission contract.
The request-boundary fix changes bound runtime source, so publish specification coverage 69.0.0 and formal semantic validation 70.0.0. Replayed outcomes and claim limits are unchanged.
Name the existing size-guard tests in the #1091 module docstring and say why
they stay. Drop the 16 parametrized cases whose input repeated another case
under a misleading id, require exactly one response start per exchange, and
limit the guard's log to the fixed audit-failure message. The guide now says
that a route runs once the adapter has read the last body chunk, and that a
server can report a disconnect after the client has sent the whole body.
P0 now declares exactly-once-effects and P2 declares multi-owner, so every available profile names the API-404-C4 exclusions that apply to it. The runtime architecture table and the P2 guide state the same limits.
The profile declaration change moves the bound implementation digest, so publish specification coverage 70.0.0 and formal semantic validation 71.0.0 above the #1091 releases. Replayed outcomes and claim limits are unchanged.
@doublewhy
doublewhy force-pushed the 8-stronger-claim-exclusions branch from 01ce1b8 to a18c821 Compare October 9, 2026 12:44
@doublewhy
doublewhy marked this pull request as ready for review October 9, 2026 15:06

This branch has not been deployed

No deployments
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.

1 participant