Appearance
Haptique Kitchen Developer Wiki
Goal
This wiki is the execution-ready reference for Haptique Kitchen driver authors and maintainers. A third-party developer should be able to move from source to a valid registry submission without guessing at schema details, packaging rules, or review criteria. A HOS maintainer should be able to rebuild, sign, validate, and review an installable package using the same page.
Architecture
The authoritative reference lives in two flat Markdown files under wiki/docs/:
- Haptique Kitchen — end-to-end lifecycle, publication, signing, registry PR review, and safety boundaries
- Driver Manifest — canonical manifest schema and field reference
Tech stack
- Markdown (GFM)
- Git-backed wiki review
- npm workspaces in the HOS monorepo
- Public registry validation from a checkout of
haptique-kitchen-registry
Registry contract
- Schema revision:
1.1 - Schema hash:
bfe719aa3a6dcb8afd279f87180dfd489ebd7a2e - Validation command:
npm ci && npm run validate
Run the validation command from a checkout of the public registry repository, not from the HOS monorepo.
Source-only vs installable
Kitchen supports two publication tracks:
Source-only
A source-only package is the developer-owned source repository plus the registry metadata needed for review. It includes:
- manifest
- driver code
- tests
- README
A source-only package does not include an artifact block.
Installable
An installable package is the maintainer-published ZIP asset referenced from the registry entry. It adds the signed release artifact required for local installation.
Installable packages must provide:
artifact.downloadUrlartifact.sha256artifact.signatureartifact.signingKeyId
Public registry location
The public registry is:
text
https://github.com/Cantata-Communication-Solutions/haptique-kitchen-registryThe generated catalog is read from:
text
https://raw.githubusercontent.com/Cantata-Communication-Solutions/haptique-kitchen-registry/main/catalog/index.jsonThe registry stores metadata; source code and release assets stay in the developer-owned repository until a maintainer promotes an installable package.
Source-only developer path
Follow this path when authoring a new driver from source:
- Create the manifest using the canonical fields in Driver Manifest.
- Write the driver code.
- Write tests in the source repository.
- Write the README in the source repository.
- Run the source repository's declared build and test commands.
- Optionally run the HOS builder validation gate with
npm run test --workspace=apps/mcp-driver-builder.
The builder gate checks manifest shape, ZIP safety, and driver compatibility before a package becomes candidate material for the registry.
Required manifest pieces for source-only submission:
keynameversiondriverType(python | lua | javascript)driverFile(.py | .lua | .js)propertiesioenvMapcommands
Manifest field rules:
properties.typemust be one ofstring | number | boolean | selectproperties.defaultValueis optionalio.inputs[]andio.outputs[]each requirekey,label, andsignalsignalmust be one ofaudio | video | control | network | powercommands[]must include at leastkeyandlabel
Source-only packages omit the artifact block entirely.
Example source-only registry entry:
json
{
"id": "com.example.audio-mixer",
"name": "Audio Mixer Driver",
"type": "driver",
"version": "1.2.0",
"summary": "Professional audio mixer control for Haptique",
"description": "Controls volume, mute, input source selection, and status reporting for a sample audio mixer.",
"author": "Example Community",
"trustLevel": "community",
"tags": ["audio", "mixer"],
"deviceClass": "audio-interface",
"capabilities": ["audio.mixing", "audio.volume", "audio.mute"],
"permissions": ["audio.output", "audio.input", "network.status"],
"source": {
"repo": "https://github.com/example-audio/audio-mixer-driver"
},
"compatibility": {
"haptiqueOS": ">=2.0.0"
},
"driver": {
"key": "EXAMPLE_AUDIO_MIXER",
"logicalDeviceUi": {
"defaultLayout": "grid",
"primaryControls": ["volume", "mute", "inputSource"]
}
}
}Maintainer rebuild, signing, and release
When a source-only package is accepted for publication, a maintainer rebuilds the installable ZIP from the reviewed source commit.
Review checklist
Before publishing, confirm:
- source repository is public
- manifest and runtime file match the reviewed commit
- permissions are explicit and minimal
- compatibility is declared
- logical device UI hints are present when required by the package policy
- no protected-core or Fleet-owned functionality is being moved into Kitchen
Deterministic rebuild
The maintainer rebuild uses the reviewed source commit and produces a normalized ZIP with:
- fixed timestamps at
1980-01-01 00:00:00 - compression level 9
- relative paths only
- no path traversal
- no NUL bytes
The ZIP packaging rules are strict:
- exactly one root
*.driver.json - exactly one root runtime file (
.py,.lua, or.js) - optional root
requirements.txtfor Python packages - no README or test files in the runtime ZIP
__MACOSX,.DS_Store, and AppleDouble._*metadata are treated as ignored metadata during inspection
The HOS builder gate should be rerun on the rebuilt package with npm run test --workspace=apps/mcp-driver-builder.
Signing
Installable packages are signed with the haptique-app-v1 Ed25519 scheme.
The signature payload is the exact newline-delimited string used by the builder:
text
haptique-app-v1
id:<id>
type:<type>
version:<version>
sha256:<sha256>Signing policy:
- production signing key ID:
haptique-shell-ed25519-2026-07 - the private key stays in the secure signer / Keychain only
- the private key must not appear in the repo, CI logs, or contributor workflows
Release asset
The installable registry entry points at a public GitHub Release ZIP.
The maintainer must verify that:
- the download URL is public and unauthenticated
- the bytes match the reviewed source commit
- the SHA256 in the registry entry matches the actual ZIP bytes
- the signature matches the SHA256 and the signing key ID
Policy note: whether the release must be non-draft and non-prerelease should be confirmed against the release policy before publication.
Installable registry entry example
json
{
"id": "com.example.audio-mixer",
"name": "Audio Mixer Driver",
"type": "driver",
"version": "1.2.0",
"summary": "Professional audio mixer control for Haptique",
"description": "Controls volume, mute, input source selection, and status reporting for a sample audio mixer.",
"author": "Example Community",
"trustLevel": "community",
"tags": ["audio", "mixer"],
"deviceClass": "audio-interface",
"capabilities": ["audio.mixing", "audio.volume", "audio.mute"],
"permissions": ["audio.output", "audio.input", "network.status"],
"source": {
"repo": "https://github.com/example-audio/audio-mixer-driver"
},
"artifact": {
"downloadUrl": "https://github.com/example-audio/audio-mixer-driver/releases/download/v1.2.0/EXAMPLE_AUDIO_MIXER-1.2.0.zip",
"sha256": "0000000000000000000000000000000000000000000000000000000000000000",
"signature": "AAAAfakesignatureAAAAfakesignatureAAAAfakesignatureAAAAfakesignatureAAA=",
"signingKeyId": "haptique-shell-ed25519-2026-07"
},
"compatibility": {
"haptiqueOS": ">=2.0.0"
},
"driver": {
"key": "EXAMPLE_AUDIO_MIXER",
"logicalDeviceUi": {
"defaultLayout": "grid",
"primaryControls": ["volume", "mute", "inputSource"]
}
}
}Registry PR and approval flow
Registry packages live at paths such as:
text
packages/drivers/<id>.jsonA valid registry entry may include only the fields allowed by the public registry contract:
idnametypeversionsummarydescriptionauthortrustLeveltagsdeviceClasscapabilitiespermissionssourceartifactcompatibilitydriverdashboardModuleshellPackagekitchen
Review flow:
- Contributor opens a PR with
<id>.json. - The registry checkout runs
npm ci && npm run validate. - Maintainer reviews the entry against the contract, the source repository, and the package policy.
- If the package is installable, the artifact block must be present and valid.
- If the package is source-only, the artifact block stays omitted.
- Merge happens only after the registry validation and maintainer review both pass.
Policy requirements for Haptique review:
- reverse-DNS
id - public source repository
- explicit
permissions compatibility.haptiqueOSdriver.keylogicalDeviceUi.defaultLayoutlogicalDeviceUi.primaryControls
Lifecycle safety boundaries
Kitchen is not the boundary for HOS core, Fleet, or OTA ownership.
Kitchen does not install protected-core payloads. Protected-core payloads are rejected before activation.
Built-in packages cannot be uninstalled through Kitchen.
Uninstall and rollback require removing active integrations that use the driver first.
Fleet-managed drivers remain outside Kitchen scope, and OTA updates remain an HOS release boundary rather than a community path.
If activation fails, the installer can quarantine the attempted activation and roll back the previous working package.
Troubleshooting
ZIP rejected because it contains protected-core payload
- Symptom: install fails with a protected-core rejection.
- Probable cause: the ZIP contains payload classified as protected core.
- Fix: remove protected-core content and publish only community-appropriate driver files.
ZIP rejected because it contains too many or too few runtime files
- Symptom: install fails during ZIP inspection.
- Probable cause: the package has more than one manifest, more than one runtime source file, or unexpected runtime content.
- Fix: keep exactly one root
*.driver.json, one root.py/.lua/.jsfile, and optional Pythonrequirements.txtonly.
Signature verification fails
- Symptom: signature validation fails.
- Probable cause: wrong key ID, hash mismatch, or malformed base64 signature.
- Fix: rebuild the ZIP deterministically, recompute SHA256, and sign the exact payload format shown above.
npm ci && npm run validate fails in the registry checkout
- Symptom: registry CI validation fails.
- Probable cause: dependency install problems or schema validation errors.
- Fix: run the command from the public registry checkout and correct the JSON entry to match the contract.
Builder validation rejects the manifest
- Symptom:
npm run test --workspace=apps/mcp-driver-builderreports schema errors. - Probable cause: stale field names, wrong
driverFileextension, invaliddriverType, or malformedio/commands/propertiesdata. - Fix: correct the manifest to use canonical field names and supported values.
Installer quarantines activation
- Symptom: install starts but ends in quarantine or rollback.
- Probable cause: the driver was activated but not found in the catalog or failed runtime initialization.
- Fix: check the manifest fields, ensure the driver is present in the catalog, and remove active integrations before retrying rollback or uninstall.
Final checklist
- [ ] Manifest uses canonical field names:
key,defaultValue,string,signal - [ ]
driverTypeis one ofpython | lua | javascript - [ ]
driverFileextension matchesdriverType - [ ] All property entries use
typevalues fromstring | number | boolean | select - [ ] All property entries have valid
defaultValuevalues where present - [ ] All IO port entries have valid
signalvalues fromaudio | video | control | network | power - [ ]
envMapcontains only string-to-string mappings - [ ]
commandsinclude at leastkeyandlabel - [ ] Source repository is public and referenced in
source.repo - [ ] Package id uses reverse-DNS form
- [ ]
compatibility.haptiqueOSis defined - [ ]
permissionsare declared - [ ]
npm ci && npm run validatepasses in the public registry checkout - [ ] Installable packages include
artifact.downloadUrl,artifact.sha256,artifact.signature, andartifact.signingKeyId - [ ] ZIP contains exactly one root
*.driver.json - [ ] ZIP contains exactly one root runtime file
- [ ] ZIP does not include
README, tests, or other runtime-unsupported files - [ ] ZIP does not rely on
__MACOSX,.DS_Store, or AppleDouble metadata - [ ] Signature payload uses the exact newline-delimited format
- [ ]
logicalDeviceUi.defaultLayoutandlogicalDeviceUi.primaryControlsare present when required by package policy - [ ] Active integrations are removed before uninstalling or rolling back