work
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled

This commit is contained in:
StellaOps Bot
2025-11-25 08:01:23 +02:00
parent d92973d6fd
commit 6bee1fdcf5
207 changed files with 12816 additions and 2295 deletions

View File

@@ -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
View 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.

View File

@@ -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)

View File

@@ -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.

View 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).

View 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.

View File

@@ -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/`.

View File

@@ -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 (airgap 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.

View 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. |

View 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.

View 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.

View 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.

View 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.

View 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.

View 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`.

View 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`.

View 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.

View 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.

View 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.

View 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.

View 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.

View 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
```

View 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]'
```

View 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 `25` 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.

View 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/`.

View 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.

View 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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View 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.

View 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

View File

@@ -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 AIs 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 Cores 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`. |

View 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).

View 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.

View File

@@ -0,0 +1,3 @@
a:1
b:2
c:3

View 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.