generated from coulomb/repo-seed
170 lines
4.4 KiB
Markdown
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.
|