use common.nu *

# Retain actual records/archives once, omitting reproducible extracted source copies.
def 'main pack' [evidence: string, tools: string, output: string, staging: string] {
    let records = ($evidence | path expand)
    let tools = ($tools | path expand)
    let out = ($output | path expand)
    let stage = ($staging | path expand)
    fresh $out
    fresh $stage
    let tooling = (tool-bundle $tools)
    let selected = (files $records | where {|f|
        not ($f.path | str starts-with package/baseline/) and not ($f.path | str starts-with package/current/)
        and not ($f.path | str starts-with consumer/nox/)
    })
    for file in $selected {
        let dest = ($stage | path join records $file.path)
        mkdir ($dest | path dirname)
        cp ($records | path join $file.path) $dest
        require ((digest $dest) == $file.sha256) 'record changed while retaining'
    }
    for file in (files $tools) {
        let dest = ($stage | path join tools $file.path)
        mkdir ($dest | path dirname)
        cp ($tools | path join $file.path) $dest
        require ((digest $dest) == $file.sha256) 'tool changed while retaining'
    }
    let inventory = (files $stage)
    capture $out archive [tar -czf ($out | path join evidence.tar.gz) -C $stage ...$inventory.path] $out {} | ignore
    {files: $inventory, tooling: $tooling, capsule_sha256: (digest ($out | path join evidence.tar.gz)),
        candidate: (open ($records | path join package/identities.json)).candidate.head,
        publication_authorized: false} | to json | save ($out | path join bundle.json)
}

def 'main unpack' [capsule: string, destination: string] {
    let source = ($capsule | path expand)
    let out = ($destination | path expand)
    let manifest = (open ($source | path join bundle.json))
    let archive = ($source | path join evidence.tar.gz)
    require ((digest $archive) == $manifest.capsule_sha256) 'capsule checksum differs'
    let listing = (do { ^tar -tzf $archive } | complete)
    require ($listing.exit_code == 0 and ($listing.stdout | lines | sort) == ($manifest.files.path | sort)) 'capsule inventory differs'
    require ($manifest.files.path | all {|p| not ($p | str starts-with '/') and '..' not-in ($p | split row '/')}) 'unsafe capsule member'
    fresh $out
    let result = (do { ^tar -xzf $archive -C $out } | complete)
    require ($result.exit_code == 0 and (files $out) == $manifest.files) 'capsule contents differ'
    {records: ($out | path join records), tools: ($out | path join tools)} | to json
}

def main [] { help main }

Homonyms

cyb/honeycrisp/audit/2026-10-17-acpu-package-evidence/retain.nu
cyb/honeycrisp/audit/2026-10-17-acpu-release-proposal/retain.nu
soft3/nox/audit/2026-10-17-published-api-baseline/retain.nu
soft3/nox/audit/2026-10-17-hemera-feature-performance/retain.nu
soft3/nox/audit/2026-10-17-published-api-baseline/retention-1/retain.nu
cyb/honeycrisp/audit/2026-10-17-acpu-release-proposal/review-epoch-2/audit/2026-10-17-acpu-release-proposal/retain.nu

Graph