Skip to content

Preserve explicitly empty worker command contracts through admission #436

Open

Description

@rmcdaniel

Current delivery status

The PHP correction is merged in #464, exact main 35cd3642825488e5b193260155889e5c4257cd95, tree 62b974c52d900f85c25bd9551dfe1bbe1b1bd1ea. Candidate and fresh-main feature, performance, HTTP topology and boundary checks pass. Final source handoff.

Server 2.8.2 / Helm 0.1.170 is published and normally installed. Three fresh published-image HTTP originals pass explicit empty, named and omitted legacy declarations with unchanged histories. Sample #224 is delivered, including normal native amd64/arm64 published-image acceptance.

The additional numeric-string name case is corrected in merged #466, exact source b49a4f9ebed76e0538e9f6bfa48ba9f1de273ed3, reviewed tree ccce4f49e609cda0b87b8197fa2b6f89d46bbb76. Candidate/fresh-main checks and four fresh source HTTP originals pass. Literal 0 also required the separate Workflow #799 correction, delivered in compatible Workflow 2.5.22. The original affected 2.8.3 observations remain failed.

PHP publication and installed acceptance are complete. The final current Server 2.8.5 image, source f7d1bfc7 and immutable index f6a6507a, passes four normally installed Python 2.5.15 name/declaration controls (0, 17, 017, ordinary), malformed-registration refusals and a separate genuine literal-0 queued timer completion with exact int64/null/Unicode output. Its earlier immutable-image consumer remains a separate result. Sample #225 and documentation follow-through are delivered.

Native/shared acceptance remains separately owned under #325 and does not inherit these PHP passes. The native registration/history source checkpoint explicitly leaves selected-build routing, bounded observation and numeric-name acceptance unqualified. This issue remains open for the complete native/shared contract, not pending PHP publication. No frozen actor or original history is changed.

Original problem

An explicitly empty worker command contract is discarded during registration, so workflows started after successful registration still have an unavailable command-contract snapshot. Operators cannot distinguish a workflow that declares no commands from a run with missing declarations.

Provider-free reproduction: published Server 2.6.1, normal Python SDK 2.5.13, default protocol 1.20. One actual Worker registers an empty workflow and another with query current. Start fresh originals after its successful registration barrier. The named workflow's bounded observation reports source=durable_history and query current. The empty workflow instead reports source=unavailable, backfill_needed=true, backfill_available=false.

The normally installed Python worker builds explicit empty queries, query_contracts, signals, signal_contracts, updates, update_contracts and update_validators lists. The exact published WorkerController::workflowCommandContract returns null when the six command/contract lists are empty. Waterline's real PHP observation agrees with the native observation. This is a backend retention gap, separate from Waterline #181's recovery wording.

Proposed contract and acceptance

Settle the shared observable contract before changing either implementation:

  • Preserve an explicitly supplied valid empty contract through registration and original admission. Its durable empty snapshot should be distinguishable from unavailable metadata.
  • Keep omitted legacy metadata unavailable. Do not invent an empty declaration for an old run or rewrite it from a later worker registration.
  • Compare absent, explicitly empty and named contracts before/after registration, including namespace/type/build matching and malformed input refusal.
  • Qualify PHP Server and the reserved Rust/shared implementation against the agreed cases. Preserve existing frozen fixture outcomes.

The initial four-run baseline preceded the correction above; its readable findings are preserved. Completed local raw data, namespaces, roles and resources are removed. That original observation does not establish a rewrite failure. Coordination with Server #325 is required for the shared fixture boundary.

Activity

  1. added
    kind:defectA public product behavior is incorrect
    priority:P2Normal-priority product work
    status:readyReady for implementation
    on Oct 13, 2026
  2. rmcdaniel commented on Oct 15, 2026

    @rmcdaniel
    MemberAuthor

    PHP contract disposition before implementation

    Read-only inspection of published 2.8.1 / ed80351 confirms the same empty-contract discard in WorkerController::workflowCommandContract(). No current-release HTTP reproduction or correction is claimed yet.

    The portable distinction is an explicit valid declaration for the selected workflow type versus an absent declaration. A valid contract with no commands is still a declaration. The admission snapshot should be durable and empty, with source=durable_history; it must not become unavailable merely because the normalized lists are empty.

    • Missing legacy metadata stays unavailable. Null or malformed input must not be converted into an authoritative empty contract.
    • Preserve existing namespace, task queue, workflow type and selected build/cohort matching. An unrelated registration cannot supply the snapshot.
    • Persist the selected original admission snapshot. Later registrations and backfill must not rewrite it or fabricate declarations for historical runs.
    • Cover omitted, explicit empty and named contracts; unsupported/mismatched types/builds; malformed declarations; and unchanged original snapshots after registration changes. Qualify the current published HTTP baseline before the corrected source, then the normally installed release and consumer observation.

    General owns the scoped PHP correction and publication. Native/shared acceptance remains separately coordinated with #325. No SDK change, new protocol floor, frozen tuple rewrite or native capability is implied. Implementation starts after the PHP source window is coordinated; current Sample #223 release-consumer gates retain priority.

  3. rmcdaniel commented on Oct 15, 2026

    @rmcdaniel
    MemberAuthor

    Confirmed again on normally published Server 2.8.1 / ed80351, immutable image index sha256:4d10f1ac080d5530c9c73e5137304ed6a07d124d2e115143874cb2061e20e8c9, loaded Workflow 2.5.21, using normal Python SDK 2.5.15 and an isolated SQLite database.

    One actual Python Worker registers three workflow types and reaches the registration barrier before admission. Its normal declaration builder supplies all seven explicit empty lists for the empty workflow. A narrow Client decorator omits only the third workflow's per-type declaration for the legacy control. All three originals reach their own waiting timer through the real worker.

    Original Run Bounded observation
    Explicit empty 01m4yy5za2x05qwwmtkg1neesp source=unavailable, backfill_needed=true, backfill_available=false
    Named query current 01m4yy60a7q85n8cgy70qr72j7 source=durable_history, query/contract current, no backfill needed
    Omitted declaration 01m4yy60xyr6cpypyfs11bh2q2 unavailable, as required for missing legacy metadata

    The worker drains normally, all three originals are explicitly terminated, and the isolated namespace is deleted. This reproduces the current PHP admission/observation gap; no corrected source, native comparison, SDK defect or frozen tuple change is claimed. The agreed correction must preserve the distinction between explicit empty and omitted metadata without inventing historical snapshots.

  4. rmcdaniel commented on Oct 15, 2026

    @rmcdaniel
    MemberAuthor

    The PHP source correction is fully qualified on exact main 35cd3642825488e5b193260155889e5c4257cd95, tree 62b974c52d900f85c25bd9551dfe1bbe1b1bd1ea, identical to reviewed #464 candidate 4d296ab8.

    The merged remote head is deleted and verified absent. The source is ready for separately qualified native/shared integration by its owner. No pass is carried to a combined tree.

    Next is the agreed compatible Server 2.8.2 / Helm 0.1.170 release: standard generated metadata only, including Composer product-train/content-hash without changing any package or reference. Publication, installed-image/consumer acceptance and native/shared follow-through remain pending, so #436 stays open.

  5. rmcdaniel commented on Oct 15, 2026

    @rmcdaniel
    MemberAuthor

    Native follow-through begins as a separate narrow source slice under #325: validate/normalize per-workflow registration entries before mutation, preserve an explicit empty declaration as empty lists in the original WorkflowStarted snapshot, keep omitted/legacy metadata unavailable, and preserve original snapshots across registration changes. This uses the settled PHP boundary and separate source branch; PHP282 publication does not qualify native. Native build-rollout routing, selected-cohort matching and the bounded observation route remain explicit additional gates, not inferred from this registration/history slice. No PHP/SDK/version/shared frozen changes. Focused counterfactual and current-code controls will precede any adoption; the admitted #458/#463 executions remain untouched.

  6. added
    status:in-progressApproved work is actively being implemented or validated
    and removed
    status:readyReady for implementation
    on Oct 15, 2026
  7. rmcdaniel commented on Oct 15, 2026

    @rmcdaniel
    MemberAuthor

    Additional workflow-name boundary

    A separate read-only control on exact published-source WorkerController 7e215d296da8a4cebcb94bcc7b14f1af61c08a43 found a remaining numeric-string map-key case. PHP decodes the JSON object {"17":{}} with an integer array key. workflowCommandContracts() skips that entry because it requires a string key. The named control {"example":{}} retains its explicit empty declaration. The actual registration/start string-validation rules accept workflow type "17".

    This control invokes the exact source helper with the normal application validator. It does not establish an actual published-image HTTP admission result for numeric names yet. The three independently qualified nonnumeric Server 2.8.2 originals remain passed.

    General owns the small PHP follow-through after the active Sample #224 release-consumer gate. Verify the published HTTP boundary first, then cover numeric-string names, malformed entries and immutable original snapshots in the existing admission regressions. Native map handling is separately coordinated with its owner. No published tag, history, deadline or frozen fixture is changed.

  8. rmcdaniel commented on Oct 15, 2026

    @rmcdaniel
    MemberAuthor

    The numeric-name case is now reproduced through actual HTTP on unmodified published Server 2.8.2, immutable index sha256:91a5bb87dbf280c1966693af3eb1d13eac6912d88fd82ae2095f05830a38dab0, with normal Python SDK 2.5.15 and one actual Worker registration.

    Workflow type Declaration Original run Observation
    17 Explicit empty lists 01m4z3ebhqy4qqnapedsy9kr85 unavailable, backfill needed
    0 Named query current 01m4z3ec1g2rp027pn9614e5gz unavailable, query missing
    017 Explicit empty lists 01m4z3ec6jymzte63pb3c4x6ew durable empty declaration
    numeric.control Named query current 01m4z3ecg4agbwxt840aepexya durable declaration, query retained

    All four admissions return 201. Reading observation leaves each original WorkflowStarted event unchanged. The Worker drains normally with deregistration 200, all four originals terminate and namespace deletion returns 200. The API receives explicit SIGTERM and exits 0/no OOM, then its database/container/network are removed.

    This confirms the narrow map-key loss in the current PHP registration path. It does not invalidate the earlier nonnumeric release controls or establish a native defect. The correction will preserve numeric-string workflow names, validate their entries before registration and retain their definition fingerprints. Focused regressions and an exact-parent counterfactual precede the source handoff. No existing history, tuple, schema or deadline changes.

  9. rmcdaniel commented on Oct 15, 2026

    @rmcdaniel
    MemberAuthor

    Native registration/history checkpoint for #436: source de19a53b61997f5d57dc679693f29b772f86af43, whole tree 2804607e50513053a2f081eeccb99f712be25f31, now passes all 128 execution tests independently on SQLite, MySQL 8.4 and PostgreSQL 17. SQLite also passes 75 library tests with the existing 18 explicit ignores. The three new declaration regressions fail on the original source and pass on each database.

    Explicit valid empty declarations remain distinguishable from omitted/unknown metadata, malformed declarations refuse before registration mutation, later registration preserves original history, and omitted re-registration preserves the known future declaration. This remains a registration/history slice: selected build-cohort routing, bounded observation and numeric workflow-name acceptance are not qualified here. General owns the separate PHP numeric-name correction.

    This combined source also contains the separately recorded named-timer cancellation bind correction: its strengthened original-timer regression fails on the prior source across all three databases and passes after binding the selected run's namespace. The earlier 127/128 SQLite execution and original hosted failures remain failed; these fresh results do not replace them or establish a historical PHP cause. Hosted combined qualification is still ahead.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind:defectA public product behavior is incorrectpriority:P2Normal-priority product workstatus:in-progressApproved work is actively being implemented or validated

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions