Skip to content

id(app_manifest): strict-shape parser accepts blank/garbage field values — empty name/version, zero-command CLI interface, non-hash module_hash #4063

Closed

Description

@dezren39

Problem

parse_app_manifest (pkgs/id/src/app_manifest.rs, main @ df3f836) is strict about manifest shape (#[serde(deny_unknown_fields)] on every struct, kebab-case app.id, folder/id match) but barely checks field values — and the checks it does have are applied inconsistently:

  • program.kind must be non-empty (app_manifest.rs:117-120) and program.module_hash must be non-empty after trim (:130-135) — but app.name and app.version have no checks at all: name = "" and version = "" are accepted.
  • The "at least one interface" rule (:110-113) checks interfaces.cli.is_some(), so [interfaces.cli] with commands = [] satisfies it — an app declaring no commands and no web surface passes the rule whose entire purpose is to require an interface.
  • capabilities.request entries are unchecked: blank strings and duplicates are accepted (request = ["", "", "../../etc"]).
  • program.module_hash = "not-a-hash" is accepted. The sibling world-apply manifest validates exactly this field: world_manifest.rs:229-235 requires 1..=64 plain hex digits. The app-packaging design (§2) presents the app manifest's module_hash as the same concept ("a prebuilt module", mutually exclusive with source, "same rule as the world-apply manifest").

Verified this run with a probe crate on the laptop compiling a sha256-identical copy of app_manifest.rs from main df3f836 (probe: ~/git/fleet/probe-appmanifest-20261101 on the laptop) — all of these were ACCEPTED: empty name+version; cli-only manifest with commands = []; module_hash = "not-a-hash"; capabilities.request = ["", "", "../../etc"].

Why it matters

Discovery (#2324) registers whatever passes this parser, and serve logs it as a discovered app. Blank names/versions, zero-command CLI interfaces, and non-hash "hashes" are exactly the authoring mistakes a strict v1 schema (the module's own doc comment: "The strict, version-one description of one unpacked app folder") exists to catch at the gate — instead they pass silently and will surface as broken display, unroutable apps, or unresolvable module references in the consumers (#2325, the pack step) that trust the gate.

Acceptance criteria

  • parse_app_manifest rejects empty/blank app.name and app.version.
  • An [interfaces.cli] section with an empty commands list does not satisfy the at-least-one-interface rule (and blank command names are rejected).
  • capabilities.request entries must be non-blank; duplicates are rejected or deduplicated with the rule documented in a test.
  • program.module_hash is validated to the same shape the world-apply manifest uses (hex digits, bounded length — see world_manifest.rs:229-235), or the divergence is explicitly documented in the module docs with a reason.
  • Unit tests cover each rejection above; the checked-in tic-tac-toe manifest and all existing tests still pass.

Activity

  1. added
    queue/queuedHas a queued task in the Supabase agent queue
    source/creatorFiled by the new-issue-creator job
    task/triageQueue packet kind: verify, reproduce, and route this item
    priority/lowNice to have; do when convenient
    app/idPackage/app: id (pkgs/ or apps/ in this repo)
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    effort/sSmall: expected under 2 hours of work
    on Nov 1, 2026
  2. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · filed

    • Agent: new-issue-creator job (new-issue-creator-code-a)
    • Session / ID: new-issue-creator-code-a run 2026-11-01 17:05 CST
    • Found via: filed this run
    • Task: Filed this issue — parse_app_manifest accepts blank/garbage field values (empty name/version, zero-command CLI interface, non-hash module_hash, blank capability requests), verified by a laptop probe crate against a sha256-identical copy of app_manifest.rs @ df3f836
    • Expectation: effort/s — triage confirms on current main, then routes the fix per the acceptance criteria
    • Links: queue packet enqueued this run (repo-health-code-pilot)
  3. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up for triage

  4. added
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 1, 2026
  5. 5 remaining items

  6. added
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    task/small-fixQueue packet kind: bounded fix with reproduction and targeted tests
    and removed
    work/assignedQueue worker lifecycle state
    task/triageQueue packet kind: verify, reproduce, and route this item
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 1, 2026
  7. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

  8. dezren39 commented on Nov 2, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done (fixed, merged)

  9. dezren39 commented on Nov 2, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · verification update (task 5971)

    • The default-features cargo test --lib app_manifest run on the laptop worktree finished after the merge of PR fix(id): validate app manifest field values (#4063) #4082: 8 passed, 0 failed in the real id lib target (1555 filtered out) — the full-target evidence now matches the probe-crate result recorded earlier. No follow-up needed.
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)effort/sSmall: expected under 2 hours of workkind/bugSomething isn't working (prefixed form of the classic bug label)priority/lowNice to have; do when convenientsource/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