generated from coulomb/repo-seed
275 lines
7.2 KiB
Markdown
275 lines
7.2 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
|
|
|
|
Bundled incubating extensions live under:
|
|
|
|
```text
|
|
extensions/<extension-id>/
|
|
INTENT.md
|
|
extension.json
|
|
src/
|
|
docs/
|
|
schemas/
|
|
evidence-requests/
|
|
checks/
|
|
mappings/
|
|
profiles/
|
|
runners/
|
|
normalizers/
|
|
reports/
|
|
workplans/
|
|
```
|
|
|
|
Production extensions may also live in their own repositories. The repository
|
|
root is then the extension root and must contain `extension.json`:
|
|
|
|
```text
|
|
open-cmis-tck/
|
|
INTENT.md
|
|
extension.json
|
|
src/
|
|
mappings/
|
|
profiles/
|
|
runners/
|
|
workplans/
|
|
```
|
|
|
|
Pass external extension repos to the core CLI with:
|
|
|
|
```sh
|
|
guide-board --extension-dir ../open-cmis-tck extensions list
|
|
```
|
|
|
|
Multiple `--extension-dir` values are allowed. `GUIDE_BOARD_EXTENSION_PATHS`
|
|
may also provide an OS-path-separated list for local automation and containers.
|
|
|
|
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.
|
|
- `mappings`: mapping set IDs under `mappings/<mapping-id>.json`.
|
|
- `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.
|
|
|
|
Runner context values are stable for bundled and external extensions:
|
|
|
|
- `root`: the guide-board core root.
|
|
- `extension_path`: the absolute path to the extension root.
|
|
- `run_dir`: the current run output directory.
|
|
- `plan`: the immutable run plan snapshot.
|
|
|
|
## Mapping Sets
|
|
|
|
Mapping sets connect normalized evidence requirement refs to capability groups,
|
|
controls, conformance classes, quality dimensions, or other assessment targets.
|
|
|
|
Each mapping set lives under:
|
|
|
|
```text
|
|
extensions/<extension-id>/mappings/<mapping-id>.json
|
|
```
|
|
|
|
and validates against:
|
|
|
|
```text
|
|
docs/schemas/mapping-set.schema.json
|
|
```
|
|
|
|
The core does not embed domain policy. It only joins evidence `requirement_refs`
|
|
to extension-owned mappings and writes normalized mapping records to:
|
|
|
|
```text
|
|
runs/<run-id>/normalized/mappings.json
|
|
```
|
|
|
|
## Evidence Request Sets
|
|
|
|
Procedural and hybrid compliance extensions may include evidence request sets
|
|
under:
|
|
|
|
```text
|
|
evidence-requests/<request-set-id>.json
|
|
```
|
|
|
|
These files validate against:
|
|
|
|
```text
|
|
docs/schemas/evidence-request-set.schema.json
|
|
```
|
|
|
|
Evidence request sets are for collection guidance and review workflow. They
|
|
should reference official requirements by stable IDs or user-held licensed
|
|
material, but they must not redistribute proprietary standard text. A starter
|
|
template lives at:
|
|
|
|
```text
|
|
extensions/_template/evidence-request-set.json
|
|
```
|
|
|
|
See `docs/COMPLIANCE-EVIDENCE-PACKS.md` for the compliance-pack strategy.
|
|
|
|
## Expectations And Waivers
|
|
|
|
Assessment profiles may reference expectation and waiver sets:
|
|
|
|
```json
|
|
{
|
|
"expectations_ref": "profiles/expectations/example.json",
|
|
"waivers_ref": "profiles/waivers/example.json"
|
|
}
|
|
```
|
|
|
|
Expectation sets mark known posture as expected. Waiver sets mark approved,
|
|
time-bounded exceptions. Both are applied after findings are generated, and the
|
|
assessment package records policy summary counts.
|
|
|
|
## 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.
|
|
|
|
Artifact refs must be paths relative to the run directory. After runner
|
|
execution, the core fingerprints existing artifact refs into the assessment
|
|
package `artifact_manifest`.
|
|
|
|
If a Python runner raises an exception, the core converts that failure into
|
|
`infrastructure_error` evidence so the assessment package remains complete.
|
|
|
|
Preflight runners are gates. If an extension preflight returns `fail`, `blocked`,
|
|
or `infrastructure_error`, downstream check groups for that extension are not
|
|
executed; they receive `blocked` evidence with `blocked_reason:
|
|
preflight_failed`.
|
|
|
|
## 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 normalizer plug-in contracts.
|
|
- Add extension-owned schema validation for domain-specific target profile
|
|
fields.
|