Files
open-cmis-tck/docs/EXTENSION-SDK.md

170 lines
4.4 KiB
Markdown

# Guide Board Extension SDK
Status: draft
Created: 2026-05-07
## Purpose
This document defines the first extension integration contract for `guide-board`.
It is intentionally small: extensions declare metadata in `extension.json`, the
core discovers them, and runners can produce normalized evidence through a stable
dictionary contract.
## Extension Layout
Incubating extensions live under:
```text
extensions/<extension-id>/
INTENT.md
extension.json
src/
docs/
schemas/
checks/
mappings/
profiles/
runners/
normalizers/
reports/
workplans/
```
Only `INTENT.md` and `extension.json` are required for discovery. Additional
folders appear as the extension grows.
## Manifest Contract
`extension.json` must validate against:
```text
docs/schemas/extension-manifest.schema.json
```
The key runtime fields are:
- `id`: must match the extension directory name.
- `extension_type`: one of the supported archetypes from the architecture
blueprint.
- `supported_frameworks`: framework IDs this extension can contribute evidence
for.
- `check_groups`: named groups that assessment profiles can select.
- `preflight_runner`: optional runner ID used before selected check groups.
- `runner_entrypoints`: concrete runner declarations.
- `certification_boundary`: explicit statement of what the extension does not
certify.
## Runner Entry Points
Runner entry points currently support these kinds:
- `python_module`: load a Python file from the extension directory and call a
function.
- `command`: execute a manifest-declared argv without shell expansion. The core
writes a context JSON file and expects the command to print a JSON runner
result to stdout.
- `external`: declare an external harness that the baseline core cannot execute
yet.
Example:
```json
{
"id": "cmis-browser-preflight",
"kind": "python_module",
"module_path": "src/open_cmis_tck/preflight.py",
"callable": "run",
"command": null,
"description": "Checks whether the CMIS Browser Binding endpoint is reachable."
}
```
Command runner example:
```json
{
"id": "opencmis-tck",
"kind": "command",
"module_path": null,
"callable": null,
"command": ["python3", "runners/opencmis_tck.py", "--context", "{context_json}"],
"description": "Checks dependency posture and prepares OpenCMIS TCK execution."
}
```
Command placeholders:
- `{context_json}`: generated context file for the current step.
- `{root}`: repository root.
- `{run_dir}`: current run directory.
- `{extension_path}`: current extension directory.
The command is executed with the extension directory as its working directory.
The core does not use a shell for command runners.
## Python Runner Contract
A Python runner receives one context object and returns one result object.
```python
def run(context: dict) -> dict:
return {
"result": "pass",
"observations": ["Observed the expected condition."],
"facts": {"key": "value"},
"artifact_refs": [],
}
```
Context fields:
- `root`: repository root path as a string.
- `run_dir`: output run directory path as a string.
- `run_id`: current run ID.
- `plan`: full run plan snapshot.
- `step`: the step being executed.
- `target_profile`: target profile snapshot.
- `assessment_profile`: assessment profile snapshot.
- `extension_path`: extension directory path as a string.
- `runner`: manifest runner declaration.
Result fields:
- `result`: one of the guide-board evidence result statuses.
- `observations`: human-readable observations.
- `facts`: structured facts extracted by the runner.
- `artifact_refs`: references to raw artifacts written by the runner.
If a Python runner raises an exception, the core converts that failure into
`infrastructure_error` evidence so the assessment package remains complete.
## Result Statuses
Initial statuses:
- `pass`
- `fail`
- `warning`
- `manual`
- `not_applicable`
- `skipped`
- `expected_gap`
- `waiver_applied`
- `unsupported_by_design`
- `infrastructure_error`
- `blocked`
- `unknown`
## Current Extension Examples
- `sample-noop`: no runner, used to validate the core contracts.
- `open-cmis-tck`: provides a Python CMIS Browser Binding preflight runner and
declares the future external OpenCMIS TCK runner.
## Next SDK Steps
- Add artifact helper APIs for extension-generated raw files.
- Add normalizer and mapping plug-in contracts.
- Add extension-owned schema validation for domain-specific target profile
fields.