Skip to content

ci(policy): require every published contract to trace to a governing requirement - #1422

Draft
doublewhy wants to merge 5 commits into
devfrom
712-contract-requirement-tracing
Draft

doublewhy wants to merge 5 commits into
devfrom
712-contract-requirement-tracing

Conversation

@doublewhy

@doublewhy doublewhy commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Summary

A schema could be published, and stay published, with no requirement governing it. experiment-authoring-input-v1 was linked to EXP-736 only after review (#675, PR #711), and tools/check_requirement_governance.py checks only the files a branch changes. This PR adds a whole-inventory policy gate, tools/check_contract_requirement_tracing.py, and backfills every link the gate found missing.

A published contract is traced when an ACTIVE or DRAFT requirement record carries an IMPLEMENTS → SPEC link to its exact schema path. On origin/dev at b22f3b63, 61 of the 139 published contracts met that rule. This PR backfills the other 78 across 39 requirement records, so the current tree passes with no allowlist and no waiver. From now on, a PR that publishes a schema must add its owner link in the same change.

The issue asked for these decisions:

  • CODE_FILE links do not count. raes_contracts/contracts/bundle.py generates all 139 contracts, and seven requirements link it as a CODE_FILE. Accepting module links would therefore mark every contract traced.
  • DRAFT owners qualify, and DEPRECATED or ARCHIVED owners never do. requirement_governance.py rejects that same status set for implementation work. 9 contracts trace only to DRAFT owners. Three of those owners, API-411, API-418, and API-421, are the contract requirements for participant outcome reports, participant budgets, and time. The fourth, EXP-719, is the treatment and factor design requirement that experiment-binding-descriptors-v1 serves.
  • Other link types do not count. CONSTRAINS, DOCUMENTS, TESTS, and VERIFIES record a different relation. An IMPLEMENTS link to a schema path typed CONFIG, SCHEMA, or DOCUMENTATION does not count as ownership either, and is retyped to SPEC only where it records ownership. This PR retypes the 6 such links on otherwise-untraced contracts (ACT-610, ASR-511, ASR-516 twice, ASR-535, and SEM-218). It leaves the other 19 unchanged: API-424 (1), DSL-130 (2), GOV-922 (6), SEM-212 (2), SEM-213 (4), SEM-219 (3), and SEM-226 (1). Each of those sits on a contract that already has a SPEC owner, and descriptions such as "Published vocabulary validation" and "temporal contracts" record a narrower relation, not ownership.
  • Source and lane. Records are read offline through RepositoryRequirementClient, the repository source that tools/policy/requirement_order.yaml selects. The gate makes no Ground Control request, so it runs in every CI policy run as policy / published contract requirement tracing.
  • Inventory. The gate reads contracts/schemas/**/*.json. The contracts lane already fails when that tree disagrees with schema_bundle() (check_generated_schemas.py) or with the publication manifest (check_schema_publication.py). A new test pins all three to one set.

Requirement UIDs

Related Issues

Closes #712

ADR Impact

  • No ADR required. The gate applies ADR-009 §7, which makes contracts/schemas/ the normative authority. No ADR text changes.

Changes

  • tools/check_contract_requirement_tracing.py (new): inventories contracts/schemas/**/*.json and loads every docs/requirements/<UID>/requirement.md through RepositoryRequirementClient. It reports [contract-requirement-trace-missing] for each published contract without a live IMPLEMENTS → SPEC owner. A record the parser rejects is reported as [contract-requirement-record-unreadable] and owns nothing. --report lists each contract's owners and never gates. --json and tools/policy/exceptions.yaml waivers behave as in check_schema_coverage.py.
  • tools/nox_support/policy_lanes.py: adds one _WORKING_TREE_POLICY_STAGES row after policy / published schema coverage. The gate therefore runs in nox -s policy, verify-fast-feedback, and the CI policy lane, and is skipped under --staged like its siblings.
  • docs/requirements/*/requirement.md (39 records): adds 74 IMPLEMENTS → SPEC lines and retypes 6 existing IMPLEMENTS lines to SPEC (3 CONFIG, 2 DOCUMENTATION, 1 SCHEMA). Each of the 78 contracts gains one owner, except the two participant-episode schemas, which gain two (RUN-311 and API-417). API-417, API-418, and EXP-719 had no Traceability section, so each gains one. API-407's two lines own mixed-backend-execution-binding-v1 and mixed-backend-stage-report-v1, which feat(contracts): publish mixed-backend execution and readback contracts #1442 published after this branch was first cut. DSL-111's three lines and DSL-142's one line own the four inject contracts that feat(contracts): publish inject readback, correlation and backend declaration contracts #1449 published after that. The table below gives each owner.
  • docs/explain/reference/published-contract-requirement-tracing.md (new): documents the rule, the decisions above, the evidence order for choosing an owner, and the phase ownership roots that requirement governance applies when a governed branch edits the owner's record. docs/explain/reference/README.md indexes it.
  • implementations/python/tests/test_issue_712_contract_requirement_tracing.py (new): 25 tests, described in the Test Plan.
Backfilled owners for the 78 contracts

Evidence classes, strongest first:

  • recorded (24 contracts): the requirement already recorded the contract, through its exact schema path under another link or artifact type, or through its catalog or publication record.
  • declared (32): a requirement was named by the publishing PR's Requirement UIDs section or branch, by the publishing commit's message, or by the closing issue's Requirements section or title.
  • statement (22): none of those named a requirement, so the owner is the requirement whose statement names the contract's subject, with corroboration where any exists. These rows deserve the closest review.

Each publishing PR or commit below is the one that added the schema path, found with git log --diff-filter=A (no --follow) and GitHub's commit-to-PR lookup.

Evidence Owner Contracts Basis
recorded ACT-610 nist-csf-defensive-categories-source-v1 (retyped) already IMPLEMENTS → CONFIG on the schema path
recorded ACT-611 fipa-communicative-acts-source-v1, w3c-activitystreams-activity-types-source-v1 already IMPLEMENTS → SPEC on the matching contracts/concept-authority/ source documents
recorded API-402 evaluation-history-event-stream-v1, evaluation-result-envelope-v1, workflow-history-event-stream-v1, workflow-result-envelope-v1 already CONSTRAINS each path; statement covers result and history contracts
recorded API-403 workflow-cancellation-request-v1 already CONSTRAINS the path; statement covers mutating control-plane operations
recorded API-406 participant-lifecycle-event-v1, participant-observation-envelope-v1 already DOCUMENTS each path; statement covers participant observations and state-change reports
recorded API-408 participant-history-view-v1, participant-status-view-v1 already DOCUMENTS each path; statement covers status and history retrieval
recorded API-411 (DRAFT) participant-outcome-report-v1 already DOCUMENTS the path; statement covers participant outcome reporting
recorded API-412 processor-manifest-v2 already CONSTRAINS the path; statement is the processor manifest
recorded ASR-501 raes-semantic-invariants-v1 already IMPLEMENTS → CONFIG on the contract's publication entry
recorded ASR-511 validation-profile-catalog-v1 (retyped) already IMPLEMENTS → CONFIG on the schema path
recorded ASR-516 authoring-adapter-comparison-v1, authoring-adapter-vector-v1 (both retyped) already IMPLEMENTS → DOCUMENTATION on each schema path
recorded ASR-535 participant-opacity-model-check-evidence-v1 (retyped) already IMPLEMENTS → CONFIG on the schema path
recorded RUN-301 scenario-instantiation-request-v1 already CONSTRAINS the path; statement resolves parameters into an instantiated scenario
recorded RUN-303 evaluation-plan-v1, orchestration-plan-v1, provisioning-plan-v1 already CONSTRAINS each path; statement is planning semantics
recorded SEM-218 recursive-realization-constraint-v1 (retyped) already IMPLEMENTS → SCHEMA on the schema path
declared API-402 backend-operation-capabilities-v1, backend-operation-control-v1, backend-operation-request-v1, backend-operation-response-v1 PR #1388 and issue #1360 declare API-402
declared API-407 mixed-backend-execution-binding-v1, mixed-backend-stage-report-v1 PR #1442 published both for issue #1371. Its Requirement UIDs section names API-407 as the requirement the change extends, and it states the rules for both contracts under the API-407 section of specs/formal/runtime-contracts/participant-backend-contracts.md. Issue #1371 asks to update the API-407 contracts. API-407 already owns mixed-participant-composition-profile-v1 and links the issue #1355 runtime modules whose carriers these contracts publish
declared API-421 (DRAFT) time-model-v1, time-runtime-state-v1, realized-time-model-v1 PR #865 branch API-421-time-contracts
declared API-423 participant-boundary-flow-policy-v1 PR #1053 declares API-409, API-423, SEM-230, and SEM-233; API-423 is the crossing-policy contract requirement
declared ASR-515 validation-basis-disclosure-v1 PR #871 declares ASR-515
declared ASR-516 authoring-adapter-profile-v1 PR #1302 and issue #1005 declare ASR-516
declared ASR-530 exploit-path-analysis-evidence-v1 PR #848 declares ASR-530
declared ASR-535 participant-opacity-analysis-evidence-v1, participant-opacity-analysis-input-v1, behavioral-relation-profile-v1, participant-opacity-model-check-input-v1 PR #992 published the first three and PR #997 the model-check input, and each declares ASR-535 and SEM-231; ASR-535 records the sibling model-check evidence and covers relation-bound claim records
declared DSL-114 sdl-candidate-synthesis-input-v1, sdl-candidate-synthesis-profile-v1, sdl-candidate-synthesis-record-v1 PR #1113 branch 988-dsl-114-candidate-synthesis
declared EXP-707 experiment-capture-spec-v1 PR #574 declares EXP-707, EXP-708, EXP-709, and EXP-715; EXP-707 is the capture specification
declared EXP-709 experiment-derived-measure-v1 PR #574, as above; EXP-709 is the derived-measure model
declared GOV-903 sdl-semantic-migration-context-v1 PR #1283 and issue #1210 declare GOV-903
declared GOV-918 semantic-projection-report-v1 PR #1079 branch 987-gov-918-semantic-projection-reports
declared GOV-942 behavioral-relations-v1, scientific-completeness-assessment-v1, scientific-completeness-taxonomy-v1 PR #770 with issue #747, and PR #751 with issue #727, declare GOV-942
declared RUN-311, and API-417 (DRAFT) participant-episode-history-event-stream-v1, participant-episode-state-envelope-v1 commit 9dbbb87 published both without a PR, under the subject "Add participant episode lifecycle contract surface for RUN-311"; RUN-311 links ADR-013 and test_run_311_participant_episode_lifecycle.py. API-417 also owns both, by statement: plain-data contracts for participant episode initialization, reset, completion, and restart observation
declared SEM-218 plan-realization-profiles-v1, backend-realization-preparation-v1 PR #1251 published both and declares ASR-532, SEM-218, and SEM-219. SEM-218 and ASR-532 both link the two defining modules and prose specifications. SEM-218 is the owner because its statement covers concerns left open to backend realization, requirement_order.yaml gives its phase the contracts/schemas/plans root, and it records the sibling recursive-realization-constraint-v1; ASR-532's statement is backend result validation
declared SEM-220 participant-decision-surface-v2 PR #914 published v2 and closes issue #909, whose title names RUN-311 and SEM-220 and whose body says SEM-220 defines the decision surface; SEM-220 already owns v1
statement ACT-605 participant-execution-control-v1, participant-execution-service-state-v1 ADR-092 (cited by PR #924) names the autonomous-participant execution path as ACT-605's implementation; ACT-605 links the issue #898 tests as "Autonomous participant control and lifecycle coverage"
statement ACT-614 participant-execution-binding-v1 ACT-614 links the defining module, raes_contracts/contracts/participant_execution.py, as "Execution binding contract"
statement API-418 (DRAFT) participant-resource-budget-event-v1, participant-resource-budget-policy-v1, participant-resource-budget-state-v1, participant-resource-pool-capacity-v1 statement: plain-data contracts for participant budgets, quotas, and usage accounting
statement DSL-111 inject-trigger-request-v1, inject-occurrence-v1, inject-occurrence-outcome-v1 PR #1449 published all four inject contracts and, like issue #1366, declares no requirement. Its reference page, docs/explain/reference/inject-occurrence-contracts.md, names ADR-112 and EI-01 to EI-06 in specs/sdl/external-injects.md as their authority, and EI-06 says DSL-111 "owns authored narrative identity and this occurrence relation". DSL-111's statement covers authorized external requests that instantiate authored injects as independently identified occurrences, duplicate prevention through retry keys, occurrence identities and scheduled slots, and distinct admission, refusal, application, partial and indeterminate outcomes. It links ADR-112 and the EI specification
statement DSL-142 inject-occurrence-correlation-v1 PR #1449, as above. EI-06 says DSL-142 "owns optional participant binding", and DSL-142's statement requires a participant delivery composed with an externally triggered world effect to join that effect's exact occurrence and produced result, which are the identities the correlation carries for participant consumers
statement EXP-707 observation-demand-v1 the contract is a scoped capture policy; PR #1245 cites ADR-064, which assigns "declare what evidence an experiment intends to capture" to EXP-707
statement EXP-719 (DRAFT) experiment-binding-descriptors-v1 statement: treatment, factor, and condition definitions; the descriptors bind experiment factors and conditions to their targets
statement EXP-733 participant-configuration-result-v1 statement: preserve the participant implementations a run used with their selected manifests and configurations; the result records exactly that
statement GOV-903 sdl-lineage-ledger-v1 GOV-903 links ADR-080, the lineage-ledger authority, and test_sdl_lineage.py
statement GOV-913 associated-artifact-manifest-v1 PR #741 listed no Requirement UIDs, but it ran requirement governance with GOV-913 and mapped the manifest to the reusable-asset trust policy
statement GOV-920 domain-profile-admission-policy-v1, domain-profile-binding-v1, domain-profile-definition-v1, domain-profile-resolution-context-v1, domain-profile-support-declaration-v1 statement: shared semantic profiles that declare compatible concept, contract, and behavior assumptions
statement SEM-207 proposition-truth-result-v1 statement: objective success interpretation; SEM-207's reference, objective-semantics.md, documents backend-neutral propositions

#1449's Requirement UIDs section calls DSL-111 and DSL-142 context only, because the sdl-language phase's ownership roots in tools/policy/requirement_order.yaml do not include contracts/schemas/control-plane/. That limits which files a branch governed by those requirements may change. This PR changes only their records, which are inside those roots, and the tracing gate does not read ownership roots. DSL-114 (also sdl-language) owning the candidate-synthesis contracts and API-407 owning two control-plane contracts are the same pattern.

Test Plan

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

Rebase rounds: the branch was rebased from 35122105 onto dev at a4357f9a, which added the API-407 lines (73ce3bdd, now f9980e09). It was then rebased from a4357f9a onto dev at b22f3b63, the #1449 merge. The four earlier commits applied cleanly and are patch-identical (git range-diff a4357f9a..73ce3bdd origin/dev..HEAD~1 reports = for each), and the checker, its tests, the lane wiring, and both docs pages are byte-identical to 73ce3bdd. On the rebased tree the gate exited 1 with four findings, for inject-trigger-request-v1, inject-occurrence-v1, inject-occurrence-outcome-v1, and inject-occurrence-correlation-v1. With the DSL-111 and DSL-142 lines in 4001d9c3 it exits 0, and --report lists DSL-111 as the owner of the first three, DSL-142 as the owner of the correlation contract, and no contract as UNTRACED. CI run 38296542965 on 4001d9c3 succeeded, as did the Docs (38296542599), Bootstrap qualification (38296542692), PR Title Lint, and PR Body Policy runs. All 14 required checks passed, including sonar; 32 checks passed in total, and the only skipped one was deploy. Every result below was re-run on 4001d9c3 unless it names another commit.

uv run --project implementations/python --frozen --all-extras python -m pytest implementations/python/tests/test_issue_712_contract_requirement_tracing.py -q -p no:cacheprovider passed (25 passed). The module has no integration or fuzz cases: -m integration and -m fuzz each deselect all 25.

The temporary-repository cases cover the following:

  • ACTIVE and DRAFT owners trace a contract. DEPRECATED and ARCHIVED owners do not, and one live owner beside a retired one is enough.
  • None of these trace a contract on the exact path: IMPLEMENTS typed CODE_FILE, CONFIG, SCHEMA, or DOCUMENTATION, or CONSTRAINS, DOCUMENTS, TESTS, or VERIFIES typed SPEC. Neither does IMPLEMENTS → SPEC on the source document beside the schema. Each of these cases also asserts that no record was unreadable, so none can pass on a parse failure.
  • A malformed link line, a symlinked record, and a non-UID directory each fail closed and own nothing.
  • The CLI's JSON and text output and exit codes, a shared waiver that suppresses only its named finding, and --report behave as documented.

A wiring test drives _run_working_tree_policies against a stand-in nox, the pattern test_nox_shard_wiring.py uses. It asserts that the stage runs on the working tree and is skipped under --staged. Two live-tree tests assert that the checked-in tree passes and that the gate's inventory equals both the publication catalog and schema_bundle().

Regression checks:

  • I restored docs/requirements to origin/dev, which removes only the backfill. python tools/check_contract_requirement_tracing.py then exited 1 with 78 contract-requirement-trace-missing findings, and the module failed only test_checked_in_repository_traces_every_published_contract (1 failed, 24 passed). With the backfill restored, the gate exits 0 and all 25 tests pass.
  • I loosened the gate's link rule in two temporary mutants. Counting any IMPLEMENTS link failed the CODE_FILE, CONFIG, SCHEMA, and DOCUMENTATION cases. Counting any link typed SPEC failed the CONSTRAINS, DOCUMENTS, TESTS, and VERIFIES cases. In both runs the other 5 cases of that test passed.

Every *_governance.py and *_policy_ownership.py module (17) passed, along with three other modules that read requirement records, test_issue_1237_requirement_scope.py, test_issue_1185_api_404_profile_alignment.py, and test_public_project_readiness.py, and the three modules that cover the DSL-111 and DSL-142 subjects, test_issue_1353_external_inject_design.py, test_dsl_142_participant_inject_delivery.py, and test_issue_794_participant_io_adoption.py. The result was 319 passed, 1 deselected, and with -m integration the deselected case passed. test_repo_policy_tools.py, test_nox_shard_wiring.py, test_identity_cutover_policy.py, and test_project_positioning.py, which cover the policy lanes, passed: 246 passed, 2 deselected. With -m integration, those 2 passed.

nox -s verify-fast-feedback -- --base-rev origin/dev passed, with 27 stages passed and 3 skipped; the new stage took 0.39 s. The skipped stages were YAML syntax and JSON syntax, because no such file changed, and policy / requirement governance, which the runner skips because the branch carries no requirement UID and no scope file. nox -s lint and make policy passed.

Under its own tests and the project coverage config in implementations/python/pyproject.toml, the checker has 98% line and branch coverage: 78 statements with 1 missed, and 20 branches with 1 partial (SonarCloud new-code coverage 98.0% at ddb0cfbd and again at 73ce3bdd; at 4001d9c3 SonarCloud reports new-code coverage 97.96%, 0 new issues, 0.0% duplication, and quality gate OK). The only missed line is the sys.path insert at line 49. vale --config .vale.ini reported 0 errors, 0 warnings, and 0 suggestions on the new reference page, which the docs lane does not lint.

The reference page's note on ownership roots rests on a probe of evaluate_requirement_governance and evaluate_requirement_scope. In each, a branch governed by GOV-918, RUN-311, or API-412 edited that requirement's own record. The scope runs bound every changed file to that requirement, and all six runs reported requirement-ownership-mismatch on the record. This probe ran at ddb0cfbd. Since then, dev has changed tools/policy/requirement_order.yaml only by adding eight issue #297 ownership roots, none of them a GOV-918, RUN-311, or API-412 record, and it did not change between a4357f9a and b22f3b63.

Ground Control Checks

  • Repository policy command passes: make policy exited 0, and the only skipped stage was requirement governance.
  • Regression check fails without the backfill and passes with it, as described in the Test Plan.
  • Pre-push code review and test-quality review completed, or not run for this lane: an independent review of the second commit (ebac3e65, now 8b1cf134 after the rebases) returned two blocking findings and three minor ones, and the third commit (ddb0cfbd, now 9bdae90a) fixes all five. The blocking findings were an overbroad retyping rule and citation and classification errors in the backfill table. The minor ones were the coverage figure, the missing TESTS, SCHEMA, and DOCUMENTATION negative cases, and the ownership-roots note. The two rebase-round commits, f9980e09 (formerly 73ce3bdd, the two API-407 lines) and 4001d9c3 (the three DSL-111 lines and one DSL-142 line), were then reviewed independently at 4001d9c3: the owners, their phase mapping and the gate on dev's schemas all hold.

Traceability

  • IMPLEMENTS: tools/check_contract_requirement_tracing.py, tools/nox_support/policy_lanes.py, docs/explain/reference/published-contract-requirement-tracing.md, and 80 IMPLEMENTS → SPEC links owning the 78 contracts, in 39 docs/requirements/<UID>/requirement.md records, listed in the table above
  • TESTS: implementations/python/tests/test_issue_712_contract_requirement_tracing.py

Checklist

  • Code follows the project coding standards: small functions that reuse RepositoryRequirementClient, PolicyFailure, and the shared waiver loader.
  • FM: not applicable. There is no SDL, contract, schema, or runtime semantic change, only repository policy tooling and traceability records. No executable or runtime adoption is claimed.
  • Published contract schemas regenerated if models changed: no model or schema changed, and contracts/schemas/ is untouched.
  • PR title is a Conventional Commit: ci(policy), which does not cut a release.
  • Architectural docs updated: the new reference page documents the rule.

Documentation

Updated: docs/explain/reference/published-contract-requirement-tracing.md (new) and the index in docs/explain/reference/README.md.

@doublewhy
doublewhy marked this pull request as ready for review October 9, 2026 11:41
@doublewhy
doublewhy marked this pull request as draft October 9, 2026 17:15
@doublewhy
doublewhy force-pushed the 712-contract-requirement-tracing branch from ddb0cfb to 73ce3bd Compare October 12, 2026 01:49
…requirement

Add tools/check_contract_requirement_tracing.py as the "policy / published
contract requirement tracing" stage. A published schema is traced when an
ACTIVE or DRAFT requirement record carries an IMPLEMENTS -> SPEC link to its
exact path; CODE_FILE links, other link types, and DEPRECATED or ARCHIVED
owners never count, and an unreadable record fails closed.

Backfill the 72 published contracts that had no such link across 35
requirement records, and document the rule in
docs/explain/reference/published-contract-requirement-tracing.md.

Closes #712
…isode owner

An IMPLEMENTS link to a schema path typed CONFIG, SCHEMA, or DOCUMENTATION
does not count as ownership and is retyped to SPEC only where it records
ownership. The reference page and the checker docstring no longer call every
such link a classification error: the 19 that remain record a narrower
relation on contracts that already have a SPEC owner, and stay as they are.

RUN-311 gains IMPLEMENTS -> SPEC links to the two participant-episode schemas,
which commit 9dbbb87 published for RUN-311. The reference page now says that
a requirement-governed branch must keep the edited record inside the ownership
roots of its governing requirement's phase, and counts the publishing commit
as declaring evidence. The negative tests add TESTS links and IMPLEMENTS links
typed SCHEMA or DOCUMENTATION, and assert that each record was read.
PR #1442 published mixed-backend-execution-binding-v1 and
mixed-backend-stage-report-v1 after this branch was cut, so the tracing
gate reported both as untraced once the branch was rebased onto dev.

API-407 owns both. Issue #1371, which #1442 implements, asks to "Update
API-407 contracts" for these carriers, and #1442 states the rules for
both contracts under the API-407 section of
specs/formal/runtime-contracts/participant-backend-contracts.md. The
API-407 statement requires the installed mapping, bridge,
time-coordination and readback services that the binding pins and the
stage reports evidence to be checked in context, and API-407 already
owns mixed-participant-composition-profile-v1 and links the issue #1355
runtime modules whose carriers #1442 published.
PR #1449 published inject-trigger-request-v1, inject-occurrence-v1,
inject-occurrence-outcome-v1 and inject-occurrence-correlation-v1 after
this branch was cut, so the tracing gate reported all four as untraced
once the branch was rebased onto dev.

Neither #1449 nor issue #1366 declared a requirement, so each owner
follows from its statement and the governing specification. #1449's
reference page names ADR-112 and EI-01 to EI-06 in
specs/sdl/external-injects.md as the contracts' authority, and EI-06
says that DSL-111 owns authored narrative identity and the occurrence
relation and DSL-142 owns optional participant binding.

DSL-111 owns the request, occurrence and outcome contracts. Its
statement requires authorized external requests to instantiate authored
injects as independently identified occurrences, prevents duplicate
logical execution through retry keys, occurrence identities and
scheduled slots, and keeps admission, refusal, application, partial and
indeterminate outcomes distinct. It already links ADR-112 and the EI
specification.

DSL-142 owns the correlation contract. Its statement requires a
participant delivery composed with an externally triggered world effect
to join that effect's exact occurrence and produced result, which is
the identity set the correlation carries for participant consumers.
@doublewhy
doublewhy force-pushed the 712-contract-requirement-tracing branch from 73ce3bd to 4001d9c Compare October 12, 2026 19:16
@doublewhy
doublewhy marked this pull request as ready for review October 12, 2026 19:36
@doublewhy
doublewhy marked this pull request as draft October 12, 2026 22:42

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