Skip to content

id(publications): Registry::load restores records publish() would refuse — duplicates, empty worlds, non-canonical shadow paths #5179

Closed

Description

@dezren39

id(publications): Registry::load restores records publish() would refuse — duplicates, empty worlds, non-canonical shadow paths

Summary

Registry::publish (pkgs/id/src/publications.rs:195) enforces the registry's invariants: non-empty world name (:200), canonical mount path via canonicalize_mount_path (:204), one publication per placement (:207), and the #2147 shadow-acknowledgement gate (:216). Registry::load (:297) enforces none of them — it is a bare serde_json::from_str, so a persisted publications.json that is syntactically valid but semantically invalid is restored verbatim at boot.

That breaks the module's own stated contract: the module doc (publications.rs:40-49) and the boot call site (pkgs/id/src/commands/serve.rs, the #2147 slice-1 comment) both say a registry that cannot be honoured must fail loudly rather than silently restore the wrong set. Today only unparseable JSON fails; parseable-but-invalid records sail through.

Verified behaviour (laptop probe, main 464467b)

Probe crate ~/git/fleet/probe-2026-11-03-laneB-pubload (path-dep on pkgs/id, Registry public API only):

  • Control — publish() refuses all three: empty world name, non-canonical path //world, duplicate placement /arena.
  • A hand-written publications.json containing exactly those violations (duplicate /arena mounts for worlds a+b, an empty-world mount, an unacknowledged //world mount, an unacknowledged /api/ trailing-slash mount) loads with Ok and restores all 5 records.
  • boot_warnings(KNOWN_EXPLORER_ROUTES) on the loaded registry returns 2 warnings, and the one for the //world mount names the wrong route: shadows() (publications.rs:151) compares the raw stored string, so //world fails to match the /world route it denotes and instead matches route / via the "//" prefix — the warning claims the mount shadows /. The id(serve): dynamic publish/unpublish — bind and unbind programs and pages to ports, interfaces, and paths at runtime #2147 duty is to warn loudly naming the shadowed route; a non-canonical spelling makes the warning name a route the mount does not denote (and any future route-matching at apply time faces the same raw-string mismatch).
  • unpublish canonicalises its argument (publications.rs:239), so a stored /api/ record can never be removed by naming /api — the lookup compares canonical /api against stored /api/ and reports "nothing published at path /api" (probe: unpublish(/api) against the loaded registry errors).

Why it matters

Acceptance criteria

Activity

  1. added
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    source/creatorFiled by the new-issue-creator job
    task/small-fixQueue packet kind: bounded fix with reproduction and targeted tests
    queue/queuedHas a queued task in the Supabase agent queue
    priority/normalOrdinary priority (the default)
    app/idPackage/app: id (pkgs/ or apps/ in this repo)
    on Nov 3, 2026
  2. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · filed

  3. added
    queue/claimedQueue worker lifecycle state
    work/assignedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 3, 2026
  4. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    agent-note:v1
    event: picked_up
    task: 8859 (repo-health-code-pilot; worker repo-worker-code; lane code-c)
    state: claimed; implementing Registry::load validation in a laptop worktree on branch queue/8859-5179-publications-load-validation.

  5. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    agent-note:v1
    event: parked
    task: 8859 (repo-health-code-pilot; worker repo-worker-code; lane code-c)
    state: implementation complete, PR open, parked on Codex review.

    PR: #5190 (branch queue/8859-5179-publications-load-validation, commit 97bbf55, pkgs/id/src/publications.rs only, +192/-12)

    • load() validates the persisted set (validate_persisted): empty world / non-canonical stored mount path / duplicate placement fails naming the file.
    • boot_warnings shadow-matches on the normalised spelling (stored //world now names route /world).
    • unpublish compares normalised spellings on both sides (canonical /api removes a stored /api/).
      Tests: cargo test --lib publications on the laptop — 14 passed, 0 failed (9 pre-existing + 5 new load/boot-warning/unpublish cases).

    Parked because: Codex review on PR #5190 still running at park time (and the production-line-limit check pending). Resume: read Codex findings, disposition each (fix or reply), merge under standing criteria, close out task 8859.

  6. added
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    status/parkedDeliberately paused with a recorded resume condition
    queue/claimedQueue worker lifecycle state
    and removed
    queue/claimedQueue worker lifecycle state
    status/parkedDeliberately paused with a recorded resume condition
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    on Nov 3, 2026
  7. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done

  8. dezren39 commented on Nov 4, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done

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

    app/idPackage/app: id (pkgs/ or apps/ in this repo)kind/bugSomething isn't working (prefixed form of the classic bug label)priority/normalOrdinary priority (the default)source/creatorFiled by the new-issue-creator jobtask/small-fixQueue packet kind: bounded fix with reproduction and targeted tests

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions