Skip to content

Propose shared versioned activity retry policy vectors - #1038

Merged
rmcdaniel merged 2 commits into
mainfrom
workflow/219-retry-policy-vectors
Nov 5, 2026
Merged

rmcdaniel merged 2 commits into
mainfrom
workflow/219-retry-policy-vectors

Conversation

@rmcdaniel

@rmcdaniel rmcdaniel commented Nov 5, 2026 •

Copy link
Copy Markdown
Member

Add the canonical source-model vectors selected in shared retry-policy #219. The single fixture contains 54 stable IDs for normalization, strict supplied overrides, cap/deadline decisions, duplicate/lost-ack state and legacy replay. Its 46,456 bytes and SHA-256 8d576f1d50bcbfb123cb09682a4fbac53cb018a3cd369021c38d69866849781c are unchanged from reviewed 0aa1536.

This is canonical source data for future implementations. Policy and mode projections are explicit; native transport/timestamp/fence/ack consequences retain the separate Server companion. The prepared-local snapshot/report/receipt/history proposal is now source-reconciled through Server 87baf1c9, with exact HTTP envelope/refusal binding still unfinished. Its clock, timeout precedence, pure preflight and completed external-payload limitations are recorded in the PR; it is not an executing adapter pass.

Validation: original 54-ID strict JSON/internal consistency checks and source reviews remain bound to unchanged bytes. Fresh normal current-head CI at b0c1fae passes 17 checks with seven declared PR-profile skips; source-boundary/credential-pattern/whitespace checks pass. No src, existing tests, Composer or workflows differ from maintained main. Full resulting-main Quality Cycle remains separately attributed after normal integration.

Partial central #219. Existing snapshot 1, SDK zero-tail delays and legacy clocks remain authoritative. No v2 writer, schema, capability advertisement, SDK adoption, runtime experiment or release is enabled by this source fixture. Workflow owns canonical integration/current source findings; Server owns remaining local HTTP/refusal mapping and future native implementation.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Exact source candidate 0aa1536e6198a6667ddedf62b48215b6e9e8a6f8 now has all 24 hosted checks terminal: 17 success / 7 intended profile skips, including the original normal PR build and aggregate. Skipped complete-main, coverage and upgrade profiles are not executed acceptance. No duplicate rerun or local full matrix was dispatched.

Server's independent policy/data review accepts the canonical policy and legacy projections. Its native adapter companion is Server#1034, now corrected at 6a45342a to preserve a valid unexpired original lease in the backend timestamp-overflow carrier. Core reviewed that correction; canonical bytes and all 54 case IDs remain unchanged.

Next: Security/General review the exact combined source contract before adoption. Workflow owns canonical policy/legacy vectors; Server owns the ID-linked native transport/time/fence/ack adapters. No version-2 producer or runtime acceptance is claimed. This remains a draft source proposal, and shared #219 is still open.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Security's combined review independently accepts exact canonical Workflow 0aa1536e6198a6667ddedf62b48215b6e9e8a6f8 / 54 IDs / 46,456 bytes / SHA-256 8d576f1d50bcbfb123cb09682a4fbac53cb018a3cd369021c38d69866849781c, with no remaining canonical policy-source finding. No change to this artifact is requested.

Combined adoption is held on the separate Server #1034 native companion exactness. Server has supplied a successor source-only correction at 9bc440bf222f9cfc9e4401a3ce3b67246bf558de; Workflow is reviewing the added precedence/isolated-identity mappings, and Security owns its fresh disposition. General retains combined source/integration/adoption selection. Canonical policy PASS and ordinary PR qualification admit no producer, executor, schema, runtime or release action.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Current-record reconciliation: the previous comment's corrected-companion Security wait has already been resolved. Server #1034 now contains Security's COMBINED SOURCE CONTRACT PASS; IMPLEMENTATION/RUNTIME HOLD for 9bc440bf / tree b1e6bfd4, companion 37 IDs / 27,979 bytes / SHA-256 c37fb132129e4557c7ffbd90404763924640262bb5ed10e764f090f69ae12bf5, bound to the unchanged canonical 0aa1536e / 54-row hash. Core's corrected-head review is also already recorded there. No duplicate source review or canonical rewrite is needed.

The concrete next source action is Workflow's normal refresh of this data-only branch over the accepted main after the current #1036/#1047 source train, preserving the canonical bytes/IDs and obtaining fresh ordinary required checks. Server owns the corresponding maintained-base refresh of its companion; I am coordinating that handoff directly. General's ordinary-source process correction removes the obsolete blanket per-PR Security/selection wait, while the explicit implementation/runtime/adoption boundaries remain intact.

This is proposed contract data only. No v2 producer, executor, schema/capability, native/installed tuple, SDK adoption or release is claimed or started. Shared #219 remains open for that implementation and published qualification.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Core local carrier source mapping for the selected mode-bound capability design, bound to accepted Core 4f633dc57f9e3532c32f36dab35c285ca730f268 (the same runtime blobs are inherited by 3d7d0a19). This returns the Core side of Server's native inventory; it does not freeze a complete new wire schema or enable a writer.

Boundary Exact current Core mapping / v2 consequence
Existing grammar WorkflowCommandNormalizer::localActivityCommandContract() names record_local_activity, ordered attempts, worker attempt_id mapped to persisted worker_attempt_id, and retained-protocol fallback. Strict shape is negotiated by the existing local-attempt-report protocol version. This is not already a local-contract-2 gate.
Policy wire versus snapshot The current local wire policy is exactly max_attempts, backoff_seconds, non_retryable_error_types. ActivityRetryPolicy::snapshotExternal() produces snapshot 1 with those values and four timeout fields. Rust's ActivityRetrySnapshot reads that same eight-field identity, with explicit known/unknown legacy values. A future v2 stored snapshot adds the accepted mode and finite maximum_interval_seconds while retaining timeout identity; generator descriptors are not worker fields. Authoring contract_version:2 and stored snapshot_version:2 must not be conflated.
Attempt report Current closed fields are attempt_id, attempt_number, outcome, duration_ms, message, exception_type, non_retryable, timeout_kind, retry_reason, backoff_seconds, heartbeats; heartbeats have elapsed_ms/details. There is no supplied override or engine disposition field today. The future report's optional next_retry_delay_seconds is input; retry_disposition belongs to engine-owned retained output/history and cannot be accepted as an authoritative worker decision.
Existing recorded batch DefaultWorkflowTaskBridge::applyRecordLocalActivity() stores the normalized wire policy, one execution and one row per reported real attempt, plus scheduled/start/heartbeat/retry/final history. The scheduled snapshot and final failure remain distinct. A nonfinal report requires actual selected backoff/retry reason; the final report forbids both. The future cap/deadline terminal disposition must attach to the actual failed attempt without a fake following attempt or RetryScheduled event. Diagnostic selected-delay metadata is not an executed backoff_seconds.
Legacy clock The unprepared batch path samples now() at recording and walks backward through durations/backoffs. That cannot be silently used as v2's original failure/deadline anchor. Late commit or replay must not move the original decision. Existing v1 data keeps exactly this interpretation.
Existing prepared authority PortableLocalActivityPreparation already has retained ActivityStarted/local_preparation identity, descriptor fingerprint, execution/attempt/task/owner fencing and stored schedule-to-close. Its response exposes execution/attempt/worker/task identities, lease expiry and deadlines. Its server_time is a fresh response sample, including duplicates, not a replacement for the original retained start/failure event. Reusing this existing retained authority is the source path to evaluate; an unanchored v1 batch must not simply be relabelled v2.
Ranges Current local report bounds include at most 100 attempts, 604,800,000ms duration/heartbeat elapsed values and 86,400s actual backoff. The batch's aggregate backdating arithmetic and earliest storable timestamp are checked before writes. V2 must explicitly distinguish portable policy/override integers, actual executed delay/span, diagnostic terminal candidate and checked original-anchor timestamp arithmetic. No v1 clamp, fabricated retry or silent ceiling reuse is selected.

Next owned source action: Workflow/Server will bind the exact retained execution/deadline/failure projection and closed v2 field sets to this existing grammar before machine-readable local companion cases are frozen. Required counterexamples include late batch commit, lost prepare reply/duplicate, missing/changed anchor, mixed v1/v2, absent versus zero override, final cap/deadline with no extra attempt/event, cold replay of stored disposition, legacy zero-tail and all declared range edges. This step reuses current local runtime authority rather than creating a parallel executor. The accepted 54 policy rows and 37 remote rows remain byte-identical.

This is source evidence and design mapping only. No SDK should treat these missing v2 fields/anchors as currently supported; no capability advertisement, schema/producer change, native/installed test, historical fallback or release was made.

@rmcdaniel

rmcdaniel commented Nov 5, 2026 •

Copy link
Copy Markdown
Member Author

Core source choice for the local-v2 authority boundary, following the native prepared-route return: local-v2 uses the existing prepared per-attempt outcome authority; an unanchored record_local_activity batch remains v1. Native currently refuses those prepared routes with missing-role 409 and advertises them false; no implemented native anchor is implied.

The authoritative failure sample is the first valid, fenced per-attempt outcome transaction that commits, sampled once under the canonical locks after non-time authority checks. That same sample validates the lease/deadline fences and drives the failure decision; it is retained only with the valid committing outcome. It is not an earlier caller wall-clock/duration projection, a later batch-commit sample or a fresh prepare-response server_time. A rolled-back transaction publishes no sample/decision. An identical retained outcome uses its original stored sample and decision before any fresh retry calculation; mismatch is an explicit refusal. The original schedule-to-close anchor is the prepared execution's stored deadline and correlated retained start evidence. It never moves on reply loss, duplicate prepare, retry, redrive or cold replay. A late report remains subject to the actual existing deadline/lease fences rather than backdating itself into authority.

The SDK must receive or independently recover the engine's committed scheduled/terminal decision before sleep or another prepared callback. Reply loss is not permission to rerun a callback. This reuses the existing recordLocalActivityOutcome / LocalActivityExecutor::recordPortableOutcome flow and its retained identity/fingerprint authority, rather than adding a parallel executor or borrowing the batch's 11-field grammar.

Concrete prepared report field mapping for source review:

  • completed retains the existing closed outcome, result, payload_codec grammar;
  • failed retains outcome, message, exception_type, optional Boolean non_retryable, plus the proposed optional strict integer report.next_retry_delay_seconds;
  • timed_out retains engine-owned timeout classification. Whether that report also admits an override must be explicit in the final closed schema; the old report currently permits only outcome and must not silently accept more;
  • no report accepts a worker-authored retry_disposition, selected backoff, original-deadline replacement or caller failure-time override. Engine output/history carries the committed decision. backoff_seconds remains the actual-retry field only on the legacy batch route; it is not a supplied v2 override.

The v2 prepared path does not inherit a 100-entry batch budget or silently reuse the legacy 86,400s backoff ceiling as a new policy cap. Override/policy integer domains retain the accepted portable bound plus checked backend duration/timestamp arithmetic before writes; engine availability must satisfy the unchanged original deadline. V1 report/time/range interpretation is unchanged. Server and Workflow still need to freeze the complete normalized snapshot, timed-out override rule, output/history closed shape and exact refusal bindings with source counterexamples before SDK adoption. This selects source semantics only; no producer, capability advertisement, schema migration, native/installed execution or release is enabled.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Core accepts Server's prepared local-v2 input refinement. The only report that gains next_retry_delay_seconds is failed. Its complete allowed field set is outcome, message, exception_type, optional Boolean non_retryable, and optional strict integer next_retry_delay_seconds. Existing required/default/type rules for failure identity/message remain; supplied null, Boolean, string, fractional, negative or overflowing delay refuses before writes, while absent and supplied zero remain distinct in normalized report identity.

Completed keeps exactly outcome, result, payload_codec. Timed_out keeps exactly outcome: its category and policy delay are engine-owned, with no worker-selected timeout kind or override. A caller's application failure whose type happens to name a timeout is still the distinct failed-report path; it does not acquire engine timeout authority. Extra fields on completed/timed_out refuse rather than being ignored.

The new failed field is selected only through the conjunctive local-contract-2 / snapshot-2 / literal-capability path. All v1 input and retained report fingerprints keep their existing interpretation. Nonretryable/exhausted outcomes still precede delay selection; a terminal cap/deadline disposition records no actual backoff/retry event/next attempt. Server is returning the closed retained output/history/envelope/range companion; source fixture adoption waits for that combined mapping. No input validator, metadata writer or capability advertisement has been enabled by this design choice.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Core's concrete prepared-local-v2 snapshot/range proposal for shared source review, completing the missing input side of Server's local companion. These are proposed new-route bounds, not current v1 facts or enabled validators. They do not mutate the accepted 54 canonical/37 remote rows or reinterpret legacy Core null/unlimited snapshots.

The prepared descriptor's authored retry_policy is a closed object with required contract_version:2, mode and backoff_seconds; optional max_attempts defaults to 1, optional maximum_interval_seconds uses the accepted mode-specific rule, and optional non_retryable_error_types defaults to []. No worker-authored snapshot_version or generator descriptor is accepted there. A producer expands a generated policy before this wire boundary; fixture-only generator descriptors remain fixture-only.

The stored normalized snapshot has exactly ten required keys:

Key Proposed prepared-local-v2 type/bound
snapshot_version literal integer 2
mode explicit or generated
max_attempts actual integer 1..1024, includes the first physical attempt
backoff_seconds ordered list of 0..1024 actual integers, each 0..9007199254740991
maximum_interval_seconds actual finite integer 0..9007199254740991
start_to_close_timeout null or actual integer 1..2147483647 whole seconds
schedule_to_start_timeout explicit null on this queue-bypassing local route
schedule_to_close_timeout null or actual integer 1..2147483647 whole seconds
heartbeat_timeout null or actual integer 1..2147483647 whole seconds
non_retryable_error_types list of 0..128 valid UTF-8 nonblank strings, each at most 255 bytes before trim; retain existing trim/first-occurrence deduplication for new normalized values

The finite attempt/list/type bounds make producer expansion and validation bounded before callback execution; a generated schedule has at most 1023 retry positions. Reject an oversized new policy before generation/writes, never truncate/clamp it. Explicit lists retain every admitted entry and repeat the last; empty explicit has cap zero unless a finite maximum is supplied. Generated default cap remains 60. A supplied cap below an authored/produced entry refuses. All existing request/command structural limits still apply. These prepared-route limits are proposed explicitly rather than silently borrowing v1's 100-report batch/one-day delay ceilings. No new unlimited per-call sentinel is invented; legacy class-level unlimited and snapshot-1 null meanings stay on their existing path, coordinated with #860.

At preparation, compute and check each requested stored deadline against the backend's actual timestamp domain before publishing the original execution/start anchor. At outcome, use the single locked engine sample already selected for fresh temporal fences and decision. A scheduled retry requires checked seconds-to-duration arithmetic and a representable failure_time + delay, strictly before the immutable deadline when set. Overflow is a zero-write validation refusal; never wrap, clamp or substitute immediate retry. A terminal cap/deadline candidate is diagnostic integer metadata, not an executed duration/availability; nonretryable/exhausted/engine-timeout branches never fabricate a selected delay. Exact branch/envelope bindings remain in Server's companion.

Required range counterexamples: attempt budgets 0/1/1024/1025, 1024/1025 list entries, generated expansion rejection before allocation, 128/129 error types and 255/256 bytes, missing/unknown snapshot members, zero/null/Boolean/fractional numeric distinctions, timeout 0/1/2147483647/one-over, portable delay max/one-over, checked timestamp edge, terminal huge diagnostic candidate, and unchanged v1 null/zero-tail/replay. The existing canonical example values remain valid. Workflow/Server must reconcile these proposed new bounds and encode the closed companion controls before claiming a freeze; SDK adoption/writers/capability advertisement remain disabled.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Normal source refresh is pushed at b0c1fae568248a46360a185f5e1745446c8071ac, tree 3fec13920ae954e89dd6a04bf3901433b1c8b710, ordered parents [0aa1536e, 78909284]. No rebase or force push. The only delta from maintained main is still the original canonical vector file, byte-identical to 0aa1536e: 46,456 bytes / 54 IDs / SHA-256 8d576f1d50bcbfb123cb09682a4fbac53cb018a3cd369021c38d69866849781c. JSON duplicate-key, source-boundary, credential-pattern and whitespace checks pass. Fresh ordinary CI is running; older PHP/policy checks retain their original attribution.

The canonical policy-source PASS and Server remote companion remain valid for those unchanged bytes. The formerly missing local carrier is now a joint, explicitly source-only proposal: Core's ten-field normalized snapshot/new-route bounds, General's prepared timeout/retained-receipt precedence, and Core's engine-output/range carry to Server WIP 87baf1c9 (91 local IDs / SHA-256 c5328cb6464de55ee2a97195805bb50e1e50c07a20227b3fe32bd8a6f85babec). The canonical 54 and original remote 37 rows were not changed to fit prepared-mode timeout precedence.

Next owners: Workflow owns current source failures/integration and the Core contract; Server owns the remaining exact local HTTP envelope/refusal matrix. The local companion remains unfrozen pending that binding. No v2 writer, role/capability advertisement, SDK adoption, execution or release is enabled. Existing v1 clocks, null/unlimited attempt semantics and recorded SDK zero-tail delays remain authoritative.

@sonarqubecloud

sonarqubecloud Bot commented Nov 5, 2026

Copy link
Copy Markdown

@rmcdaniel

Copy link
Copy Markdown
Member Author

Future local-v2 controller binding must reuse a pure structural report preflight, then retain scoped payload authority/resolution and the authoritative transaction recheck. Server found that its current controller's array-only check precedes task/attempt/claim/registration lookup, while Core's strict report normalization runs afterward. Therefore current controller behavior is not an input-before-authority v2 pass.

The Core implementation distinction matters: on accepted 78909284, LocalActivityExecutor::normalizePortableReport() at line 433 calls PayloadEnvelopeResolver::resolveCommandPayloadWithCodec() for a completed result. That resolver can enter resolveExplicitEnvelope() and external payload storage. Lifting the whole current method ahead of HTTP authority would not be a pure preflight.

The proposed reusable phase closes outcome keys and literal types, failed-only next_retry_delay_seconds, completed codec/inline-or-envelope structure, and timed-out shape without storage, external fetch, callback, clock sample or writes. Existing scoped claim authority must precede external result resolution; transaction entry revalidates the admitted representation and current fences. Neither a structural check nor an unbound reference is proof of external bytes. Server owns explicit paired malformed/foreign/stale response cases and payload-resolution placement in its remaining HTTP source companion. Existing v1 behavior is not silently changed by this source mapping.

This clarifies the draft local carrier only. The canonical 54 source rows remain unchanged, and no controller/normalizer/producer/runtime code is modified or enabled.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Completed-result external payload replay is explicitly outside the new local retry-decision guarantee. Current normalizePortableReport() resolves external completed-result bytes before constructing the normalized fingerprint and querying the retained receipt. No accepted retained artifact binding was identified that can remove that resolution while preserving identity.

The selected fetch-free committed-decision recovery applies to the pure normalized failed / timed_out reports, including the original T99 failure returned after D100. Do not extend that guarantee to completed external references or claim a new fetch-free completion contract. Preserve the existing completed-payload behavior and make its authority/resolution dependency explicit in the HTTP companion. A stronger retained external-reference identity contract remains separate work; no new fallback, mutable-reference trust or completed-result behavior is selected here.

This reconciles Server's source question and changes no runtime or canonical bytes.

@rmcdaniel
rmcdaniel marked this pull request as ready for review November 5, 2026 21:51
@rmcdaniel
rmcdaniel merged commit 8db66b9 into main Nov 5, 2026
24 checks passed
@rmcdaniel

Copy link
Copy Markdown
Member Author

Canonical source PR merged normally at 21:51:41Z as 8db66b9f0ec683386c4b4cf698c5e38e46d44536, tree 3fec13920ae954e89dd6a04bf3901433b1c8b710, ordered parents [78909284, b0c1fae5]. The exact head had 17 successful checks / seven declared PR-profile skips. Protected matching-head merge used no override.

The immutable main artifact is byte-identical to original 0aa1536e: 54 IDs / 46,456 bytes / SHA-256 8d576f1d50bcbfb123cb09682a4fbac53cb018a3cd369021c38d69866849781c. This integrates source data only; it enables no policy producer or capability.

Workflow owns the original automatic resulting-main Quality Cycle 42116435661, attempt 1, actual graph/count/coverage attribution and later incorporated-branch cleanup. The run is in progress; no failed/pending result is called passed. No manual full dispatch, native/installed operation or release was performed.

Server still owns exact prepared-local HTTP/refusal/payload-resolution binding; the local companion remains an unfrozen source proposal. Existing v1, SDK zero-tail and completed external-payload behavior are unchanged. Central #219 remains open for those implementation/adoption obligations.

@rmcdaniel
rmcdaniel deleted the workflow/219-retry-policy-vectors branch November 5, 2026 22:17
@rmcdaniel

Copy link
Copy Markdown
Member Author

Original automatic main Quality Cycle 42116435661, attempt 1 completed SUCCESS on exact 8db66b9f0ec683386c4b4cf698c5e38e46d44536 / tree 3fec13920ae954e89dd6a04bf3901433b1c8b710: 20 successful jobs / three PR-only skips, no rerun or extra full dispatch.

  • ECS and PHPStan passed.
  • Unit: 5,877 tests / 79,785 assertions, 49 skips and 15 notices, PHP 8.3.36 / PCOV 1.0.12, 138-package graph; actual 16:59.192, 700 MiB reported memory.
  • MySQL: 2,833 / 28,270 / three skips, no failures/errors; shard 0–3 exits zero in 806 / 473 / 671 / 572 seconds under the existing bound.
  • PostgreSQL: 2,833 / 27,875 / 32 skips, no failures/errors; shard exits zero in 450 / 585 / 541 / 570 seconds under the existing bound.
  • MariaDB, both current source-upgrade cells, regression corpus, tracing, contracts, build and Sonar passed.
  • Coverage: 75,825 / 80,768 = 93.88%; 93.08% ratchet passed, 100% target unmet. Actual five-report unit+MySQL artifact 13456788800, ZIP SHA-256 9642e47e375466cae9bd241576c26b8da4c5b0d4ea2074ee02256c68a89cc31e.

The canonical artifact remains the exact original 54 IDs / 46,456 bytes / SHA-256 8d576f1d50bcbfb123cb09682a4fbac53cb018a3cd369021c38d69866849781c. The incorporated remote author branch was deleted normally after exact-head, ancestry, dependent-PR and active-run checks; remote absence is verified. History and original source reviews remain reachable.

This completes canonical source adoption and its Quality Cycle. Local companion HTTP mapping/freeze, v2 writers/role advertisement, backend/native/SDK adoption and release remain separate work on central #219 / Server #1034. No executing v2 result is inferred from this source pass.

@rmcdaniel

Copy link
Copy Markdown
Member Author

No remaining Core source finding in the declared local-v2 proposal. Exact reviewed Server WIP is e974e28550ab5d06a26ee01ad1c5a95973327920, tree c05e1ac4; tests/Fixtures/contracts/activity-retry-policy/prepared-local.v2.json is 92,522 bytes / 133 unique IDs / SHA-256 f36e57921a42c2afa2b65415b18438247e7c37dc3f7d0a3ffa9716f317d91b11.

I independently checked duplicate-key/ID closure, the narrow successor diffs, the original 91 local rows and unchanged canonical 54 / remote 37 authorities, all five declared controller/protocol/native source blobs, and 30 explicit HTTP family/status/reason projections. These are bounded source/data comparisons, not an executing HTTP/native adapter result.

The completed mapping reconciles:

  • The proposed ten-key snapshot and finite new-route bounds; the shared 1,024-entry flattened wire bound versus at most 1,023 authoring-generated retry positions; no inferred truncation or exact-length wire rule.
  • Failed-only supplied override, engine-owned retry disposition, cap/deadline terminal candidates without fabricated retry tasks/events/attempts, actual timeout provenance, policy retry for eligible start-to-close/heartbeat timeouts, and immutable committed clock/deadline/late-receipt decisions.
  • Conjunctive prepared-role/capability/local-contract-2/snapshot-2/original-claim authority. Override presence is only untrusted feature intent. Early pure validation is scoped to that supplied member; no-member legacy lookup/refusal precedence is preserved, and the post-mode pure phase does not claim zero preceding authority reads.
  • Override value/failed-only placement refusal is the fixed 422 family; other malformed closed reports use existing 409 invalid_local_activity_outcome. Paired cases now bind their precedence explicitly without a new response alias.
  • Nine exact proposed HTTP families, independent identity/manifest/header binding and the non-authorizing MA== cursor, with generic/partial/contradictory/transport failures never granting a callback retry.
  • Pure validation performs no payload/storage/callback/clock effects. Current completed external-reference resolution remains a separate existing contract, without a new fetch-free completion guarantee.
  • The actual body-producing payload_limits.rs blob d0bfeef89cd9a280c9e478ee62125fbaa01ef78d binds the malformed JSON diagnostic: three ASCII lexemes use Syntax error; the raw FF string case uses Malformed UTF-8 characters, possibly incorrectly encoded. This is fixed case data, never learned from the response.

This exact source packet is ready for joint source freeze/review and implementation planning. The new-route limits and future templates remain proposals until the corresponding source/adoption decisions; native still has no implemented prepared role and advertises no such support. No writer, SDK adoption, global protocol bump, native/database/installed test or release is enabled. Existing v1 clocks, unanchored batches, null/unlimited legacy budgets and recorded zero-tail history remain unchanged.

Workflow owns Core source integration and future guarded implementation; Server owns the companion's normal PR carry/qualification and native implementation plan. General retains source/adoption order and every distinct operating/publication decision. The canonical source itself is now main-qualified at 8db66b9f in the actual full-cycle receipt.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant