save checkpoint: save features
This commit is contained in:
@@ -1,10 +1,26 @@
|
||||
# AirGap Controller Task Board
|
||||
# AirGap Controller Task Board
|
||||
|
||||
This board mirrors active sprint tasks for this module.
|
||||
Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229_049_BE_csproj_audit_maint_tests.md`.
|
||||
|
||||
| Task ID | Status | Notes |
|
||||
| --- | --- | --- |
|
||||
| QA-AIRGAP-VERIFY-001 | DONE | Completed `air-gap-bundle-system`; evidence captured under `docs/qa/feature-checks/runs/airgap/air-gap-bundle-system/run-001/`. |
|
||||
| QA-AIRGAP-VERIFY-002 | DONE | Completed `air-gap-epistemic-mode-with-sealed-startup-and-feed-snapshots`; evidence captured under `docs/qa/feature-checks/runs/airgap/air-gap-epistemic-mode-with-sealed-startup-and-feed-snapshots/run-001/`. |
|
||||
| QA-AIRGAP-VERIFY-003 | DONE | Completed `deterministic-rekor-receipts-with-offline-verification`; evidence captured under `docs/qa/feature-checks/runs/airgap/deterministic-rekor-receipts-with-offline-verification/run-002/`. |
|
||||
| QA-AIRGAP-VERIFY-004 | DONE | Completed `deterministic-replay-and-verification-in-air-gap-mode`; evidence captured under `docs/qa/feature-checks/runs/airgap/deterministic-replay-and-verification-in-air-gap-mode/run-001/`. |
|
||||
| QA-AIRGAP-VERIFY-005 | DONE | Completed `deterministic-test-harness`; evidence captured under `docs/qa/feature-checks/runs/airgap/deterministic-test-harness/run-001/`. |
|
||||
| QA-AIRGAP-VERIFY-006 | DONE | Completed `dsse-receipt-schema-for-authority-sbomer-vexer-flows`; evidence captured under `docs/qa/feature-checks/runs/airgap/dsse-receipt-schema-for-authority-sbomer-vexer-flows/run-001/`. |
|
||||
| QA-AIRGAP-VERIFY-007 | BLOCKED | Ownership handoff applied by user direction; lane terminalized as `skipped` with `skipReason=owned_by_other_agent` per FLOW collision handling. |
|
||||
| QA-AIRGAP-VERIFY-008 | DONE | Completed `offline-kit-metrics-and-diagnostics`; evidence captured under `docs/qa/feature-checks/runs/airgap/offline-kit-metrics-and-diagnostics/run-001/`. |
|
||||
| QA-AIRGAP-VERIFY-009 | DONE | Completed `time-anchoring-for-offline-environments`; evidence captured under `docs/qa/feature-checks/runs/airgap/time-anchoring-for-offline-environments/run-001/`. |
|
||||
| QA-AIRGAP-VERIFY-010 | DONE | Completed `trust-profile-management`; evidence captured under `docs/qa/feature-checks/runs/airgap/trust-profile-management/run-002/`. |
|
||||
| AUDIT-0024-M | DONE | Revalidated 2026-01-06 (maintainability audit). |
|
||||
| AUDIT-0024-T | DONE | Revalidated 2026-01-06 (test coverage audit). |
|
||||
| AUDIT-0024-A | TODO | Revalidated 2026-01-06; open findings pending apply. |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,11 +1,27 @@
|
||||
# AirGap Importer Task Board
|
||||
# AirGap Importer Task Board
|
||||
|
||||
This board mirrors active sprint tasks for this module.
|
||||
Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229_049_BE_csproj_audit_maint_tests.md`.
|
||||
|
||||
| Task ID | Status | Notes |
|
||||
| --- | --- | --- |
|
||||
| QA-AIRGAP-VERIFY-001 | DONE | Completed `air-gap-bundle-system`; evidence captured under `docs/qa/feature-checks/runs/airgap/air-gap-bundle-system/run-001/`. |
|
||||
| QA-AIRGAP-VERIFY-002 | DONE | Completed `air-gap-epistemic-mode-with-sealed-startup-and-feed-snapshots`; evidence captured under `docs/qa/feature-checks/runs/airgap/air-gap-epistemic-mode-with-sealed-startup-and-feed-snapshots/run-001/`. |
|
||||
| QA-AIRGAP-VERIFY-003 | DONE | Completed `deterministic-rekor-receipts-with-offline-verification`; evidence captured under `docs/qa/feature-checks/runs/airgap/deterministic-rekor-receipts-with-offline-verification/run-002/`. |
|
||||
| QA-AIRGAP-VERIFY-004 | DONE | Completed `deterministic-replay-and-verification-in-air-gap-mode`; evidence captured under `docs/qa/feature-checks/runs/airgap/deterministic-replay-and-verification-in-air-gap-mode/run-001/`. |
|
||||
| QA-AIRGAP-VERIFY-005 | DONE | Completed `deterministic-test-harness`; evidence captured under `docs/qa/feature-checks/runs/airgap/deterministic-test-harness/run-001/`. |
|
||||
| QA-AIRGAP-VERIFY-006 | DONE | Completed `dsse-receipt-schema-for-authority-sbomer-vexer-flows`; evidence captured under `docs/qa/feature-checks/runs/airgap/dsse-receipt-schema-for-authority-sbomer-vexer-flows/run-001/`. |
|
||||
| QA-AIRGAP-VERIFY-007 | BLOCKED | Ownership handoff applied by user direction; lane terminalized as `skipped` with `skipReason=owned_by_other_agent` per FLOW collision handling. |
|
||||
| QA-AIRGAP-VERIFY-008 | DONE | Completed `offline-kit-metrics-and-diagnostics`; evidence captured under `docs/qa/feature-checks/runs/airgap/offline-kit-metrics-and-diagnostics/run-001/`. |
|
||||
| QA-AIRGAP-VERIFY-009 | DONE | Completed `time-anchoring-for-offline-environments`; evidence captured under `docs/qa/feature-checks/runs/airgap/time-anchoring-for-offline-environments/run-001/`. |
|
||||
| QA-AIRGAP-VERIFY-010 | DONE | Completed `trust-profile-management`; evidence captured under `docs/qa/feature-checks/runs/airgap/trust-profile-management/run-002/`. |
|
||||
| AUDIT-0026-M | DONE | Revalidated 2026-01-06; findings recorded in audit report. |
|
||||
| AUDIT-0026-T | DONE | Revalidated 2026-01-06; test gaps recorded in audit report. |
|
||||
| AUDIT-0026-A | TODO | DSSE PAE helper + invariant formatting, EvidenceGraph canonical JSON, RuleBundleValidator path validation, JsonNormalizer culture, parser JsonOptions, SbomNormalizer ASCII. |
|
||||
| VAL-SMOKE-001 | DONE | Resolved DSSE signer ambiguity; smoke build now proceeds. |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,13 +1,29 @@
|
||||
# AirGap Time Task Board
|
||||
# AirGap Time Task Board
|
||||
|
||||
This board mirrors active sprint tasks for this module.
|
||||
Source of truth: `docs/implplan/SPRINT_20260130_002_Tools_csproj_remediation_solid_review.md` and `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229_049_BE_csproj_audit_maint_tests.md`.
|
||||
|
||||
| Task ID | Status | Notes |
|
||||
| --- | --- | --- |
|
||||
| QA-AIRGAP-VERIFY-001 | DONE | Completed `air-gap-bundle-system`; evidence captured under `docs/qa/feature-checks/runs/airgap/air-gap-bundle-system/run-001/`. |
|
||||
| QA-AIRGAP-VERIFY-002 | DONE | Completed `air-gap-epistemic-mode-with-sealed-startup-and-feed-snapshots`; evidence captured under `docs/qa/feature-checks/runs/airgap/air-gap-epistemic-mode-with-sealed-startup-and-feed-snapshots/run-001/`. |
|
||||
| QA-AIRGAP-VERIFY-003 | DONE | Completed `deterministic-rekor-receipts-with-offline-verification`; evidence captured under `docs/qa/feature-checks/runs/airgap/deterministic-rekor-receipts-with-offline-verification/run-002/`. |
|
||||
| QA-AIRGAP-VERIFY-004 | DONE | Completed `deterministic-replay-and-verification-in-air-gap-mode`; evidence captured under `docs/qa/feature-checks/runs/airgap/deterministic-replay-and-verification-in-air-gap-mode/run-001/`. |
|
||||
| QA-AIRGAP-VERIFY-005 | DONE | Completed `deterministic-test-harness`; evidence captured under `docs/qa/feature-checks/runs/airgap/deterministic-test-harness/run-001/`. |
|
||||
| QA-AIRGAP-VERIFY-006 | DONE | Completed `dsse-receipt-schema-for-authority-sbomer-vexer-flows`; evidence captured under `docs/qa/feature-checks/runs/airgap/dsse-receipt-schema-for-authority-sbomer-vexer-flows/run-001/`. |
|
||||
| QA-AIRGAP-VERIFY-007 | BLOCKED | Ownership handoff applied by user direction; lane terminalized as `skipped` with `skipReason=owned_by_other_agent` per FLOW collision handling. |
|
||||
| QA-AIRGAP-VERIFY-008 | DONE | Completed `offline-kit-metrics-and-diagnostics`; evidence captured under `docs/qa/feature-checks/runs/airgap/offline-kit-metrics-and-diagnostics/run-001/`. |
|
||||
| QA-AIRGAP-VERIFY-009 | DONE | Completed `time-anchoring-for-offline-environments`; evidence captured under `docs/qa/feature-checks/runs/airgap/time-anchoring-for-offline-environments/run-001/`. |
|
||||
| QA-AIRGAP-VERIFY-010 | DONE | Completed `trust-profile-management`; evidence captured under `docs/qa/feature-checks/runs/airgap/trust-profile-management/run-002/`. |
|
||||
| AUDIT-0034-M | DONE | Revalidated 2026-01-06; findings recorded in audit report. |
|
||||
| AUDIT-0034-T | DONE | Revalidated 2026-01-06; test coverage tracked in AUDIT-0035. |
|
||||
| AUDIT-0034-A | TODO | Address TimeTelemetry queue growth, TimeTokenParser endianness, and default store wiring. |
|
||||
| TASK-029-002 | DONE | Offline RFC3161 verification using bundled TSA chain/OCSP/CRL. |
|
||||
| REMED-05 | DONE | Remediation checklist: docs/implplan/audits/csproj-standards/remediation/checklists/src/AirGap/StellaOps.AirGap.Time/StellaOps.AirGap.Time.md. |
|
||||
| REMED-06 | DONE | SOLID review notes updated for SPRINT_20260130_002. |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
using StellaOps.AirGap.Importer.Policy;
|
||||
using StellaOps.TestKit;
|
||||
|
||||
namespace StellaOps.AirGap.Importer.Tests;
|
||||
|
||||
public sealed class OfflineVerificationPolicyLoaderTests
|
||||
{
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task LoadAsync_ParsesYaml_AndCanonicalizes()
|
||||
{
|
||||
var filePath = CreateTempFilePath(".yaml");
|
||||
try
|
||||
{
|
||||
const string yaml = """
|
||||
keys:
|
||||
- " KeyB "
|
||||
- "keya"
|
||||
- "KEYB"
|
||||
tlog:
|
||||
mode: "STRICT "
|
||||
checkpoint: " checkpoints/latest.chk "
|
||||
entry_pack: " entries/latest.pack "
|
||||
attestations:
|
||||
required:
|
||||
- type: "SLSA"
|
||||
- type: " slsa "
|
||||
optional:
|
||||
- type: "SPDX"
|
||||
constraints:
|
||||
subjects:
|
||||
alg: " SHA256 "
|
||||
certs:
|
||||
allowed_issuers:
|
||||
- " CN=RootB "
|
||||
- "CN=RootA"
|
||||
- "cn=rootb"
|
||||
allow_expired_if_timepinned: true
|
||||
""";
|
||||
|
||||
await File.WriteAllTextAsync(filePath, yaml);
|
||||
|
||||
var policy = await OfflineVerificationPolicyLoader.LoadAsync(filePath);
|
||||
|
||||
Assert.Equal(["keya", "KeyB"], policy.Keys);
|
||||
Assert.Equal("strict", policy.Tlog?.Mode);
|
||||
Assert.Equal("checkpoints/latest.chk", policy.Tlog?.Checkpoint);
|
||||
Assert.Equal("entries/latest.pack", policy.Tlog?.EntryPack);
|
||||
Assert.Equal(["slsa"], policy.Attestations?.Required.Select(static r => r.Type).ToArray());
|
||||
Assert.Equal(["spdx"], policy.Attestations?.Optional.Select(static r => r.Type).ToArray());
|
||||
Assert.Equal("sha256", policy.Constraints?.Subjects?.Algorithm);
|
||||
Assert.Equal(["CN=RootA", "CN=RootB"], policy.Constraints?.Certs?.AllowedIssuers);
|
||||
Assert.True(policy.Constraints?.Certs?.AllowExpiredIfTimePinned);
|
||||
}
|
||||
finally
|
||||
{
|
||||
DeleteIfExists(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task LoadAsync_ParsesJsonWithCommentsAndTrailingCommas()
|
||||
{
|
||||
var filePath = CreateTempFilePath(".json");
|
||||
try
|
||||
{
|
||||
const string json = """
|
||||
{
|
||||
// comment
|
||||
"keys": ["k2", "k1",],
|
||||
"tlog": {
|
||||
"mode": "PERMISSIVE",
|
||||
},
|
||||
}
|
||||
""";
|
||||
|
||||
await File.WriteAllTextAsync(filePath, json);
|
||||
|
||||
var policy = await OfflineVerificationPolicyLoader.LoadAsync(filePath);
|
||||
|
||||
Assert.Equal(["k1", "k2"], policy.Keys);
|
||||
Assert.Equal("permissive", policy.Tlog?.Mode);
|
||||
}
|
||||
finally
|
||||
{
|
||||
DeleteIfExists(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task LoadAsync_Throws_WhenPolicyIsEmpty()
|
||||
{
|
||||
var filePath = CreateTempFilePath(".yaml");
|
||||
try
|
||||
{
|
||||
await File.WriteAllTextAsync(filePath, " ");
|
||||
|
||||
await Assert.ThrowsAsync<InvalidDataException>(() => OfflineVerificationPolicyLoader.LoadAsync(filePath));
|
||||
}
|
||||
finally
|
||||
{
|
||||
DeleteIfExists(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
private static string CreateTempFilePath(string extension)
|
||||
{
|
||||
var root = Path.Combine(Path.GetTempPath(), "stellaops-airgap-tests", Guid.NewGuid().ToString("N"));
|
||||
Directory.CreateDirectory(root);
|
||||
return Path.Combine(root, $"offline-policy{extension}");
|
||||
}
|
||||
|
||||
private static void DeleteIfExists(string filePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var dir = Path.GetDirectoryName(filePath);
|
||||
if (!string.IsNullOrWhiteSpace(dir) && Directory.Exists(dir))
|
||||
{
|
||||
Directory.Delete(dir, recursive: true);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Best-effort cleanup for test temp assets.
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user