FICCDocumentation
nightly prerelease / Version 0.3.0.dev1Project website
Reference library
Module development
On this page
  1. Extension boundary
  2. Development commands
  3. Make a package
  4. Build the language examples
  5. Build the broker examples
  6. UI and capabilities

Module SDK#

Policy packages have a separate signing and decision interface. They restrict authorization and are not ordinary workspace modules. Identity providers have a separate trusted interface for external authentication. They do not grant project permissions. Certificate providers adapt approved private authorities. The host owns contributor invitation, independent key approval and current connection authority. See contributor operations and the separate OpenSSH trust workflow. Executor providers supply approved container runtime behavior. Scheduler providers propose project job order and concurrency. Both are trusted installation packages with independent host enforcement. Inspection providers supply optional local scanner behavior; the host owns immutable file binding, dataset restrictions and exemptions.

FICC modules are runtime ZIP packages. The host owns the interface, credentials, permission checks and process sandbox. A module supplies a manifest, optional program files and declarative component data. The browser never runs module code.

Extension boundary#

Packages can combine the documented broker primitives and host components. Program files execute in separate sandboxed processes after explicit grants. Adding a package does not require a FICC rebuild.

The separate provider-adapter role permits packaged VM provider logic through registered host transports. It requires an explicit provider:admin grant for the exact archive digest and immutable profile. That grant permits administration of the registered provider account. It cannot enforce read-only account access. See the adapter protocol and helpers.

Ordinary modules have C, C++, Rust, Python and JavaScript helpers, with TypeScript authoring support. Adapters have Python, C and C++ helpers. Other adapter languages implement the documented framed protocol. New transport classes require host integration and qualification. Existing libvirt, Proxmox, container and administration integrations retain fixed host adapters.

Keep provider behavior inside packages where the documented capabilities permit it. Host components own authentication, credential access, transport limits and display. Do not place credentials or commands in component state to bypass that boundary.

Controller persistence uses a separate state driver interface. State drivers are trusted installation packages with full controller authority. They are not sandboxed workspace modules and cannot be installed through module grants.

Development commands#

Use Python 3.12 or later from the FICC development environment. Run commands from the FICC source directory. Build the default packages with:

sh
python tools/build-modules.py defaults --fetch --output dist/modules

This builds the separate supplied packages. Install an archive through the module manager, review its digest and requested capabilities, then enable it with explicit workspace grants. Default packages use the same archive inspection and permission checks as third-party packages. They are not registered by the application wheel. A hash identifies bytes; it does not prove publisher identity. Install packages only from a source you trust.

Make a package#

Create a source directory with manifest.json and an optional payload/ directory. Put the runtime entry point and all required runtime files inside payload/. Their paths are relative to the package root. Copy a manifest from modules/ for a host component, or from sdk/examples/ for a program. Set a unique ID and version. The files inventory is generated by the packer; leave it empty in the source.

sh
python tools/build-modules.py pack /path/to/module-source --output dist/modules

The packer includes files under payload/. Python protocol 2 modules that use the supplied SDK must copy sdk/python/ficc_module.py into that directory. The defaults command includes this dependency for the supplied Python modules. The packer does not install or infer third-party dependencies.

Native sources can also declare build.json beside the manifest. The fixed builder compiles declared C or C++ sources and selected, checksum-pinned ZIP dependencies. It accepts no build scripts or custom compiler flags. The generated program and dependency notices enter the inspected archive. Existing payload members cannot replace generated files.

Use --cache for a private dependency directory and --fetch to permit pinned downloads. Installation never compiles package code.

The packer rejects links, invalid paths and oversized files. It builds a complete SHA256 inventory and calls FICC's archive inspector before publishing the ZIP. Member order, timestamps, permissions and JSON encoding are fixed. Equal input bytes produce equal archive bytes. Existing different output is refused; change the version or use a new output directory. Compiler output can differ between toolchains even when the ZIP format is deterministic.

Build the language examples#

The examples implement the same echo batch in C, C++, Rust, Python, JavaScript and TypeScript. TypeScript is the compiled path within the JavaScript family. The C and C++ examples use the same C protocol library. The Rust example uses the Rust library. Python and JavaScript have small reusable protocol libraries.

sh
python tools/build-modules.py examples --fetch --output dist/module-examples
python sdk/conformance.py --packages dist/module-examples

Build requirements: Linux x86_64 or aarch64, a C11 compiler, a C++17 compiler, Cargo/Rust, Python 3.12 or later, and Node.js 22 or later. Native examples need the C.UTF-8 locale and the build system's C/C++ runtime ABI. Build for the target distribution; an architecture match alone does not establish ABI compatibility. Activation checks Linux ELF64 headers, the declared architecture and native loader availability inside the sandbox before replacing an active package. It does not execute native package code to discover dependencies. Use --node /path/to/node on both commands when required. Build one example with --language python or another language name. Use --cache to place build files outside the default sdk/build directory.

--fetch permits downloads of pinned build dependencies. cJSON 1.7.19 and TypeScript 5.9.3 are pinned by URL, byte size and SHA256 in dependencies.json. Rust uses exact serde_json 1.0.145 and a committed Cargo.lock for all transitive versions and checksums. No npm install scripts run. Later builds can omit --fetch and use the verified cache; Cargo then runs with --frozen. No host packages are installed. See dependency licenses.

Conformance runs the known SDK examples as local child processes. It tests N=1 and N=64, output identity/order, text escaping, Unicode, maximum target length, unknown actions and malformed frames. Do not use this command to run untrusted packages: it does not apply the FICC sandbox. A passing result is protocol evidence, not qualification of the installed host's sandbox, permissions or provider access. The installed FICC runtime must pass its own sandbox check before it enables a program package. A missing runtime or unavailable sandbox keeps it disabled.

Build the broker examples#

Each language also has a separate protocol 2 resource example. It requests system:read and calls the host's system.resources.read primitive with an empty parameter object. This reads saved system status and resource measurements under the current caller's permissions. The module receives no transport credentials.

sh
python tools/build-modules.py examples --broker --fetch --output dist/module-broker-examples
python sdk/conformance.py --broker --packages dist/module-broker-examples

Omit --fetch when the verified dependency cache is populated. --language, --cache and --node retain their existing meanings. Archives use distinct org.example.resources.<language> IDs. The Python build API selects this path with example(language, cache, fetch, node, broker=True); its default still builds the protocol 1 echo example. TypeScript compiles its broker source to JavaScript.

The broker helpers give the complete target batch to one handler. The handler calls a declared primitive for the batch or a subset, then returns complete per-target results. Grants and caller permissions remain host checks. A refusal can affect one target; cancellation, malformed traffic and lost authority fail the invocation. Calls are sequential and share the host's process deadline. Do not retry a mutation merely because a pipe closed.

Broker conformance performs 32 checks per language: N=1/N=64 success and errors, request and response identities, cancellation, result shape and malformed frames. It runs only the known local examples. Real host qualification separately needs the actual installed archives, current system:read grants and a working sandbox. The retained test tests/tools/test_module_sdk_broker.py can consume a built directory through FICC_SDK_BROKER_PACKAGES; explicitly set FICC_REAL_MODULE_SANDBOX=1 to run its real installed-host cases.

UI and capabilities#

Views have a column, row, group or tabs root. The component format includes tables, fields, menus, trees, meters, logs, editors, clocks and audio. Use unique component IDs so stored state remains stable. Buttons reference declared action IDs. The host renders labels as text. HTML, script, CSS and external URL fields are not supported.

Notes use workspace:read and workspace:write. The audio player also requests audio:playback; it uses an explicit local file picker and starts only after a user action. Playback permission does not grant microphone access. The clock uses workspace:read and a declared IANA timezone. The default clock uses UTC. Workspace persistence and audio ownership remain host services.

A manifest can declare optional_capabilities, a unique subset of capabilities. If omitted, every declared capability remains required. Required permissions need explicit target grants before activation and panel placement. Optional permissions can remain ungranted, including permissions unavailable on this host. Selecting an unavailable permission is refused. Every action and host primitive still requires its own current grants; declaring a permission optional never grants access.

For example, the libvirt package requires vm:read and can offer vm:power and vm:console separately. The file editor offers files:write separately from read.

Changing the grant set increments the package revision and invalidates active calls.

Protocol 1 echo examples declare no capabilities. Protocol 2 resource examples use the constrained host broker. Do not embed passwords, provider tokens or shell commands in manifests or component state. Package dependencies must be bundled; manifest dependency resolution is not supported.

See the process protocols, the complete manifests under sdk/examples/, and the shared cases in fixtures/conformance.json.

Artifact and dataset interfaces describe digest-bound source transfers, installable filesystem storage providers and durable job input access.

Data source interfaces define installable SQL, file-format, object and customer API providers, registered queries and verified dataset exports.

Audit destination interfaces define bounded durable appends, exact acknowledgements and separately installed destination providers.

FICC / DocumentationBack to top

Search documentation

Press Escape to close

Loading search...

    Reading appearance

    Choose colours, surfaces and text independently. These settings are saved for this documentation site in this browser.

    Flat surfaces remove decorative materials. Typography is a separate choice. Increased contrast uses the Contrast palette. System forced colours always take precedence.