audit, advisories and doctors/setup work

This commit is contained in:
master
2026-01-13 18:53:39 +02:00
parent 9ca7cb183e
commit d7be6ba34b
811 changed files with 54242 additions and 4056 deletions

View File

@@ -31,31 +31,31 @@
| 6 | AUDIT-HOTLIST-SCANNER-NATIVE-0001 | DONE | Applied 2026-01-13; tracker updated | Guild - Scanner | Remediate hotlist findings for `src/Scanner/StellaOps.Scanner.Analyzers.Native/StellaOps.Scanner.Analyzers.Native.csproj`; apply fixes, add tests, update audit tracker. |
| 7 | AUDIT-HOTLIST-SCANNER-WEBSERVICE-0001 | DONE | Applied 2026-01-13; Hotlist S2/M2/Q2 | Guild - Scanner | Remediate hotlist findings for `src/Scanner/StellaOps.Scanner.WebService/StellaOps.Scanner.WebService.csproj`; apply fixes, add tests, update audit tracker. |
| 8 | AUDIT-HOTLIST-EXPORTCENTER-CORE-0001 | DOING | In progress 2026-01-13; Hotlist S2/M2/Q1 | Guild - ExportCenter | Remediate hotlist findings for `src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Core/StellaOps.ExportCenter.Core.csproj`; apply fixes, add tests, update audit tracker. |
| 9 | AUDIT-HOTLIST-SIGNALS-0001 | TODO | Approved 2026-01-12; Hotlist S2/M2/Q1 | Guild - Signals | Remediate hotlist findings for `src/Signals/StellaOps.Signals/StellaOps.Signals.csproj`; apply fixes, add tests, update audit tracker. |
| 9 | AUDIT-HOTLIST-SIGNALS-0001 | DONE | Applied 2026-01-13; audit tracker updated | Guild - Signals | Remediate hotlist findings for `src/Signals/StellaOps.Signals/StellaOps.Signals.csproj`; apply fixes, add tests, update audit tracker. |
| 10 | AUDIT-HOTLIST-SCANNER-LANG-DENO-0001 | DONE | Applied 2026-01-13; runtime hardening, determinism fixes, tests updated | Guild - Scanner | Remediate hotlist findings for `src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Deno/StellaOps.Scanner.Analyzers.Lang.Deno.csproj`; apply fixes, add tests, update audit tracker. |
| 11 | AUDIT-HOTLIST-VEXLENS-0001 | TODO | Approved 2026-01-12; Hotlist S1/M4/Q0 | Guild - VexLens | Remediate hotlist findings for `src/VexLens/StellaOps.VexLens/StellaOps.VexLens.csproj`; apply fixes, add tests, update audit tracker. |
| 12 | AUDIT-HOTLIST-CONCELIER-CORE-0001 | TODO | Approved 2026-01-12; Hotlist S1/M3/Q2 | Guild - Concelier | Remediate hotlist findings for `src/Concelier/__Libraries/StellaOps.Concelier.Core/StellaOps.Concelier.Core.csproj`; apply fixes, add tests, update audit tracker. |
| 11 | AUDIT-HOTLIST-VEXLENS-0001 | DONE | Applied 2026-01-13; audit tracker updated | Guild - VexLens | Remediate hotlist findings for `src/VexLens/StellaOps.VexLens/StellaOps.VexLens.csproj`; apply fixes, add tests, update audit tracker. |
| 12 | AUDIT-HOTLIST-CONCELIER-CORE-0001 | DONE | Applied 2026-01-13; audit tracker updated | Guild - Concelier | Remediate hotlist findings for `src/Concelier/__Libraries/StellaOps.Concelier.Core/StellaOps.Concelier.Core.csproj`; apply fixes, add tests, update audit tracker. |
| 13 | AUDIT-HOTLIST-SCANNER-REACHABILITY-0001 | DONE | Applied 2026-01-13; tracker updated | Guild - Scanner | Remediate hotlist findings for `src/Scanner/__Libraries/StellaOps.Scanner.Reachability/StellaOps.Scanner.Reachability.csproj`; apply fixes, add tests, update audit tracker. |
| 14 | AUDIT-HOTLIST-EVIDENCE-0001 | DONE | Applied 2026-01-13 | Guild - Core | Remediate hotlist findings for `src/__Libraries/StellaOps.Evidence/StellaOps.Evidence.csproj`; apply fixes, add tests, update audit tracker. |
| 15 | AUDIT-HOTLIST-ZASTAVA-OBSERVER-0001 | TODO | Approved 2026-01-12; Hotlist S1/M3/Q0 | Guild - Zastava | Remediate hotlist findings for `src/Zastava/StellaOps.Zastava.Observer/StellaOps.Zastava.Observer.csproj`; apply fixes, add tests, update audit tracker. |
| 16 | AUDIT-HOTLIST-TESTKIT-0001 | TODO | Approved 2026-01-12; Hotlist S0/M4/Q1 | Guild - Core | Remediate hotlist findings for `src/__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj`; apply fixes, add tests, update audit tracker. |
| 17 | AUDIT-HOTLIST-EXCITITOR-WORKER-0001 | TODO | Approved 2026-01-12; Hotlist S0/M4/Q1 | Guild - Excititor | Remediate hotlist findings for `src/Excititor/StellaOps.Excititor.Worker/StellaOps.Excititor.Worker.csproj`; apply fixes, add tests, update audit tracker. |
| 18 | AUDIT-HOTLIST-SCANNER-WORKER-0001 | TODO | Approved 2026-01-12; Hotlist S0/M4/Q1 | Guild - Scanner | Remediate hotlist findings for `src/Scanner/StellaOps.Scanner.Worker/StellaOps.Scanner.Worker.csproj`; apply fixes, add tests, update audit tracker. |
| 19 | AUDIT-HOTLIST-ROUTER-MICROSERVICE-0001 | TODO | Approved 2026-01-12; Hotlist S0/M4/Q0 | Guild - Router | Remediate hotlist findings for `src/Router/__Libraries/StellaOps.Microservice/StellaOps.Microservice.csproj`; apply fixes, add tests, update audit tracker. |
| 20 | AUDIT-HOTLIST-CONCELIER-WEBSERVICE-0001 | TODO | Approved 2026-01-12; Hotlist S0/M3/Q2 | Guild - Concelier | Remediate hotlist findings for `src/Concelier/StellaOps.Concelier.WebService/StellaOps.Concelier.WebService.csproj`; apply fixes, add tests, update audit tracker. |
| 21 | AUDIT-HOTLIST-PROVCACHE-0001 | TODO | Approved 2026-01-12; Hotlist S0/M3/Q1 | Guild - Core | Remediate hotlist findings for `src/__Libraries/StellaOps.Provcache/StellaOps.Provcache.csproj`; apply fixes, add tests, update audit tracker. |
| 22 | AUDIT-HOTLIST-EXCITITOR-CORE-0001 | TODO | Approved 2026-01-12; Hotlist Q2/S1/M2 | Guild - Excititor | Remediate hotlist findings for `src/Excititor/__Libraries/StellaOps.Excititor.Core/StellaOps.Excititor.Core.csproj`; apply fixes, add tests, update audit tracker. |
| 23 | AUDIT-HOTLIST-SBOMSERVICE-0001 | TODO | Approved 2026-01-12; Hotlist Q2/S1/M2 | Guild - SbomService | Remediate hotlist findings for `src/SbomService/StellaOps.SbomService/StellaOps.SbomService.csproj`; apply fixes, add tests, update audit tracker. |
| 15 | AUDIT-HOTLIST-ZASTAVA-OBSERVER-0001 | DONE | Applied 2026-01-13; tests updated | Guild - Zastava | Remediate hotlist findings for `src/Zastava/StellaOps.Zastava.Observer/StellaOps.Zastava.Observer.csproj`; apply fixes, add tests, update audit tracker. |
| 16 | AUDIT-HOTLIST-TESTKIT-0001 | DONE | Applied 2026-01-13; tests updated | Guild - Core | Remediate hotlist findings for `src/__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj`; apply fixes, add tests, update audit tracker. |
| 17 | AUDIT-HOTLIST-EXCITITOR-WORKER-0001 | DONE | Applied 2026-01-13; determinism, DI, tests | Guild - Excititor | Remediate hotlist findings for `src/Excititor/StellaOps.Excititor.Worker/StellaOps.Excititor.Worker.csproj`; apply fixes, add tests, update audit tracker. |
| 18 | AUDIT-HOTLIST-SCANNER-WORKER-0001 | DONE | Applied 2026-01-13; determinism, cancellation, DSSE | Guild - Scanner | Remediate hotlist findings for `src/Scanner/StellaOps.Scanner.Worker/StellaOps.Scanner.Worker.csproj`; apply fixes, add tests, update audit tracker. |
| 19 | AUDIT-HOTLIST-ROUTER-MICROSERVICE-0001 | DONE | Applied 2026-01-13; tracker updated | Guild - Router | Remediate hotlist findings for `src/Router/__Libraries/StellaOps.Microservice/StellaOps.Microservice.csproj`; apply fixes, add tests, update audit tracker. |
| 20 | AUDIT-HOTLIST-CONCELIER-WEBSERVICE-0001 | DONE | Applied 2026-01-13; TimeProvider defaults, ASCII cleanup, federation tests | Guild - Concelier | Remediate hotlist findings for `src/Concelier/StellaOps.Concelier.WebService/StellaOps.Concelier.WebService.csproj`; apply fixes, add tests, update audit tracker. |
| 21 | AUDIT-HOTLIST-PROVCACHE-0001 | DONE | Applied 2026-01-13; audit tracker updated | Guild - Core | Remediate hotlist findings for `src/__Libraries/StellaOps.Provcache/StellaOps.Provcache.csproj`; apply fixes, add tests, update audit tracker. |
| 22 | AUDIT-HOTLIST-EXCITITOR-CORE-0001 | BLOCKED | Blocked 2026-01-13; Excititor.Core files modified by another agent | Guild - Excititor | Remediate hotlist findings for `src/Excititor/__Libraries/StellaOps.Excititor.Core/StellaOps.Excititor.Core.csproj`; apply fixes, add tests, update audit tracker. |
| 23 | AUDIT-HOTLIST-SBOMSERVICE-0001 | BLOCKED | Blocked 2026-01-13; SbomService files modified by another agent | Guild - SbomService | Remediate hotlist findings for `src/SbomService/StellaOps.SbomService/StellaOps.SbomService.csproj`; apply fixes, add tests, update audit tracker. |
| 24 | AUDIT-HOTLIST-SCANNER-SBOMER-BUILDX-0001 | DONE | Applied 2026-01-13; Hotlist Q2/S1/M2 | Guild - Scanner | Remediate hotlist findings for `src/Scanner/StellaOps.Scanner.Sbomer.BuildXPlugin/StellaOps.Scanner.Sbomer.BuildXPlugin.csproj`; apply fixes, add tests, update audit tracker. |
| 25 | AUDIT-HOTLIST-ATTESTOR-WEBSERVICE-0001 | TODO | Approved 2026-01-12; Hotlist Q2/S0/M2 | Guild - Attestor | Remediate hotlist findings for `src/Attestor/StellaOps.Attestor/StellaOps.Attestor.WebService/StellaOps.Attestor.WebService.csproj`; apply fixes, add tests, update audit tracker. |
| 26 | AUDIT-HOTLIST-POLICY-TOOLS-0001 | TODO | Approved 2026-01-12; Hotlist Q2/S0/M1 | Guild - Policy | Remediate hotlist findings for `src/__Libraries/StellaOps.Policy.Tools/StellaOps.Policy.Tools.csproj`; apply fixes, add tests, update audit tracker. |
| 27 | AUDIT-HOTLIST-SCANNER-SOURCES-0001 | TODO | Approved 2026-01-12; Hotlist Q2/S0/M1 | Guild - Scanner | Remediate hotlist findings for `src/Scanner/__Libraries/StellaOps.Scanner.Sources/StellaOps.Scanner.Sources.csproj`; apply fixes, add tests, update audit tracker. |
| 28 | AUDIT-HOTLIST-BINARYINDEX-GOLDENSET-0001 | TODO | Approved 2026-01-12; Hotlist Q2/S0/M0 | Guild - BinaryIndex | Remediate hotlist findings for `src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.GoldenSet/StellaOps.BinaryIndex.GoldenSet.csproj`; apply fixes, add tests, update audit tracker. |
| 29 | AUDIT-TESTGAP-DEVOPS-0001 | TODO | Approved 2026-01-12; Production Test Gap Inventory | Guild - DevOps | Add tests and references for:<br>`devops/services/crypto/sim-crypto-service/SimCryptoService.csproj`<br>`devops/services/crypto/sim-crypto-smoke/SimCryptoSmoke.csproj`<br>`devops/services/cryptopro/linux-csp-service/CryptoProLinuxApi.csproj`<br>`devops/tools/nuget-prime/nuget-prime.csproj`<br>`devops/tools/nuget-prime/nuget-prime-v9.csproj`. |
| 30 | AUDIT-TESTGAP-DOCS-0001 | TODO | Approved 2026-01-12; Production Test Gap Inventory | Guild - Docs | Add test scaffolding or formal waivers for:<br>`docs/dev/sdks/plugin-templates/StellaOps.Templates.csproj`<br>`docs/dev/sdks/plugin-templates/stellaops-plugin-connector/StellaOps.Plugin.MyConnector.csproj`<br>`docs/dev/sdks/plugin-templates/stellaops-plugin-scheduler/StellaOps.Plugin.MyJob.csproj`. |
| 25 | AUDIT-HOTLIST-ATTESTOR-WEBSERVICE-0001 | DONE | Applied 2026-01-13; feature gating + determinism + tests | Guild - Attestor | Remediate hotlist findings for `src/Attestor/StellaOps.Attestor/StellaOps.Attestor.WebService/StellaOps.Attestor.WebService.csproj`; apply fixes, add tests, update audit tracker. |
| 26 | AUDIT-HOTLIST-POLICY-TOOLS-0001 | DONE | Applied 2026-01-14; determinism + parsing guards + tests | Guild - Policy | Remediate hotlist findings for `src/__Libraries/StellaOps.Policy.Tools/StellaOps.Policy.Tools.csproj`; apply fixes, add tests, update audit tracker. |
| 27 | AUDIT-HOTLIST-SCANNER-SOURCES-0001 | DOING | Started 2026-01-14; Hotlist Q2/S0/M1 | Guild - Scanner | Remediate hotlist findings for `src/Scanner/__Libraries/StellaOps.Scanner.Sources/StellaOps.Scanner.Sources.csproj`; apply fixes, add tests, update audit tracker. |
| 28 | AUDIT-HOTLIST-BINARYINDEX-GOLDENSET-0001 | DONE | Applied 2026-01-13; tracker updated | Guild - BinaryIndex | Remediate hotlist findings for `src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.GoldenSet/StellaOps.BinaryIndex.GoldenSet.csproj`; apply fixes, add tests, update audit tracker. |
| 29 | AUDIT-TESTGAP-DEVOPS-0001 | DONE | Applied 2026-01-13; tests added | Guild - DevOps | Add tests and references for:<br>`devops/services/crypto/sim-crypto-service/SimCryptoService.csproj`<br>`devops/services/crypto/sim-crypto-smoke/SimCryptoSmoke.csproj`<br>`devops/services/cryptopro/linux-csp-service/CryptoProLinuxApi.csproj`<br>`devops/tools/nuget-prime/nuget-prime.csproj`<br>`devops/tools/nuget-prime/nuget-prime-v9.csproj`. |
| 30 | AUDIT-TESTGAP-DOCS-0001 | DONE | Applied 2026-01-13; template tests added, template package waived | Guild - Docs | Add test scaffolding or formal waivers for:<br>`docs/dev/sdks/plugin-templates/StellaOps.Templates.csproj`<br>`docs/dev/sdks/plugin-templates/stellaops-plugin-connector/StellaOps.Plugin.MyConnector.csproj`<br>`docs/dev/sdks/plugin-templates/stellaops-plugin-scheduler/StellaOps.Plugin.MyJob.csproj`. |
| 31 | AUDIT-TESTGAP-CRYPTO-0001 | TODO | Approved 2026-01-12; Production Test Gap Inventory | Guild - Cryptography | Add tests for:<br>`src/__Libraries/StellaOps.Cryptography.Plugin.Pkcs11Gost/StellaOps.Cryptography.Plugin.Pkcs11Gost.csproj`<br>`src/__Libraries/StellaOps.Cryptography.Plugin.WineCsp/StellaOps.Cryptography.Plugin.WineCsp.csproj`<br>`src/__Libraries/StellaOps.Cryptography.Providers.OfflineVerification/StellaOps.Cryptography.Providers.OfflineVerification.csproj`<br>`src/Cryptography/StellaOps.Cryptography.Plugin.Eidas/StellaOps.Cryptography.Plugin.Eidas.csproj`<br>`src/Cryptography/StellaOps.Cryptography.Plugin.Fips/StellaOps.Cryptography.Plugin.Fips.csproj`<br>`src/Cryptography/StellaOps.Cryptography.Plugin.Gost/StellaOps.Cryptography.Plugin.Gost.csproj`<br>`src/Cryptography/StellaOps.Cryptography.Plugin.Hsm/StellaOps.Cryptography.Plugin.Hsm.csproj`<br>`src/Cryptography/StellaOps.Cryptography.Plugin.Sm/StellaOps.Cryptography.Plugin.Sm.csproj`<br>`src/Cryptography/StellaOps.Cryptography.Plugin/StellaOps.Cryptography.Plugin.csproj`<br>`src/Cryptography/StellaOps.Cryptography.Profiles.Ecdsa/StellaOps.Cryptography.Profiles.Ecdsa.csproj`<br>`src/Cryptography/StellaOps.Cryptography.Profiles.EdDsa/StellaOps.Cryptography.Profiles.EdDsa.csproj`<br>`src/Cryptography/StellaOps.Cryptography/StellaOps.Cryptography.csproj`. |
| 32 | AUDIT-TESTGAP-CORELIB-0001 | TODO | Approved 2026-01-12; Production Test Gap Inventory | Guild - Core | Add tests for:<br>`src/__Libraries/StellaOps.Infrastructure.EfCore/StellaOps.Infrastructure.EfCore.csproj`<br>`src/__Libraries/StellaOps.Interop/StellaOps.Interop.csproj`<br>`src/__Libraries/StellaOps.Orchestrator.Schemas/StellaOps.Orchestrator.Schemas.csproj`<br>`src/__Libraries/StellaOps.Policy.Tools/StellaOps.Policy.Tools.csproj`<br>`src/__Libraries/StellaOps.PolicyAuthoritySignals.Contracts/StellaOps.PolicyAuthoritySignals.Contracts.csproj`<br>`src/__Libraries/StellaOps.Provcache.Postgres/StellaOps.Provcache.Postgres.csproj`<br>`src/__Libraries/StellaOps.Provcache.Valkey/StellaOps.Provcache.Valkey.csproj`<br>`src/__Libraries/StellaOps.ReachGraph.Cache/StellaOps.ReachGraph.Cache.csproj`<br>`src/__Libraries/StellaOps.ReachGraph.Persistence/StellaOps.ReachGraph.Persistence.csproj`<br>`src/__Libraries/StellaOps.Signals.Contracts/StellaOps.Signals.Contracts.csproj`. |
| 33 | AUDIT-TESTGAP-ADVISORYAI-0001 | TODO | Approved 2026-01-12; Production Test Gap Inventory | Guild - AdvisoryAI | Add tests for:<br>`src/AdvisoryAI/StellaOps.AdvisoryAI.Plugin.Unified/StellaOps.AdvisoryAI.Plugin.Unified.csproj`<br>`src/AdvisoryAI/StellaOps.AdvisoryAI.Scm.Plugin.Unified/StellaOps.AdvisoryAI.Scm.Plugin.Unified.csproj`<br>`src/AdvisoryAI/StellaOps.AdvisoryAI.Worker/StellaOps.AdvisoryAI.Worker.csproj`. |
| 33 | AUDIT-TESTGAP-ADVISORYAI-0001 | DONE | Applied 2026-01-14; tests + deterministic jitter source | Guild - AdvisoryAI | Add tests for:<br>`src/AdvisoryAI/StellaOps.AdvisoryAI.Plugin.Unified/StellaOps.AdvisoryAI.Plugin.Unified.csproj`<br>`src/AdvisoryAI/StellaOps.AdvisoryAI.Scm.Plugin.Unified/StellaOps.AdvisoryAI.Scm.Plugin.Unified.csproj`<br>`src/AdvisoryAI/StellaOps.AdvisoryAI.Worker/StellaOps.AdvisoryAI.Worker.csproj`. |
| 34 | AUDIT-TESTGAP-AUTH-CONCELIER-ATTESTOR-0001 | TODO | Approved 2026-01-12; Production Test Gap Inventory | Guild - Module Leads | Add tests for:<br>`src/Attestor/StellaOps.Attestor.Types/Tools/StellaOps.Attestor.Types.Generator/StellaOps.Attestor.Types.Generator.csproj`<br>`src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Unified/StellaOps.Authority.Plugin.Unified.csproj`<br>`src/Concelier/__Libraries/StellaOps.Concelier.ProofService/StellaOps.Concelier.ProofService.csproj`<br>`src/Concelier/StellaOps.Concelier.Plugin.Unified/StellaOps.Concelier.Plugin.Unified.csproj`. |
| 35 | AUDIT-TESTGAP-SERVICES-CORE-0001 | TODO | Approved 2026-01-12; Production Test Gap Inventory | Guild - Platform Services | Add tests for:<br>`src/EvidenceLocker/StellaOps.EvidenceLocker/StellaOps.EvidenceLocker.csproj`<br>`src/EvidenceLocker/StellaOps.EvidenceLocker/StellaOps.EvidenceLocker.Worker/StellaOps.EvidenceLocker.Worker.csproj`<br>`src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Worker/StellaOps.ExportCenter.Worker.csproj`<br>`src/Feedser/StellaOps.Feedser.BinaryAnalysis/StellaOps.Feedser.BinaryAnalysis.csproj`<br>`src/IssuerDirectory/StellaOps.IssuerDirectory/StellaOps.IssuerDirectory.Infrastructure/StellaOps.IssuerDirectory.Infrastructure.csproj`<br>`src/IssuerDirectory/StellaOps.IssuerDirectory/StellaOps.IssuerDirectory.WebService/StellaOps.IssuerDirectory.WebService.csproj`<br>`src/Notify/__Libraries/StellaOps.Notify.Storage.InMemory/StellaOps.Notify.Storage.InMemory.csproj`<br>`src/OpsMemory/StellaOps.OpsMemory.WebService/StellaOps.OpsMemory.WebService.csproj`<br>`src/Orchestrator/StellaOps.Orchestrator/StellaOps.Orchestrator.Worker/StellaOps.Orchestrator.Worker.csproj`<br>`src/PacksRegistry/StellaOps.PacksRegistry/StellaOps.PacksRegistry.Persistence.EfCore/StellaOps.PacksRegistry.Persistence.EfCore.csproj`<br>`src/PacksRegistry/StellaOps.PacksRegistry/StellaOps.PacksRegistry.Worker/StellaOps.PacksRegistry.Worker.csproj`. |
| 36 | AUDIT-TESTGAP-SERVICES-PLATFORM-0001 | TODO | Approved 2026-01-12; Production Test Gap Inventory | Guild - Platform Services | Add tests for:<br>`src/Policy/__Libraries/StellaOps.Policy.AuthSignals/StellaOps.Policy.AuthSignals.csproj`<br>`src/Policy/__Libraries/StellaOps.Policy.Explainability/StellaOps.Policy.Explainability.csproj`<br>`src/Policy/StellaOps.Policy.Registry/StellaOps.Policy.Registry.csproj`<br>`src/RiskEngine/StellaOps.RiskEngine/StellaOps.RiskEngine.Worker/StellaOps.RiskEngine.Worker.csproj`<br>`src/Scheduler/StellaOps.Scheduler.Worker.Host/StellaOps.Scheduler.Worker.Host.csproj`<br>`src/Signals/StellaOps.Signals.Scheduler/StellaOps.Signals.Scheduler.csproj`<br>`src/TaskRunner/StellaOps.TaskRunner/StellaOps.TaskRunner.Worker/StellaOps.TaskRunner.Worker.csproj`<br>`src/TimelineIndexer/StellaOps.TimelineIndexer/StellaOps.TimelineIndexer.WebService/StellaOps.TimelineIndexer.WebService.csproj`<br>`src/Unknowns/__Libraries/StellaOps.Unknowns.Persistence.EfCore/StellaOps.Unknowns.Persistence.EfCore.csproj`<br>`src/VexHub/__Libraries/StellaOps.VexHub.Persistence/StellaOps.VexHub.Persistence.csproj`<br>`src/VexLens/StellaOps.VexLens.Persistence/StellaOps.VexLens.Persistence.csproj`<br>`src/VexLens/StellaOps.VexLens.WebService/StellaOps.VexLens.WebService.csproj`. |
@@ -117,6 +117,34 @@
| 2026-01-13 | Started AUDIT-HOTLIST-EVIDENCE-0001 remediation work. | Project Mgmt |
| 2026-01-13 | Completed AUDIT-HOTLIST-EVIDENCE-0001 (determinism, schema validation, budgets, retention, tests). | Project Mgmt |
| 2026-01-13 | Started AUDIT-HOTLIST-EXPORTCENTER-CORE-0001 remediation work. | Project Mgmt |
| 2026-01-13 | Completed AUDIT-HOTLIST-CONCELIER-CORE-0001; determinism fixes and tests applied; audit trackers updated. | Project Mgmt |
| 2026-01-13 | Completed AUDIT-HOTLIST-SIGNALS-0001; revalidated fixes already in code, audit trackers updated. | Project Mgmt |
| 2026-01-13 | Completed AUDIT-HOTLIST-VEXLENS-0001; determinism defaults and tracker updates applied. | Project Mgmt |
| 2026-01-13 | Started AUDIT-HOTLIST-ZASTAVA-OBSERVER-0001 remediation work. | Project Mgmt |
| 2026-01-13 | Completed AUDIT-HOTLIST-ZASTAVA-OBSERVER-0001; TimeProvider retry-after, explicit timestamps, ASCII truncation, HttpClient injection, tests added, audit trackers updated. | Project Mgmt |
| 2026-01-13 | Started AUDIT-HOTLIST-TESTKIT-0001 remediation work. | Project Mgmt |
| 2026-01-13 | Completed AUDIT-HOTLIST-TESTKIT-0001; HttpClientFactory fixtures, TimeProvider request timestamps, ASCII cleanup, deterministic random, Task.Run removal, sync-over-async removal, tests added, audit trackers updated. | Project Mgmt |
| 2026-01-13 | Started AUDIT-HOTLIST-EXCITITOR-WORKER-0001 remediation work. | Project Mgmt |
| 2026-01-13 | Completed AUDIT-HOTLIST-EXCITITOR-WORKER-0001; determinism/DI fixes, plugin diagnostics, deterministic jitter/IDs, tests added; audit trackers updated. | Project Mgmt |
| 2026-01-13 | Completed AUDIT-HOTLIST-ROUTER-MICROSERVICE-0001; headers, request dispatch, schema direction, options validation, YAML parsing diagnostics, tests, and audit trackers updated. | Project Mgmt |
| 2026-01-13 | Completed AUDIT-HOTLIST-CONCELIER-WEBSERVICE-0001; TimeProvider defaults, ASCII cleanup, federation endpoint tests, audit trackers updated. | Project Mgmt |
| 2026-01-13 | Completed AUDIT-HOTLIST-BINARYINDEX-GOLDENSET-0001; newline determinism, TODO cleanup, and review workflow tests updated. | Project Mgmt |
| 2026-01-13 | Completed AUDIT-HOTLIST-SCANNER-WORKER-0001; determinism/cancellation, DSSE canon, test fixes; updated audit trackers and TASKS.md. | Project Mgmt |
| 2026-01-13 | Completed AUDIT-HOTLIST-PROVCACHE-0001; lazy fetch allowlist/timeout enforcement, canonical JSON signing, signature verification, options validation, and tests; audit trackers updated. | Project Mgmt |
| 2026-01-13 | Started AUDIT-TESTGAP-DEVOPS-0001 (devops service/tool test scaffolding). | Implementer |
| 2026-01-13 | Completed AUDIT-TESTGAP-DEVOPS-0001; added devops tests, AGENTS, and package versions. Tests: `dotnet test devops/services/crypto/sim-crypto-service/__Tests/SimCryptoService.Tests/SimCryptoService.Tests.csproj`, `dotnet test devops/services/crypto/sim-crypto-smoke/__Tests/SimCryptoSmoke.Tests/SimCryptoSmoke.Tests.csproj`, `dotnet test devops/services/cryptopro/linux-csp-service/__Tests/CryptoProLinuxApi.Tests/CryptoProLinuxApi.Tests.csproj`, `dotnet test devops/tools/nuget-prime/__Tests/NugetPrime.Tests/NugetPrime.Tests.csproj`. | Implementer |
| 2026-01-13 | Started AUDIT-TESTGAP-DOCS-0001 (plugin template test scaffolding). | Implementer |
| 2026-01-13 | Completed AUDIT-TESTGAP-DOCS-0001; added plugin template tests, waived template package, updated audit tracker. Tests: `dotnet test docs/dev/sdks/plugin-templates/stellaops-plugin-connector/__Tests/StellaOps.Plugin.MyConnector.Tests/StellaOps.Plugin.MyConnector.Tests.csproj`, `dotnet test docs/dev/sdks/plugin-templates/stellaops-plugin-scheduler/__Tests/StellaOps.Plugin.MyJob.Tests/StellaOps.Plugin.MyJob.Tests.csproj` (failed: template project references not present in repo). | Implementer |
| 2026-01-13 | Re-ran template tests after updating ProjectReference paths, package versions, and connector interface usage. Tests: `dotnet test docs/dev/sdks/plugin-templates/stellaops-plugin-connector/__Tests/StellaOps.Plugin.MyConnector.Tests/StellaOps.Plugin.MyConnector.Tests.csproj`, `dotnet test docs/dev/sdks/plugin-templates/stellaops-plugin-scheduler/__Tests/StellaOps.Plugin.MyJob.Tests/StellaOps.Plugin.MyJob.Tests.csproj`. | Implementer |
| 2026-01-13 | Blocked AUDIT-HOTLIST-EXCITITOR-CORE-0001; Excititor.Core files already modified by another agent. | Project Mgmt |
| 2026-01-13 | Blocked AUDIT-HOTLIST-SBOMSERVICE-0001; SbomService files already modified by another agent. | Project Mgmt |
| 2026-01-13 | Completed AUDIT-HOTLIST-ATTESTOR-WEBSERVICE-0001; feature gating filter, correlation ID provider, proof chain/verification summary fixes, tests updated. | Project Mgmt |
| 2026-01-13 | Started AUDIT-TESTGAP-ADVISORYAI-0001 (plugin/unified + worker tests, deterministic jitter source). | AdvisoryAI |
| 2026-01-14 | Completed AUDIT-TESTGAP-ADVISORYAI-0001; added adapter tests, worker cache tests, jitter source injection, and updated audit trackers. | AdvisoryAI |
| 2026-01-14 | Tests: `dotnet test src/AdvisoryAI/__Tests/StellaOps.AdvisoryAI.Tests/StellaOps.AdvisoryAI.Tests.csproj`. | AdvisoryAI |
| 2026-01-14 | Started AUDIT-HOTLIST-POLICY-TOOLS-0001 remediation work. | Project Mgmt |
| 2026-01-14 | Completed AUDIT-HOTLIST-POLICY-TOOLS-0001; LF schema output, fixed-time default, parsing guards, deterministic summary output, cancellation propagation, tests added. | Project Mgmt |
| 2026-01-14 | Started AUDIT-HOTLIST-SCANNER-SOURCES-0001 remediation work. | Project Mgmt |
## Decisions & Risks
- APPROVED 2026-01-12: All pending APPLY actions are approved for execution under module review gates.
@@ -125,6 +153,8 @@
- Backlog size (851 TODO APPLY items); mitigate by prioritizing hotlists then long-tail batches.
- Devops and docs items are in scope; cross-directory changes must be logged per sprint guidance.
- BLOCKED: AUDIT-HOTLIST-CLI-0001 requires edits in `src/Cli/__Tests/StellaOps.Cli.Tests` which are under active modification by another agent; defer until those changes land or ownership is coordinated.
- BLOCKED: AUDIT-HOTLIST-EXCITITOR-CORE-0001 is blocked because `src/Excititor/__Libraries/StellaOps.Excititor.Core` is under active modification by another agent.
- BLOCKED: AUDIT-HOTLIST-SBOMSERVICE-0001 is blocked because `src/SbomService/StellaOps.SbomService` is under active modification by another agent.
## Next Checkpoints
- TBD: Security hotlist remediation review.

View File

@@ -1,7 +1,12 @@
# Master Index 20260113 - OCI Layer-Level Binary Integrity Verification
# Sprint 20260113_000 - Master Index - OCI Binary Integrity
## Executive Summary
## Topic & Scope
- Coordinate four sprint batches implementing OCI layer-level image integrity verification with binary patch detection and evidence linking.
- Align Scanner, Attestor, Excititor, CLI, and Tools deliverables for DSSE attestations, VEX links, and validation corpus coverage.
- Provide a 25-30 point, 13-sprint plan with dependencies, metrics, and datasets for evidence-first security.
- **Working directory:** `docs/implplan`.
### Executive Summary
This master index coordinates four sprint batches implementing **OCI layer-level image integrity verification** with binary patch detection capabilities. The complete feature set enables:
1. **Multi-arch image inspection** with layer enumeration
@@ -13,10 +18,8 @@ This master index coordinates four sprint batches implementing **OCI layer-level
**Total Effort:** ~25-30 story points across 4 batches, 13 sprints
**Priority:** High (core differentiator for evidence-first security)
## Background
### Advisory Origin
### Background
#### Advisory Origin
The original product advisory specified requirements for:
> OCI layer-level image integrity verification that:
@@ -26,7 +29,7 @@ The original product advisory specified requirements for:
> - Maps findings to VEX with cryptographic evidence links
> - Validates against a curated "golden pairs" corpus
### Strategic Value
#### Strategic Value
| Capability | Business Value |
|------------|----------------|
@@ -35,19 +38,18 @@ The original product advisory specified requirements for:
| VEX evidence links | Deterministic, reproducible security decisions |
| Golden pairs validation | Confidence in detection accuracy |
## Sprint Batch Index
### Sprint Batch Index
| Batch | ID | Topic | Sprints | Status | Priority |
|-------|-----|-------|---------|--------|----------|
| 1 | 20260113_001 | ELF Section Hashes & Binary Diff Attestation | 4 | TODO | P0 |
| 2 | 20260113_002 | Image Index Resolution CLI | 3 | TODO | P1 |
| 3 | 20260113_003 | VEX Evidence Auto-Linking | 2 | TODO | P1 |
| 4 | 20260113_004 | Golden Pairs Pilot (Vendor Backport Corpus) | 3 | TODO | P2 |
| 1 | 20260113_001 | ELF Section Hashes and Binary Diff Attestation | 4 | DOING | P0 |
| 2 | 20260113_002 | Image Index Resolution CLI | 3 | DONE | P1 |
| 3 | 20260113_003 | VEX Evidence Auto-Linking | 2 | DONE | P1 |
| 4 | 20260113_004 | Golden Pairs Pilot (Vendor Backport Corpus) | 3 | BLOCKED | P2 |
## Batch Details
### Batch 001: ELF Section Hashes & Binary Diff Attestation
### Batch Details
#### Batch 001: ELF Section Hashes and Binary Diff Attestation
**Index:** [SPRINT_20260113_001_000_INDEX_binary_diff_attestation.md](SPRINT_20260113_001_000_INDEX_binary_diff_attestation.md)
**Scope:** Core binary analysis infrastructure
@@ -64,8 +66,7 @@ The original product advisory specified requirements for:
- `BinaryDiffV1` - In-toto predicate for diff attestations
- `SectionDelta` - Section comparison result
### Batch 002: Image Index Resolution CLI
#### Batch 002: Image Index Resolution CLI
**Index:** [SPRINT_20260113_002_000_INDEX_image_index_resolution.md](SPRINT_20260113_002_000_INDEX_image_index_resolution.md)
**Scope:** Multi-arch image inspection and layer enumeration
@@ -81,8 +82,7 @@ The original product advisory specified requirements for:
- `PlatformManifest` - Per-platform manifest info
- `LayerInfo` - Layer digest, size, media type
### Batch 003: VEX Evidence Auto-Linking
#### Batch 003: VEX Evidence Auto-Linking
**Index:** [SPRINT_20260113_003_000_INDEX_vex_evidence_linking.md](SPRINT_20260113_003_000_INDEX_vex_evidence_linking.md)
**Scope:** Automatic linking of VEX entries to binary diff evidence
@@ -96,8 +96,7 @@ The original product advisory specified requirements for:
- `VexEvidenceLink` - Link to evidence attestation
- `VexEvidenceLinkSet` - Multi-evidence aggregation
### Batch 004: Golden Pairs Pilot
#### Batch 004: Golden Pairs Pilot
**Index:** [SPRINT_20260113_004_000_INDEX_golden_pairs_pilot.md](SPRINT_20260113_004_000_INDEX_golden_pairs_pilot.md)
**Scope:** Validation dataset for binary patch detection
@@ -105,7 +104,7 @@ The original product advisory specified requirements for:
| Sprint | ID | Module | Topic | Key Deliverables |
|--------|-----|--------|-------|------------------|
| 1 | 004_001 | TOOLS | Golden Pairs Data Model | `GoldenPairMetadata`, JSON schema |
| 2 | 004_002 | TOOLS | Mirror & Diff Pipeline | Package mirror, diff validation |
| 2 | 004_002 | TOOLS | Mirror and Diff Pipeline | Package mirror, diff validation |
| 3 | 004_003 | TOOLS | Pilot CVE Corpus (3 CVEs) | Dirty Pipe, Baron Samedit, PrintNightmare |
**Target CVEs:**
@@ -113,45 +112,9 @@ The original product advisory specified requirements for:
- CVE-2021-3156 (Baron Samedit) - sudo
- CVE-2021-34527 (PrintNightmare) - Windows PE (conditional)
## Dependency Graph
```
+-----------------------------------------------------------------------------------+
| DEPENDENCY FLOW |
+-----------------------------------------------------------------------------------+
| |
| BATCH 001: Binary Diff Attestation |
| +------------------------------------------------------------------+ |
| | Sprint 001 (ELF Hashes) --> Sprint 002 (Predicate) --> Sprint 003 (CLI) |
| +------------------------------------------------------------------+ |
| | | |
| v v |
| BATCH 002: Image Index Resolution | |
| +--------------------------------+ | |
| | Sprint 001 --> Sprint 002 (CLI)| | |
| +--------------------------------+ | |
| | | |
| v v |
| BATCH 003: VEX Evidence Linking <------+ |
| +--------------------------------+ |
| | Sprint 001 (Linker) --> Sprint 002 (CLI) |
| +--------------------------------+ |
| |
| BATCH 004: Golden Pairs (Validation) - Can start in parallel with Batch 001 |
| +------------------------------------------------------------------+ |
| | Sprint 001 (Model) --> Sprint 002 (Pipeline) --> Sprint 003 (Corpus) |
| +------------------------------------------------------------------+ |
| | |
| v |
| Uses Batch 001 Sprint 001 (ELF Hashes) for validation |
| |
+-----------------------------------------------------------------------------------+
```
## Cross-Cutting Concerns
### Determinism Requirements
### Cross-Cutting Concerns
#### Determinism Requirements
All components must follow CLAUDE.md Section 8 determinism rules:
| Requirement | Implementation |
@@ -162,7 +125,7 @@ All components must follow CLAUDE.md Section 8 determinism rules:
| JSON | RFC 8785 canonical encoding for hashing |
| Hashes | SHA-256 lowercase hex, no prefix |
### DSSE/In-Toto Standards
#### DSSE and In-Toto Standards
| Standard | Version | Usage |
|----------|---------|-------|
@@ -171,7 +134,7 @@ All components must follow CLAUDE.md Section 8 determinism rules:
| BinaryDiffV1 | 1.0.0 | Custom predicate for binary diff attestations |
| Rekor | v1 | Optional transparency log integration |
### Test Requirements
#### Test Requirements
| Category | Coverage |
|----------|----------|
@@ -180,9 +143,9 @@ All components must follow CLAUDE.md Section 8 determinism rules:
| Determinism | Identical inputs produce identical outputs |
| Golden | Validation against known-good corpus |
## File Manifest
### File Manifest
### Sprint Files
#### Sprint Files
```
docs/implplan/
@@ -213,7 +176,7 @@ docs/implplan/
+-- SPRINT_20260113_004_003_TOOLS_pilot_corpus.md
```
### Schema Files
#### Schema Files
```
docs/schemas/
@@ -222,7 +185,7 @@ docs/schemas/
+-- golden-pairs-index.schema.json # Corpus index (Batch 004)
```
### Source Directories
#### Source Directories
```
src/
@@ -255,9 +218,9 @@ datasets/
+-- CVE-2021-3156/
```
## Success Metrics
### Success Metrics
### Functional Metrics
#### Functional Metrics
| Metric | Target |
|--------|--------|
@@ -266,7 +229,7 @@ datasets/
| Attestation verification | 100% pass Rekor/in-toto validation |
| VEX evidence link coverage | >= 90% of applicable entries |
### Performance Metrics
#### Performance Metrics
| Metric | Target |
|--------|--------|
@@ -274,7 +237,7 @@ datasets/
| Binary diff comparison | < 500ms per pair |
| Image index resolution | < 2s for multi-arch images |
## Risk Register
### Risk Register
| Risk | Likelihood | Impact | Mitigation |
|------|------------|--------|------------|
@@ -283,9 +246,9 @@ datasets/
| Package archive availability | Medium | High | Cache packages locally |
| Cross-platform DSSE signing | Low | Medium | Use portable signing libraries |
## Execution Schedule
### Execution Schedule
### Recommended Order
#### Recommended Order
1. **Week 1-2:** Batch 001 Sprints 1-2 (ELF hashes, predicate)
2. **Week 2-3:** Batch 002 Sprint 1 (image inspector) + Batch 004 Sprint 1 (data model)
@@ -293,22 +256,77 @@ datasets/
4. **Week 4-5:** Batch 003 (VEX linking) + Batch 004 Sprint 2 (pipeline)
5. **Week 5-6:** Documentation sprints + Batch 004 Sprint 3 (corpus)
### Parallelization Opportunities
#### Parallelization Opportunities
- Batch 004 Sprint 1 can start immediately (no dependencies)
- Documentation sprints can run in parallel with implementation
- Batch 002 Sprint 1 can start after Batch 001 Sprint 1
## Execution Log
## Dependencies & Concurrency
- Batch dependencies are captured in the batch index files; Batch 001 Sprint 001 is the earliest gating sprint.
- Batch 004 can start in parallel with Batch 001; documentation sprints can run in parallel with implementation work.
- Other 20260113_000 planning documents are index-only, so parallel edits remain safe.
```
+-----------------------------------------------------------------------------------+
| DEPENDENCY FLOW |
+-----------------------------------------------------------------------------------+
| |
| BATCH 001: Binary Diff Attestation |
| +------------------------------------------------------------------+ |
| | Sprint 001 (ELF Hashes) -> Sprint 002 (Predicate) -> Sprint 003 (CLI) |
| +------------------------------------------------------------------+ |
| | | |
| v v |
| BATCH 002: Image Index Resolution | |
| +--------------------------------+ | |
| | Sprint 001 -> Sprint 002 (CLI) | | |
| +--------------------------------+ | |
| | | |
| v v |
| BATCH 003: VEX Evidence Linking <------+ |
| +--------------------------------+ |
| | Sprint 001 (Linker) -> Sprint 002 (CLI) |
| +--------------------------------+ |
| |
| BATCH 004: Golden Pairs (Validation) - Can start in parallel with Batch 001 |
| +------------------------------------------------------------------+ |
| | Sprint 001 (Model) -> Sprint 002 (Pipeline) -> Sprint 003 (Corpus) |
| +------------------------------------------------------------------+ |
| | |
| v |
| Uses Batch 001 Sprint 001 (ELF Hashes) for validation |
| |
+-----------------------------------------------------------------------------------+
```
## Documentation Prerequisites
- `docs/README.md`
- `docs/07_HIGH_LEVEL_ARCHITECTURE.md`
- `docs/modules/platform/architecture-overview.md`
- `docs/modules/scanner/architecture.md`
- `docs/modules/attestor/architecture.md`
- `docs/modules/cli/architecture.md`
- `docs/modules/excititor/architecture.md`
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 1 | INDEX-20260113-000-01 | DONE | None | Project Mgmt | Normalize master index to standard sprint template and ASCII-only formatting. |
| 2 | INDEX-20260113-000-02 | DONE | None | Project Mgmt | Verify batch index links and file manifest entries remain consistent. |
## Execution Log
| Date (UTC) | Update | Owner |
|------------|--------|-------|
| --- | --- | --- |
| 2026-01-13 | Master index created from product advisory analysis. | Project Mgmt |
| 2026-01-13 | Batch 001 INDEX already existed; added to master index. | Project Mgmt |
| 2026-01-13 | Batches 002, 003, 004 sprint files created. | Project Mgmt |
| 2026-01-13 | Normalized sprint file to standard template; ASCII-only cleanup; no semantic changes. | Project Mgmt |
| 2026-01-13 | Batch 001 CLI and Docs sprints completed; remaining batch work in progress. | CLI + Docs |
| 2026-01-13 | Batch 002 sprints completed (image inspection service, CLI, docs). | Scanner + CLI + Docs |
| 2026-01-13 | Batch 003 completed; Batch 004 data model and pipeline done; pilot corpus blocked. | Excititor + CLI + Tools |
## Decisions & Risks
- **APPROVED 2026-01-13**: Four-batch structure covering full advisory scope.
- **APPROVED 2026-01-13**: ELF-first approach; PE support conditional on Batch 001 progress.
- **APPROVED 2026-01-13**: Golden pairs stored in datasets/, not git LFS initially.
@@ -317,7 +335,6 @@ datasets/
- **RISK**: Kernel binaries are large; may need to extract specific modules.
## Next Checkpoints
- Batch 001 complete -> Core binary diff infrastructure operational
- Batch 002 complete -> Multi-arch image inspection available
- Batch 003 complete -> VEX entries include evidence links
@@ -325,7 +342,6 @@ datasets/
- All batches complete -> Full OCI layer-level integrity verification operational
## References
- [OCI Image Index Specification](https://github.com/opencontainers/image-spec/blob/main/image-index.md)
- [DSSE Specification](https://github.com/secure-systems-lab/dsse)
- [In-Toto Attestation Framework](https://github.com/in-toto/attestation)

View File

@@ -1,174 +0,0 @@
# Sprint Batch 20260113_001 - Binary Diff Attestation (ELF Section Hashes)
## Executive Summary
This sprint batch implements **targeted enhancements** for binary-level image integrity verification, focusing on ELF section-level hashing for vendor backport detection and DSSE-signed attestations for binary diffs. This addresses the genuine gaps identified in the OCI Layer-Level Image Integrity advisory analysis while avoiding redundant work on already-implemented capabilities.
**Scope:** ELF-only (PE/Mach-O deferred to M2+)
**Effort Estimate:** 5-7 story points across 4 sprints
**Priority:** Medium (enhancement, not blocking)
## Background
### Advisory Analysis Summary
The original product advisory proposed comprehensive OCI layer-level verification capabilities. Analysis revealed:
| Category | Coverage |
|----------|----------|
| **Already Implemented** | ~80% (OCI manifest parsing, layer SBOM fragmentation, DSSE pipeline, VEX emission) |
| **Partial Overlap** | ~15% (ELF symbols exist, section hashes missing) |
| **Genuine Gaps** | ~5% (section hashes, BinaryDiffV1 predicate, CLI diff verb) |
This batch addresses only the genuine gaps to maximize value while avoiding redundant effort.
### Existing Capabilities (No Work Needed)
- OCI manifest/index parsing with Docker & OCI media types
- Per-layer SBOM fragmentation with three-way diff
- DSSE envelope creation → Attestor → Rekor pipeline
- VEX emission with trust scoring and evidence links
- ELF Build-ID, symbol table parsing, link graph analysis
### New Capabilities (This Batch)
1. **ELF Section Hash Extractor** - SHA-256 per `.text`, `.rodata`, `.data`, `.symtab` sections
2. **BinaryDiffV1 In-Toto Predicate** - Schema for binary-level diff attestations
3. **CLI `stella scan diff --mode=elf`** - Binary-section-level diff with DSSE output
4. **Documentation** - Architecture docs and CLI reference updates
## Sprint Index
| Sprint | ID | Module | Topic | Status | Owner |
|--------|-----|--------|-------|--------|-------|
| 1 | SPRINT_20260113_001_001 | SCANNER | ELF Section Hash Extractor | TODO | Guild - Scanner |
| 2 | SPRINT_20260113_001_002 | ATTESTOR | BinaryDiffV1 In-Toto Predicate | TODO | Guild - Attestor |
| 3 | SPRINT_20260113_001_003 | CLI | Binary Diff Command Enhancement | TODO | Guild - CLI |
| 4 | SPRINT_20260113_001_004 | DOCS | Documentation & Architecture | TODO | Guild - Docs |
## Dependencies
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ Dependency Graph │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Sprint 1 (ELF Section Hashes) │
│ │ │
│ ├──────────────────┐ │
│ ▼ ▼ │
│ Sprint 2 (Predicate) Sprint 4 (Docs) │
│ │ │ │
│ ▼ │ │
│ Sprint 3 (CLI) ─────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```
- **Sprint 1** is foundational (no dependencies)
- **Sprint 2** depends on Sprint 1 (uses section hash models)
- **Sprint 3** depends on Sprint 1 & 2 (consumes extractor and predicate)
- **Sprint 4** can proceed in parallel with Sprints 2-3
## Acceptance Criteria (Batch-Level)
### Must Have
1. **Section Hash Extraction**
- Compute SHA-256 for `.text`, `.rodata`, `.data`, `.symtab` ELF sections
- Deterministic output (stable ordering, canonical JSON)
- Evidence properties in SBOM components
2. **BinaryDiffV1 Predicate**
- In-toto compliant predicate schema
- Subjects: image@digest, platform
- Inputs: base/target manifests
- Findings: per-path section deltas
3. **CLI Integration**
- `stella scan diff --mode=elf` produces binary-section-level diff
- `--emit-dsse=<dir>` outputs signed attestations
- Human-readable and JSON output formats
4. **Documentation**
- Architecture doc under `docs/modules/scanner/`
- CLI reference updates
- Predicate schema specification
### Should Have
- Confidence scoring for section hash matches (0.0-1.0)
- Integration with existing VEX evidence blocks
### Deferred (Out of Scope)
- PE/Mach-O section analysis (M2)
- Vendor backport corpus and 95% precision target (follow-up sprint)
- `ctr images export` integration (use existing OCI blob pull)
- Multi-platform diff in single invocation
## Technical Context
### Key Files to Extend
| Component | File | Purpose |
|-----------|------|---------|
| ELF Analysis | `src/Scanner/StellaOps.Scanner.Analyzers.Native/Hardening/ElfHardeningExtractor.cs` | Add section hash extraction |
| Native Models | `src/Scanner/__Libraries/StellaOps.Scanner.Contracts/CallGraphModels.cs` | Section hash models |
| DSSE Signing | `src/Scanner/__Libraries/StellaOps.Scanner.Reachability/Witnesses/WitnessDsseSigner.cs` | Pattern for BinaryDiffSigner |
| Predicates | `src/Attestor/__Libraries/StellaOps.Attestor.StandardPredicates/` | Add BinaryDiffV1 |
| CLI | `src/Cli/StellaOps.Cli/Commands/` | Add diff subcommand |
### Determinism Requirements
Per CLAUDE.md Section 8:
1. **TimeProvider injection** - No `DateTime.UtcNow` calls
2. **Stable ordering** - Section hashes sorted by section name
3. **Canonical JSON** - RFC 8785 for digest computation
4. **InvariantCulture** - All formatting/parsing
5. **DSSE PAE compliance** - Use shared `DsseHelper`
## Risk Assessment
| Risk | Likelihood | Impact | Mitigation |
|------|------------|--------|------------|
| Section hash instability across compilers | Medium | High | Document compiler/flag assumptions; use position-independent matching as fallback |
| ELF parsing edge cases | Low | Medium | Comprehensive test fixtures; existing ELF library handles most cases |
| CLI integration conflicts | Low | Low | CLI tests blocked by other agent; coordinate ownership |
## Success Metrics
- [ ] All unit tests pass (100% of new code covered)
- [ ] Integration tests with synthetic ELF fixtures pass
- [ ] CLI help and completions work
- [ ] Documentation builds without warnings
- [ ] No regressions in existing Scanner tests
## Documentation Prerequisites
Before starting implementation, reviewers must read:
- `docs/README.md`
- `docs/ARCHITECTURE_REFERENCE.md`
- `docs/modules/scanner/architecture.md` (if exists)
- `CLAUDE.md` Section 8 (Code Quality & Determinism Rules)
- `src/Scanner/StellaOps.Scanner.Analyzers.Native/AGENTS.md` (if exists)
## Execution Log
| Date (UTC) | Update | Owner |
|------------|--------|-------|
| 2026-01-13 | Sprint batch created from advisory analysis; 4 sprints defined. | Project Mgmt |
## Decisions & Risks
- **APPROVED 2026-01-13**: Scope limited to ELF-only; PE/Mach-O deferred to M2.
- **APPROVED 2026-01-13**: 80% precision target for initial release; 95% deferred to corpus sprint.
- **RISK**: CLI tests currently blocked by other agent work; Sprint 3 may need coordination.
## Next Checkpoints
- Sprint 1 completion → Sprint 2 & 4 can start
- Sprint 2 completion → Sprint 3 can start
- All sprints complete → Integration testing checkpoint

View File

@@ -1,234 +0,0 @@
# Sprint 20260113_001_001_SCANNER - ELF Section Hash Extractor
## Topic & Scope
- Implement per-section SHA-256 hash extraction for ELF binaries
- Target sections: `.text`, `.rodata`, `.data`, `.symtab`, `.dynsym`
- Integrate with existing `ElfHardeningExtractor` infrastructure
- Expose section hashes as SBOM component evidence properties
- **Working directory:** `src/Scanner/StellaOps.Scanner.Analyzers.Native/`
## Dependencies & Concurrency
- No blocking dependencies (foundational sprint)
- Parallel work safe within Scanner.Native module
- Sprint 2 (BinaryDiffV1 predicate) depends on this sprint's models
## Documentation Prerequisites
- `docs/README.md`
- `docs/ARCHITECTURE_REFERENCE.md`
- `CLAUDE.md` Section 8 (Determinism Rules)
- `src/Scanner/StellaOps.Scanner.Analyzers.Native/AGENTS.md` (if exists)
- ELF specification reference (https://refspecs.linuxfoundation.org/elf/elf.pdf)
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
|---|---------|--------|---------------------------|--------|-----------------|
| 1 | ELF-SECTION-MODELS-0001 | TODO | None | Guild - Scanner | Define `ElfSectionHash` and `ElfSectionHashSet` models in `src/Scanner/__Libraries/StellaOps.Scanner.Contracts/`. Include section name, offset, size, SHA-256 hash, and optional BLAKE3 hash. |
| 2 | ELF-SECTION-EXTRACTOR-0001 | TODO | Depends on ELF-SECTION-MODELS-0001 | Guild - Scanner | Implement `ElfSectionHashExtractor` class that reads ELF sections and computes per-section hashes. Integrate with existing ELF parsing in `ElfHardeningExtractor`. |
| 3 | ELF-SECTION-CONFIG-0001 | TODO | Depends on ELF-SECTION-EXTRACTOR-0001 | Guild - Scanner | Add configuration options for section hash extraction: enabled/disabled, section allowlist, hash algorithms. Use `IOptions<T>` with `ValidateOnStart`. |
| 4 | ELF-SECTION-EVIDENCE-0001 | TODO | Depends on ELF-SECTION-EXTRACTOR-0001 | Guild - Scanner | Emit section hashes as SBOM component `properties[]` with keys: `evidence:section:<name>:sha256`, `evidence:section:<name>:blake3`, `evidence:section:<name>:size`. |
| 5 | ELF-SECTION-DI-0001 | TODO | Depends on all above | Guild - Scanner | Register `ElfSectionHashExtractor` in `ServiceCollectionExtensions.cs`. Ensure `TimeProvider` and `IGuidGenerator` are injected for determinism. |
| 6 | ELF-SECTION-TESTS-0001 | TODO | Depends on all above | Guild - Scanner | Add unit tests in `src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Native.Tests/` covering: valid ELF with all sections, stripped ELF (missing symtab), malformed ELF, empty sections, large binaries. |
| 7 | ELF-SECTION-FIXTURES-0001 | TODO | Depends on ELF-SECTION-TESTS-0001 | Guild - Scanner | Create synthetic ELF test fixtures under `src/Scanner/__Tests/__Datasets/elf-section-hashes/` with known section contents for golden hash verification. |
| 8 | ELF-SECTION-DETERMINISM-0001 | TODO | Depends on all above | Guild - Scanner | Add determinism regression test: same ELF input produces identical section hashes across runs. Use `FakeTimeProvider` and fixed GUID generator. |
## Technical Specification
### ElfSectionHash Model
```csharp
namespace StellaOps.Scanner.Contracts;
/// <summary>
/// Represents a cryptographic hash of an ELF section.
/// </summary>
public sealed record ElfSectionHash
{
/// <summary>Section name (e.g., ".text", ".rodata").</summary>
public required string Name { get; init; }
/// <summary>Section offset in file.</summary>
public required long Offset { get; init; }
/// <summary>Section size in bytes.</summary>
public required long Size { get; init; }
/// <summary>SHA-256 hash of section contents (lowercase hex).</summary>
public required string Sha256 { get; init; }
/// <summary>Optional BLAKE3-256 hash of section contents (lowercase hex).</summary>
public string? Blake3 { get; init; }
/// <summary>Section type from ELF header.</summary>
public required ElfSectionType SectionType { get; init; }
/// <summary>Section flags from ELF header.</summary>
public required ElfSectionFlags Flags { get; init; }
}
/// <summary>
/// Collection of section hashes for a single ELF binary.
/// </summary>
public sealed record ElfSectionHashSet
{
/// <summary>Path to the ELF binary.</summary>
public required string FilePath { get; init; }
/// <summary>SHA-256 hash of the entire file.</summary>
public required string FileHash { get; init; }
/// <summary>Build-ID from .note.gnu.build-id if present.</summary>
public string? BuildId { get; init; }
/// <summary>Section hashes, sorted by section name.</summary>
public required ImmutableArray<ElfSectionHash> Sections { get; init; }
/// <summary>Extraction timestamp (UTC ISO-8601).</summary>
public required DateTimeOffset ExtractedAt { get; init; }
/// <summary>Extractor version for reproducibility.</summary>
public required string ExtractorVersion { get; init; }
}
```
### Extractor Interface
```csharp
namespace StellaOps.Scanner.Analyzers.Native;
public interface IElfSectionHashExtractor
{
/// <summary>
/// Extracts section hashes from an ELF binary.
/// </summary>
/// <param name="elfPath">Path to the ELF file.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>Section hash set, or null if not a valid ELF.</returns>
Task<ElfSectionHashSet?> ExtractAsync(
string elfPath,
CancellationToken cancellationToken = default);
/// <summary>
/// Extracts section hashes from ELF bytes in memory.
/// </summary>
Task<ElfSectionHashSet?> ExtractFromBytesAsync(
ReadOnlyMemory<byte> elfBytes,
string virtualPath,
CancellationToken cancellationToken = default);
}
```
### Target Sections
| Section | Purpose | Backport Relevance |
|---------|---------|-------------------|
| `.text` | Executable code | **High** - patched functions change this |
| `.rodata` | Read-only data | Medium - string constants may change |
| `.data` | Initialized data | Low - rarely changes for patches |
| `.symtab` | Symbol table | **High** - function signatures |
| `.dynsym` | Dynamic symbols | **High** - exported API |
| `.gnu.hash` | GNU hash table | Low - derived from symbols |
### SBOM Evidence Properties
```json
{
"type": "library",
"name": "libssl.so.3",
"properties": [
{"name": "evidence:build-id", "value": "abc123..."},
{"name": "evidence:section:.text:sha256", "value": "e3b0c442..."},
{"name": "evidence:section:.text:size", "value": "1048576"},
{"name": "evidence:section:.rodata:sha256", "value": "d7a8fbb3..."},
{"name": "evidence:section:.symtab:sha256", "value": "9f86d081..."},
{"name": "evidence:section-set:sha256", "value": "combined_hash..."},
{"name": "evidence:extractor-version", "value": "1.0.0"}
]
}
```
### Determinism Requirements
1. **Ordering**: Sections sorted lexicographically by name
2. **Hash format**: Lowercase hexadecimal, no prefix
3. **Timestamps**: From injected `TimeProvider.GetUtcNow()`
4. **Version string**: Assembly version or build metadata
5. **JSON serialization**: RFC 8785 canonical for any digest computation
### Configuration Schema
```yaml
scanner:
native:
sectionHashes:
enabled: true
algorithms:
- sha256
- blake3 # optional
sections:
- .text
- .rodata
- .data
- .symtab
- .dynsym
maxSectionSize: 104857600 # 100MB limit per section
```
## Test Cases
### Unit Tests
| Test | Description | Expected |
|------|-------------|----------|
| `ExtractAsync_ValidElf_ReturnsAllSections` | Standard ELF with all target sections | All 5 sections extracted with valid hashes |
| `ExtractAsync_StrippedElf_OmitsSymtab` | Stripped binary without .symtab | Only .text, .rodata, .data returned |
| `ExtractAsync_InvalidElf_ReturnsNull` | Non-ELF file (PE, Mach-O, random) | Returns null, no exception |
| `ExtractAsync_EmptySection_ReturnsEmptyHash` | ELF with zero-size .data | Hash of empty content (`e3b0c442...`) |
| `ExtractAsync_LargeSection_RespectsLimit` | Section > maxSectionSize | Section skipped or truncated per config |
| `ExtractAsync_Deterministic_SameOutput` | Same ELF, multiple runs | Identical `ElfSectionHashSet` |
| `ExtractFromBytesAsync_SameAsFile` | Memory vs file extraction | Identical results |
### Integration Tests
| Test | Description | Expected |
|------|-------------|----------|
| `LayerAnalysis_ElfWithSections_EmitsEvidence` | Container layer with ELF binaries | SBOM components have section hash properties |
| `Diff_SameBinaryDifferentPatch_DetectsSectionChange` | Two builds with backport | `.text` hash differs, other sections same |
### Fixtures
Create under `src/Scanner/__Tests/__Datasets/elf-section-hashes/`:
```
elf-section-hashes/
├── README.md # Fixture documentation
├── standard-amd64.elf # Standard ELF with all sections
├── standard-amd64.golden.json # Expected section hashes
├── stripped-amd64.elf # Stripped binary
├── stripped-amd64.golden.json
├── minimal-arm64.elf # Minimal ELF (few sections)
├── minimal-arm64.golden.json
└── corrupt.bin # Invalid ELF magic
```
## Execution Log
| Date (UTC) | Update | Owner |
|------------|--------|-------|
| 2026-01-13 | Sprint created from advisory analysis. | Project Mgmt |
## Decisions & Risks
- **APPROVED**: SHA-256 as primary hash; BLAKE3 optional for performance.
- **APPROVED**: 100MB per-section limit to prevent memory exhaustion.
- **RISK**: Some ELF parsers may handle edge cases differently; use LibObjectFile or similar well-tested library.
- **RISK**: Section ordering may vary by toolchain; normalize by sorting.
## Next Checkpoints
- Task 1-2 complete → Models and extractor ready for integration
- Task 6-8 complete → Sprint can be marked DONE
- Unblock Sprint 2 (BinaryDiffV1 predicate)

View File

@@ -1,441 +0,0 @@
# Sprint 20260113_001_002_ATTESTOR - BinaryDiffV1 In-Toto Predicate
## Topic & Scope
- Define `BinaryDiffV1` in-toto predicate schema for binary-level diff attestations
- Implement predicate builder and serializer
- Integrate with existing DSSE signing infrastructure
- Support both ELF section diffs and future PE/Mach-O extensions
- **Working directory:** `src/Attestor/__Libraries/StellaOps.Attestor.StandardPredicates/`
## Dependencies & Concurrency
- **Depends on:** Sprint 001 (ELF Section Hash models)
- Parallel work safe within Attestor module
- Sprint 3 (CLI) depends on this sprint
## Documentation Prerequisites
- `docs/README.md`
- `docs/ARCHITECTURE_REFERENCE.md`
- `CLAUDE.md` Section 8 (Determinism Rules)
- in-toto attestation specification (https://github.com/in-toto/attestation/blob/main/spec/v1/statement.md)
- DSSE envelope specification (https://github.com/secure-systems-lab/dsse/blob/master/envelope.md)
- Existing predicates: `src/Attestor/__Libraries/StellaOps.Attestor.StandardPredicates/`
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
|---|---------|--------|---------------------------|--------|-----------------|
| 1 | BINARYDIFF-SCHEMA-0001 | TODO | Sprint 001 models | Guild - Attestor | Define `BinaryDiffV1` predicate schema with JSON Schema and C# models. Include subjects, inputs, findings, and verification materials. |
| 2 | BINARYDIFF-MODELS-0001 | TODO | Depends on BINARYDIFF-SCHEMA-0001 | Guild - Attestor | Implement C# record types for `BinaryDiffPredicate`, `BinaryDiffSubject`, `BinaryDiffInput`, `BinaryDiffFinding`, `SectionDelta`. |
| 3 | BINARYDIFF-BUILDER-0001 | TODO | Depends on BINARYDIFF-MODELS-0001 | Guild - Attestor | Implement `BinaryDiffPredicateBuilder` with fluent API for constructing predicates from section hash comparisons. |
| 4 | BINARYDIFF-SERIALIZER-0001 | TODO | Depends on BINARYDIFF-MODELS-0001 | Guild - Attestor | Implement canonical JSON serialization using RFC 8785. Register with existing `IPredicateSerializer` infrastructure. |
| 5 | BINARYDIFF-SIGNER-0001 | TODO | Depends on all above | Guild - Attestor | Implement `BinaryDiffDsseSigner` following `WitnessDsseSigner` pattern. Payload type: `stellaops.binarydiff.v1`. |
| 6 | BINARYDIFF-VERIFIER-0001 | TODO | Depends on BINARYDIFF-SIGNER-0001 | Guild - Attestor | Implement `BinaryDiffDsseVerifier` for signature and schema validation. |
| 7 | BINARYDIFF-DI-0001 | TODO | Depends on all above | Guild - Attestor | Register all services in DI. Add `IOptions<BinaryDiffOptions>` for configuration. |
| 8 | BINARYDIFF-TESTS-0001 | TODO | Depends on all above | Guild - Attestor | Add comprehensive unit tests covering: schema validation, serialization round-trip, signing/verification, edge cases (empty findings, large diffs). |
| 9 | BINARYDIFF-JSONSCHEMA-0001 | TODO | Depends on BINARYDIFF-SCHEMA-0001 | Guild - Attestor | Publish JSON Schema to `docs/schemas/binarydiff-v1.schema.json` for external validation. |
## Technical Specification
### Predicate Type
```
stellaops.binarydiff.v1
```
### BinaryDiffV1 Schema
```json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://stellaops.io/schemas/binarydiff-v1.schema.json",
"title": "BinaryDiffV1",
"description": "In-toto predicate for binary-level diff attestations",
"type": "object",
"required": ["predicateType", "subjects", "inputs", "findings", "metadata"],
"properties": {
"predicateType": {
"const": "stellaops.binarydiff.v1"
},
"subjects": {
"type": "array",
"items": { "$ref": "#/$defs/BinaryDiffSubject" },
"minItems": 1
},
"inputs": {
"$ref": "#/$defs/BinaryDiffInputs"
},
"findings": {
"type": "array",
"items": { "$ref": "#/$defs/BinaryDiffFinding" }
},
"metadata": {
"$ref": "#/$defs/BinaryDiffMetadata"
}
},
"$defs": {
"BinaryDiffSubject": {
"type": "object",
"required": ["name", "digest"],
"properties": {
"name": {
"type": "string",
"description": "Image reference (e.g., docker://repo/app@sha256:...)"
},
"digest": {
"type": "object",
"additionalProperties": { "type": "string" }
},
"platform": {
"$ref": "#/$defs/Platform"
}
}
},
"BinaryDiffInputs": {
"type": "object",
"required": ["base", "target"],
"properties": {
"base": { "$ref": "#/$defs/ImageReference" },
"target": { "$ref": "#/$defs/ImageReference" }
}
},
"ImageReference": {
"type": "object",
"required": ["digest"],
"properties": {
"reference": { "type": "string" },
"digest": { "type": "string" },
"manifestDigest": { "type": "string" },
"platform": { "$ref": "#/$defs/Platform" }
}
},
"Platform": {
"type": "object",
"properties": {
"os": { "type": "string" },
"architecture": { "type": "string" },
"variant": { "type": "string" }
}
},
"BinaryDiffFinding": {
"type": "object",
"required": ["path", "changeType", "binaryFormat"],
"properties": {
"path": {
"type": "string",
"description": "File path within the image filesystem"
},
"changeType": {
"enum": ["added", "removed", "modified", "unchanged"]
},
"binaryFormat": {
"enum": ["elf", "pe", "macho", "unknown"]
},
"layerDigest": {
"type": "string",
"description": "Layer that introduced this change"
},
"baseHashes": {
"$ref": "#/$defs/SectionHashSet"
},
"targetHashes": {
"$ref": "#/$defs/SectionHashSet"
},
"sectionDeltas": {
"type": "array",
"items": { "$ref": "#/$defs/SectionDelta" }
},
"confidence": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"verdict": {
"enum": ["patched", "vanilla", "unknown", "incompatible"]
}
}
},
"SectionHashSet": {
"type": "object",
"properties": {
"buildId": { "type": "string" },
"fileHash": { "type": "string" },
"sections": {
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/SectionInfo"
}
}
}
},
"SectionInfo": {
"type": "object",
"required": ["sha256", "size"],
"properties": {
"sha256": { "type": "string" },
"blake3": { "type": "string" },
"size": { "type": "integer" }
}
},
"SectionDelta": {
"type": "object",
"required": ["section", "status"],
"properties": {
"section": {
"type": "string",
"description": "Section name (e.g., .text, .rodata)"
},
"status": {
"enum": ["identical", "modified", "added", "removed"]
},
"baseSha256": { "type": "string" },
"targetSha256": { "type": "string" },
"sizeDelta": { "type": "integer" }
}
},
"BinaryDiffMetadata": {
"type": "object",
"required": ["toolVersion", "analysisTimestamp"],
"properties": {
"toolVersion": { "type": "string" },
"analysisTimestamp": {
"type": "string",
"format": "date-time"
},
"configDigest": { "type": "string" },
"totalBinaries": { "type": "integer" },
"modifiedBinaries": { "type": "integer" },
"analyzedSections": {
"type": "array",
"items": { "type": "string" }
}
}
}
}
}
```
### C# Model Classes
```csharp
namespace StellaOps.Attestor.StandardPredicates.BinaryDiff;
/// <summary>
/// BinaryDiffV1 predicate for in-toto attestations.
/// </summary>
public sealed record BinaryDiffPredicate
{
public const string PredicateType = "stellaops.binarydiff.v1";
public required ImmutableArray<BinaryDiffSubject> Subjects { get; init; }
public required BinaryDiffInputs Inputs { get; init; }
public required ImmutableArray<BinaryDiffFinding> Findings { get; init; }
public required BinaryDiffMetadata Metadata { get; init; }
}
public sealed record BinaryDiffSubject
{
public required string Name { get; init; }
public required ImmutableDictionary<string, string> Digest { get; init; }
public Platform? Platform { get; init; }
}
public sealed record BinaryDiffInputs
{
public required ImageReference Base { get; init; }
public required ImageReference Target { get; init; }
}
public sealed record ImageReference
{
public string? Reference { get; init; }
public required string Digest { get; init; }
public string? ManifestDigest { get; init; }
public Platform? Platform { get; init; }
}
public sealed record Platform
{
public required string Os { get; init; }
public required string Architecture { get; init; }
public string? Variant { get; init; }
}
public sealed record BinaryDiffFinding
{
public required string Path { get; init; }
public required ChangeType ChangeType { get; init; }
public required BinaryFormat BinaryFormat { get; init; }
public string? LayerDigest { get; init; }
public SectionHashSet? BaseHashes { get; init; }
public SectionHashSet? TargetHashes { get; init; }
public ImmutableArray<SectionDelta> SectionDeltas { get; init; }
public double? Confidence { get; init; }
public Verdict? Verdict { get; init; }
}
public enum ChangeType { Added, Removed, Modified, Unchanged }
public enum BinaryFormat { Elf, Pe, Macho, Unknown }
public enum Verdict { Patched, Vanilla, Unknown, Incompatible }
public sealed record SectionHashSet
{
public string? BuildId { get; init; }
public required string FileHash { get; init; }
public required ImmutableDictionary<string, SectionInfo> Sections { get; init; }
}
public sealed record SectionInfo
{
public required string Sha256 { get; init; }
public string? Blake3 { get; init; }
public required long Size { get; init; }
}
public sealed record SectionDelta
{
public required string Section { get; init; }
public required SectionStatus Status { get; init; }
public string? BaseSha256 { get; init; }
public string? TargetSha256 { get; init; }
public long? SizeDelta { get; init; }
}
public enum SectionStatus { Identical, Modified, Added, Removed }
public sealed record BinaryDiffMetadata
{
public required string ToolVersion { get; init; }
public required DateTimeOffset AnalysisTimestamp { get; init; }
public string? ConfigDigest { get; init; }
public int TotalBinaries { get; init; }
public int ModifiedBinaries { get; init; }
public ImmutableArray<string> AnalyzedSections { get; init; }
}
```
### Builder API
```csharp
public interface IBinaryDiffPredicateBuilder
{
IBinaryDiffPredicateBuilder WithSubject(string name, string digest, Platform? platform = null);
IBinaryDiffPredicateBuilder WithInputs(ImageReference baseImage, ImageReference targetImage);
IBinaryDiffPredicateBuilder AddFinding(BinaryDiffFinding finding);
IBinaryDiffPredicateBuilder WithMetadata(Action<BinaryDiffMetadataBuilder> configure);
BinaryDiffPredicate Build();
}
```
### DSSE Integration
```csharp
public interface IBinaryDiffDsseSigner
{
Task<BinaryDiffDsseResult> SignAsync(
BinaryDiffPredicate predicate,
CancellationToken cancellationToken = default);
}
public sealed record BinaryDiffDsseResult
{
public required string PayloadType { get; init; } // stellaops.binarydiff.v1
public required byte[] Payload { get; init; }
public required ImmutableArray<DsseSignature> Signatures { get; init; }
public required string EnvelopeJson { get; init; }
public string? RekorLogIndex { get; init; }
public string? RekorEntryId { get; init; }
}
```
### In-Toto Statement Wrapper
```json
{
"_type": "https://in-toto.io/Statement/v1",
"subject": [
{
"name": "docker://registry.example.com/app@sha256:abc123...",
"digest": {
"sha256": "abc123..."
}
}
],
"predicateType": "stellaops.binarydiff.v1",
"predicate": {
"inputs": {
"base": { "digest": "sha256:old..." },
"target": { "digest": "sha256:new..." }
},
"findings": [
{
"path": "/usr/lib/libssl.so.3",
"changeType": "modified",
"binaryFormat": "elf",
"sectionDeltas": [
{ "section": ".text", "status": "modified", "baseSha256": "...", "targetSha256": "..." }
],
"confidence": 0.95,
"verdict": "patched"
}
],
"metadata": {
"toolVersion": "1.0.0",
"analysisTimestamp": "2026-01-13T12:00:00Z"
}
}
}
```
## Determinism Requirements
1. **Canonical JSON**: RFC 8785 for all serialization before signing
2. **Stable ordering**: Findings sorted by path; sections sorted by name
3. **Timestamps**: From injected `TimeProvider`
4. **Hash computation**: Use shared `CanonicalJsonSerializer`
5. **DSSE PAE**: Use shared `DsseHelper.ComputePreAuthenticationEncoding`
## Test Cases
### Unit Tests
| Test | Description | Expected |
|------|-------------|----------|
| `Serialize_RoundTrip_Identical` | Serialize then deserialize | Identical predicate |
| `Serialize_Canonical_DeterministicOutput` | Same predicate, multiple serializations | Byte-identical JSON |
| `Build_ValidInputs_CreatesPredicate` | Builder with all required fields | Valid predicate |
| `Build_MissingSubject_Throws` | Builder without subject | `ArgumentException` |
| `Sign_ValidPredicate_ReturnsEnvelope` | Sign with test key | Valid DSSE envelope |
| `Verify_ValidEnvelope_Succeeds` | Verify signed envelope | Verification passes |
| `Verify_TamperedPayload_Fails` | Modified payload | Verification fails |
| `Schema_ValidJson_Passes` | Valid JSON against schema | Schema validation passes |
| `Schema_InvalidJson_Fails` | Missing required field | Schema validation fails |
### Integration Tests
| Test | Description | Expected |
|------|-------------|----------|
| `SignAndSubmit_RekorIntegration` | Sign and submit to Rekor (test instance) | Log entry created |
| `EndToEnd_DiffToAttestation` | From image diff to signed attestation | Valid DSSE with findings |
## Execution Log
| Date (UTC) | Update | Owner |
|------------|--------|-------|
| 2026-01-13 | Sprint created from advisory analysis. | Project Mgmt |
## Decisions & Risks
- **APPROVED**: Predicate type `stellaops.binarydiff.v1` follows StellaOps naming convention.
- **APPROVED**: Support both ELF and future PE/Mach-O via `binaryFormat` discriminator.
- **RISK**: Schema evolution requires versioning strategy; defer to v2 if breaking changes needed.
- **RISK**: Large diffs may produce large attestations; consider summary mode for >1000 findings.
## Next Checkpoints
- Task 1-4 complete → Schema and models ready for integration
- Task 5-6 complete → Signing/verification operational
- Task 8 complete → Sprint can be marked DONE
- Unblock Sprint 3 (CLI)

View File

@@ -1,358 +0,0 @@
# Sprint 20260113_001_003_CLI - Binary Diff Command Enhancement
## Topic & Scope
- Implement `stella scan diff --mode=elf` for binary-section-level diff
- Add `--emit-dsse=<dir>` option for DSSE attestation output
- Support human-readable table and JSON output formats
- Integrate with existing scan infrastructure and OCI registry client
- **Working directory:** `src/Cli/StellaOps.Cli/Commands/`
## Dependencies & Concurrency
- **Depends on:** Sprint 001 (ELF Section Hash Extractor)
- **Depends on:** Sprint 002 (BinaryDiffV1 Predicate)
- **BLOCKED RISK:** CLI tests under active modification; coordinate before touching test files
- Parallel work safe for command implementation; test coordination required
## Documentation Prerequisites
- `docs/README.md`
- `docs/ARCHITECTURE_REFERENCE.md`
- `CLAUDE.md` Section 8 (Determinism Rules)
- `src/Cli/StellaOps.Cli/AGENTS.md` (if exists)
- Existing CLI commands: `src/Cli/StellaOps.Cli/Commands/`
- System.CommandLine documentation
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
|---|---------|--------|---------------------------|--------|-----------------|
| 1 | CLI-DIFF-COMMAND-0001 | TODO | Sprint 001 & 002 complete | Guild - CLI | Create `BinaryDiffCommand` class under `Commands/Scan/` implementing `stella scan diff` subcommand with required options. |
| 2 | CLI-DIFF-OPTIONS-0001 | TODO | Depends on CLI-DIFF-COMMAND-0001 | Guild - CLI | Define command options: `--base` (base image ref), `--target` (target image ref), `--mode` (elf/pe/auto), `--emit-dsse` (output dir), `--format` (table/json), `--platform` (os/arch). |
| 3 | CLI-DIFF-SERVICE-0001 | TODO | Depends on CLI-DIFF-OPTIONS-0001 | Guild - CLI | Implement `BinaryDiffService` that orchestrates: image pull, layer extraction, section hash computation, diff computation, predicate building. |
| 4 | CLI-DIFF-RENDERER-0001 | TODO | Depends on CLI-DIFF-SERVICE-0001 | Guild - CLI | Implement `BinaryDiffRenderer` for table and JSON output formats. Table shows path, change type, verdict, confidence. JSON outputs full diff structure. |
| 5 | CLI-DIFF-DSSE-OUTPUT-0001 | TODO | Depends on CLI-DIFF-SERVICE-0001 | Guild - CLI | Implement DSSE output: one envelope per platform manifest, written to `--emit-dsse` directory with naming convention `{platform}-binarydiff.dsse.json`. |
| 6 | CLI-DIFF-PROGRESS-0001 | TODO | Depends on CLI-DIFF-SERVICE-0001 | Guild - CLI | Add progress reporting for long-running operations: layer download progress, binary analysis progress, section hash computation. |
| 7 | CLI-DIFF-DI-0001 | TODO | Depends on all above | Guild - CLI | Register all services in `Program.cs` DI setup. Wire up `IHttpClientFactory`, `IElfSectionHashExtractor`, `IBinaryDiffDsseSigner`. |
| 8 | CLI-DIFF-HELP-0001 | TODO | Depends on CLI-DIFF-COMMAND-0001 | Guild - CLI | Add comprehensive help text, examples, and shell completions for the new command. |
| 9 | CLI-DIFF-TESTS-0001 | BLOCKED | Depends on all above; CLI tests under active modification | Guild - CLI | Add unit tests for command parsing, service logic, and output rendering. Coordinate with other agent before modifying test files. |
| 10 | CLI-DIFF-INTEGRATION-0001 | TODO | Depends on CLI-DIFF-TESTS-0001 | Guild - CLI | Add integration test with synthetic OCI images containing known ELF binaries. Verify end-to-end flow. |
## Technical Specification
### Command Syntax
```bash
# Basic usage
stella scan diff --base <image-ref> --target <image-ref>
# With binary mode
stella scan diff --base docker://repo/app:1.0.0 --target docker://repo/app:1.0.1 --mode=elf
# With DSSE output
stella scan diff --base @sha256:abc... --target @sha256:def... \
--mode=elf --emit-dsse=./attestations/
# JSON output
stella scan diff --base image1 --target image2 --format=json > diff.json
# Specific platform
stella scan diff --base image1 --target image2 --platform=linux/amd64
```
### Command Options
| Option | Short | Type | Required | Default | Description |
|--------|-------|------|----------|---------|-------------|
| `--base` | `-b` | string | Yes | - | Base image reference (tag or @digest) |
| `--target` | `-t` | string | Yes | - | Target image reference (tag or @digest) |
| `--mode` | `-m` | enum | No | `auto` | Analysis mode: `elf`, `pe`, `auto` |
| `--emit-dsse` | `-d` | path | No | - | Directory for DSSE attestation output |
| `--format` | `-f` | enum | No | `table` | Output format: `table`, `json`, `summary` |
| `--platform` | `-p` | string | No | - | Platform filter (e.g., `linux/amd64`) |
| `--include-unchanged` | - | bool | No | `false` | Include unchanged binaries in output |
| `--sections` | - | string[] | No | all | Sections to analyze (e.g., `.text,.rodata`) |
| `--registry-auth` | - | string | No | - | Path to Docker config for authentication |
| `--timeout` | - | int | No | `300` | Timeout in seconds for operations |
| `--verbose` | `-v` | bool | No | `false` | Enable verbose output |
### Output Formats
#### Table Format (Default)
```
Binary Diff: docker://repo/app:1.0.0 → docker://repo/app:1.0.1
Platform: linux/amd64
Analysis Mode: ELF Section Hashes
PATH CHANGE VERDICT CONFIDENCE SECTIONS CHANGED
────────────────────────────────────────────────────────────────────────────────
/usr/lib/libssl.so.3 modified patched 0.95 .text, .rodata
/usr/lib/libcrypto.so.3 modified patched 0.92 .text
/usr/bin/openssl modified unknown 0.75 .text, .data
/usr/lib/libc.so.6 unchanged - - -
Summary: 4 binaries analyzed, 3 modified, 1 unchanged
Patched: 2, Unknown: 1
```
#### JSON Format
```json
{
"schemaVersion": "1.0.0",
"base": {
"reference": "docker://repo/app:1.0.0",
"digest": "sha256:abc123..."
},
"target": {
"reference": "docker://repo/app:1.0.1",
"digest": "sha256:def456..."
},
"platform": {
"os": "linux",
"architecture": "amd64"
},
"analysisMode": "elf",
"timestamp": "2026-01-13T12:00:00Z",
"findings": [
{
"path": "/usr/lib/libssl.so.3",
"changeType": "modified",
"verdict": "patched",
"confidence": 0.95,
"sectionDeltas": [
{ "section": ".text", "status": "modified" },
{ "section": ".rodata", "status": "modified" }
]
}
],
"summary": {
"totalBinaries": 4,
"modified": 3,
"unchanged": 1,
"verdicts": {
"patched": 2,
"unknown": 1
}
}
}
```
#### Summary Format
```
Binary Diff Summary
───────────────────
Base: docker://repo/app:1.0.0 (sha256:abc123...)
Target: docker://repo/app:1.0.1 (sha256:def456...)
Platform: linux/amd64
Binaries: 4 total, 3 modified, 1 unchanged
Verdicts: 2 patched, 1 unknown
DSSE Attestation: ./attestations/linux-amd64-binarydiff.dsse.json
```
### DSSE Output Structure
```
attestations/
├── linux-amd64-binarydiff.dsse.json # DSSE envelope
├── linux-amd64-binarydiff.payload.json # Raw predicate (for inspection)
└── linux-arm64-binarydiff.dsse.json # (if multi-arch)
```
### Service Architecture
```csharp
namespace StellaOps.Cli.Services;
public interface IBinaryDiffService
{
Task<BinaryDiffResult> ComputeDiffAsync(
BinaryDiffRequest request,
IProgress<BinaryDiffProgress>? progress = null,
CancellationToken cancellationToken = default);
}
public sealed record BinaryDiffRequest
{
public required string BaseImageRef { get; init; }
public required string TargetImageRef { get; init; }
public required BinaryDiffMode Mode { get; init; }
public Platform? Platform { get; init; }
public ImmutableArray<string>? Sections { get; init; }
public bool IncludeUnchanged { get; init; }
public string? RegistryAuthPath { get; init; }
}
public sealed record BinaryDiffResult
{
public required ImageReference Base { get; init; }
public required ImageReference Target { get; init; }
public required Platform Platform { get; init; }
public required ImmutableArray<BinaryDiffFinding> Findings { get; init; }
public required BinaryDiffSummary Summary { get; init; }
public BinaryDiffPredicate? Predicate { get; init; }
}
public sealed record BinaryDiffProgress
{
public required string Phase { get; init; } // "pulling", "extracting", "analyzing", "diffing"
public required string CurrentItem { get; init; }
public required int Current { get; init; }
public required int Total { get; init; }
}
```
### Command Implementation Pattern
```csharp
namespace StellaOps.Cli.Commands.Scan;
public class BinaryDiffCommand : Command
{
public BinaryDiffCommand() : base("diff", "Compare binaries between two images")
{
AddOption(BaseOption);
AddOption(TargetOption);
AddOption(ModeOption);
AddOption(EmitDsseOption);
AddOption(FormatOption);
AddOption(PlatformOption);
// ... other options
}
public static Option<string> BaseOption { get; } = new(
aliases: ["--base", "-b"],
description: "Base image reference (tag or @digest)")
{
IsRequired = true
};
// ... other options
public new class Handler : ICommandHandler
{
private readonly IBinaryDiffService _diffService;
private readonly IBinaryDiffDsseSigner _signer;
private readonly IBinaryDiffRenderer _renderer;
private readonly IConsole _console;
public async Task<int> InvokeAsync(InvocationContext context)
{
var cancellationToken = context.GetCancellationToken();
// Parse options
var baseRef = context.ParseResult.GetValueForOption(BaseOption)!;
var targetRef = context.ParseResult.GetValueForOption(TargetOption)!;
// ...
// Execute diff
var progress = new Progress<BinaryDiffProgress>(p =>
_console.WriteLine($"[{p.Phase}] {p.CurrentItem} ({p.Current}/{p.Total})"));
var result = await _diffService.ComputeDiffAsync(
new BinaryDiffRequest { ... },
progress,
cancellationToken);
// Emit DSSE if requested
if (!string.IsNullOrEmpty(emitDssePath))
{
var dsseResult = await _signer.SignAsync(result.Predicate!, cancellationToken);
await WriteDsseAsync(emitDssePath, result.Platform, dsseResult, cancellationToken);
}
// Render output
await _renderer.RenderAsync(result, format, _console.Out, cancellationToken);
return 0;
}
}
}
```
### Error Handling
| Error | Exit Code | Message |
|-------|-----------|---------|
| Invalid base image | 1 | `Error: Unable to resolve base image '{ref}': {reason}` |
| Invalid target image | 1 | `Error: Unable to resolve target image '{ref}': {reason}` |
| Authentication failed | 2 | `Error: Registry authentication failed for '{registry}'` |
| Platform not found | 3 | `Error: Platform '{platform}' not found in image index` |
| No ELF binaries | 0 | `Warning: No ELF binaries found in images` (success with warning) |
| Timeout | 124 | `Error: Operation timed out after {timeout}s` |
| Network error | 5 | `Error: Network error: {message}` |
### Progress Reporting
```
[pulling] Fetching base manifest... (1/4)
[pulling] Fetching target manifest... (2/4)
[pulling] Downloading layers... (3/4)
└─ sha256:abc123... 45.2 MB/128.5 MB (35%)
[extracting] Extracting base layers... (1/8)
[extracting] Extracting target layers... (5/8)
[analyzing] Computing section hashes... (1/156)
└─ /usr/lib/libssl.so.3
[analyzing] Computing section hashes... (78/156)
└─ /usr/bin/python3.11
[diffing] Comparing binaries... (1/156)
[complete] Analysis complete.
```
## Determinism Requirements
1. **Output ordering**: Findings sorted by path
2. **Timestamps**: From injected `TimeProvider`
3. **Hash formats**: Lowercase hexadecimal
4. **JSON output**: RFC 8785 canonical when `--format=json`
5. **DSSE files**: Canonical JSON serialization
## Test Cases
### Unit Tests
| Test | Description | Expected |
|------|-------------|----------|
| `ParseOptions_ValidArgs_Succeeds` | All required options provided | Options parsed correctly |
| `ParseOptions_MissingBase_Fails` | Missing --base | Parse error |
| `ComputeDiff_IdenticalImages_NoChanges` | Same image for base and target | Empty findings, summary shows 0 modified |
| `ComputeDiff_ModifiedBinary_DetectsChange` | Binary with .text change | Finding with modified status |
| `ComputeDiff_AddedBinary_Detected` | Binary in target only | Finding with added status |
| `ComputeDiff_RemovedBinary_Detected` | Binary in base only | Finding with removed status |
| `RenderTable_ValidResult_FormatsCorrectly` | Result with findings | Properly formatted table |
| `RenderJson_ValidResult_CanonicalOutput` | Same result, multiple renders | Byte-identical JSON |
| `EmitDsse_ValidResult_CreatesFile` | With --emit-dsse | DSSE file created |
### Integration Tests
| Test | Description | Expected |
|------|-------------|----------|
| `EndToEnd_RealImages_ProducesOutput` | Two synthetic OCI images | Valid diff output |
| `EndToEnd_WithDsse_ValidAttestation` | Diff with --emit-dsse | Verifiable DSSE |
| `MultiArch_SpecificPlatform_FiltersCorrectly` | Multi-arch image with --platform | Only specified platform analyzed |
## Execution Log
| Date (UTC) | Update | Owner |
|------------|--------|-------|
| 2026-01-13 | Sprint created from advisory analysis. | Project Mgmt |
| 2026-01-13 | Task CLI-DIFF-TESTS-0001 marked BLOCKED: CLI tests under active modification. | Project Mgmt |
## Decisions & Risks
- **APPROVED**: Command placed under `stella scan diff` (not separate `stella-scan image diff` as in advisory).
- **APPROVED**: Support `--mode=elf` initially; `--mode=pe` and `--mode=auto` stubbed for future.
- **BLOCKED**: CLI tests require coordination with other agent work; tests deferred.
- **RISK**: Long-running operations need robust timeout and cancellation handling.
- **RISK**: Large images may cause memory pressure; consider streaming approach for layer extraction.
## Next Checkpoints
- Task 1-6 complete → Command implementation ready
- Task 7-8 complete → Help and DI wired up
- Task 9-10 complete (after unblock) → Sprint can be marked DONE

View File

@@ -1,351 +0,0 @@
# Sprint 20260113_001_004_DOCS - Binary Diff Attestation Documentation
## Topic & Scope
- Create architecture documentation for binary diff attestation feature
- Update CLI reference with new `stella scan diff` command
- Publish BinaryDiffV1 predicate JSON Schema
- Add developer guide for extending binary analysis
- **Working directory:** `docs/`
## Dependencies & Concurrency
- Can proceed in parallel with Sprints 2-3 (after Sprint 1 models stabilize)
- No blocking dependencies for initial documentation drafts
- Final documentation review after all implementation sprints complete
## Documentation Prerequisites
- `docs/README.md`
- `docs/ARCHITECTURE_REFERENCE.md`
- `CLAUDE.md` (for documentation standards)
- Existing module docs: `docs/modules/scanner/`
- Existing CLI docs: `docs/API_CLI_REFERENCE.md`
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
|---|---------|--------|---------------------------|--------|-----------------|
| 1 | DOCS-ARCH-0001 | TODO | Sprint 001 models | Guild - Docs | Create `docs/modules/scanner/binary-diff-attestation.md` architecture document covering ELF section hashing, diff computation, and DSSE attestation flow. |
| 2 | DOCS-CLI-0001 | TODO | Sprint 003 command spec | Guild - Docs | Update `docs/API_CLI_REFERENCE.md` with `stella scan diff` command documentation including all options, examples, and output formats. |
| 3 | DOCS-SCHEMA-0001 | TODO | Sprint 002 schema | Guild - Docs | Publish `docs/schemas/binarydiff-v1.schema.json` with full JSON Schema definition and validation examples. |
| 4 | DOCS-DEVGUIDE-0001 | TODO | All sprints | Guild - Docs | Create `docs/dev/extending-binary-analysis.md` developer guide for adding new binary formats (PE, Mach-O) and custom section extractors. |
| 5 | DOCS-EXAMPLES-0001 | TODO | Sprint 003 complete | Guild - Docs | Add usage examples to `docs/examples/binary-diff/` with sample commands, expected outputs, and DSSE verification steps. |
| 6 | DOCS-GLOSSARY-0001 | TODO | None | Guild - Docs | Update `docs/GLOSSARY.md` (if exists) or create glossary entries for: section hash, binary diff, vendor backport, DSSE envelope. |
| 7 | DOCS-CHANGELOG-0001 | TODO | All sprints complete | Guild - Docs | Add changelog entry for binary diff attestation feature in `CHANGELOG.md`. |
| 8 | DOCS-REVIEW-0001 | TODO | All above complete | Guild - Docs | Final documentation review: cross-link all docs, verify examples work, spell-check, ensure consistency with existing docs. |
## Documentation Deliverables
### 1. Architecture Document
**File:** `docs/modules/scanner/binary-diff-attestation.md`
**Outline:**
```markdown
# Binary Diff Attestation
## Overview
- Purpose and use cases
- Relationship to SBOM and VEX
## Architecture
### Component Diagram
- ElfSectionHashExtractor
- BinaryDiffService
- BinaryDiffPredicateBuilder
- BinaryDiffDsseSigner
### Data Flow
1. Image resolution
2. Layer extraction
3. Binary identification
4. Section hash computation
5. Diff computation
6. Predicate construction
7. DSSE signing
## ELF Section Hashing
### Target Sections
- .text (executable code)
- .rodata (read-only data)
- .data (initialized data)
- .symtab (symbol table)
- .dynsym (dynamic symbols)
### Hash Algorithm
- SHA-256 primary
- BLAKE3 optional
### Determinism Guarantees
- Stable ordering
- Canonical serialization
## BinaryDiffV1 Predicate
### Schema Overview
- Subjects (image references)
- Inputs (base/target)
- Findings (per-binary deltas)
- Metadata
### Evidence Properties
- Section hashes in SBOM
- Confidence scoring
- Verdict classification
## DSSE Attestation
### Envelope Structure
- Payload type: stellaops.binarydiff.v1
- Signature algorithm
- Rekor submission
### Verification
- cosign compatibility
- Offline verification
## Integration Points
### VEX Mapping
- Linking to vulnerability status
- Backport evidence
### Policy Engine
- Binary evidence rules
- Trust thresholds
## Configuration
### Options
- Section selection
- Hash algorithms
- Output formats
## Limitations and Future Work
### Current Limitations
- ELF only (PE/Mach-O planned)
- Single-platform per invocation
### Roadmap
- PE section analysis (M2)
- Mach-O section analysis (M2)
- Vendor backport corpus (M3)
```
### 2. CLI Reference Update
**File:** `docs/API_CLI_REFERENCE.md` (append to Scan section)
**Content:**
```markdown
### stella scan diff
Compare binaries between two container images at the section level.
#### Synopsis
```bash
stella scan diff --base <image-ref> --target <image-ref> [options]
```
#### Description
The `diff` command performs binary-level comparison between two container images,
analyzing ELF section hashes to detect changes and classify them as patches,
vanilla updates, or unknown modifications.
#### Options
| Option | Description |
|--------|-------------|
| `--base`, `-b` | Base image reference (required) |
| `--target`, `-t` | Target image reference (required) |
| `--mode`, `-m` | Analysis mode: `elf`, `pe`, `auto` (default: `auto`) |
| `--emit-dsse`, `-d` | Directory for DSSE attestation output |
| `--format`, `-f` | Output format: `table`, `json`, `summary` (default: `table`) |
| `--platform`, `-p` | Platform filter (e.g., `linux/amd64`) |
| `--include-unchanged` | Include unchanged binaries in output |
| `--sections` | Sections to analyze (comma-separated) |
| `--registry-auth` | Path to Docker config for authentication |
| `--timeout` | Timeout in seconds (default: 300) |
| `--verbose`, `-v` | Enable verbose output |
#### Examples
**Basic comparison:**
```bash
stella scan diff --base myapp:1.0.0 --target myapp:1.0.1
```
**With DSSE attestation output:**
```bash
stella scan diff -b myapp:1.0.0 -t myapp:1.0.1 \
--mode=elf --emit-dsse=./attestations/
```
**JSON output for automation:**
```bash
stella scan diff -b myapp:1.0.0 -t myapp:1.0.1 --format=json > diff.json
```
**Specific platform:**
```bash
stella scan diff -b myapp:1.0.0 -t myapp:1.0.1 --platform=linux/arm64
```
#### Output
**Table format** shows a summary of changes:
```
PATH CHANGE VERDICT CONFIDENCE
/usr/lib/libssl.so.3 modified patched 0.95
/usr/lib/libcrypto.so.3 modified patched 0.92
```
**JSON format** provides full diff details for programmatic consumption.
#### Exit Codes
| Code | Description |
|------|-------------|
| 0 | Success |
| 1 | Invalid image reference |
| 2 | Authentication failed |
| 3 | Platform not found |
| 124 | Timeout |
| 5 | Network error |
#### See Also
- `stella scan layers` - List layers in an image
- `stella scan sbom` - Generate SBOM for an image
- [Binary Diff Attestation Architecture](../modules/scanner/binary-diff-attestation.md)
```
### 3. JSON Schema
**File:** `docs/schemas/binarydiff-v1.schema.json`
(Full schema as defined in Sprint 002)
### 4. Developer Guide
**File:** `docs/dev/extending-binary-analysis.md`
**Outline:**
```markdown
# Extending Binary Analysis
## Overview
This guide explains how to add support for new binary formats (PE, Mach-O)
or custom section extractors to the binary diff attestation system.
## Architecture
### Extractor Interface
- ISectionHashExtractor<TConfig>
- Registration pattern
- Configuration binding
### Adding a New Format
#### Step 1: Define Models
- Section hash models
- Format-specific metadata
#### Step 2: Implement Extractor
- Parse binary format
- Extract sections
- Compute hashes
#### Step 3: Register Services
- DI registration
- Configuration binding
- Format detection
#### Step 4: Add Tests
- Unit test fixtures
- Golden file comparisons
- Edge cases
### Example: PE Section Extractor
```csharp
public class PeSectionHashExtractor : ISectionHashExtractor<PeConfig>
{
// Implementation example
}
```
## Best Practices
### Determinism
- Stable ordering
- Canonical hashing
- Injected dependencies
### Performance
- Streaming large binaries
- Caching strategies
- Parallel extraction
### Security
- Input validation
- Memory limits
- Malformed input handling
```
### 5. Usage Examples
**Directory:** `docs/examples/binary-diff/`
**Files:**
```
binary-diff/
├── README.md # Overview and prerequisites
├── basic-comparison.md # Simple diff example
├── dsse-attestation.md # DSSE output and verification
├── policy-integration.md # Using diffs in policy rules
├── ci-cd-integration.md # GitHub Actions / GitLab CI examples
└── sample-outputs/
├── diff-table.txt # Sample table output
├── diff.json # Sample JSON output
└── attestation.dsse.json # Sample DSSE envelope
```
## Quality Checklist
- [ ] All code examples compile/run
- [ ] All links are valid
- [ ] Consistent terminology with existing docs
- [ ] No spelling/grammar errors
- [ ] Screenshots/diagrams where helpful
- [ ] Cross-references to related docs
- [ ] Version compatibility noted
## Execution Log
| Date (UTC) | Update | Owner |
|------------|--------|-------|
| 2026-01-13 | Sprint created from advisory analysis. | Project Mgmt |
## Decisions & Risks
- **APPROVED**: Documentation follows existing StellaOps documentation patterns.
- **APPROVED**: JSON Schema published under `docs/schemas/` for external consumption.
- **RISK**: Documentation may need updates if implementation details change; defer final review until code complete.
## Next Checkpoints
- Task 1-3 complete → Core documentation in place
- Task 4-5 complete → Developer and user resources ready
- Task 8 complete → Sprint can be marked DONE

View File

@@ -1,197 +0,0 @@
# Sprint Batch 20260113_002 - Image Index Resolution CLI
## Executive Summary
This sprint batch implements **OCI multi-arch image inspection** capabilities, enabling users to enumerate image indices, platform manifests, and layer digests through CLI commands. This completes the "index -> manifests -> layers" flow requested in the OCI Layer-Level Image Integrity advisory.
**Scope:** OCI image index resolution with Docker & OCI media type support
**Effort Estimate:** 4-5 story points across 3 sprints
**Priority:** Medium (usability enhancement)
## Background
### Advisory Requirements
The original advisory specified:
> Resolve an image index (if present), list all platform manifests, then for each manifest list ordered layer digests and sizes. Accept Docker and OCI media types.
### Existing Capabilities
| Component | Status | Location |
|-----------|--------|----------|
| `OciIndex` record | EXISTS | `src/Concelier/__Libraries/.../OciIndex.cs` |
| `OciManifest` record | EXISTS | `src/Concelier/__Libraries/.../OciManifest.cs` |
| `OciRegistryClient` | EXISTS | `src/Excititor/__Libraries/.../Fetch/OciRegistryClient.cs` |
| `OciImageReferenceParser` | EXISTS | `src/Cli/StellaOps.Cli/Services/OciImageReferenceParser.cs` |
| `LayeredRootFileSystem` | EXISTS | `src/Scanner/__Libraries/.../FileSystem/LayeredRootFileSystem.cs` |
### Gap Analysis
| Capability | Status |
|------------|--------|
| Parse OCI image index from registry | Partial (records exist, no handler) |
| Walk index -> platform manifests | MISSING |
| CLI `image inspect` verb | MISSING |
| JSON output with canonical digests | MISSING |
## Sprint Index
| Sprint | ID | Module | Topic | Status | Owner |
|--------|-----|--------|-------|--------|-------|
| 1 | SPRINT_20260113_002_001 | SCANNER | OCI Image Index Inspector Service | TODO | Guild - Scanner |
| 2 | SPRINT_20260113_002_002 | CLI | Image Inspect Command | TODO | Guild - CLI |
| 3 | SPRINT_20260113_002_003 | DOCS | Image Inspection Documentation | TODO | Guild - Docs |
## Dependencies
```
+-----------------------------------------------------------------------+
| Dependency Graph |
+-----------------------------------------------------------------------+
| |
| Sprint 1 (Inspector Service) |
| | |
| +------------------+ |
| v v |
| Sprint 2 (CLI) Sprint 3 (Docs) |
| |
+-----------------------------------------------------------------------+
```
- **Sprint 1** is foundational (no dependencies)
- **Sprint 2** depends on Sprint 1 (uses inspector service)
- **Sprint 3** can proceed in parallel with Sprint 2
**Cross-Batch Dependencies:**
- None (this batch is independent of 001)
## Acceptance Criteria (Batch-Level)
### Must Have
1. **Image Index Resolution**
- Accept image reference (tag or digest)
- Detect and parse image index (multi-arch) vs single manifest
- Return platform manifest list with os/arch/variant
2. **Layer Enumeration**
- For each platform manifest: ordered layer digests
- Include layer sizes and media types
- Support both Docker and OCI media types
3. **CLI Command**
- `stella image inspect <reference>` with output formats
- `--resolve-index` flag to walk multi-arch structure
- `--print-layers` flag to include layer details
- JSON output with canonical ordering
4. **Documentation**
- CLI reference for new commands
- Architecture doc for inspector service
### Should Have
- Platform filtering (`--platform linux/amd64`)
- Config blob inspection (`--config` flag)
- Cache manifest responses (in-memory, session-scoped)
### Deferred (Out of Scope)
- `skopeo` or `ctr` CLI integration (use HTTP API)
- Offline image tar inspection (handled by existing LayeredRootFileSystem)
- Image pulling/export (out of scope)
## Technical Context
### Key Files to Create/Extend
| Component | File | Purpose |
|-----------|------|---------|
| Inspector Service | `src/Scanner/__Libraries/StellaOps.Scanner.Storage.Oci/OciImageInspector.cs` | NEW: Unified index/manifest inspection |
| Inspector Models | `src/Scanner/__Libraries/StellaOps.Scanner.Contracts/OciInspectionModels.cs` | NEW: Inspection result models |
| CLI Command | `src/Cli/StellaOps.Cli/Commands/ImageCommandGroup.cs` | NEW: `stella image` command group |
| CLI Handler | `src/Cli/StellaOps.Cli/Commands/CommandHandlers.Image.cs` | NEW: Image command handlers |
### Output Schema
```json
{
"reference": "docker.io/library/nginx:latest",
"resolvedDigest": "sha256:abc123...",
"mediaType": "application/vnd.oci.image.index.v1+json",
"isMultiArch": true,
"platforms": [
{
"os": "linux",
"architecture": "amd64",
"variant": null,
"manifestDigest": "sha256:def456...",
"configDigest": "sha256:ghi789...",
"layers": [
{
"order": 0,
"digest": "sha256:layer1...",
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"size": 31457280
}
],
"totalSize": 157286400
}
],
"inspectedAt": "2026-01-13T12:00:00Z",
"inspectorVersion": "1.0.0"
}
```
### Determinism Requirements
Per CLAUDE.md Section 8:
1. **Ordering**: Platforms sorted by os/arch/variant; layers by order
2. **Timestamps**: From injected `TimeProvider`
3. **JSON serialization**: Canonical key ordering
4. **InvariantCulture**: All size/number formatting
## Risk Assessment
| Risk | Likelihood | Impact | Mitigation |
|------|------------|--------|------------|
| Registry auth complexity | Medium | Medium | Use existing `OciRegistryClient` auth handling |
| Rate limiting on public registries | Low | Low | Implement retry with backoff |
| Non-standard manifest schemas | Low | Medium | Graceful degradation with warnings |
## Success Metrics
- [ ] All unit tests pass
- [ ] Integration tests against Docker Hub, GHCR, and mock registry
- [ ] CLI completions and help work correctly
- [ ] JSON output is valid and deterministic
## Documentation Prerequisites
Before starting implementation, reviewers must read:
- `docs/README.md`
- `docs/ARCHITECTURE_REFERENCE.md`
- `CLAUDE.md` Section 8 (Code Quality & Determinism Rules)
- OCI Image Index Spec: https://github.com/opencontainers/image-spec/blob/main/image-index.md
- OCI Image Manifest Spec: https://specs.opencontainers.org/image-spec/manifest/
## Execution Log
| Date (UTC) | Update | Owner |
|------------|--------|-------|
| 2026-01-13 | Sprint batch created from advisory analysis. | Project Mgmt |
## Decisions & Risks
- **APPROVED 2026-01-13**: Use HTTP Registry API v2 only; no external CLI tool dependencies.
- **APPROVED 2026-01-13**: Single-manifest images return as degenerate case (1-element platform list).
- **RISK**: Some registries may not support OCI index; handle Docker manifest list as fallback.
## Next Checkpoints
- Sprint 1 completion -> Sprint 2 can start
- All sprints complete -> Integration testing checkpoint
- Integrate with Batch 001 CLI commands post-completion

View File

@@ -1,271 +0,0 @@
# Sprint 20260113_002_001_SCANNER - OCI Image Index Inspector Service
## Topic & Scope
- Implement unified OCI image inspection service
- Support image index (multi-arch) and single manifest resolution
- Walk index -> platform manifests -> ordered layers
- Support both Docker and OCI media types
- **Working directory:** `src/Scanner/__Libraries/StellaOps.Scanner.Storage.Oci/`
## Dependencies & Concurrency
- No blocking dependencies (foundational sprint)
- Uses existing `OciRegistryClient` for HTTP operations
- Sprint 2 (CLI) depends on this sprint
## Documentation Prerequisites
- `docs/README.md`
- `docs/ARCHITECTURE_REFERENCE.md`
- `CLAUDE.md` Section 8 (Determinism Rules)
- OCI Image Index Spec: https://github.com/opencontainers/image-spec/blob/main/image-index.md
- OCI Image Manifest Spec: https://specs.opencontainers.org/image-spec/manifest/
- Docker Manifest List: https://docs.docker.com/registry/spec/manifest-v2-2/
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
|---|---------|--------|---------------------------|--------|-----------------|
| 1 | IMG-INSPECT-MODELS-0001 | TODO | None | Guild - Scanner | Define `ImageInspectionResult`, `PlatformManifest`, `LayerInfo` models in `src/Scanner/__Libraries/StellaOps.Scanner.Contracts/OciInspectionModels.cs`. Include all OCI/Docker discriminators. |
| 2 | IMG-INSPECT-INTERFACE-0001 | TODO | Depends on MODELS-0001 | Guild - Scanner | Define `IOciImageInspector` interface with `InspectAsync(reference, options, ct)` signature. Options include: resolveIndex, includeLayers, platformFilter. |
| 3 | IMG-INSPECT-IMPL-0001 | TODO | Depends on INTERFACE-0001 | Guild - Scanner | Implement `OciImageInspector` class. Handle HEAD request for manifest detection, then GET for content. Detect index vs manifest by media type. |
| 4 | IMG-INSPECT-INDEX-0001 | TODO | Depends on IMPL-0001 | Guild - Scanner | Implement index resolution: parse `application/vnd.oci.image.index.v1+json` and `application/vnd.docker.distribution.manifest.list.v2+json`. Extract platform descriptors. |
| 5 | IMG-INSPECT-MANIFEST-0001 | TODO | Depends on IMPL-0001 | Guild - Scanner | Implement manifest parsing: `application/vnd.oci.image.manifest.v1+json` and `application/vnd.docker.distribution.manifest.v2+json`. Extract config and layers. |
| 6 | IMG-INSPECT-LAYERS-0001 | TODO | Depends on MANIFEST-0001 | Guild - Scanner | For each manifest, enumerate layers with: order (0-indexed), digest, mediaType, size. Support compressed and uncompressed variants. |
| 7 | IMG-INSPECT-AUTH-0001 | TODO | Depends on IMPL-0001 | Guild - Scanner | Integrate with existing registry auth: token-based, basic, anonymous. Handle 401 -> token refresh flow. |
| 8 | IMG-INSPECT-DI-0001 | TODO | Depends on all above | Guild - Scanner | Register `IOciImageInspector` in `ServiceCollectionExtensions.cs`. Inject `TimeProvider`, `IHttpClientFactory`, `ILogger`. |
| 9 | IMG-INSPECT-TESTS-0001 | TODO | Depends on all above | Guild - Scanner | Unit tests covering: single manifest, multi-arch index, Docker manifest list, missing manifest, auth errors, malformed responses. |
| 10 | IMG-INSPECT-INTEGRATION-0001 | TODO | Depends on TESTS-0001 | Guild - Scanner | Integration tests against mock OCI registry (testcontainers or in-memory). Test real Docker Hub and GHCR in CI. |
## Technical Specification
### Models
```csharp
namespace StellaOps.Scanner.Contracts;
/// <summary>
/// Result of inspecting an OCI image reference.
/// </summary>
public sealed record ImageInspectionResult
{
/// <summary>Original image reference provided.</summary>
public required string Reference { get; init; }
/// <summary>Resolved digest of the index or manifest.</summary>
public required string ResolvedDigest { get; init; }
/// <summary>Media type of the resolved artifact.</summary>
public required string MediaType { get; init; }
/// <summary>True if this is a multi-arch image index.</summary>
public required bool IsMultiArch { get; init; }
/// <summary>Platform manifests (1 for single-arch, N for multi-arch).</summary>
public required ImmutableArray<PlatformManifest> Platforms { get; init; }
/// <summary>Inspection timestamp (UTC).</summary>
public required DateTimeOffset InspectedAt { get; init; }
/// <summary>Inspector version for reproducibility.</summary>
public required string InspectorVersion { get; init; }
/// <summary>Registry that was queried.</summary>
public required string Registry { get; init; }
/// <summary>Repository name.</summary>
public required string Repository { get; init; }
/// <summary>Warnings encountered during inspection.</summary>
public ImmutableArray<string> Warnings { get; init; } = [];
}
/// <summary>
/// A platform-specific manifest within an image index.
/// </summary>
public sealed record PlatformManifest
{
/// <summary>Operating system (e.g., "linux", "windows").</summary>
public required string Os { get; init; }
/// <summary>CPU architecture (e.g., "amd64", "arm64").</summary>
public required string Architecture { get; init; }
/// <summary>Architecture variant (e.g., "v8" for arm64).</summary>
public string? Variant { get; init; }
/// <summary>OS version (mainly for Windows).</summary>
public string? OsVersion { get; init; }
/// <summary>Digest of this platform's manifest.</summary>
public required string ManifestDigest { get; init; }
/// <summary>Media type of the manifest.</summary>
public required string ManifestMediaType { get; init; }
/// <summary>Digest of the config blob.</summary>
public required string ConfigDigest { get; init; }
/// <summary>Ordered list of layers.</summary>
public required ImmutableArray<LayerInfo> Layers { get; init; }
/// <summary>Total size of all layers in bytes.</summary>
public required long TotalSize { get; init; }
/// <summary>Platform string (os/arch/variant).</summary>
public string PlatformString => Variant is null
? $"{Os}/{Architecture}"
: $"{Os}/{Architecture}/{Variant}";
}
/// <summary>
/// Information about a single layer.
/// </summary>
public sealed record LayerInfo
{
/// <summary>Layer order (0-indexed, application order).</summary>
public required int Order { get; init; }
/// <summary>Layer digest (sha256:...).</summary>
public required string Digest { get; init; }
/// <summary>Media type of the layer blob.</summary>
public required string MediaType { get; init; }
/// <summary>Compressed size in bytes.</summary>
public required long Size { get; init; }
/// <summary>Optional annotations from the manifest.</summary>
public ImmutableDictionary<string, string>? Annotations { get; init; }
}
```
### Interface
```csharp
namespace StellaOps.Scanner.Storage.Oci;
public interface IOciImageInspector
{
/// <summary>
/// Inspects an OCI image reference.
/// </summary>
/// <param name="reference">Image reference (e.g., "nginx:latest", "ghcr.io/org/app@sha256:...").</param>
/// <param name="options">Inspection options.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>Inspection result or null if not found.</returns>
Task<ImageInspectionResult?> InspectAsync(
string reference,
ImageInspectionOptions? options = null,
CancellationToken cancellationToken = default);
}
public sealed record ImageInspectionOptions
{
/// <summary>Resolve multi-arch index to platform manifests (default: true).</summary>
public bool ResolveIndex { get; init; } = true;
/// <summary>Include layer details (default: true).</summary>
public bool IncludeLayers { get; init; } = true;
/// <summary>Filter to specific platform (e.g., "linux/amd64").</summary>
public string? PlatformFilter { get; init; }
/// <summary>Maximum platforms to inspect (default: unlimited).</summary>
public int? MaxPlatforms { get; init; }
/// <summary>Request timeout.</summary>
public TimeSpan? Timeout { get; init; }
}
```
### Media Type Handling
| Media Type | Type | Handling |
|------------|------|----------|
| `application/vnd.oci.image.index.v1+json` | OCI Index | Parse as index, enumerate manifests |
| `application/vnd.docker.distribution.manifest.list.v2+json` | Docker List | Parse as index (compatible) |
| `application/vnd.oci.image.manifest.v1+json` | OCI Manifest | Parse as manifest, extract layers |
| `application/vnd.docker.distribution.manifest.v2+json` | Docker Manifest | Parse as manifest (compatible) |
| Other | Unknown | Return warning, skip or fail per config |
### Algorithm
```pseudo
function InspectAsync(reference, options):
parsed = ParseReference(reference) // registry, repo, tag/digest
// Step 1: Resolve to digest
digest = HEAD(registry, repo, parsed.tagOrDigest)
mediaType = response.headers["Content-Type"]
// Step 2: Get manifest content
body = GET(registry, repo, digest, Accept: mediaType)
// Step 3: Classify and parse
if mediaType in [OCI_INDEX, DOCKER_MANIFEST_LIST]:
index = ParseIndex(body)
platforms = []
for descriptor in index.manifests:
if options.platformFilter and not matches(descriptor, filter):
continue
manifest = await InspectManifest(registry, repo, descriptor.digest)
platforms.append(manifest)
return Result(isMultiArch=true, platforms)
else:
manifest = ParseManifest(body)
platform = ExtractPlatform(manifest.config)
layers = ExtractLayers(manifest)
return Result(isMultiArch=false, [platform])
```
### Determinism Requirements
1. **Platform ordering**: Sort by os ASC, architecture ASC, variant ASC
2. **Layer ordering**: Preserve manifest order (0-indexed)
3. **Timestamps**: From injected `TimeProvider`
4. **JSON**: Canonical serialization for any digest computation
5. **Warnings**: Sorted lexicographically
## Test Cases
### Unit Tests
| Test | Description | Expected |
|------|-------------|----------|
| `Inspect_SingleManifest_ReturnsSinglePlatform` | Image without index | 1 platform, layers present |
| `Inspect_MultiArchIndex_ReturnsAllPlatforms` | Image with 5 platforms | 5 platforms, each with layers |
| `Inspect_DockerManifestList_Parses` | Legacy Docker format | Correctly parsed as index |
| `Inspect_PlatformFilter_ReturnsFiltered` | Filter to linux/amd64 | Only matching platform returned |
| `Inspect_NotFound_ReturnsNull` | 404 response | Returns null, no exception |
| `Inspect_AuthRequired_RefreshesToken` | 401 -> token refresh | Successful after refresh |
| `Inspect_Deterministic_SameOutput` | Same image, multiple calls | Identical result (ignoring timestamp) |
### Integration Tests
| Test | Description | Expected |
|------|-------------|----------|
| `Inspect_DockerHub_NginxLatest` | Public Docker Hub image | Multi-arch result with linux/amd64, linux/arm64 |
| `Inspect_GHCR_PublicImage` | GitHub Container Registry | Valid result |
| `Inspect_MockRegistry_AllScenarios` | Testcontainers registry | All edge cases covered |
## Execution Log
| Date (UTC) | Update | Owner |
|------------|--------|-------|
| 2026-01-13 | Sprint created from advisory analysis. | Project Mgmt |
## Decisions & Risks
- **APPROVED**: Single manifest images return as 1-element platforms array for API consistency.
- **APPROVED**: Use existing `OciRegistryClient` for HTTP operations where compatible.
- **RISK**: Some registries return incorrect Content-Type; handle by sniffing JSON structure.
- **RISK**: Large multi-arch images (10+ platforms) may be slow; add max_platforms limit.
## Next Checkpoints
- Task 1-3 complete -> Basic inspection working
- Task 4-6 complete -> Full index/manifest/layer resolution
- Task 9-10 complete -> Sprint can be marked DONE
- Unblock Sprint 2 (CLI)

View File

@@ -1,283 +0,0 @@
# Sprint 20260113_002_002_CLI - Image Inspect Command
## Topic & Scope
- Implement `stella image inspect` CLI command
- Support `--resolve-index`, `--print-layers`, `--platform` flags
- JSON and human-readable output formats
- Integrate with OCI Image Inspector service
- **Working directory:** `src/Cli/StellaOps.Cli/Commands/`
## Dependencies & Concurrency
- **Depends on:** Sprint 002_001 (OCI Image Inspector Service)
- Parallel work safe within CLI module
- Sprint 3 (Docs) can proceed in parallel
## Documentation Prerequisites
- `docs/README.md`
- `CLAUDE.md` Section 8 (Determinism Rules)
- `src/Cli/StellaOps.Cli/AGENTS.md` (if exists)
- Existing CLI patterns in `LayerSbomCommandGroup.cs`
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
|---|---------|--------|---------------------------|--------|-----------------|
| 1 | CLI-IMAGE-GROUP-0001 | TODO | None | Guild - CLI | Create `ImageCommandGroup.cs` with `stella image` root command and subcommand registration. |
| 2 | CLI-IMAGE-INSPECT-0001 | TODO | Depends on GROUP-0001 | Guild - CLI | Implement `stella image inspect <reference>` command with options: `--resolve-index`, `--print-layers`, `--platform`, `--output`. |
| 3 | CLI-IMAGE-HANDLER-0001 | TODO | Depends on INSPECT-0001, Sprint 001 service | Guild - CLI | Implement `CommandHandlers.Image.cs` with `HandleInspectImageAsync` that calls `IOciImageInspector`. |
| 4 | CLI-IMAGE-OUTPUT-TABLE-0001 | TODO | Depends on HANDLER-0001 | Guild - CLI | Implement table output for human-readable display using Spectre.Console. Show platforms, layers, sizes. |
| 5 | CLI-IMAGE-OUTPUT-JSON-0001 | TODO | Depends on HANDLER-0001 | Guild - CLI | Implement JSON output with canonical ordering. Match schema from Sprint 001 models. |
| 6 | CLI-IMAGE-REGISTER-0001 | TODO | Depends on all above | Guild - CLI | Register `ImageCommandGroup` in `CommandFactory.cs`. Wire DI for `IOciImageInspector`. |
| 7 | CLI-IMAGE-TESTS-0001 | TODO | Depends on all above | Guild - CLI | Unit tests covering: successful inspect, not found, auth error, invalid reference, output formats. |
| 8 | CLI-IMAGE-GOLDEN-0001 | TODO | Depends on TESTS-0001 | Guild - CLI | Golden output tests for determinism: same input produces identical output across runs. |
## Technical Specification
### Command Structure
```
stella image <subcommand>
Subcommands:
inspect Inspect OCI image manifest and layers
```
### `stella image inspect` Command
```
stella image inspect <reference> [options]
Arguments:
<reference> Image reference (e.g., nginx:latest, ghcr.io/org/app@sha256:...)
Options:
--resolve-index, -r Resolve multi-arch index to platform manifests (default: true)
--print-layers, -l Include layer details in output (default: true)
--platform, -p Filter to specific platform (e.g., linux/amd64)
--output, -o Output format: table (default), json
--verbose, -v Show detailed information including warnings
--timeout Request timeout in seconds (default: 60)
Examples:
stella image inspect nginx:latest
stella image inspect nginx:latest --output json
stella image inspect nginx:latest --platform linux/arm64
stella image inspect ghcr.io/org/app@sha256:abc123... --print-layers
```
### Output Examples
#### Table Output (Default)
```
Image: nginx:latest
Resolved Digest: sha256:abc123...
Media Type: application/vnd.oci.image.index.v1+json
Multi-Arch: Yes (5 platforms)
Platforms:
+-------+--------------+----------+---------+---------------+------------+
| OS | Architecture | Variant | Layers | Total Size | Manifest |
+-------+--------------+----------+---------+---------------+------------+
| linux | amd64 | - | 7 | 142.3 MB | sha256:... |
| linux | arm64 | v8 | 7 | 138.1 MB | sha256:... |
| linux | arm | v7 | 7 | 135.2 MB | sha256:... |
| linux | 386 | - | 7 | 145.8 MB | sha256:... |
| linux | ppc64le | - | 7 | 148.5 MB | sha256:... |
+-------+--------------+----------+---------+---------------+------------+
Layers (linux/amd64):
+-------+------------------+------------------------------------------------+----------+
| Order | Size | Digest | Type |
+-------+------------------+------------------------------------------------+----------+
| 0 | 31.4 MB | sha256:a803e7c4b030... | tar+gzip |
| 1 | 62.5 MB | sha256:8a6e7b1c9d2e... | tar+gzip |
| ... | ... | ... | ... |
+-------+------------------+------------------------------------------------+----------+
Inspected at: 2026-01-13T12:00:00Z
```
#### JSON Output
```json
{
"reference": "nginx:latest",
"resolvedDigest": "sha256:abc123...",
"mediaType": "application/vnd.oci.image.index.v1+json",
"isMultiArch": true,
"registry": "docker.io",
"repository": "library/nginx",
"platforms": [
{
"os": "linux",
"architecture": "amd64",
"variant": null,
"manifestDigest": "sha256:def456...",
"configDigest": "sha256:ghi789...",
"layers": [
{
"order": 0,
"digest": "sha256:layer1...",
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"size": 31457280
}
],
"totalSize": 157286400
}
],
"inspectedAt": "2026-01-13T12:00:00Z",
"inspectorVersion": "1.0.0"
}
```
### Implementation
```csharp
// ImageCommandGroup.cs
namespace StellaOps.Cli.Commands;
public static class ImageCommandGroup
{
public static Command Build(
IServiceProvider services,
StellaOpsCliOptions options,
Option<bool> verboseOption,
CancellationToken cancellationToken)
{
var imageCommand = new Command("image", "OCI image operations");
imageCommand.AddCommand(BuildInspectCommand(services, options, verboseOption, cancellationToken));
return imageCommand;
}
private static Command BuildInspectCommand(
IServiceProvider services,
StellaOpsCliOptions options,
Option<bool> verboseOption,
CancellationToken cancellationToken)
{
var referenceArg = new Argument<string>("reference")
{
Description = "Image reference (e.g., nginx:latest, ghcr.io/org/app@sha256:...)"
};
var resolveIndexOption = new Option<bool>("--resolve-index", new[] { "-r" })
{
Description = "Resolve multi-arch index to platform manifests",
DefaultValue = true
};
var printLayersOption = new Option<bool>("--print-layers", new[] { "-l" })
{
Description = "Include layer details in output",
DefaultValue = true
};
var platformOption = new Option<string?>("--platform", new[] { "-p" })
{
Description = "Filter to specific platform (e.g., linux/amd64)"
};
var outputOption = new Option<string>("--output", new[] { "-o" })
{
Description = "Output format: table (default), json"
};
var timeoutOption = new Option<int>("--timeout")
{
Description = "Request timeout in seconds",
DefaultValue = 60
};
var inspect = new Command("inspect", "Inspect OCI image manifest and layers")
{
referenceArg,
resolveIndexOption,
printLayersOption,
platformOption,
outputOption,
timeoutOption,
verboseOption
};
inspect.SetAction(async (parseResult, _) =>
{
var reference = parseResult.GetValue(referenceArg) ?? string.Empty;
var resolveIndex = parseResult.GetValue(resolveIndexOption);
var printLayers = parseResult.GetValue(printLayersOption);
var platform = parseResult.GetValue(platformOption);
var output = parseResult.GetValue(outputOption) ?? "table";
var timeout = parseResult.GetValue(timeoutOption);
var verbose = parseResult.GetValue(verboseOption);
return await CommandHandlers.HandleInspectImageAsync(
services, reference, resolveIndex, printLayers,
platform, output, timeout, verbose, cancellationToken);
});
return inspect;
}
}
```
### Error Handling
| Scenario | Exit Code | Message |
|----------|-----------|---------|
| Success | 0 | (output) |
| Image not found | 1 | `Error: Image not found: <reference>` |
| Auth required | 2 | `Error: Authentication required for <registry>` |
| Invalid reference | 2 | `Error: Invalid image reference: <reference>` |
| Network error | 2 | `Error: Network error: <message>` |
| Timeout | 2 | `Error: Request timed out` |
### Determinism Requirements
1. **Ordering**: JSON keys sorted; platforms sorted by os/arch/variant
2. **Size formatting**: Use InvariantCulture for all numbers
3. **Timestamps**: Display as UTC ISO-8601
4. **Digest truncation**: Consistent truncation (e.g., first 12 chars for display)
## Test Cases
### Unit Tests
| Test | Description | Expected |
|------|-------------|----------|
| `Inspect_ValidReference_ReturnsSuccess` | Mock successful inspection | Exit code 0, valid output |
| `Inspect_NotFound_ReturnsError` | 404 from registry | Exit code 1, error message |
| `Inspect_InvalidReference_ReturnsError` | Malformed reference | Exit code 2, validation error |
| `Inspect_JsonOutput_ValidJson` | Request JSON format | Parseable JSON output |
| `Inspect_TableOutput_FormatsCorrectly` | Default table format | Table with headers and rows |
| `Inspect_PlatformFilter_FiltersResults` | Filter to linux/amd64 | Only matching platform in output |
### Golden Output Tests
| Test | Description | Expected |
|------|-------------|----------|
| `Inspect_Json_Deterministic` | Same input, multiple runs | Byte-identical JSON |
| `Inspect_Table_Deterministic` | Same input, multiple runs | Identical table output |
## Execution Log
| Date (UTC) | Update | Owner |
|------------|--------|-------|
| 2026-01-13 | Sprint created from advisory analysis. | Project Mgmt |
## Decisions & Risks
- **APPROVED**: Table output as default (more user-friendly).
- **APPROVED**: JSON output matches service model exactly (no transformation).
- **RISK**: CLI tests may conflict with other agent work; coordinate ownership.
- **RISK**: Table formatting may truncate long digests; use consistent truncation.
## Next Checkpoints
- Task 1-3 complete -> Basic command working
- Task 4-5 complete -> Both output formats working
- Task 7-8 complete -> Sprint can be marked DONE

View File

@@ -1,102 +0,0 @@
# Sprint 20260113_002_003_DOCS - Image Inspection Documentation
## Topic & Scope
- Document OCI Image Inspector architecture
- Create CLI reference for `stella image inspect`
- Add usage examples and troubleshooting guide
- **Working directory:** `docs/`
## Dependencies & Concurrency
- Can proceed in parallel with Sprint 002_002
- Should finalize after Sprint 002_001 models are stable
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
|---|---------|--------|---------------------------|--------|-----------------|
| 1 | DOCS-IMAGE-ARCH-0001 | TODO | Sprint 001 complete | Guild - Docs | Create `docs/modules/scanner/image-inspection.md` documenting the OCI Image Inspector service architecture, supported media types, and integration points. |
| 2 | DOCS-IMAGE-CLI-0001 | TODO | Sprint 002 complete | Guild - Docs | Add `stella image inspect` to CLI reference in `docs/API_CLI_REFERENCE.md`. Include all options, examples, and exit codes. |
| 3 | DOCS-IMAGE-EXAMPLES-0001 | TODO | Depends on CLI-0001 | Guild - Docs | Create practical usage examples in `docs/guides/image-inspection-guide.md` covering Docker Hub, GHCR, private registries, and CI/CD integration. |
| 4 | DOCS-IMAGE-TROUBLESHOOT-0001 | TODO | Depends on EXAMPLES-0001 | Guild - Docs | Add troubleshooting section for common issues: auth failures, rate limits, unsupported media types. |
## Technical Specification
### Architecture Documentation Outline
```markdown
# OCI Image Inspection
## Overview
- Purpose and use cases
- Supported registries and media types
## Architecture
- IOciImageInspector interface
- Index vs manifest resolution flow
- Platform enumeration algorithm
## Media Type Support
| Media Type | Description | Support |
|------------|-------------|---------|
| ... | ... | ... |
## Integration Points
- CLI integration
- Programmatic usage
- Webhook/CI integration
## Configuration
- Registry authentication
- Timeout and retry settings
## Determinism
- Output ordering guarantees
- Reproducibility considerations
```
### CLI Reference Addition
```markdown
## stella image inspect
Inspect OCI image manifest and layers.
### Synopsis
stella image inspect <reference> [options]
### Arguments
| Argument | Description |
|----------|-------------|
| reference | Image reference (tag or digest) |
### Options
| Option | Description | Default |
|--------|-------------|---------|
| --resolve-index, -r | Resolve multi-arch index | true |
| --print-layers, -l | Include layer details | true |
| --platform, -p | Platform filter | (all) |
| --output, -o | Output format (table, json) | table |
### Examples
...
### Exit Codes
| Code | Meaning |
|------|---------|
| 0 | Success |
| 1 | Image not found |
| 2 | Error (auth, network, invalid input) |
```
## Execution Log
| Date (UTC) | Update | Owner |
|------------|--------|-------|
| 2026-01-13 | Sprint created from advisory analysis. | Project Mgmt |
## Next Checkpoints
- All tasks complete -> Sprint can be marked DONE
- Coordinate with Sprint 002_001/002 for accuracy

View File

@@ -1,233 +0,0 @@
# Sprint Batch 20260113_003 - VEX Evidence Auto-Linking
## Executive Summary
This sprint batch implements **automatic linking** between VEX exploitability status and DSSE binary-diff evidence bundles. When a binary analysis determines a vulnerability is "not_affected" due to a vendor backport, the system automatically links the VEX assertion to the cryptographic evidence that proves the claim.
**Scope:** VEX-to-evidence linking for binary-diff attestations
**Effort Estimate:** 3-4 story points across 2 sprints
**Priority:** Medium (completes evidence chain)
## Background
### Advisory Requirements
The original advisory specified:
> Surface exploitability conclusions via CycloneDX VEX (e.g., "CVE-X.Y not affected due to backported fix; evidence -> DSSE bundle link").
> For each CVE in SBOM components, attach exploitability status with `analysis.justification` ("component_not_present", "vulnerable_code_not_in_execute_path", "fixed", etc.) and `analysis.detail` linking the DSSE evidence URI.
### Existing Capabilities
| Component | Status | Location |
|-----------|--------|----------|
| `VexPredicate` | EXISTS | `src/Attestor/__Libraries/.../Predicates/VexPredicate.cs` |
| `VexDeltaEntity` | EXISTS | `src/Excititor/__Libraries/.../Observations/VexDeltaModels.cs` |
| `CycloneDxExporter` | EXISTS | `src/Excititor/__Libraries/.../CycloneDxExporter.cs` |
| `BinaryDiffV1 Predicate` | IN PROGRESS | Batch 001 Sprint 002 |
| `BinaryDiffDsseSigner` | IN PROGRESS | Batch 001 Sprint 002 |
### Gap Analysis
| Capability | Status |
|------------|--------|
| Store DSSE bundle URIs with VEX assertions | MISSING |
| Auto-link binary-diff evidence to VEX | MISSING |
| Emit `analysis.detail` with evidence URI in CycloneDX VEX | MISSING |
| CLI `stella vex gen` with evidence links | PARTIAL |
## Sprint Index
| Sprint | ID | Module | Topic | Status | Owner |
|--------|-----|--------|-------|--------|-------|
| 1 | SPRINT_20260113_003_001 | EXCITITOR | VEX Evidence Linker Service | TODO | Guild - Excititor |
| 2 | SPRINT_20260113_003_002 | CLI | VEX Generation with Evidence Links | TODO | Guild - CLI |
## Dependencies
```
+-----------------------------------------------------------------------+
| Dependency Graph |
+-----------------------------------------------------------------------+
| |
| Batch 001 (Binary Diff Attestation) |
| | |
| v |
| Sprint 1 (VEX Evidence Linker) |
| | |
| v |
| Sprint 2 (CLI Integration) |
| |
+-----------------------------------------------------------------------+
```
**Cross-Batch Dependencies:**
- Batch 001 Sprint 002 (BinaryDiffV1 predicate) must be complete
- VEX Evidence Linker consumes DSSE bundle URIs from binary diff
## Acceptance Criteria (Batch-Level)
### Must Have
1. **Evidence URI Storage**
- Store DSSE bundle URIs alongside VEX assertions
- Support multiple evidence sources per VEX entry
- URIs point to OCI artifact digests or CAS addresses
2. **Auto-Link on Binary Diff**
- When binary diff detects "patched" verdict, create VEX link
- Link includes: DSSE envelope digest, predicate type, confidence score
- Justification auto-set to "vulnerable_code_not_in_execute_path" or "code_not_reachable"
3. **CycloneDX VEX Output**
- `analysis.detail` contains evidence URI
- `analysis.response` includes evidence metadata
- Compatible with CycloneDX VEX 1.5+ schema
4. **CLI Integration**
- `stella vex gen` includes `--link-evidence` flag
- JSON output contains evidence links
- Human-readable output shows evidence summary
### Should Have
- Confidence threshold filtering (only link if confidence >= X)
- Evidence chain validation (verify DSSE before linking)
### Deferred (Out of Scope)
- UI for evidence visualization (follow-up sprint)
- Evidence refresh/update workflow
- Third-party evidence import
## Technical Context
### Key Files to Create/Extend
| Component | File | Purpose |
|-----------|------|---------|
| Evidence Linker | `src/Excititor/__Libraries/StellaOps.Excititor.Core/Evidence/VexEvidenceLinker.cs` | NEW: Service to link VEX -> DSSE |
| Evidence Models | `src/Excititor/__Libraries/StellaOps.Excititor.Core/Evidence/VexEvidenceLinkModels.cs` | NEW: Link models |
| CycloneDX Mapper | `src/Excititor/__Libraries/.../CycloneDxVexMapper.cs` | EXTEND: Add evidence links |
| CLI Handler | `src/Cli/StellaOps.Cli/Commands/VexGenCommandGroup.cs` | EXTEND: Add evidence option |
### VEX with Evidence Link Schema (CycloneDX)
```json
{
"bomFormat": "CycloneDX",
"specVersion": "1.6",
"vulnerabilities": [
{
"id": "CVE-2023-12345",
"source": { "name": "NVD" },
"analysis": {
"state": "not_affected",
"justification": "code_not_reachable",
"detail": "Binary analysis confirms vendor backport applied. Evidence: oci://registry.example.com/evidence@sha256:abc123",
"response": ["update"],
"firstIssued": "2026-01-13T12:00:00Z"
},
"affects": [
{
"ref": "urn:cdx:stellaops/app@1.0.0/libssl.so.3",
"versions": [{ "version": "3.0.2", "status": "unaffected" }]
}
],
"properties": [
{
"name": "stellaops:evidence:type",
"value": "binary-diff"
},
{
"name": "stellaops:evidence:uri",
"value": "oci://registry.example.com/evidence@sha256:abc123..."
},
{
"name": "stellaops:evidence:confidence",
"value": "0.95"
},
{
"name": "stellaops:evidence:predicate-type",
"value": "stellaops.binarydiff.v1"
}
]
}
]
}
```
### Evidence Link Model
```csharp
public sealed record VexEvidenceLink
{
/// <summary>Type of evidence (binary-diff, reachability, runtime, etc.).</summary>
public required string EvidenceType { get; init; }
/// <summary>URI to the DSSE bundle (oci://, cas://, file://).</summary>
public required string EvidenceUri { get; init; }
/// <summary>Digest of the DSSE envelope.</summary>
public required string EnvelopeDigest { get; init; }
/// <summary>Predicate type in the DSSE envelope.</summary>
public required string PredicateType { get; init; }
/// <summary>Confidence score (0.0-1.0).</summary>
public required double Confidence { get; init; }
/// <summary>When the evidence was created.</summary>
public required DateTimeOffset CreatedAt { get; init; }
/// <summary>Signer identity (key ID or certificate subject).</summary>
public string? SignerIdentity { get; init; }
/// <summary>Rekor log index if submitted to transparency log.</summary>
public string? RekorLogIndex { get; init; }
}
```
## Risk Assessment
| Risk | Likelihood | Impact | Mitigation |
|------|------------|--------|------------|
| Evidence URI format inconsistency | Medium | Medium | Define URI schema spec; validate on link |
| Stale evidence links | Medium | Low | Include evidence timestamp; optional refresh |
| Large evidence bundles | Low | Medium | Link to bundle, don't embed content |
## Success Metrics
- [ ] VEX output includes evidence links when available
- [ ] Evidence URIs resolve to valid DSSE bundles
- [ ] CLI shows evidence in human-readable format
- [ ] CycloneDX VEX validates against schema
## Documentation Prerequisites
Before starting implementation, reviewers must read:
- `docs/README.md`
- `docs/ARCHITECTURE_REFERENCE.md`
- `CLAUDE.md` Section 8 (Code Quality & Determinism Rules)
- CycloneDX VEX specification: https://cyclonedx.org/capabilities/vex/
- Batch 001 BinaryDiffV1 predicate schema
## Execution Log
| Date (UTC) | Update | Owner |
|------------|--------|-------|
| 2026-01-13 | Sprint batch created from advisory analysis. | Project Mgmt |
## Decisions & Risks
- **APPROVED 2026-01-13**: Evidence stored as URI references, not embedded content.
- **APPROVED 2026-01-13**: Use CycloneDX `properties[]` for Stella-specific evidence metadata.
- **RISK**: CycloneDX `analysis.detail` has length limits; use URI not full content.
## Next Checkpoints
- Batch 001 Sprint 002 complete -> Sprint 1 can start
- Sprint 1 complete -> Sprint 2 can start
- All sprints complete -> Integration testing checkpoint

View File

@@ -1,377 +0,0 @@
# Sprint 20260113_003_001_EXCITITOR - VEX Evidence Linker Service
## Topic & Scope
- Implement VEX-to-evidence linking service
- Auto-link binary-diff attestations to VEX assertions
- Store evidence URIs alongside VEX entries
- Emit evidence metadata in CycloneDX VEX output
- **Working directory:** `src/Excititor/__Libraries/StellaOps.Excititor.Core/`
## Dependencies & Concurrency
- **Depends on:** Batch 001 Sprint 002 (BinaryDiffV1 predicate)
- Parallel work safe within Excititor module
- Sprint 2 (CLI) depends on this sprint
## Documentation Prerequisites
- `docs/README.md`
- `CLAUDE.md` Section 8 (Determinism Rules)
- CycloneDX VEX specification: https://cyclonedx.org/capabilities/vex/
- Batch 001 BinaryDiffV1 predicate schema
- Existing VEX models in `src/Excititor/__Libraries/.../VexDeltaModels.cs`
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
|---|---------|--------|---------------------------|--------|-----------------|
| 1 | VEX-LINK-MODELS-0001 | TODO | None | Guild - Excititor | Define `VexEvidenceLink`, `VexEvidenceLinkSet`, and `EvidenceType` enum in `Evidence/VexEvidenceLinkModels.cs`. Include URI, digest, predicate type, confidence, timestamps. |
| 2 | VEX-LINK-INTERFACE-0001 | TODO | Depends on MODELS-0001 | Guild - Excititor | Define `IVexEvidenceLinker` interface with `LinkAsync(vexEntry, evidenceSource, ct)` and `GetLinksAsync(vexEntryId, ct)` methods. |
| 3 | VEX-LINK-BINARYDIFF-0001 | TODO | Depends on INTERFACE-0001, Batch 001 | Guild - Excititor | Implement `BinaryDiffEvidenceLinker` that extracts evidence from `BinaryDiffPredicate` findings and creates `VexEvidenceLink` entries. |
| 4 | VEX-LINK-STORE-0001 | TODO | Depends on MODELS-0001 | Guild - Excititor | Implement `IVexEvidenceLinkStore` interface and in-memory implementation. Define PostgreSQL schema for persistent storage. |
| 5 | VEX-LINK-AUTOLINK-0001 | TODO | Depends on BINARYDIFF-0001 | Guild - Excititor | Implement auto-linking pipeline: when binary-diff produces "patched" verdict, create VEX link with appropriate justification. |
| 6 | VEX-LINK-CYCLONEDX-0001 | TODO | Depends on AUTOLINK-0001 | Guild - Excititor | Extend `CycloneDxVexMapper` to emit `analysis.detail` with evidence URI and `properties[]` with evidence metadata. |
| 7 | VEX-LINK-VALIDATION-0001 | TODO | Depends on all above | Guild - Excititor | Implement evidence validation: verify DSSE signature before accepting link. Optional: verify Rekor inclusion. |
| 8 | VEX-LINK-DI-0001 | TODO | Depends on all above | Guild - Excititor | Register all services in DI. Add `IOptions<VexEvidenceLinkOptions>` for configuration (confidence threshold, validation mode). |
| 9 | VEX-LINK-TESTS-0001 | TODO | Depends on all above | Guild - Excititor | Unit tests covering: link creation, storage, auto-linking, CycloneDX output, validation success/failure. |
## Technical Specification
### Models
```csharp
namespace StellaOps.Excititor.Core.Evidence;
/// <summary>
/// Link between a VEX assertion and supporting evidence.
/// </summary>
public sealed record VexEvidenceLink
{
/// <summary>Unique link identifier.</summary>
public required string LinkId { get; init; }
/// <summary>VEX entry this evidence supports.</summary>
public required string VexEntryId { get; init; }
/// <summary>Type of evidence.</summary>
public required EvidenceType EvidenceType { get; init; }
/// <summary>URI to the evidence artifact (oci://, cas://, https://).</summary>
public required string EvidenceUri { get; init; }
/// <summary>Digest of the DSSE envelope (sha256:...).</summary>
public required string EnvelopeDigest { get; init; }
/// <summary>Predicate type in the DSSE envelope.</summary>
public required string PredicateType { get; init; }
/// <summary>Confidence score from the evidence (0.0-1.0).</summary>
public required double Confidence { get; init; }
/// <summary>Justification derived from evidence.</summary>
public required VexJustification Justification { get; init; }
/// <summary>When the evidence was created.</summary>
public required DateTimeOffset EvidenceCreatedAt { get; init; }
/// <summary>When the link was created.</summary>
public required DateTimeOffset LinkedAt { get; init; }
/// <summary>Signer identity (key ID or certificate subject).</summary>
public string? SignerIdentity { get; init; }
/// <summary>Rekor log index if submitted to transparency log.</summary>
public string? RekorLogIndex { get; init; }
/// <summary>Whether the evidence signature was validated.</summary>
public bool SignatureValidated { get; init; }
/// <summary>Additional metadata as key-value pairs.</summary>
public ImmutableDictionary<string, string> Metadata { get; init; }
= ImmutableDictionary<string, string>.Empty;
}
/// <summary>
/// Types of evidence that can support VEX assertions.
/// </summary>
public enum EvidenceType
{
/// <summary>Binary-level diff showing patch applied.</summary>
BinaryDiff,
/// <summary>Call graph analysis showing code not reachable.</summary>
ReachabilityAnalysis,
/// <summary>Runtime analysis showing code not executed.</summary>
RuntimeAnalysis,
/// <summary>Human attestation (manual review).</summary>
HumanAttestation,
/// <summary>Vendor advisory or statement.</summary>
VendorAdvisory,
/// <summary>Other/custom evidence type.</summary>
Other
}
/// <summary>
/// VEX justification codes (CycloneDX compatible).
/// </summary>
public enum VexJustification
{
CodeNotPresent,
CodeNotReachable,
RequiresConfiguration,
RequiresDependency,
RequiresEnvironment,
ProtectedByCompiler,
ProtectedAtRuntime,
ProtectedAtPerimeter,
ProtectedByMitigatingControl
}
/// <summary>
/// Collection of evidence links for a VEX entry.
/// </summary>
public sealed record VexEvidenceLinkSet
{
/// <summary>VEX entry ID.</summary>
public required string VexEntryId { get; init; }
/// <summary>All evidence links, sorted by confidence descending.</summary>
public required ImmutableArray<VexEvidenceLink> Links { get; init; }
/// <summary>Highest confidence among all links.</summary>
public double MaxConfidence => Links.IsEmpty ? 0 : Links.Max(l => l.Confidence);
/// <summary>Primary link (highest confidence).</summary>
public VexEvidenceLink? PrimaryLink => Links.IsEmpty ? null : Links[0];
}
```
### Interfaces
```csharp
namespace StellaOps.Excititor.Core.Evidence;
/// <summary>
/// Service for linking VEX assertions to supporting evidence.
/// </summary>
public interface IVexEvidenceLinker
{
/// <summary>
/// Creates a link between a VEX entry and evidence.
/// </summary>
Task<VexEvidenceLink> LinkAsync(
string vexEntryId,
EvidenceSource source,
CancellationToken cancellationToken = default);
/// <summary>
/// Gets all evidence links for a VEX entry.
/// </summary>
Task<VexEvidenceLinkSet> GetLinksAsync(
string vexEntryId,
CancellationToken cancellationToken = default);
/// <summary>
/// Auto-links evidence from a binary diff result.
/// </summary>
Task<ImmutableArray<VexEvidenceLink>> AutoLinkFromBinaryDiffAsync(
BinaryDiffPredicate diff,
string dsseEnvelopeUri,
CancellationToken cancellationToken = default);
}
/// <summary>
/// Source of evidence for linking.
/// </summary>
public sealed record EvidenceSource
{
/// <summary>Evidence type.</summary>
public required EvidenceType Type { get; init; }
/// <summary>URI to the evidence artifact.</summary>
public required string Uri { get; init; }
/// <summary>Digest of the artifact.</summary>
public required string Digest { get; init; }
/// <summary>Predicate type if DSSE/in-toto.</summary>
public string? PredicateType { get; init; }
/// <summary>Confidence score.</summary>
public double Confidence { get; init; } = 1.0;
/// <summary>DSSE envelope bytes for validation.</summary>
public byte[]? EnvelopeBytes { get; init; }
}
/// <summary>
/// Storage for evidence links.
/// </summary>
public interface IVexEvidenceLinkStore
{
Task SaveAsync(VexEvidenceLink link, CancellationToken ct = default);
Task<VexEvidenceLink?> GetAsync(string linkId, CancellationToken ct = default);
Task<ImmutableArray<VexEvidenceLink>> GetByVexEntryAsync(string vexEntryId, CancellationToken ct = default);
Task DeleteAsync(string linkId, CancellationToken ct = default);
}
```
### Auto-Link Algorithm
```pseudo
function AutoLinkFromBinaryDiff(diff, dsseUri):
links = []
for finding in diff.findings where finding.verdict == Patched:
// Determine affected VEX entry
vexEntryId = LookupVexEntry(finding.path, diff.inputs.target)
if vexEntryId is null:
continue // No matching VEX entry
// Determine justification from finding
justification = DetermineJustification(finding)
// Create link
link = VexEvidenceLink {
linkId: GenerateId(vexEntryId, dsseUri),
vexEntryId: vexEntryId,
evidenceType: BinaryDiff,
evidenceUri: dsseUri,
envelopeDigest: ComputeDigest(diff),
predicateType: "stellaops.binarydiff.v1",
confidence: finding.confidence ?? 0.9,
justification: justification,
evidenceCreatedAt: diff.metadata.analysisTimestamp,
linkedAt: timeProvider.GetUtcNow()
}
links.append(link)
return links
function DetermineJustification(finding):
// If .text section changed -> code was patched
if finding.sectionDeltas.any(d => d.section == ".text" && d.status == Modified):
return CodeNotPresent // Vulnerable code removed/replaced
// If only .rodata changed -> data patched
if finding.sectionDeltas.all(d => d.section != ".text"):
return ProtectedAtRuntime // Runtime behavior changed
return CodeNotReachable // Default for verified patches
```
### CycloneDX Output Enhancement
```csharp
// In CycloneDxVexMapper
private void MapEvidenceLinks(VulnerabilityAnalysis analysis, VexEvidenceLinkSet links)
{
if (links.PrimaryLink is null) return;
var primary = links.PrimaryLink;
// Set analysis.detail with evidence URI
analysis.Detail = $"Evidence: {primary.EvidenceUri}";
// Add evidence properties
analysis.Properties ??= [];
analysis.Properties.Add(new Property
{
Name = "stellaops:evidence:type",
Value = primary.EvidenceType.ToString().ToLowerInvariant()
});
analysis.Properties.Add(new Property
{
Name = "stellaops:evidence:uri",
Value = primary.EvidenceUri
});
analysis.Properties.Add(new Property
{
Name = "stellaops:evidence:confidence",
Value = primary.Confidence.ToString("F2", CultureInfo.InvariantCulture)
});
analysis.Properties.Add(new Property
{
Name = "stellaops:evidence:predicate-type",
Value = primary.PredicateType
});
if (primary.RekorLogIndex is not null)
{
analysis.Properties.Add(new Property
{
Name = "stellaops:evidence:rekor-index",
Value = primary.RekorLogIndex
});
}
}
```
### Configuration
```yaml
excititor:
evidence:
linking:
enabled: true
autoLinkOnBinaryDiff: true
confidenceThreshold: 0.8
validateSignatures: true
validateRekorInclusion: false
maxLinksPerEntry: 10
```
## Determinism Requirements
1. **Link ID generation**: Deterministic from vexEntryId + evidenceUri
2. **Ordering**: Links sorted by confidence DESC, then by linkedAt ASC
3. **Timestamps**: From injected `TimeProvider`
4. **Confidence formatting**: Two decimal places, InvariantCulture
## Test Cases
### Unit Tests
| Test | Description | Expected |
|------|-------------|----------|
| `Link_ValidSource_CreatesLink` | Link with valid evidence | Link created with correct fields |
| `Link_DuplicateSource_Deduplicates` | Same source linked twice | Single link returned |
| `AutoLink_PatchedFinding_CreatesLinks` | Binary diff with patched verdict | Links created for affected entries |
| `AutoLink_VanillaFinding_NoLinks` | Binary diff with vanilla verdict | No links created |
| `GetLinks_ExistingEntry_ReturnsSet` | Query by VEX entry ID | All links returned, sorted |
| `MapCycloneDx_WithLinks_IncludesEvidence` | CycloneDX export with links | Properties contain evidence metadata |
| `Validate_ValidSignature_Succeeds` | DSSE with valid signature | Validation passes |
| `Validate_InvalidSignature_Rejects` | DSSE with bad signature | Validation fails, link rejected |
### Integration Tests
| Test | Description | Expected |
|------|-------------|----------|
| `EndToEnd_BinaryDiffToVex_LinksEvidence` | Full pipeline from diff to VEX | VEX output contains evidence links |
## Execution Log
| Date (UTC) | Update | Owner |
|------------|--------|-------|
| 2026-01-13 | Sprint created from advisory analysis. | Project Mgmt |
## Decisions & Risks
- **APPROVED**: Evidence stored as URIs, not embedded content.
- **APPROVED**: Auto-link only for high-confidence findings (>= threshold).
- **RISK**: Signature validation may fail for offline evidence; add bypass option.
- **RISK**: VEX entry lookup requires correlation logic; may need component PURL matching.
## Next Checkpoints
- Task 1-4 complete -> Core linking operational
- Task 5-6 complete -> Auto-link and CycloneDX working
- Task 9 complete -> Sprint can be marked DONE
- Unblock Sprint 2 (CLI)

View File

@@ -1,132 +0,0 @@
# Sprint 20260113_003_002_CLI - VEX Generation with Evidence Links
## Topic & Scope
- Extend `stella vex gen` command with evidence linking
- Add `--link-evidence` flag to include binary-diff evidence
- Display evidence summary in human-readable output
- Emit evidence metadata in JSON output
- **Working directory:** `src/Cli/StellaOps.Cli/Commands/`
## Dependencies & Concurrency
- **Depends on:** Sprint 003_001 (VEX Evidence Linker)
- Extends existing `VexGenCommandGroup.cs`
## Documentation Prerequisites
- `docs/README.md`
- `CLAUDE.md` Section 8 (Determinism Rules)
- Existing VEX CLI in `src/Cli/StellaOps.Cli/Commands/VexGenCommandGroup.cs`
- Sprint 003_001 models and interfaces
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
|---|---------|--------|---------------------------|--------|-----------------|
| 1 | CLI-VEX-EVIDENCE-OPT-0001 | TODO | None | Guild - CLI | Add `--link-evidence` option to `stella vex gen` command. Default: true if evidence available. |
| 2 | CLI-VEX-EVIDENCE-HANDLER-0001 | TODO | Depends on OPT-0001, Sprint 001 | Guild - CLI | Extend VEX generation handler to call `IVexEvidenceLinker.GetLinksAsync()` and include in output. |
| 3 | CLI-VEX-EVIDENCE-JSON-0001 | TODO | Depends on HANDLER-0001 | Guild - CLI | Emit evidence links in JSON output under `evidence` key per vulnerability. |
| 4 | CLI-VEX-EVIDENCE-TABLE-0001 | TODO | Depends on HANDLER-0001 | Guild - CLI | Show evidence summary in table output: type, confidence, URI (truncated). |
| 5 | CLI-VEX-EVIDENCE-TESTS-0001 | TODO | Depends on all above | Guild - CLI | Unit tests for evidence flag, output formats, missing evidence handling. |
## Technical Specification
### Command Enhancement
```
stella vex gen <scan-id> [options]
Existing options:
--output, -o Output format (json, table, cyclonedx)
--format, -f VEX format (openvex, cyclonedx)
New options:
--link-evidence Include evidence links in output (default: true)
--evidence-threshold Minimum confidence for evidence (default: 0.8)
--show-evidence-uri Show full evidence URIs (default: truncated)
```
### Output Examples
#### Table Output with Evidence
```
VEX Report for scan abc123
+----------------+-------------+----------------+------------+------------------+
| CVE | Component | Status | Confidence | Evidence |
+----------------+-------------+----------------+------------+------------------+
| CVE-2023-12345 | libssl.so.3 | not_affected | 0.95 | binary-diff [OK] |
| CVE-2023-67890 | libcrypto | affected | - | (none) |
| CVE-2024-11111 | nginx | not_affected | 0.88 | reachability |
+----------------+-------------+----------------+------------+------------------+
Evidence Details:
CVE-2023-12345: oci://registry/evidence@sha256:abc123...
Type: binary-diff, Predicate: stellaops.binarydiff.v1
Signer: CN=StellaOps Signing Key
```
#### JSON Output with Evidence
```json
{
"scanId": "abc123",
"generatedAt": "2026-01-13T12:00:00Z",
"vulnerabilities": [
{
"id": "CVE-2023-12345",
"component": "libssl.so.3",
"status": "not_affected",
"justification": "code_not_present",
"evidence": {
"type": "binary-diff",
"uri": "oci://registry/evidence@sha256:abc123...",
"confidence": 0.95,
"predicateType": "stellaops.binarydiff.v1",
"validatedSignature": true,
"rekorIndex": "12345678"
}
}
]
}
```
### Implementation Notes
```csharp
// Extend HandleVexGenAsync
if (linkEvidence)
{
var linker = services.GetRequiredService<IVexEvidenceLinker>();
foreach (var entry in vexEntries)
{
var links = await linker.GetLinksAsync(entry.Id, ct);
if (links.PrimaryLink is not null && links.MaxConfidence >= evidenceThreshold)
{
entry.Evidence = links.PrimaryLink;
}
}
}
```
## Test Cases
| Test | Description | Expected |
|------|-------------|----------|
| `VexGen_WithEvidence_IncludesLinks` | Evidence available | Links in output |
| `VexGen_NoEvidence_OmitsField` | No evidence | `evidence: null` |
| `VexGen_BelowThreshold_Filtered` | Low confidence evidence | Evidence omitted |
| `VexGen_TableFormat_ShowsSummary` | Table output | Evidence column populated |
## Execution Log
| Date (UTC) | Update | Owner |
|------------|--------|-------|
| 2026-01-13 | Sprint created from advisory analysis. | Project Mgmt |
## Next Checkpoints
- All tasks complete -> Sprint can be marked DONE
- Batch 003 complete -> Evidence chain operational

View File

@@ -1,17 +1,20 @@
# Sprint Batch 20260113_004 - Golden Pairs Pilot (Vendor Backport Corpus)
# Sprint 20260113_004_000 - Index - Golden Pairs Pilot
## Executive Summary
## Topic & Scope
- Build the curated golden pairs dataset infrastructure to validate binary diff accuracy against real backports.
- Define data models, mirroring pipeline, and a three-CVE pilot corpus for regression testing.
- Align Tools implementation with the Scanner binary diff features for deterministic validation.
- **Working directory:** `docs/implplan`.
### Executive Summary
This sprint batch implements a **curated dataset infrastructure** for binary patch verification. "Golden pairs" are matched sets of stock (upstream) vs vendor-patched binaries tied to specific CVEs, enabling validation of the binary diff system's ability to detect vendor backports.
**Scope:** Pilot corpus with 3 CVEs (Dirty Pipe, sudo Baron Samedit, PrintNightmare)
**Effort Estimate:** 5-6 story points across 3 sprints
**Priority:** Medium (validation infrastructure)
## Background
### Advisory Requirements
### Background
#### Advisory Requirements
The original advisory specified:
> A curated dataset of **stock vs vendor-patched binaries** tied to authoritative **CVE + patch evidence** lets Stella Ops prove (with bytes) that a fix is present, powering deterministic VEX and "evidence-first" decisions.
@@ -19,16 +22,15 @@ The original advisory specified:
> **Starter CVEs (tiny pilot):**
> - **Linux:** Dirty Pipe (CVE-2022-0847) - kernel backport showcase
> - **Unix userland:** sudo "Baron Samedit" (CVE-2021-3156) - classic multi-distro patch
> - **Windows:** PrintNightmare (CVE-2021-34527) - PE + KB workflow
### Why Golden Pairs Matter
> - **Windows:** PrintNightmare (CVE-2021-34527) - PE and KB workflow
#### Why Golden Pairs Matter
1. **Validation**: Ground truth for testing binary diff accuracy
2. **Regression Testing**: Detect if changes break patch detection
3. **Precision Metrics**: Measure actual false positive/negative rates
3. **Precision Metrics**: Measure actual false positive and false negative rates
4. **Documentation**: Examples of vendor backport patterns
### Existing Capabilities
#### Existing Capabilities
| Component | Status | Location |
|-----------|--------|----------|
@@ -37,7 +39,7 @@ The original advisory specified:
| Function Fingerprinting | EXISTS | `src/BinaryIndex/__Libraries/.../FingerprintModels.cs` |
| Build-ID Index | EXISTS | `src/Scanner/.../Index/OfflineBuildIdIndex.cs` |
### Gap Analysis
#### Gap Analysis
| Capability | Status |
|------------|--------|
@@ -46,59 +48,33 @@ The original advisory specified:
| Diff pipeline for corpus | MISSING |
| Validation harness | MISSING |
## Sprint Index
### Sprint Index
| Sprint | ID | Module | Topic | Status | Owner |
|--------|-----|--------|-------|--------|-------|
| 1 | SPRINT_20260113_004_001 | TOOLS | Golden Pairs Data Model & Schema | TODO | Guild - Tools |
| 2 | SPRINT_20260113_004_002 | TOOLS | Mirror & Diff Pipeline | TODO | Guild - Tools |
| 3 | SPRINT_20260113_004_003 | TOOLS | Pilot CVE Corpus (3 CVEs) | TODO | Guild - Tools |
| 1 | SPRINT_20260113_004_001 | TOOLS | Golden Pairs Data Model and Schema | DONE | Guild - Tools |
| 2 | SPRINT_20260113_004_002 | TOOLS | Mirror and Diff Pipeline | DONE | Guild - Tools |
| 3 | SPRINT_20260113_004_003 | TOOLS | Pilot CVE Corpus (3 CVEs) | BLOCKED | Guild - Tools |
## Dependencies
```
+-----------------------------------------------------------------------+
| Dependency Graph |
+-----------------------------------------------------------------------+
| |
| Batch 001 (ELF Section Hashes) |
| | |
| v |
| Sprint 1 (Data Model) |
| | |
| v |
| Sprint 2 (Mirror & Diff Pipeline) |
| | |
| v |
| Sprint 3 (Pilot Corpus) |
| |
+-----------------------------------------------------------------------+
```
**Cross-Batch Dependencies:**
- Batch 001 Sprint 001 (ELF Section Hashes) should be complete for validation
- Pipeline uses section hashes for diff validation
## Acceptance Criteria (Batch-Level)
### Must Have
### Acceptance Criteria (Batch-Level)
#### Must Have
1. **Data Model**
- Schema for golden pair metadata (CVE, package, distro, versions)
- Support for ELF (Linux) and PE (Windows) binaries
- Storage for original + patched binaries with hashes
- Storage for original and patched binaries with hashes
- Links to vendor advisories and patch commits
2. **Mirror Scripts**
- Fetch pre-patch and post-patch package versions
- Support Debian/Ubuntu apt repos
- Support Debian and Ubuntu apt repos
- Hash verification on download
- Deterministic mirroring (reproducible)
3. **Diff Pipeline**
- Run section hash extraction on pairs
- Produce comparison JSON report
- Compute match/mismatch metrics
- Compute match and mismatch metrics
- Validate against expected outcomes
4. **Pilot Corpus (3 CVEs)**
@@ -106,21 +82,19 @@ The original advisory specified:
- CVE-2021-3156 (Baron Samedit): sudo binary pair
- CVE-2021-34527 (PrintNightmare): Windows spoolsv.dll pair (if PE ready)
### Should Have
#### Should Have
- Debug symbol extraction (dbgsym packages)
- Function-level diff report
- CI integration for regression testing
### Deferred (Out of Scope)
- Ghidra/Diaphora integration (separate sprint)
#### Deferred (Out of Scope)
- Ghidra and Diaphora integration (separate sprint)
- Full multi-distro coverage
- Automated corpus updates
## Technical Context
### Technical Context
### Repository Layout
#### Repository Layout
```
src/Tools/GoldenPairs/
@@ -157,7 +131,7 @@ datasets/golden-pairs/
+-- README.md
```
### Metadata Schema
#### Metadata Schema
```json
{
@@ -207,7 +181,7 @@ datasets/golden-pairs/
}
```
### Diff Report Schema
#### Diff Report Schema
```json
{
@@ -227,7 +201,7 @@ datasets/golden-pairs/
}
```
## Risk Assessment
### Risk Assessment
| Risk | Likelihood | Impact | Mitigation |
|------|------------|--------|------------|
@@ -236,38 +210,55 @@ datasets/golden-pairs/
| Windows PE complexity | High | Medium | Defer PrintNightmare if PE support not ready |
| Hash instability | Low | Medium | Pin to specific package versions |
## Success Metrics
### Success Metrics
- [ ] 3 CVE pairs with complete metadata
- [ ] Mirror scripts fetch correct versions
- [ ] Diff pipeline produces expected verdicts
- [ ] CI regression test passes
- [ ] Documentation complete
## Documentation Prerequisites
## Dependencies & Concurrency
- Batch 001 Sprint 001 (ELF Section Hashes) should be complete for validation.
- Sprint 1 is foundational; Sprint 2 depends on the data model, Sprint 3 depends on the pipeline.
- Other 20260113_004_000 planning artifacts are index-only, so parallel edits remain safe.
```
Batch 001 Sprint 001 (ELF Hashes)
-> Sprint 1 (Data Model)
Sprint 1 (Data Model)
-> Sprint 2 (Mirror and Diff Pipeline)
Sprint 2 (Mirror and Diff Pipeline)
-> Sprint 3 (Pilot Corpus)
```
## Documentation Prerequisites
Before starting implementation, reviewers must read:
- `docs/README.md`
- `CLAUDE.md` Section 8 (Code Quality & Determinism Rules)
- `CLAUDE.md` Section 8 (Code Quality and Determinism Rules)
- Batch 001 ELF section hash schema
- ELF specification for section analysis
## Execution Log
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 1 | INDEX-20260113-004-000-01 | DONE | None | Project Mgmt | Normalize sprint batch index to standard template and ASCII-only formatting. |
| 2 | INDEX-20260113-004-000-02 | DONE | None | Project Mgmt | Clarify dependency flow and checkpoint wording without changing scope. |
## Execution Log
| Date (UTC) | Update | Owner |
|------------|--------|-------|
| 2026-01-13 | Sprint batch created from advisory analysis. | Project Mgmt |
| 2026-01-13 | Normalized sprint file to standard template; ASCII-only cleanup; no semantic changes. | Project Mgmt |
| 2026-01-13 | Updated sprint statuses (004_001 DONE, 004_002 DONE, 004_003 BLOCKED). | Tools |
## Decisions & Risks
- **APPROVED 2026-01-13**: Pilot with 3 CVEs; expand corpus in follow-up sprint.
- **APPROVED 2026-01-13**: Focus on ELF first; PE support conditional on Batch 001 progress.
- **APPROVED 2026-01-13**: Store binaries in datasets/, not in git LFS initially.
- **RISK**: Kernel binaries are large; consider extracting specific .ko modules instead.
## Next Checkpoints
- Sprint 1 complete -> Data model ready for population
- Sprint 2 complete -> Pipeline can process pairs
- Sprint 3 complete -> Pilot corpus validated, CI integrated

View File

@@ -25,14 +25,14 @@
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
|---|---------|--------|---------------------------|--------|-----------------|
| 1 | GP-MODEL-METADATA-0001 | TODO | None | Guild - Tools | Define `GoldenPairMetadata` record with CVE, artifact, original/patched refs, patch info, advisories, expected diff. |
| 2 | GP-MODEL-ARTIFACT-0001 | TODO | None | Guild - Tools | Define `BinaryArtifact` record with package, version, distro, source, hashes, buildId, symbols availability. |
| 3 | GP-MODEL-DIFF-0001 | TODO | None | Guild - Tools | Define `GoldenDiffReport` record with section comparison, verdict, confidence, tool version. |
| 4 | GP-SCHEMA-JSON-0001 | TODO | Depends on MODEL-* | Guild - Tools | Create JSON Schema `golden-pair-v1.schema.json` for metadata validation. Publish to `docs/schemas/`. |
| 5 | GP-SCHEMA-INDEX-0001 | TODO | Depends on SCHEMA-JSON | Guild - Tools | Create corpus index schema `golden-pairs-index.schema.json` for dataset manifest. |
| 6 | GP-STORAGE-LAYOUT-0001 | TODO | Depends on MODEL-* | Guild - Tools | Document storage layout in `datasets/golden-pairs/README.md`. Include artifact naming conventions. |
| 7 | GP-MODEL-LOADER-0001 | TODO | Depends on all models | Guild - Tools | Implement `GoldenPairLoader` service to read/validate metadata from filesystem. |
| 8 | GP-MODEL-TESTS-0001 | TODO | Depends on all above | Guild - Tools | Unit tests for model serialization, schema validation, loader functionality. |
| 1 | GP-MODEL-METADATA-0001 | DONE | None | Guild - Tools | Define `GoldenPairMetadata` record with CVE, artifact, original/patched refs, patch info, advisories, expected diff. |
| 2 | GP-MODEL-ARTIFACT-0001 | DONE | None | Guild - Tools | Define `BinaryArtifact` record with package, version, distro, source, hashes, buildId, symbols availability. |
| 3 | GP-MODEL-DIFF-0001 | DONE | None | Guild - Tools | Define `GoldenDiffReport` record with section comparison, verdict, confidence, tool version. |
| 4 | GP-SCHEMA-JSON-0001 | DONE | Depends on MODEL-* | Guild - Tools | Create JSON Schema `golden-pair-v1.schema.json` for metadata validation. Publish to `docs/schemas/`. |
| 5 | GP-SCHEMA-INDEX-0001 | DONE | Depends on SCHEMA-JSON | Guild - Tools | Create corpus index schema `golden-pairs-index.schema.json` for dataset manifest. |
| 6 | GP-STORAGE-LAYOUT-0001 | DONE | Depends on MODEL-* | Guild - Tools | Document storage layout in `datasets/golden-pairs/README.md`. Include artifact naming conventions. |
| 7 | GP-MODEL-LOADER-0001 | DONE | Depends on all models | Guild - Tools | Implement `GoldenPairLoader` service to read/validate metadata from filesystem. |
| 8 | GP-MODEL-TESTS-0001 | DONE | Depends on all above | Guild - Tools | Unit tests for model serialization, schema validation, loader functionality. |
## Technical Specification
@@ -332,6 +332,7 @@ datasets/golden-pairs/
| Date (UTC) | Update | Owner |
|------------|--------|-------|
| 2026-01-13 | Sprint created from advisory analysis. | Project Mgmt |
| 2026-01-13 | Implemented models, schemas, loader, and tests; documented corpus layout. | Tools |
## Decisions & Risks

View File

@@ -26,16 +26,16 @@
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
|---|---------|--------|---------------------------|--------|-----------------|
| 1 | GP-MIRROR-INTERFACE-0001 | TODO | None | Guild - Tools | Define `IPackageMirrorService` interface with `FetchAsync(artifact, destination, ct)` signature. Support verification and resume. |
| 2 | GP-MIRROR-APT-0001 | TODO | Depends on INTERFACE | Guild - Tools | Implement `AptPackageMirrorService` for Debian/Ubuntu. Parse Packages.gz, download .deb, extract target binary. |
| 3 | GP-MIRROR-VERIFY-0001 | TODO | Depends on APT | Guild - Tools | Implement hash verification: compare downloaded SHA-256 with metadata. Fail if mismatch. |
| 4 | GP-DIFF-INTERFACE-0001 | TODO | Sprint 001 models | Guild - Tools | Define `IDiffPipelineService` interface with `DiffAsync(pair, ct)` returning `GoldenDiffReport`. |
| 5 | GP-DIFF-IMPL-0001 | TODO | Depends on INTERFACE, Batch 001 | Guild - Tools | Implement `DiffPipelineService` that: loads metadata, extracts section hashes, compares, produces report. |
| 6 | GP-DIFF-VALIDATE-0001 | TODO | Depends on IMPL | Guild - Tools | Implement validation against `expectedDiff`: check sections changed/identical, verdict, confidence threshold. |
| 7 | GP-CLI-MIRROR-0001 | TODO | Depends on MIRROR-* | Guild - Tools | Add `golden-pairs mirror <cve>` CLI command to fetch artifacts for a pair. |
| 8 | GP-CLI-DIFF-0001 | TODO | Depends on DIFF-* | Guild - Tools | Add `golden-pairs diff <cve>` CLI command to run diff and validation. |
| 9 | GP-CLI-VALIDATE-0001 | TODO | Depends on all above | Guild - Tools | Add `golden-pairs validate` CLI command to run all pairs and produce summary. |
| 10 | GP-TESTS-0001 | TODO | Depends on all above | Guild - Tools | Unit and integration tests for mirror, diff, validation services. |
| 1 | GP-MIRROR-INTERFACE-0001 | DONE | None | Guild - Tools | Define `IPackageMirrorService` interface with `FetchAsync(artifact, destination, ct)` signature. Support verification and resume. |
| 2 | GP-MIRROR-APT-0001 | DONE | Depends on INTERFACE | Guild - Tools | Implement `AptPackageMirrorService` for Debian/Ubuntu. Parse Packages.gz, download .deb, extract target binary. |
| 3 | GP-MIRROR-VERIFY-0001 | DONE | Depends on APT | Guild - Tools | Implement hash verification: compare downloaded SHA-256 with metadata. Fail if mismatch. |
| 4 | GP-DIFF-INTERFACE-0001 | DONE | Sprint 001 models | Guild - Tools | Define `IDiffPipelineService` interface with `DiffAsync(pair, ct)` returning `GoldenDiffReport`. |
| 5 | GP-DIFF-IMPL-0001 | DONE | Depends on INTERFACE, Batch 001 | Guild - Tools | Implement `DiffPipelineService` that: loads metadata, extracts section hashes, compares, produces report. |
| 6 | GP-DIFF-VALIDATE-0001 | DONE | Depends on IMPL | Guild - Tools | Implement validation against `expectedDiff`: check sections changed/identical, verdict, confidence threshold. |
| 7 | GP-CLI-MIRROR-0001 | DONE | Depends on MIRROR-* | Guild - Tools | Add `golden-pairs mirror <cve>` CLI command to fetch artifacts for a pair. |
| 8 | GP-CLI-DIFF-0001 | DONE | Depends on DIFF-* | Guild - Tools | Add `golden-pairs diff <cve>` CLI command to run diff and validation. |
| 9 | GP-CLI-VALIDATE-0001 | DONE | Depends on all above | Guild - Tools | Add `golden-pairs validate` CLI command to run all pairs and produce summary. |
| 10 | GP-TESTS-0001 | DONE | Depends on all above | Guild - Tools | Unit and integration tests for mirror, diff, validation services. |
## Technical Specification
@@ -314,6 +314,7 @@ jobs:
| Date (UTC) | Update | Owner |
|------------|--------|-------|
| 2026-01-13 | Sprint created from advisory analysis. | Project Mgmt |
| 2026-01-13 | Implemented mirror, diff pipeline, CLI commands, and tests. | Tools |
## Decisions & Risks
@@ -321,6 +322,7 @@ jobs:
- **APPROVED**: Cache downloaded packages locally to avoid re-fetch.
- **RISK**: Apt repository structure may vary; handle exceptions gracefully.
- **RISK**: Some packages may be removed from mirrors; document fallbacks.
- **NOTE**: Apt mirror expects direct package URLs; Packages.gz lookup deferred.
## Next Checkpoints

View File

@@ -27,18 +27,18 @@
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
|---|---------|--------|---------------------------|--------|-----------------|
| 1 | GP-CORPUS-DIRTYPIPE-META-0001 | TODO | None | Guild - Tools | Create `CVE-2022-0847/metadata.json` with full golden pair metadata. Identify Ubuntu 22.04 kernel package versions. |
| 2 | GP-CORPUS-DIRTYPIPE-FETCH-0001 | TODO | Depends on META, Sprint 002 | Guild - Tools | Fetch vmlinux binaries for pre-patch (5.16.11) and post-patch (5.16.12) versions using mirror service. |
| 3 | GP-CORPUS-DIRTYPIPE-DIFF-0001 | TODO | Depends on FETCH | Guild - Tools | Run diff pipeline, validate .text section change, verify verdict matches expected. |
| 4 | GP-CORPUS-DIRTYPIPE-DOCS-0001 | TODO | Depends on all above | Guild - Tools | Document advisory links, patch commit, functions changed. Archive advisory PDFs. |
| 5 | GP-CORPUS-BARON-META-0001 | TODO | None | Guild - Tools | Create `CVE-2021-3156/metadata.json`. Identify Debian 11 sudo package versions. |
| 6 | GP-CORPUS-BARON-FETCH-0001 | TODO | Depends on META, Sprint 002 | Guild - Tools | Fetch sudo binaries for pre-patch and post-patch versions. |
| 7 | GP-CORPUS-BARON-DIFF-0001 | TODO | Depends on FETCH | Guild - Tools | Run diff pipeline, validate, verify verdict. |
| 8 | GP-CORPUS-BARON-DOCS-0001 | TODO | Depends on all above | Guild - Tools | Document advisory links, patch commit. |
| 9 | GP-CORPUS-PRINT-META-0001 | TODO (CONDITIONAL) | PE support ready | Guild - Tools | Create `CVE-2021-34527/metadata.json` if PE section hashing available. |
| 10 | GP-CORPUS-INDEX-0001 | TODO | Depends on all pairs | Guild - Tools | Create `index.json` corpus manifest listing all pairs with summary. |
| 11 | GP-CORPUS-README-0001 | TODO | Depends on INDEX | Guild - Tools | Create `README.md` with corpus documentation, usage instructions, extension guide. |
| 12 | GP-CORPUS-CI-0001 | TODO | Depends on all above | Guild - Tools | Add CI workflow to validate corpus on changes. Integrate with test reporting. |
| 1 | GP-CORPUS-DIRTYPIPE-META-0001 | BLOCKED | None | Guild - Tools | Create `CVE-2022-0847/metadata.json` with full golden pair metadata. Identify Ubuntu 22.04 kernel package versions. |
| 2 | GP-CORPUS-DIRTYPIPE-FETCH-0001 | BLOCKED | Depends on META, Sprint 002 | Guild - Tools | Fetch vmlinux binaries for pre-patch (5.16.11) and post-patch (5.16.12) versions using mirror service. |
| 3 | GP-CORPUS-DIRTYPIPE-DIFF-0001 | BLOCKED | Depends on FETCH | Guild - Tools | Run diff pipeline, validate .text section change, verify verdict matches expected. |
| 4 | GP-CORPUS-DIRTYPIPE-DOCS-0001 | BLOCKED | Depends on all above | Guild - Tools | Document advisory links, patch commit, functions changed. Archive advisory PDFs. |
| 5 | GP-CORPUS-BARON-META-0001 | BLOCKED | None | Guild - Tools | Create `CVE-2021-3156/metadata.json`. Identify Debian 11 sudo package versions. |
| 6 | GP-CORPUS-BARON-FETCH-0001 | BLOCKED | Depends on META, Sprint 002 | Guild - Tools | Fetch sudo binaries for pre-patch and post-patch versions. |
| 7 | GP-CORPUS-BARON-DIFF-0001 | BLOCKED | Depends on FETCH | Guild - Tools | Run diff pipeline, validate, verify verdict. |
| 8 | GP-CORPUS-BARON-DOCS-0001 | BLOCKED | Depends on all above | Guild - Tools | Document advisory links, patch commit. |
| 9 | GP-CORPUS-PRINT-META-0001 | BLOCKED (CONDITIONAL) | PE support ready | Guild - Tools | Create `CVE-2021-34527/metadata.json` if PE section hashing available. |
| 10 | GP-CORPUS-INDEX-0001 | BLOCKED | Depends on all pairs | Guild - Tools | Create `index.json` corpus manifest listing all pairs with summary. |
| 11 | GP-CORPUS-README-0001 | BLOCKED | Depends on INDEX | Guild - Tools | Create `README.md` with corpus documentation, usage instructions, extension guide. |
| 12 | GP-CORPUS-CI-0001 | BLOCKED | Depends on all above | Guild - Tools | Add CI workflow to validate corpus on changes. Integrate with test reporting. |
## Technical Specification
@@ -243,6 +243,7 @@ golden-pairs validate --all
| Date (UTC) | Update | Owner |
|------------|--------|-------|
| 2026-01-13 | Sprint created from advisory analysis. | Project Mgmt |
| 2026-01-13 | Marked corpus tasks blocked pending confirmed package sources, hashes, and artifacts. | Tools |
## Decisions & Risks
@@ -250,6 +251,7 @@ golden-pairs validate --all
- **APPROVED**: Use Debian snapshot archive for reproducible sudo packages.
- **RISK**: Kernel binaries are very large; consider extracting specific .ko modules.
- **RISK**: Package removal from archives; cache locally after first fetch.
- **BLOCKER**: Requires confirmed package URLs, hashes, and binaries before metadata and corpus can be generated.
## Next Checkpoints

View File

@@ -0,0 +1,64 @@
# Sprint 20260113_005_ADVISORYAI_controlled_conversational_interface - Controlled Conversational Interface (AdvisoryAI)
## Topic & Scope
- Add Chat Gateway guardrails (quotas, budgets, scrubber) to the AdvisoryAI chat pipeline.
- Enforce sanctioned tool registry (read-only default) with policy checks for tool use.
- Persist immutable audit logs for prompts, redactions, tool calls, and model identifiers.
- **Working directory:** `src/AdvisoryAI/`.
## Dependencies & Concurrency
- Depends on policy tool lattice sprint for allow/deny evaluation.
- UI and CLI sprints can proceed in parallel once chat API schema is stable.
## Documentation Prerequisites
- `docs/README.md`
- `docs/ARCHITECTURE_OVERVIEW.md`
- `docs/modules/advisory-ai/architecture.md`
- `docs/modules/advisory-ai/chat-interface.md`
- `docs/security/assistant-guardrails.md`
- `docs-archived/product/advisories/13-Jan-2026 - Controlled Conversational Interface.md`
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 1 | AIAI-CHAT-DOCS-0001 | DONE | None | Guild - AdvisoryAI | Update `docs/modules/advisory-ai/architecture.md` and `docs/modules/advisory-ai/chat-interface.md` with Chat Gateway guardrails and audit log details. |
| 2 | AIAI-CHAT-GW-0001 | DONE | Policy lattice sprint | Guild - AdvisoryAI | Implement Chat Gateway quotas and token budgets with deterministic counters and rejection codes; use settings overrides with env defaults. |
| 3 | AIAI-CHAT-SCRUB-0001 | DONE | AIAI-CHAT-GW-0001 | Guild - AdvisoryAI | Add PII/secret scrubber (regex + entropy + allowlist) for input/output with test vectors. |
| 4 | AIAI-CHAT-TOOLS-0001 | DONE | Policy lattice sprint | Guild - AdvisoryAI | Implement sanctioned tool registry with schema-bound invocation and read-only defaults; enforce per-tenant allowlist. |
| 5 | AIAI-CHAT-AUDIT-0001 | DONE | AIAI-CHAT-TOOLS-0001 | Guild - AdvisoryAI | Persist audit log tables (prompts, tool invocations, policy decisions, evidence links) with content hashes; optional DSSE capture. |
| 6 | AIAI-CHAT-PLUGIN-0001 | BLOCKED | AIAI-CHAT-TOOLS-0001 | Guild - AdvisoryAI | Build adapters for `vex.query`, `sbom.read`, and `scanner.findings.topk`. |
| 7 | AIAI-CHAT-TEST-0001 | BLOCKED | AIAI-CHAT-AUDIT-0001 | Guild - AdvisoryAI | Add integration tests for quotas, scrubber blocks, policy denies, and audit log persistence. |
| 8 | AIAI-CHAT-SETTINGS-0001 | DONE | AIAI-CHAT-GW-0001 | Guild - AdvisoryAI | Add chat settings store and API for quota/allowlist overrides (UI/CLI), with env defaults. |
| 9 | AIAI-CHAT-DOCTOR-0001 | DONE | AIAI-CHAT-SETTINGS-0001 | Guild - AdvisoryAI | Add chat doctor endpoint to diagnose quota/tool limitations and last deny reasons. |
| 10 | AIAI-CHAT-ENDPOINTS-0002 | DONE | None | Guild - AdvisoryAI | Fix chat endpoints: register determinism GUID provider, allow role-based auth headers, and add SSE streaming for conversation turns. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2026-01-13 | Sprint created from controlled conversational interface advisory; docs updated. | Product Mgmt |
| 2026-01-13 | Added settings/doctor tasks for quota and allowlist overrides. | Product Mgmt |
| 2026-01-13 | Started AIAI-CHAT-GW-0001, AIAI-CHAT-TOOLS-0001, AIAI-CHAT-SETTINGS-0001, AIAI-CHAT-DOCTOR-0001. | AdvisoryAI |
| 2026-01-13 | Completed AIAI-CHAT-GW-0001, AIAI-CHAT-TOOLS-0001, AIAI-CHAT-SETTINGS-0001, AIAI-CHAT-DOCTOR-0001; tests blocked by `src/__Libraries/StellaOps.TestKit/Connectors/ConnectorHttpFixture.cs` compile error (IServiceProvider missing Dispose). | AdvisoryAI |
| 2026-01-13 | Marked remaining AdvisoryAI tasks blocked to avoid conflicting parallel changes; pending ownership handoff. | AdvisoryAI |
| 2026-01-13 | Fixed chat endpoint binding/auth/streaming (AIAI-CHAT-ENDPOINTS-0002); tests run with `dotnet test --no-build` due to external build failure in `src/Router/__Libraries/StellaOps.Microservice/ServiceCollectionExtensions.cs`. | AdvisoryAI |
| 2026-01-13 | Cleared duplicate `using` in `src/Router/__Libraries/StellaOps.Microservice/ServiceCollectionExtensions.cs`; `dotnet build` now succeeds. | AdvisoryAI |
| 2026-01-13 | Resumed AIAI-CHAT-SCRUB-0001 for entropy/allowlist scrubber updates. | AdvisoryAI |
| 2026-01-13 | Completed AIAI-CHAT-SCRUB-0001; tuned guardrail redaction pre-checks and performance scenarios; AdvisoryAI tests pass. | AdvisoryAI |
| 2026-01-13 | Started AIAI-CHAT-AUDIT-0001 for chat audit persistence. | AdvisoryAI |
| 2026-01-13 | Completed AIAI-CHAT-AUDIT-0001; added Postgres audit logger + migration, docs, and tests; ran `dotnet test src/AdvisoryAI/__Tests/StellaOps.AdvisoryAI.Tests/StellaOps.AdvisoryAI.Tests.csproj -v minimal`. | AdvisoryAI |
| 2026-01-13 | Reaffirmed UI/CLI settings overrides (env defaults) and doctor action expectations in assistant-parameters guidance. | AdvisoryAI |
## Decisions & Risks
- Decision: Use existing conversation storage and chat endpoints as the base; extend with Chat Gateway controls.
- Decision: Guardrail and audit expectations are captured in `docs/modules/advisory-ai/chat-interface.md` and `docs/security/assistant-guardrails.md`.
- Decision: Quotas and tool allowlists are configurable via UI/CLI settings with env defaults.
- Decision: Chat endpoints accept scopes or role headers (`chat:user`, `chat:admin`) for authorization.
- Risk: Tool schemas may shift across modules; require a shared contract before enabling more tools.
- Risk: Settings persistence needs Postgres-backed store; in-memory defaults are not durable.
- Risk: Audit log storage growth; define retention windows and offline export procedures.
- Risk: Full build previously failed due to duplicate using in `src/Router/__Libraries/StellaOps.Microservice/ServiceCollectionExtensions.cs`; resolved locally, re-run baseline builds as needed.
## Next Checkpoints
- API schema review for tool invocation and audit log payloads.
- Guardrail test vectors approved by Security Guild.
- Demo: read-only advisor flow with citations.

View File

@@ -0,0 +1,47 @@
# Sprint 20260113_005_CLI_advise_chat - Advise Chat CLI
## Topic & Scope
- Add `stella advise ask` for controlled conversational queries with evidence refs.
- Default to read-only output; expose flags for evidence and action suppression.
- Align output with Advisor UI evidence chips and citations.
- **Working directory:** `src/Cli/`.
## Dependencies & Concurrency
- Depends on AdvisoryAI chat API schema and policy tool lattice decisions.
- Can run in parallel with UI once API contracts are stable.
## Documentation Prerequisites
- `docs/README.md`
- `docs/modules/cli/architecture.md`
- `docs/modules/advisory-ai/chat-interface.md`
- `docs/security/assistant-guardrails.md`
- `docs-archived/product/advisories/13-Jan-2026 - Controlled Conversational Interface.md`
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 1 | CLI-CHAT-DOCS-0001 | DONE | None | Guild - CLI | Update `docs/modules/cli/architecture.md` with `advise ask` command details. |
| 2 | CLI-CHAT-CMD-0001 | BLOCKED | AdvisoryAI chat API | Guild - CLI | Add `advise ask` command and route to chat query endpoint. |
| 3 | CLI-CHAT-FLAGS-0001 | BLOCKED | CLI-CHAT-CMD-0001 | Guild - CLI | Implement `--no-action` and `--evidence` flags with safe defaults. |
| 4 | CLI-CHAT-OUTPUT-0001 | BLOCKED | CLI-CHAT-CMD-0001 | Guild - CLI | Render citations and evidence refs in JSON and table output. |
| 5 | CLI-CHAT-TEST-0001 | BLOCKED | CLI-CHAT-CMD-0001 | Guild - CLI | Add unit tests for flags, output formats, and policy deny handling. |
| 6 | CLI-CHAT-SETTINGS-0001 | BLOCKED | AdvisoryAI settings API | Guild - CLI | Add `advise settings` for chat quotas/allowlist overrides. |
| 7 | CLI-CHAT-DOCTOR-0001 | BLOCKED | AdvisoryAI doctor API | Guild - CLI | Add `advise doctor` to show chat quota/tool limitations. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2026-01-13 | Sprint created from controlled conversational interface advisory; docs updated. | Product Mgmt |
| 2026-01-13 | Added settings and doctor tasks for quota/allowlist overrides. | Product Mgmt |
| 2026-01-13 | Marked CLI advise tasks blocked pending AdvisoryAI API stability and parallel module ownership. | CLI |
## Decisions & Risks
- Decision: Default to read-only responses; action suppression is explicit.
- Decision: CLI command details documented in `docs/modules/cli/architecture.md`.
- Risk: Long responses may exceed token budgets; keep output truncation deterministic.
- Risk: Settings updates require scope-gated access; align with Authority scopes.
- BLOCKED: AdvisoryAI chat/settings/doctor APIs pending stable contract and active parallel changes.
## Next Checkpoints
- CLI UX review for evidence output format.
- API contract validation for chat queries and error codes.

View File

@@ -0,0 +1,43 @@
# Sprint 20260113_005_DOCS_controlled_conversational_interface - Controlled Conversational Interface Docs
## Topic & Scope
- Capture the controlled conversational interface advisory and archive it for long-term reference.
- Update high-level docs to reflect the evidence-first advisor capability and cross-links.
- Extend guardrail and assistant parameter docs to cover quotas, scrubber, and tool gating.
- **Working directory:** `docs/`.
## Dependencies & Concurrency
- No upstream dependencies; doc updates can run in parallel with implementation sprints.
## Documentation Prerequisites
- `docs/README.md`
- `docs/ARCHITECTURE_OVERVIEW.md`
- `docs/modules/platform/architecture-overview.md`
- `docs/security/assistant-guardrails.md`
- `docs/modules/policy/guides/assistant-parameters.md`
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 1 | DOCS-CCI-0001 | DONE | None | Guild - Docs | Create and archive the advisory: `docs-archived/product/advisories/13-Jan-2026 - Controlled Conversational Interface.md`. |
| 2 | DOCS-CCI-0002 | DONE | DOCS-CCI-0001 | Guild - Docs | Update `docs/key-features.md`, `docs/ARCHITECTURE_OVERVIEW.md`, and add `docs/07_HIGH_LEVEL_ARCHITECTURE.md` references. |
| 3 | DOCS-CCI-0003 | DONE | DOCS-CCI-0001 | Guild - Docs | Update `docs/security/assistant-guardrails.md` for scrubber, budgets, and audit trail notes. |
| 4 | DOCS-CCI-0004 | DONE | DOCS-CCI-0001 | Guild - Docs | Update `docs/modules/policy/guides/assistant-parameters.md` with chat quotas and tool gating. |
| 5 | DOCS-CCI-0005 | DONE | DOCS-CCI-0001 | Guild - Docs | Update module AGENTS to reflect advisor guardrails (`docs/modules/advisory-ai/AGENTS.md`, `docs/modules/ui/AGENTS.md`, `docs/modules/cli/AGENTS.md`, `docs/modules/policy/AGENTS.md`). |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2026-01-13 | Sprint created from controlled conversational interface advisory; doc updates completed and advisory archived. | Product Mgmt |
| 2026-01-13 | Updated AdvisoryAI, UI, CLI, and Policy AGENTS to reflect advisor guardrails. | Docs |
## Decisions & Risks
- Decision: Use `docs/ARCHITECTURE_OVERVIEW.md` as the canonical high-level doc; add `docs/07_HIGH_LEVEL_ARCHITECTURE.md` as a legacy pointer.
- Decision: AGENTS updates recorded in this sprint to keep module guardrails aligned.
- Risk: Links to archived advisories must be maintained for traceability; validate docs links after merges.
- Risk: `docs/implplan/SPRINT_0301_0001_0001_docs_md_i.md` is referenced in `docs/AGENTS.md` but is not present in the repo.
- Risk: `docs/implplan/archived/all-tasks.md` referenced by advisory workflow is missing; historical task cross-check was limited.
## Next Checkpoints
- Docs Guild review of updated advisory, guardrail, and parameter docs.
- Link validation sweep for docs references.

View File

@@ -0,0 +1,69 @@
# Sprint 20260113-005-DOCTOR · Orchestrator Doctor Self Service
## Topic & Scope
- Define Doctor packs for Release Orchestrator integrations with deterministic checks and verbatim fix commands.
- Add JSONL evidence logs and optional DSSE summaries for audit-grade Doctor runs.
- Align CLI and UI with a shared `how_to_fix` command contract for self-service remediation.
- Expected evidence: updated specs in `docs/doctor/doctor-capabilities.md`, updated module doc in `docs/modules/release-orchestrator/modules/integration-hub.md`, and sample manifest in `docs/benchmarks/doctor/doctor-plugin-release-orchestrator-gitlab.yaml`.
- **Working directory:** `src/Doctor`.
- **Allowed cross-module paths:** `src/__Libraries/StellaOps.Doctor/**`, `src/Cli/**`, `src/Web/**`, `src/ReleaseOrchestrator/**`, `plugins/doctor/**`, `samples/**`.
## Dependencies & Concurrency
- Depends on Doctor engine/library and CLI command group integration.
- No known conflicts with other 20260113 sprints; safe to run in parallel with CC peers.
## Documentation Prerequisites
- `docs/README.md`
- `docs/technical/architecture/07_HIGH_LEVEL_ARCHITECTURE.md`
- `docs/modules/release-orchestrator/architecture.md`
- `docs/modules/release-orchestrator/modules/integration-hub.md`
- `docs/doctor/doctor-capabilities.md`
- `docs/modules/platform/architecture-overview.md`
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 1 | DOCS-DR-0001 | DONE | Advisory sync | Product · Docs | Sync Doctor advisory into docs and add sample manifest (`docs-archived/product/advisories/13-Jan-2026 - Release Orchestrator Doctor Self Service.md`, `docs/doctor/doctor-capabilities.md`, `docs/modules/release-orchestrator/modules/integration-hub.md`, `docs/key-features.md`, `docs/benchmarks/doctor/doctor-plugin-release-orchestrator-gitlab.yaml`). |
| 2 | DOCTOR-DR-0002 | DONE | Pack schema + loader | Backend · Doctor | Implement YAML pack loader for `plugins/doctor/*.yaml` with discovery gating, exec runner, and parse expectations. |
| 2.1 | AGENTS-DOCTOR-0001 | DONE | Module charter | Project · Doctor | Create `src/Doctor/AGENTS.md` with module constraints, test strategy, and allowed shared libs. |
| 3 | PACKS-DR-0003 | DONE | DOCTOR-DR-0002 | Backend · Doctor | Add first-party Doctor packs for GitLab, GitHub, Gitea, Harbor/OCI, Vault, LDAP under `plugins/doctor/`. |
| 4 | CLI-DR-0004 | DONE | DOCTOR-DR-0002 | CLI · Platform | Add `stella doctor run` alias and `stella doctor fix` pipeline with dry-run by default and `--apply` gating. |
| 5 | ORCH-DR-0005 | BLOCKED | DOCTOR-DR-0002 | Backend · Release Orchestrator | Implement orchestrator checks for webhooks, branch policy, registry push/pull, SBOM ingestion, vault, LDAP, migrations, and policy pack verification. |
| 6 | DOCTOR-DR-0006 | DONE | DOCTOR-DR-0002 | Backend · Doctor | Emit JSONL evidence logs and optional DSSE summaries with deterministic ordering and offline-safe defaults. |
| 7 | UI-DR-0007 | DONE | DOCTOR-DR-0002 | Frontend · Web | Build Doctor UI page with packs -> plugins -> checks, copy fix commands, run fix gating, and JSON/DSSE export. |
| 8 | SAMPLES-DR-0008 | DONE | None | Docs · QA | Add sample SBOMs (CycloneDX 1.6 and SPDX 3.0.1) under `samples/` for ingestion tests. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2026-01-13 | Sprint created; advisory synced into docs and sample manifest added. | Product |
| 2026-01-13 | Recorded fix exposure, non-destructive execution, and DSSE command note decisions in docs. | Product |
| 2026-01-13 | Added `src/Doctor/AGENTS.md`, updated scope to allow cross-module edits, and started DOCTOR-DR-0002. | Implementer |
| 2026-01-13 | Implemented YAML pack loader, exec runner, parse expectations, and unit tests. | Implementer |
| 2026-01-13 | Added first-party Doctor packs for GitLab, GitHub, Gitea, Harbor, Vault, and LDAP. | Implementer |
| 2026-01-13 | Added sample CycloneDX 1.6 and SPDX 3.0.1 SBOMs under `samples/`. | Implementer |
| 2026-01-13 | Started DOCTOR-DR-0006 evidence log and DSSE summary output. | Implementer |
| 2026-01-13 | Completed DOCTOR-DR-0006 evidence log and DSSE summary output. | Implementer |
| 2026-01-13 | Marked CLI/UI/orchestrator tasks blocked pending parallel module ownership. | Implementer |
| 2026-01-13 | Started CLI-DR-0004 (doctor run alias and doctor fix pipeline). | Implementer |
| 2026-01-13 | Completed CLI-DR-0004; added doctor fix command and run alias. | Implementer |
| 2026-01-13 | Tests: `dotnet test src/Cli/__Tests/StellaOps.Cli.Tests` failed due to existing compile errors in `src/Cli/StellaOps.Cli/Commands/Scan/BinaryDiffRenderer.cs`, `src/Cli/StellaOps.Cli/Commands/CommandHandlers.Image.cs`, and `src/Cli/StellaOps.Cli/Commands/CommandHandlers.VerdictVerify.cs`. | Implementer |
| 2026-01-13 | Fixed CLI compile errors in `src/Cli/StellaOps.Cli/Commands/Scan/BinaryDiffRenderer.cs`, `src/Cli/StellaOps.Cli/Commands/CommandHandlers.Image.cs`, `src/Cli/StellaOps.Cli/Commands/Scan/BinaryDiffKeyLoader.cs`, and `src/Cli/StellaOps.Cli/Commands/Scan/BinaryDiffService.cs`. | Implementer |
| 2026-01-13 | Tests: `dotnet test src/Cli/__Tests/StellaOps.Cli.Tests -v minimal` failed with MSB9008 warning (missing `StellaOps.Scanner.Storage.Oci.csproj`) and CS2012 file lock on `src/Cli/__Tests/StellaOps.Cli.Tests/obj/Debug/net10.0/StellaOps.Cli.Tests.dll`. | Implementer |
| 2026-01-13 | Tests: rerun with custom `BaseIntermediateOutputPath` failed with duplicate assembly attribute errors in `src/__Libraries/StellaOps.Infrastructure.EfCore` (CS0579). | Implementer |
| 2026-01-13 | Fixed DSSE PAE usage in offline import test and routed JSON output to Console.Out for stable JSON; tests: `dotnet test src/Cli/__Tests/StellaOps.Cli.Tests -v minimal` (pass). | Implementer |
| 2026-01-13 | Started UI-DR-0007 (Doctor pack list, fix gating, DSSE export). | Implementer |
| 2026-01-13 | Completed UI-DR-0007; tests: `npx ng test --watch=false --include "src/app/features/doctor/**/*.spec.ts"` failed due to pre-existing TS errors in advisory-ai, vex-hub, policy, and shared component specs. | Implementer |
## Decisions & Risks
- Decision: UI and CLI must expose fix actions; CLI uses `stella doctor fix` and UI mirrors commands. See `docs/doctor/doctor-capabilities.md` and `docs/doctor/cli-reference.md`.
- Decision: Remediation UX should favor concise copy/paste commands; `how_to_fix` is the agent-facing alias of `remediation`. See `docs/doctor/doctor-capabilities.md` and `docs/modules/release-orchestrator/modules/integration-hub.md`.
- Decision: Doctor fix executes only non-destructive commands; destructive steps are manual and never executed by Doctor. See `docs/doctor/doctor-capabilities.md`.
- Decision: DSSE summaries include `doctor_command` and assume operator execution. See `docs/doctor/doctor-capabilities.md` and `docs/modules/release-orchestrator/modules/integration-hub.md`.
- Risk: Pack execution safety. YAML packs execute CLI commands and must be sandboxed/allowlisted to avoid unsafe actions.
- Risk: DSSE signing flow. Define signer/key ownership and offline key distribution for Doctor summary artifacts.
- BLOCKED: UI/Release Orchestrator tasks paused to avoid conflicts with parallel work in those modules.
## Next Checkpoints
- 2026-01-20: Design review for pack schema, CLI contract, and UI wiring.
- 2026-01-27: Prototype demo with JSONL evidence log and fix command rendering.

View File

@@ -0,0 +1,46 @@
# Sprint 20260113_005_POLICY_assistant_tool_lattice - Assistant Tool Lattice
## Topic & Scope
- Define policy lattice rules for assistant tool access (read-only vs action).
- Provide a policy evaluation surface for Chat Gateway allow/deny checks.
- Align tool access with Authority scopes and tenant constraints.
- **Working directory:** `src/Policy/`.
## Dependencies & Concurrency
- AdvisoryAI sprint depends on this policy evaluation for tool gating.
- Can run in parallel with UI/CLI work once rule schema is agreed.
## Documentation Prerequisites
- `docs/README.md`
- `docs/ARCHITECTURE_OVERVIEW.md`
- `docs/modules/policy/architecture.md`
- `docs/modules/policy/guides/assistant-parameters.md`
- `docs-archived/product/advisories/13-Jan-2026 - Controlled Conversational Interface.md`
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 1 | POL-CHAT-DOCS-0001 | DONE | None | Guild - Policy | Update `docs/modules/policy/guides/assistant-parameters.md` with chat quotas, scrubber, and tool gating settings. |
| 2 | POL-CHAT-SCHEMA-0001 | DONE | None | Guild - Policy | Define tool access schema or DSL rules (tool name, scope, tenant, role, resource). |
| 3 | POL-CHAT-EVAL-0001 | DONE | POL-CHAT-SCHEMA-0001 | Guild - Policy | Implement policy evaluation endpoint for Chat Gateway allow/deny checks. |
| 4 | POL-CHAT-SCOPE-0001 | DONE | POL-CHAT-SCHEMA-0001 | Guild - Policy | Map Authority scopes to tool lattice rules and document default deny behavior. |
| 5 | POL-CHAT-TEST-0001 | DONE | POL-CHAT-EVAL-0001 | Guild - Policy | Add determinism and authorization tests for tool lattice evaluation. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2026-01-13 | Sprint created from controlled conversational interface advisory; docs updated. | Product Mgmt |
| 2026-01-13 | Noted UI/CLI-configurable allowlist defaults for tool lattice alignment. | Product Mgmt |
| 2026-01-13 | Marked remaining policy tasks blocked pending schema decisions and parallel module ownership. | Policy |
| 2026-01-13 | Implemented tool lattice schema, evaluator, gateway endpoint, and tests; documented default scope mapping. | Policy |
## Decisions & Risks
- Decision: Default deny for tool actions; allow read-only tools via explicit rules.
- Decision: Tool lattice parameters are documented in `docs/modules/policy/guides/assistant-parameters.md`.
- Decision: Tool lattice must align with settings-based allowlists (env defaults, UI/CLI overrides).
- Risk: Policy evaluation latency may impact chat UX; ensure caching and deterministic ordering.
- Decision: Default scope mapping documented in `docs/modules/policy/guides/assistant-tool-lattice.md`.
## Next Checkpoints
- DSL/schema review with Policy Guild.
- Contract review with AdvisoryAI for tool allow/deny payloads.

View File

@@ -0,0 +1,48 @@
# Sprint 20260113_005_UI_advisor_chat_panel - Advisor Chat Panel
## Topic & Scope
- Deliver the Advisor chat panel with evidence citations and action confirmation.
- Provide UI parity for controlled conversational interface (read-only by default).
- Surface quota/budget feedback for chat requests.
- **Working directory:** `src/Web/StellaOps.Web/`.
## Dependencies & Concurrency
- Depends on AdvisoryAI chat endpoints and tool schema stability.
- Can run in parallel with CLI work once API contracts are set.
## Documentation Prerequisites
- `docs/README.md`
- `docs/modules/ui/architecture.md`
- `docs/modules/advisory-ai/chat-interface.md`
- `docs/security/assistant-guardrails.md`
- `docs-archived/product/advisories/13-Jan-2026 - Controlled Conversational Interface.md`
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 1 | UI-CHAT-DOCS-0001 | DONE | None | Guild - UI | Update `docs/modules/ui/architecture.md` with Advisor chat panel and evidence drawer notes. |
| 2 | UI-CHAT-PANEL-0001 | BLOCKED | AdvisoryAI chat API | Guild - UI | Build chat panel with conversation list, streaming responses, and input controls. |
| 3 | UI-CHAT-CITATIONS-0001 | BLOCKED | UI-CHAT-PANEL-0001 | Guild - UI | Implement citations and evidence chips with object ref links. |
| 4 | UI-CHAT-ACTIONS-0001 | BLOCKED | Policy tool lattice | Guild - UI | Add action confirmation modal and policy-deny display states. |
| 5 | UI-CHAT-QUOTA-0001 | BLOCKED | UI-CHAT-PANEL-0001 | Guild - UI | Surface quota/budget exhaustion and retry hints (doctor output). |
| 6 | UI-CHAT-TEST-0001 | BLOCKED | UI-CHAT-PANEL-0001 | Guild - UI | Add unit and e2e coverage for chat panel, citations, and actions. |
| 7 | UI-CHAT-SETTINGS-0001 | BLOCKED | AdvisoryAI settings API | Guild - UI | Add settings view for chat quotas and tool allowlist (env defaults + overrides). |
| 8 | UI-CHAT-DOCTOR-0001 | BLOCKED | UI-CHAT-PANEL-0001 | Guild - UI | Add doctor action to show chat limit status and last denial reasons. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2026-01-13 | Sprint created from controlled conversational interface advisory; docs updated. | Product Mgmt |
| 2026-01-13 | Added settings and doctor tasks for quota/allowlist overrides. | Product Mgmt |
| 2026-01-13 | Marked UI chat tasks blocked pending API/tool lattice stability and parallel module ownership. | UI |
## Decisions & Risks
- Decision: Advisor UI defaults to read-only; actions are opt-in and confirmed.
- Decision: Advisor UI surface documented in `docs/modules/ui/architecture.md`.
- Decision: Settings UI must show env defaults and saved overrides for quotas/allowlist.
- Risk: Streaming UI performance; ensure backpressure and log scrubbing on client.
- BLOCKED: AdvisoryAI API and policy lattice contracts pending; avoid parallel changes without coordination.
## Next Checkpoints
- UI design review with citations panel mock.
- API contract validation for streaming chat events.