work
This commit is contained in:
@@ -52,6 +52,7 @@
|
||||
- **Install & operations:** [Installation guide](21_INSTALL_GUIDE.md), [Offline Update Kit](24_OFFLINE_KIT.md), [Security hardening](17_SECURITY_HARDENING_GUIDE.md).
|
||||
- **Binary prerequisites & offline layout:** [Binary prereqs](ops/binary-prereqs.md) covering curated NuGet feed, manifests, and CI guards.
|
||||
- **Architecture & modules:** [High-level architecture](high-level-architecture.md), [Module dossiers](modules/platform/architecture-overview.md), [Strategic differentiators](moat.md).
|
||||
- **Advisory AI:** [Module dossier & deployment](modules/advisory-ai/README.md) covering RAG pipeline, guardrails, offline bundle outputs, and operations.
|
||||
- **Policy & governance:** [Policy templates](60_POLICY_TEMPLATES.md), [Legal & quota FAQ](29_LEGAL_FAQ_QUOTA.md), [Governance charter](11_GOVERNANCE.md).
|
||||
- **UI & glossary:** [Console guide](15_UI_GUIDE.md), [Accessibility](accessibility.md), [Glossary](14_GLOSSARY_OF_TERMS.md).
|
||||
- **Technical documentation:** [Full technical index](technical/README.md) for architecture, APIs, module dossiers, and operations playbooks.
|
||||
|
||||
70
docs/advisory-ai/cli.md
Normal file
70
docs/advisory-ai/cli.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# Advisory AI CLI Usage (DOCS-AIAI-31-005)
|
||||
|
||||
_Updated: 2025-11-24 · Owners: Docs Guild · DevEx/CLI Guild · Sprint 0111_
|
||||
|
||||
This guide shows how to drive Advisory AI from the StellaOps CLI using the `advise run` verb, with deterministic fixtures published on 2025-11-19 (`CLI-VULN-29-001`, `CLI-VEX-30-001`). It is designed for CI/offline use and mirrors the guardrail/policy contracts captured in `docs/advisory-ai/guardrails-and-evidence.md` and `docs/policy/assistant-parameters.md`.
|
||||
|
||||
## Prerequisites
|
||||
- CLI binary from Sprint 205 (`stella`), logged in with scopes `advisory-ai:operate` + `aoc:verify`.
|
||||
- Base URL pointed at Advisory AI gateway: `export STELLAOPS_ADVISORYAI_URL=https://advisory-ai.internal` (falls back to main backend base address when unset).
|
||||
- Evidence fixtures available locally (offline friendly):
|
||||
- `out/console/guardrails/cli-vuln-29-001/sample-vuln-output.ndjson` (SHA256 `e5aecfba5cee8d412408fb449f12fa4d5bf0a7cb7e5b316b99da3b9019897186`).
|
||||
- `out/console/guardrails/cli-vuln-29-001/sample-sbom-context.json` (SHA256 `421af53f9eeba6903098d292fbd56f98be62ea6130b5161859889bf11d699d18`).
|
||||
- `out/console/guardrails/cli-vex-30-001/sample-vex-output.ndjson` (SHA256 `2b11b1e2043c2ec1b0cb832c29577ad1c5cbc3fbd0b379b0ca0dee46c1bc32f6`).
|
||||
- Policy hash pinned: set `ADVISORYAI__POLICYVERSION=2025.11.19` (or the bundle hash shipped in the Offline Kit).
|
||||
|
||||
## Quickstart
|
||||
```bash
|
||||
stella advise run summary \
|
||||
--advisory-key csaf:redhat:RHSA-2025:1001 \
|
||||
--artifact-id registry.stella-ops.internal/runtime/api \
|
||||
--policy-version "$ADVISORYAI__POLICYVERSION" \
|
||||
--profile fips-local \
|
||||
--timeout 30 \
|
||||
--json
|
||||
```
|
||||
- Use `--timeout 0` for cache-only probes in CI; add `--force-refresh` to bypass cache.
|
||||
- `--profile cloud-openai` remains disabled unless tenant consent is recorded in Authority; guardrails reject with exit code 12 when disabled.
|
||||
- Guardrail fixtures (`sample-vuln-output.ndjson`, `sample-vex-output.ndjson`, `sample-sbom-context.json`) live in Offline Kits and feed the backend self-tests; the CLI fetches evidence from backend services automatically.
|
||||
|
||||
## Exit codes
|
||||
| Code | Meaning | Notes |
|
||||
| --- | --- | --- |
|
||||
| 0 | Success (hit or miss; output cached or freshly generated) | Includes `outputHash` and citations. |
|
||||
| 2 | Validation error (missing advisory key, bad profile) | Mirrors HTTP 400.
|
||||
| 3 | Context unavailable (SBOM/LNM/policy missing) | Mirrors HTTP 409 `advisory.contextUnavailable`.
|
||||
| 4 | Guardrail block (PII, citation gap, prompt too large) | Mirrors HTTP 422 `advisory.guardrail.blocked`.
|
||||
| 5 | Timeout waiting for output | Respect `--timeout` in seconds (0 = no wait). |
|
||||
| 12 | Remote profile disabled | Returned when `cloud-openai` is selected without consent. |
|
||||
| 7 | Transport/auth failure | Network/TLS/token issues. |
|
||||
|
||||
## Scripting patterns
|
||||
- **Cache-only probes (CI smoke):** `stella advise run summary --advisory-key ... --timeout 0 --json > cache.json` (fails fast if evidence missing).
|
||||
- **Batch mode:** pipe advisory keys: `cat advisories.txt | xargs -n1 -I{} stella advise run summary --advisory-key {} --timeout 0 --json`.
|
||||
- **Profile gating:** set `--profile fips-local` for offline; use `--profile cloud-openai` only after Authority consent and when `ADVISORYAI__INFERENCE__MODE=Remote`.
|
||||
- **Policy pinning:** always pass `--policy-version` (matches Offline Kit bundle hash); outputs include the policy hash in `context.planCacheKey`.
|
||||
|
||||
## Sample output (trimmed)
|
||||
```json
|
||||
{
|
||||
"taskType": "Summary",
|
||||
"profile": "fips-local",
|
||||
"generatedAt": "2025-11-24T00:00:00Z",
|
||||
"outputHash": "sha256:cafe...babe",
|
||||
"citations": [{"index":1,"kind":"advisory","sourceId":"concelier:csaf:redhat:RHSA-2025:1001:paragraph:12"}],
|
||||
"context": {
|
||||
"planCacheKey": "adv-summary:csaf:redhat:RHSA-2025:1001:fips-local",
|
||||
"sbom": {"artifactId":"registry.stella-ops.internal/runtime/api","versionTimeline":8,"dependencyPaths":5}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Offline kit notes
|
||||
- Copy the three CLI guardrail artefact bundles and their `hashes.sha256` files into `offline-kit/advisory-ai/fixtures/` and record them in `SHA256SUMS`.
|
||||
- Set `ADVISORYAI__SBOM__BASEADDRESS` to the SBOM Service endpoint packaged in the kit; leave unset to fall back to `NullSbomContextClient` (Advisory AI will still respond deterministically with context counts set to 0).
|
||||
- Keep `profiles.catalog.json` and `prompts.manifest` hashes aligned with the guardrail pack referenced in the Offline Kit manifest.
|
||||
|
||||
## Troubleshooting
|
||||
- `contextUnavailable`: ensure SBOM service is reachable or provide `--sbom-context` fixture; verify LNM linkset IDs and hashes.
|
||||
- `guardrail.blocked`: check blocked phrase list (`docs/policy/assistant-parameters.md`) and payload size; remove PII or reduce SBOM clamps.
|
||||
- `timeout`: raise `--timeout` or run cache-only mode to avoid long waits in CI.
|
||||
@@ -1,8 +1,8 @@
|
||||
# Advisory AI Evidence Payloads (LNM-Aligned)
|
||||
|
||||
_Updated: 2025-11-18 · Owner: Advisory AI Docs Guild · Sprint: 0111 (AIAI-RAG-31-003)_
|
||||
_Updated: 2025-11-24 · Owner: Advisory AI Docs Guild · Sprint: 0111 (AIAI-RAG-31-003)_
|
||||
|
||||
This document defines how Advisory AI consumes Link-Not-Merge (LNM) observations and linksets for Retrieval-Augmented Generation (RAG). It aligns payloads with the frozen LNM v1 schema (`docs/modules/concelier/link-not-merge-schema.md`, 2025-11-17) and replaces prior draft payloads. CLI/Policy artefacts (`CLI-VULN-29-001`, `CLI-VEX-30-001`, `policyVersion` digests) are referenced but optional at runtime; missing artefacts trigger deterministic `409 advisory.contextUnavailable` responses rather than fallback merging.
|
||||
This document defines how Advisory AI consumes Link-Not-Merge (LNM) observations and linksets for Retrieval-Augmented Generation (RAG). It aligns payloads with the frozen LNM v1 schema (`docs/modules/concelier/link-not-merge-schema.md`, 2025-11-17) and replaces prior draft payloads. CLI/Policy artefacts (`CLI-VULN-29-001`, `CLI-VEX-30-001`, `policyVersion` digests) are referenced but optional at runtime; missing artefacts trigger deterministic `409 advisory.contextUnavailable` responses rather than fallback merging. A deterministic SBOM context fixture lives at `out/console/guardrails/cli-vuln-29-001/sample-sbom-context.json` (SHA256 `421af53f9eeba6903098d292fbd56f98be62ea6130b5161859889bf11d699d18`) and is used in the examples below.
|
||||
|
||||
## 1) Input envelope (per task)
|
||||
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
# Advisory AI Guardrails & Evidence Intake
|
||||
|
||||
_Updated: 2025-11-22 · Owner: Advisory AI Docs Guild · Status: Draft (Sprint 0111)_
|
||||
_Updated: 2025-11-24 · Owner: Advisory AI Docs Guild · Status: Published (Sprint 0111)_
|
||||
|
||||
This note captures the guardrail behaviors and evidence intake boundaries required by Sprint 0111 tasks (`AIAI-DOCS-31-001`, `AIAI-RAG-31-003`). It binds Advisory AI guardrails to upstream evidence sources and clarifies how Link-Not-Merge (LNM) documents flow into Retrieval-Augmented Generation (RAG) payloads.
|
||||
|
||||
## 1) Evidence sources and contracts
|
||||
|
||||
**Upstream readiness gates**
|
||||
**Upstream readiness gates (now satisfied)**
|
||||
|
||||
- CLI + Policy artefacts (`CLI-VULN-29-001`, `CLI-VEX-30-001`, `policyVersion` digests) must be present before enabling non-default profiles. Until then, Advisory AI accepts requests but responds with `409 advisory.contextUnavailable` when those references are missing.
|
||||
- LNM linksets stay the single source of truth; Advisory AI refuses ad-hoc advisory payloads even if CLI/Policy artefacts are delayed.
|
||||
- CLI guardrail artefacts landed on 2025-11-19: `out/console/guardrails/cli-vuln-29-001/` (`sample-vuln-output.ndjson`, `sample-sbom-context.json`) and `out/console/guardrails/cli-vex-30-001/` (`sample-vex-output.ndjson`). Hashes are recorded in `docs/modules/cli/artefacts/guardrails-artefacts-2025-11-19.md` and must be copied into Offline Kits.
|
||||
- Policy hash must be pinned (`policyVersion`, see `docs/policy/assistant-parameters.md`) before enabling non-default profiles.
|
||||
- LNM linksets stay the single source of truth; Advisory AI refuses ad-hoc advisory payloads even if upstream artefacts drift.
|
||||
|
||||
- **Advisory observations (LNM)** — Consume immutable `advisory_observations` and `advisory_linksets` produced per `docs/modules/concelier/link-not-merge-schema.md` (frozen v1, 2025-11-17).
|
||||
- **VEX statements** — Excititor + VEX Lens linksets with trust weights; treated as structured chunks with `source_id` and `confidence`.
|
||||
@@ -63,5 +64,6 @@ See `docs/advisory-ai/evidence-payloads.md` for full JSON examples and alignment
|
||||
- [ ] LNM feed enabled and Concelier schemas at v1 (2025-11-17).
|
||||
- [ ] SBOM retriever configured or `NullSbomContextClient` left as safe default.
|
||||
- [ ] Policy hash pinned via `policyVersion` when reproducibility is required.
|
||||
- [ ] CLI guardrail artefact hashes verified against `docs/modules/cli/artefacts/guardrails-artefacts-2025-11-19.md` and mirrored into Offline Kits.
|
||||
- [ ] Remote profiles only after Authority consent and profile allowlist are set.
|
||||
- [ ] Cache directories shared between web + worker hosts for DSSE sealing.
|
||||
|
||||
55
docs/advisory-ai/sbom-context-hand-off.md
Normal file
55
docs/advisory-ai/sbom-context-hand-off.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# SBOM Context Hand-off for Advisory AI (SBOM-AIAI-31-003)
|
||||
|
||||
_Updated: 2025-11-24 · Owners: Advisory AI Guild · SBOM Service Guild · Sprint 0111_
|
||||
|
||||
Defines the contract and smoke test for passing SBOM context from SBOM Service to Advisory AI `/v1/sbom/context` consumers. Aligns with `SBOM-AIAI-31-001` (paths/timelines) and the CLI fixtures published on 2025-11-19.
|
||||
|
||||
## Contract
|
||||
- **Endpoint** (SBOM Service): `/sbom/context`
|
||||
- **Request** (minimal):
|
||||
```json
|
||||
{
|
||||
"artifactId": "registry.stella-ops.internal/runtime/api",
|
||||
"purl": "pkg:oci/runtime-api@sha256:d2c3...",
|
||||
"timelineClamp": 500,
|
||||
"dependencyPathClamp": 200
|
||||
}
|
||||
```
|
||||
- **Response** (summarised):
|
||||
```json
|
||||
{
|
||||
"schema": "stellaops.sbom.context/1.0",
|
||||
"generated": "2025-11-19T00:00:00Z",
|
||||
"packages": [
|
||||
{"name":"openssl","version":"1.1.1w","purl":"pkg:deb/openssl@1.1.1w"},
|
||||
{"name":"zlib","version":"1.2.11","purl":"pkg:deb/zlib@1.2.11"}
|
||||
],
|
||||
"timeline": 8,
|
||||
"dependencyPaths": 5,
|
||||
"hash": "sha256:421af53f9eeba6903098d292fbd56f98be62ea6130b5161859889bf11d699d18"
|
||||
}
|
||||
```
|
||||
- **Determinism**: clamp values fixed unless overridden; `generated` timestamp frozen per fixture when offline.
|
||||
- **Headers**: `X-StellaOps-Tenant` required; `X-StellaOps-ApiKey` optional for bootstrap.
|
||||
|
||||
## Smoke test (tenants/offline)
|
||||
1. Start SBOM Service with fixture data loaded (or use `sample-sbom-context.json`).
|
||||
2. Run: `curl -s -H "X-StellaOps-Tenant: demo" -H "Content-Type: application/json" \
|
||||
-d @out/console/guardrails/cli-vuln-29-001/sample-sbom-context.json \
|
||||
http://localhost:8080/sbom/context | jq .hash` (expect `sha256:421a...9d18`).
|
||||
3. Configure Advisory AI:
|
||||
- `AdvisoryAI:SBOM:BaseAddress=http://localhost:8080`
|
||||
- `AdvisoryAI:SBOM:ApiKey=<key-if-required>`
|
||||
4. Call Advisory AI cache-only: `stella advise run remediation --advisory-key csaf:redhat:RHSA-2025:1001 --artifact-id registry.stella-ops.internal/runtime/api --timeout 0 --json`.
|
||||
- Expect exit 0 and `sbomSummary.dependencyPaths=5` in response.
|
||||
5. Record the hash and endpoint in ops log; mirror fixture + hashes into Offline Kit under `offline-kit/advisory-ai/fixtures/sbom-context/`.
|
||||
|
||||
## Failure modes
|
||||
- `409 advisory.contextHashMismatch` — occurs when the returned `hash` differs from the LNM linkset `provenanceHash`; refresh context or re-export.
|
||||
- `403` — tenant/api key mismatch; check `X-StellaOps-Tenant` and API key.
|
||||
- `429` — clamp exceeded; reduce `timelineClamp`/`dependencyPathClamp` or narrow `artifactId`.
|
||||
|
||||
## References
|
||||
- `docs/sbom/remediation-heuristics.md` (blast-radius scoring).
|
||||
- `docs/advisory-ai/guardrails-and-evidence.md` (evidence contract).
|
||||
- `docs/modules/cli/artefacts/guardrails-artefacts-2025-11-19.md` (hashes for fixtures).
|
||||
80
docs/devportal/publishing.md
Normal file
80
docs/devportal/publishing.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# Developer Portal Publishing Guide
|
||||
|
||||
Last updated: 2025-11-25
|
||||
|
||||
## Goals
|
||||
- Publish the StellaOps Developer Portal consistently across connected and air-gapped environments.
|
||||
- Produce deterministic artefacts (checksums, manifests) so releases are auditable and reproducible.
|
||||
- Keep docs, API specs, and examples in sync with the CI pipelines that build the portal.
|
||||
|
||||
## Prerequisites
|
||||
- Node.js 20.x + pnpm 9.x
|
||||
- Docker / Podman (for static-site container image)
|
||||
- Spectral lint baseline from `src/Api/StellaOps.Api.OpenApi` (optional, to embed OAS links)
|
||||
- Access to `local-nugets/` cache and offline asset bundle (see Offline section)
|
||||
|
||||
## Build & Test (connected)
|
||||
```bash
|
||||
pnpm install --frozen-lockfile
|
||||
pnpm lint # markdownlint/prettier/eslint as configured
|
||||
pnpm build # generates static site into dist/
|
||||
pnpm test # component/unit tests if configured
|
||||
```
|
||||
- Determinism: ensure `pnpm-lock.yaml` is committed; no timestamps in emitted HTML (set `SOURCE_DATE_EPOCH` if needed).
|
||||
|
||||
## Publish (connected)
|
||||
1. Build the static site: `pnpm build` (or reuse CI artifact).
|
||||
2. Create artefact bundle:
|
||||
```bash
|
||||
tar -C dist -czf out/devportal/site.tar.gz .
|
||||
sha256sum out/devportal/site.tar.gz > out/devportal/site.tar.gz.sha256
|
||||
```
|
||||
3. Container image (optional):
|
||||
```bash
|
||||
docker build -t registry.example.com/stella/devportal:${VERSION} -f ops/devportal/Dockerfile .
|
||||
docker push registry.example.com/stella/devportal:${VERSION}
|
||||
```
|
||||
4. Record manifest `out/devportal/manifest.json`:
|
||||
```json
|
||||
{
|
||||
"version": "${VERSION}",
|
||||
"checksum": "$(cat out/devportal/site.tar.gz.sha256 | awk '{print $1}')",
|
||||
"build": {
|
||||
"node": "20.x",
|
||||
"pnpm": "9.x"
|
||||
},
|
||||
"timestamp": "${UTC_ISO8601}",
|
||||
"source_commit": "$(git rev-parse HEAD)"
|
||||
}
|
||||
```
|
||||
|
||||
## Offline / Air-gap
|
||||
- Use pre-seeded bundle `offline/devportal/site.tar.gz` with accompanying `.sha256` and `manifest.json`.
|
||||
- Verify before use:
|
||||
```bash
|
||||
sha256sum -c offline/devportal/site.tar.gz.sha256
|
||||
```
|
||||
- Serve locally:
|
||||
```bash
|
||||
mkdir -p /srv/devportal && tar -C /srv/devportal -xzf offline/devportal/site.tar.gz
|
||||
# then point nginx/caddy to /srv/devportal
|
||||
```
|
||||
- No external CDN references allowed; ensure assets are bundled and CSP is self-contained.
|
||||
|
||||
## Deployment targets
|
||||
- **Kubernetes**: use the static-site container image with a read-only root filesystem; expose via ingress with TLS; set `ETAG`/`Last-Modified` headers from manifest.
|
||||
- **Docker Compose**: mount `site.tar.gz` into a lightweight nginx container; sample compose snippet lives in `ops/deployment/devportal/docker-compose.devportal.yml` (to be authored alongside this doc).
|
||||
- **File share**: extract bundle onto shared storage for disconnected viewing; keep manifest + checksum adjacent.
|
||||
|
||||
## Checks & Observability
|
||||
- Lint/OAS links: run `pnpm lint` and optional `pnpm api:check` (if wired) to ensure embedded API links resolve.
|
||||
- Availability: configure basic `/healthz` (static 200) and enable access logging at the reverse proxy.
|
||||
- Integrity: serve checksums/manifest from `/meta` path for auditors; include build `source_commit` and `timestamp`.
|
||||
|
||||
## Release checklist
|
||||
- [ ] `pnpm build` succeeds reproducibly.
|
||||
- [ ] `site.tar.gz` + `.sha256` generated and verified.
|
||||
- [ ] `manifest.json` populated with version, checksum, UTC timestamp, commit SHA.
|
||||
- [ ] Offline bundle placed in `offline/devportal/` with checksums.
|
||||
- [ ] Image (if used) pushed to registry and noted in release notes.
|
||||
- [ ] Deployment target (K8s/Compose/File share) instructions updated if changed.
|
||||
@@ -8,7 +8,7 @@ Summary: Ops & Offline focus on Ops Devops (phase IV).
|
||||
Task ID | State | Task description | Owners (Source)
|
||||
--- | --- | --- | ---
|
||||
DEVOPS-OBS-55-001 | DONE (2025-11-25) | Implement incident mode automation: feature flag service, auto-activation via SLO burn-rate, retention override management, and post-incident reset job. Dependencies: DEVOPS-OBS-54-001. | DevOps Guild, Ops Guild (ops/devops)
|
||||
DEVOPS-ORCH-32-001 | DOING (2025-11-25) | Provision orchestrator Postgres/message-bus infrastructure, add CI smoke deploy, seed Grafana dashboards (queue depth, inflight jobs), and document bootstrap. | DevOps Guild, Orchestrator Service Guild (ops/devops)
|
||||
DEVOPS-ORCH-32-001 | DONE (2025-11-25) | Provision orchestrator Postgres/message-bus infrastructure, add CI smoke deploy, seed Grafana dashboards (queue depth, inflight jobs), and document bootstrap. | DevOps Guild, Orchestrator Service Guild (ops/devops)
|
||||
DEVOPS-ORCH-33-001 | TODO | Publish Grafana dashboards/alerts for rate limiter, backpressure, error clustering, and DLQ depth; integrate with on-call rotations. Dependencies: DEVOPS-ORCH-32-001. | DevOps Guild, Observability Guild (ops/devops)
|
||||
DEVOPS-ORCH-34-001 | TODO | Harden production monitoring (synthetic probes, burn-rate alerts, replay smoke), document incident response, and prep GA readiness checklist. Dependencies: DEVOPS-ORCH-33-001. | DevOps Guild, Orchestrator Service Guild (ops/devops)
|
||||
DEVOPS-POLICY-27-001 | TODO | Add CI pipeline stages to run `stella policy lint | DevOps Guild, DevEx/CLI Guild (ops/devops)
|
||||
@@ -37,3 +37,4 @@ Updates
|
||||
- 2025-11-25 · DEVOPS-CI-110-001 runner published at `ops/devops/ci-110-runner/`; initial TRX slices stored under `ops/devops/artifacts/ci-110/20251125T030557Z/` (Concelier health, Excititor airgap import).
|
||||
- 2025-11-25 · MIRROR-CRT-56-CI-001 completed: CI signing script now emits milestone hash summary, enforces DSSE/TUF/time-anchor steps, and uploads `milestone.json` via `mirror-sign.yml`.
|
||||
- 2025-11-25 · DEVOPS-OBS-55-001 completed: added offline incident-mode automation script (`scripts/observability/incident-mode.sh`) and runbook (`ops/devops/observability/incident-mode.md`) to auto-toggle incident flag, retention overrides, and cooldown reset based on burn rate inputs.
|
||||
- 2025-11-25 · DEVOPS-ORCH-32-001 completed: added orchestrator infra compose stack (Postgres+Mongo+NATS), smoke script (`scripts/orchestrator/smoke.sh`), alerts, Grafana dashboard, and bootstrap README under `ops/devops/orchestrator/`.
|
||||
|
||||
@@ -8,6 +8,11 @@ Advisory AI is the retrieval-augmented assistant that synthesizes advisory and V
|
||||
- Propose remediation hints aligned with Offline Kit staging and export bundles.
|
||||
- Expose API/UI surfaces with guardrails on model prompts, outputs, and retention.
|
||||
|
||||
## Contributor quickstart
|
||||
- Read `docs/modules/advisory-ai/AGENTS.md` before making changes; it lists required docs, determinism/offline rules, and working directory scope.
|
||||
- Keep outputs aggregation-only with stable ordering and UTC timestamps; tests must cover guardrails, tenant safety, and provenance.
|
||||
- When updating contracts/telemetry, sync the relevant docs here and cross-link from sprint Decisions & Risks.
|
||||
|
||||
## Key components
|
||||
- RAG pipeline drawing from Conseiller, Excititor, VEX Lens, Policy Engine, and SBOM Service data.
|
||||
- Prompt templates and guard models enforcing provenance and redaction policies.
|
||||
@@ -26,6 +31,13 @@ Advisory AI is the retrieval-augmented assistant that synthesizes advisory and V
|
||||
- Redaction policies validated against security/LLM guardrail tests.
|
||||
- Guardrail behaviour, blocked phrases, and operational alerts are detailed in `/docs/security/assistant-guardrails.md`.
|
||||
|
||||
## Outputs & artefacts
|
||||
- **Run/plan records (deterministic):** persisted under `/app/data/{queue,plans,outputs}` (or `ADVISORYAI__STORAGE__*` overrides) with ISO timestamps, provenance hashes, and stable ordering for replay.
|
||||
- **Service surfaces (air‑gap friendly):** `/ops/advisory-ai/runs` streams NDJSON status; `/ops/advisory-ai/runs/{id}` returns the immutable run/plan bundle with guardrail decisions.
|
||||
- **Events:** worker emits `advisory_ai_run_completed` with digests (plan, output, guardrail) for downstream consumers; feature-flagged to keep offline deployments silent.
|
||||
- **Offline bundle:** `advisory-ai-bundle.tgz` packages prompts, sanitized inputs, outputs, guardrail audit trail, and signatures; build via `docs/modules/advisory-ai/deployment.md` recipes to keep artefacts deterministic across air-gapped imports.
|
||||
- **Observability:** metrics/logs share the `advisory_ai` meter/logger namespace (latency, guardrail blocks/validations, citation coverage). Dashboards and alerts must reference these canonical names to avoid drift.
|
||||
|
||||
## Deployment & configuration
|
||||
- **Containers:** `advisory-ai-web` fronts the API/cache while `advisory-ai-worker` drains the queue and executes prompts. Both containers mount a shared RWX volume providing `/app/data/{queue,plans,outputs}` (defaults; configurable via `ADVISORYAI__STORAGE__*`).
|
||||
- **Remote inference toggle:** Set `ADVISORYAI__INFERENCE__MODE=Remote` to send sanitized prompts to an external inference tier. Provide `ADVISORYAI__INFERENCE__REMOTE__BASEADDRESS` (and optional `...__APIKEY`, `...__TIMEOUT`) to complete the circuit; failures fall back to the sanitized prompt and surface `inference.fallback_*` metadata.
|
||||
|
||||
8
docs/modules/advisory-ai/TASKS.md
Normal file
8
docs/modules/advisory-ai/TASKS.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# Advisory AI · Tasks
|
||||
|
||||
| Task ID | Description | Owner(s) | Sprint | Status | Notes |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| ADVISORY-AI-DOCS-0001 | Align module docs with `AGENTS.md` guardrails and required reading. | Docs Guild | SPRINT_312_docs_modules_advisory_ai | DONE (2025-11-24) | AGENTS/README now call out offline/determinism guardrails and required docs. |
|
||||
| ADVISORY-AI-ENG-0001 | Sync module doc pointers into parent docs tree. | Module Team | SPRINT_312_docs_modules_advisory_ai | DONE (2025-11-24) | Root docs/README now links to Advisory AI dossier. |
|
||||
| ADVISORY-AI-OPS-0001 | Document Advisory AI outputs/artefacts in module README. | Ops Guild | SPRINT_312_docs_modules_advisory_ai | DONE (2025-11-24) | README section expanded with concrete outputs/endpoints/bundles/events. |
|
||||
|
||||
19
docs/modules/attestor/prep/2025-11-24-attest-plan-2001.md
Normal file
19
docs/modules/attestor/prep/2025-11-24-attest-plan-2001.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# Attestation Plan 2001 · Evidence Locker contract handoff (2025-11-24)
|
||||
|
||||
Owners: Evidence Locker Guild · Excititor Guild
|
||||
Status: Published (unblocks ATTEST-PLAN-2001)
|
||||
|
||||
## Inputs
|
||||
- Sealed bundle contract: `docs/modules/evidence-locker/prep/2025-11-24-evidence-locker-contract.md`
|
||||
- Bundle schema: `docs/modules/evidence-locker/schemas/bundle.schema.json`
|
||||
- Sample bundle + hash: `docs/modules/evidence-locker/samples/evidence-bundle-sample.tgz` (+ `.sha256`)
|
||||
|
||||
## Plan
|
||||
1) Align attestation payloads with sealed bundle contract (subjects, DSSE layout, manifest fields).
|
||||
2) Produce CLI/Export Center consumer notes: expected file layout, required hashes, validation steps.
|
||||
3) Add verification harness reference for Excititor/Attestor (reuse sample bundle + DSSE public key from contract note).
|
||||
4) Update downstream sprints (Excititor airgap/export, Export Center) with contract link and hash.
|
||||
|
||||
## Next actions
|
||||
- Evidence Locker Guild: confirm final schema hash matches sample bundle (track in contract note).
|
||||
- Excititor Guild: wire contract path into airgap/attestation tests; report readiness in respective sprints.
|
||||
25
docs/modules/cli/guides/commands/advisory.md
Normal file
25
docs/modules/cli/guides/commands/advisory.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# stella advisory — Command Guide
|
||||
|
||||
## Commands
|
||||
- `stella advisory list --source <provider> [--status <status>] [--output json|ndjson|table] [--offline]`
|
||||
- `stella advisory get --id <advisoryId> [--output json|table] [--offline]`
|
||||
- `stella advisory export --bundle <path> [--offline]`
|
||||
|
||||
## Flags (common)
|
||||
- `--offline`: pull from cached advisory snapshots/mirror bundles only; exit code 5 if remote needed.
|
||||
- `--source`: provider filter (msrc, nvd, osv, csaf, etc.).
|
||||
- `--status`: affected, fixed, not_affected, withdrawn, disputed.
|
||||
- `--output`: json (default), ndjson, table.
|
||||
|
||||
## Inputs/outputs
|
||||
- Inputs: Concelier/Excititor advisory projections; cached mirror bundles when offline.
|
||||
- Outputs: raw evidence with provenance (`observationId`, `linksetId`, signatures); no merging/inference.
|
||||
- Exit codes per `output-and-exit-codes.md`; not found → 4, offline violation → 5.
|
||||
|
||||
## Determinism rules
|
||||
- Sorted by advisory key; withdrawn/duplicate handling matches upstream evidence; no severity inference.
|
||||
- Timestamps UTC; hashes lowercase hex.
|
||||
|
||||
## Offline/air-gap notes
|
||||
- Mirror bundles must be preloaded for offline use; CLI verifies signatures against trust roots.
|
||||
- Export uses local evidence only; produces deterministic bundle with manifest + checksums.
|
||||
21
docs/modules/cli/guides/commands/aoc.md
Normal file
21
docs/modules/cli/guides/commands/aoc.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# stella aoc — Command Guide
|
||||
|
||||
## Commands
|
||||
- `stella aoc verify --input <evidence> [--policy <path>] [--offline]`
|
||||
- `stella aoc explain --input <evidence> [--output json|table]`
|
||||
|
||||
## Flags (common)
|
||||
- `--offline`: verify evidence without remote calls; exit code 5 if network would be required.
|
||||
- `--policy`: optional AOC policy file; defaults to platform policy.
|
||||
- `--output`: json (default), table.
|
||||
|
||||
## Inputs/outputs
|
||||
- Inputs: AOC evidence bundle; optional policy file.
|
||||
- Outputs: verification results with rationale; aggregation-only.
|
||||
- Exit codes per `output-and-exit-codes.md`; 3 for auth failures, 4 for missing evidence, 5 for offline violation.
|
||||
|
||||
## Determinism rules
|
||||
- Stable ordering of findings; timestamps UTC; hashes lowercase hex.
|
||||
|
||||
## Offline/air-gap notes
|
||||
- Trust roots loaded locally; no remote downloads allowed in offline mode.
|
||||
19
docs/modules/cli/guides/commands/auth.md
Normal file
19
docs/modules/cli/guides/commands/auth.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# stella auth — Command Guide
|
||||
|
||||
## Commands
|
||||
- `stella auth login --token <token> [--url <baseUrl>]`
|
||||
- `stella auth status`
|
||||
- `stella auth logout`
|
||||
|
||||
## Flags
|
||||
- `--url`: API base URL; defaults to config/env.
|
||||
- `--token`: bearer token or OIDC device code (future); stored in config if allowed.
|
||||
|
||||
## Behaviour
|
||||
- Login writes token to config file or keyring (where supported) with deterministic permissions; never echoes secrets.
|
||||
- Status prints current user/tenant scopes if available; uses exit code 3 when unauthenticated.
|
||||
- Logout removes stored token and cached session data.
|
||||
|
||||
## Offline/air-gap notes
|
||||
- Login requires network; if `--offline` is set, command must fail with exit code 5.
|
||||
- Status/logout work offline using cached credentials only.
|
||||
25
docs/modules/cli/guides/commands/export.md
Normal file
25
docs/modules/cli/guides/commands/export.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# stella export — Command Guide
|
||||
|
||||
## Commands
|
||||
- `stella export mirror --bundle <path> --profile <name> [--offline]`
|
||||
- `stella export verify --bundle <path> --trust-roots <file>`
|
||||
- `stella export plan --output json` (preview bundle contents)
|
||||
|
||||
## Flags (common)
|
||||
- `--offline`: enforce no network; fail with exit code 5 if registry/object-store calls would occur.
|
||||
- `--profile`: named export profile (schema/manifest version); defaults to latest supported.
|
||||
- `--trust-roots`: PEM/TUF/DSSE trust roots for verification.
|
||||
- `--output`: json (default) or table for plan outputs.
|
||||
|
||||
## Inputs/outputs
|
||||
- Inputs: export profiles, mirror configuration, optional cached artefacts.
|
||||
- Outputs: deterministic bundle tarball + manifest (checksums, signatures, metadata); verify emits status + detailed reasons.
|
||||
- Exit codes follow `output-and-exit-codes.md`; verification failure uses exit code 3.
|
||||
|
||||
## Determinism rules
|
||||
- Manifest ordering is stable; checksums hex-lowercase; timestamps UTC.
|
||||
- No network-dependent mutation; offline bundles must be reproducible.
|
||||
|
||||
## Offline/air-gap notes
|
||||
- `--offline` must be honored; registry pulls are forbidden unless cached in profile path.
|
||||
- Verification uses only local trust roots; no remote key fetch.
|
||||
24
docs/modules/cli/guides/commands/notify.md
Normal file
24
docs/modules/cli/guides/commands/notify.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# stella notify — Command Guide
|
||||
|
||||
## Commands
|
||||
- `stella notify send --channel <email|chat|webhook> --template <id> --data <file>`
|
||||
- `stella notify list --status <pending|sent|failed> [--output json|table] [--offline]`
|
||||
- `stella notify get --id <messageId> [--offline]`
|
||||
|
||||
## Flags (common)
|
||||
- `--offline`: only allowed when notification queue snapshots are cached; otherwise exit code 5.
|
||||
- `--tenant`: scope to tenant; enforced by server RLS.
|
||||
- `--output`: json/ndjson/table.
|
||||
|
||||
## Inputs/outputs
|
||||
- Inputs: Notify API; optional cached queue snapshots when offline.
|
||||
- Outputs: message metadata, status, delivery results; no template content leaks.
|
||||
- Exit codes follow `output-and-exit-codes.md`; 4 for not found, 5 for offline violation.
|
||||
|
||||
## Determinism rules
|
||||
- Listings sorted by created time then id; timestamps UTC.
|
||||
- No retries triggered by the CLI; it only submits/reads.
|
||||
|
||||
## Offline/air-gap notes
|
||||
- Sending in offline mode is disallowed (exit code 5); only listing cached snapshots is permitted.
|
||||
- Templates must be preloaded; no remote fetches when `--offline`.
|
||||
23
docs/modules/cli/guides/commands/orchestrator.md
Normal file
23
docs/modules/cli/guides/commands/orchestrator.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# stella orchestrator — Command Guide
|
||||
|
||||
## Commands
|
||||
- `stella orchestrator jobs list --output json|table [--offline]`
|
||||
- `stella orchestrator jobs get --id <jobId> [--offline]`
|
||||
- `stella orchestrator runs get --id <runId> [--offline]`
|
||||
|
||||
## Flags (common)
|
||||
- `--offline`: only allowed when cached ledger snapshots are available; otherwise exit code 5.
|
||||
- `--status`, `--type`: filters for job listings; deterministic sort by created time then id.
|
||||
- `--output`: json/ndjson/table.
|
||||
|
||||
## Inputs/outputs
|
||||
- Inputs: Orchestrator API or cached run ledger snapshots.
|
||||
- Outputs: job/run metadata with provenance hashes and DSSE/attestation pointers when available.
|
||||
- Exit codes per `output-and-exit-codes.md`; 4 for not found, 5 for offline violation.
|
||||
|
||||
## Determinism rules
|
||||
- Sorted outputs; timestamps UTC; hashes hex lowercase.
|
||||
- No inferred state beyond orchestrator responses.
|
||||
|
||||
## Offline/air-gap notes
|
||||
- Ledger snapshots must be preloaded; no live scheduler calls when `--offline`.
|
||||
25
docs/modules/cli/guides/commands/policy.md
Normal file
25
docs/modules/cli/guides/commands/policy.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# stella policy — Command Guide
|
||||
|
||||
## Commands
|
||||
- `stella policy eval --input <bundle> --subject <sbom|vex|vuln> [--offline] [--output json|ndjson|table]`
|
||||
- `stella policy simulate --from <bundleA> --to <bundleB> [--budget <ms>] [--offline]`
|
||||
- `stella policy publish --input <bundle> --sign --attest`
|
||||
|
||||
## Flags (common)
|
||||
- `--offline` / `STELLA_OFFLINE=1`: forbid network calls; use cached bundles only.
|
||||
- `--tenant <id>`: scope evaluation to tenant; RLS enforcement required on the server.
|
||||
- `--rationale`: include rationale IDs in responses.
|
||||
- `--output`: `json` (default), `ndjson`, or `table`.
|
||||
|
||||
## Inputs/outputs
|
||||
- Inputs: policy bundles (signed), subject artifacts (SBOM/VEX/Vuln snapshots).
|
||||
- Outputs: deterministic JSON/NDJSON or tables; includes `correlationId`, `policyVersion`, `rationaleIds` when requested.
|
||||
- Exit codes follow `output-and-exit-codes.md`.
|
||||
|
||||
## Determinism rules
|
||||
- Sort evaluation results by subject key; timestamps UTC ISO-8601.
|
||||
- No inferred verdicts beyond Policy Engine response.
|
||||
|
||||
## Offline/air-gap notes
|
||||
- When `--offline`, evaluation must use locally cached bundles and subject artifacts; fail with exit code 5 if network would be needed.
|
||||
- Trust roots loaded from `STELLA_TRUST_ROOTS` when verifying signed bundles.
|
||||
25
docs/modules/cli/guides/commands/sbom.md
Normal file
25
docs/modules/cli/guides/commands/sbom.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# stella sbom — Command Guide
|
||||
|
||||
## Commands
|
||||
- `stella sbom generate --image <ref> [--output sbom.spdx.json] [--offline]`
|
||||
- `stella sbom compose --fragment <path> --output composition.json --offline`
|
||||
- `stella sbom verify --file <sbom> --signature <sig> --key <keyfile>`
|
||||
|
||||
## Flags (common)
|
||||
- `--offline`: no network pulls; use local cache/OCI archive.
|
||||
- `--format`: `spdx-json` (default) or `cyclonedx-json`.
|
||||
- `--attest`: emit DSSE attestation alongside SBOM.
|
||||
- `--hash`: include layer/file hashes (deterministic ordering).
|
||||
|
||||
## Inputs/outputs
|
||||
- Inputs: container image, directory, or fragments.
|
||||
- Outputs: deterministic SPDX/CycloneDX JSON, optional DSSE + checksums.
|
||||
- Exit codes per `output-and-exit-codes.md`; verification failure uses exit code 3 or 4 depending on cause.
|
||||
|
||||
## Determinism rules
|
||||
- Stable ordering of packages/files; timestamps UTC.
|
||||
- Hashes hex-lowercase; no host-specific paths.
|
||||
|
||||
## Offline/air-gap notes
|
||||
- With `--offline`, image sources must already be cached (tar/OCI archive); command fails with exit code 5 if it would fetch remotely.
|
||||
- Verification uses local trust roots; no remote key fetch.
|
||||
23
docs/modules/cli/guides/commands/vex.md
Normal file
23
docs/modules/cli/guides/commands/vex.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# stella vex — Command Guide
|
||||
|
||||
## Commands
|
||||
- `stella vex consensus --query <filter> [--output json|ndjson|table] [--offline]`
|
||||
- `stella vex get --id <consensusId> [--offline]`
|
||||
- `stella vex simulate --input <vexDocs> --policy <policyConfig> [--offline]`
|
||||
|
||||
## Flags (common)
|
||||
- `--offline`: use cached consensus snapshots; fail with exit code 5 if remote would be hit.
|
||||
- `--policy <path>`: apply trust/weighting config; aggregation-only outputs.
|
||||
- `--page-size`, `--page-token`: deterministic pagination.
|
||||
|
||||
## Inputs/outputs
|
||||
- Inputs: VEX consensus projection (VexLens); optional cached snapshots when offline.
|
||||
- Outputs: consensus states with `consensus_state`, `confidence`, `weights`, `issuers`, `rationale`; stable ordering.
|
||||
|
||||
## Determinism rules
|
||||
- Sort by `consensusId`; pagination tokens deterministic.
|
||||
- No verdict inference beyond upstream consensus projection; CLI stays aggregation-only.
|
||||
|
||||
## Offline/air-gap notes
|
||||
- Cached snapshots are required when `--offline`; otherwise exit code 5 with remediation message.
|
||||
- Trust roots for signature verification are loaded from `STELLA_TRUST_ROOTS` when verifying cached snapshots.
|
||||
25
docs/modules/cli/guides/commands/vuln.md
Normal file
25
docs/modules/cli/guides/commands/vuln.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# stella vuln — Command Guide
|
||||
|
||||
## Commands
|
||||
- `stella vuln list --query <filter> [--group-by <field>] [--output json|ndjson|table] [--offline]`
|
||||
- `stella vuln get --id <vulnId> [--output json|table] [--offline]`
|
||||
- `stella vuln simulate --from <policyA> --to <policyB> --subjects <path> [--offline]`
|
||||
|
||||
## Flags (common)
|
||||
- `--offline`: read from cached snapshots; fail with exit code 5 if network would be used.
|
||||
- `--policy <id>`: scope queries to a policy projection.
|
||||
- `--page-size`, `--page-token`: deterministic pagination.
|
||||
- `--group-by`: `cve`, `package`, `status`, `advisory` (results stay stably ordered within groups).
|
||||
|
||||
## Inputs/outputs
|
||||
- Inputs: Vuln Explorer API; optional cached snapshots when offline.
|
||||
- Outputs: sorted lists or detail documents with provenance pointers (`advisoryId`, `evidenceIds`, `consensusId`).
|
||||
- Exit codes follow `output-and-exit-codes.md`; 4 for not found, 5 for offline violation.
|
||||
|
||||
## Determinism rules
|
||||
- Lists sorted by primary key then timestamp; group-by keeps stable ordering inside each bucket.
|
||||
- Timestamps UTC ISO-8601; hashes lower-case hex.
|
||||
|
||||
## Offline/air-gap notes
|
||||
- Use cached snapshots (`--offline`) when remote Explorer is unavailable; commands must not attempt network calls in this mode.
|
||||
- Simulation must read local policy snapshots and subjects when offline.
|
||||
40
docs/modules/cli/guides/configuration.md
Normal file
40
docs/modules/cli/guides/configuration.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# stella CLI — Configuration
|
||||
|
||||
## Precedence (highest → lowest)
|
||||
1. Command-line flags (e.g., `--output json`, `--offline`)
|
||||
2. Environment variables
|
||||
3. Config file (`config.yaml`/`config.json`) loaded from the first existing path:
|
||||
- `$STELLA_CONFIG` (explicit override)
|
||||
- `$XDG_CONFIG_HOME/stella/config.yaml` (or `%APPDATA%\\Stella\\config.yaml` on Windows)
|
||||
- `$HOME/.config/stella/config.yaml`
|
||||
|
||||
Tip: keep secrets in env vars, not in the config file; tokens are read from `STELLA_TOKEN`, registry creds from `STELLA_REGISTRY_AUTH`, etc.
|
||||
|
||||
## Common settings (YAML example)
|
||||
```yaml
|
||||
output: json # json|ndjson|table
|
||||
offline: true # force no-network mode
|
||||
api:
|
||||
baseUrl: https://console.stella.local
|
||||
token: ${STELLA_TOKEN} # prefer env substitution
|
||||
policy:
|
||||
tenant: demo-tenant
|
||||
rationale: true
|
||||
airgap:
|
||||
bundlesPath: /var/stella/bundles
|
||||
trustRoots: /var/stella/trust/roots.pem
|
||||
observability:
|
||||
traceparent: auto # always inject trace headers when available
|
||||
```
|
||||
|
||||
## Air-gap/offline knobs
|
||||
- `--offline` or `STELLA_OFFLINE=1` forbids network calls; commands must rely on local bundles/caches.
|
||||
- `airgap.bundlesPath` controls where imports/exports read/write sealed bundles.
|
||||
- Mirror/import/export commands respect `STELLA_TRUST_ROOTS` for DSSE/TUF verification.
|
||||
|
||||
## Logging & telemetry
|
||||
- `STELLA_LOG_LEVEL=debug` for verbose logs; `trace` adds wire dumps (still deterministic).
|
||||
- Tracing headers: CLI injects `traceparent` when provided by the environment (CI runners, gateways); never emits PII.
|
||||
|
||||
## Profiles (planned)
|
||||
- Profiles will live under `profiles/<name>.yaml` and can be selected with `--profile <name>`; until shipped, stick to the single default config file.
|
||||
32
docs/modules/cli/guides/forensics.md
Normal file
32
docs/modules/cli/guides/forensics.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# stella CLI — Forensics Guide
|
||||
|
||||
## Commands
|
||||
- `stella forensic snapshot create --case <id> --output <path>`: capture current evidence snapshot; emits manifest + checksums.
|
||||
- `stella forensic verify --bundle <path>`: validate checksums, DSSE signatures, and timeline chain-of-custody.
|
||||
- `stella attest verify --file <attestation>`: reuse attestor flows for envelope verification (see `guides/commands/attest.md`).
|
||||
|
||||
## Flags
|
||||
- `--offline`: prohibit network access; use local bundles only (exit code 5 if remote call would occur).
|
||||
- `--output json|table` (default json) for verification results.
|
||||
- `--trust-roots <file>`: PEM/TUF/DSSE trust roots for verification.
|
||||
|
||||
## Outputs & exit codes
|
||||
- Success → 0; verification failure → 3; missing bundle → 4; offline violation → 5.
|
||||
- Verification output includes `status`, `checksum`, `signature`, `subject`, `rationale` fields; ordering is deterministic.
|
||||
|
||||
## Determinism rules
|
||||
- Snapshots record UTC timestamps and stable file ordering; hashes are lowercase hex.
|
||||
- CLI never mutates evidence; it only validates and reports.
|
||||
|
||||
## Offline/air-gap notes
|
||||
- Always supply trust roots from sealed media when in air-gap mode; no remote key fetch is allowed.
|
||||
- Store snapshots under a deterministic path (`case-id/date/`) to simplify audits.
|
||||
|
||||
## Examples
|
||||
```bash
|
||||
# Create a snapshot for case ACME-123
|
||||
stella forensic snapshot create --case ACME-123 --output out/forensics/acme-123.tgz
|
||||
|
||||
# Verify a snapshot with pinned trust roots
|
||||
stella forensic verify --bundle out/forensics/acme-123.tgz --trust-roots trust/roots.pem --output table
|
||||
```
|
||||
32
docs/modules/cli/guides/observability.md
Normal file
32
docs/modules/cli/guides/observability.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# stella CLI — Observability Guide
|
||||
|
||||
## Commands
|
||||
- `stella obs top` (planned): stream service health (SLO/burn-rate, queue depth, error rates) with table/JSON output.
|
||||
- `stella obs trace <trace_id>`: fetch correlated trace if server supports it; prints correlation/trace IDs.
|
||||
- `stella obs logs --from <ts> --to <ts> [--service <name>]`: pull logs for a window with pagination tokens.
|
||||
|
||||
## Flags
|
||||
- `--output json|ndjson|table` (default: json).
|
||||
- `--offline`: when set, commands must operate on cached logs/trace bundles only; if remote access would be used, exit code 5.
|
||||
- `--page-size`, `--page-token`: deterministic pagination.
|
||||
|
||||
## Output & exit codes
|
||||
- Exit codes follow `guides/output-and-exit-codes.md` (not found → 4; offline violation → 5).
|
||||
- Correlation IDs and trace IDs are echoed on stderr in verbose mode for scripting/debugging.
|
||||
|
||||
## Determinism & privacy
|
||||
- Logs/trace exports are ordered by timestamp then id; timestamps are UTC ISO-8601.
|
||||
- CLI never redacts server-side; it only forwards what the API returns. Avoid printing secrets—use `--output json` with `jq` to filter locally.
|
||||
|
||||
## Offline/air-gap
|
||||
- With `--offline`, `stella obs *` must read only cached bundles; no network calls are allowed.
|
||||
- For sealed environments, pass `--trust-roots <pem>` when verifying cached trace/log bundles.
|
||||
|
||||
## Examples
|
||||
```bash
|
||||
# Fetch logs for the last hour in NDJSON
|
||||
stella obs logs --from "2025-11-25T01:00:00Z" --to "2025-11-25T02:00:00Z" --output ndjson
|
||||
|
||||
# Retrieve a trace and pretty print spans
|
||||
stella obs trace 4f2c8d1c-3b1e-4a7f-9e4a-1f4c56 --output json | jq '.spans[0]'
|
||||
```
|
||||
34
docs/modules/cli/guides/output-and-exit-codes.md
Normal file
34
docs/modules/cli/guides/output-and-exit-codes.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# stella CLI — Output & Exit Codes
|
||||
|
||||
## Output formats
|
||||
- `--output json` (default): deterministic JSON objects per record.
|
||||
- `--output ndjson`: one JSON object per line for streaming/large results.
|
||||
- `--output table`: aligned columns for humans; preserves stable column order.
|
||||
- Use `--quiet` to suppress informational logs; errors still print to stderr.
|
||||
|
||||
## Exit codes (contract)
|
||||
- `0` — Success.
|
||||
- `1` — Generic error (unexpected exception).
|
||||
- `2` — Validation or user input error.
|
||||
- `3` — AuthN/AuthZ failure (expired token, missing scope).
|
||||
- `4` — Not found / resource missing.
|
||||
- `5` — Network disabled/offline violation when a command requires connectivity.
|
||||
- `10` — Retryable/transient error (service unavailable, backoff suggested).
|
||||
|
||||
Clients and scripts should treat `2–5` as non-retryable unless input changes; only `10` should trigger automated retry with backoff.
|
||||
|
||||
## Determinism & ordering
|
||||
- Lists are sorted (stable) by primary key or timestamp per command documentation.
|
||||
- Timestamps are UTC ISO-8601; hashes use hex lowercase.
|
||||
- Randomness is seeded; avoid machine-specific paths in emitted artefacts.
|
||||
|
||||
## Examples
|
||||
```bash
|
||||
stella vuln list --output json | jq '.items[0]'
|
||||
stella export mirror --offline --output ndjson > mirror.ndjson
|
||||
stella task-runner simulate --output table
|
||||
```
|
||||
|
||||
## Observability signals
|
||||
- When tracing headers are present (`traceparent`), CLI propagates them; otherwise it emits new span IDs only in verbose logs.
|
||||
- Metrics are not emitted by the CLI itself; servers capture request telemetry and can be correlated via the returned correlation/trace IDs printed on errors in verbose mode.
|
||||
32
docs/modules/cli/guides/overview.md
Normal file
32
docs/modules/cli/guides/overview.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# stella CLI — Overview
|
||||
|
||||
## What it does
|
||||
- Single entrypoint for scans, exports, policy management, VEX/Vuln queries, air-gapped kit operations, and task-runner interactions.
|
||||
- Evidence-preserving: the CLI never mutates upstream evidence; it emits signed manifests and deterministic JSON/NDJSON where possible.
|
||||
- Offline-ready: every command must run with cached feeds/bundles when `STELLA_OFFLINE=1` or `--offline` is set.
|
||||
|
||||
## Core verbs (at a glance)
|
||||
- `stella scan ...` — container/dir scans; emits SBOM + findings bundles.
|
||||
- `stella policy ...` — push/eval/simulate policy bundles; attach evidence; request rationale.
|
||||
- `stella vex ...` / `stella vuln ...` — query VEX consensus and vulnerability projections with pagination/budgets.
|
||||
- `stella export ...` — mirror/export bundles; verify signatures; produce checksums/attestations.
|
||||
- `stella airgap ...` — import/export sealed bundles; validate trust roots; run without network.
|
||||
- `stella task-runner ...` — submit/inspect pack runs; stream logs; collect artefacts.
|
||||
|
||||
## Imposed rules (apply to every command)
|
||||
- Determinism first: stable ordering, UTC ISO-8601 timestamps, no host-specific paths in outputs.
|
||||
- Aggregation-only: if a command shows advisory/VEX data, it must not infer verdicts beyond published evidence.
|
||||
- Offline/air-gap parity: every feature documents its offline flag(s) and expected cache locations.
|
||||
|
||||
## Quick start
|
||||
```bash
|
||||
stella --help # top-level verbs
|
||||
stella scan image ghcr.io/acme/app:1.2.3 --output json --offline
|
||||
stella policy eval --input policy.bundle.json --subject sbom.spdx.jsonl --explain
|
||||
stella export mirror --bundle out/mirror.tgz --verify
|
||||
```
|
||||
|
||||
## Where to read next
|
||||
- Configuration precedence and file locations: `configuration.md`
|
||||
- Output formats and exit codes: `output-and-exit-codes.md`
|
||||
- Command-specific guides: see `cli-reference.md` and verb-specific guides under `guides/`.
|
||||
19
docs/modules/cli/guides/parity-matrix.md
Normal file
19
docs/modules/cli/guides/parity-matrix.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# stella CLI — Parity Matrix
|
||||
|
||||
Use this matrix to verify that CLI surfaces match the corresponding service APIs, schemas, and offline behaviours. Every row must stay deterministic and aggregation-only.
|
||||
|
||||
| Area | Server/API | CLI command(s) | Output contract | Offline support | Notes |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| Policy eval/simulate | Policy Engine `/policy/eval` `/policy/simulate` | `stella policy eval`, `stella policy simulate` | Stable JSON/NDJSON; includes `correlationId`, `policyVersion`, `rationaleIds` | Must run with cached bundles when `--offline` | No verdict inference beyond engine response. |
|
||||
| VEX consensus | VexLens `/vex/consensus` | `stella vex consensus` | Deterministic pagination; weights/issuers/rationale echoed | Cached consensus snapshots permitted | Uses aggregation-only contract. |
|
||||
| Vulnerability list/detail | Vuln Explorer `/vuln` | `stella vuln list`, `stella vuln get` | Sorted by `vulnId`; includes provenance pointers; no missing fields inferred | Must respect `--offline` using cached snapshots | |
|
||||
| Export/mirror bundles | Export Service `/export/*` | `stella export mirror`, `stella export verify` | Emits manifest + checksums; verification errors are deterministic | Yes (air-gap bundles) | All paths must be relative and normalized. |
|
||||
| Air-gap import/export | AirGap `/airgap/*` | `stella airgap import`, `stella airgap export` | Returns sealed bundle IDs, provenance hashes | Yes; network calls forbidden when `--offline` or sealed mode | |
|
||||
| Task Runner | TaskRunner `/runs` | `stella task-runner run`, `stella task-runner logs` | Monotonic log stream; stable ordering by `sequence` | Local/log-only when offline; remote requires connectivity | |
|
||||
| Attestations | Attestor `/attest/*` | `stella attest verify`, `stella attest list` | Verification results include DSSE status, signature details; no risk scoring | Yes, using cached trust roots/bundles | |
|
||||
| SBOM | Scanner `/sbom/*` | `stella sbom generate`, `stella sbom compose` | Emits SPDX/CycloneDX + hashes; preserves ordering | Yes; reads local images/files when offline | |
|
||||
|
||||
Validation checklist:
|
||||
- Commands echo correlation/trace IDs on errors (verbose mode) to match server logs.
|
||||
- Exit codes follow the contract in `output-and-exit-codes.md`.
|
||||
- When a server feature is unavailable offline, the CLI must fail with exit code 5 and an actionable message.
|
||||
73
docs/modules/concelier/api/evidence-batch.md
Normal file
73
docs/modules/concelier/api/evidence-batch.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# Concelier Evidence Batch API (draft v1)
|
||||
|
||||
Path: `POST /v1/evidence/batch`
|
||||
Auth: same as other advisory read endpoints; requires tenant header `X-Stella-Tenant`.
|
||||
Purpose: allow graph/UI/export clients to fetch observations and linksets for a set of components (purls/aliases) in one round-trip, without derived judgments.
|
||||
|
||||
## Request
|
||||
```json
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"componentId": "component-a",
|
||||
"purls": ["pkg:maven/org.example/app@1.0.0"],
|
||||
"aliases": ["CVE-2025-0001"]
|
||||
}
|
||||
],
|
||||
"observationLimit": 50,
|
||||
"linksetLimit": 50
|
||||
}
|
||||
```
|
||||
|
||||
Field rules:
|
||||
- `items` is required and must be non-empty.
|
||||
- Each item must supply at least one identifier (`purls` or `aliases`).
|
||||
- `observationLimit` and `linksetLimit` default to 50, max 200; values ≤0 are ignored.
|
||||
|
||||
## Response
|
||||
```json
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"componentId": "component-a",
|
||||
"observations": [
|
||||
{
|
||||
"id": "obs:123",
|
||||
"tenant": "demo",
|
||||
"aliases": ["CVE-2025-0001"],
|
||||
"purls": ["pkg:maven/org.example/app@1.0.0"],
|
||||
"source": "nvd",
|
||||
"asOf": "2025-11-25T12:00:00Z"
|
||||
}
|
||||
],
|
||||
"linksets": [
|
||||
{
|
||||
"advisoryId": "CVE-2025-0001",
|
||||
"source": "nvd",
|
||||
"normalized": {
|
||||
"purls": ["pkg:maven/org.example/app@1.0.0"]
|
||||
},
|
||||
"createdAt": "2025-11-25T12:00:00Z"
|
||||
}
|
||||
],
|
||||
"hasMore": false,
|
||||
"retrievedAt": "2025-11-25T12:00:01Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Determinism:
|
||||
- Results ordered by provider ordering returned from storage; clients must not assume stable sort keys beyond the documented arrays.
|
||||
- `retrievedAt` is server UTC ISO-8601.
|
||||
- `hasMore` is true if either observations or linksets were truncated by the supplied limits.
|
||||
|
||||
Notes:
|
||||
- No derived severity/weights are added; payloads mirror stored observations/linksets.
|
||||
- For empty matches, the endpoint returns empty `observations` and `linksets` with `hasMore=false`.
|
||||
|
||||
Fixtures:
|
||||
- Sample request/response above; further fixtures can be generated from `docs/samples/lnm/` data once LNM v1 fixtures are refreshed.
|
||||
|
||||
Changelog:
|
||||
- 2025-11-25: initial draft and implementation aligned with `/v1/evidence/batch` endpoint.
|
||||
@@ -56,12 +56,18 @@
|
||||
- **Unit**: guard rejection paths, provenance enforcement, idempotent insertions, linkset determinism.
|
||||
- **Property**: fuzz upstream payloads to guarantee no forbidden fields emerge.
|
||||
- **Integration**: batch ingest (50k advisories, mixed VEX fixtures), verifying zero guard violations and consistent supersedes.
|
||||
- **Contract**: Policy Engine consumers verify raw-only reads; Export Center consumes canonical datasets.
|
||||
- **End-to-end**: ingest/verify flow with CLI + Console actions to confirm observability and guard reporting.
|
||||
|
||||
## Definition of done
|
||||
- Validators deployed and verified in staging/offline environments.
|
||||
- Runtime guards, CLI/Console workflows, and CI linting all active.
|
||||
- Observability dashboards and runbooks updated; metrics visible.
|
||||
- Documentation updates merged; Offline Kit instructions published.
|
||||
- ./TASKS.md reflects status transitions; cross-module dependencies acknowledged in ../../TASKS.md.
|
||||
- **Contract**: Policy Engine consumers verify raw-only reads; Export Center consumes canonical datasets.
|
||||
- **End-to-end**: ingest/verify flow with CLI + Console actions to confirm observability and guard reporting.
|
||||
|
||||
## Definition of done
|
||||
- Validators deployed and verified in staging/offline environments.
|
||||
- Runtime guards, CLI/Console workflows, and CI linting all active.
|
||||
- Observability dashboards and runbooks updated; metrics visible.
|
||||
- Documentation updates merged; Offline Kit instructions published.
|
||||
- ./TASKS.md reflects status transitions; cross-module dependencies acknowledged in ../../TASKS.md.
|
||||
|
||||
## Readiness checkpoints (2025-11-25)
|
||||
- Sprint 110 attestation chain validated: `/internal/attestations/verify` endpoint and evidence bundle tests green (`TestResults/concelier-attestation/web.trx`, `core.trx`).
|
||||
- Link-Not-Merge cache + console consumption docs frozen (see `operations/lnm-cache-plan.md`, `operations/console-lnm-consumption.md`); cache headers remain deterministic.
|
||||
- Observation events transport reviewed; backlog guardrails and NATS/air-gap guidance updated in `operations/observation-events.md`.
|
||||
- Next gating dependency: TaskRunner contract drop (sprint 0157 blockers) before wiring approvals/pack ingest flows into Concelier.
|
||||
|
||||
@@ -29,3 +29,9 @@ Defaults: disabled, transport `mongo`; subject/stream as above.
|
||||
## Testing
|
||||
- Without NATS: leave `enabled=false`; app continues writing outbox only.
|
||||
- With NATS: run a local `nats-server -js` and set `enabled=true transport=nats`. Verify published messages on subject via `nats sub concelier.advisory.observation.updated.v1`.
|
||||
|
||||
## 2025-11-25 demo review notes
|
||||
- Verified attestation demo emits `StellaOps.Concelier.Advisory.Observations` meter with counters `events_published_total` and gauges `outbox_backlog`. Ensure these metrics are scraped with tenant labels.
|
||||
- Backlog guard: alert if `outbox_backlog > 500` for 10m while `transport=nats`; recommended SLO is P95 publish latency < 2s.
|
||||
- When transport disabled for air-gap runs, confirm background worker remains paused (`enabled=false`) to avoid noisy retries; resume only after mirror bundles restored.
|
||||
- TRX from `/internal/attestations/verify` suite lives at `TestResults/concelier-attestation/web.trx` for current demo build; keep alongside dashboards for reproducibility.
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
# Evidence Locker sealed bundle contract · 2025-11-24
|
||||
|
||||
Owners: Evidence Locker Guild · Security Guild
|
||||
Status: Published 2025-11-24 (source for ELOCKER-CONTRACT-2001)
|
||||
|
||||
## Deliverables
|
||||
- Bundle schema: `bundle.schema.json` (sealed DSSE envelope + manifest) — stored under `docs/modules/evidence-locker/schemas/bundle.schema.json`.
|
||||
- DSSE layout: subject digests, payload (`evidence_bundle.json`), and signatures recorded; transparency optional; canonical hash: `SHA256:6f51d7a5c9d0c5db8a1f6e9d4a0af13e3e7eb5bcb4fa8457de99d8b1c2b3b8ff`.
|
||||
- Sample bundle: `docs/modules/evidence-locker/samples/evidence-bundle-sample.tgz` with accompanying `.sha256` file.
|
||||
|
||||
## Scope and guarantees
|
||||
- Sealed, offline-friendly; deterministic ordering of files in the tarball; UTC timestamps fixed to `1970-01-01T00:00:00Z` for reproducibility.
|
||||
- Payload includes: `manifest.json`, `evidence_bundle.json`, `signatures/` (DSSE), `checksums.txt`.
|
||||
- No network dependencies; validation and hashing performed locally.
|
||||
|
||||
## Validation
|
||||
- `docs/modules/evidence-locker/schemas/bundle.schema.json` validated via `ajv` offline run (see `prep/validate.sh`).
|
||||
- DSSE signature verifies with sample keypair; transparency step skipped (optional).
|
||||
|
||||
## Next steps
|
||||
- Publish NuGet contract (if needed) referencing the schema path.
|
||||
- Provide CLI/Export Center consumers with manifest path and hash above.
|
||||
- Unblock ATTEST-PLAN-2001; keep downstream sprints updated.
|
||||
@@ -85,6 +85,26 @@ This note defines the deterministic, aggregation-only contract that Excititor ex
|
||||
- When mirror bundles are configured, `provenance.canonicalUri` points to the local bundle path; otherwise it is omitted.
|
||||
- All payloads are side-effect free; no remote fetches occur while streaming.
|
||||
|
||||
## Airgap import (sealed mode) — EXCITITOR-AIRGAP-56/57/58
|
||||
- Endpoint: `POST /airgap/v1/vex/import` (thin bundle envelope). Deterministic fields: `bundleId`, `mirrorGeneration`, `signedAt`, `publisher`, `payloadHash`, optional `payloadUrl`, `signature` (base64), optional `transparencyLog`, optional `tenantId`.
|
||||
- Sealed-mode toggle: set `EXCITITOR_SEALED=1` or `Excititor:Airgap:SealedMode=true`. When enabled:
|
||||
- External payload URLs are rejected with **AIRGAP_EGRESS_BLOCKED** (HTTP 403).
|
||||
- Optional allowlist `Excititor:Airgap:TrustedPublishers` gates mirror publishers; failures return **AIRGAP_SOURCE_UNTRUSTED** (HTTP 403).
|
||||
- Error catalog (all 4xx):
|
||||
- **AIRGAP_SIGNATURE_MISSING** / **AIRGAP_SIGNATURE_INVALID**
|
||||
- **AIRGAP_PAYLOAD_STALE** (±5s clock skew guard)
|
||||
- **AIRGAP_SOURCE_UNTRUSTED** (unknown/blocked publisher or signer set)
|
||||
- **AIRGAP_PAYLOAD_MISMATCH** (bundle hash not in signer manifest)
|
||||
- **AIRGAP_EGRESS_BLOCKED** (sealed mode forbids HTTP/HTTPS payloadUrl)
|
||||
- **AIRGAP_IMPORT_DUPLICATE** (idempotent on `(bundleId,mirrorGeneration)`)
|
||||
- Portable manifest outputs (EXCITITOR-AIRGAP-58-001):
|
||||
- Response echoes `manifest`, `manifestSha256`, `evidence` paths derived from the bundle ID/generation; also persisted on the import record.
|
||||
- Evidence Locker linkage: `evidence/{bundleId}/{generation}/bundle.ndjson` path recorded for downstream replay/export.
|
||||
- Timeline events (deterministic order, ISO timestamps):
|
||||
- `airgap.import.started`, `airgap.import.completed`, `airgap.import.failed`
|
||||
- Attributes: `{tenantId,bundleId,generation,stalenessSeconds?,errorCode?}`
|
||||
- Emitted for every import attempt; stored on the import record and logged for audit.
|
||||
|
||||
## Samples
|
||||
- NDJSON sample: `docs/samples/excititor/chunks-sample.ndjson` (hashes in `.sha256`) aligned to the schema above.
|
||||
|
||||
|
||||
7
docs/modules/vuln-explorer/api.md
Normal file
7
docs/modules/vuln-explorer/api.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Vuln Explorer API – draft v1 (2025-11-25)
|
||||
|
||||
- OpenAPI: `docs/modules/vuln-explorer/openapi/vuln-explorer.v1.yaml`
|
||||
- Scope: read-only vulnerability listing/detail for Console/CLI; deterministic ordering (score desc, id asc) with opaque page tokens.
|
||||
- Required headers: `x-stella-tenant`; optional `policyVersion`.
|
||||
- Filters: CVE, PURL, severity band, exploitability flag, fixAvailable.
|
||||
- Responses include policyVersion + rationaleId for explainability; provenance anchors back to Findings Ledger/evidence bundles.
|
||||
188
docs/modules/vuln-explorer/openapi/vuln-explorer.v1.yaml
Normal file
188
docs/modules/vuln-explorer/openapi/vuln-explorer.v1.yaml
Normal file
@@ -0,0 +1,188 @@
|
||||
# Vuln Explorer API · v1 (draft 2025-11-25)
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: StellaOps Vuln Explorer API
|
||||
version: "1.0.0-draft.2025-11-25"
|
||||
description: >
|
||||
Read-only vulnerability exploration surface. All responses are deterministic
|
||||
under identical inputs and include policy version + rationale identifiers.
|
||||
servers:
|
||||
- url: https://{host}
|
||||
variables:
|
||||
host:
|
||||
default: vuln-explorer.local
|
||||
tags:
|
||||
- name: Vulns
|
||||
paths:
|
||||
/vulns:
|
||||
get:
|
||||
summary: List vulnerabilities
|
||||
tags: [Vulns]
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/Tenant'
|
||||
- $ref: '#/components/parameters/PolicyVersion'
|
||||
- $ref: '#/components/parameters/PageSize'
|
||||
- $ref: '#/components/parameters/PageToken'
|
||||
- $ref: '#/components/parameters/Cve'
|
||||
- $ref: '#/components/parameters/Purl'
|
||||
- $ref: '#/components/parameters/Severity'
|
||||
- $ref: '#/components/parameters/Exploitability'
|
||||
- $ref: '#/components/parameters/FixAvailable'
|
||||
responses:
|
||||
'200':
|
||||
description: Paged vulnerabilities ordered by (score desc, id asc).
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/VulnListResponse'
|
||||
/vulns/{id}:
|
||||
get:
|
||||
summary: Get vulnerability by stable ID
|
||||
tags: [Vulns]
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/Tenant'
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
description: Stable vulnerability id (hash over source ids+purls).
|
||||
responses:
|
||||
'200':
|
||||
description: Vulnerability detail with evidence/provenance.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Vuln'
|
||||
'404':
|
||||
description: Not found for tenant/policy scope.
|
||||
|
||||
components:
|
||||
parameters:
|
||||
Tenant:
|
||||
name: x-stella-tenant
|
||||
in: header
|
||||
required: true
|
||||
schema: { type: string }
|
||||
description: Tenant identifier; required for all endpoints.
|
||||
PolicyVersion:
|
||||
name: policyVersion
|
||||
in: query
|
||||
schema: { type: string }
|
||||
description: Policy version/rationale to contextualise scores.
|
||||
PageSize:
|
||||
name: pageSize
|
||||
in: query
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 1
|
||||
maximum: 200
|
||||
default: 50
|
||||
description: Max items per page.
|
||||
PageToken:
|
||||
name: pageToken
|
||||
in: query
|
||||
schema: { type: string }
|
||||
description: Opaque token encoding last (score,id) tuple.
|
||||
Cve:
|
||||
name: cve
|
||||
in: query
|
||||
schema: { type: array, items: { type: string }, minItems: 1 }
|
||||
style: form
|
||||
explode: true
|
||||
description: Filter by CVE ids.
|
||||
Purl:
|
||||
name: purl
|
||||
in: query
|
||||
schema: { type: array, items: { type: string }, minItems: 1 }
|
||||
style: form
|
||||
explode: true
|
||||
description: Filter by PURL(s); matches affected packages.
|
||||
Severity:
|
||||
name: severity
|
||||
in: query
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
enum: [CRITICAL, HIGH, MEDIUM, LOW, NONE]
|
||||
style: form
|
||||
explode: true
|
||||
description: Filter by normalized severity band.
|
||||
Exploitability:
|
||||
name: exploitability
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
enum: [known, likely, unknown, none]
|
||||
description: Derived exploitability flag (from KEV + VEX + telemetry).
|
||||
FixAvailable:
|
||||
name: fixAvailable
|
||||
in: query
|
||||
schema: { type: boolean }
|
||||
description: Whether at least one fix is available.
|
||||
|
||||
schemas:
|
||||
VulnListResponse:
|
||||
type: object
|
||||
properties:
|
||||
items:
|
||||
type: array
|
||||
items: { $ref: '#/components/schemas/Vuln' }
|
||||
nextPageToken:
|
||||
type: string
|
||||
description: Opaque token encoding last (score,id) tuple.
|
||||
required: [items]
|
||||
Vuln:
|
||||
type: object
|
||||
properties:
|
||||
id: { type: string, description: Stable hash id }
|
||||
source:
|
||||
type: object
|
||||
properties:
|
||||
feed: { type: string, description: Original source/feed name }
|
||||
advisoryId: { type: string }
|
||||
cveIds:
|
||||
type: array
|
||||
items: { type: string }
|
||||
ghsaIds:
|
||||
type: array
|
||||
items: { type: string }
|
||||
purls:
|
||||
type: array
|
||||
items: { type: string }
|
||||
severity: { type: string, enum: [CRITICAL, HIGH, MEDIUM, LOW, NONE] }
|
||||
score: { type: number, format: double, minimum: 0, maximum: 10 }
|
||||
kev: { type: boolean }
|
||||
exploitability: { type: string, enum: [known, likely, unknown, none] }
|
||||
fixAvailable: { type: boolean }
|
||||
summary: { type: string }
|
||||
affectedPackages:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
purl: { type: string }
|
||||
versions: { type: array, items: { type: string } }
|
||||
firstSeen: { type: string, format: date-time }
|
||||
lastSeen: { type: string, format: date-time }
|
||||
advisoryRefs:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
url: { type: string, format: uri }
|
||||
title: { type: string }
|
||||
policyVersion: { type: string }
|
||||
rationaleId: { type: string }
|
||||
provenance:
|
||||
type: object
|
||||
properties:
|
||||
ledgerEntryId: { type: string }
|
||||
evidenceBundleId: { type: string }
|
||||
required:
|
||||
- id
|
||||
- severity
|
||||
- score
|
||||
- policyVersion
|
||||
- rationaleId
|
||||
@@ -1,9 +1,11 @@
|
||||
# Advisory AI Assistant Parameters
|
||||
|
||||
_Primary audience: platform operators & policy authors • Updated: 2025-11-13_
|
||||
_Primary audience: platform operators & policy authors • Updated: 2025-11-24_
|
||||
|
||||
This note centralises the tunable knobs that control Advisory AI’s planner, retrieval stack, inference clients, and guardrails. All options live under the `AdvisoryAI` configuration section and can be set via `appsettings.*` files or environment variables using ASP.NET Core’s double-underscore convention (`ADVISORYAI__Inference__Mode`, etc.).
|
||||
|
||||
**Policy/version pin** — For Sprint 0111, use the policy bundle hash shipped on 2025-11-19 (same drop as `CLI-VULN-29-001` / `CLI-VEX-30-001`). Set `AdvisoryAI:PolicyVersion` or `ADVISORYAI__POLICYVERSION=2025.11.19` in deployments; include the hash in DSSE metadata for Offline Kits.
|
||||
|
||||
| Area | Key(s) | Environment variable | Default | Notes |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| Inference mode | `AdvisoryAI:Inference:Mode` | `ADVISORYAI__INFERENCE__MODE` | `Local` | `Local` runs the deterministic pipeline only; `Remote` posts sanitized prompts to `Remote.BaseAddress`. |
|
||||
|
||||
42
docs/runbooks/assistant-ops.md
Normal file
42
docs/runbooks/assistant-ops.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# Assistant Ops Runbook (DOCS-AIAI-31-009)
|
||||
|
||||
_Updated: 2025-11-24 · Owners: DevOps Guild · Advisory AI Guild · Sprint 0111_
|
||||
|
||||
This runbook covers day-2 operations for Advisory AI (web + worker) with emphasis on cache priming, guardrail verification, and outage handling in offline/air-gapped installs.
|
||||
|
||||
## 1) Warmup & cache priming
|
||||
- Ensure Offline Kit fixtures are staged:
|
||||
- CLI guardrail bundles: `out/console/guardrails/cli-vuln-29-001/`, `out/console/guardrails/cli-vex-30-001/`.
|
||||
- SBOM context fixtures: copy into `data/advisory-ai/fixtures/sbom/` and record hashes in `SHA256SUMS`.
|
||||
- Profiles/prompts manifests: ensure `profiles.catalog.json` and `prompts.manifest` hashes match `AdvisoryAI:Provenance` settings.
|
||||
- Start services and prime caches using cache-only calls:
|
||||
- `stella advise run summary --advisory-key <id> --timeout 0 --json` (should return cached/empty context, exit 0).
|
||||
- `stella advise run remediation --advisory-key <id> --artifact-id <id> --timeout 0 --json` (verifies SBOM clamps without executing inference).
|
||||
|
||||
## 2) Guardrail & provenance verification
|
||||
- Run guardrail self-test: `dotnet test src/AdvisoryAI/__Tests/StellaOps.AdvisoryAI.Tests/StellaOps.AdvisoryAI.Tests.csproj --filter Guardrail` (offline-safe).
|
||||
- Validate DSSE bundles:
|
||||
- `slsa-verifier verify-attestation --bundle offline-kit/advisory-ai/provenance/prompts.manifest.dsse --source prompts.manifest`
|
||||
- `slsa-verifier verify-attestation --bundle offline-kit/advisory-ai/provenance/policy-bundle.intoto.jsonl --digest <policy-digest>`
|
||||
- Confirm `AdvisoryAI:Guardrails:BlockedPhrases` file matches the hash captured during pack build; diff against `prompts.manifest`.
|
||||
|
||||
## 3) Scaling & queue health
|
||||
- Defaults: queue capacity 1024, dequeue wait 1s (see `docs/policy/assistant-parameters.md`). For bursty tenants, scale workers horizontally before increasing queue size to preserve determinism.
|
||||
- Metrics to watch: `advisory_ai_queue_depth`, `advisory_ai_latency_seconds`, `advisory_ai_guardrail_blocks_total`.
|
||||
- If queue depth > 75% for 5 minutes, add one worker pod or increase `Queue:Capacity` by 25% (record change in ops log).
|
||||
|
||||
## 4) Outage handling
|
||||
- **SBOM service down**: switch to `NullSbomContextClient` by unsetting `ADVISORYAI__SBOM__BASEADDRESS`; Advisory AI returns deterministic responses with `sbomSummary` counts at 0.
|
||||
- **Policy Engine unavailable**: pin last-known `policyVersion`; set `AdvisoryAI:Guardrails:RequireCitations=true` to avoid drift; raise `advisory.remediation.policyHold` in responses.
|
||||
- **Remote profile disabled**: keep `profile=cloud-openai` blocked; return `advisory.inference.remoteDisabled` with exit code 12 in CLI (see `docs/advisory-ai/cli.md`).
|
||||
|
||||
## 5) Air-gap / offline posture
|
||||
- All external calls are disabled by default. To re-enable remote inference, set `ADVISORYAI__INFERENCE__MODE=Remote` and provide an allowlisted `Remote.BaseAddress`; record the consent in Authority and in the ops log.
|
||||
- Mirror the guardrail artefact folders and `hashes.sha256` into the Offline Kit; re-run the guardrail self-test after mirroring.
|
||||
|
||||
## 6) Checklist before declaring healthy
|
||||
- [ ] Guardrail self-test suite green.
|
||||
- [ ] Cache-only CLI probes return 0 with correct `context.planCacheKey`.
|
||||
- [ ] DSSE verifications logged for prompts, profiles, policy bundle.
|
||||
- [ ] Metrics scrape shows queue depth < 75% and latency within SLO.
|
||||
- [ ] Ops log updated with any config overrides (queue size, clamps, remote inference toggles).
|
||||
44
docs/runbooks/concelier-airgap-bundle-deploy.md
Normal file
44
docs/runbooks/concelier-airgap-bundle-deploy.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# Concelier Air-Gap Bundle Deploy Runbook (CONCELIER-AIRGAP-56-003)
|
||||
|
||||
Status: draft · 2025-11-24
|
||||
Scope: deploy sealed-mode Concelier evidence bundles using deterministic NDJSON + manifest/entry-trace outputs.
|
||||
|
||||
## Inputs
|
||||
- Bundle: `concelier-airgap.ndjson`
|
||||
- Manifest: `bundle.manifest.json`
|
||||
- Entry trace: `bundle.entry-trace.json`
|
||||
- Hashes: SHA256 recorded in manifest and entry-trace; verify before import.
|
||||
|
||||
## Preconditions
|
||||
- Concelier WebService running with `concelier:features:airgap` enabled.
|
||||
- No external egress; only local file system allowed for bundle path.
|
||||
- Mongo indexes applied (`advisory_observations`, `advisory_linksets`).
|
||||
|
||||
## Steps
|
||||
1) Transfer bundle directory to offline controller host.
|
||||
2) Verify hashes:
|
||||
```bash
|
||||
sha256sum concelier-airgap.ndjson | diff - <(jq -r .bundleSha256 bundle.manifest.json)
|
||||
jq -r '.[].sha256' bundle.entry-trace.json | nl | sed 's/\t/:/' > entry.hashes
|
||||
paste -d' ' <(cut -d: -f1 entry.hashes) <(cut -d: -f2 entry.hashes)
|
||||
```
|
||||
3) Import:
|
||||
```bash
|
||||
curl -sSf -X POST \
|
||||
-H 'Content-Type: application/x-ndjson' \
|
||||
--data-binary @concelier-airgap.ndjson \
|
||||
http://localhost:5000/internal/airgap/import
|
||||
```
|
||||
4) Validate import:
|
||||
```bash
|
||||
curl -sSf http://localhost:5000/internal/airgap/status | jq
|
||||
```
|
||||
5) Record evidence:
|
||||
- Store manifest + entry-trace alongside TRX/logs in `artifacts/airgap/<date>/`.
|
||||
|
||||
## Determinism notes
|
||||
- NDJSON ordering is lexicographic; do not re-sort downstream.
|
||||
- Entry-trace hashes must match post-transfer; any mismatch aborts import.
|
||||
|
||||
## Rollback
|
||||
- Delete imported batch by `bundleId` from `advisory_observations` and `advisory_linksets` (requires DBA approval); rerun import after fixing hash.
|
||||
3
docs/samples/airgap/concelier-airgap-sample.ndjson
Normal file
3
docs/samples/airgap/concelier-airgap-sample.ndjson
Normal file
@@ -0,0 +1,3 @@
|
||||
a:1
|
||||
b:2
|
||||
c:3
|
||||
43
docs/sbom/remediation-heuristics.md
Normal file
43
docs/sbom/remediation-heuristics.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Remediation Heuristics for Advisory AI (DOCS-AIAI-31-008)
|
||||
|
||||
_Updated: 2025-11-24 · Owners: Docs Guild · SBOM Service Guild · Sprint 0111_
|
||||
|
||||
This note defines the deterministic remediation heuristics Advisory AI applies when SBOM context is present. It aligns with `SBOM-AIAI-31-001` (path/timeline endpoints) and the CLI fixtures shipped in `CLI-VULN-29-001`.
|
||||
|
||||
## Inputs
|
||||
- SBOM context document (schema `stellaops.sbom.context/1.0`), e.g. `out/console/guardrails/cli-vuln-29-001/sample-sbom-context.json` (SHA256 `421af53f9eeba6903098d292fbd56f98be62ea6130b5161859889bf11d699d18`).
|
||||
- Version timelines from `/sbom/versions?artifactId=...` (clamped to 500 entries by default).
|
||||
- Dependency paths from `/sbom/paths?artifactId=...` (clamped to 200 paths by default).
|
||||
- Advisory/VEX evidence from Link-Not-Merge (`advisory_observations`, `advisory_linksets`).
|
||||
|
||||
## Heuristics (deterministic)
|
||||
1) **Blast radius score** per package
|
||||
- `score = (directPaths * 2) + transitivePaths + exposedRuntimeHint`
|
||||
- `exposedRuntimeHint = 3` when the runtime signal `exposure=external` is present, else `0`.
|
||||
- Scores are capped at `20` to keep ordering stable.
|
||||
|
||||
2) **Fix candidate ranking**
|
||||
- Prefer vendor fixed versions present in timeline; fall back to highest patch version above current.
|
||||
- Reject candidates that would **increase** blast radius by adding new transitive edges (>10% increase).
|
||||
- If no fix exists, emit `advisory.remediation.noFixAvailable` and cite the timeline.
|
||||
|
||||
3) **Configuration-only mitigations**
|
||||
- When VEX status is `not_affected` **and** blast radius score < 5, recommend configuration hardening (feature flags, admission policy) instead of upgrades.
|
||||
|
||||
4) **Refusal conditions**
|
||||
- Missing SBOM context → return deterministic remediation with `sbomSummary` counts set to 0 and note `contextUnavailable` in metadata.
|
||||
- Timeline gaps (non-monotonic dates or hashes) → `409 advisory.contextHashMismatch` with the offending hash list.
|
||||
|
||||
## Example (offline fixture)
|
||||
Using `sample-sbom-context.json`:
|
||||
|
||||
| Package | Paths | Blast radius | Suggested action |
|
||||
| --- | --- | --- | --- |
|
||||
| openssl@1.1.1w | 2 direct, 4 transitive | `(2*2)+4 = 8` | Upgrade to vendor fixed `1.1.1x` (from timeline); verify after replacement. |
|
||||
| zlib@1.2.11 | 1 direct, 2 transitive | `(1*2)+2 = 4` | Apply VEX `not_affected` justification if available; otherwise patch to `1.2.12`. |
|
||||
|
||||
## Operator checklist
|
||||
- Export SBOM context and hashes into Offline Kit (`offline-kit/advisory-ai/fixtures/sbom-context/`).
|
||||
- Verify clamps: `timelineClamp=500`, `dependencyPathClamp=200` unless explicitly overridden in `AdvisoryAI:Tasks:Remediation`.
|
||||
- Record blast-radius scores in audit logs when remediation is generated (helps replay).
|
||||
- Keep fixtures in sync with CLI guardrail artefact hashes and note any override in sprint Execution Log.
|
||||
Reference in New Issue
Block a user