feat: expand controlled package lifecycle pilot evidence

This commit is contained in:
codex
2026-08-06 09:59:43 +03:00
parent 64fa1f5664
commit 9fce6ee830
+28 -9
View File
@@ -1,4 +1,5 @@
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.IO;
using Launcher.Next.Core;
@@ -8,22 +9,40 @@ namespace Launcher.Next.App;
internal static class PackageLifecyclePilotCli
{
private sealed class Fault(PackageLifecycleFaultPoint point) : IPackageLifecycleFaultInjector
{ public void ThrowIfRequested(PackageLifecycleFaultPoint requested) { if(requested==point) throw new IOException($"INJECTED:{point}"); } }
public static async Task<int> RunAsync(string[] args)
{
if (args.Length != 4 || args[0] != "--mode" || args[1] != "PackageLifecyclePilot" || args[2] != "--root") return 2;
ResolvedPackagePilotRoot pilotRoot; try { pilotRoot=new PathResolver().ResolvePackagePilotRoot(args[3]); } catch { return 2; }
var root=pilotRoot.Value; var id=Guid.NewGuid().ToString("N"); var evidenceDir=Path.Combine(root,"evidence",id); Directory.CreateDirectory(evidenceDir);
ResolvedPackageLifecycleRoots roots; try { roots=new PathResolver().ResolvePackageLifecycleRoots(args[3]); } catch { return 2; }
var id=Guid.NewGuid().ToString("N"); var started=DateTimeOffset.UtcNow; var evidenceDir=Path.Combine(roots.Evidence.Value,id);
Directory.CreateDirectory(evidenceDir); Directory.CreateDirectory(roots.Catalog.Value); Directory.CreateDirectory(Path.Combine(roots.Pilot.Value,"foreign-staging-fixture"));
try
{
var catalog=Path.Combine(root,"catalog"); Directory.CreateDirectory(catalog); var store=new LocalPackageStore(root,new Sha256FileHasher());
async Task<(ImmutableLocalPackage,PackageManifest)> Materialize(string version,byte seed)
{ var a=new[]{seed,(byte)(seed+1)}; var b=new[]{(byte)(seed+2)}; await File.WriteAllBytesAsync(Path.Combine(catalog,"entry.dll"),a); await File.WriteAllBytesAsync(Path.Combine(catalog,"payload.dat"),b); var manifest=new PackageManifest(1,"Pilot.Package",version,"Plant3D",2026,"x64","entry.dll",[new("entry.dll",a.Length,Convert.ToHexString(SHA256.HashData(a))),new("payload.dat",b.Length,Convert.ToHexString(SHA256.HashData(b)))],new("none",""),RolloutChannel:"pilot"); return (await store.MaterializeAsync(manifest,catalog,CancellationToken.None),manifest); }
var store=new LocalPackageStore(roots.Pilot.Value,new Sha256FileHasher());
async Task<(ImmutableLocalPackage Package,PackageManifest Manifest)> Materialize(string version,byte seed,LocalPackageStore target)
{ var a=new[]{seed,(byte)(seed+1)};var b=new[]{(byte)(seed+2)};await File.WriteAllBytesAsync(Path.Combine(roots.Catalog.Value,"entry.dll"),a);await File.WriteAllBytesAsync(Path.Combine(roots.Catalog.Value,"payload.dat"),b);var manifest=new PackageManifest(1,"Pilot.Package",version,"Plant3D",2026,"x64","entry.dll",[new("entry.dll",a.Length,Convert.ToHexString(SHA256.HashData(a))),new("payload.dat",b.Length,Convert.ToHexString(SHA256.HashData(b)))],new("none",""),RolloutChannel:"pilot");return(await target.MaterializeAsync(manifest,roots.Catalog.Value,CancellationToken.None),manifest); }
PackageRequirement Req(string v)=>new("Pilot.Package","Plant3D",2026,"x64","pilot",v,"pilot-roster",true);
var (a,ma)=await Materialize("1.0.0",1); var pointersAfterA=await store.GetCurrentVersionAsync("Pilot.Package",CancellationToken.None); var aa=await store.ActivateImmutableAsync(a,Req("1.0.0"),CancellationToken.None); var repeat=await store.ActivateImmutableAsync(a,Req("1.0.0"),CancellationToken.None);
var (b,mb)=await Materialize("2.0.0",4); var beforeB=await store.GetCurrentVersionAsync("Pilot.Package",CancellationToken.None); var ab=await store.ActivateImmutableAsync(b,Req("2.0.0"),CancellationToken.None); var rollback=await store.RollbackAsync(ab.Receipt!,CancellationToken.None); var current=await store.GetCurrentVersionAsync("Pilot.Package",CancellationToken.None);
var evidence=new { schemaVersion=1,mode="PackageLifecyclePilot",operationId=id,terminalState=current=="1.0.0"?"Succeeded":"Blocked",sourceClassification="SyntheticLocal",rootFingerprint=Convert.ToHexString(SHA256.HashData(System.Text.Encoding.UTF8.GetBytes(id+root))),packages=new[]{new{version=ma.Version,manifestSha256=Convert.ToHexString(SHA256.HashData(JsonSerializer.SerializeToUtf8Bytes(ma)))},new{version=mb.Version,manifestSha256=Convert.ToHexString(SHA256.HashData(JsonSerializer.SerializeToUtf8Bytes(mb)))}},pointers=new{afterMaterializeA=pointersAfterA,afterActivateA=aa.Outcome,repeatedA=repeat.Outcome,beforeActivateB=beforeB,afterActivateB=ab.Outcome,afterRollback=rollback.Outcome,current},sideEffects=new{corporateDfsUsed=false,corporateDfsWriteAttempted=false,autoCadLaunchAttempted=false,processLaunchAttempted=false,productionPointerMutationAttempted=false,productionProjectAccessed=false}};
var final=Path.Combine(evidenceDir,"package-lifecycle-pilot.json"); var temp=final+".tmp"; await File.WriteAllTextAsync(temp,JsonSerializer.Serialize(evidence)); File.Move(temp,final,true); return current=="1.0.0"?0:2;
var initial=await store.GetCurrentVersionAsync("Pilot.Package",CancellationToken.None);
var (a,ma)=await Materialize("1.0.0",1,store); var afterMaterializeA=await store.GetCurrentVersionAsync("Pilot.Package",CancellationToken.None); await store.BindAsync(Req("1.0.0"),"1.0.0",CancellationToken.None);
var aa=await store.ActivateImmutableAsync(a,Req("1.0.0"),CancellationToken.None); var repeat=await store.ActivateImmutableAsync(a,Req("1.0.0"),CancellationToken.None);
var (b,mb)=await Materialize("2.0.0",4,store); var beforeB=await store.GetCurrentVersionAsync("Pilot.Package",CancellationToken.None); await store.BindAsync(Req("2.0.0"),"2.0.0",CancellationToken.None);
var ab=await store.ActivateImmutableAsync(b,Req("2.0.0"),CancellationToken.None); var rollback=await store.RollbackAsync(ab.Receipt!,CancellationToken.None); var current=await store.GetCurrentVersionAsync("Pilot.Package",CancellationToken.None); var lkg=await store.ResolveAsync(Req("1.0.0"),CancellationToken.None);
async Task<string> ExpectedFault(PackageLifecycleFaultPoint point,string version)
{ try { await Materialize(version,9,new LocalPackageStore(roots.Pilot.Value,new Sha256FileHasher(),new Fault(point))); return "UnexpectedSuccess"; } catch { return "Blocked"; } }
var materializationFault=await ExpectedFault(PackageLifecycleFaultPoint.AfterPayloadCopyBeforeValidation,"9.0.0");
string pointerFault; try { await new LocalPackageStore(roots.Pilot.Value,new Sha256FileHasher(),new Fault(PackageLifecycleFaultPoint.BeforePointerReplace)).ActivateImmutableAsync(b,Req("2.0.0"),CancellationToken.None);pointerFault="UnexpectedSuccess";}catch{pointerFault="Blocked";}
var foreign=Path.Combine(roots.Pilot.Value,"foreign-staging-fixture");var fake=new PackageStagingOwnership("foreign","Pilot.Package","0",foreign,DateTimeOffset.UtcNow,"foreign");var cleanup=(await store.CleanupOwnedStagingAsync(fake,CancellationToken.None)).Outcome;
var success=initial is null&&afterMaterializeA is null&&aa.Outcome=="Activated"&&repeat.Outcome=="AlreadyActiveExact"&&beforeB=="1.0.0"&&ab.Outcome=="Activated"&&rollback.Outcome=="RolledBack"&&current=="1.0.0"&&lkg?.Version=="1.0.0"&&materializationFault=="Blocked"&&pointerFault=="Blocked"&&cleanup=="OwnershipUnknown"&&Directory.Exists(foreign);
object Package(PackageManifest m)=>new{exactIdentity=new{m.PackageId,m.Product,m.ProductYear,m.Architecture,m.RolloutChannel,m.Version},manifestSha256=Convert.ToHexString(SHA256.HashData(JsonSerializer.SerializeToUtf8Bytes(m))),payloadSetSha256=PayloadSet(m),payloadFiles=m.Files.Select(x=>new{x.Path,x.Length,x.Sha256})};
var evidence=new { schemaVersion=2,launcherCommit=ThisCommit(),operationId=id,mode="PackageLifecyclePilot",startedUtc=started,endedUtc=DateTimeOffset.UtcNow,terminalState=success?"Succeeded":"Blocked",exitClassification=success?"CONTROLLED_FILESYSTEM_PILOT_VERIFIED":"BLOCKED",sourceClassification="SyntheticLocal",typedRoots=new[]{Role("Catalog",roots.Catalog.Value,id),Role("Staging",roots.Staging.Value,id),Role("VersionStore",roots.VersionStore.Value,id),Role("Active",roots.Active.Value,id),Role("Evidence",roots.Evidence.Value,id)},packages=new[]{Package(ma),Package(mb)},pointers=new{initial,afterMaterializeA,afterActivateA=aa.Outcome,generationA=aa.Receipt?.PointerGeneration,repeatedA=repeat.Outcome,beforeActivateB=beforeB,afterActivateB=ab.Outcome,generationB=ab.Receipt?.PointerGeneration,afterRollback=rollback.Outcome,current,contentBoundSchema=2},exactLkg=new{selected=lkg?.Version,directoryScanAttempted=false,exactBinding=lkg is not null},failureScenarios=new[]{new{faultPoint="AfterPayloadCopyBeforeValidation",actual=materializationFault,invariant=current=="1.0.0"},new{faultPoint="BeforePointerReplace",actual=pointerFault,invariant=(await store.GetCurrentVersionAsync("Pilot.Package",CancellationToken.None))=="1.0.0"},new{faultPoint="OwnershipMismatch",actual=cleanup,invariant=Directory.Exists(foreign)}},locking=new{scope="ProcessLocal",crossProcessSafety="NotVerified",networkShareSafety="NotSupported"},sideEffects=new{corporateDfsUsed=false,corporateDfsWriteAttempted=false,autoCadLaunchAttempted=false,processLaunchAttempted=false,productionPointerMutationAttempted=false,productionProjectAccessed=false,foundationUiCreated=false},claims=new{materializationIsolation="Verified",ownedStagingCleanup="Verified",immutableContentBinding="Verified",activation="Verified",activationIdempotency="Verified",receiptBoundRollback="Verified",deterministicFailureRecovery="Verified",exactLkg="Verified",processLocalConcurrency="Verified",corporateDfs="NotVerified",autoCadRuntime="NotVerified",productionAcceptance="NotVerified"}};
var final=Path.Combine(evidenceDir,"package-lifecycle-pilot.json");var temp=final+"."+id+".tmp";await using(var stream=new FileStream(temp,FileMode.CreateNew,FileAccess.Write,FileShare.None)){await JsonSerializer.SerializeAsync(stream,evidence);await stream.FlushAsync();stream.Flush(true);}File.Move(temp,final);using var reread=JsonDocument.Parse(await File.ReadAllTextAsync(final));if(reread.RootElement.GetProperty("schemaVersion").GetInt32()!=2)return 10;return success?0:10;
}
catch { return 10; }
}
private static object Role(string role,string path,string salt)=>new{role,localOnly=true,topologyValidated=true,reparseRejected=true,fingerprint=Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(salt+Path.GetFullPath(path))))};
private static string PayloadSet(PackageManifest m)=>Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(string.Join("|",m.Files.OrderBy(x=>x.Path,StringComparer.Ordinal).Select(x=>$"{x.Path}:{x.Length}:{x.Sha256}")))));
private static string ThisCommit()=>Environment.GetEnvironmentVariable("LAUNCHER_COMMIT")??"WORKTREE_BUILD";
}