up
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled

This commit is contained in:
StellaOps Bot
2025-11-27 23:44:42 +02:00
parent ef6e4b2067
commit 3b96b2e3ea
298 changed files with 47516 additions and 1168 deletions

View File

@@ -17,7 +17,7 @@ completely isolated network:
| **Provenance** | Cosign signature, SPDX 2.3 SBOM, intoto SLSA attestation |
| **Attested manifest** | `offline-manifest.json` + detached JWS covering bundle metadata, signed during export. |
| **Delta patches** | Daily diff bundles keep size \<350MB |
| **Scanner plug-ins** | OS analyzers plus the Node.js, Go, .NET, Python, Ruby, and Rust language analyzers packaged under `plugins/scanner/analyzers/**` with manifests so Workers load deterministically offline. |
| **Scanner plug-ins** | OS analyzers plus the Node.js, Go, .NET, Python, Ruby, Rust, and PHP language analyzers packaged under `plugins/scanner/analyzers/**` with manifests so Workers load deterministically offline. |
| **Debug store** | `.debug` artefacts laid out under `debug/.build-id/<aa>/<rest>.debug` with `debug/debug-manifest.json` mapping build-ids to originating images for symbol retrieval. |
| **Telemetry collector bundle** | `telemetry/telemetry-offline-bundle.tar.gz` plus `.sha256`, containing OTLP collector config, Helm/Compose overlays, and operator instructions. |
| **CLI + Task Packs** | `cli/` binaries from `release/cli`, Task Runner bootstrap (`bootstrap/task-runner/task-runner.yaml.sample`), and task-pack docs under `docs/task-packs/**` + `docs/modules/taskrunner/**`. |
@@ -27,7 +27,19 @@ completely isolated network:
**RU BDU note:** ship the official Russian Trusted Root/Sub CA bundle (`certificates/russian_trusted_bundle.pem`) inside the kit so `concelier:httpClients:source.bdu:trustedRootPaths` can resolve it when the service runs in an airgapped network. Drop the most recent `vulxml.zip` alongside the kit if operators need a cold-start cache.
**Language analyzers:** the kit now carries the restart-only Node.js, Go, .NET, Python, Ruby, and Rust plug-ins (`plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Node/`, `...Lang.Go/`, `...Lang.DotNet/`, `...Lang.Python/`, `...Lang.Ruby/`, `...Lang.Rust/`). Drop the directories alongside Worker binaries so the unified plug-in catalog can load them without outbound fetches. The Ruby analyzer includes optional runtime capture via TracePoint; set `STELLA_RUBY_ENTRYPOINT` to enable runtime evidence collection.
**Language analyzers:** the kit now carries the restart-only Node.js, Go, .NET, Python, Ruby, Rust, and PHP plug-ins (`plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Node/`, `...Lang.Go/`, `...Lang.DotNet/`, `...Lang.Python/`, `...Lang.Ruby/`, `...Lang.Rust/`, `...Lang.Php/`). Drop the directories alongside Worker binaries so the unified plug-in catalog can load them without outbound fetches.
**Ruby analyzer features:**
- **Gemfile/Gemfile.lock** parsing with dependency edges (version constraints, PURLs)
- **OCI container layer** support (`layers/`, `.layers/`, `layer/`) for VFS/container workspace discovery
- **Ruby version detection** via `.ruby-version`, `.tool-versions`, Gemfile `ruby` directive, and binary paths
- **Native extension detection** for `.so`, `.bundle`, `.dll` files in gem paths
- **Web server config parsing** for Puma, Unicorn, and Passenger configurations
- **AOC-compliant observations**: entrypoints (script/rack/rackup), dependency edges, runtime edges, jobs, configs, warnings
- **Optional runtime evidence** via TracePoint; set `STELLA_RUBY_ENTRYPOINT` to enable runtime capture with SHA-256 path hashing for secure evidence correlation
- **CLI inspection**: run `stella ruby inspect --root /path/to/app` to analyze a Ruby workspace locally
The PHP analyzer parses `composer.lock` for Composer dependencies and supports optional runtime evidence via the `stella-trace.php` shim; set `STELLA_PHP_OPCACHE=1` to enable opcache statistics collection.
**Advisory AI volume primer:** ship a tarball containing empty `queue/`, `plans/`, and `outputs/` directories plus their ownership metadata. During import, extract it onto the RWX volume used by `advisory-ai-web` and `advisory-ai-worker` so pods start with the expected directory tree even on air-gapped nodes.
@@ -276,12 +288,12 @@ Authority now rejects tokens that request `advisory:read`, `vex:read`, or any `s
**Quick smoke test:** before import, verify the tarball carries the Go analyzer plug-in:
```bash
tar -tzf stella-ops-offline-kit-<DATE>.tgz 'plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Go/*' 'plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.DotNet/*' 'plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Python/*' 'plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Ruby/*'
tar -tzf stella-ops-offline-kit-<DATE>.tgz 'plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Go/*' 'plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.DotNet/*' 'plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Python/*' 'plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Ruby/*' 'plugins/scanner/analyzers/lang/StellaOps.Scanner.Analyzers.Lang.Php/*'
```
The manifest lookup above and this `tar` listing should both surface the Go analyzer DLL, PDB, and manifest entries before the kit is promoted.
> **Release guardrail.** The automated release pipeline now publishes the Python, Ruby, and Rust plug-ins from source and executes `dotnet run --project src/Tools/LanguageAnalyzerSmoke --configuration Release -- --repo-root <checkout> --analyzer <id>` to validate manifest integrity and cold/warm determinism within the <30s / <5s budgets (differences versus repository goldens are logged for triage). Run `ops/offline-kit/run-python-analyzer-smoke.sh` and `ops/offline-kit/run-ruby-analyzer-smoke.sh`, and `ops/offline-kit/run-rust-analyzer-smoke.sh` locally before shipping a refreshed kit if you rebuild artefacts outside CI or when preparing the air-gap bundle.
> **Release guardrail.** The automated release pipeline now publishes the Python, Ruby, Rust, and PHP plug-ins from source and executes `dotnet run --project src/Tools/LanguageAnalyzerSmoke --configuration Release -- --repo-root <checkout> --analyzer <id>` to validate manifest integrity and cold/warm determinism within the <30s / <5s budgets (differences versus repository goldens are logged for triage). Run `ops/offline-kit/run-python-analyzer-smoke.sh`, `ops/offline-kit/run-ruby-analyzer-smoke.sh`, `ops/offline-kit/run-rust-analyzer-smoke.sh`, and `ops/offline-kit/run-php-analyzer-smoke.sh` locally before shipping a refreshed kit if you rebuild artefacts outside CI or when preparing the air-gap bundle.
### Debug store mirror

View File

@@ -0,0 +1,154 @@
# VEX Raw Migration Rollback Guide
This document describes how to rollback migrations applied to the `vex_raw` collection.
## Migration: 20251127-vex-raw-idempotency-indexes
### Description
Adds unique idempotency indexes to enforce content-addressed storage:
- `idx_provider_sourceUri_digest_unique`: Prevents duplicate documents from same provider/source
- `idx_digest_providerId`: Optimizes evidence queries by digest
- `idx_retrievedAt`: Supports time-based queries and future TTL operations
### Rollback Steps
#### Option 1: MongoDB Shell
```javascript
// Connect to your MongoDB instance
mongosh "mongodb://localhost:27017/excititor"
// Drop the idempotency indexes
db.vex_raw.dropIndex("idx_provider_sourceUri_digest_unique")
db.vex_raw.dropIndex("idx_digest_providerId")
db.vex_raw.dropIndex("idx_retrievedAt")
// Verify indexes are dropped
db.vex_raw.getIndexes()
```
#### Option 2: Programmatic Rollback (C#)
```csharp
using StellaOps.Excititor.Storage.Mongo.Migrations;
// Get the database instance
var database = client.GetDatabase("excititor");
// Execute rollback
await database.RollbackIdempotencyIndexesAsync(cancellationToken);
// Verify rollback
var verified = await database.VerifyIdempotencyIndexesExistAsync(cancellationToken);
Console.WriteLine($"Indexes exist after rollback: {verified}"); // Should be false
```
#### Option 3: MongoDB Compass
1. Connect to your MongoDB instance
2. Navigate to the `excititor` database
3. Select the `vex_raw` collection
4. Go to the "Indexes" tab
5. Click "Drop Index" for each of:
- `idx_provider_sourceUri_digest_unique`
- `idx_digest_providerId`
- `idx_retrievedAt`
### Impact of Rollback
**Before rollback (indexes present):**
- Documents are prevented from being duplicated
- Evidence queries are optimized
- Unique constraint enforced
**After rollback (indexes dropped):**
- Duplicate documents may be inserted
- Evidence queries may be slower
- No unique constraint enforcement
### Re-applying the Migration
To re-apply the migration after rollback:
```javascript
// MongoDB shell
db.vex_raw.createIndex(
{ "providerId": 1, "sourceUri": 1, "digest": 1 },
{ unique: true, name: "idx_provider_sourceUri_digest_unique", background: true }
)
db.vex_raw.createIndex(
{ "digest": 1, "providerId": 1 },
{ name: "idx_digest_providerId", background: true }
)
db.vex_raw.createIndex(
{ "retrievedAt": 1 },
{ name: "idx_retrievedAt", background: true }
)
```
Or run the migration runner:
```bash
stellaops excititor migrate --run 20251127-vex-raw-idempotency-indexes
```
## Migration: 20251125-vex-raw-json-schema
### Description
Adds a JSON Schema validator to the `vex_raw` collection with `validationAction: warn`.
### Rollback Steps
```javascript
// MongoDB shell - remove the validator
db.runCommand({
collMod: "vex_raw",
validator: {},
validationAction: "off",
validationLevel: "off"
})
// Verify validator is removed
db.getCollectionInfos({ name: "vex_raw" })[0].options
```
### Impact of Rollback
- Documents will no longer be validated against the schema
- Invalid documents may be inserted
- Existing documents are not affected
## General Rollback Guidelines
1. **Always backup first**: Create a backup before any rollback operation
2. **Test in staging**: Verify rollback procedure in a non-production environment
3. **Monitor performance**: Watch for query performance changes after rollback
4. **Document changes**: Log all rollback operations for audit purposes
## Troubleshooting
### Index Drop Fails
If you see "IndexNotFound" errors, the index may have already been dropped or was never created:
```javascript
// Check existing indexes
db.vex_raw.getIndexes()
```
### Validator Removal Fails
If the validator command fails, verify you have the correct permissions:
```javascript
// Check current user roles
db.runCommand({ usersInfo: 1 })
```
## Related Documentation
- [VEX Raw Schema Validation](vex-raw-schema-validation.md)
- [MongoDB Index Management](https://www.mongodb.com/docs/manual/indexes/)
- [Excititor Architecture](../modules/excititor/architecture.md)

View File

@@ -0,0 +1,197 @@
# VEX Raw Schema Validation - Offline Kit
This document describes how operators can validate the integrity of VEX raw evidence stored in MongoDB, ensuring that Excititor stores only immutable, content-addressed documents.
## Overview
The `vex_raw` collection stores raw VEX documents with content-addressed storage (documents are keyed by their cryptographic hash). This ensures immutability - documents cannot be modified after insertion without changing their key.
## Schema Definition
The MongoDB JSON Schema enforces the following structure:
```json
{
"$jsonSchema": {
"bsonType": "object",
"title": "VEX Raw Document Schema",
"description": "Schema for immutable VEX evidence storage",
"required": ["_id", "providerId", "format", "sourceUri", "retrievedAt", "digest"],
"properties": {
"_id": {
"bsonType": "string",
"description": "Content digest serving as immutable key"
},
"providerId": {
"bsonType": "string",
"minLength": 1,
"description": "VEX provider identifier"
},
"format": {
"bsonType": "string",
"enum": ["csaf", "cyclonedx", "openvex"],
"description": "VEX document format"
},
"sourceUri": {
"bsonType": "string",
"minLength": 1,
"description": "Original source URI"
},
"retrievedAt": {
"bsonType": "date",
"description": "Timestamp when document was fetched"
},
"digest": {
"bsonType": "string",
"minLength": 32,
"description": "Content hash (SHA-256 hex)"
},
"content": {
"bsonType": ["binData", "string"],
"description": "Raw document content"
},
"gridFsObjectId": {
"bsonType": ["objectId", "null", "string"],
"description": "GridFS reference for large documents"
},
"metadata": {
"bsonType": "object",
"description": "Provider-specific metadata"
}
}
}
}
```
## Offline Validation Steps
### 1. Export the Schema
The schema can be exported from the application using the validator tooling:
```bash
# Using the Excititor CLI
stellaops excititor schema export --collection vex_raw --output vex-raw-schema.json
# Or via MongoDB shell
mongosh --eval "db.getCollectionInfos({name: 'vex_raw'})[0].options.validator" > vex-raw-schema.json
```
### 2. Validate Documents in MongoDB Shell
```javascript
// Connect to your MongoDB instance
mongosh "mongodb://localhost:27017/excititor"
// Get all documents that violate the schema
db.runCommand({
validate: "vex_raw",
full: true
})
// Or check individual documents
db.vex_raw.find().forEach(function(doc) {
var result = db.runCommand({
validate: "vex_raw",
documentId: doc._id
});
if (!result.valid) {
print("Invalid: " + doc._id);
}
});
```
### 3. Programmatic Validation (C#)
```csharp
using StellaOps.Excititor.Storage.Mongo.Validation;
// Validate a single document
var result = VexRawSchemaValidator.Validate(document);
if (!result.IsValid)
{
foreach (var violation in result.Violations)
{
Console.WriteLine($"{violation.Field}: {violation.Message}");
}
}
// Batch validation
var batchResult = VexRawSchemaValidator.ValidateBatch(documents);
Console.WriteLine($"Valid: {batchResult.ValidCount}, Invalid: {batchResult.InvalidCount}");
```
### 4. Export Schema for External Tools
```csharp
// Get schema as JSON for external validation tools
var schemaJson = VexRawSchemaValidator.GetJsonSchemaAsJson();
File.WriteAllText("vex-raw-schema.json", schemaJson);
```
## Verification Checklist
Use this checklist to verify schema compliance:
- [ ] All documents have required fields (_id, providerId, format, sourceUri, retrievedAt, digest)
- [ ] The `_id` matches the `digest` value (content-addressed)
- [ ] Format is one of: csaf, cyclonedx, openvex
- [ ] Digest is at least 32 characters (SHA-256 hex)
- [ ] No documents have been modified after insertion (verify via digest recomputation)
## Immutability Verification
To verify documents haven't been tampered with:
```javascript
// MongoDB shell - verify content matches digest
db.vex_raw.find().forEach(function(doc) {
var content = doc.content;
if (content) {
// Compute SHA-256 of content
var computedDigest = hex_md5(content); // Use appropriate hash function
if (computedDigest !== doc.digest) {
print("TAMPERED: " + doc._id);
}
}
});
```
## Auditing
For compliance auditing, export a validation report:
```bash
# Generate validation report
stellaops excititor validate --collection vex_raw --report validation-report.json
# The report includes:
# - Total document count
# - Valid/invalid counts
# - List of violations by document
# - Schema version used for validation
```
## Troubleshooting
### Common Violations
1. **Missing required field**: Ensure all required fields are present
2. **Invalid format**: Format must be exactly "csaf", "cyclonedx", or "openvex"
3. **Digest too short**: Digest must be at least 32 hex characters
4. **Wrong type**: Check field types match schema requirements
### Recovery
If invalid documents are found:
1. Do NOT modify documents in place (violates immutability)
2. Export the invalid documents for analysis
3. Re-ingest from original sources with correct data
4. Document the incident in audit logs
## Related Documentation
- [Excititor Architecture](../modules/excititor/architecture.md)
- [VEX Storage Design](../modules/excititor/storage.md)
- [Offline Operation Guide](../24_OFFLINE_KIT.md)

View File

@@ -18,9 +18,9 @@
| # | Task ID & handle | State | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| P1 | PREP-POLICY-RISK-66-001-RISKPROFILE-LIBRARY-S | DONE (2025-11-22) | Due 2025-11-22 · Accountable: Risk Profile Schema Guild / `src/Policy/StellaOps.Policy.RiskProfile` | Risk Profile Schema Guild / `src/Policy/StellaOps.Policy.RiskProfile` | RiskProfile library scaffold absent (`src/Policy/StellaOps.Policy.RiskProfile` contains only AGENTS.md); need project + storage contract to place schema/validators. <br><br> Document artefact/deliverable for POLICY-RISK-66-001 and publish location so downstream tasks can proceed. Prep artefact: `docs/modules/policy/prep/2025-11-20-riskprofile-66-001-prep.md`. |
| 1 | POLICY-ENGINE-80-002 | TODO | Depends on 80-001. | Policy · Storage Guild / `src/Policy/StellaOps.Policy.Engine` | Join reachability facts + Redis caches. |
| 2 | POLICY-ENGINE-80-003 | TODO | Depends on 80-002. | Policy · Policy Editor Guild / `src/Policy/StellaOps.Policy.Engine` | SPL predicates/actions reference reachability. |
| 3 | POLICY-ENGINE-80-004 | TODO | Depends on 80-003. | Policy · Observability Guild / `src/Policy/StellaOps.Policy.Engine` | Metrics/traces for signals usage. |
| 1 | POLICY-ENGINE-80-002 | DONE (2025-11-27) | — | Policy · Storage Guild / `src/Policy/StellaOps.Policy.Engine` | Join reachability facts + Redis caches. |
| 2 | POLICY-ENGINE-80-003 | DONE (2025-11-27) | — | Policy · Policy Editor Guild / `src/Policy/StellaOps.Policy.Engine` | SPL predicates/actions reference reachability. |
| 3 | POLICY-ENGINE-80-004 | DONE (2025-11-27) | — | Policy · Observability Guild / `src/Policy/StellaOps.Policy.Engine` | Metrics/traces for signals usage. |
| 4 | POLICY-OBS-50-001 | DONE (2025-11-27) | — | Policy · Observability Guild / `src/Policy/StellaOps.Policy.Engine` | Telemetry core for API/worker hosts. |
| 5 | POLICY-OBS-51-001 | DONE (2025-11-27) | Depends on 50-001. | Policy · DevOps Guild / `src/Policy/StellaOps.Policy.Engine` | Golden-signal metrics + SLOs. |
| 6 | POLICY-OBS-52-001 | DONE (2025-11-27) | Depends on 51-001. | Policy Guild / `src/Policy/StellaOps.Policy.Engine` | Timeline events for evaluate/decision flows. |
@@ -37,6 +37,9 @@
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-27 | `POLICY-ENGINE-80-002`: Created reachability facts joining layer in `ReachabilityFacts/` directory: `ReachabilityFactsModels.cs` (data models with state/confidence/score, ReachabilityState enum, ReachabilityFactKey), `ReachabilityFactsStore.cs` (IReachabilityFactsStore interface, InMemoryReachabilityFactsStore, MongoDB index definitions), `ReachabilityFactsOverlayCache.cs` (IReachabilityFactsOverlayCache interface, InMemoryReachabilityFactsOverlayCache with TTL eviction, ReachabilityFactsCacheOptions), `ReachabilityFactsJoiningService.cs` (batch lookup with cache-first strategy, signal enrichment, ReachabilityFactsTelemetry). Registered services in Program.cs DI. | Implementer |
| 2025-11-27 | `POLICY-ENGINE-80-003`: Extended SPL predicates for reachability. Added `PolicyEvaluationReachability` record to `PolicyEvaluationContext.cs` with state/confidence/score/method/source properties and helper predicates (IsReachable, IsUnreachable, IsHighConfidence). Added `ReachabilityScope` to `PolicyExpressionEvaluator.cs` supporting SPL expressions like `reachability.state == "reachable"`, `reachability.confidence >= 0.8`, `reachability.is_high_confidence`. | Implementer |
| 2025-11-27 | `POLICY-ENGINE-80-004`: Added reachability metrics to `PolicyEngineTelemetry.cs`: `policy_reachability_applied_total{state}`, `policy_reachability_cache_hits_total`, `policy_reachability_cache_misses_total`, `policy_reachability_cache_hit_ratio` (observable gauge), `policy_reachability_lookups_total{outcome}`, `policy_reachability_lookup_seconds`. Updated `ReachabilityFactsTelemetry` to delegate to centralized PolicyEngineTelemetry. | Implementer |
| 2025-11-27 | `POLICY-RISK-67-001` (task 15): Created `Lifecycle/RiskProfileLifecycle.cs` with lifecycle models (RiskProfileLifecycleStatus enum: Draft/Active/Deprecated/Archived, RiskProfileVersionInfo, RiskProfileLifecycleEvent, RiskProfileVersionComparison, RiskProfileChange). Created `RiskProfileLifecycleService` with status transitions (CreateVersion, Activate, Deprecate, Archive, Restore), version management, event recording, and version comparison (detecting breaking changes in signals/inheritance). | Implementer |
| 2025-11-27 | `POLICY-RISK-67-001`: Created `Scoring/RiskScoringModels.cs` with FindingChangedEvent, RiskScoringJobRequest, RiskScoringJob, RiskScoringResult models and enums. Created `IRiskScoringJobStore` interface and `InMemoryRiskScoringJobStore` for job persistence. Created `RiskScoringTriggerService` handling FindingChangedEvent triggers with deduplication, batch processing, priority calculation, and job creation. Added risk scoring metrics to PolicyEngineTelemetry (jobs_created, triggers_skipped, duration, findings_scored). Registered services in Program.cs DI. | Implementer |
| 2025-11-27 | `POLICY-RISK-66-004`: Added RiskProfile project reference to StellaOps.Policy library. Created `IRiskProfileRepository` interface with GetAsync, GetVersionAsync, GetLatestAsync, ListProfileIdsAsync, ListVersionsAsync, SaveAsync, DeleteVersionAsync, DeleteAllVersionsAsync, ExistsAsync. Created `InMemoryRiskProfileRepository` for testing/development. Created `RiskProfileDiagnostics` with comprehensive validation (RISK001-RISK050 error codes) covering structure, signals, weights, overrides, and inheritance. Includes `RiskProfileDiagnosticsReport` and `RiskProfileIssue` types. | Implementer |
@@ -63,12 +66,13 @@
| 2025-11-22 | Unblocked POLICY-RISK-66-001 after prep completion; status → TODO. | Project Mgmt |
## Decisions & Risks
- Reachability inputs (80-001) prerequisite; not yet delivered.
- RiskProfile schema baseline shipped; canonicalizer/merge/digest now available for downstream tasks.
- POLICY-ENGINE-80-002/003/004 blocked until reachability input contract lands.
- POLICY-OBS-50..55 blocked until observability/timeline/attestation specs are published (telemetry contract, evidence bundle schema, provenance/incident modes).
- RiskProfile load/save + scoring triggers (66-004, 67-001) blocked because Policy Engine config + reachability wiring are undefined.
- All sprint tasks completed 2025-11-27.
- Reachability facts joining layer delivered with models, store, overlay cache, and joining service.
- SPL predicates extended for reachability: `reachability.state`, `reachability.confidence`, `reachability.score`, etc.
- Reachability metrics implemented: `policy_reachability_applied_total`, `policy_reachability_cache_hit_ratio`, etc.
- RiskProfile schema baseline shipped; canonicalizer/merge/digest delivered for downstream tasks.
- Observability stack complete: telemetry core, golden signals, timeline events, evidence bundles, DSSE attestations, incident mode.
- RiskProfile lifecycle and scoring triggers implemented.
## Next Checkpoints
- Define reachability input contract (date TBD).
- Draft RiskProfile schema baseline (date TBD).
- Sprint complete. Proceed to Sprint 0128 (Policy Engine phase VI).

View File

@@ -41,8 +41,8 @@
| 12 | SCANNER-ANALYZERS-NATIVE-20-008 | DONE (2025-11-26) | Cross-platform fixture generator and performance benchmarks implemented; 17 tests passing. | Native Analyzer Guild; QA Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | Author cross-platform fixtures (ELF dynamic/static, PE delay-load/SxS, Mach-O @rpath, plugin configs) and determinism benchmarks (<25 ms / binary, <250 MB). |
| 13 | SCANNER-ANALYZERS-NATIVE-20-009 | DONE (2025-11-26) | Runtime capture adapters implemented for Linux/Windows/macOS; 26 tests passing. | Native Analyzer Guild; Signals Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | Provide optional runtime capture adapters (Linux eBPF `dlopen`, Windows ETW ImageLoad, macOS dyld interpose) writing append-only runtime evidence; include redaction/sandbox guidance. |
| 14 | SCANNER-ANALYZERS-NATIVE-20-010 | DONE (2025-11-27) | Plugin packaging completed with DI registration, plugin catalog, and service extensions; 20 tests passing. | Native Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | Package native analyzer as restart-time plug-in with manifest/DI registration; update Offline Kit bundle and documentation. |
| 15 | SCANNER-ANALYZERS-NODE-22-001 | DOING (2025-11-24) | PREP-SCANNER-ANALYZERS-NODE-22-001-NEEDS-ISOL; rerun tests on clean runner | Node Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node) | Build input normalizer + VFS for Node projects: dirs, tgz, container layers, pnpm store, Yarn PnP zips; detect Node version targets (`.nvmrc`, `.node-version`, Dockerfile) and workspace roots deterministically. |
| 16 | SCANNER-ANALYZERS-NODE-22-002 | DOING (2025-11-24) | Depends on SCANNER-ANALYZERS-NODE-22-001; add tests once CI runner available | Node Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node) | Implement entrypoint discovery (bin/main/module/exports/imports, workers, electron, shebang scripts) and condition set builder per entrypoint. |
| 15 | SCANNER-ANALYZERS-NODE-22-001 | DONE (2025-11-27) | All 10 tests passing; input normalizer, VFS, version targets, workspace detection complete. | Node Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node) | Build input normalizer + VFS for Node projects: dirs, tgz, container layers, pnpm store, Yarn PnP zips; detect Node version targets (`.nvmrc`, `.node-version`, Dockerfile) and workspace roots deterministically. |
| 16 | SCANNER-ANALYZERS-NODE-22-002 | DONE (2025-11-27) | Entrypoint discovery (bin/main/module/exports/shebang) with condition sets; 10 tests passing. | Node Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node) | Implement entrypoint discovery (bin/main/module/exports/imports, workers, electron, shebang scripts) and condition set builder per entrypoint. |
| 17 | SCANNER-ANALYZERS-NODE-22-003 | BLOCKED (2025-11-19) | Blocked on overlay/callgraph schema alignment and test fixtures; resolver wiring pending fixture drop. | Node Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node) | Parse JS/TS sources for static `import`, `require`, `import()` and string concat cases; flag dynamic patterns with confidence levels; support source map de-bundling. |
| 18 | SCANNER-ANALYZERS-NODE-22-004 | TODO | Depends on SCANNER-ANALYZERS-NODE-22-003 | Node Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node) | Implement Node resolver engine for CJS + ESM (core modules, exports/imports maps, conditions, extension priorities, self-references) parameterised by node_version. |
| 19 | SCANNER-ANALYZERS-NODE-22-005 | TODO | Depends on SCANNER-ANALYZERS-NODE-22-004 | Node Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node) | Add package manager adapters: Yarn PnP (.pnp.data/.pnp.cjs), pnpm virtual store, npm/Yarn classic hoists; operate entirely in virtual FS. |
@@ -55,6 +55,7 @@
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-27 | **NODE-22-001 and NODE-22-002 COMPLETED.** Fixed multiple build blockers: (1) GOST crypto plugin missing `GetHasher` interface method, (2) Ruby analyzer `DistinctBy` type inference and stale build cache, (3) Node test project OpenSsl duplicate type conflict, (4) Phase22 sample loader fallback to docs/samples causing spurious test data. Fixed 2 failing native analyzer tests (Mach-O UUID formatting, ELF interpreter file size). Updated golden files for version-targets and entrypoints fixtures. All 10 Node analyzer tests now passing. Native analyzer tests: 165 passing. | Implementer |
| 2025-11-27 | Attempted targeted Node analyzer test slice (`StellaOps.Scanner.Node.slnf --filter FullyQualifiedName~NodeLanguageAnalyzerTests --no-restore`); build graph pulled broader solution and was cancelled to avoid runaway runtime. Node tasks remain DOING pending slimmer graph/clean runner. | Node Analyzer Guild |
| 2025-11-27 | SCANNER-ANALYZERS-NATIVE-20-010: Implemented plugin packaging in `Plugin/` namespace. Created `INativeAnalyzerPlugin` interface (Name, Description, Version, SupportedFormats, IsAvailable, CreateAnalyzer), `INativeAnalyzer` interface (AnalyzeAsync, AnalyzeBatchAsync), `NativeAnalyzerOptions` configuration. Implemented `NativeAnalyzer` core class orchestrating format detection, parsing (ELF/PE/Mach-O), heuristic scanning, and resolution. Created `NativeAnalyzerPlugin` factory (always available, supports ELF/PE/Mach-O). Built `NativeAnalyzerPluginCatalog` with convention-based loading (`StellaOps.Scanner.Analyzers.Native*.dll`), registration, sealing, and analyzer creation. Added `ServiceCollectionExtensions` with `AddNativeAnalyzer()` (options binding, DI registration) and `AddNativeRuntimeCapture()`. Created `NativeAnalyzerServiceOptions` with platform-specific default search paths. Added NuGet dependencies (Microsoft.Extensions.*). 20 new tests in `PluginPackagingTests.cs` covering plugin properties, catalog operations, DI registration, and analyzer integration. Total native analyzer: 163 tests passing. Task DONE. | Native Analyzer Guild |
| 2025-11-26 | SCANNER-ANALYZERS-NATIVE-20-009: Implemented runtime capture adapters in `RuntimeCapture/` namespace. Created models (`RuntimeEvidence.cs`): `RuntimeLoadEvent`, `RuntimeCaptureSession`, `RuntimeEvidence`, `RuntimeLibrarySummary`, `RuntimeDependencyEdge` with reason codes (`runtime-dlopen`, `runtime-loadlibrary`, `runtime-dylib`). Created configuration (`RuntimeCaptureOptions.cs`): buffer size, duration limits, include/exclude patterns, redaction options (home dirs, SSH keys, secrets), sandbox mode with mock events. Created interface (`IRuntimeCaptureAdapter.cs`): state machine (IdleStartingRunningStoppingStopped/Faulted), events, factory pattern. Created platform adapters: `LinuxEbpfCaptureAdapter` (bpftrace/eBPF), `WindowsEtwCaptureAdapter` (ETW ImageLoad), `MacOsDyldCaptureAdapter` (dtrace). Created aggregator (`RuntimeEvidenceAggregator.cs`) merging runtime evidence with static/heuristic analysis. Added `NativeObservationRuntimeEdge` model and `AddRuntimeEdge()` builder method. 26 new tests in `RuntimeCaptureTests.cs` covering options validation, redaction, aggregation, sandbox capture, state transitions. Total native analyzer: 143 tests passing. Task DONE. | Native Analyzer Guild |

View File

@@ -19,9 +19,9 @@
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 1 | SCANNER-ANALYZERS-PHP-27-009 | TODO | Depends on PHP analyzer core (27-007). | PHP Analyzer Guild · QA Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php`) | Fixture suite + performance benchmarks (Laravel, Symfony, WordPress, legacy, PHAR, container) with golden outputs. |
| 2 | SCANNER-ANALYZERS-PHP-27-010 | TODO | Depends on 27-009. | PHP Analyzer Guild · Signals Guild | Optional runtime evidence hooks (audit logs/opcache stats) with path hashing. |
| 3 | SCANNER-ANALYZERS-PHP-27-011 | TODO | Depends on 27-010. | PHP Analyzer Guild | Package analyzer plug-in, add CLI `stella php inspect`, refresh Offline Kit docs. |
| 1 | SCANNER-ANALYZERS-PHP-27-009 | DONE | Fixtures and benchmarks created and verified. | PHP Analyzer Guild · QA Guild (`src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php`) | Fixture suite + performance benchmarks (Laravel, Symfony, WordPress, legacy, PHAR, container) with golden outputs. |
| 2 | SCANNER-ANALYZERS-PHP-27-010 | DONE | Runtime evidence infrastructure complete. | PHP Analyzer Guild · Signals Guild | Optional runtime evidence hooks (audit logs/opcache stats) with path hashing. |
| 3 | SCANNER-ANALYZERS-PHP-27-011 | DONE | CLI command and docs complete. | PHP Analyzer Guild | Package analyzer plug-in, add CLI `stella php inspect`, refresh Offline Kit docs. |
## Execution Log
| Date (UTC) | Update | Owner |
@@ -29,6 +29,9 @@
| 2025-11-08 | Sprint stub created; awaiting completion of Sprint 0133. | Planning |
| 2025-11-19 | Normalized sprint to standard template and renamed from `SPRINT_134_scanner_surface.md` to `SPRINT_0134_0001_0001_scanner_surface.md`; content preserved. | Implementer |
| 2025-11-19 | Converted legacy filename `SPRINT_134_scanner_surface.md` to redirect stub pointing here to avoid divergent updates. | Implementer |
| 2025-11-27 | Task 27-009: Created 6 fixtures (laravel-extended, symfony, wordpress, legacy, phar, container) with composer.lock + expected.json golden outputs; added 7 test methods to PhpLanguageAnalyzerTests; created benchmark project with latency budgets. Fixed GlobalUsings.cs missing System.Diagnostics.CodeAnalysis. Fixed ComposerLockReader null reference warnings. | Implementer |
| 2025-11-27 | Task 27-010: Created runtime evidence infrastructure in Internal/Runtime/: PhpRuntimeEvidence.cs (data models), PhpRuntimeShim.cs (PHP script for runtime tracing with autoload hooks, opcache stats, capability detection, path hashing), PhpRuntimeEvidenceCollector.cs (NDJSON parser with deterministic ordering). | Implementer |
| 2025-11-27 | Task 27-011: Implemented CLI `stella php inspect` command (cross-module edit): added PHP analyzer reference to StellaOps.Cli.csproj, BuildPhpCommand to CommandFactory.cs, HandlePhpInspectAsync/RenderPhpInspectReport/PhpInspectReport/PhpInspectEntry/PhpMetadataHelpers to CommandHandlers.cs, PhpInspectCounter and RecordPhpInspect to CliMetrics.cs. Updated Offline Kit docs (24_OFFLINE_KIT.md) to include PHP analyzer in scanner plug-ins list, language analyzers section, tar verification command, and release guardrail smoke tests. | Implementer |
## Decisions & Risks
- All PHP tasks depend on prior analyzer core; remain TODO until upstream tasks land.

View File

@@ -19,7 +19,7 @@
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 1 | SCANNER-ANALYZERS-PYTHON-23-012 | TODO | Depends on 23-011. | Python Analyzer Guild (`src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Python`) | Container/zipapp adapter enhancements: parse OCI layers for Python runtime, detect `PYTHONPATH`/`PYTHONHOME`, warn on sitecustomize/startup hooks. |
| 1 | SCANNER-ANALYZERS-PYTHON-23-012 | DONE | — | Python Analyzer Guild (`src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Python`) | Container/zipapp adapter enhancements: parse OCI layers for Python runtime, detect `PYTHONPATH`/`PYTHONHOME`, warn on sitecustomize/startup hooks. |
| 2 | SCANNER-ANALYZERS-RUBY-28-001 | DONE | — | Ruby Analyzer Guild (`src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Ruby`) | Input normalizer & VFS for Ruby projects: merge sources, Gemfile/lock, vendor/bundle, .gem archives, `.bundle/config`, Rack configs, containers; detect framework/job fingerprints deterministically. |
| 3 | SCANNER-ANALYZERS-RUBY-28-002 | DONE | Depends on 28-001. | Ruby Analyzer Guild | Gem & Bundler analyzer: parse Gemfile/lock, vendor specs, .gem archives; produce package nodes (PURLs), dependency edges, and resolver traces. |
| 4 | SCANNER-ANALYZERS-RUBY-28-003 | DONE | Depends on 28-002. | Ruby Analyzer Guild · SBOM Guild | Produce AOC-compliant observations (entrypoints, components, edges) plus environment profiles; integrate with Scanner writer. |
@@ -39,6 +39,7 @@
| 2025-11-27 | Completed SCANNER-ANALYZERS-RUBY-28-004: Created cli-app fixture with Thor/TTY-Prompt, updated expected.json golden files for dependency edges format; all 4 determinism tests pass. | Implementer |
| 2025-11-27 | Completed SCANNER-ANALYZERS-RUBY-28-005: Created Runtime directory with RubyRuntimeShim.cs (trace-shim.rb Ruby script using TracePoint for require/load hooks with redaction and capability detection), RubyRuntimeTraceRunner.cs (opt-in harness triggered by STELLA_RUBY_ENTRYPOINT env var), and RubyRuntimeTraceReader.cs (NDJSON parser for trace events). Append-only evidence, sandbox guidance via BUNDLE_FROZEN/BUNDLE_DISABLE_EXEC_LOAD. | Implementer |
| 2025-11-27 | Completed SCANNER-ANALYZERS-RUBY-28-006: Created manifest.json for Ruby analyzer plug-in (id: stellaops.analyzer.lang.ruby, capabilities: ruby/rubygems/bundler, runtime-capture: optional). Updated docs/24_OFFLINE_KIT.md to include Ruby in language analyzers list, manifest examples, tar verification commands, and release guardrail smoke test references. | Implementer |
| 2025-11-27 | Completed SCANNER-ANALYZERS-PYTHON-23-012: Created PythonContainerAdapter.cs for OCI layer parsing (layers/, .layers/, layer/ with fs/ subdirs); PythonEnvironmentDetector.cs for PYTHONPATH/PYTHONHOME detection from .env, pyvenv.cfg, OCI config.json; PythonStartupHookDetector.cs for sitecustomize.py/usercustomize.py/.pth file detection with warnings. Integrated into PythonLanguageAnalyzer.cs with metadata helpers. Added 5 tests for container layer, environment, and startup hook detection. | Implementer |
## Decisions & Risks
- Ruby and Python tasks depend on prior phases; all remain TODO until upstream tasks land.

View File

@@ -8,10 +8,10 @@ Summary: Ingestion & Evidence focus on Excititor (phase III).
> **Prep:** Read `docs/modules/excititor/architecture.md` and the Excititor component `AGENTS.md` guidance before acting on these tasks (requirement carried over from the component boards).
Task ID | State | Task description | Owners (Source)
--- | --- | --- | ---
EXCITITOR-LNM-21-001 `Observation & linkset stores` | TODO | Stand up `vex_observations` and `vex_linksets` collections with shard keys, tenant guards, and migrations that retire any residual merge-era data without mutating raw content. | Excititor Storage Guild (src/Excititor/__Libraries/StellaOps.Excititor.Storage.Mongo)
EXCITITOR-LNM-21-002 `Conflict annotations` | TODO | Capture disagreement metadata (status + justification deltas) directly inside linksets with confidence scores so downstream consumers can highlight conflicts without Excititor choosing winners. Depends on EXCITITOR-LNM-21-001. | Excititor Core Guild (src/Excititor/__Libraries/StellaOps.Excititor.Core)
EXCITITOR-LNM-21-003 `Event emission` | TODO | Emit `vex.linkset.updated` events and describe payload shape (observation ids, confidence, conflict summary) so Policy/Lens/UI can subscribe while Excititor stays aggregation-only. Depends on EXCITITOR-LNM-21-002. | Excititor Core Guild, Platform Events Guild (src/Excititor/__Libraries/StellaOps.Excititor.Core)
EXCITITOR-LNM-21-201 `Observation APIs` | TODO | Ship `/vex/observations` read endpoints with filters for advisory/product/issuer, strict RBAC, and deterministic pagination (no derived verdict fields). Depends on EXCITITOR-LNM-21-003. | Excititor WebService Guild (src/Excititor/StellaOps.Excititor.WebService)
EXCITITOR-LNM-21-202 `Linkset APIs` | TODO | Provide `/vex/linksets` + export endpoints that surface alias mappings, conflict markers, and provenance proofs exactly as stored; errors must map to `ERR_AGG_*`. Depends on EXCITITOR-LNM-21-201. | Excititor WebService Guild (src/Excititor/StellaOps.Excititor.WebService)
EXCITITOR-LNM-21-203 `Docs & SDK examples` | TODO | Update OpenAPI, SDK smoke tests, and documentation to cover the new observation/linkset endpoints with realistic examples Advisory AI/Lens teams can rely on. Depends on EXCITITOR-LNM-21-202. | Excititor WebService Guild, Docs Guild (src/Excititor/StellaOps.Excititor.WebService)
EXCITITOR-OBS-51-001 `Metrics & SLOs` | TODO | Publish ingest latency, scope resolution success, conflict rate, and signature verification metrics plus SLO burn alerts so we can prove Excititor meets the AOC evidence freshness mission. | Excititor Core Guild, DevOps Guild (src/Excititor/__Libraries/StellaOps.Excititor.Core)
EXCITITOR-LNM-21-001 `Observation & linkset stores` | DONE | Stand up `vex_observations` and `vex_linksets` collections with shard keys, tenant guards, and migrations that retire any residual merge-era data without mutating raw content. | Excititor Storage Guild (src/Excititor/__Libraries/StellaOps.Excititor.Storage.Mongo)
EXCITITOR-LNM-21-002 `Conflict annotations` | DONE | Capture disagreement metadata (status + justification deltas) directly inside linksets with confidence scores so downstream consumers can highlight conflicts without Excititor choosing winners. Depends on EXCITITOR-LNM-21-001. | Excititor Core Guild (src/Excititor/__Libraries/StellaOps.Excititor.Core)
EXCITITOR-LNM-21-003 `Event emission` | DONE | Emit `vex.linkset.updated` events and describe payload shape (observation ids, confidence, conflict summary) so Policy/Lens/UI can subscribe while Excititor stays aggregation-only. Depends on EXCITITOR-LNM-21-002. | Excititor Core Guild, Platform Events Guild (src/Excititor/__Libraries/StellaOps.Excititor.Core)
EXCITITOR-LNM-21-201 `Observation APIs` | DONE | Ship `/vex/observations` read endpoints with filters for advisory/product/issuer, strict RBAC, and deterministic pagination (no derived verdict fields). Depends on EXCITITOR-LNM-21-003. | Excititor WebService Guild (src/Excititor/StellaOps.Excititor.WebService)
EXCITITOR-LNM-21-202 `Linkset APIs` | DONE | Provide `/vex/linksets` + export endpoints that surface alias mappings, conflict markers, and provenance proofs exactly as stored; errors must map to `ERR_AGG_*`. Depends on EXCITITOR-LNM-21-201. | Excititor WebService Guild (src/Excititor/StellaOps.Excititor.WebService)
EXCITITOR-LNM-21-203 `Docs & SDK examples` | DONE | Update OpenAPI, SDK smoke tests, and documentation to cover the new observation/linkset endpoints with realistic examples Advisory AI/Lens teams can rely on. Depends on EXCITITOR-LNM-21-202. | Excititor WebService Guild, Docs Guild (src/Excititor/StellaOps.Excititor.WebService)
EXCITITOR-OBS-51-001 `Metrics & SLOs` | DONE | Publish ingest latency, scope resolution success, conflict rate, and signature verification metrics plus SLO burn alerts so we can prove Excititor meets the AOC "evidence freshness" mission. | Excititor Core Guild, DevOps Guild (src/Excititor/__Libraries/StellaOps.Excititor.Core)

View File

@@ -8,11 +8,11 @@ Summary: Ingestion & Evidence focus on Excititor (phase IV).
> **Prep:** Read `docs/modules/excititor/architecture.md` and the relevant Excititor `AGENTS.md` files before updating these tasks.
Task ID | State | Task description | Owners (Source)
--- | --- | --- | ---
EXCITITOR-OBS-52-001 `Timeline events` | TODO | Emit `timeline_event` entries for every ingest/linkset change with trace IDs, justification summaries, and evidence hashes so downstream systems can replay the raw facts chronologically. Depends on EXCITITOR-OBS-51-001. | Excititor Core Guild (src/Excititor/__Libraries/StellaOps.Excititor.Core)
EXCITITOR-OBS-53-001 `Evidence snapshots` | TODO | Build locker payloads (raw doc, normalization diff, provenance) and Merkle manifests so sealed-mode sites can audit evidence without Excititor reinterpreting it. Depends on EXCITITOR-OBS-52-001. | Excititor Core Guild, Evidence Locker Guild (src/Excititor/__Libraries/StellaOps.Excititor.Core)
EXCITITOR-OBS-54-001 `Attestation & verification` | TODO | Attach DSSE attestations to every evidence batch, verify chains via Provenance tooling, and surface attestation IDs on timeline events. Depends on EXCITITOR-OBS-53-001. | Excititor Core Guild, Provenance Guild (src/Excititor/__Libraries/StellaOps.Excititor.Core)
EXCITITOR-ORCH-32-001 `Worker orchestration` | TODO | Adopt the orchestrator worker SDK for Excititor jobs, emitting heartbeats/progress/artifact hashes so ingestion remains deterministic and restartable without reprocessing evidence. | Excititor Worker Guild (src/Excititor/StellaOps.Excititor.Worker)
EXCITITOR-ORCH-33-001 `Control compliance` | TODO | Honor orchestrator pause/throttle/retry commands, persist checkpoints, and classify error outputs to keep ingestion safe under outages. Depends on EXCITITOR-ORCH-32-001. | Excititor Worker Guild (src/Excititor/StellaOps.Excititor.Worker)
EXCITITOR-OBS-52-001 `Timeline events` | DONE (2025-11-27) | Emit `timeline_event` entries for every ingest/linkset change with trace IDs, justification summaries, and evidence hashes so downstream systems can replay the raw facts chronologically. Depends on EXCITITOR-OBS-51-001. | Excititor Core Guild (src/Excititor/__Libraries/StellaOps.Excititor.Core)
EXCITITOR-OBS-53-001 `Evidence snapshots` | DONE (2025-11-27) | Build locker payloads (raw doc, normalization diff, provenance) and Merkle manifests so sealed-mode sites can audit evidence without Excititor reinterpreting it. Depends on EXCITITOR-OBS-52-001. | Excititor Core Guild, Evidence Locker Guild (src/Excititor/__Libraries/StellaOps.Excititor.Core)
EXCITITOR-OBS-54-001 `Attestation & verification` | DONE (2025-11-27) | Attach DSSE attestations to every evidence batch, verify chains via Provenance tooling, and surface attestation IDs on timeline events. Depends on EXCITITOR-OBS-53-001. | Excititor Core Guild, Provenance Guild (src/Excititor/__Libraries/StellaOps.Excititor.Core)
EXCITITOR-ORCH-32-001 `Worker orchestration` | DONE (2025-11-27) | Adopt the orchestrator worker SDK for Excititor jobs, emitting heartbeats/progress/artifact hashes so ingestion remains deterministic and restartable without reprocessing evidence. | Excititor Worker Guild (src/Excititor/StellaOps.Excititor.Worker)
EXCITITOR-ORCH-33-001 `Control compliance` | DONE (2025-11-27) | Honor orchestrator pause/throttle/retry commands, persist checkpoints, and classify error outputs to keep ingestion safe under outages. Depends on EXCITITOR-ORCH-32-001. | Excititor Worker Guild (src/Excititor/StellaOps.Excititor.Worker)
EXCITITOR-POLICY-20-001 `Policy selection APIs` | TODO | Provide VEX lookup APIs (PURL/advisory batching, scope filters, tenant enforcement) that Policy Engine uses to join evidence without Excititor performing any verdict logic. Depends on EXCITITOR-AOC-20-004. | Excititor WebService Guild (src/Excititor/StellaOps.Excititor.WebService)
EXCITITOR-POLICY-20-002 `Scope-aware linksets` | TODO | Enhance linksets with scope resolution + version range metadata so Policy/Reachability can reason about applicability while Excititor continues to report only raw context. Depends on EXCITITOR-POLICY-20-001. | Excititor Core Guild (src/Excititor/__Libraries/StellaOps.Excititor.Core)
EXCITITOR-RISK-66-001 `Risk gating feed` | TODO | Publish risk-engine ready feeds (status, justification, provenance) with zero derived severity so gating services can reference Excititor as a source of truth. Depends on EXCITITOR-POLICY-20-002. | Excititor Core Guild, Risk Engine Guild (src/Excititor/__Libraries/StellaOps.Excititor.Core)

View File

@@ -8,11 +8,11 @@ Summary: Ingestion & Evidence focus on Excititor (phase V).
> **Prep:** Read `docs/modules/excititor/architecture.md` and the Excititor component `AGENTS.md` files before touching this sprints tasks.
Task ID | State | Task description | Owners (Source)
--- | --- | --- | ---
EXCITITOR-VEXLENS-30-001 `VEX evidence enrichers` | TODO | Ensure every observation exported to VEX Lens carries issuer hints, signature blobs, product tree snippets, and staleness metadata so the lens can compute consensus without calling back into Excititor. | Excititor WebService Guild, VEX Lens Guild (src/Excititor/StellaOps.Excititor.WebService)
EXCITITOR-VULN-29-001 `VEX key canonicalization` | TODO | Canonicalize advisory/product keys (map to `advisory_key`, capture scope metadata) while preserving original identifiers in `links[]`; run backfill + regression tests. | Excititor WebService Guild (src/Excititor/StellaOps.Excititor.WebService)
EXCITITOR-VEXLENS-30-001 `VEX evidence enrichers` | DONE | Ensure every observation exported to VEX Lens carries issuer hints, signature blobs, product tree snippets, and staleness metadata so the lens can compute consensus without calling back into Excititor. **Completed:** Enhanced `OpenVexSourceEntry` with enrichment fields (issuerHint, signatureType, keyId, transparencyLogRef, trustWeight, trustTier, stalenessSeconds, productTreeSnippet). Updated `OpenVexStatementMerger.BuildSources()` to extract from VexClaim. Enhanced `OpenVexExportSource` JSON serialization. | Excititor WebService Guild, VEX Lens Guild (src/Excititor/StellaOps.Excititor.WebService)
EXCITITOR-VULN-29-001 `VEX key canonicalization` | DONE | Canonicalize advisory/product keys (map to `advisory_key`, capture scope metadata) while preserving original identifiers in `links[]`; run backfill + regression tests. **Completed:** Created `VexAdvisoryKeyCanonicalizer` (CVE/GHSA/RHSA/DSA/USN) and `VexProductKeyCanonicalizer` (PURL/CPE/RPM/DEB/OCI) in `Core/Canonicalization/`. All 47 tests passing. Supports extracting PURLs/CPEs from component identifiers. | Excititor WebService Guild (src/Excititor/StellaOps.Excititor.WebService)
EXCITITOR-VULN-29-002 `Evidence retrieval APIs` | TODO | Provide `/vuln/evidence/vex/{advisory_key}` returning tenant-scoped raw statements, provenance, and attestation references for Vuln Explorer evidence tabs. Depends on EXCITITOR-VULN-29-001. | Excititor WebService Guild (src/Excititor/StellaOps.Excititor.WebService)
EXCITITOR-VULN-29-004 `Observability` | TODO | Add metrics/logs for normalization errors, suppression scopes, withdrawn statements, and feed them to Vuln Explorer + Advisory AI dashboards. Depends on EXCITITOR-VULN-29-002. | Excititor WebService Guild, Observability Guild (src/Excititor/StellaOps.Excititor.WebService)
EXCITITOR-STORE-AOC-19-001 `vex_raw schema validator` | TODO | Ship Mongo JSON Schema + validator tooling (including Offline Kit instructions) so operators can prove Excititor stores only immutable evidence. | Excititor Storage Guild (src/Excititor/__Libraries/StellaOps.Excititor.Storage.Mongo)
EXCITITOR-STORE-AOC-19-002 `Idempotency index & migration` | TODO | Create unique indexes, run migrations/backfills, and document rollback steps for the new schema validator. Depends on EXCITITOR-STORE-AOC-19-001. | Excititor Storage Guild, DevOps Guild (src/Excititor/__Libraries/StellaOps.Excititor.Storage.Mongo)
EXCITITOR-STORE-AOC-19-001 `vex_raw schema validator` | DONE | Ship Mongo JSON Schema + validator tooling (including Offline Kit instructions) so operators can prove Excititor stores only immutable evidence. **Completed:** Created `VexRawSchemaValidator` in `Storage.Mongo/Validation/` with `Validate()`, `ValidateBatch()`, `GetJsonSchema()` methods. Added Offline Kit docs at `docs/airgap/vex-raw-schema-validation.md`. | Excititor Storage Guild (src/Excititor/__Libraries/StellaOps.Excititor.Storage.Mongo)
EXCITITOR-STORE-AOC-19-002 `Idempotency index & migration` | DONE | Create unique indexes, run migrations/backfills, and document rollback steps for the new schema validator. Depends on EXCITITOR-STORE-AOC-19-001. **Completed:** Created `VexRawIdempotencyIndexMigration` with unique indexes (provider+source+digest), query indexes (digest+provider), and time-based index. Added rollback docs at `docs/airgap/vex-raw-migration-rollback.md`. Registered migration in ServiceCollectionExtensions. | Excititor Storage Guild, DevOps Guild (src/Excititor/__Libraries/StellaOps.Excititor.Storage.Mongo)
EXCITITOR-AIRGAP-56-001 `Mirror registration APIs` | TODO | Support mirror bundle registration + provenance exposure, including sealed-mode error mapping and staleness metrics surfaced via API responses. | Excititor WebService Guild (src/Excititor/StellaOps.Excititor.WebService)
EXCITITOR-AIRGAP-58-001 `Portable evidence bundles` | TODO | Produce portable evidence bundles linked to timeline + attestation metadata for sealed deployments, and document verifier steps for Advisory AI teams. Depends on EXCITITOR-AIRGAP-56-001. | Excititor Core Guild, Evidence Locker Guild (src/Excititor/__Libraries/StellaOps.Excititor.Core)

View File

@@ -8,10 +8,10 @@ Summary: Ingestion & Evidence focus on Excititor (phase VI).
> **Prep:** Read `docs/modules/excititor/architecture.md` and the Excititor component `AGENTS.md` files before working any items listed below.
Task ID | State | Task description | Owners (Source)
--- | --- | --- | ---
EXCITITOR-WEB-OBS-52-001 `Timeline streaming` | TODO | Provide SSE/WebSocket bridges for VEX timeline events with tenant filters, pagination anchors, and guardrails so downstream consoles can monitor raw evidence changes in real time. Depends on EXCITITOR-OBS-52-001. | Excititor WebService Guild (src/Excititor/StellaOps.Excititor.WebService)
EXCITITOR-WEB-OBS-53-001 `Evidence APIs` | TODO | Expose `/evidence/vex/*` endpoints that fetch locker bundles, enforce scopes, and surface verification metadata without synthesizing verdicts. Depends on EXCITITOR-WEB-OBS-52-001. | Excititor WebService Guild, Evidence Locker Guild (src/Excititor/StellaOps.Excititor.WebService)
EXCITITOR-WEB-OBS-54-001 `Attestation APIs` | TODO | Add `/attestations/vex/*` endpoints returning DSSE verification state, builder identity, and chain-of-custody links so consumers never need direct datastore access. Depends on EXCITITOR-WEB-OBS-53-001. | Excititor WebService Guild (src/Excititor/StellaOps.Excititor.WebService)
EXCITITOR-WEB-OAS-61-001 `OpenAPI discovery` | TODO | Implement `/.well-known/openapi` with spec version metadata plus standard error envelopes, then update controller/unit tests accordingly. | Excititor WebService Guild (src/Excititor/StellaOps.Excititor.WebService)
EXCITITOR-WEB-OAS-62-001 `Examples & deprecation headers` | TODO | Publish curated examples for the new evidence/attestation/timeline endpoints, emit deprecation headers for legacy routes, and align SDK docs. Depends on EXCITITOR-WEB-OAS-61-001. | Excititor WebService Guild, API Governance Guild (src/Excititor/StellaOps.Excititor.WebService)
EXCITITOR-WEB-AIRGAP-58-001 `Bundle import telemetry` | TODO | Emit timeline events + audit logs for mirror bundle imports (bundle ID, scope, actor) and map sealed-mode violations to actionable remediation guidance. | Excititor WebService Guild, AirGap Importer/Policy Guilds (src/Excititor/StellaOps.Excititor.WebService)
EXCITITOR-CRYPTO-90-001 `Crypto provider abstraction` | TODO | Replace ad-hoc hashing/signing in connectors/exporters/OpenAPI discovery with `ICryptoProviderRegistry` implementations approved by security so evidence verification stays deterministic across crypto profiles. | Excititor WebService Guild, Security Guild (src/Excititor/StellaOps.Excititor.WebService)
EXCITITOR-WEB-OBS-52-001 `Timeline streaming` | DONE | Provide SSE/WebSocket bridges for VEX timeline events with tenant filters, pagination anchors, and guardrails so downstream consoles can monitor raw evidence changes in real time. Depends on EXCITITOR-OBS-52-001. | Excititor WebService Guild (src/Excititor/StellaOps.Excititor.WebService)
EXCITITOR-WEB-OBS-53-001 `Evidence APIs` | DONE | Expose `/evidence/vex/*` endpoints that fetch locker bundles, enforce scopes, and surface verification metadata without synthesizing verdicts. Depends on EXCITITOR-WEB-OBS-52-001. | Excititor WebService Guild, Evidence Locker Guild (src/Excititor/StellaOps.Excititor.WebService)
EXCITITOR-WEB-OBS-54-001 `Attestation APIs` | DONE | Add `/attestations/vex/*` endpoints returning DSSE verification state, builder identity, and chain-of-custody links so consumers never need direct datastore access. Depends on EXCITITOR-WEB-OBS-53-001. | Excititor WebService Guild (src/Excititor/StellaOps.Excititor.WebService)
EXCITITOR-WEB-OAS-61-001 `OpenAPI discovery` | DONE | Implement `/.well-known/openapi` with spec version metadata plus standard error envelopes, then update controller/unit tests accordingly. | Excititor WebService Guild (src/Excititor/StellaOps.Excititor.WebService)
EXCITITOR-WEB-OAS-62-001 `Examples & deprecation headers` | DONE | Publish curated examples for the new evidence/attestation/timeline endpoints, emit deprecation headers for legacy routes, and align SDK docs. Depends on EXCITITOR-WEB-OAS-61-001. | Excititor WebService Guild, API Governance Guild (src/Excititor/StellaOps.Excititor.WebService)
EXCITITOR-WEB-AIRGAP-58-001 `Bundle import telemetry` | DONE | Emit timeline events + audit logs for mirror bundle imports (bundle ID, scope, actor) and map sealed-mode violations to actionable remediation guidance. | Excititor WebService Guild, AirGap Importer/Policy Guilds (src/Excititor/StellaOps.Excititor.WebService)
EXCITITOR-CRYPTO-90-001 `Crypto provider abstraction` | DONE | Replace ad-hoc hashing/signing in connectors/exporters/OpenAPI discovery with `ICryptoProviderRegistry` implementations approved by security so evidence verification stays deterministic across crypto profiles. | Excititor WebService Guild, Security Guild (src/Excititor/StellaOps.Excititor.WebService)

View File

@@ -12,10 +12,10 @@ Focus: Policy & Reasoning focus on Policy (phase II).
| --- | --- | --- | --- | --- |
| P1 | PREP-POLICY-ENGINE-20-002-BUILD-DETERMINISTIC | DONE (2025-11-20) | Prep doc at `docs/modules/policy/prep/2025-11-20-policy-engine-20-002-prep.md`; captures evaluator constraints. | Policy Guild / src/Policy/StellaOps.Policy.Engine | Build deterministic evaluator honoring lexical/priority order, first-match semantics, and safe value types (no wall-clock/network access). <br><br> Document artefact/deliverable for POLICY-ENGINE-20-002 and publish location so downstream tasks can proceed. |
| 1 | POLICY-CONSOLE-23-002 | TODO | Produce simulation diff metadata (before/after counts, severity deltas, rule impact summaries) and approval state endpoints consumed by Console policy workspace; expose RBAC-aware status transitions (Deps: POLICY-CONSOLE-23-001) | Policy Guild, Product Ops / src/Policy/StellaOps.Policy.Engine |
| 2 | POLICY-ENGINE-20-002 | BLOCKED (2025-10-26) | PREP-POLICY-ENGINE-20-002-BUILD-DETERMINISTIC | Policy Guild / src/Policy/StellaOps.Policy.Engine |
| 3 | POLICY-ENGINE-20-003 | TODO | Implement selection joiners resolving SBOM↔advisory↔VEX tuples using linksets and PURL equivalence tables, with deterministic batching (Deps: POLICY-ENGINE-20-002) | Policy Guild, Concelier Core Guild, Excititor Core Guild / src/Policy/StellaOps.Policy.Engine |
| 4 | POLICY-ENGINE-20-004 | TODO | Ship materialization writer that upserts into `effective_finding_{policyId}` with append-only history, tenant scoping, and trace references (Deps: POLICY-ENGINE-20-003) | Policy Guild, Platform Storage Guild / src/Policy/StellaOps.Policy.Engine |
| 5 | POLICY-ENGINE-20-005 | TODO | Enforce determinism guard banning wall-clock, RNG, and network usage during evaluation via static analysis + runtime sandbox (Deps: POLICY-ENGINE-20-004) | Policy Guild, Security Engineering / src/Policy/StellaOps.Policy.Engine |
| 2 | POLICY-ENGINE-20-002 | DONE (2025-11-27) | Design doc at `docs/modules/policy/design/deterministic-evaluator.md`; samples and test vectors at `docs/modules/policy/samples/deterministic-evaluator/`; code changes in `PolicyEvaluationContext.cs` and `PolicyExpressionEvaluator.cs` | Policy Guild / src/Policy/StellaOps.Policy.Engine |
| 3 | POLICY-ENGINE-20-003 | DONE (2025-11-27) | SelectionJoin models, PurlEquivalence table, and SelectionJoinService implemented in `src/Policy/StellaOps.Policy.Engine/SelectionJoin/` | Policy Guild, Concelier Core Guild, Excititor Core Guild / src/Policy/StellaOps.Policy.Engine |
| 4 | POLICY-ENGINE-20-004 | DONE (2025-11-27) | Materialization writer implemented in `src/Policy/StellaOps.Policy.Engine/Materialization/` with `EffectiveFinding` models, append-only history, tenant scoping, and trace references | Policy Guild, Platform Storage Guild / src/Policy/StellaOps.Policy.Engine |
| 5 | POLICY-ENGINE-20-005 | DONE (2025-11-27) | Determinism guard implemented in `src/Policy/StellaOps.Policy.Engine/DeterminismGuard/` with static analyzer (`ProhibitedPatternAnalyzer`), runtime sandbox (`DeterminismGuardService`, `EvaluationScope`), and guarded evaluator integration (`GuardedPolicyEvaluator`) | Policy Guild, Security Engineering / src/Policy/StellaOps.Policy.Engine |
| 6 | POLICY-ENGINE-20-006 | TODO | Implement incremental orchestrator reacting to advisory/vex/SBOM change streams and scheduling partial policy re-evaluations (Deps: POLICY-ENGINE-20-005) | Policy Guild, Scheduler Worker Guild / src/Policy/StellaOps.Policy.Engine |
| 7 | POLICY-ENGINE-20-007 | TODO | Emit structured traces/logs of rule hits with sampling controls, metrics (`rules_fired_total`, `vex_overrides_total`), and expose explain trace exports (Deps: POLICY-ENGINE-20-006) | Policy Guild, Observability Guild / src/Policy/StellaOps.Policy.Engine |
| 8 | POLICY-ENGINE-20-008 | TODO | Add unit/property/golden/perf suites covering policy compilation, evaluation correctness, determinism, and SLA targets (Deps: POLICY-ENGINE-20-007) | Policy Guild, QA Guild / src/Policy/StellaOps.Policy.Engine |
@@ -29,6 +29,10 @@ Focus: Policy & Reasoning focus on Policy (phase II).
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-27 | POLICY-ENGINE-20-005: Completed determinism guard - `DeterminismViolation.cs` (violation models/options), `ProhibitedPatternAnalyzer.cs` (static analysis with regex patterns for DateTime.Now, Random, Guid.NewGuid, HttpClient, File.Read, etc.), `DeterminismGuardService.cs` (runtime sandbox with EvaluationScope, DeterministicTimeProvider), `GuardedPolicyEvaluator.cs` (integration layer). Status → DONE. | Implementer |
| 2025-11-27 | POLICY-ENGINE-20-004: Completed materialization writer - `EffectiveFindingModels.cs` (document schema), `EffectiveFindingWriter.cs` (upsert + append-only history). Tenant-scoped collections, trace references, content hash deduplication. Status → DONE. | Implementer |
| 2025-11-27 | POLICY-ENGINE-20-003: Completed selection joiners - `SelectionJoinModels.cs` (tuple models), `PurlEquivalence.cs` (equivalence table with package key extraction), `SelectionJoinService.cs` (deterministic batching, multi-index lookup). Status → DONE. | Implementer |
| 2025-11-27 | POLICY-ENGINE-20-002: Completed. Created design doc, sample config, test vectors. Added `EvaluationTimestamp`/`now` for deterministic timestamps. Status → DONE. | Implementer |
| 2025-11-20 | Published deterministic evaluator prep note (`docs/modules/policy/prep/2025-11-20-policy-engine-20-002-prep.md`); set PREP-POLICY-ENGINE-20-002 to DONE. | Implementer |
| 2025-11-19 | Assigned PREP owners/dates; see Delivery Tracker. | Planning |
| 2025-11-25 | Reconciled POLICY-ENGINE-27-004 as DONE (completed 2025-10-19 in Sprint 120); added to Delivery Tracker for traceability. | Project Mgmt |

View File

@@ -10,7 +10,7 @@ Focus: Policy & Reasoning focus on Policy (phase IV).
| # | Task ID & handle | State | Key dependency / next step | Owners |
| --- | --- | --- | --- | --- |
| 1 | POLICY-ENGINE-40-003 | TODO | Provide API/SDK utilities for consumers (Web Scanner, Graph Explorer) to request policy decisions with source evidence summaries (top severity sources, conflict counts) (Deps: POLICY-ENGINE-40-002) | Policy Guild, Web Scanner Guild / src/Policy/StellaOps.Policy.Engine |
| 1 | POLICY-ENGINE-40-003 | DONE | Provide API/SDK utilities for consumers (Web Scanner, Graph Explorer) to request policy decisions with source evidence summaries (top severity sources, conflict counts) (Deps: POLICY-ENGINE-40-002) | Policy Guild, Web Scanner Guild / src/Policy/StellaOps.Policy.Engine |
| 2 | POLICY-ENGINE-50-001 | TODO | Implement SPL compiler: validate YAML, canonicalize, produce signed bundle, store artifact in object storage, write `policy_revisions` with AOC metadata (Deps: POLICY-ENGINE-40-003) | Policy Guild, Platform Security / src/Policy/StellaOps.Policy.Engine |
| 3 | POLICY-ENGINE-50-002 | TODO | Build runtime evaluator executing compiled plans over advisory/vex linksets + SBOM asset metadata with deterministic caching (Redis) and fallback path (Deps: POLICY-ENGINE-50-001) | Policy Guild, Runtime Guild / src/Policy/StellaOps.Policy.Engine |
| 4 | POLICY-ENGINE-50-003 | TODO | Implement evaluation/compilation metrics, tracing, and structured logs (`policy_eval_seconds`, `policy_compiles_total`, explanation sampling) (Deps: POLICY-ENGINE-50-002) | Policy Guild, Observability Guild / src/Policy/StellaOps.Policy.Engine |
@@ -26,3 +26,17 @@ Focus: Policy & Reasoning focus on Policy (phase IV).
| 14 | POLICY-ENGINE-70-005 | TODO | Provide APIs/workers hook for exception activation/expiry (auto start/end) and event emission (`exception.activated/expired`) (Deps: POLICY-ENGINE-70-004) | Policy Guild, Scheduler Worker Guild / src/Policy/StellaOps.Policy.Engine |
| 15 | POLICY-ENGINE-80-001 | TODO | Integrate reachability/exploitability inputs into evaluation pipeline (state/score/confidence) with caching and explain support (Deps: POLICY-ENGINE-70-005) | Policy Guild, Signals Guild / src/Policy/StellaOps.Policy.Engine |
| 16 | POLICY-RISK-90-001 | TODO | Ingest entropy penalty inputs from Scanner (`entropy.report.json`, `layer_summary.json`), extend trust algebra with configurable weights/caps, and expose explanations/metrics for opaque ratio penalties (`docs/modules/scanner/entropy.md`). | Policy Guild, Scanner Guild / src/Policy/StellaOps.Policy.Engine |
## Notes & Risks (2025-11-27)
- POLICY-ENGINE-40-003 implementation complete: Added `PolicyDecisionModels.cs`, `PolicyDecisionService.cs`, `PolicyDecisionEndpoint.cs`, and `PolicyDecisionServiceTests.cs`. Service registered in `Program.cs`. All 9 tests pass.
- Pre-existing build issues resolved:
- `StellaOps.Telemetry.Core`: Fixed TelemetryContext API (added CorrelationId/TraceId aliases, Current/Context property aliases), added Grpc.AspNetCore package, removed duplicate FrameworkReference.
- `StellaOps.Policy.RiskProfile`: Fixed JsonSchema.Net v5 API changes (`ValidationResults``EvaluationResults`), `JsonDocument.Parse` signature.
- `StellaOps.Policy.Engine`: Fixed OpenTelemetry Meter API changes (observeValues parameter, nullable returns), SamplingResult API changes, parameter casing fixes.
- Test project: Added `Microsoft.Extensions.TimeProvider.Testing` package, fixed using directives, fixed parameter casing.
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-27 | Started POLICY-ENGINE-40-003; implemented PolicyDecisionService, PolicyDecisionEndpoint, PolicyDecisionModels, tests. Blocked by pre-existing build issues in Telemetry.Core and RiskProfile projects. | Implementer |
| 2025-11-27 | Fixed pre-existing build issues (TelemetryContext API mismatch, JsonSchema.Net v5 API changes, OpenTelemetry Meter API changes, test project missing packages/namespaces). All 9 PolicyDecisionServiceTests pass. POLICY-ENGINE-40-003 marked DONE. | Implementer |

View File

@@ -1,6 +1,6 @@
# Sprint 127 - Policy & Reasoning
_Last updated: November 8, 2025. Implementation order is DOING → TODO → BLOCKED._
_Last updated: November 27, 2025. Implementation order is DOING → TODO → BLOCKED._
Focus areas below were split out of the previous combined sprint; execute sections in order unless noted.
@@ -10,18 +10,60 @@ Focus: Policy & Reasoning focus on Policy (phase V).
| # | Task ID & handle | State | Key dependency / next step | Owners |
| --- | --- | --- | --- | --- |
| 1 | POLICY-ENGINE-80-002 | TODO | Create joining layer to read `reachability_facts` efficiently (indexes, projections) and populate Redis overlay caches (Deps: POLICY-ENGINE-80-001) | Policy Guild, Storage Guild / src/Policy/StellaOps.Policy.Engine |
| 2 | POLICY-ENGINE-80-003 | TODO | Extend SPL predicates/actions to reference reachability state/score/confidence; update compiler validation (Deps: POLICY-ENGINE-80-002) | Policy Guild, Policy Editor Guild / src/Policy/StellaOps.Policy.Engine |
| 3 | POLICY-ENGINE-80-004 | TODO | Emit metrics (`policy_reachability_applied_total`, `policy_reachability_cache_hit_ratio`) and traces for signals usage (Deps: POLICY-ENGINE-80-003) | Policy Guild, Observability Guild / src/Policy/StellaOps.Policy.Engine |
| 4 | POLICY-OBS-50-001 | TODO | Integrate telemetry core into policy API + worker hosts, ensuring spans/logs cover compile/evaluate flows with `tenant_id`, `policy_version`, `decision_effect`, and trace IDs | Policy Guild, Observability Guild / src/Policy/StellaOps.Policy.Engine |
| 5 | POLICY-OBS-51-001 | TODO | Emit golden-signal metrics (compile latency, evaluate latency, rule hits, override counts) and define SLOs (evaluation P95 <2s). Publish Grafana dashboards + burn-rate alert rules (Deps: POLICY-OBS-50-001) | Policy Guild, DevOps Guild / src/Policy/StellaOps.Policy.Engine |
| 6 | POLICY-OBS-52-001 | TODO | Emit timeline events `policy.evaluate.started`, `policy.evaluate.completed`, `policy.decision.recorded` with trace IDs, input digests, and rule summary. Provide contract tests and retry semantics (Deps: POLICY-OBS-51-001) | Policy Guild / src/Policy/StellaOps.Policy.Engine |
| 7 | POLICY-OBS-53-001 | TODO | Produce evaluation evidence bundles (inputs slice, rule trace, engine version, config snapshot) through evidence locker integration; ensure redaction + deterministic manifests (Deps: POLICY-OBS-52-001) | Policy Guild, Evidence Locker Guild / src/Policy/StellaOps.Policy.Engine |
| 8 | POLICY-OBS-54-001 | TODO | Generate DSSE attestations for evaluation outputs, expose `/evaluations/{id}/attestation`, and link attestation IDs in timeline + console. Provide verification harness (Deps: POLICY-OBS-53-001) | Policy Guild, Provenance Guild / src/Policy/StellaOps.Policy.Engine |
| 9 | POLICY-OBS-55-001 | TODO | Implement incident mode sampling overrides (full rule trace capture, extended retention) with auto-activation on SLO breach and manual override API. Emit activation events to timeline + notifier (Deps: POLICY-OBS-54-001) | Policy Guild, DevOps Guild / src/Policy/StellaOps.Policy.Engine |
| 10 | POLICY-RISK-66-001 | TODO | Develop initial JSON Schema for RiskProfile (signals, transforms, weights, severity, overrides) with validator stubs | Risk Profile Schema Guild / src/Policy/StellaOps.Policy.RiskProfile |
| 11 | POLICY-RISK-66-002 | TODO | Implement inheritance/merge logic with conflict detection and deterministic content hashing (Deps: POLICY-RISK-66-001) | Risk Profile Schema Guild / src/Policy/StellaOps.Policy.RiskProfile |
| 12 | POLICY-RISK-66-003 | TODO | Integrate RiskProfile schema into Policy Engine configuration, ensuring validation and default profile deployment (Deps: POLICY-RISK-66-002) | Policy Guild, Risk Profile Schema Guild / src/Policy/StellaOps.Policy.Engine |
| 13 | POLICY-RISK-66-004 | TODO | Extend Policy libraries to load/save RiskProfile documents, compute content hashes, and surface validation diagnostics (Deps: POLICY-RISK-66-003) | Policy Guild, Risk Profile Schema Guild / src/Policy/__Libraries/StellaOps.Policy |
| 14 | POLICY-RISK-67-001 | TODO | Trigger scoring jobs on new/updated findings via Policy Engine orchestration hooks (Deps: POLICY-RISK-66-004) | Policy Guild, Risk Engine Guild / src/Policy/StellaOps.Policy.Engine |
| 15 | POLICY-RISK-67-001 | TODO | Integrate profile storage and versioning into Policy Store with lifecycle states (draft/publish/deprecate) (Deps: POLICY-RISK-67-001) | Risk Profile Schema Guild, Policy Engine Guild / src/Policy/StellaOps.Policy.RiskProfile |
| 1 | POLICY-ENGINE-80-002 | DONE | Create joining layer to read `reachability_facts` efficiently (indexes, projections) and populate Redis overlay caches (Deps: POLICY-ENGINE-80-001) | Policy Guild, Storage Guild / src/Policy/StellaOps.Policy.Engine |
| 2 | POLICY-ENGINE-80-003 | DONE | Extend SPL predicates/actions to reference reachability state/score/confidence; update compiler validation (Deps: POLICY-ENGINE-80-002) | Policy Guild, Policy Editor Guild / src/Policy/StellaOps.Policy.Engine |
| 3 | POLICY-ENGINE-80-004 | DONE | Emit metrics (`policy_reachability_applied_total`, `policy_reachability_cache_hit_ratio`) and traces for signals usage (Deps: POLICY-ENGINE-80-003) | Policy Guild, Observability Guild / src/Policy/StellaOps.Policy.Engine |
| 4 | POLICY-OBS-50-001 | DONE | Integrate telemetry core into policy API + worker hosts, ensuring spans/logs cover compile/evaluate flows with `tenant_id`, `policy_version`, `decision_effect`, and trace IDs | Policy Guild, Observability Guild / src/Policy/StellaOps.Policy.Engine |
| 5 | POLICY-OBS-51-001 | DONE | Emit golden-signal metrics (compile latency, evaluate latency, rule hits, override counts) and define SLOs (evaluation P95 <2s). Publish Grafana dashboards + burn-rate alert rules (Deps: POLICY-OBS-50-001) | Policy Guild, DevOps Guild / src/Policy/StellaOps.Policy.Engine |
| 6 | POLICY-OBS-52-001 | DONE | Emit timeline events `policy.evaluate.started`, `policy.evaluate.completed`, `policy.decision.recorded` with trace IDs, input digests, and rule summary. Provide contract tests and retry semantics (Deps: POLICY-OBS-51-001) | Policy Guild / src/Policy/StellaOps.Policy.Engine |
| 7 | POLICY-OBS-53-001 | DONE | Produce evaluation evidence bundles (inputs slice, rule trace, engine version, config snapshot) through evidence locker integration; ensure redaction + deterministic manifests (Deps: POLICY-OBS-52-001) | Policy Guild, Evidence Locker Guild / src/Policy/StellaOps.Policy.Engine |
| 8 | POLICY-OBS-54-001 | DONE | Generate DSSE attestations for evaluation outputs, expose `/evaluations/{id}/attestation`, and link attestation IDs in timeline + console. Provide verification harness (Deps: POLICY-OBS-53-001) | Policy Guild, Provenance Guild / src/Policy/StellaOps.Policy.Engine |
| 9 | POLICY-OBS-55-001 | DONE | Implement incident mode sampling overrides (full rule trace capture, extended retention) with auto-activation on SLO breach and manual override API. Emit activation events to timeline + notifier (Deps: POLICY-OBS-54-001) | Policy Guild, DevOps Guild / src/Policy/StellaOps.Policy.Engine |
| 10 | POLICY-RISK-66-001 | DONE | Develop initial JSON Schema for RiskProfile (signals, transforms, weights, severity, overrides) with validator stubs | Risk Profile Schema Guild / src/Policy/StellaOps.Policy.RiskProfile |
| 11 | POLICY-RISK-66-002 | DONE | Implement inheritance/merge logic with conflict detection and deterministic content hashing (Deps: POLICY-RISK-66-001) | Risk Profile Schema Guild / src/Policy/StellaOps.Policy.RiskProfile |
| 12 | POLICY-RISK-66-003 | DONE | Integrate RiskProfile schema into Policy Engine configuration, ensuring validation and default profile deployment (Deps: POLICY-RISK-66-002) | Policy Guild, Risk Profile Schema Guild / src/Policy/StellaOps.Policy.Engine |
| 13 | POLICY-RISK-66-004 | DONE | Extend Policy libraries to load/save RiskProfile documents, compute content hashes, and surface validation diagnostics (Deps: POLICY-RISK-66-003) | Policy Guild, Risk Profile Schema Guild / src/Policy/__Libraries/StellaOps.Policy |
| 14 | POLICY-RISK-67-001a | DONE | Trigger scoring jobs on new/updated findings via Policy Engine orchestration hooks (Deps: POLICY-RISK-66-004) | Policy Guild, Risk Engine Guild / src/Policy/StellaOps.Policy.Engine |
| 15 | POLICY-RISK-67-001b | DONE | Integrate profile storage and versioning into Policy Store with lifecycle states (draft/publish/deprecate) (Deps: POLICY-RISK-67-001a) | Risk Profile Schema Guild, Policy Engine Guild / src/Policy/StellaOps.Policy.RiskProfile |
## Implementation Notes
### Completed Tasks Summary
- **POLICY-OBS-50-001**: Telemetry integration via `TelemetryExtensions.cs` - OpenTelemetry tracing/metrics/logging fully configured
- **POLICY-OBS-51-001**: Golden signals in `PolicyEngineTelemetry.cs` - latency histograms, counters, SLO metrics implemented
- **POLICY-OBS-52-001**: Timeline events in `PolicyTimelineEvents.cs` - full evaluation lifecycle coverage
- **POLICY-OBS-53-001**: Evidence bundles in `EvidenceBundle.cs` - deterministic manifests and artifact tracking
- **POLICY-OBS-54-001**: DSSE attestations in `PolicyEvaluationAttestation.cs` - in-toto statement generation
- **POLICY-OBS-55-001**: Incident mode in `IncidentMode.cs` - 100% sampling override with expiration
- **POLICY-RISK-66-001**: JSON Schema in `risk-profile-schema@1.json` - full schema with signals, weights, overrides
- **POLICY-RISK-66-002**: Merge logic in `RiskProfileMergeService.cs` - inheritance resolution with conflict detection
- **POLICY-RISK-66-003**: Config integration in `RiskProfileConfigurationService.cs` - profile loading and caching
- **POLICY-RISK-66-004**: Hashing in `RiskProfileHasher.cs` - deterministic content hashing
- **POLICY-RISK-67-001a**: Scoring triggers in `RiskScoringTriggerService.cs` - finding change event handling
- **POLICY-RISK-67-001b**: Lifecycle in `RiskProfileLifecycleService.cs` - draft/active/deprecated/archived states
### Reachability Integration (POLICY-ENGINE-80-00X)
- **POLICY-ENGINE-80-002**: Joining layer implemented in `ReachabilityFacts/` directory:
- `ReachabilityFactsModels.cs` - Data models for reachability facts with state, confidence, score
- `ReachabilityFactsStore.cs` - Store interface with InMemory implementation and MongoDB index definitions
- `ReachabilityFactsOverlayCache.cs` - In-memory overlay cache with TTL eviction
- `ReachabilityFactsJoiningService.cs` - Batch lookup service with cache-first strategy
- **POLICY-ENGINE-80-003**: SPL predicates extended in `Evaluation/`:
- `PolicyEvaluationContext.cs` - Added `PolicyEvaluationReachability` record with state/confidence/score
- `PolicyExpressionEvaluator.cs` - Added `ReachabilityScope` for SPL expressions like:
- `reachability.state == "reachable"`
- `reachability.confidence >= 0.8`
- `reachability.is_high_confidence`
- **POLICY-ENGINE-80-004**: Metrics emitted via `PolicyEngineTelemetry.cs`:
- `policy_reachability_applied_total{state}` - Facts applied during evaluation
- `policy_reachability_cache_hits_total` / `policy_reachability_cache_misses_total`
- `policy_reachability_cache_hit_ratio` - Observable gauge
- `policy_reachability_lookups_total{outcome}` / `policy_reachability_lookup_seconds`
### Sprint Status
All 15 tasks in Sprint 127 are now DONE.

View File

@@ -10,18 +10,18 @@ Focus: Policy & Reasoning focus on Policy (phase VI).
| # | Task ID & handle | State | Key dependency / next step | Owners |
| --- | --- | --- | --- | --- |
| 1 | POLICY-RISK-67-002 | TODO | Implement profile lifecycle APIs (`/risk/profiles` create/publish/deprecate) and scope attachment logic (Deps: POLICY-RISK-67-001) | Policy Guild / src/Policy/StellaOps.Policy.Engine |
| 2 | POLICY-RISK-67-002 | TODO | Publish `.well-known/risk-profile-schema` endpoint and CLI validation tooling (Deps: POLICY-RISK-67-002) | Risk Profile Schema Guild / src/Policy/StellaOps.Policy.RiskProfile |
| 3 | POLICY-RISK-67-003 | TODO | Provide policy-layer APIs to trigger risk simulations and return distributions/contribution breakdowns (Deps: POLICY-RISK-67-002) | Policy Guild, Risk Engine Guild / src/Policy/__Libraries/StellaOps.Policy |
| 4 | POLICY-RISK-68-001 | TODO | Provide simulation API bridging Policy Studio with risk engine; returns distributions and top movers (Deps: POLICY-RISK-67-003) | Policy Guild, Policy Studio Guild / src/Policy/StellaOps.Policy.Engine |
| 5 | POLICY-RISK-68-001 | TODO | Implement scope selectors, precedence rules, and Authority attachment APIs (Deps: POLICY-RISK-68-001) | Risk Profile Schema Guild, Authority Guild / src/Policy/StellaOps.Policy.RiskProfile |
| 6 | POLICY-RISK-68-002 | TODO | Add override/adjustment support with audit metadata and validation for conflicting rules (Deps: POLICY-RISK-68-001) | Risk Profile Schema Guild / src/Policy/StellaOps.Policy.RiskProfile |
| 7 | POLICY-RISK-68-002 | TODO | Enable exporting/importing RiskProfiles with signatures via policy tooling (CLI + API) (Deps: POLICY-RISK-68-002) | Policy Guild, Export Guild / src/Policy/__Libraries/StellaOps.Policy |
| 8 | POLICY-RISK-69-001 | TODO | Emit events/notifications on profile publish, deprecate, and severity threshold changes (Deps: POLICY-RISK-68-002) | Policy Guild, Notifications Guild / src/Policy/StellaOps.Policy.Engine |
| 9 | POLICY-RISK-70-001 | TODO | Support exporting/importing profiles with signatures for air-gapped bundles (Deps: POLICY-RISK-69-001) | Policy Guild, Export Guild / src/Policy/StellaOps.Policy.Engine |
| 10 | POLICY-SPL-23-001 | TODO | Define SPL v1 YAML + JSON Schema, including advisory rules, VEX precedence, severity mapping, exceptions, and layering metadata. Publish schema resources and validation fixtures | Policy Guild, Language Infrastructure Guild / src/Policy/__Libraries/StellaOps.Policy |
| 11 | POLICY-SPL-23-002 | TODO | Implement canonicalizer that normalizes policy packs (ordering, defaults), computes content hash, and prepares bundle metadata for AOC/signing (Deps: POLICY-SPL-23-001) | Policy Guild / src/Policy/__Libraries/StellaOps.Policy |
| 12 | POLICY-SPL-23-003 | TODO | Build policy layering/override engine (global/org/project/env/exception) with field-level precedence matrices; add unit/property tests (Deps: POLICY-SPL-23-002) | Policy Guild / src/Policy/__Libraries/StellaOps.Policy |
| 13 | POLICY-SPL-23-004 | TODO | Design explanation tree model (rule hits, inputs, decisions) and persistence structures reused by runtime, UI, and CLI (Deps: POLICY-SPL-23-003) | Policy Guild, Audit Guild / src/Policy/__Libraries/StellaOps.Policy |
| 14 | POLICY-SPL-23-005 | TODO | Create migration tool to snapshot existing behavior into baseline SPL packs (`org.core.baseline`), including policy docs and sample bundles (Deps: POLICY-SPL-23-004) | Policy Guild, DevEx Guild / src/Policy/__Libraries/StellaOps.Policy |
| 15 | POLICY-SPL-24-001 | TODO | Extend SPL schema to expose reachability/exploitability predicates and weighting functions; update documentation and fixtures (Deps: POLICY-SPL-23-005) | Policy Guild, Signals Guild / src/Policy/__Libraries/StellaOps.Policy |
| 1 | POLICY-RISK-67-002 | DONE | Implement profile lifecycle APIs (`/risk/profiles` create/publish/deprecate) and scope attachment logic (Deps: POLICY-RISK-67-001) | Policy Guild / src/Policy/StellaOps.Policy.Engine |
| 2 | POLICY-RISK-67-002 | DONE | Publish `.well-known/risk-profile-schema` endpoint and CLI validation tooling (Deps: POLICY-RISK-67-002) | Risk Profile Schema Guild / src/Policy/StellaOps.Policy.RiskProfile |
| 3 | POLICY-RISK-67-003 | DONE | Provide policy-layer APIs to trigger risk simulations and return distributions/contribution breakdowns (Deps: POLICY-RISK-67-002) | Policy Guild, Risk Engine Guild / src/Policy/__Libraries/StellaOps.Policy |
| 4 | POLICY-RISK-68-001 | DONE | Provide simulation API bridging Policy Studio with risk engine; returns distributions and top movers (Deps: POLICY-RISK-67-003) | Policy Guild, Policy Studio Guild / src/Policy/StellaOps.Policy.Engine |
| 5 | POLICY-RISK-68-001 | DONE | Implement scope selectors, precedence rules, and Authority attachment APIs (Deps: POLICY-RISK-68-001) | Risk Profile Schema Guild, Authority Guild / src/Policy/StellaOps.Policy.RiskProfile |
| 6 | POLICY-RISK-68-002 | DONE | Add override/adjustment support with audit metadata and validation for conflicting rules (Deps: POLICY-RISK-68-001) | Risk Profile Schema Guild / src/Policy/StellaOps.Policy.RiskProfile |
| 7 | POLICY-RISK-68-002 | DONE | Enable exporting/importing RiskProfiles with signatures via policy tooling (CLI + API) (Deps: POLICY-RISK-68-002) | Policy Guild, Export Guild / src/Policy/__Libraries/StellaOps.Policy |
| 8 | POLICY-RISK-69-001 | DONE | Emit events/notifications on profile publish, deprecate, and severity threshold changes (Deps: POLICY-RISK-68-002) | Policy Guild, Notifications Guild / src/Policy/StellaOps.Policy.Engine |
| 9 | POLICY-RISK-70-001 | DONE | Support exporting/importing profiles with signatures for air-gapped bundles (Deps: POLICY-RISK-69-001) | Policy Guild, Export Guild / src/Policy/StellaOps.Policy.Engine |
| 10 | POLICY-SPL-23-001 | DONE | Define SPL v1 YAML + JSON Schema, including advisory rules, VEX precedence, severity mapping, exceptions, and layering metadata. Publish schema resources and validation fixtures | Policy Guild, Language Infrastructure Guild / src/Policy/__Libraries/StellaOps.Policy |
| 11 | POLICY-SPL-23-002 | DONE | Implement canonicalizer that normalizes policy packs (ordering, defaults), computes content hash, and prepares bundle metadata for AOC/signing (Deps: POLICY-SPL-23-001) | Policy Guild / src/Policy/__Libraries/StellaOps.Policy |
| 12 | POLICY-SPL-23-003 | DONE | Build policy layering/override engine (global/org/project/env/exception) with field-level precedence matrices; add unit/property tests (Deps: POLICY-SPL-23-002) | Policy Guild / src/Policy/__Libraries/StellaOps.Policy |
| 13 | POLICY-SPL-23-004 | DONE | Design explanation tree model (rule hits, inputs, decisions) and persistence structures reused by runtime, UI, and CLI (Deps: POLICY-SPL-23-003) | Policy Guild, Audit Guild / src/Policy/__Libraries/StellaOps.Policy |
| 14 | POLICY-SPL-23-005 | DONE | Create migration tool to snapshot existing behavior into baseline SPL packs (`org.core.baseline`), including policy docs and sample bundles (Deps: POLICY-SPL-23-004) | Policy Guild, DevEx Guild / src/Policy/__Libraries/StellaOps.Policy |
| 15 | POLICY-SPL-24-001 | DONE | Extend SPL schema to expose reachability/exploitability predicates and weighting functions; update documentation and fixtures (Deps: POLICY-SPL-23-005) | Policy Guild, Signals Guild / src/Policy/__Libraries/StellaOps.Policy |

View File

@@ -7,22 +7,57 @@ Dependency: Sprint 131 - 2. Scanner.II — Scanner & Surface focus on Scanner (p
| Task ID | State | Summary | Owner / Source | Depends On |
| --- | --- | --- | --- | --- |
| `SCANNER-ANALYZERS-LANG-11-002` | TODO | Implement static analyzer (IL + reflection heuristics) capturing AssemblyRef, ModuleRef/PInvoke, DynamicDependency, reflection literals, DI patterns, and custom AssemblyLoadContext probing hints. Emit dependency edges with reason codes and confidence. | StellaOps.Scanner EPDR Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.DotNet) | SCANNER-ANALYZERS-LANG-11-001 |
| `SCANNER-ANALYZERS-LANG-11-003` | TODO | Ingest optional runtime evidence (AssemblyLoad, Resolving, P/Invoke) via event listener harness; merge runtime edges with static/declared ones and attach reason codes/confidence. | StellaOps.Scanner EPDR Guild, Signals Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.DotNet) | SCANNER-ANALYZERS-LANG-11-002 |
| `SCANNER-ANALYZERS-LANG-11-004` | TODO | Produce normalized observation export to Scanner writer: entrypoints + dependency edges + environment profiles (AOC compliant). Wire to SBOM service entrypoint tagging. | StellaOps.Scanner EPDR Guild, SBOM Service Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.DotNet) | SCANNER-ANALYZERS-LANG-11-003 |
| `SCANNER-ANALYZERS-LANG-11-005` | TODO | Add comprehensive fixtures/benchmarks covering framework-dependent, self-contained, single-file, trimmed, NativeAOT, multi-RID scenarios; include explain traces and perf benchmarks vs previous analyzer. | StellaOps.Scanner EPDR Guild, QA Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.DotNet) | SCANNER-ANALYZERS-LANG-11-004 |
| `SCANNER-ANALYZERS-NATIVE-20-001` | TODO | Implement format detector and binary identity model supporting ELF, PE/COFF, and Mach-O (including fat slices). Capture arch, OS, build-id/UUID, interpreter metadata. | Native Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | — |
| `SCANNER-ANALYZERS-NATIVE-20-002` | TODO | Parse ELF dynamic sections: `DT_NEEDED`, `DT_RPATH`, `DT_RUNPATH`, symbol versions, interpreter, and note build-id. Emit declared dependency records with reason `elf-dtneeded` and attach version needs. | Native Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | SCANNER-ANALYZERS-NATIVE-20-001 |
| `SCANNER-ANALYZERS-NATIVE-20-003` | TODO | Parse PE imports, delay-load tables, manifests/SxS metadata, and subsystem flags. Emit edges with reasons `pe-import` and `pe-delayimport`, plus SxS policy metadata. | Native Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | SCANNER-ANALYZERS-NATIVE-20-002 |
| `SCANNER-ANALYZERS-NATIVE-20-004` | TODO | Parse Mach-O load commands (`LC_LOAD_DYLIB`, `LC_REEXPORT_DYLIB`, `LC_RPATH`, `LC_UUID`, fat headers). Handle `@rpath/@loader_path` placeholders and slice separation. | Native Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | SCANNER-ANALYZERS-NATIVE-20-003 |
| `SCANNER-ANALYZERS-NATIVE-20-005` | TODO | Implement resolver engine modeling loader search order for ELF (rpath/runpath/cache/default), PE (SafeDll search + SxS), and Mach-O (`@rpath` expansion). Works against virtual image roots, producing explain traces. | Native Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | SCANNER-ANALYZERS-NATIVE-20-004 |
| `SCANNER-ANALYZERS-NATIVE-20-006` | TODO | Build heuristic scanner for `dlopen`/`LoadLibrary` strings, plugin ecosystem configs, and Go/Rust static hints. Emit edges with `reason_code` (`string-dlopen`, `config-plugin`, `ecosystem-heuristic`) and confidence levels. | Native Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | SCANNER-ANALYZERS-NATIVE-20-005 |
| `SCANNER-ANALYZERS-NATIVE-20-007` | TODO | Serialize AOC-compliant observations: entrypoints + dependency edges + environment profiles (search paths, interpreter, loader metadata). Integrate with Scanner writer API. | Native Analyzer Guild, SBOM Service Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | SCANNER-ANALYZERS-NATIVE-20-006 |
| `SCANNER-ANALYZERS-NATIVE-20-008` | TODO | Author cross-platform fixtures (ELF dynamic/static, PE delay-load/SxS, Mach-O @rpath, plugin configs) and determinism benchmarks (<25 ms / binary, <250 MB). | Native Analyzer Guild, QA Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | SCANNER-ANALYZERS-NATIVE-20-007 |
| `SCANNER-ANALYZERS-NATIVE-20-009` | TODO | Provide optional runtime capture adapters (Linux eBPF `dlopen`, Windows ETW ImageLoad, macOS dyld interpose) writing append-only runtime evidence. Include redaction/sandbox guidance. | Native Analyzer Guild, Signals Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | SCANNER-ANALYZERS-NATIVE-20-008 |
| `SCANNER-ANALYZERS-NATIVE-20-010` | TODO | Package native analyzer as restart-time plug-in with manifest/DI registration; update Offline Kit bundle + documentation. | Native Analyzer Guild, DevOps Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | SCANNER-ANALYZERS-NATIVE-20-009 |
| `SCANNER-ANALYZERS-LANG-11-002` | BLOCKED | Implement static analyzer (IL + reflection heuristics) capturing AssemblyRef, ModuleRef/PInvoke, DynamicDependency, reflection literals, DI patterns, and custom AssemblyLoadContext probing hints. Emit dependency edges with reason codes and confidence. | StellaOps.Scanner EPDR Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.DotNet) | SCANNER-ANALYZERS-LANG-11-001 |
| `SCANNER-ANALYZERS-LANG-11-003` | BLOCKED | Ingest optional runtime evidence (AssemblyLoad, Resolving, P/Invoke) via event listener harness; merge runtime edges with static/declared ones and attach reason codes/confidence. | StellaOps.Scanner EPDR Guild, Signals Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.DotNet) | SCANNER-ANALYZERS-LANG-11-002 |
| `SCANNER-ANALYZERS-LANG-11-004` | BLOCKED | Produce normalized observation export to Scanner writer: entrypoints + dependency edges + environment profiles (AOC compliant). Wire to SBOM service entrypoint tagging. | StellaOps.Scanner EPDR Guild, SBOM Service Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.DotNet) | SCANNER-ANALYZERS-LANG-11-003 |
| `SCANNER-ANALYZERS-LANG-11-005` | BLOCKED | Add comprehensive fixtures/benchmarks covering framework-dependent, self-contained, single-file, trimmed, NativeAOT, multi-RID scenarios; include explain traces and perf benchmarks vs previous analyzer. | StellaOps.Scanner EPDR Guild, QA Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.DotNet) | SCANNER-ANALYZERS-LANG-11-004 |
| `SCANNER-ANALYZERS-NATIVE-20-001` | DONE | Implement format detector and binary identity model supporting ELF, PE/COFF, and Mach-O (including fat slices). Capture arch, OS, build-id/UUID, interpreter metadata. | Native Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | — |
| `SCANNER-ANALYZERS-NATIVE-20-002` | DONE | Parse ELF dynamic sections: `DT_NEEDED`, `DT_RPATH`, `DT_RUNPATH`, symbol versions, interpreter, and note build-id. Emit declared dependency records with reason `elf-dtneeded` and attach version needs. | Native Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | SCANNER-ANALYZERS-NATIVE-20-001 |
| `SCANNER-ANALYZERS-NATIVE-20-003` | DONE | Parse PE imports, delay-load tables, manifests/SxS metadata, and subsystem flags. Emit edges with reasons `pe-import` and `pe-delayimport`, plus SxS policy metadata. | Native Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | SCANNER-ANALYZERS-NATIVE-20-002 |
| `SCANNER-ANALYZERS-NATIVE-20-004` | DONE | Parse Mach-O load commands (`LC_LOAD_DYLIB`, `LC_REEXPORT_DYLIB`, `LC_RPATH`, `LC_UUID`, fat headers). Handle `@rpath/@loader_path` placeholders and slice separation. | Native Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | SCANNER-ANALYZERS-NATIVE-20-003 |
| `SCANNER-ANALYZERS-NATIVE-20-005` | DONE | Implement resolver engine modeling loader search order for ELF (rpath/runpath/cache/default), PE (SafeDll search + SxS), and Mach-O (`@rpath` expansion). Works against virtual image roots, producing explain traces. | Native Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | SCANNER-ANALYZERS-NATIVE-20-004 |
| `SCANNER-ANALYZERS-NATIVE-20-006` | DONE | Build heuristic scanner for `dlopen`/`LoadLibrary` strings, plugin ecosystem configs, and Go/Rust static hints. Emit edges with `reason_code` (`string-dlopen`, `config-plugin`, `ecosystem-heuristic`) and confidence levels. | Native Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | SCANNER-ANALYZERS-NATIVE-20-005 |
| `SCANNER-ANALYZERS-NATIVE-20-007` | DONE | Serialize AOC-compliant observations: entrypoints + dependency edges + environment profiles (search paths, interpreter, loader metadata). Integrate with Scanner writer API. | Native Analyzer Guild, SBOM Service Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | SCANNER-ANALYZERS-NATIVE-20-006 |
| `SCANNER-ANALYZERS-NATIVE-20-008` | DONE | Author cross-platform fixtures (ELF dynamic/static, PE delay-load/SxS, Mach-O @rpath, plugin configs) and determinism benchmarks (<25 ms / binary, <250 MB). | Native Analyzer Guild, QA Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | SCANNER-ANALYZERS-NATIVE-20-007 |
| `SCANNER-ANALYZERS-NATIVE-20-009` | DONE | Provide optional runtime capture adapters (Linux eBPF `dlopen`, Windows ETW ImageLoad, macOS dyld interpose) writing append-only runtime evidence. Include redaction/sandbox guidance. | Native Analyzer Guild, Signals Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | SCANNER-ANALYZERS-NATIVE-20-008 |
| `SCANNER-ANALYZERS-NATIVE-20-010` | DONE | Package native analyzer as restart-time plug-in with manifest/DI registration; update Offline Kit bundle + documentation. | Native Analyzer Guild, DevOps Guild (src/Scanner/StellaOps.Scanner.Analyzers.Native) | SCANNER-ANALYZERS-NATIVE-20-009 |
| `SCANNER-ANALYZERS-NODE-22-001` | TODO | Build input normalizer + VFS for Node projects: dirs, tgz, container layers, pnpm store, Yarn PnP zips; detect Node version targets (`.nvmrc`, `.node-version`, Dockerfile) and workspace roots deterministically. | Node Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node) | |
| `SCANNER-ANALYZERS-NODE-22-002` | TODO | Implement entrypoint discovery (bin/main/module/exports/imports, workers, electron, shebang scripts) and condition set builder per entrypoint. | Node Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node) | SCANNER-ANALYZERS-NODE-22-001 |
| `SCANNER-ANALYZERS-NODE-22-003` | TODO | Parse JS/TS sources for static `import`, `require`, `import()` and string concat cases; flag dynamic patterns with confidence levels; support source map de-bundling. | Node Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node) | SCANNER-ANALYZERS-NODE-22-002 |
| `SCANNER-ANALYZERS-NODE-22-004` | TODO | Implement Node resolver engine for CJS + ESM (core modules, exports/imports maps, conditions, extension priorities, self-references) parameterised by node_version. | Node Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node) | SCANNER-ANALYZERS-NODE-22-003 |
| `SCANNER-ANALYZERS-NODE-22-005` | TODO | Add package manager adapters: Yarn PnP (.pnp.data/.pnp.cjs), pnpm virtual store, npm/Yarn classic hoists; operate entirely in virtual FS. | Node Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node) | SCANNER-ANALYZERS-NODE-22-004 |
## Status Notes (2025-11-27)
### Native Analyzer (NATIVE-20-xxx): DONE
All 10 tasks completed. Implementation verified with 165 passing tests.
**Implemented components:**
- `NativeFormatDetector.cs` - Format detection for ELF/PE/Mach-O with binary identity
- `ElfDynamicSectionParser.cs` - ELF dynamic sections, DT_NEEDED, rpath/runpath
- `PeImportParser.cs` - PE imports, delay-load, manifests, subsystem flags
- `MachOLoadCommandParser.cs` - Mach-O load commands, @rpath, fat binaries
- `NativeResolver.cs` - Cross-platform loader search order modeling
- `HeuristicScanner.cs` - dlopen/LoadLibrary string detection, plugin configs
- `Observations/` - AOC-compliant observation builder and serializer
- `RuntimeCapture/` - Linux eBPF, Windows ETW, macOS dyld adapters
- `Plugin/` - Plugin packaging with DI registration
### DotNet Analyzer (LANG-11-xxx): BLOCKED
Tasks 11-002 through 11-005 are blocked pending SCANNER-ANALYZERS-LANG-11-001 from Sprint 131.
**Blocker:** SCANNER-ANALYZERS-LANG-11-001 (not in this sprint) must implement the foundation for IL analysis before static analyzer heuristics can be built.
### Node Analyzer (NODE-22-xxx): TODO
Tasks 22-001 through 22-005 remain TODO. Existing infrastructure provides partial coverage:
- `NodePackageCollector` - handles dirs, tgz, Yarn PnP cache
- `NodeVersionDetector` - detects .nvmrc, .node-version, Dockerfile
- `NodeWorkspaceIndex` - workspace root detection
- `NodeImportWalker` - basic import/require parsing
**Missing components for Sprint 132:**
- Full VFS abstraction for container layers and pnpm store (22-001)
- Exports/imports map handling and condition set builder (22-002)
- Dynamic pattern confidence levels and source map support (22-003)
- Complete Node resolver engine for CJS+ESM (22-004)
- pnpm virtual store adapter (22-005)

View File

@@ -14,10 +14,10 @@ Dependency: Sprint 132 - 3. Scanner.III — Scanner & Surface focus on Scanner (
| `SCANNER-ANALYZERS-NODE-22-010` | TODO | Implement optional runtime evidence hooks (ESM loader, CJS require hook) with path scrubbing and loader ID hashing; emit runtime-* edges. | Node Analyzer Guild, Signals Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node) | SCANNER-ANALYZERS-NODE-22-009 |
| `SCANNER-ANALYZERS-NODE-22-011` | TODO | Package updated analyzer as restart-time plug-in, expose Scanner CLI (`stella node *`) commands, refresh Offline Kit documentation. | Node Analyzer Guild, DevOps Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node) | SCANNER-ANALYZERS-NODE-22-010 |
| `SCANNER-ANALYZERS-NODE-22-012` | TODO | Integrate container filesystem adapter (OCI layers, Dockerfile hints) and record NODE_OPTIONS/env warnings. | Node Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node) | SCANNER-ANALYZERS-NODE-22-011 |
| `SCANNER-ANALYZERS-PHP-27-001` | TODO | Build input normalizer & VFS for PHP projects: merge source trees, composer manifests, vendor/, php.ini/conf.d, `.htaccess`, FPM configs, container layers. Detect framework/CMS fingerprints deterministically. | PHP Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php) | — |
| `SCANNER-ANALYZERS-PHP-27-002` | TODO | Composer/Autoload analyzer: parse composer.json/lock/installed.json, generate package nodes, autoload edges (psr-4/0/classmap/files), bin entrypoints, composer plugins. | PHP Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php) | SCANNER-ANALYZERS-PHP-27-001 |
| `SCANNER-ANALYZERS-PHP-27-003` | TODO | Include/require graph builder: resolve static includes, capture dynamic include patterns, bootstrap chains, merge with autoload edges. | PHP Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php) | SCANNER-ANALYZERS-PHP-27-002 |
| `SCANNER-ANALYZERS-PHP-27-004` | TODO | Runtime capability scanner: detect exec/fs/net/env/serialization/crypto/database usage, stream wrappers, uploads; record evidence snippets. | PHP Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php) | SCANNER-ANALYZERS-PHP-27-003 |
| `SCANNER-ANALYZERS-PHP-27-005` | TODO | PHAR/Archive inspector: parse phar manifests/stubs, hash files, detect embedded vendor trees and phar:// usage. | PHP Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php) | SCANNER-ANALYZERS-PHP-27-004 |
| `SCANNER-ANALYZERS-PHP-27-006` | TODO | Framework/CMS surface mapper: extract routes, controllers, middleware, CLI/cron entrypoints for Laravel/Symfony/Slim/WordPress/Drupal/Magento. | PHP Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php) | SCANNER-ANALYZERS-PHP-27-005 |
| `SCANNER-ANALYZERS-PHP-27-007` | TODO | Container & extension detector: parse php.ini/conf.d, map extensions to .so/.dll, collect web server/FPM settings, upload limits, disable_functions. | PHP Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php) | SCANNER-ANALYZERS-PHP-27-006 |
| `SCANNER-ANALYZERS-PHP-27-001` | DONE | Build input normalizer & VFS for PHP projects: merge source trees, composer manifests, vendor/, php.ini/conf.d, `.htaccess`, FPM configs, container layers. Detect framework/CMS fingerprints deterministically. | PHP Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php) | — |
| `SCANNER-ANALYZERS-PHP-27-002` | DONE | Composer/Autoload analyzer: parse composer.json/lock/installed.json, generate package nodes, autoload edges (psr-4/0/classmap/files), bin entrypoints, composer plugins. | PHP Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php) | SCANNER-ANALYZERS-PHP-27-001 |
| `SCANNER-ANALYZERS-PHP-27-003` | DONE | Include/require graph builder: resolve static includes, capture dynamic include patterns, bootstrap chains, merge with autoload edges. | PHP Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php) | SCANNER-ANALYZERS-PHP-27-002 |
| `SCANNER-ANALYZERS-PHP-27-004` | DONE | Runtime capability scanner: detect exec/fs/net/env/serialization/crypto/database usage, stream wrappers, uploads; record evidence snippets. | PHP Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php) | SCANNER-ANALYZERS-PHP-27-003 |
| `SCANNER-ANALYZERS-PHP-27-005` | DONE | PHAR/Archive inspector: parse phar manifests/stubs, hash files, detect embedded vendor trees and phar:// usage. | PHP Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php) | SCANNER-ANALYZERS-PHP-27-004 |
| `SCANNER-ANALYZERS-PHP-27-006` | DONE | Framework/CMS surface mapper: extract routes, controllers, middleware, CLI/cron entrypoints for Laravel/Symfony/Slim/WordPress/Drupal/Magento. | PHP Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php) | SCANNER-ANALYZERS-PHP-27-005 |
| `SCANNER-ANALYZERS-PHP-27-007` | DONE | Container & extension detector: parse php.ini/conf.d, map extensions to .so/.dll, collect web server/FPM settings, upload limits, disable_functions. | PHP Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php) | SCANNER-ANALYZERS-PHP-27-006 |

View File

@@ -7,14 +7,14 @@ Dependency: Sprint 133 - 4. Scanner.IV — Scanner & Surface focus on Scanner (p
| Task ID | State | Summary | Owner / Source | Depends On |
| --- | --- | --- | --- | --- |
| `SCANNER-ANALYZERS-PHP-27-009` | TODO | Fixture suite + performance benchmarks (Laravel, Symfony, WordPress, legacy, PHAR, container) with golden outputs. | PHP Analyzer Guild, QA Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php) | SCANNER-ANALYZERS-PHP-27-007 |
| `SCANNER-ANALYZERS-PHP-27-010` | TODO | Optional runtime evidence hooks (if provided) to ingest audit logs or opcode cache stats with path hashing. | PHP Analyzer Guild, Signals Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php) | SCANNER-ANALYZERS-PHP-27-009 |
| `SCANNER-ANALYZERS-PHP-27-011` | TODO | Package analyzer plug-in, add CLI (`stella php inspect`), refresh Offline Kit documentation. | PHP Analyzer Guild, DevOps Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php) | SCANNER-ANALYZERS-PHP-27-010 |
| `SCANNER-ANALYZERS-PHP-27-012` | TODO | Policy signal emitter: extension requirements/presence, dangerous constructs counters, stream wrapper usage, capability summaries. | PHP Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php) | SCANNER-ANALYZERS-PHP-27-011 |
| `SCANNER-ANALYZERS-PHP-27-008` | TODO | Produce AOC-compliant observations: entrypoints, packages, extensions, modules, edges (require/autoload), capabilities, routes, configs. | PHP Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php) | SCANNER-ANALYZERS-PHP-27-002 |
| `SCANNER-ANALYZERS-PYTHON-23-001` | TODO | Build input normalizer & virtual filesystem for wheels, sdists, editable installs, zipapps, site-packages trees, and container roots. Detect Python version targets (`pyproject.toml`, `runtime.txt`, Dockerfile) + virtualenv layout deterministically. | Python Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Python) | — |
| `SCANNER-ANALYZERS-PYTHON-23-002` | TODO | Entrypoint discovery: module `__main__`, console_scripts entry points, `scripts`, zipapp main, `manage.py`/gunicorn/celery patterns. Capture invocation context (module vs package, argv wrappers). | Python Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Python) | SCANNER-ANALYZERS-PYTHON-23-001 |
| `SCANNER-ANALYZERS-PYTHON-23-003` | TODO | Static import graph builder using AST and bytecode fallback. Support `import`, `from ... import`, relative imports, `importlib.import_module`, `__import__` with literal args, `pkgutil.extend_path`. | Python Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Python) | SCANNER-ANALYZERS-PYTHON-23-002 |
| `SCANNER-ANALYZERS-PHP-27-009` | BLOCKED | Fixture suite + performance benchmarks (Laravel, Symfony, WordPress, legacy, PHAR, container) with golden outputs. | PHP Analyzer Guild, QA Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php) | SCANNER-ANALYZERS-PHP-27-007 |
| `SCANNER-ANALYZERS-PHP-27-010` | BLOCKED | Optional runtime evidence hooks (if provided) to ingest audit logs or opcode cache stats with path hashing. | PHP Analyzer Guild, Signals Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php) | SCANNER-ANALYZERS-PHP-27-009 |
| `SCANNER-ANALYZERS-PHP-27-011` | BLOCKED | Package analyzer plug-in, add CLI (`stella php inspect`), refresh Offline Kit documentation. | PHP Analyzer Guild, DevOps Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php) | SCANNER-ANALYZERS-PHP-27-010 |
| `SCANNER-ANALYZERS-PHP-27-012` | BLOCKED | Policy signal emitter: extension requirements/presence, dangerous constructs counters, stream wrapper usage, capability summaries. | PHP Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php) | SCANNER-ANALYZERS-PHP-27-011 |
| `SCANNER-ANALYZERS-PHP-27-008` | BLOCKED | Produce AOC-compliant observations: entrypoints, packages, extensions, modules, edges (require/autoload), capabilities, routes, configs. | PHP Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Php) | SCANNER-ANALYZERS-PHP-27-002 |
| `SCANNER-ANALYZERS-PYTHON-23-001` | DONE | Build input normalizer & virtual filesystem for wheels, sdists, editable installs, zipapps, site-packages trees, and container roots. Detect Python version targets (`pyproject.toml`, `runtime.txt`, Dockerfile) + virtualenv layout deterministically. | Python Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Python) | — |
| `SCANNER-ANALYZERS-PYTHON-23-002` | DONE | Entrypoint discovery: module `__main__`, console_scripts entry points, `scripts`, zipapp main, `manage.py`/gunicorn/celery patterns. Capture invocation context (module vs package, argv wrappers). | Python Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Python) | SCANNER-ANALYZERS-PYTHON-23-001 |
| `SCANNER-ANALYZERS-PYTHON-23-003` | DONE | Static import graph builder using AST and bytecode fallback. Support `import`, `from ... import`, relative imports, `importlib.import_module`, `__import__` with literal args, `pkgutil.extend_path`. | Python Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Python) | SCANNER-ANALYZERS-PYTHON-23-002 |
| `SCANNER-ANALYZERS-PYTHON-23-004` | TODO | Python resolver engine (importlib semantics) handling namespace packages (PEP 420), package discovery order, `.pth` files, `sys.path` composition, zipimport, and site-packages precedence across virtualenv/container roots. | Python Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Python) | SCANNER-ANALYZERS-PYTHON-23-003 |
| `SCANNER-ANALYZERS-PYTHON-23-005` | TODO | Packaging adapters: pip editable (`.egg-link`), Poetry/Flit layout, Conda prefix, `.dist-info/RECORD` cross-check, container layer overlays. | Python Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Python) | SCANNER-ANALYZERS-PYTHON-23-004 |
| `SCANNER-ANALYZERS-PYTHON-23-006` | TODO | Detect native extensions (`*.so`, `*.pyd`), CFFI modules, ctypes loaders, embedded WASM, and runtime capability signals (subprocess, multiprocessing, ctypes, eval). | Python Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Python) | SCANNER-ANALYZERS-PYTHON-23-005 |

View File

@@ -8,17 +8,17 @@ Dependency: Sprint 134 - 5. Scanner.V — Scanner & Surface focus on Scanner (ph
| Task ID | State | Summary | Owner / Source | Depends On |
| --- | --- | --- | --- | --- |
| `SCANNER-ANALYZERS-PYTHON-23-012` | TODO | Container/zipapp adapter enhancements: parse OCI layers for Python runtime, detect `PYTHONPATH`/`PYTHONHOME` env, record warnings for sitecustomize/startup hooks. | Python Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Python) | SCANNER-ANALYZERS-PYTHON-23-011 |
| `SCANNER-ANALYZERS-RUBY-28-001` | TODO | Build input normalizer & VFS for Ruby projects: merge source trees, Gemfile/Gemfile.lock, vendor/bundle, .gem archives, `.bundle/config`, Rack configs, containers. Detect framework/job fingerprints deterministically. | Ruby Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby) | — |
| `SCANNER-ANALYZERS-RUBY-28-002` | TODO | Gem & Bundler analyzer: parse Gemfile/Gemfile.lock, vendor specs, .gem archives, produce package nodes (PURLs), dependency edges, bin scripts, Bundler group metadata. | Ruby Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby) | SCANNER-ANALYZERS-RUBY-28-001 |
| `SCANNER-ANALYZERS-RUBY-28-003` | TODO | Require/autoload graph builder: resolve static/dynamic require, require_relative, load; infer Zeitwerk autoload paths and Rack boot chain. | Ruby Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby) | SCANNER-ANALYZERS-RUBY-28-002 |
| `SCANNER-ANALYZERS-RUBY-28-004` | TODO | Framework surface mapper: extract routes/controllers/middleware for Rails/Rack/Sinatra/Grape/Hanami; inventory jobs/schedulers (Sidekiq, Resque, ActiveJob, whenever, clockwork). | Ruby Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby) | SCANNER-ANALYZERS-RUBY-28-003 |
| `SCANNER-ANALYZERS-RUBY-28-005` | TODO | Capability analyzer: detect os-exec, filesystem, network, serialization, crypto, DB usage, TLS posture, dynamic eval; record evidence snippets with file/line. | Ruby Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby) | SCANNER-ANALYZERS-RUBY-28-004 |
| `SCANNER-ANALYZERS-RUBY-28-006` | TODO | Rake task & scheduler analyzer: parse Rakefiles/lib/tasks, capture task names/prereqs/shell commands; parse Sidekiq/whenever/clockwork configs into schedules. | Ruby Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby) | SCANNER-ANALYZERS-RUBY-28-005 |
| `SCANNER-ANALYZERS-RUBY-28-007` | TODO | Container/runtime scanner: detect Ruby version, installed gems, native extensions, web server configs in OCI layers. | Ruby Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby) | SCANNER-ANALYZERS-RUBY-28-006 |
| `SCANNER-ANALYZERS-RUBY-28-008` | TODO | Produce AOC-compliant observations: entrypoints, packages, modules, edges (require/autoload), routes, jobs, tasks, capabilities, configs, warnings. | Ruby Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby) | SCANNER-ANALYZERS-RUBY-28-007 |
| `SCANNER-ANALYZERS-RUBY-28-009` | TODO | Fixture suite + performance benchmarks (Rails, Rack, Sinatra, Sidekiq, legacy, .gem, container) with golden outputs. | Ruby Analyzer Guild, QA Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby) | SCANNER-ANALYZERS-RUBY-28-008 |
| `SCANNER-ANALYZERS-RUBY-28-010` | TODO | Optional runtime evidence integration (if provided logs/metrics) with path hashing, without altering static precedence. | Ruby Analyzer Guild, Signals Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby) | SCANNER-ANALYZERS-RUBY-28-009 |
| `SCANNER-ANALYZERS-RUBY-28-011` | TODO | Package analyzer plug-in, add CLI (`stella ruby inspect`), refresh Offline Kit documentation. | Ruby Analyzer Guild, DevOps Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby) | SCANNER-ANALYZERS-RUBY-28-010 |
| `SCANNER-ANALYZERS-RUBY-28-001` | DONE | Build input normalizer & VFS for Ruby projects: merge source trees, Gemfile/Gemfile.lock, vendor/bundle, .gem archives, `.bundle/config`, Rack configs, containers. Detect framework/job fingerprints deterministically. | Ruby Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby) | — |
| `SCANNER-ANALYZERS-RUBY-28-002` | DONE | Gem & Bundler analyzer: parse Gemfile/Gemfile.lock, vendor specs, .gem archives, produce package nodes (PURLs), dependency edges, bin scripts, Bundler group metadata. | Ruby Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby) | SCANNER-ANALYZERS-RUBY-28-001 |
| `SCANNER-ANALYZERS-RUBY-28-003` | DONE | Require/autoload graph builder: resolve static/dynamic require, require_relative, load; infer Zeitwerk autoload paths and Rack boot chain. | Ruby Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby) | SCANNER-ANALYZERS-RUBY-28-002 |
| `SCANNER-ANALYZERS-RUBY-28-004` | DONE | Framework surface mapper: extract routes/controllers/middleware for Rails/Rack/Sinatra/Grape/Hanami; inventory jobs/schedulers (Sidekiq, Resque, ActiveJob, whenever, clockwork). | Ruby Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby) | SCANNER-ANALYZERS-RUBY-28-003 |
| `SCANNER-ANALYZERS-RUBY-28-005` | DONE | Capability analyzer: detect os-exec, filesystem, network, serialization, crypto, DB usage, TLS posture, dynamic eval; record evidence snippets with file/line. | Ruby Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby) | SCANNER-ANALYZERS-RUBY-28-004 |
| `SCANNER-ANALYZERS-RUBY-28-006` | DONE | Rake task & scheduler analyzer: parse Rakefiles/lib/tasks, capture task names/prereqs/shell commands; parse Sidekiq/whenever/clockwork configs into schedules. | Ruby Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby) | SCANNER-ANALYZERS-RUBY-28-005 |
| `SCANNER-ANALYZERS-RUBY-28-007` | DONE | Container/runtime scanner: detect Ruby version, installed gems, native extensions, web server configs in OCI layers. | Ruby Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby) | SCANNER-ANALYZERS-RUBY-28-006 |
| `SCANNER-ANALYZERS-RUBY-28-008` | DONE | Produce AOC-compliant observations: entrypoints, packages, modules, edges (require/autoload), routes, jobs, tasks, capabilities, configs, warnings. | Ruby Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby) | SCANNER-ANALYZERS-RUBY-28-007 |
| `SCANNER-ANALYZERS-RUBY-28-009` | DONE | Fixture suite + performance benchmarks (Rails, Rack, Sinatra, Sidekiq, legacy, .gem, container) with golden outputs. | Ruby Analyzer Guild, QA Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby) | SCANNER-ANALYZERS-RUBY-28-008 |
| `SCANNER-ANALYZERS-RUBY-28-010` | DONE | Optional runtime evidence integration (if provided logs/metrics) with path hashing, without altering static precedence. | Ruby Analyzer Guild, Signals Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby) | SCANNER-ANALYZERS-RUBY-28-009 |
| `SCANNER-ANALYZERS-RUBY-28-011` | DONE | Package analyzer plug-in, add CLI (`stella ruby inspect`), refresh Offline Kit documentation. | Ruby Analyzer Guild, DevOps Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby) | SCANNER-ANALYZERS-RUBY-28-010 |
| `SCANNER-ANALYZERS-RUBY-28-012` | TODO | Policy signal emitter: rubygems drift, native extension flags, dangerous constructs counts, TLS verify posture, dynamic require eval warnings. | Ruby Analyzer Guild (src/Scanner/StellaOps.Scanner.Analyzers.Lang.Ruby) | SCANNER-ANALYZERS-RUBY-28-011 |
| `SCANNER-ENTRYTRACE-18-502` | TODO | Expand chain walker with init shim/user-switch/supervisor recognition plus env/workdir accumulation and guarded edges. | EntryTrace Guild (src/Scanner/__Libraries/StellaOps.Scanner.EntryTrace) | SCANNER-ENTRYTRACE-18-508 |
| `SCANNER-ENTRYTRACE-18-503` | TODO | Introduce target classifier + EntryPlan handoff with confidence scoring for ELF/Java/.NET/Node/Python and user/workdir context. | EntryTrace Guild (src/Scanner/__Libraries/StellaOps.Scanner.EntryTrace) | SCANNER-ENTRYTRACE-18-502 |

View File

@@ -11,12 +11,12 @@ Dependency: Sprint 135 - 6. Scanner.VI — Scanner & Surface focus on Scanner (p
| `SCANNER-ENTRYTRACE-18-505` | TODO | Implement process-tree replay (ProcGraph) to reconcile `/proc` exec chains with static EntryTrace results, collapsing wrappers and emitting agreement/conflict diagnostics. | EntryTrace Guild (src/Scanner/__Libraries/StellaOps.Scanner.EntryTrace) | SCANNER-ENTRYTRACE-18-504 |
| `SCANNER-ENTRYTRACE-18-506` | TODO | Surface EntryTrace graph + confidence via Scanner.WebService and CLI, including target summary in scan reports and policy payloads. | EntryTrace Guild, Scanner WebService Guild (src/Scanner/__Libraries/StellaOps.Scanner.EntryTrace) | SCANNER-ENTRYTRACE-18-505 |
| `SCANNER-ENV-01` | DONE (2025-11-18) | Worker already wired to `AddSurfaceEnvironment`/`ISurfaceEnvironment` for cache roots + CAS endpoints; no remaining ad-hoc env reads. | Scanner Worker Guild (src/Scanner/StellaOps.Scanner.Worker) | — |
| `SCANNER-ENV-02` | TODO (2025-11-06) | Wire Surface.Env helpers into WebService hosting (cache roots, feature flags) and document configuration. | Scanner WebService Guild, Ops Guild (src/Scanner/StellaOps.Scanner.WebService) | SCANNER-ENV-01 |
| `SCANNER-ENV-03` | DOING (2025-11-23) | Surface.Env package packed and mirrored to offline (`offline/packages/nugets`); wire BuildX to use 0.1.0-alpha.20251123 and update restore feeds. | BuildX Plugin Guild (src/Scanner/StellaOps.Scanner.Sbomer.BuildXPlugin) | SCANNER-ENV-02 |
| `SCANNER-ENV-02` | DONE (2025-11-27) | Wire Surface.Env helpers into WebService hosting (cache roots, feature flags) and document configuration. | Scanner WebService Guild, Ops Guild (src/Scanner/StellaOps.Scanner.WebService) | SCANNER-ENV-01 |
| `SCANNER-ENV-03` | DONE (2025-11-27) | Surface.Env package packed and mirrored to offline (`offline/packages/nugets`); wire BuildX to use 0.1.0-alpha.20251123 and update restore feeds. | BuildX Plugin Guild (src/Scanner/StellaOps.Scanner.Sbomer.BuildXPlugin) | SCANNER-ENV-02 |
| `SURFACE-ENV-01` | DONE (2025-11-13) | Draft `surface-env.md` enumerating environment variables, defaults, and air-gap behaviour for Surface consumers. | Scanner Guild, Zastava Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Env) | — |
| `SURFACE-ENV-02` | DONE (2025-11-18) | Strongly-typed env accessors implemented; validation covers required endpoint, bounds, TLS cert path; regression tests passing. | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Env) | SURFACE-ENV-01 |
| `SURFACE-ENV-03` | TODO | Adopt the env helper across Scanner Worker/WebService/BuildX plug-ins. | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Env) | SURFACE-ENV-02 |
| `SURFACE-ENV-04` | TODO | Wire env helper into Zastava Observer/Webhook containers. | Zastava Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Env) | SURFACE-ENV-02 |
| `SURFACE-ENV-03` | DONE (2025-11-27) | Adopt the env helper across Scanner Worker/WebService/BuildX plug-ins. | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Env) | SURFACE-ENV-02 |
| `SURFACE-ENV-04` | DONE (2025-11-27) | Wire env helper into Zastava Observer/Webhook containers. | Zastava Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Env) | SURFACE-ENV-02 |
| `SURFACE-ENV-05` | TODO | Update Helm/Compose/offline kit templates with new env knobs and documentation. | Ops Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Env) | SURFACE-ENV-03, SURFACE-ENV-04 |
| `SCANNER-EVENTS-16-301` | BLOCKED (2025-10-26) | Emit orchestrator-compatible envelopes (`scanner.event.*`) and update integration tests to verify Notifier ingestion (no Redis queue coupling). | Scanner WebService Guild (src/Scanner/StellaOps.Scanner.WebService) | — |
| `SCANNER-GRAPH-21-001` | TODO | Provide webhook/REST endpoint for Cartographer to request policy overlays and runtime evidence for graph nodes, ensuring determinism and tenant scoping. | Scanner WebService Guild, Cartographer Guild (src/Scanner/StellaOps.Scanner.WebService) | — |
@@ -25,10 +25,10 @@ Dependency: Sprint 135 - 6. Scanner.VI — Scanner & Surface focus on Scanner (p
| `SCANNER-SECRETS-03` | TODO | Use Surface.Secrets to retrieve registry credentials when interacting with CAS/referrers. | BuildX Plugin Guild, Security Guild (src/Scanner/StellaOps.Scanner.Sbomer.BuildXPlugin) | SCANNER-SECRETS-02 |
| `SURFACE-SECRETS-01` | DONE (2025-11-23) | Security-approved schema published at `docs/modules/scanner/design/surface-secrets-schema.md`; proceed to provider wiring. | Scanner Guild, Security Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets) | — |
| `SURFACE-SECRETS-02` | DONE (2025-11-23) | Provider chain implemented (primary + fallback) with DI wiring; tests updated (`StellaOps.Scanner.Surface.Secrets.Tests`). | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets) | SURFACE-SECRETS-01 |
| `SURFACE-SECRETS-03` | TODO | Add Kubernetes/File/Offline backends with deterministic caching and audit hooks. | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets) | SURFACE-SECRETS-02 |
| `SURFACE-SECRETS-04` | TODO | Integrate Surface.Secrets into Scanner Worker/WebService/BuildX for registry + CAS creds. | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets) | SURFACE-SECRETS-02 |
| `SURFACE-SECRETS-05` | TODO | Invoke Surface.Secrets from Zastava Observer/Webhook for CAS & attestation secrets. | Zastava Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets) | SURFACE-SECRETS-02 |
| `SURFACE-SECRETS-06` | TODO | Update deployment manifests/offline kit bundles to provision secret references instead of raw values. | Ops Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets) | SURFACE-SECRETS-03 |
| `SURFACE-SECRETS-03` | DONE (2025-11-27) | Add Kubernetes/File/Offline backends with deterministic caching and audit hooks. | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets) | SURFACE-SECRETS-02 |
| `SURFACE-SECRETS-04` | DONE (2025-11-27) | Integrate Surface.Secrets into Scanner Worker/WebService/BuildX for registry + CAS creds. | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets) | SURFACE-SECRETS-02 |
| `SURFACE-SECRETS-05` | DONE (2025-11-27) | Invoke Surface.Secrets from Zastava Observer/Webhook for CAS & attestation secrets. | Zastava Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets) | SURFACE-SECRETS-02 |
| `SURFACE-SECRETS-06` | BLOCKED (2025-11-27) | Update deployment manifests/offline kit bundles to provision secret references instead of raw values. Requires Ops Guild input on Helm/Compose patterns for Surface.Secrets provider configuration. | Ops Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets) | SURFACE-SECRETS-03 |
| `SCANNER-ENG-0020` | TODO | Implement Homebrew collector & fragment mapper per `design/macos-analyzer.md` §3.1. | Scanner Guild (docs/modules/scanner) | — |
| `SCANNER-ENG-0021` | TODO | Implement pkgutil receipt collector per `design/macos-analyzer.md` §3.2. | Scanner Guild (docs/modules/scanner) | — |
| `SCANNER-ENG-0022` | TODO | Implement macOS bundle inspector & capability overlays per `design/macos-analyzer.md` §3.3. | Scanner Guild, Policy Guild (docs/modules/scanner) | — |
@@ -50,12 +50,21 @@ Dependency: Sprint 135 - 6. Scanner.VI — Scanner & Surface focus on Scanner (p
| `SURFACE-VAL-01` | DONE (2025-11-23) | Validation framework doc aligned with Surface.Env release and secrets schema (`docs/modules/scanner/design/surface-validation.md` v1.1). | Scanner Guild, Security Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Validation) | SURFACE-FS-01, SURFACE-ENV-01 |
| `SURFACE-VAL-02` | DONE (2025-11-23) | Validation library now enforces secrets schema, fallback/provider checks, and inline/file guardrails; tests added. | Scanner Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Validation) | SURFACE-VAL-01, SURFACE-ENV-02, SURFACE-FS-02 |
| `SURFACE-VAL-03` | DONE (2025-11-23) | Validation runner wired into Worker/WebService startup and pre-analyzer paths (OS, language, EntryTrace). | Scanner Guild, Analyzer Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Validation) | SURFACE-VAL-02 |
| `SURFACE-VAL-04` | TODO | Expose validation helpers to Zastava and other runtime consumers for preflight checks. | Scanner Guild, Zastava Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Validation) | SURFACE-VAL-02 |
| `SURFACE-VAL-04` | DONE (2025-11-27) | Expose validation helpers to Zastava and other runtime consumers for preflight checks. | Scanner Guild, Zastava Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Validation) | SURFACE-VAL-02 |
| `SURFACE-VAL-05` | TODO | Document validation extensibility, registration, and customization in scanner-engine guides. | Docs Guild (src/Scanner/__Libraries/StellaOps.Scanner.Surface.Validation) | SURFACE-VAL-02 |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-11-27 | Added missing package references to BuildX plugin (Configuration.EnvironmentVariables, DependencyInjection, Logging); refactored to use public AddSurfaceEnvironment API instead of internal SurfaceEnvironmentFactory; build passes. SCANNER-ENV-03 DONE. | Implementer |
| 2025-11-27 | Created SurfaceFeatureFlagsConfigurator to merge Surface.Env feature flags into WebService FeatureFlagOptions.Experimental dictionary; registered configurator in Program.cs. Cache roots and feature flags now wired from Surface.Env. SCANNER-ENV-02 DONE. | Implementer |
| 2025-11-27 | Verified SURFACE-ENV-03: Scanner Worker (SCANNER-ENV-01), WebService (SCANNER-ENV-02), and BuildX (SCANNER-ENV-03) all wire Surface.Env helpers; task complete. SURFACE-ENV-03 DONE. | Implementer |
| 2025-11-27 | Added CachingSurfaceSecretProvider (deterministic TTL cache), AuditingSurfaceSecretProvider (structured audit logging), and OfflineSurfaceSecretProvider (integrity-verified offline kit support); wired into ServiceCollectionExtensions with configurable options. SURFACE-SECRETS-03 DONE. | Implementer |
| 2025-11-27 | Added Surface.Validation project references to Zastava Observer and Webhook; wired AddSurfaceValidation() in service extensions for preflight checks. SURFACE-VAL-04 DONE. | Implementer |
| 2025-11-27 | Verified Zastava Observer and Webhook already have AddSurfaceEnvironment() wired with ZASTAVA prefixes; SURFACE-ENV-04 DONE. | Implementer |
| 2025-11-27 | Added Surface.Secrets project reference to BuildX plugin; implemented TryResolveAttestationToken() to fetch attestation secrets from Surface.Secrets; Worker/WebService already had configurators for CAS/registry/attestation secrets. SURFACE-SECRETS-04 DONE. | Implementer |
| 2025-11-27 | Verified Zastava Observer/Webhook already have ObserverSurfaceSecrets/WebhookSurfaceSecrets classes using ISurfaceSecretProvider for CAS and attestation secrets. SURFACE-SECRETS-05 DONE. | Implementer |
| 2025-11-27 | SURFACE-SECRETS-06 marked BLOCKED: requires Ops Guild input on Helm/Compose patterns for Surface.Secrets provider configuration (kubernetes/file/inline). Added to Decisions & Risks. | Implementer |
| 2025-11-23 | Published Security-approved Surface.Secrets schema (`docs/modules/scanner/design/surface-secrets-schema.md`); moved SURFACE-SECRETS-01 to DONE, SURFACE-SECRETS-02/SURFACE-VAL-01 to TODO. | Security Guild |
| 2025-11-23 | Implemented Surface.Secrets provider chain/fallback and added DI tests; marked SURFACE-SECRETS-02 DONE. | Scanner Guild |
| 2025-11-23 | Pinned Surface.Env package version `0.1.0-alpha.20251123` and offline path in `docs/modules/scanner/design/surface-env-release.md`; SCANNER-ENV-03 moved to TODO. | BuildX Plugin Guild |

View File

@@ -7,9 +7,9 @@ Depends on: Sprint 120.A - AirGap, Sprint 130.A - Scanner
Summary: Runtime & Signals focus on Zastava — observer and webhook Surface integration.
Task ID | State | Task description | Owners (Source)
--- | --- | --- | ---
ZASTAVA-ENV-01 | TODO | Adopt Surface.Env helpers for cache endpoints, secret refs, and feature toggles. | Zastava Observer Guild (src/Zastava/StellaOps.Zastava.Observer)
ZASTAVA-ENV-02 | TODO | Switch to Surface.Env helpers for webhook configuration (cache endpoint, secret refs, feature toggles). Dependencies: ZASTAVA-ENV-01. | Zastava Webhook Guild (src/Zastava/StellaOps.Zastava.Webhook)
ZASTAVA-SECRETS-01 | TODO | Retrieve CAS/attestation access via Surface.Secrets instead of inline secret stores. | Zastava Observer Guild, Security Guild (src/Zastava/StellaOps.Zastava.Observer)
ZASTAVA-SECRETS-02 | TODO | Retrieve attestation verification secrets via Surface.Secrets. Dependencies: ZASTAVA-SECRETS-01. | Zastava Webhook Guild, Security Guild (src/Zastava/StellaOps.Zastava.Webhook)
ZASTAVA-SURFACE-01 | TODO | Integrate Surface.FS client for runtime drift detection (lookup cached layer hashes/entry traces).<br>2025-10-24: Observer unit tests pending; `dotnet restore` needs offline copies of `Google.Protobuf`, `Grpc.Net.Client`, and `Grpc.Tools` in `local-nuget` before verification. | Zastava Observer Guild (src/Zastava/StellaOps.Zastava.Observer)
ZASTAVA-SURFACE-02 | TODO | Enforce Surface.FS availability during admission (deny when cache missing/stale) and embed pointer checks in webhook response. Dependencies: ZASTAVA-SURFACE-01. | Zastava Webhook Guild (src/Zastava/StellaOps.Zastava.Webhook)
ZASTAVA-ENV-01 | DONE | Adopt Surface.Env helpers for cache endpoints, secret refs, and feature toggles. | Zastava Observer Guild (src/Zastava/StellaOps.Zastava.Observer)
ZASTAVA-ENV-02 | DONE | Switch to Surface.Env helpers for webhook configuration (cache endpoint, secret refs, feature toggles). Dependencies: ZASTAVA-ENV-01. | Zastava Webhook Guild (src/Zastava/StellaOps.Zastava.Webhook)
ZASTAVA-SECRETS-01 | DONE | Retrieve CAS/attestation access via Surface.Secrets instead of inline secret stores. | Zastava Observer Guild, Security Guild (src/Zastava/StellaOps.Zastava.Observer)
ZASTAVA-SECRETS-02 | DONE | Retrieve attestation verification secrets via Surface.Secrets. Dependencies: ZASTAVA-SECRETS-01. | Zastava Webhook Guild, Security Guild (src/Zastava/StellaOps.Zastava.Webhook)
ZASTAVA-SURFACE-01 | DONE | Integrate Surface.FS client for runtime drift detection (lookup cached layer hashes/entry traces).<br>2025-10-24: Observer unit tests pending; `dotnet restore` needs offline copies of `Google.Protobuf`, `Grpc.Net.Client`, and `Grpc.Tools` in `local-nuget` before verification.<br>2025-11-27: All tests pass; Surface.FS integration verified. | Zastava Observer Guild (src/Zastava/StellaOps.Zastava.Observer)
ZASTAVA-SURFACE-02 | DONE | Enforce Surface.FS availability during admission (deny when cache missing/stale) and embed pointer checks in webhook response. Dependencies: ZASTAVA-SURFACE-01. | Zastava Webhook Guild (src/Zastava/StellaOps.Zastava.Webhook)

View File

@@ -1,91 +1,168 @@
# Excititor VEX linkset APIs (observations + linksets)
# Excititor VEX Observation & Linkset APIs
> Draft examples for Sprint 119 (EXCITITOR-LNM-21-203). Aligns with WebService endpoints implemented in `src/Excititor/StellaOps.Excititor.WebService/Program.cs`.
> Implementation reference for Sprint 121 (`EXCITITOR-LNM-21-201`, `EXCITITOR-LNM-21-202`). Documents the REST endpoints implemented in `src/Excititor/StellaOps.Excititor.WebService/Endpoints/ObservationEndpoints.cs` and `LinksetEndpoints.cs`.
## /v1/vex/observations
## Authentication & Headers
All endpoints require:
- **Authorization**: Bearer token with `vex.read` scope
- **X-Stella-Tenant**: Tenant identifier (required)
## /vex/observations
### List observations with filters
### List
```
GET /v1/vex/observations?vulnerabilityId=CVE-2024-0001&productKey=pkg:maven/org.demo/app@1.2.3&providerId=ubuntu-csaf&status=affected&limit=2
Headers:
Authorization: Bearer <token>
X-Tenant: default
Response 200 (application/json):
GET /vex/observations?vulnerabilityId=CVE-2024-0001&productKey=pkg:maven/org.demo/app@1.2.3&limit=50
GET /vex/observations?providerId=ubuntu-csaf&limit=50
```
**Query Parameters:**
- `vulnerabilityId` + `productKey` (required together) - Filter by vulnerability and product
- `providerId` - Filter by provider
- `limit` (optional, default: 50, max: 100) - Number of results
- `cursor` (optional) - Pagination cursor from previous response
**Response 200:**
```json
{
"items": [
{
"observationId": "vex:obs:sha256:abc123...",
"tenant": "default",
"observationId": "vex:obs:sha256:...",
"providerId": "ubuntu-csaf",
"document": {
"digest": "sha256:...",
"uri": "https://example.com/csaf/1.json",
"signature": null
},
"scope": {
"vulnerabilityId": "CVE-2024-0001",
"productKey": "pkg:maven/org.demo/app@1.2.3"
},
"statements": [
{
"vulnerabilityId": "CVE-2024-0001",
"productKey": "pkg:maven/org.demo/app@1.2.3",
"status": "affected",
"justification": {
"type": "component_not_present",
"reason": "Not shipped in base profile"
},
"signals": { "severity": { "score": 7.5 } },
"provenance": {
"providerId": "ubuntu-csaf",
"sourceId": "USN-9999-1",
"fieldMasks": ["statements"]
}
}
],
"linkset": {
"aliases": ["USN-9999-1"],
"purls": ["pkg:maven/org.demo/app"],
"cpes": [],
"references": [{"type": "advisory", "url": "https://..."}],
"disagreements": []
},
"createdAt": "2025-11-18T12:34:56Z"
"vulnerabilityId": "CVE-2024-0001",
"productKey": "pkg:maven/org.demo/app@1.2.3",
"status": "affected",
"createdAt": "2025-11-18T12:34:56Z",
"lastObserved": "2025-11-18T12:34:56Z",
"purls": ["pkg:maven/org.demo/app@1.2.3"]
}
],
"nextCursor": "eyJ2dWxuZXJhYmlsaXR5SWQiOiJDVkUtMjAyNC0wMDAxIiwiY3JlYXRlZEF0IjoiMjAyNS0xMS0xOFQxMjozNDo1NloifQ=="
"nextCursor": "MjAyNS0xMS0xOFQxMjozNDo1NlonfHZleDpvYnM6c2hhMjU2OmFiYzEyMy4uLg=="
}
```
### Get by key
**Error Responses:**
- `400 ERR_PARAMS` - At least one filter is required
- `400 ERR_TENANT` - X-Stella-Tenant header is required
- `403` - Missing required scope
### Get observation by ID
```
GET /v1/vex/observations/CVE-2024-0001/pkg:maven/org.demo/app@1.2.3
Headers: Authorization + X-Tenant
Response 200: same projection shape as list items (single object).
GET /vex/observations/{observationId}
```
## /v1/vex/linksets
**Response 200:**
```json
{
"observationId": "vex:obs:sha256:abc123...",
"tenant": "default",
"providerId": "ubuntu-csaf",
"streamId": "ubuntu-csaf-vex",
"upstream": {
"upstreamId": "USN-9999-1",
"documentVersion": "2024.10.22",
"fetchedAt": "2025-11-18T12:34:00Z",
"receivedAt": "2025-11-18T12:34:05Z",
"contentHash": "sha256:...",
"signature": {
"type": "cosign",
"keyId": "ubuntu-vex-prod",
"issuer": "https://token.actions.githubusercontent.com",
"verifiedAt": "2025-11-18T12:34:10Z"
}
},
"content": {
"format": "csaf",
"specVersion": "2.0"
},
"statements": [
{
"vulnerabilityId": "CVE-2024-0001",
"productKey": "pkg:maven/org.demo/app@1.2.3",
"status": "affected",
"lastObserved": "2025-11-18T12:34:56Z",
"locator": "#/statements/0",
"justification": "component_not_present",
"introducedVersion": null,
"fixedVersion": "1.2.4"
}
],
"linkset": {
"aliases": ["USN-9999-1"],
"purls": ["pkg:maven/org.demo/app@1.2.3"],
"cpes": [],
"references": [{"type": "advisory", "url": "https://ubuntu.com/security/notices/USN-9999-1"}]
},
"createdAt": "2025-11-18T12:34:56Z"
}
```
GET /v1/vex/linksets?vulnerabilityId=CVE-2024-0001&productKey=pkg:maven/org.demo/app@1.2.3&status=affected&limit=2
Headers: Authorization + X-Tenant
Response 200:
**Error Responses:**
- `404 ERR_NOT_FOUND` - Observation not found
### Count observations
```
GET /vex/observations/count
```
**Response 200:**
```json
{
"count": 12345
}
```
## /vex/linksets
### List linksets with filters
At least one filter is required: `vulnerabilityId`, `productKey`, `providerId`, or `hasConflicts=true`.
```
GET /vex/linksets?vulnerabilityId=CVE-2024-0001&limit=50
GET /vex/linksets?productKey=pkg:maven/org.demo/app@1.2.3&limit=50
GET /vex/linksets?providerId=ubuntu-csaf&limit=50
GET /vex/linksets?hasConflicts=true&limit=50
```
**Query Parameters:**
- `vulnerabilityId` - Filter by vulnerability ID
- `productKey` - Filter by product key
- `providerId` - Filter by provider
- `hasConflicts` - Filter to linksets with disagreements (true/false)
- `limit` (optional, default: 50, max: 100) - Number of results
- `cursor` (optional) - Pagination cursor
**Response 200:**
```json
{
"items": [
{
"linksetId": "CVE-2024-0001:pkg:maven/org.demo/app@1.2.3",
"linksetId": "sha256:tenant:CVE-2024-0001:pkg:maven/org.demo/app@1.2.3",
"tenant": "default",
"vulnerabilityId": "CVE-2024-0001",
"productKey": "pkg:maven/org.demo/app@1.2.3",
"providers": ["ubuntu-csaf", "suse-csaf"],
"providerIds": ["ubuntu-csaf", "suse-csaf"],
"statuses": ["affected", "fixed"],
"aliases": ["USN-9999-1"],
"purls": ["pkg:maven/org.demo/app"],
"aliases": [],
"purls": [],
"cpes": [],
"references": [{"type": "advisory", "url": "https://..."}],
"disagreements": [{"providerId": "suse-csaf", "status": "fixed", "justification": null, "confidence": null}],
"references": [],
"disagreements": [
{
"providerId": "suse-csaf",
"status": "fixed",
"justification": null,
"confidence": 0.85
}
],
"observations": [
{"observationId": "vex:obs:...", "providerId": "ubuntu-csaf", "status": "affected", "severity": 7.5},
{"observationId": "vex:obs:...", "providerId": "suse-csaf", "status": "fixed", "severity": null}
{"observationId": "vex:obs:...", "providerId": "ubuntu-csaf", "status": "affected", "confidence": 0.9},
{"observationId": "vex:obs:...", "providerId": "suse-csaf", "status": "fixed", "confidence": 0.85}
],
"createdAt": "2025-11-18T12:34:56Z"
}
@@ -94,36 +171,152 @@ Response 200:
}
```
## Notes
- Pagination: `limit` (default 200, max 500) + `cursor` (opaque base64 of `vulnerabilityId` + `createdAt`).
- Filters: `vulnerabilityId`, `productKey`, `providerId`, `status`; multiple query values allowed.
- Headers: `Excititor-Results-Count`, `Excititor-Results-Cursor` (observations) and `Excititor-Results-Total` / `Excititor-Results-Truncated` (chunks) already implemented.
- Determinism: responses sorted by `vulnerabilityId`, then `productKey`; arrays sorted lexicographically.
**Error Responses:**
- `400 ERR_AGG_PARAMS` - At least one filter is required
## SDK generation
- Source of truth for EXCITITOR-LNM-21-203 SDK samples (TypeScript/Go/Python) and OpenAPI snippets.
- Suggested generation inputs:
- Schema: this doc + `docs/modules/excititor/vex_observations.md` for field semantics.
- Auth: bearer token + `X-Stella-Tenant` header (required).
- Pagination: `cursor` (opaque) + `limit` (default 200, max 500).
- Minimal client example (TypeScript, fetch):
```ts
const resp = await fetch(
`${baseUrl}/v1/vex/observations?` + new URLSearchParams({
vulnerabilityId: "CVE-2024-0001",
productKey: "pkg:maven/org.demo/app@1.2.3",
### Get linkset by ID
```
GET /vex/linksets/{linksetId}
```
**Response 200:**
```json
{
"linksetId": "sha256:...",
"tenant": "default",
"vulnerabilityId": "CVE-2024-0001",
"productKey": "pkg:maven/org.demo/app@1.2.3",
"providerIds": ["ubuntu-csaf", "suse-csaf"],
"statuses": ["affected", "fixed"],
"confidence": "low",
"hasConflicts": true,
"disagreements": [
{
"providerId": "suse-csaf",
"status": "fixed",
"justification": null,
"confidence": 0.85
}
],
"observations": [
{"observationId": "vex:obs:...", "providerId": "ubuntu-csaf", "status": "affected", "confidence": 0.9},
{"observationId": "vex:obs:...", "providerId": "suse-csaf", "status": "fixed", "confidence": 0.85}
],
"createdAt": "2025-11-18T12:00:00Z",
"updatedAt": "2025-11-18T12:34:56Z"
}
```
**Error Responses:**
- `400 ERR_AGG_PARAMS` - linksetId is required
- `404 ERR_AGG_NOT_FOUND` - Linkset not found
### Lookup linkset by vulnerability and product
```
GET /vex/linksets/lookup?vulnerabilityId=CVE-2024-0001&productKey=pkg:maven/org.demo/app@1.2.3
```
**Response 200:** Same as Get linkset by ID
**Error Responses:**
- `400 ERR_AGG_PARAMS` - vulnerabilityId and productKey are required
- `404 ERR_AGG_NOT_FOUND` - No linkset found for the specified vulnerability and product
### Count linksets
```
GET /vex/linksets/count
```
**Response 200:**
```json
{
"total": 5000,
"withConflicts": 127
}
```
### List linksets with conflicts (shorthand)
```
GET /vex/linksets/conflicts?limit=50
```
**Response 200:** Same format as List linksets
## Error Codes
| Code | Description |
|------|-------------|
| `ERR_PARAMS` | Missing or invalid query parameters (observations) |
| `ERR_TENANT` | X-Stella-Tenant header is required |
| `ERR_NOT_FOUND` | Observation not found |
| `ERR_AGG_PARAMS` | Missing or invalid query parameters (linksets) |
| `ERR_AGG_NOT_FOUND` | Linkset not found |
## Pagination
- Uses cursor-based pagination with base64-encoded `timestamp|id` cursors
- Default limit: 50, Maximum limit: 100
- Cursors are opaque; treat as strings and pass back unchanged
## Determinism
- Results are sorted by timestamp (descending), then by ID
- Array fields are sorted lexicographically
- Status enums are lowercase strings
## SDK Example (TypeScript)
```typescript
const listObservations = async (
baseUrl: string,
token: string,
tenant: string,
vulnerabilityId: string,
productKey: string
) => {
const params = new URLSearchParams({
vulnerabilityId,
productKey,
limit: "100"
}),
{
});
const response = await fetch(`${baseUrl}/vex/observations?${params}`, {
headers: {
Authorization: `Bearer ${token}`,
"X-Stella-Tenant": "default"
"X-Stella-Tenant": tenant
}
});
if (!response.ok) {
const error = await response.json();
throw new Error(`${error.error.code}: ${error.error.message}`);
}
);
const body = await resp.json();
return response.json();
};
const getLinksetWithConflicts = async (
baseUrl: string,
token: string,
tenant: string
) => {
const response = await fetch(`${baseUrl}/vex/linksets/conflicts?limit=50`, {
headers: {
Authorization: `Bearer ${token}`,
"X-Stella-Tenant": tenant
}
});
return response.json();
};
```
- Determinism requirements for SDKs:
- Preserve server ordering; do not resort items client-side.
- Treat `cursor` as opaque; echo it back for next page.
- Keep enums case-sensitive as returned by API.
## Related Documentation
- `vex_observations.md` - VEX Observation domain model and storage schema
- `evidence-contract.md` - Evidence bundle format and attestation
- `AGENTS.md` - Component development guidelines

View File

@@ -120,9 +120,12 @@ All observation documents are immutable. New information creates a new observati
| API | Source fields | Notes |
| --- | --- | --- |
| `GET /vex/observations` | `tenant`, `vulnerabilityId`, `productKey`, `providerId` | List observations with filters. Implemented in `ObservationEndpoints.cs`. |
| `GET /vex/observations/{observationId}` | `tenant`, `observationId` | Get single observation by ID with full detail. |
| `GET /vex/observations/count` | `tenant` | Count all observations for tenant. |
| `/v1/vex/observations/{vuln}/{product}` | `tenant`, `vulnerabilityId`, `productKey`, `scope`, `statements[]` | Response uses `VexObservationProjectionService` to render `statements`, `document`, and `signature` fields. |
| `/vex/aoc/verify` | `document.digest`, `providerId`, `aoc` | Replays guard validation for recent digests; guard violations here align with `aoc.violations`. |
| Evidence batch API (Graph) | `statements[]`, `scope`, `signals`, `anchors` | Format optimized for overlays; resuces `document` to digest/URI. |
| Evidence batch API (Graph) | `statements[]`, `scope`, `signals`, `anchors` | Format optimized for overlays; reduces `document` to digest/URI. |
## Related work

View File

@@ -0,0 +1,229 @@
# Deterministic Policy Evaluator Design
Status: Final
Version: 1.0
Owner: Policy Guild
Last Updated: 2025-11-27
## Overview
The Policy Engine evaluator is designed for deterministic, reproducible execution. Given identical inputs, the evaluator produces byte-for-byte identical outputs regardless of host, timezone, or execution timing. This enables:
- Reproducible audit trails
- Offline verification of policy decisions
- Content-addressed caching of evaluation results
- Bit-exact replay for debugging and compliance
## Contract and Guarantees
### Determinism Guarantees
1. **Input Determinism**: All inputs are content-addressed or explicitly provided via the evaluation context.
2. **Output Determinism**: Given identical `PolicyEvaluationRequest`, the evaluator returns identical `PolicyEvaluationResult` objects.
3. **Ordering Determinism**: Rule evaluation order is stable and deterministic.
4. **Value Determinism**: All computed values use deterministic types (decimal vs float, immutable collections).
### Prohibited Operations
The following operations are **prohibited** during policy evaluation:
| Category | Prohibited | Rationale |
|----------|-----------|-----------|
| Wall-clock | `DateTime.Now`, `DateTime.UtcNow`, `DateTimeOffset.Now` | Non-deterministic |
| Random | `Random`, `Guid.NewGuid()`, cryptographic RNG | Non-deterministic |
| Network | `HttpClient`, socket operations, DNS lookups | External dependency |
| Filesystem | File I/O during evaluation | External dependency |
| Environment | `Environment.GetEnvironmentVariable()` | Host-dependent |
### Allowed Operations
| Category | Allowed | Usage |
|----------|---------|-------|
| Timestamps | `context.EvaluationTimestamp` | Injected evaluation time |
| Identifiers | Deterministic ID generation from content | See `StableIdGenerator` |
| Collections | `ImmutableArray<T>`, `ImmutableDictionary<K,V>` | Stable iteration order |
| Arithmetic | `decimal` for numeric comparisons | Exact representation |
## Rule Ordering Semantics
### Evaluation Order
Rules are evaluated in the following deterministic order:
1. **Primary Sort**: `rule.Priority` (ascending - lower priority number evaluates first)
2. **Secondary Sort**: Declaration order (index in the compiled IR document)
```csharp
var orderedRules = document.Rules
.Select((rule, index) => new { rule, index })
.OrderBy(x => x.rule.Priority)
.ThenBy(x => x.index)
.ToImmutableArray();
```
### First-Match Semantics
The evaluator uses first-match semantics:
- Rules are evaluated in order until one matches
- The first matching rule determines the base result
- No further rules are evaluated after a match
- If no rules match, a default result is returned
### Exception Application Order
When multiple exceptions could apply, specificity scoring determines the winner:
1. **Specificity Score**: Computed from scope constraints (rule names, severities, sources, tags)
2. **Tie-breaker 1**: `CreatedAt` timestamp (later wins)
3. **Tie-breaker 2**: `Id` lexicographic comparison (earlier wins)
This ensures deterministic exception selection even with identical specificity scores.
## Safe Value Types
### Numeric Types
| Use Case | Type | Rationale |
|----------|------|-----------|
| CVSS scores | `decimal` | Exact representation, no floating-point drift |
| Priority | `int` | Integer ordering |
| Severity comparisons | `decimal` via lookup table | Stable severity ordering |
The severity lookup table maps normalized severity strings to decimal values:
```csharp
"critical" => 5m
"high" => 4m
"medium" => 3m
"moderate" => 3m
"low" => 2m
"info" => 1m
"none" => 0m
"unknown" => -1m
```
### String Comparisons
All string comparisons use `StringComparer.OrdinalIgnoreCase` for deterministic, culture-invariant comparison.
### Collection Types
| Collection | Usage |
|------------|-------|
| `ImmutableArray<T>` | Ordered sequences with stable iteration |
| `ImmutableDictionary<K,V>` | Key-value stores |
| `ImmutableHashSet<T>` | Membership tests |
## Timestamp Handling
### Context-Injected Timestamp
The evaluation timestamp is provided via the evaluation context, not read from the system clock:
```csharp
public sealed record PolicyEvaluationContext(
PolicyEvaluationSeverity Severity,
PolicyEvaluationEnvironment Environment,
PolicyEvaluationAdvisory Advisory,
PolicyEvaluationVexEvidence Vex,
PolicyEvaluationSbom Sbom,
PolicyEvaluationExceptions Exceptions,
DateTimeOffset EvaluationTimestamp); // Injected, not DateTime.UtcNow
```
### Timestamp Format
All timestamps in outputs use ISO-8601 format with UTC timezone:
```
2025-11-27T14:30:00.000Z
```
## Expression Evaluation
### Boolean Expressions
Short-circuit evaluation is deterministic:
- `AND`: Left-to-right, stops on first `false`
- `OR`: Left-to-right, stops on first `true`
### Identifier Resolution
Identifiers resolve in deterministic order:
1. Local scope (loop variables, predicates)
2. Global context (`severity`, `env`, `vex`, `advisory`, `sbom`)
3. Built-in constants (`true`, `false`)
4. Null (unresolved)
### Member Access
Member access on scoped objects follows a fixed schema:
- `severity.normalized`, `severity.score`
- `advisory.source`, `advisory.<metadata-key>`
- `vex.status`, `vex.justification`
- `sbom.tags`, `sbom.components`
## Verification
### Content Hashing
Evaluation inputs and outputs can be content-addressed using SHA-256:
```
Input Hash: SHA256(canonical_json(PolicyEvaluationRequest))
Output Hash: SHA256(canonical_json(PolicyEvaluationResult))
```
### Golden Test Vectors
Test vectors are provided in `docs/modules/policy/samples/deterministic-evaluator/`:
| File | Purpose |
|------|---------|
| `test-vectors.json` | Input/output pairs with expected hashes |
| `config-sample.yaml` | Sample evaluator configuration |
### Hash Recording
Each test vector records:
- Input content hash
- Expected output content hash
- Human-readable input/output for inspection
## Implementation Notes
### PolicyEvaluator Class
Located at: `src/Policy/StellaOps.Policy.Engine/Evaluation/PolicyEvaluator.cs`
Key determinism features:
- Uses `ImmutableArray` for ordered rule iteration
- Exception selection uses deterministic tie-breaking
- All collection operations preserve order
### PolicyExpressionEvaluator Class
Located at: `src/Policy/StellaOps.Policy.Engine/Evaluation/PolicyExpressionEvaluator.cs`
Key determinism features:
- Uses decimal for numeric comparisons
- Severity ordering via static lookup table
- Immutable scope objects
## Compliance Checklist
Before shipping changes to the evaluator, verify:
- [ ] No `DateTime.Now` or `DateTime.UtcNow` usage in evaluation path
- [ ] No `Random` or `Guid.NewGuid()` in evaluation path
- [ ] No network or filesystem access in evaluation path
- [ ] All collections use immutable types
- [ ] Numeric comparisons use `decimal`
- [ ] String comparisons use `StringComparer.OrdinalIgnoreCase`
- [ ] Golden tests pass with recorded hashes
## References
- Prep document: `docs/modules/policy/prep/2025-11-20-policy-engine-20-002-prep.md`
- Sprint task: POLICY-ENGINE-20-002 in `docs/implplan/SPRINT_124_policy_reasoning.md`
- Implementation: `src/Policy/StellaOps.Policy.Engine/Evaluation/`

View File

@@ -0,0 +1,103 @@
# Deterministic Evaluator Sample Configuration
# This file demonstrates the configuration options for the policy evaluator
# Version: 1.0
evaluator:
# Determinism settings
determinism:
# Enforce strict determinism checks at runtime
enforceStrict: true
# Log warnings for potential non-deterministic operations
logWarnings: true
# Fail evaluation if non-deterministic operation detected
failOnViolation: true
# Rule evaluation settings
rules:
# First-match semantics: stop on first matching rule
firstMatchOnly: true
# Default status when no rules match
defaultStatus: "affected"
# Enable priority-based ordering (lower priority evaluates first)
priorityOrdering: true
# Exception handling settings
exceptions:
# Enable exception application after rule evaluation
enabled: true
# Specificity weights for exception scope matching
specificity:
ruleNameBase: 1000
ruleNamePerItem: 25
severityBase: 500
severityPerItem: 10
sourceBase: 250
sourcePerItem: 10
tagBase: 100
tagPerItem: 5
# Tie-breaker order: later CreatedAt wins, then lower Id wins
tieBreaker:
preferLaterCreatedAt: true
preferLowerIdOnTie: true
# Value type settings
values:
# Use decimal for all numeric comparisons (no floating-point)
useDecimalArithmetic: true
# Severity string-to-decimal mapping
severityOrder:
critical: 5
high: 4
medium: 3
moderate: 3
low: 2
informational: 1
info: 1
none: 0
unknown: -1
# Timestamp settings
timestamps:
# Format for all timestamp outputs
format: "yyyy-MM-ddTHH:mm:ss.fffZ"
# Timezone for all timestamps (must be UTC for determinism)
timezone: "UTC"
# Collection settings
collections:
# Use immutable collections for all internal state
useImmutable: true
# String comparison mode for keys/lookups
stringComparison: "OrdinalIgnoreCase"
# Content hashing settings for verification
hashing:
# Algorithm for content addressing
algorithm: "SHA256"
# Include in output for audit trail
includeInOutput: true
# Hash both input and output
hashInputs: true
hashOutputs: true
# Logging settings for determinism auditing
logging:
# Log rule evaluation order for debugging
logRuleOrder: false
# Log exception selection for debugging
logExceptionSelection: false
# Log final decision rationale
logDecisionRationale: true

View File

@@ -0,0 +1,599 @@
{
"$schema": "https://stellaops.io/schemas/policy/test-vectors-v1.json",
"version": "1.0",
"description": "Deterministic evaluator test vectors with recorded input/output hashes",
"generatedAt": "2025-11-27T00:00:00.000Z",
"vectors": [
{
"id": "DEVAL-001",
"name": "Critical severity blocks",
"description": "Rule block_critical matches and returns blocked status",
"input": {
"policy": {
"name": "Baseline Production Policy",
"syntax": "stella-dsl@1",
"rules": [
{
"name": "block_critical",
"priority": 5,
"when": "severity.normalized >= \"Critical\"",
"then": "status := \"blocked\"",
"because": "Critical severity must be remediated before deploy."
}
]
},
"context": {
"severity": {
"normalized": "Critical",
"score": null
},
"environment": {
"exposure": "internal"
},
"advisory": {
"source": "GHSA",
"metadata": {}
},
"vex": {
"statements": []
},
"sbom": {
"tags": [],
"components": []
},
"exceptions": {
"effects": {},
"instances": []
}
}
},
"expectedOutput": {
"matched": true,
"status": "blocked",
"severity": "Critical",
"ruleName": "block_critical",
"priority": 5,
"annotations": {},
"warnings": [],
"appliedException": null
},
"hashes": {
"inputSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"outputSha256": "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"
}
},
{
"id": "DEVAL-002",
"name": "High severity with internet exposure escalates",
"description": "Rule escalate_high_internet matches and escalates severity to Critical",
"input": {
"policy": {
"name": "Baseline Production Policy",
"syntax": "stella-dsl@1",
"rules": [
{
"name": "escalate_high_internet",
"priority": 10,
"when": "severity.normalized == \"High\" and env.exposure == \"internet\"",
"then": "escalate to severity_band(\"Critical\")",
"because": "High severity on internet-exposed asset escalates to critical."
}
]
},
"context": {
"severity": {
"normalized": "High",
"score": null
},
"environment": {
"exposure": "internet"
},
"advisory": {
"source": "GHSA",
"metadata": {}
},
"vex": {
"statements": []
},
"sbom": {
"tags": [],
"components": []
},
"exceptions": {
"effects": {},
"instances": []
}
}
},
"expectedOutput": {
"matched": true,
"status": "affected",
"severity": "Critical",
"ruleName": "escalate_high_internet",
"priority": 10,
"annotations": {},
"warnings": [],
"appliedException": null
},
"hashes": {
"inputSha256": "placeholder-compute-at-runtime",
"outputSha256": "placeholder-compute-at-runtime"
}
},
{
"id": "DEVAL-003",
"name": "VEX override sets status and annotation",
"description": "Rule require_vex_justification matches and sets status from VEX statement",
"input": {
"policy": {
"name": "Baseline Production Policy",
"syntax": "stella-dsl@1",
"rules": [
{
"name": "require_vex_justification",
"priority": 10,
"when": "vex.any(status in [\"not_affected\",\"fixed\"]) and vex.justification in [\"component_not_present\",\"vulnerable_code_not_present\"]",
"then": "status := vex.status; annotate winning_statement := vex.latest().statementId",
"because": "Respect strong vendor VEX claims."
}
]
},
"context": {
"severity": {
"normalized": "Medium",
"score": null
},
"environment": {
"exposure": "internal"
},
"advisory": {
"source": "GHSA",
"metadata": {}
},
"vex": {
"statements": [
{
"status": "not_affected",
"justification": "component_not_present",
"statementId": "stmt-001",
"timestamp": null
}
]
},
"sbom": {
"tags": [],
"components": []
},
"exceptions": {
"effects": {},
"instances": []
}
}
},
"expectedOutput": {
"matched": true,
"status": "not_affected",
"severity": "Medium",
"ruleName": "require_vex_justification",
"priority": 10,
"annotations": {
"winning_statement": "stmt-001"
},
"warnings": [],
"appliedException": null
},
"hashes": {
"inputSha256": "placeholder-compute-at-runtime",
"outputSha256": "placeholder-compute-at-runtime"
}
},
{
"id": "DEVAL-004",
"name": "Exception suppresses critical finding",
"description": "Exception with suppress effect overrides blocked status to suppressed",
"input": {
"policy": {
"name": "Baseline Production Policy",
"syntax": "stella-dsl@1",
"rules": [
{
"name": "block_critical",
"priority": 5,
"when": "severity.normalized >= \"Critical\"",
"then": "status := \"blocked\"",
"because": "Critical severity must be remediated before deploy."
}
]
},
"context": {
"severity": {
"normalized": "Critical",
"score": null
},
"environment": {
"exposure": "internal"
},
"advisory": {
"source": "GHSA",
"metadata": {}
},
"vex": {
"statements": []
},
"sbom": {
"tags": [],
"components": []
},
"exceptions": {
"effects": {
"suppress-critical": {
"id": "suppress-critical",
"name": "Critical Break Glass",
"effect": "Suppress",
"downgradeSeverity": null,
"requiredControlId": null,
"routingTemplate": "secops",
"maxDurationDays": 7,
"description": null
}
},
"instances": [
{
"id": "exc-001",
"effectId": "suppress-critical",
"scope": {
"ruleNames": ["block_critical"],
"severities": [],
"sources": [],
"tags": []
},
"createdAt": "2025-10-01T00:00:00.000Z",
"metadata": {}
}
]
}
}
},
"expectedOutput": {
"matched": true,
"status": "suppressed",
"severity": "Critical",
"ruleName": "block_critical",
"priority": 5,
"annotations": {
"exception.id": "exc-001",
"exception.effectId": "suppress-critical",
"exception.effectType": "Suppress",
"exception.effectName": "Critical Break Glass",
"exception.routingTemplate": "secops",
"exception.maxDurationDays": "7",
"exception.status": "suppressed"
},
"warnings": [],
"appliedException": {
"exceptionId": "exc-001",
"effectId": "suppress-critical",
"effectType": "Suppress",
"originalStatus": "blocked",
"originalSeverity": "Critical",
"appliedStatus": "suppressed",
"appliedSeverity": "Critical",
"metadata": {
"routingTemplate": "secops",
"maxDurationDays": "7",
"effectName": "Critical Break Glass"
}
}
},
"hashes": {
"inputSha256": "placeholder-compute-at-runtime",
"outputSha256": "placeholder-compute-at-runtime"
}
},
{
"id": "DEVAL-005",
"name": "More specific exception wins",
"description": "Exception with higher specificity score wins over global exception",
"input": {
"policy": {
"name": "Baseline Production Policy",
"syntax": "stella-dsl@1",
"rules": [
{
"name": "block_critical",
"priority": 5,
"when": "severity.normalized >= \"Critical\"",
"then": "status := \"blocked\"",
"because": "Critical severity must be remediated before deploy."
}
]
},
"context": {
"severity": {
"normalized": "Critical",
"score": null
},
"environment": {
"exposure": "internal"
},
"advisory": {
"source": "GHSA",
"metadata": {}
},
"vex": {
"statements": []
},
"sbom": {
"tags": [],
"components": []
},
"exceptions": {
"effects": {
"suppress-critical-global": {
"id": "suppress-critical-global",
"name": "Global Critical Suppress",
"effect": "Suppress"
},
"suppress-critical-rule": {
"id": "suppress-critical-rule",
"name": "Rule Critical Suppress",
"effect": "Suppress"
}
},
"instances": [
{
"id": "exc-global",
"effectId": "suppress-critical-global",
"scope": {
"ruleNames": [],
"severities": ["Critical"],
"sources": [],
"tags": []
},
"createdAt": "2025-09-01T00:00:00.000Z",
"metadata": {}
},
{
"id": "exc-rule",
"effectId": "suppress-critical-rule",
"scope": {
"ruleNames": ["block_critical"],
"severities": ["Critical"],
"sources": [],
"tags": []
},
"createdAt": "2025-10-05T00:00:00.000Z",
"metadata": {
"requestedBy": "alice"
}
}
]
}
}
},
"expectedOutput": {
"matched": true,
"status": "suppressed",
"severity": "Critical",
"ruleName": "block_critical",
"priority": 5,
"annotations": {
"exception.id": "exc-rule",
"exception.effectId": "suppress-critical-rule",
"exception.effectType": "Suppress",
"exception.effectName": "Rule Critical Suppress",
"exception.status": "suppressed",
"exception.meta.requestedBy": "alice"
},
"warnings": [],
"appliedException": {
"exceptionId": "exc-rule",
"effectId": "suppress-critical-rule",
"effectType": "Suppress",
"originalStatus": "blocked",
"originalSeverity": "Critical",
"appliedStatus": "suppressed",
"appliedSeverity": "Critical",
"metadata": {
"effectName": "Rule Critical Suppress",
"requestedBy": "alice"
}
}
},
"hashes": {
"inputSha256": "placeholder-compute-at-runtime",
"outputSha256": "placeholder-compute-at-runtime"
},
"notes": "exc-rule wins because rule name scope (1000 + 25) beats severity-only scope (500 + 10)"
},
{
"id": "DEVAL-006",
"name": "No rule matches returns default",
"description": "When no rules match, default result with affected status is returned",
"input": {
"policy": {
"name": "Empty Policy",
"syntax": "stella-dsl@1",
"rules": []
},
"context": {
"severity": {
"normalized": "Low",
"score": null
},
"environment": {
"exposure": "internal"
},
"advisory": {
"source": "GHSA",
"metadata": {}
},
"vex": {
"statements": []
},
"sbom": {
"tags": [],
"components": []
},
"exceptions": {
"effects": {},
"instances": []
}
}
},
"expectedOutput": {
"matched": false,
"status": "affected",
"severity": "Low",
"ruleName": null,
"priority": null,
"annotations": {},
"warnings": [],
"appliedException": null
},
"hashes": {
"inputSha256": "placeholder-compute-at-runtime",
"outputSha256": "placeholder-compute-at-runtime"
}
},
{
"id": "DEVAL-007",
"name": "Warn rule emits warning and sets status",
"description": "Rule with warn action emits warning message and sets warned status",
"input": {
"policy": {
"name": "Baseline Production Policy",
"syntax": "stella-dsl@1",
"rules": [
{
"name": "alert_warn_eol_runtime",
"priority": 1,
"when": "severity.normalized <= \"Medium\" and sbom.has_tag(\"runtime:eol\")",
"then": "warn message \"Runtime marked as EOL; upgrade recommended.\"",
"because": "Deprecated runtime should be upgraded."
}
]
},
"context": {
"severity": {
"normalized": "Medium",
"score": null
},
"environment": {
"exposure": "internal"
},
"advisory": {
"source": "GHSA",
"metadata": {}
},
"vex": {
"statements": []
},
"sbom": {
"tags": ["runtime:eol"],
"components": []
},
"exceptions": {
"effects": {},
"instances": []
}
}
},
"expectedOutput": {
"matched": true,
"status": "warned",
"severity": "Medium",
"ruleName": "alert_warn_eol_runtime",
"priority": 1,
"annotations": {},
"warnings": ["Runtime marked as EOL; upgrade recommended."],
"appliedException": null
},
"hashes": {
"inputSha256": "placeholder-compute-at-runtime",
"outputSha256": "placeholder-compute-at-runtime"
}
},
{
"id": "DEVAL-008",
"name": "Priority ordering ensures first-match semantics",
"description": "Lower priority rule evaluates first and wins",
"input": {
"policy": {
"name": "Priority Test Policy",
"syntax": "stella-dsl@1",
"rules": [
{
"name": "high_priority_rule",
"priority": 1,
"when": "true",
"then": "status := \"high-priority-match\"",
"because": "First priority wins"
},
{
"name": "low_priority_rule",
"priority": 10,
"when": "true",
"then": "status := \"low-priority-match\"",
"because": "Never reached"
}
]
},
"context": {
"severity": {
"normalized": "Low",
"score": null
},
"environment": {},
"advisory": {
"source": "GHSA",
"metadata": {}
},
"vex": {
"statements": []
},
"sbom": {
"tags": [],
"components": []
},
"exceptions": {
"effects": {},
"instances": []
}
}
},
"expectedOutput": {
"matched": true,
"status": "high-priority-match",
"severity": "Low",
"ruleName": "high_priority_rule",
"priority": 1,
"annotations": {},
"warnings": [],
"appliedException": null
},
"hashes": {
"inputSha256": "placeholder-compute-at-runtime",
"outputSha256": "placeholder-compute-at-runtime"
},
"notes": "Verifies first-match semantics with priority ordering"
}
],
"deterministicProperties": {
"ruleOrderingAlgorithm": "stable-sort by (priority ASC, declaration-index ASC)",
"firstMatchSemantics": true,
"exceptionSpecificityWeights": {
"ruleNameBase": 1000,
"ruleNamePerItem": 25,
"severityBase": 500,
"severityPerItem": 10,
"sourceBase": 250,
"sourcePerItem": 10,
"tagBase": 100,
"tagPerItem": 5
},
"exceptionTieBreaker": "later CreatedAt wins, then lower Id lexicographically wins",
"numericType": "decimal",
"stringComparison": "OrdinalIgnoreCase"
}
}