finish off sprint advisories and sprints

This commit is contained in:
master
2026-01-24 00:12:43 +02:00
parent 726d70dc7f
commit c70e83719e
266 changed files with 46699 additions and 1328 deletions

View File

@@ -1,258 +0,0 @@
# Sprint 20260120-029 · Delta Delivery Attestation (Planning Only)
## Topic & Scope
- **Status:** PLANNING - Not committed to implementation
- **Origin:** Product advisory on delta-sig attestation for verifiable update delivery
- **Purpose:** Scope the work required to extend delta-sig from CVE detection to delta patch delivery
- Working directory: `src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.DeltaSig`
- This document captures analysis and proposed tasks; no implementation is scheduled.
## Advisory Summary
The advisory proposes extending Stella Ops' delta-sig capabilities to support **patch delivery and reconstruction verification**, similar to:
- **Chromium Courgette/Zucchini:** Instruction-aware binary diffing for smaller patches
- **Microsoft MSDelta/LZX-delta:** Windows Update delta compression
- **deltarpm:** RPM delta packages that rebuild full RPMs from installed content
- **zchunk:** Chunk-based delta format with HTTP range requests and independent verification
### Current vs. Proposed Use Cases
| Aspect | Current Implementation | Advisory Proposal |
|--------|------------------------|-------------------|
| **Purpose** | CVE detection via signature matching | Patch delivery and reconstruction |
| **Question answered** | "Does this binary have the security patch?" | "Can I apply this delta to reconstruct the target?" |
| **Data flow** | Signature DB → Match target → Verdict | Base + Delta → Apply → Reconstruct target |
| **Output** | `vulnerable`/`patched` verdict | Reconstructed binary + verification |
## Gap Analysis
### Already Covered (No Gap)
1. **Function-level signatures** - v1 and v2 predicates with `DeltaSignature`, `SymbolSignature`, chunk hashes
2. **Multiple hash algorithms** - SHA-256/384/512, CFG edge hash, semantic hash
3. **Normalization recipes** - `NormalizationRef` with recipe ID, version, steps
4. **Deterministic signature generation** - Fully implemented
5. **IR-level semantic analysis** - v2 has `IrDiffReferenceV2` with CAS storage
6. **DSSE envelope signing** - Implemented via `DeltaSigAttestorIntegration`
7. **Reproducible rebuild infrastructure** - `IRebuildService` exists (for full packages)
### Identified Gaps
#### GAP-1: Base Artifact Reference for Delta Application
**Advisory requirement:** "Base artifact reference: canonical artifact ID + digest(s) of the required base."
**Current state:** `DeltaSigPredicateV2.Subject` is a single artifact. No field to specify base for reconstruction.
**Proposed schema extension:**
```json
{
"baselineReference": {
"purl": "pkg:deb/debian/openssl@1.1.1k-1",
"digest": { "sha256": "abc123..." },
"buildId": "...",
"requiredExact": true
}
}
```
#### GAP-2: Reconstruction Algorithm Fingerprint
**Advisory requirement:** "Algorithm fingerprint: `{courgette|zucchini|msdelta|deltarpm|zchunk}@version`"
**Current state:** `MatchAlgorithm` tracks detection algorithms, not reconstruction algorithms.
**Proposed schema extension:**
```json
{
"reconstructionAlgorithm": {
"algorithm": "zchunk",
"version": "1.5.2",
"dictionaryDigest": "sha256:def456..."
}
}
```
#### GAP-3: Chunk/Segment Map for Stream Verification
**Advisory requirement:** "Chunk/segment map: offsets, sizes, per-chunk hashes to stream-verify during apply."
**Current state:** `ChunkHash` designed for matching, not reconstruction verification.
**Proposed schema extension:**
```json
{
"segmentMap": [
{ "offset": 0, "size": 4096, "status": "unchanged", "hash": "..." },
{ "offset": 4096, "size": 512, "status": "modified", "oldHash": "...", "newHash": "..." },
{ "offset": 4608, "size": 1024, "status": "new", "hash": "..." }
]
}
```
#### GAP-4: Proof Reference to Build Info
**Advisory requirement:** "Human/readable `proof_ref`: link to buildinfo or exact reproduce-instructions."
**Current state:** `IRebuildService` exists but not linked from predicates.
**Proposed schema extension:**
```json
{
"proofRef": {
"buildinfoUrl": "https://buildinfo.example.com/openssl_1.1.1k-1.buildinfo",
"buildinfoDigest": "sha256:...",
"reproducibilityBackend": "reproduce.debian.net"
}
}
```
#### GAP-5: Two-Part Trust (Content + Manifest Signing)
**Advisory requirement:** "Two-part trust: code-sign the post-image AND sign the update manifest."
**Current state:** Single DSSE envelope signs the predicate.
**Proposed new type:**
```json
{
"manifestType": "https://stella-ops.org/delta-manifest/v1",
"baseArtifact": { "purl": "...", "digest": {...} },
"deltaArtifact": { "url": "...", "digest": {...}, "algorithm": "zchunk@1.5" },
"targetArtifact": { "purl": "...", "digest": {...} },
"predicateRef": "sha256:...",
"manifestSignatures": [...]
}
```
#### GAP-6: Reconstruction Service
**Advisory requirement:** "Reconstruction-first: given base + delta, reassemble in a clean sandbox."
**Current state:** No `IDeltaApplicationService`.
**Proposed interface:**
```csharp
public interface IDeltaApplicationService
{
Task<DeltaApplicationResult> ApplyAsync(
Stream baseArtifact,
Stream deltaArtifact,
ReconstructionAlgorithm algorithm,
CancellationToken ct);
Task<bool> VerifyReconstructionAsync(
Stream reconstructedArtifact,
string expectedDigest,
CancellationToken ct);
}
```
#### GAP-7: Acceptance Test Harness
**Advisory requirement:** "Signature/manifest checks, byte-for-byte equality."
**Current state:** No reconstruction tests.
**Required:** Test harness for base + delta → reconstruction → verification.
## Dependencies & Concurrency
- **Upstream:** Existing delta-sig v2 predicates (SPRINT_20260119_004 - DONE)
- **Upstream:** Reproducible rebuild infrastructure (SPRINT_20260119_005)
- **New dependency:** zchunk library or native binding
- **Optional:** Courgette/Zucchini (Chrome's algorithm) if PE/ELF optimization needed
- **Parallel-safe:** Schema design can proceed independently of algorithm implementation
## Proposed Task Breakdown
### Phase 1: Schema Extensions
| Task ID | Description | Effort |
|---------|-------------|--------|
| DDS-001 | Extend `DeltaSigPredicateV2` with `BaselineReference` field | Small |
| DDS-002 | Add `ReconstructionAlgorithm` to predicate schema | Small |
| DDS-003 | Define `SegmentMap` model for stream verification | Medium |
| DDS-004 | Link predicate to `.buildinfo` via `ProofRef` | Small |
| DDS-005 | Define `DeltaManifest` type and signing flow | Medium |
### Phase 2: Service Implementation
| Task ID | Description | Effort |
|---------|-------------|--------|
| DDS-006 | Implement `IDeltaApplicationService` interface | Medium |
| DDS-007 | zchunk backend for delta application | Large |
| DDS-008 | Optional: Courgette/Zucchini backend for PE/ELF | Large |
| DDS-009 | Optional: MSDelta backend for Windows | Medium |
### Phase 3: Verification & Testing
| Task ID | Description | Effort |
|---------|-------------|--------|
| DDS-010 | Reconstruction test harness | Medium |
| DDS-011 | Byte-for-byte equality verification tests | Small |
| DDS-012 | Manifest signature verification tests | Small |
### Phase 4: Documentation
| Task ID | Description | Effort |
|---------|-------------|--------|
| DDS-013 | JSON schema for delta-manifest | Small |
| DDS-014 | Documentation updates for delta delivery | Medium |
| DDS-015 | CLI command updates (if applicable) | Medium |
## Decisions & Risks
### Key Decisions Needed
- **D1:** Which reconstruction algorithms to support initially? (zchunk recommended for cross-platform)
- **D2:** Is manifest signing required, or is predicate signing sufficient?
- **D3:** Should delta delivery be a separate predicate type or extension of v2?
- **D4:** Air-gap story: pre-bundle deltas or rely on CAS?
### Risks
- **R1:** zchunk library may require native bindings (no pure .NET implementation)
- **R2:** Courgette/Zucchini are C++ and require interop
- **R3:** Scope creep: this is orthogonal to CVE detection and could become a separate product area
- **R4:** Testing requires vendor binary pairs (base + patched) which may be hard to acquire
### Architectural Notes
Per the advisory:
> Prefer **zchunk-like chunk maps** + **trained zstd dictionaries** across package families to maximize reuse.
> For large PE/ELF apps, support **Zucchini/Courgette** paths for maximal shrink.
> Keep **MSDelta/LZX-delta** as a Windows-native backend for server components and agents.
> Treat **base availability as policy**: don't even queue a delta unless the precise base digest is present.
## Next Steps
1. **Product decision:** Prioritize delta delivery relative to other roadmap items
2. **Architecture review:** Validate proposed schema extensions with Attestor guild
3. **Prototype:** Spike zchunk integration to validate effort estimates
4. **Air-gap analysis:** Determine how deltas fit into offline deployment model
## References
- [Chromium Courgette/Zucchini](https://www.chromium.org/developers/design-documents/software-updates-courgette/)
- [Microsoft MSDelta](https://learn.microsoft.com/en-us/windows/win32/devnotes/msdelta)
- [deltarpm](https://www.novell.com/documentation/opensuse103/opensuse103_reference/data/sec_rpm_delta.html)
- [zchunk](https://github.com/zchunk/zchunk)
- [Apple Software Update Process](https://support.apple.com/guide/deployment/software-update-process-dep02c211f3e/web)
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2026-01-20 | Planning document created from product advisory gap analysis | Planning |
| 2026-01-20 | Kickoff: started decision capture for D1-D4 to move planning toward execution. | Planning |
## Sprint Status
**STATUS: PLANNING ONLY** - This document captures scope and analysis. No implementation is committed. Convert to active sprint when prioritized.

View File

@@ -1,488 +0,0 @@
# Sprint 037 Unified Trust Score Facade (B+C+D Approach)
## Topic & Scope
Implement a **facade layer** over existing EWS and Determinization systems to provide:
- **B: Unified API** - Single interface combining EWS scores + Determinization entropy
- **C: Versioned weight manifests** - Extract EWS weights to `etc/weights/*.json` files
- **D: Unknowns fraction (U)** - Expose Determinization entropy as unified metric
**Key principle:** Preserve existing guardrails, conflict detection, anchor verification, and decay mechanisms. No formula changes - only unification and better exposure.
**Working directory:** `src/Signals/`
**Secondary directories:** `src/Policy/`, `src/Cli/`, `src/Platform/`
**Expected evidence:** Unit tests, integration tests, CLI updates, API endpoints, updated documentation
---
## Dependencies & Concurrency
- **Upstream (existing, no changes to core logic):**
- EWS: `src/Signals/StellaOps.Signals/EvidenceWeightedScore/` - 6-dimension scoring with guardrails
- Determinization: `src/Policy/__Libraries/StellaOps.Policy.Determinization/` - entropy, decay, fingerprints
- CLI: `src/Cli/StellaOps.Cli/Commands/ScoreGateCommandGroup.cs` - existing `stella gate score`
- **Concurrency:** Safe to run in parallel with other sprints; no breaking changes
---
## Documentation Prerequisites
- [Policy architecture](../modules/policy/architecture.md) §3.1 Determinization Configuration
- [EWS migration](../modules/policy/design/confidence-to-ews-migration.md) - existing scoring
- [Score Proofs API](../api/scanner-score-proofs-api.md) - determinism patterns
---
## Delivery Tracker
### TSF-001 - Extract EWS Weights to Manifest Files
Status: TODO
Dependency: none
Owners: Signals Guild
Task description:
Extract existing EWS weight configuration from `EvidenceWeightPolicy` into versioned JSON manifest files. EWS continues to work exactly as before, but weights are now loaded from files.
**Implementation:**
- Create `etc/weights/` directory structure
- Create `WeightManifest` record matching existing `EvidenceWeights` structure
- Create `IWeightManifestLoader` interface + `FileBasedWeightManifestLoader`
- Update `EvidenceWeightPolicy` to load weights from manifest files (with fallback to defaults)
- Add SHA-256 content hash to manifests for audit trail
- Migrate existing default weights: `etc/weights/v2026-01-22.weights.json`
**Key constraint:** No change to scoring formula or behavior - just externalize configuration.
Completion criteria:
- [ ] `etc/weights/v2026-01-22.weights.json` with current EWS defaults
- [ ] `WeightManifest.cs` record with version, effectiveFrom, weights, hash
- [ ] `FileBasedWeightManifestLoader.cs` loading from `etc/weights/`
- [ ] `EvidenceWeightPolicy` updated to use loader
- [ ] Unit tests verifying identical scoring before/after extraction
- [ ] Existing determinism tests still pass
---
### TSF-002 - Unified Score Facade Service
Status: TODO
Dependency: TSF-001
Owners: Signals Guild
Task description:
Create `IUnifiedScoreService` facade that combines EWS computation with Determinization entropy in a single call. Returns unified result with score, U metric, breakdown, and evidence.
**Implementation:**
- Create `IUnifiedScoreService` interface in `src/Signals/StellaOps.Signals/UnifiedScore/`:
```csharp
Task<UnifiedScoreResult> ComputeAsync(UnifiedScoreRequest request, CancellationToken ct);
```
- Create `UnifiedScoreService` that internally:
1. Calls `IEvidenceWeightedScoreCalculator.Calculate()` for EWS score
2. Calls `IUncertaintyScoreCalculator.CalculateEntropy()` for entropy (U)
3. Calls `IConflictDetector.Detect()` for conflict information
4. Combines into `UnifiedScoreResult`
- `UnifiedScoreResult` includes:
- `Score` (0-100 from EWS)
- `Bucket` (ActNow/ScheduleNext/Investigate/Watchlist)
- `UnknownsFraction` (U from Determinization entropy)
- `UnknownsBand` (Complete/Adequate/Sparse/Insufficient)
- `Breakdown` (EWS dimension contributions)
- `Guardrails` (which caps/floors applied)
- `Conflicts` (from ConflictDetector)
- `WeightManifestRef` (version + hash)
- `EwsDigest` + `DeterminizationFingerprint` (for replay)
- Register in DI container
Completion criteria:
- [ ] `IUnifiedScoreService` interface defined
- [ ] `UnifiedScoreService` implementation composing EWS + Determinization
- [ ] `UnifiedScoreRequest` / `UnifiedScoreResult` DTOs
- [ ] DI registration in `ServiceCollectionExtensions`
- [ ] Unit tests for facade composition
- [ ] Verify identical EWS scores pass through unchanged
---
### TSF-003 - Unknowns Band Mapping
Status: TODO
Dependency: TSF-002
Owners: Signals Guild / Policy Guild
Task description:
Map Determinization entropy (0.0-1.0) to user-friendly unknowns bands with actionable thresholds.
**Implementation:**
- Create `UnknownsBandMapper` in `src/Signals/StellaOps.Signals/UnifiedScore/`:
```csharp
UnknownsBand MapEntropyToBand(double entropy);
string GetBandDescription(UnknownsBand band);
string GetBandAction(UnknownsBand band);
```
- Band definitions (matching existing Determinization thresholds):
| U Range | Band | Description | Action |
|---------|------|-------------|--------|
| 0.0-0.2 | Complete | Full signal coverage | Automated decisions |
| 0.2-0.4 | Adequate | Sufficient signals | Automated decisions |
| 0.4-0.6 | Sparse | Signal gaps exist | Manual review recommended |
| 0.6-1.0 | Insufficient | Critical gaps | Block pending more signals |
- Integrate with existing `ManualReviewEntropyThreshold` (0.60) and `RefreshEntropyThreshold` (0.40) from Determinization config
Completion criteria:
- [ ] `UnknownsBandMapper.cs` with configurable thresholds
- [ ] `UnknownsBand` enum (Complete, Adequate, Sparse, Insufficient)
- [ ] Configuration via `appsettings.json` aligned with Determinization
- [ ] Unit tests for threshold boundaries
- [ ] Integration with `UnifiedScoreResult`
---
### TSF-004 - Delta-If-Present Calculations
Status: TODO
Dependency: TSF-002
Owners: Signals Guild
Task description:
When signals are missing, calculate and include "delta if present" showing potential score impact. Uses existing Determinization `SignalGap` information.
**Implementation:**
- Extend `UnifiedScoreResult` with `DeltaIfPresent` list:
```csharp
IReadOnlyList<SignalDelta> DeltaIfPresent { get; }
```
- `SignalDelta` record:
```csharp
record SignalDelta(string Signal, double MinImpact, double MaxImpact, string Description);
```
- For each missing signal (from Determinization gaps):
- Calculate EWS contribution if signal were 0.0 vs 1.0
- Include weight from manifest
- Add descriptive text (e.g., "If reachability confirmed, score could change by -15 to +8")
- Use existing `SignalGap` from Determinization for missing signal list
Completion criteria:
- [ ] `SignalDelta` record defined
- [ ] Delta calculation logic in `UnifiedScoreService`
- [ ] Integration with `UnifiedScoreResult.DeltaIfPresent`
- [ ] Unit tests for delta calculation accuracy
- [ ] Test with various missing signal combinations
---
### TSF-005 - Platform API Endpoints (Score Evaluate)
Status: TODO
Dependency: TSF-002, TSF-003, TSF-004
Owners: Platform Guild
Task description:
Expose unified score via Platform service REST API endpoints.
**Implementation:**
- Add endpoints to `src/Platform/StellaOps.Platform.WebService/Endpoints/`:
- `POST /api/v1/score/evaluate` - Compute unified score (primary scoring endpoint)
- `GET /api/v1/score/weights` - List available weight manifests
- `GET /api/v1/score/weights/{version}` - Get specific manifest
- Request contract for `/score/evaluate`:
```json
{
"sbom_ref": "oci://registry/app@sha256:…",
"cvss_vector": "CVSS:3.1/…",
"vex_refs": ["oci://…/vex1"],
"rekor_receipts": ["BASE64-RECEIPT"],
"runtime_witnesses": [{"type":"process","data":"…"}],
"options": {"decay_lambda": 0.015, "weight_set_id": "v2026-01-22"}
}
```
- Response includes:
- `score_id` - unique identifier for replay lookup
- `score_value` - 0-100 score
- `unknowns` - list of unknown package refs
- `proof_ref` - OCI reference to score proof bundle
- Full `UnifiedScoreResult` structure (breakdown, U, band, deltas)
- Support `?include_delta=true` query param for delta calculations
- Add OpenAPI documentation
- Tenant-scoped via Authority
Completion criteria:
- [ ] `POST /api/v1/score/evaluate` endpoint implemented
- [ ] `/api/v1/score/weights` endpoints implemented
- [ ] Request/response contracts match advisory spec
- [ ] OpenAPI spec generated
- [ ] Authentication/authorization configured
- [ ] Integration tests for each endpoint
---
### TSF-006 - CLI `stella gate score` Enhancement
Status: TODO
Dependency: TSF-005
Owners: CLI Guild
Task description:
Enhance existing `stella gate score evaluate` command to show unified metrics (U, bands, deltas).
**Implementation:**
- Update `ScoreGateCommandGroup.cs`:
- Add `--show-unknowns` flag to include U metric and band
- Add `--show-deltas` flag to include delta-if-present
- Add `--weights-version` option to pin specific manifest
- Update table output to show U and band when requested
- Update JSON output to include full unified result
- Add new subcommand `stella gate score weights`:
- `list` - Show available weight manifest versions
- `show <version>` - Display manifest details
- `diff <v1> <v2>` - Compare two manifests
Completion criteria:
- [ ] `--show-unknowns` flag showing U and band
- [ ] `--show-deltas` flag showing delta-if-present
- [ ] `--weights-version` option for pinning
- [ ] `stella gate score weights list|show|diff` commands
- [ ] Updated help text and examples
- [ ] CLI tests for new options
---
### TSF-007 - CLI `stella score` Top-Level Command
Status: TODO
Dependency: TSF-005, TSF-011
Owners: CLI Guild
Task description:
Add new top-level `stella score` command group for direct scoring operations (complementing existing `stella gate score` which is gate-focused).
**Implementation:**
- Create `ScoreCommandGroup.cs` in `src/Cli/StellaOps.Cli/Commands/`:
- `stella score compute` - Compute unified score from signals (similar inputs to gate evaluate)
- `stella score explain <finding-id>` - Detailed explanation with breakdown
- `stella score history <finding-id>` - Score history over time
- `stella score compare <finding-id-1> <finding-id-2>` - Compare two findings
- `stella score replay <score-id>` - Fetch and display replay proof (depends on TSF-011)
- `stella score verify <score-id>` - Verify score by replaying computation locally
- Support `--format json|table|markdown` output
- Support `--offline` mode using bundled weights
- Replay/verify commands output:
- Canonical input hashes
- Step-by-step algebra decisions
- Rekor inclusion proof (if anchored)
- Verification status (pass/fail with diff if mismatch)
Completion criteria:
- [ ] `stella score compute` command
- [ ] `stella score explain` command
- [ ] `stella score history` command (if backend supports)
- [ ] `stella score compare` command
- [ ] `stella score replay` command
- [ ] `stella score verify` command
- [ ] Multiple output formats
- [ ] Offline mode support
- [ ] CLI tests
---
### TSF-008 - Console UI Score Display Enhancement
Status: TODO
Dependency: TSF-005
Owners: FE Guild
Task description:
Update Console UI components that display scores to include unknowns fraction and band.
**Implementation:**
- Update finding detail views to show:
- Score with bucket (existing)
- Unknowns fraction (U) with visual indicator
- Unknowns band with color coding
- Delta-if-present for missing signals
- Weight manifest version used
- Add tooltip/popover explaining U and what it means
- Update score trend charts to optionally show U over time
- Update findings list to show U indicator for high-uncertainty findings
Completion criteria:
- [ ] Finding detail view shows U metric and band
- [ ] Color-coded band indicator (green/yellow/orange/red)
- [ ] Delta-if-present display for missing signals
- [ ] Tooltip explaining unknowns
- [ ] Findings list shows high-U indicator
- [ ] Score trend chart option for U
---
### TSF-009 - Determinism & Replay Tests
Status: TODO
Dependency: TSF-002
Owners: QA / Signals Guild
Task description:
Verify that the unified facade maintains determinism guarantees from underlying EWS and Determinization systems.
**Implementation:**
- Create `UnifiedScoreDeterminismTests.cs`:
- Same inputs → same unified result (100+ iterations)
- EWS score unchanged through facade
- Determinization entropy unchanged through facade
- Weight manifest hash stable
- Delta calculations deterministic
- Create golden test fixtures:
- Known inputs with expected unified outputs
- Fixtures for various U bands
- Fixtures for delta calculations
- Verify existing EWS determinism tests still pass
Completion criteria:
- [ ] `UnifiedScoreDeterminismTests.cs` with iteration tests
- [ ] Golden fixtures in `__Tests/Fixtures/UnifiedScore/`
- [ ] EWS pass-through verification
- [ ] Determinization pass-through verification
- [ ] CI gate for determinism regression
- [ ] Existing EWS/Determinization tests unaffected
---
### TSF-010 - Documentation Updates
Status: TODO
Dependency: TSF-001 through TSF-009
Owners: Documentation
Task description:
Update documentation to reflect the unified scoring facade.
**Implementation:**
- Update `docs/technical/scoring-algebra.md` to describe facade approach (not rewrite)
- Update `docs/modules/policy/architecture.md` §3.1 to reference weight manifests
- Create `docs/modules/signals/unified-score.md` explaining:
- What the facade provides
- How U metric works
- How to interpret bands
- CLI command reference
- Update `docs/modules/cli/guides/commands/reference.md` with new commands
- Add troubleshooting section for common U-related issues
Completion criteria:
- [ ] `docs/technical/scoring-algebra.md` updated for facade approach
- [ ] Policy architecture doc updated
- [ ] `docs/modules/signals/unified-score.md` guide created
- [ ] CLI reference updated
- [ ] Troubleshooting guide for U issues
---
### TSF-011 - Score Replay & Verification Endpoint
Status: TODO
Dependency: TSF-005
Owners: Platform Guild / Signals Guild
Task description:
Add explicit replay endpoint that returns a signed replay log, enabling external auditors to independently verify any score computation.
**Implementation:**
- Add endpoint to `src/Platform/StellaOps.Platform.WebService/Endpoints/`:
- `GET /api/v1/score/{id}/replay` - Fetch signed replay proof for a score
- Response contract:
```json
{
"signed_replay_log_dsse": "BASE64",
"rekor_inclusion": {"logIndex": 12345, "rootHash": "…"},
"canonical_inputs": [
{"name": "sbom.json", "sha256": "…"},
{"name": "vex.json", "sha256": "…"},
{"name": "kev.snapshot", "sha256": "…"}
],
"transforms": [
{"name": "canonicalize_spdx", "version": "1.1"},
{"name": "normalize_cvss_v4", "version": "1.0"},
{"name": "age_decay", "params": {"lambda": 0.02}}
],
"algebra_steps": [
{"signal": "cvss_v4_base_norm", "w": 0.30, "value": 0.78, "term": 0.234},
{"signal": "kev_flag", "w": 0.25, "value": 1, "term": 0.25}
],
"final_score": 85,
"computed_at": "2026-01-22T12:00:00Z"
}
```
- DSSE attestation format:
- Payload type: `application/vnd.stella.score+json`
- Sign with Authority key
- Store replay log as OCI referrer ("StellaBundle" pattern):
- Reference: `oci://registry/score-proofs@sha256:`
- Attach to original artifact via OCI referrers API
- Create `IReplayLogBuilder` service:
- Collects canonical input hashes during scoring
- Records transform versions and parameters
- Captures step-by-step algebra decisions
- Generates DSSE-signed attestation
- Create `IReplayVerifier` service:
- Takes replay log + original inputs
- Re-executes scoring with pinned versions
- Returns verification result (pass/fail with diff)
Completion criteria:
- [ ] `GET /api/v1/score/{id}/replay` endpoint implemented
- [ ] `IReplayLogBuilder` service capturing full computation trace
- [ ] `IReplayVerifier` service for independent verification
- [ ] DSSE signing with `application/vnd.stella.score+json` payload type
- [ ] OCI referrer storage for replay proofs
- [ ] Rekor anchoring integration (optional, configurable)
- [ ] OpenAPI spec for replay endpoint
- [ ] Integration tests for replay/verify flow
- [ ] Golden corpus test: score → replay → verify round-trip
---
## Execution Log
| Date (UTC) | Update | Owner |
|------------|--------|-------|
| 2026-01-22 | Sprint created from product advisory | Planning |
| 2026-01-22 | Revised to B+C+D facade approach after deep analysis of existing systems | Planning |
| 2026-01-22 | Added TSF-011 (replay endpoint) per second advisory; renamed `/score/unified` to `/score/evaluate`; added `stella score replay|verify` CLI commands | Planning |
---
## Decisions & Risks
### Decisions Made
1. **Facade over rewrite** - Preserve existing EWS guardrails, conflict detection, anchor verification
2. **Weight manifest format** - JSON with SHA-256 hash, stored in `etc/weights/`
3. **U band thresholds** - Aligned with existing Determinization config (0.40/0.60 thresholds)
4. **No formula changes** - EWS scoring logic unchanged; only exposed differently
5. **Endpoint naming** - Use `/score/evaluate` (per second advisory) instead of `/score/unified` for industry alignment
6. **Explicit replay endpoint** - Add `/score/{id}/replay` returning signed DSSE attestation for auditor verification
7. **DSSE payload type** - Use `application/vnd.stella.score+json` for score attestations
8. **OCI referrer pattern** - Store replay proofs as OCI referrers ("StellaBundle") attached to scored artifacts
### Risks
1. **Performance** - Facade adds overhead calling two services
- Mitigation: Both services are fast (<100μs); combined still sub-millisecond
2. **Backward compatibility** - Existing CLI/API consumers expect current format
- Mitigation: New fields are additive; existing fields unchanged
3. **Configuration drift** - Weight manifest vs Determinization config could diverge
- Mitigation: Single source of truth via weight manifest; Determinization references it
### What We're NOT Doing
- Replacing EWS formula
- Replacing Determinization entropy calculation
- Changing guardrail logic
- Changing conflict detection
- Breaking existing CLI commands
- Breaking existing API contracts
---
## Next Checkpoints
- [ ] TSF-001 complete - Weights externalized
- [ ] TSF-002, TSF-003, TSF-004 complete - Facade functional
- [ ] TSF-005 complete - Score evaluate API endpoint
- [ ] TSF-011 complete - Replay/verification endpoint + DSSE attestation
- [ ] TSF-006, TSF-007 complete - CLI updated (including replay/verify commands)
- [ ] TSF-008 complete - UI updated
- [ ] TSF-009 complete - Determinism verified
- [ ] TSF-010 complete - Documentation finalized

View File

@@ -1,115 +0,0 @@
# Sprint 038 - eBPF Probe Type Enhancement
## Topic & Scope
- Add probe-type categorization to runtime observation models for eBPF sources
- Enable finer-grained filtering and policy evaluation based on probe type
- Document offline replay verification algorithm
- Working directory: `src/RuntimeInstrumentation/StellaOps.RuntimeInstrumentation.Tetragon/`
- Secondary directories: `src/Cli/StellaOps.Cli/Commands/`, `docs/modules/zastava/`
- Expected evidence: unit tests, updated CLI, architecture docs
## Dependencies & Concurrency
- Upstream: None (backwards-compatible enhancement)
- Can run in parallel with other sprints
- Uses existing `runtimeWitness@v1` predicate type (no new type needed)
## Documentation Prerequisites
- Archive manifest: `docs-archived/product/advisories/2026-01-22-ebpf-witness-contract/ARCHIVE_MANIFEST.md`
- Tetragon bridge: `src/RuntimeInstrumentation/StellaOps.RuntimeInstrumentation.Tetragon/TetragonWitnessBridge.cs`
- Zastava architecture: `docs/modules/zastava/architecture.md`
## Delivery Tracker
### EBPF-001 - Add ProbeType field to RuntimeObservation
Status: TODO
Dependency: none
Owners: Developer
Task description:
Extend the `RuntimeObservation` record in `TetragonWitnessBridge.cs` to include an optional `ProbeType` field. This allows distinguishing between kprobe, uprobe, tracepoint, and USDT observations while remaining backwards compatible.
Add enum and field:
```csharp
public enum EbpfProbeType
{
Kprobe,
Kretprobe,
Uprobe,
Uretprobe,
Tracepoint,
Usdt,
Fentry,
Fexit
}
// Add to RuntimeObservation record:
public EbpfProbeType? ProbeType { get; init; }
public string? FunctionName { get; init; }
public long? FunctionAddress { get; init; }
```
Completion criteria:
- [ ] `EbpfProbeType` enum added
- [ ] `ProbeType`, `FunctionName`, `FunctionAddress` fields added to `RuntimeObservation`
- [ ] Existing code continues to work (fields are optional)
- [ ] Unit tests for new fields
### EBPF-002 - Update Tetragon event parser to populate ProbeType
Status: TODO
Dependency: EBPF-001
Owners: Developer
Task description:
Update the Tetragon event parsing logic to extract and populate the `ProbeType` field from Tetragon events. Tetragon events include probe type information that should be mapped to the new enum.
Completion criteria:
- [ ] Tetragon event parser extracts probe type
- [ ] Mapping from Tetragon probe types to `EbpfProbeType` enum
- [ ] Integration tests with sample Tetragon events
### EBPF-003 - Add --probe-type filter to witness list CLI
Status: TODO
Dependency: EBPF-001
Owners: Developer
Task description:
Extend the `witness list` CLI command to support filtering by probe type. Add a `--probe-type` option that accepts: kprobe, uprobe, tracepoint, usdt.
Location: `src/Cli/StellaOps.Cli/Commands/WitnessCommandGroup.cs`
Completion criteria:
- [ ] `--probe-type` option added to `witness list` command
- [ ] Filtering logic implemented in handler
- [ ] Help text updated
- [ ] CLI test coverage added
### EBPF-004 - Document offline replay verification algorithm
Status: TODO
Dependency: none
Owners: Documentation author
Task description:
Add a section to `docs/modules/zastava/architecture.md` documenting the deterministic replay verification algorithm for runtime witnesses. This should specify:
- Input canonicalization steps (RFC 8785 JCS)
- Observation ordering rules for deterministic hashing
- Signature verification sequence
- Offline bundle structure requirements for witness verification
Completion criteria:
- [ ] New section "Offline Witness Verification" added to Zastava architecture
- [ ] Canonicalization steps documented
- [ ] Observation ordering rules specified
- [ ] Offline bundle requirements defined
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2026-01-22 | Sprint created from eBPF witness advisory. Simplified approach: extend existing model rather than new predicate type. | Planning |
## Decisions & Risks
- **Decision**: Extend existing `RuntimeObservation` with optional `ProbeType` field rather than creating new `ebpfWitness@v1` predicate type. Rationale: simpler, backwards compatible, `SourceType=Tetragon` already identifies eBPF source.
- **Risk**: None significant - all new fields are optional, existing witnesses remain valid.
## Next Checkpoints
- EBPF-001 and EBPF-004 can start immediately (no dependencies)
- EBPF-002 and EBPF-003 depend on EBPF-001

View File

@@ -1,886 +0,0 @@
# Sprint 039 Runtime→Static Linkage Verification
## Topic & Scope
Implement the **proof layer** that connects runtime eBPF observations to static analysis claims, enabling users to:
- Declare expected call-paths via a **function_map predicate** derived from SBOM
- Verify that runtime observations match declared expectations
- Complete the offline trust chain with **checkpoint signature verification**
- Query historical observations for compliance reporting
This sprint delivers the missing "contract" and "proof" layers identified in the eBPF witness advisory gap analysis.
**Working directory:** `src/Scanner/__Libraries/StellaOps.Scanner.Reachability/`
**Secondary directories:**
- `src/Attestor/` (checkpoint signature fix)
- `src/Cli/StellaOps.Cli/Commands/` (CLI commands)
- `src/RuntimeInstrumentation/` (observation persistence)
- `src/Platform/` (API endpoints)
- `src/Web/` (UI components)
**Expected evidence:** Unit tests, integration tests, CLI commands, API endpoints, UI components, updated documentation
---
## User Stories
### US-1: Security Engineer declares expected call-paths
> "As a security engineer, I want to declare which functions my service is expected to call, so I can detect unexpected runtime behavior."
### US-2: DevOps verifies runtime matches expectations
> "As a DevOps engineer, I want to verify that runtime observations match our declared function map, so I can prove our services behave as expected."
### US-3: Auditor verifies offline
> "As an auditor, I want to verify runtime-to-static linkage in an air-gapped environment with full cryptographic proof."
### US-4: SOC analyst queries observation history
> "As a SOC analyst, I want to query historical observations for a specific function to investigate anomalies."
---
## Dependencies & Concurrency
- **Upstream (required before starting):**
- Sprint 038 EBPF-001: `ProbeType` field in `RuntimeObservation` (for richer verification)
- Existing `PathWitness` model in `src/Scanner/__Libraries/StellaOps.Scanner.Reachability/Witnesses/`
- Existing `ClaimIdGenerator` for claim linking
- Existing `TetragonWitnessBridge` for observation buffering
- **Upstream (no changes needed):**
- `HttpRekorClient` - will be patched for checkpoint signatures
- `BundleManifest` v2.0.0 - function_map will be added as artifact type
- **Concurrency:**
- Safe to run in parallel with Sprint 037 (trust score)
- Depends on Sprint 038 EBPF-001 completing first
---
## Documentation Prerequisites
- [Witness contract v1](../contracts/witness-v1.md) - Node hash and path hash recipes
- [Zastava architecture](../modules/zastava/architecture.md) - Runtime signal flow
- [Attestor offline verification](../modules/attestor/guides/offline-verification.md) - Bundle verification
- Sprint 038 EBPF-004 output (offline replay algorithm docs)
---
## Delivery Tracker
### RLV-001 - Define function_map Predicate Schema
Status: TODO
Dependency: none
Owners: Scanner Guild / Attestor Guild
Task description:
Define the `function_map` predicate schema that declares expected call-paths for a service. This is the "contract" that runtime observations will be verified against.
**Schema design:**
```json
{
"_type": "https://stella.ops/predicates/function-map/v1",
"subject": {
"purl": "pkg:oci/myservice@sha256:abc123...",
"digest": { "sha256": "abc123..." }
},
"predicate": {
"schemaVersion": "1.0.0",
"service": "myservice",
"buildId": "abc123def456...",
"generatedFrom": {
"sbomRef": "sha256:...",
"staticAnalysisRef": "sha256:..."
},
"expectedPaths": [
{
"pathId": "path-001",
"description": "TLS handshake via OpenSSL",
"entrypoint": {
"symbol": "myservice::handle_request",
"nodeHash": "sha256:..."
},
"expectedCalls": [
{
"symbol": "SSL_connect",
"purl": "pkg:deb/debian/openssl@3.0.11",
"nodeHash": "sha256:...",
"probeTypes": ["uprobe", "uretprobe"],
"optional": false
},
{
"symbol": "SSL_read",
"purl": "pkg:deb/debian/openssl@3.0.11",
"nodeHash": "sha256:...",
"probeTypes": ["uprobe"],
"optional": false
}
],
"pathHash": "sha256:..."
}
],
"coverage": {
"minObservationRate": 0.95,
"windowSeconds": 1800
},
"generatedAt": "2026-01-22T12:00:00Z"
}
}
```
**Key design decisions:**
- Uses existing `nodeHash` recipe from witness-v1 contract for consistency
- `expectedCalls` array defines the "hot functions" from the advisory
- `probeTypes` specifies which probe types are acceptable for each function
- `coverage.minObservationRate` maps to advisory's "≥ 95% of calls witnessed"
- `optional` flag allows for conditional paths (feature flags, error handlers)
**Implementation:**
- Create `FunctionMapPredicate.cs` record in `src/Scanner/__Libraries/StellaOps.Scanner.Reachability/FunctionMap/`
- Create `ExpectedPath.cs` and `ExpectedCall.cs` supporting records
- Add JSON schema to `docs/schemas/function-map-v1.schema.json`
- Register predicate type with Attestor predicate router
Completion criteria:
- [ ] `FunctionMapPredicate.cs` with full schema
- [ ] JSON schema in `docs/schemas/`
- [ ] Predicate type registered: `https://stella.ops/predicates/function-map/v1`
- [ ] Unit tests for serialization/deserialization
- [ ] Schema validation tests
---
### RLV-002 - Implement FunctionMapGenerator
Status: TODO
Dependency: RLV-001
Owners: Scanner Guild
Task description:
Implement a generator that produces a `function_map` predicate from SBOM + static analysis results. This enables users to declare expected paths without manually authoring JSON.
**Implementation:**
- Create `IFunctionMapGenerator` interface:
```csharp
public interface IFunctionMapGenerator
{
Task<FunctionMapPredicate> GenerateAsync(
FunctionMapGenerationRequest request,
CancellationToken ct);
}
```
- Create `FunctionMapGenerationRequest`:
```csharp
public record FunctionMapGenerationRequest
{
public required string SbomPath { get; init; }
public required string ServiceName { get; init; }
public string? StaticAnalysisPath { get; init; }
public IReadOnlyList<string>? HotFunctionPatterns { get; init; }
public double MinObservationRate { get; init; } = 0.95;
public int WindowSeconds { get; init; } = 1800;
}
```
- Create `FunctionMapGenerator` implementation:
1. Parse SBOM to extract components with PURLs
2. If static analysis provided, extract call paths
3. If hot function patterns provided, filter to matching symbols
4. Generate node hashes using existing `NodeHashRecipe`
5. Compute path hashes using existing `PathHashRecipe`
6. Return populated `FunctionMapPredicate`
**Location:** `src/Scanner/__Libraries/StellaOps.Scanner.Reachability/FunctionMap/`
Completion criteria:
- [ ] `IFunctionMapGenerator` interface
- [ ] `FunctionMapGenerator` implementation
- [ ] Integration with existing SBOM parser
- [ ] Support for hot function pattern matching (glob/regex)
- [ ] Unit tests with sample SBOM
- [ ] Integration test: SBOM → function_map → valid predicate
---
### RLV-003 - Implement IClaimVerifier
Status: TODO
Dependency: RLV-001, Sprint 038 EBPF-001
Owners: Scanner Guild
Task description:
Implement the claim verification logic that proves runtime observations match a declared function_map. This is the core "proof" step.
**Implementation:**
- Create `IClaimVerifier` interface in `src/Scanner/__Libraries/StellaOps.Scanner.Reachability/Verification/`:
```csharp
public interface IClaimVerifier
{
Task<ClaimVerificationResult> VerifyAsync(
FunctionMapPredicate functionMap,
IReadOnlyList<RuntimeObservation> observations,
ClaimVerificationOptions options,
CancellationToken ct);
}
```
- Create `ClaimVerificationResult`:
```csharp
public record ClaimVerificationResult
{
public required bool Verified { get; init; }
public required double ObservationRate { get; init; }
public required IReadOnlyList<PathVerificationResult> Paths { get; init; }
public required IReadOnlyList<string> UnexpectedSymbols { get; init; }
public required IReadOnlyList<string> MissingExpectedSymbols { get; init; }
public required ClaimVerificationEvidence Evidence { get; init; }
}
public record PathVerificationResult
{
public required string PathId { get; init; }
public required bool Observed { get; init; }
public required int ObservationCount { get; init; }
public required IReadOnlyList<string> MatchedNodeHashes { get; init; }
public required IReadOnlyList<string> MissingNodeHashes { get; init; }
}
public record ClaimVerificationEvidence
{
public required string FunctionMapDigest { get; init; }
public required string ObservationsDigest { get; init; }
public required DateTimeOffset VerifiedAt { get; init; }
public required string VerifierVersion { get; init; }
}
```
- Create `ClaimVerifier` implementation:
1. Group observations by node hash
2. For each expected path in function_map:
- Check if all required node hashes were observed
- Check if probe types match expectations
- Calculate observation rate
3. Detect unexpected symbols (observed but not in function_map)
4. Calculate overall observation rate
5. Compare against `coverage.minObservationRate`
6. Build evidence record for audit trail
**Verification algorithm:**
```
For each path in functionMap.expectedPaths:
matched = 0
for each call in path.expectedCalls:
if observations.any(o => o.nodeHash == call.nodeHash && call.probeTypes.contains(o.probeType)):
matched++
path.observationRate = matched / path.expectedCalls.count
overallRate = observedPaths / totalPaths
verified = overallRate >= functionMap.coverage.minObservationRate
```
Completion criteria:
- [ ] `IClaimVerifier` interface defined
- [ ] `ClaimVerifier` implementation with verification algorithm
- [ ] `ClaimVerificationResult` with detailed breakdown
- [ ] Evidence record for audit trail
- [ ] Detection of unexpected symbols
- [ ] Unit tests for various scenarios (full match, partial, no match)
- [ ] Integration test with real observations
---
### RLV-004 - Fix Checkpoint Signature Verification
Status: TODO
Dependency: none
Owners: Attestor Guild
Task description:
Complete the Rekor checkpoint signature verification that currently returns `false` unconditionally. This is required for full offline trust chain.
**Current state (HttpRekorClient.cs:282-289):**
```csharp
_logger.LogDebug(
"Checkpoint signature verification is unavailable for UUID {Uuid}; treating checkpoint as unverified",
rekorUuid);
// ...
return RekorInclusionVerificationResult.Success(
logIndex.Value,
computedRootHex,
proof.Checkpoint.RootHash,
checkpointSignatureValid: false); // Always false
```
**Implementation:**
- Update `HttpRekorClient.VerifyInclusionAsync()` to:
1. Extract checkpoint note from response
2. Parse note format: body + signature lines
3. Verify signature using `CheckpointSignatureVerifier` (already exists)
4. Return actual verification result
- Add `RekorPublicKey` configuration option for pinned verification
- Support both online (fetch from Rekor) and offline (pinned key) modes
**Location:** `src/Attestor/__Libraries/StellaOps.Attestor.Infrastructure/Rekor/HttpRekorClient.cs`
**Testing:**
- Verify against real Rekor checkpoint
- Verify with pinned public key (offline mode)
- Verify rejection of tampered checkpoint
Completion criteria:
- [ ] Checkpoint signature verification implemented
- [ ] `checkpointSignatureValid` returns actual result
- [ ] Support for pinned public key (air-gap mode)
- [ ] Unit tests with test vectors
- [ ] Integration test against Rekor staging
---
### RLV-005 - Implement Runtime Observation Store
Status: TODO
Dependency: Sprint 038 EBPF-001
Owners: Signals Guild
Task description:
Implement persistent storage for runtime observations to support historical queries and compliance reporting.
**Implementation:**
- Create `IRuntimeObservationStore` interface (if not exists) in `src/RuntimeInstrumentation/`:
```csharp
public interface IRuntimeObservationStore
{
Task StoreAsync(RuntimeObservation observation, CancellationToken ct);
Task StoreBatchAsync(IReadOnlyList<RuntimeObservation> observations, CancellationToken ct);
Task<IReadOnlyList<RuntimeObservation>> QueryBySymbolAsync(
string nodeHash,
DateTimeOffset from,
DateTimeOffset to,
CancellationToken ct);
Task<IReadOnlyList<RuntimeObservation>> QueryByContainerAsync(
string containerId,
DateTimeOffset from,
DateTimeOffset to,
CancellationToken ct);
Task<ObservationSummary> GetSummaryAsync(
string nodeHash,
DateTimeOffset from,
DateTimeOffset to,
CancellationToken ct);
Task PruneOlderThanAsync(TimeSpan retention, CancellationToken ct);
}
```
- Create `PostgresRuntimeObservationStore` implementation:
- Table: `runtime_observations` with indexes on `node_hash`, `container_id`, `observed_at`
- Batch insert with conflict handling (dedup by observation_id)
- Efficient time-range queries using BRIN index on `observed_at`
- Configurable retention policy (default: 7 days)
- Create migration: `src/RuntimeInstrumentation/.../Migrations/001_runtime_observations.sql`
- Wire into `TetragonWitnessBridge` to persist observations as they arrive
**Schema:**
```sql
CREATE TABLE runtime_observations (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
observation_id TEXT NOT NULL UNIQUE,
node_hash TEXT NOT NULL,
symbol_name TEXT,
container_id TEXT NOT NULL,
pod_name TEXT,
namespace TEXT,
probe_type TEXT,
function_address BIGINT,
stack_sample_hash TEXT,
observation_count INTEGER DEFAULT 1,
duration_us BIGINT,
observed_at TIMESTAMPTZ NOT NULL,
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX idx_observations_node_hash ON runtime_observations (node_hash);
CREATE INDEX idx_observations_container ON runtime_observations (container_id);
CREATE INDEX idx_observations_time USING BRIN ON runtime_observations (observed_at);
```
Completion criteria:
- [ ] `IRuntimeObservationStore` interface
- [ ] `PostgresRuntimeObservationStore` implementation
- [ ] Database migration
- [ ] Integration with `TetragonWitnessBridge`
- [ ] Configurable retention policy
- [ ] Unit tests for store operations
- [ ] Integration tests with real Postgres
---
### RLV-006 - CLI: `stella function-map generate`
Status: TODO
Dependency: RLV-002
Owners: CLI Guild
Task description:
Add CLI command to generate a function_map predicate from SBOM.
**Implementation:**
- Create `FunctionMapCommandGroup.cs` in `src/Cli/StellaOps.Cli/Commands/`
- Add command: `stella function-map generate`
**Command spec:**
```
stella function-map generate [options]
Options:
--sbom <path> Path to SBOM file (CycloneDX/SPDX) [required]
--service <name> Service name for the function map [required]
--static-analysis <path> Path to static analysis results (optional)
--hot-functions <pattern> Glob pattern for hot functions (can repeat)
Example: --hot-functions "SSL_*" --hot-functions "crypto_*"
--min-rate <0.0-1.0> Minimum observation rate (default: 0.95)
--window <seconds> Observation window in seconds (default: 1800)
--output <path> Output path (default: stdout)
--format <json|yaml> Output format (default: json)
--sign Sign the predicate with configured key
--attest Create DSSE envelope and push to Rekor
Examples:
# Generate from SBOM with default hot functions
stella function-map generate --sbom sbom.json --service myservice
# Generate with specific hot functions
stella function-map generate --sbom sbom.json --service myservice \
--hot-functions "SSL_*" --hot-functions "EVP_*" --hot-functions "connect"
# Generate, sign, and attest
stella function-map generate --sbom sbom.json --service myservice \
--sign --attest --output function-map.json
```
Completion criteria:
- [ ] `stella function-map generate` command implemented
- [ ] All options working
- [ ] DSSE signing integration (--sign)
- [ ] Rekor attestation integration (--attest)
- [ ] JSON and YAML output formats
- [ ] Help text and examples
- [ ] CLI tests
---
### RLV-007 - CLI: `stella function-map verify`
Status: TODO
Dependency: RLV-003, RLV-005
Owners: CLI Guild
Task description:
Add CLI command to verify runtime observations against a function_map.
**Command spec:**
```
stella function-map verify [options]
Options:
--function-map <path|ref> Path or OCI reference to function_map predicate [required]
--container <id> Container ID to verify (optional, default: all)
--from <timestamp> Start of observation window (default: 30 minutes ago)
--to <timestamp> End of observation window (default: now)
--output <path> Output verification report (default: stdout)
--format <json|table|md> Output format (default: table)
--strict Fail on any unexpected symbols
--sign Sign the verification report
--offline Offline mode (use bundled observations)
--observations <path> Path to observations file (for offline mode)
Output:
Verified: true/false
Observation Rate: 97.2% (target: 95.0%)
Path Coverage:
┌──────────────┬──────────┬───────────┬─────────────┐
│ Path ID │ Status │ Rate │ Missing │
├──────────────┼──────────┼───────────┼─────────────┤
│ path-001 │ ✓ │ 100% │ - │
│ path-002 │ ✓ │ 95.5% │ - │
│ path-003 │ ✗ │ 80.0% │ SSL_write │
└──────────────┴──────────┴───────────┴─────────────┘
Unexpected Symbols: none
Evidence:
Function Map Digest: sha256:abc123...
Observations Digest: sha256:def456...
Verified At: 2026-01-22T12:00:00Z
Examples:
# Verify against stored observations
stella function-map verify --function-map function-map.json
# Verify specific container
stella function-map verify --function-map function-map.json \
--container abc123 --from "2026-01-22T11:30:00Z"
# Offline verification with bundled observations
stella function-map verify --function-map function-map.json \
--offline --observations observations.ndjson
# Sign verification report for audit
stella function-map verify --function-map function-map.json \
--sign --output verification-report.json
```
Completion criteria:
- [ ] `stella function-map verify` command implemented
- [ ] Query observations from store
- [ ] Offline mode with file input
- [ ] Table, JSON, and Markdown output formats
- [ ] Signed verification report option
- [ ] CLI tests
---
### RLV-008 - CLI: `stella observations query`
Status: TODO
Dependency: RLV-005
Owners: CLI Guild
Task description:
Add CLI command to query historical runtime observations.
**Command spec:**
```
stella observations query [options]
Options:
--symbol <name> Filter by symbol name (glob pattern)
--node-hash <hash> Filter by exact node hash
--container <id> Filter by container ID
--pod <name> Filter by pod name
--namespace <ns> Filter by Kubernetes namespace
--probe-type <type> Filter by probe type (kprobe|uprobe|tracepoint|usdt)
--from <timestamp> Start time (default: 1 hour ago)
--to <timestamp> End time (default: now)
--limit <n> Maximum results (default: 100)
--format <json|table|csv> Output format (default: table)
--summary Show summary statistics instead of individual observations
Examples:
# Query all SSL_connect observations in last hour
stella observations query --symbol "SSL_connect"
# Query by container
stella observations query --container abc123 --from "2026-01-22T11:00:00Z"
# Get summary statistics
stella observations query --symbol "SSL_*" --summary
# Export to CSV for analysis
stella observations query --namespace production --format csv > observations.csv
```
Completion criteria:
- [ ] `stella observations query` command implemented
- [ ] All filter options working
- [ ] Summary statistics mode
- [ ] CSV export for external analysis
- [ ] CLI tests
---
### RLV-009 - Platform API: Function Map Endpoints
Status: TODO
Dependency: RLV-002, RLV-003
Owners: Platform Guild
Task description:
Expose function_map operations via Platform service REST API.
**Endpoints:**
```
POST /api/v1/function-maps Create/store function map
GET /api/v1/function-maps List function maps
GET /api/v1/function-maps/{id} Get function map by ID
DELETE /api/v1/function-maps/{id} Delete function map
POST /api/v1/function-maps/{id}/verify Verify observations against map
GET /api/v1/function-maps/{id}/coverage Get current coverage statistics
```
**Request/Response contracts:**
`POST /api/v1/function-maps`:
```json
{
"sbomRef": "oci://registry/app@sha256:...",
"serviceName": "myservice",
"hotFunctions": ["SSL_*", "EVP_*"],
"options": {
"minObservationRate": 0.95,
"windowSeconds": 1800
}
}
```
`POST /api/v1/function-maps/{id}/verify`:
```json
{
"containerId": "abc123",
"from": "2026-01-22T11:00:00Z",
"to": "2026-01-22T12:00:00Z",
"strict": false
}
```
Response:
```json
{
"verified": true,
"observationRate": 0.972,
"targetRate": 0.95,
"paths": [...],
"unexpectedSymbols": [],
"evidence": {
"functionMapDigest": "sha256:...",
"observationsDigest": "sha256:...",
"verifiedAt": "2026-01-22T12:00:00Z"
}
}
```
Completion criteria:
- [ ] All endpoints implemented
- [ ] OpenAPI spec generated
- [ ] Tenant-scoped authorization
- [ ] Integration tests
- [ ] Rate limiting configured
---
### RLV-010 - UI: Function Map Management
Status: TODO
Dependency: RLV-009
Owners: FE Guild
Task description:
Add UI components for managing function maps and viewing verification results.
**Components:**
1. **Function Map List View** (`/settings/function-maps`)
- Table showing all function maps for tenant
- Columns: Service, Created, Last Verified, Coverage Status
- Actions: View, Verify Now, Delete
2. **Function Map Detail View** (`/settings/function-maps/{id}`)
- Service info and generation metadata
- Expected paths table with symbols
- Coverage thresholds configuration
- Recent verification history
3. **Function Map Generator Wizard** (`/settings/function-maps/new`)
- Step 1: Select SBOM source (file upload or OCI reference)
- Step 2: Configure hot function patterns (with suggestions)
- Step 3: Set coverage thresholds
- Step 4: Review and create
4. **Verification Results Panel** (embedded in service detail)
- Current verification status (verified/not verified)
- Observation rate gauge with threshold indicator
- Path coverage breakdown (expandable)
- Unexpected symbols warning (if any)
- Link to full verification report
5. **Observation Timeline** (`/services/{id}/observations`)
- Time-series chart of observation counts
- Filter by symbol/probe type
- Drill-down to individual observations
Completion criteria:
- [ ] Function map list view
- [ ] Function map detail view
- [ ] Generator wizard
- [ ] Verification results panel
- [ ] Observation timeline chart
- [ ] Responsive design
- [ ] Loading states and error handling
- [ ] E2E tests
---
### RLV-011 - Bundle Integration: function_map Artifact Type
Status: TODO
Dependency: RLV-001
Owners: AirGap Guild
Task description:
Add `function_map` as a supported artifact type in StellaBundle for offline verification.
**Implementation:**
- Update `BundleArtifactType` enum to include `FunctionMap`
- Update `BundleBuilder` to package function_map predicates
- Update `BundleValidator` to validate function_map artifacts
- Update `BundleVerifyCommand` to verify function_map signatures
**Bundle structure addition:**
```
bundle/
├── manifest.json
├── function-maps/
│ └── myservice-function-map.json
├── observations/
│ └── observations-2026-01-22.ndjson
└── verification/
└── verification-report.dsse.json
```
Completion criteria:
- [ ] `FunctionMap` artifact type added
- [ ] Bundle export includes function maps
- [ ] Bundle verify validates function map signatures
- [ ] Offline verification includes function map checking
- [ ] Documentation updated
---
### RLV-012 - Documentation: Runtime Linkage Verification Guide
Status: TODO
Dependency: RLV-001 through RLV-011
Owners: Documentation
Task description:
Create comprehensive documentation for the runtime→static linkage verification feature.
**Documents to create/update:**
1. **New: `docs/modules/scanner/guides/runtime-linkage.md`**
- What is runtime→static linkage verification?
- When to use function maps
- Step-by-step guide: generate → deploy probes → verify
- Troubleshooting common issues
2. **New: `docs/contracts/function-map-v1.md`**
- Predicate schema specification
- Node hash and path hash recipes (reference witness-v1)
- Coverage calculation algorithm
- Verification algorithm
3. **Update: `docs/modules/cli/guides/commands/reference.md`**
- Add `stella function-map` command group
- Add `stella observations` command group
4. **Update: `docs/modules/airgap/guides/offline-bundle-format.md`**
- Add function_map artifact type documentation
5. **New: `docs/runbooks/runtime-linkage-ops.md`**
- Operational runbook for production deployment
- Probe selection guidance
- Performance tuning
- Alert configuration
Completion criteria:
- [ ] Runtime linkage guide created
- [ ] function_map contract documented
- [ ] CLI reference updated
- [ ] Bundle format docs updated
- [ ] Operational runbook created
---
### RLV-013 - Acceptance Tests: 90-Day Pilot Criteria
Status: TODO
Dependency: All above tasks
Owners: QA Guild
Task description:
Implement acceptance tests matching the advisory's success criteria:
**Advisory acceptance criteria:**
1. **Coverage:** ≥ 95% of calls to the 6 hot funcs are witnessed over a steady-state 30-min window
2. **Integrity:** 100% DSSE sig verify + valid Rekor inclusion + valid TST
3. **Replayability:** Offline verifier reproduces the same mapping on 3 separate air-gapped runs
4. **Perf:** < 2% CPU overhead, < 50 MB RSS for collector under target load
5. **Privacy:** No raw args; only hashes and minimal context
**Test implementation:**
1. **Coverage test:**
- Generate function_map with 6 hot functions
- Run load generator for 30 minutes
- Verify observation rate 95%
2. **Integrity test:**
- Generate function_map with signing
- Create DSSE envelope
- Post to Rekor
- Add RFC-3161 timestamp
- Verify all signatures and proofs
3. **Replayability test:**
- Export StellaBundle with function_map + observations
- Run offline verification 3 times in isolated environments
- Assert identical results
4. **Performance test (if feasible in CI):**
- Measure CPU overhead with/without probes
- Measure collector memory usage
- Assert within thresholds
5. **Privacy test:**
- Inspect all observation payloads
- Assert no raw arguments present
- Assert only hashes and minimal context
Completion criteria:
- [ ] Coverage acceptance test
- [ ] Integrity acceptance test
- [ ] Replayability acceptance test (3 runs)
- [ ] Performance benchmark (manual or CI)
- [ ] Privacy audit test
- [ ] All tests passing in CI
---
## Execution Log
| Date (UTC) | Update | Owner |
|------------|--------|-------|
| 2026-01-22 | Sprint created from eBPF witness advisory gap analysis | Planning |
---
## Decisions & Risks
### Decisions Made
1. **function_map as separate predicate** - Not extending witness-v1, cleaner separation of concerns
2. **Reuse existing hash recipes** - NodeHash and PathHash from witness-v1 contract for consistency
3. **Postgres for observation storage** - Leverages existing infrastructure, supports time-range queries
4. **CLI-first verification** - Offline verification via CLI before UI for air-gap users
### Risks
1. **Observation volume** - High-traffic services may generate many observations
- Mitigation: Configurable sampling, aggregation, retention policy
2. **Clock skew** - Distributed observations may have timestamp drift
- Mitigation: Use server-side timestamps, configurable tolerance
3. **Symbol resolution accuracy** - Different runtimes have different symbol formats
- Mitigation: Use node hashes (PURL + normalized symbol) for matching
4. **Performance impact of persistence** - Writing every observation could be costly
- Mitigation: Batch writes, async persistence, sampling option
### Open Questions
1. Should function_map support version ranges for expected components, or exact versions only?
2. Should we support "learning mode" that auto-generates function_map from observations?
3. How to handle function maps for services with feature flags (conditional paths)?
---
## Next Checkpoints
- [ ] RLV-001 complete - Schema defined
- [ ] RLV-002, RLV-003 complete - Core verification logic works
- [ ] RLV-004 complete - Checkpoint signatures verified (trust chain complete)
- [ ] RLV-005 complete - Observations persisted
- [ ] RLV-006, RLV-007, RLV-008 complete - CLI fully functional
- [ ] RLV-009, RLV-010 complete - API and UI ready
- [ ] RLV-011 complete - Bundle integration for offline
- [ ] RLV-012 complete - Documentation finalized
- [ ] RLV-013 complete - Acceptance criteria met