Skip to content

Filter Package Manifests

A filter package is a versioned artifact containing one manifest and the fixture files it references. An implementation realizes its declared filters.

Those filters extend the expression language without extending the built-in filter namespace. Filter Package Manifest conformance applies to the manifest, fixtures, and observable filter behavior as one unit.

A filter-package manifest is a document using the serialization rules with this form:

manifest: 1
kind: filters
namespace: text
version: 1.2.0
filters:
slugify:
input: string
args: []
output: string
fixtures: fixtures/slugify.jsonl
wrap:
input: string
args:
- { name: width, type: int, default: 80 }
output: string
fixtures: fixtures/wrap.jsonl

Filter-package structural maps follow the closed-map rule under Duplicate and Unknown Keys. Unknown filter-package keys are invalid under that same rule.

filters MUST be a nonempty map, and every declared name MUST match the Workfile name syntax. Filter-package namespaces remain subject to the lowercase catalog-namespace syntax.

manifest MUST be present and MUST be a positive integer identifying the filter-package-manifest format version. An implementation MUST reject a format version it does not support.

kind MUST be present and MUST be filters. namespace and version MUST be present.

namespace is the first component of each dotted filter name published by the package. Namespace ownership, reservation, and catalog resolution are defined under Catalog and Packaging.

A filter-package manifest MUST NOT declare a bare filter or a name containing a dot. For a Standard Library package, artifact identity is the package namespace together with the Library edition that contains it. A Standard Library package’s version MUST equal its edition’s Standard revision; Standard Library packages are not selected or upgraded independently of the Library edition. For any other package, version is a SemVer 2.0.0 version and is part of the resolved artifact identity.

Within one major vendor-package version, a later version MUST NOT remove a filter, add a required argument, reorder arguments, narrow an accepted input or argument type, widen an output type, or change a previously valid input from a value to a fault or to a different value. It MAY add filters or trailing optional arguments.

Any other observable incompatibility requires a new major version. Build metadata is part of exact artifact identity but not SemVer precedence.

Each entry in filters contains exactly input, args, output, and fixtures. input is a type expression.

output is a type expression or the reserved literal safe_html; a package MUST use that output only for a filter whose complete normative behavior makes every result safe for unchanged insertion into an HTML fragment. args is an ordered list of argument declarations containing name, type, and optionally default.

Argument names MUST be distinct. An argument with a default is optional; every optional argument MUST follow every required argument.

A default MUST be a literal satisfying its declared type. The receiver supplies input, and call arguments bind to args by position.

Extension filters do not accept named arguments or variable arity. A validator MUST reject a call whose statically inferred receiver type, argument count, or argument type is incompatible with the declaration.

Where json prevents a static determination, the same incompatibility at evaluation is fault.filter_signature. Filters follow Purity.

For filters, the prohibited ambient state includes connections, locale, environment variables, and process-global history. A filter MUST NOT mutate its receiver or arguments. Any tables, locale data, patterns, or algorithms it uses are immutable content of the resolved package and are covered by that package’s artifact identity.

For every receiver and argument set satisfying its signature, a filter MUST deterministically return a value satisfying output or one registered evaluation fault. It MUST NOT expose a host-language exception, partial result, implementation-specific error code, or implementation-specific coercion.

Equal typed inputs under the Data Model MUST produce equal typed results or the same fault on every conforming implementation of that exact package artifact.

fixtures is a normalized package-relative path to a UTF-8 JSON Lines file included in the package. It MUST NOT be absolute, contain an empty path segment, or contain . or .. segments.

Each filter MUST name one nonempty fixture file; a file can be shared by multiple filters. Each nonempty line is one JSON object with expr and exactly one of result and fault.

expr is a whole-value interpolation containing a call to the declared dotted filter. It is evaluated with no bindings in scope and MUST use only literals and filters.

result is the expected Workfile value in its JSON representation; the declared output type supplies the interpretation of typed strings or objects. fault is a registered evaluation-fault code.

An optional why string is informative. No other keys are permitted.

The expression MUST parse and type-check against the manifest. A result MUST satisfy the declared output type.

A fixture expecting a validation error is invalid; fault describes a runtime evaluation fault only. Fixtures are normative examples of observable package behavior, not a complete definition of the filter.

Before making a package implementation available, an implementation MUST execute every fixture against that exact artifact and reject the package if any value, type, or fault differs. Passing fixtures does not relax the purity, signature, totality, or determinism requirements.

A dotted filter name has exactly two name components, namespace.filter. The first selects one filter package and the second selects one declaration in that package.

A missing package, missing filter, unsupported manifest version, failed fixture verification, or incompatible signature is a validation error. An implementation MUST NOT fall back to a bare filter, another namespace, or another package version.

Validation resolves every referenced package as specified by Catalog and Packaging. Before a run begins, the resolution MUST fix the namespace, exact version, manifest digest, and file-set digest.

Execution, recovery, and re-evaluation MUST use an implementation conforming to that same resolved artifact. Two references to one namespace within a resolved Workfile MUST resolve to one exact package version.

Merely resolving a package grants it no credentials, network access, filesystem access, or workflow bindings beyond the receiver and evaluated arguments of a call. A filter result enters expression evaluation as an ordinary typed value, and a filter fault follows the Standard evaluation-fault rules.