Add report fragments and export manifest

This commit is contained in:
2026-05-16 03:11:56 +02:00
parent 2a1a53c140
commit 6c467dd1f4
22 changed files with 630 additions and 24 deletions

View File

@@ -653,6 +653,18 @@ building complex runtime code.
- `reported_metadata`
- `certification_boundary`
### `ExportManifest`
- `export_type`
- `source_package_ref`
- `source_lock_ref`
- `summary`
- `policy_summary`
- `mapping_summary`
- `report_fragments`
- `counts`
- `certification_boundary`
## Result Vocabulary
The evidence model should allow these statuses:
@@ -740,9 +752,11 @@ runs/<run-id>/
mappings.json
reports/
report.md
fragments.json
assessment-package.json
submission-package.json
exports/
export-manifest.json
```
## Container And Service Model
@@ -836,6 +850,8 @@ hooks for runners and normalizers.
6. Add container design after the CLI baseline is stable.
7. Add optional service API around the CLI job model.
8. Add OSCAL export and procedural evidence-pack support after the internal
evidence model proves itself with executable extensions.
evidence model proves itself with executable extensions. The first generic
export is `exports/export-manifest.json`; authority-specific interchange
remains extension-owned until the internal model is stable.
The first extension SDK contract is documented in `docs/EXTENSION-SDK.md`.

View File

@@ -79,6 +79,7 @@ A completed CLI command prints a JSON result with:
- `assessment_package`: JSON assessment package path,
- `report`: Markdown report path,
- `submission_package`: portable submission package manifest path,
- `export_manifest`: portable generic JSON export manifest path,
- `retention_summary`: compact durable summary path.
The output directory uses this contract:
@@ -95,7 +96,9 @@ normalized/findings.json
normalized/mappings.json
reports/assessment-package.json
reports/report.md
reports/fragments.json
reports/submission-package.json
exports/export-manifest.json
artifacts/
```
@@ -107,6 +110,12 @@ raw artifact manifest, and repeats the certification boundary. It is a portable
handoff manifest for preparation evidence, not an authority-specific final
submission.
Extension report fragments are recorded in `reports/fragments.json`, embedded in
`reports/assessment-package.json`, and rendered into the Markdown report.
`exports/export-manifest.json` is the first generic portable export surface. It
is derived from the assessment package and carries summary, policy, mapping,
fragment, count, source-lock, and boundary references.
Use the retained run helpers for history:
```sh
@@ -121,6 +130,10 @@ PYTHONPATH=src python3 -m guide_board runs trend --runs-dir runs
PYTHONPATH=src python3 -m guide_board runs gate --runs-dir runs
```
Trend summaries include status changes, unexpected finding deltas, unresolved
review deltas, mapping target deltas, evidence result deltas, and a compact
human-readable summary string for each target/assessment pair.
## Local Service Flow
Start the service from the guide-board repository:

View File

@@ -62,7 +62,8 @@ The script:
- builds `guide-board-core:smoke`,
- mounts a host output directory at `/runs`,
- runs the bundled sample assessment,
- verifies that the expected run artifacts are present on the host.
- verifies that the expected run artifacts, report fragments, submission
manifest, and generic export manifest are present on the host.
Override the runtime, image name, or output directory when needed:

View File

@@ -83,6 +83,8 @@ The key runtime fields are:
- `normalizers`: optional plug-ins that convert native runner output into the
stable runner-result shape before evidence is written.
- `mappings`: mapping set IDs under `mappings/<mapping-id>.json`.
- `report_fragments`: optional Markdown file or Python module descriptors for
extension-owned report content.
- `certification_boundary`: explicit statement of what the extension does not
certify.
@@ -209,6 +211,53 @@ to extension-owned mappings and writes normalized mapping records to:
runs/<run-id>/normalized/mappings.json
```
## Report Fragments
Extensions can contribute report fragments through `report_fragments`.
Static Markdown file:
```json
{
"id": "overview",
"kind": "markdown_file",
"path": "reports/overview.md",
"title": "Overview"
}
```
Dynamic Python fragment:
```json
{
"id": "sdk-fixture-summary",
"kind": "python_module",
"module_path": "reports/sdk_fixture_summary.py",
"callable": "build_fragment",
"path": null,
"title": "SDK Fixture Summary"
}
```
Fragment paths are resolved relative to the extension root and must stay inside
that root. A Python fragment receives `root`, `run_dir`, `run_id`, `plan`,
`evidence`, `findings`, `mappings`, `assessment_package`, `policy_summary`,
`source_lock`, `extension_path`, and `report_fragment`.
It returns:
```python
def build_fragment(context: dict) -> dict:
return {
"markdown": "### Extension Summary\n\n- evidence items: 2",
"structured": {"evidence_count": 2},
}
```
Fragments are written to `reports/fragments.json`, embedded in the assessment
package, rendered in `reports/report.md`, and summarized in
`exports/export-manifest.json`.
## Evidence Request Sets
Procedural and hybrid compliance extensions may include evidence request sets
@@ -402,9 +451,9 @@ profiles.
## Source Lock And Submission Package
Every new run writes `sources.lock.json` and
`reports/submission-package.json`. Extension authors should treat source
metadata as part of the evidence contract:
Every new run writes `sources.lock.json`, `reports/submission-package.json`,
and the generic portable export manifest at `exports/export-manifest.json`.
Extension authors should treat source metadata as part of the evidence contract:
- declare extension, authority, framework, runner, and normalizer metadata in
`extension.json` when it is static;

View File

@@ -98,8 +98,8 @@ errors.
### `GET /runs/{job_id}/reports`
Returns the Markdown report content, assessment package JSON, retention summary,
submission package JSON when present, and their filesystem paths after a job has
succeeded.
submission package JSON, export manifest JSON when present, and their filesystem
paths after a job has succeeded.
### `GET /retained-runs`

View File

@@ -19,6 +19,7 @@
"waivers",
"challenges",
"exclusions",
"report_fragments",
"certification_boundary",
"created_at"
],
@@ -38,6 +39,7 @@
"waivers": { "type": "array", "items": { "type": "object" } },
"challenges": { "type": "array", "items": { "type": "object" } },
"exclusions": { "type": "array", "items": { "type": "object" } },
"report_fragments": { "type": "array", "items": { "type": "object" } },
"certification_boundary": { "type": "string" },
"created_at": { "type": "string" }
}

View File

@@ -0,0 +1,36 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Guide Board Export Manifest",
"type": "object",
"additionalProperties": false,
"required": [
"id",
"schema_version",
"export_type",
"run_id",
"created_at",
"source_package_ref",
"source_lock_ref",
"summary",
"policy_summary",
"mapping_summary",
"report_fragments",
"counts",
"certification_boundary"
],
"properties": {
"id": { "type": "string" },
"schema_version": { "type": "string" },
"export_type": { "type": "string" },
"run_id": { "type": "string" },
"created_at": { "type": "string" },
"source_package_ref": { "type": "string" },
"source_lock_ref": { "type": "string" },
"summary": { "type": "object" },
"policy_summary": { "type": "object" },
"mapping_summary": { "type": "object" },
"report_fragments": { "type": "array", "items": { "type": "object" } },
"counts": { "type": "object" },
"certification_boundary": { "type": "string" }
}
}

View File

@@ -142,7 +142,23 @@
}
},
"mappings": { "type": "array", "items": { "type": "string" } },
"report_fragments": { "type": "array", "items": { "type": "string" } },
"report_fragments": {
"type": "array",
"items": {
"type": ["string", "object"],
"additionalProperties": false,
"required": ["id", "kind"],
"properties": {
"id": { "type": "string" },
"kind": { "type": "string", "enum": ["markdown_file", "python_module"] },
"path": { "type": ["string", "null"] },
"module_path": { "type": ["string", "null"] },
"callable": { "type": ["string", "null"] },
"title": { "type": ["string", "null"] },
"description": { "type": ["string", "null"] }
}
}
},
"dependencies": { "type": "array", "items": { "type": "string" } },
"restricted_assets": { "type": "array", "items": { "type": "string" } },
"certification_boundary": { "type": "string" }

View File

@@ -21,6 +21,7 @@
"created_at": { "type": "string" },
"summary": { "type": "object" },
"report_refs": { "type": "array", "items": { "type": "string" } },
"export_refs": { "type": "array", "items": { "type": "string" } },
"artifact_retention": { "type": "object" }
}
}