Skip to content

Preserve manifest authority and defer resolver effects #8

Description

@sounkou-bioinfo

Observed authority drift

At commit f3475cf000a379732d37cfb317754dec5ef2b4db, registry admission mutates several global environments with assign() and silently replaces manifest, resource, resolver, term-set, and operation identifiers.

This allows an already registered resource to acquire a resolver version it never declared. Executed reproduction:

rho_register_manifest(reg, manifest_with_resolver("shared", "1.0", resource = "r1"))
rho_bind_resolver_impl(reg, "shared", impl)
rho_register_manifest(reg, manifest_with_resolver("shared", "2.0", resource = "r2"))
receipt <- rho_await(rho_resolve_resource(reg, "r1"), timeout = 1000)

Observed:

resource=r1 resolver_version=2.0

The receipt for r1 therefore reports a resolver spec introduced by another manifest after r1 was admitted. The registry no longer preserves the declaration that is supposed to authorize and explain resolution.

There is a second effect-contract failure in the same path: rho_resolve_resource() calls impl(resource, ctx) synchronously before wrapping its output. A resolver containing a one-second blocking effect made the public call itself take 1.01 seconds before returning a RhoTask.

Required contract

  1. Validate a complete manifest admission before mutating registry state.
  2. Reject duplicate identifiers within a manifest and collisions with admitted manifests unless replacement is an explicit typed operation.
  3. Preserve manifest identity, resolver identity/version, and resource declaration together so a later registration cannot rewrite an earlier receipt.
  4. Define replacement lineage and rebinding semantics explicitly; do not leave existing resources attached accidentally to a new spec or old implementation.
  5. Start resolver invocation behind the returned task. A selected execution binding owns placement and cancellation; rho_resolve_resource() must return before resolver effects run.
  6. Inject receipt time through the resolution context rather than discovering a semantic clock inside receipt construction.
  7. Make failed admission atomic: no partial manifest/resource/resolver entries remain.

Acceptance evidence

  • same-manifest duplicate identifiers fail before mutation;
  • cross-manifest resource/resolver/operation collisions fail closed;
  • the reproduced r1 receipt remains bound to shared@1.0;
  • an explicitly replaced resolver records old and new authority and has tested behavior for existing resources;
  • a blocking fixture proves rho_resolve_resource() returns a task promptly;
  • cancellation and resolver failure remain typed;
  • deterministic-clock and partial-admission fixtures pass.

Prepared in Pi using GPT Sol 5.6 High; both reproductions were executed locally against the stated commit.

Activity

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

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions