Repository navigation
Description
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.kindmust be non-empty (app_manifest.rs:117-120) andprogram.module_hashmust be non-empty after trim (:130-135) — butapp.nameandapp.versionhave no checks at all:name = ""andversion = ""are accepted.- The "at least one interface" rule (:110-113) checks
interfaces.cli.is_some(), so[interfaces.cli]withcommands = []satisfies it — an app declaring no commands and no web surface passes the rule whose entire purpose is to require an interface. capabilities.requestentries 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-235requires 1..=64 plain hex digits. The app-packaging design (§2) presents the app manifest'smodule_hashas the same concept ("a prebuilt module", mutually exclusive withsource, "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_manifestrejects empty/blankapp.nameandapp.version. - An
[interfaces.cli]section with an emptycommandslist does not satisfy the at-least-one-interface rule (and blank command names are rejected). -
capabilities.requestentries must be non-blank; duplicates are rejected or deduplicated with the rule documented in a test. -
program.module_hashis validated to the same shape the world-apply manifest uses (hex digits, bounded length — seeworld_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
dezren39 commentedon Nov 1, 2026
🤖 Agent note · filed
dezren39 commentedon Nov 1, 2026
🤖 Agent note · picked up for triage
~/git/codeis onmain, clean, but diverged from origin (ahead 1, behind 25); I will preserve the local commit and inspect it before any sync.5 remaining items
dezren39 commentedon Nov 1, 2026
🤖 Agent note · picked up
pkgs/id/src/app_manifest.rs: nonblankapp.name/app.version, CLI interface requires ≥1 command with nonblank names,capabilities.requestentries nonblank with a documented duplicate rule,program.module_hashheld to theworld_manifest.rs1..=64 plain-hex rule — each with unit testsqueue/5971-4063-*+ PR, targeted tests verified, merge under the standing criteria (Codex gate included)fix(id): validate app manifest field values (#4063) (#4082)
dezren39 commentedon Nov 2, 2026
🤖 Agent note · done (fixed, merged)
78b2bd266(2026-11-02T00:02:44Z); issue id(app_manifest): strict-shape parser accepts blank/garbage field values — empty name/version, zero-command CLI interface, non-hash module_hash #4063 closed by the merge.parse_app_manifestnow rejects blankapp.name/app.version, an[interfaces.cli]section with zero commands or blank command names, blank or duplicatecapabilities.requestentries (duplicates rejected, not deduplicated — rule pinned by test), andprogram.module_hashvalues that are not 1..=64 plain hex digits (the world-apply manifest's rule).app_manifest.rs:cargo test8/8 pass (4 new tests + 4 pre-existing, incl. tic-tac-toe parsing/discovery). Codex review on PR fix(id): validate app manifest field values (#4063) #4082 completed on851e647b5with no findings. A default-featurescargo test --lib app_manifestrun was still compiling on the laptop at merge time; a--no-default-featureslib-test build fails pre-existing on main (E0432/E0433 feature-gated imports, unrelated).[interfaces.cli]fixtures exist only inapp_manifest.rs, so no other test surface constructs app manifests.queue/5971-4063-app-manifest-validation(deleted on merge) · laptop worktree~/git/fleet/5971-4063dezren39 commentedon Nov 2, 2026
🤖 Agent note · verification update (task 5971)
cargo test --lib app_manifestrun 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 realidlib target (1555 filtered out) — the full-target evidence now matches the probe-crate result recorded earlier. No follow-up needed.