Build & ship · Step 3
Package
A typed manifest declares what your package needs and what it provides, so it moves as one signed unit rather than a folder of loose files someone has to trust by hand.
Packaging turns a finished package into one signed, movable unit instead of a folder of loose files. The manifest declares the package’s identity, what it needs, what it provides, and who may install it, and packaging hashes the code, its assets and its dependency pins into a signed sidecar record. NAOMS checks that hash before loading the package, so a change made after signing is caught.
What a person notices
Installing a package is one step, with no manual file copy involved. What it will be allowed to do is shown before it runs.
If a package has been altered since it was signed, the platform refuses to load it and records that refusal, rather than silently running the altered code.
A package can be removed cleanly, because everything it touches was declared up front.
What you do as a developer
Every package exports one typed manifest constant. NAOMS reads it before any of your code is allowed to run, so the manifest itself is the contract that gets enforced.
Declare identity
An id, a name, a version and a category. The id becomes a public contract you should never rename once you've shipped it. Other packages and the routing layer refer to it by that name.
Declare what it needs
Which parts of the shared history it reads or writes, with what access, and which events it records there. Anything not declared here is refused automatically when your code tries to reach for it.
Declare what it provides
Its callable operations and the kinds of data records it writes. One operation declaration becomes a typed method, a live message type, an agent tool, and a terminal command, all at once.
Declare who may install it
A minimum trust level a person needs before they're offered the install at all.
Sign it as one unit
Packaging computes a hash over your package's code, its declared assets, and its dependency pins, and signs that into a sidecar record alongside the manifest. The platform recomputes and checks that hash before it will load your package, so tampering after signing is caught immediately.
The manifest and the signed sidecar are two different things doing two different jobs: the manifest is what your package declares about itself; the signed sidecar is proof that what's running is what was actually signed.
A trimmed manifest shape. The field names are real; the id is a placeholder.
// A package manifest is one typed constant. The daemon reads it to decide // what your package is allowed to do before any of its code runs. export const MANIFEST: NaomsFeatureManifest = { id: "hello-package", name: "Hello Package", version: "0.1.0", category: "productivity", // What this package is allowed to read or write, and who may install it. capabilities: [{ name: "hello.read", trustLevel: "connected" }], permissions: { minTrustLevel: "connected", domainScopable: false }, // One operation here becomes a typed method AND a live message type AND // an agent tool AND a terminal command -- one declaration, four surfaces. operations: [{ name: "lookup", description: "Look something up.", version: 1, method: "ws_message", messageType: "hello_package.lookup", pattern: "send", returns: "HelloResult", }], chainTypes: [], graphTypes: [], };
How it relates to other steps
Build
The manifest is what your handlers are checked against while you're still writing them; packaging is what turns the finished result into one signed, movable unit.
Test
Your package's tests run against the same manifest declarations, so a test can't quietly pass against access the manifest never actually granted.
Distribute
What gets uploaded to a Hive or listed on a hub is this signed unit only, never your raw source folder.