generated from coulomb/repo-seed
220 lines
6.7 KiB
Markdown
220 lines
6.7 KiB
Markdown
# Document Function Layer
|
|
|
|
Date: 2026-05-04
|
|
|
|
## Purpose
|
|
|
|
Document functions are a Markdown-native authoring surface over existing
|
|
Markitect primitives. They let a document author write small deterministic
|
|
operations inline or in fenced blocks while preserving diagnostics,
|
|
provenance, trace events, capability metadata, and extension descriptors.
|
|
|
|
The first implementation is intentionally conservative:
|
|
|
|
- deterministic functions only
|
|
- no network access
|
|
- no filesystem access
|
|
- no external processes
|
|
- no provider or assisted-generation calls
|
|
- no live flex-auth or external authorization service required
|
|
|
|
Riskier functions can be added later as optional adapters once capability and
|
|
policy gates are explicit.
|
|
|
|
## Syntax
|
|
|
|
Inline calls use:
|
|
|
|
```markdown
|
|
{{mkt:text.upper "draft"}}
|
|
```
|
|
|
|
Fenced block calls use:
|
|
|
|
````markdown
|
|
```mkt-function md.codeblock lang=python
|
|
print("hello")
|
|
```
|
|
````
|
|
|
|
Names are namespace-qualified. Arguments may be positional or named:
|
|
|
|
```markdown
|
|
{{mkt:md.heading text="Decision" level=2}}
|
|
```
|
|
|
|
Pipeline calls pass the previous result as the first argument of the next
|
|
function:
|
|
|
|
```markdown
|
|
{{mkt:text.upper "draft" | text.replace DRAFT Final}}
|
|
```
|
|
|
|
Quoted pipe characters remain literal:
|
|
|
|
```markdown
|
|
{{mkt:text.replace "a|b" "|" "/"}}
|
|
```
|
|
|
|
Values of the form `${name}` are resolved from `ProcessingContext.variables`.
|
|
This keeps data binding aligned with workflow expression conventions without
|
|
creating a second workflow engine.
|
|
|
|
## Built-In Functions
|
|
|
|
Initial deterministic functions:
|
|
|
|
| Function | Purpose |
|
|
| --- | --- |
|
|
| `text.upper` | Uppercase text. |
|
|
| `text.lower` | Lowercase text. |
|
|
| `text.title` | Title-case text. |
|
|
| `text.trim` | Trim surrounding whitespace. |
|
|
| `text.replace` | Replace text. |
|
|
| `text.join` | Join values with an optional separator. |
|
|
| `md.heading` | Create a Markdown heading. |
|
|
| `md.bold` | Create bold Markdown text. |
|
|
| `md.link` | Create a Markdown link. |
|
|
| `md.codeblock` | Create a fenced code block. |
|
|
| `data.get` | Read a value from processing context variables. |
|
|
|
|
## Typed Values
|
|
|
|
Document functions now expose typed result values in addition to their legacy
|
|
raw `output` field. Each `DocumentFunctionRun` includes a `value` object with a
|
|
stable `kind`, metadata, and optional provenance.
|
|
|
|
Supported value kinds:
|
|
|
|
| Kind | Markdown mapping |
|
|
| --- | --- |
|
|
| `string` | Inline or block text. |
|
|
| `number` | Decimal text. |
|
|
| `boolean` | `true` or `false`. |
|
|
| `none` | Empty text. |
|
|
| `markdown` | Markdown content passed through directly. |
|
|
| `list` | Comma-separated inline text or newline-separated block text. |
|
|
| `dictionary` | Stable JSON object text. |
|
|
| `record` | Stable JSON object text. |
|
|
| `table` | Deterministic Markdown table. |
|
|
| `reference` | Label/title/value text, with provenance required. |
|
|
| `content_unit` | Label/title/value text, with provenance required. |
|
|
| `unknown` | Diagnostic fallback for mismatched output values. |
|
|
| `dynamic` | Reserved for explicitly dynamic values. |
|
|
|
|
Function descriptors declare `output_type`; execution validates the returned
|
|
value against that declaration. Mismatches produce
|
|
`function.output_type_mismatch`, while reference-like values without provenance
|
|
produce `function.provenance_missing`.
|
|
|
|
The raw `output` field remains for compatibility. New callers should prefer
|
|
`value` for typed API use and use the mapper when Markdown output is needed.
|
|
|
|
## CLI
|
|
|
|
List functions:
|
|
|
|
```text
|
|
mkt function list
|
|
```
|
|
|
|
Validate calls without rendering:
|
|
|
|
```text
|
|
mkt function check examples/functions/basic-functions.md
|
|
```
|
|
|
|
Render deterministic calls:
|
|
|
|
```text
|
|
mkt function render examples/functions/basic-functions.md
|
|
```
|
|
|
|
JSON and YAML outputs include calls, diagnostics, provenance, and trace data.
|
|
|
|
## Registry And Extension Fit
|
|
|
|
The function layer has its own `DocumentFunctionRegistry`. Functions are
|
|
described by `DocumentFunctionDescriptor`:
|
|
|
|
- stable id and namespace
|
|
- parameters
|
|
- output type
|
|
- execution kind
|
|
- capability declarations
|
|
- safety metadata
|
|
- examples
|
|
|
|
The built-in extension catalog exposes this layer as `document.function` with
|
|
kind `document-function`. This keeps it discoverable without replacing
|
|
processors, workflows, references, contracts, templates, or query engines.
|
|
|
|
## Policy And Capability Gates
|
|
|
|
The first evaluator blocks non-deterministic functions and supports local
|
|
capability blocking through `ProcessingContext.policy`, for example:
|
|
|
|
```python
|
|
ProcessingContext(policy={"blocked_capabilities": ["document_function"]})
|
|
```
|
|
|
|
Future functions that read files, access network resources, invoke external
|
|
processes, render exports, or call assisted generation must declare those
|
|
capabilities before execution. External policy services may provide decisions
|
|
through adapters later, but deterministic function execution has no external
|
|
service dependency.
|
|
|
|
## Syntax Boundary
|
|
|
|
The supported syntax remains intentionally conservative:
|
|
|
|
- inline calls with `{{mkt:...}}`
|
|
- fenced calls with `mkt-function`
|
|
- positional and named arguments parsed with shell-like quoting
|
|
- pipeline chaining with quoted pipe characters preserved
|
|
- `${name}` context variable lookup
|
|
- bounded pipeline depth to avoid accidental runaway expressions
|
|
|
|
Deferred syntax:
|
|
|
|
- nested function expressions
|
|
- document-local function definitions
|
|
- conditionals, loops, lambdas, or general scripting
|
|
- Quarkdown syntax compatibility in the core parser
|
|
|
|
## Natural Extensions
|
|
|
|
The deterministic layer deliberately stops before becoming a full publishing
|
|
language. The original broad render/function follow-up has been split into
|
|
native workplans:
|
|
|
|
- `MKTT-WP-0015`: typed document-function value contracts.
|
|
- `MKTT-WP-0020`: render/export adapter contracts.
|
|
- `MKTT-WP-0021`: render reference and asset manifest contracts.
|
|
- `MQD-WP-0001`: concrete Quarkdown adapter implementation in
|
|
`markitect-quarkdown`.
|
|
- `MKTF-WP-0003`: read-side source attachment metadata compatibility in
|
|
`markitect-filter`.
|
|
|
|
Those workplans should consider:
|
|
|
|
- typed document values and value-to-Markdown mapping
|
|
- constrained parser compatibility improvements, while deferring nested
|
|
function expressions and document-local reusable functions
|
|
- render/export adapter contracts, including optional Quarkdown source export
|
|
- render-aware numbering, references, tables, figures, equations, and code
|
|
blocks
|
|
- static asset and media manifests with checksums
|
|
- local permission gates for filesystem, network, external process, assisted,
|
|
and render/export functions
|
|
|
|
## Design Rules
|
|
|
|
- Stay close to Markdown and preserve CommonMark documents unless function
|
|
syntax is explicit.
|
|
- Keep deterministic execution useful without backends or providers.
|
|
- Surface diagnostics instead of silently deleting failed calls.
|
|
- Preserve source line information where available.
|
|
- Treat functions as an authoring surface over existing capabilities, not as a
|
|
second workflow engine.
|