feat: Add VEX compact fixture and implement offline verifier for Findings Ledger exports

- Introduced a new VEX compact fixture for testing purposes.
- Implemented `verify_export.py` script to validate Findings Ledger exports, ensuring deterministic ordering and applying redaction manifests.
- Added a lightweight stub `HarnessRunner` for unit tests to validate ledger hashing expectations.
- Documented tasks related to the Mirror Creator.
- Created models for entropy signals and implemented the `EntropyPenaltyCalculator` to compute penalties based on scanner outputs.
- Developed unit tests for `EntropyPenaltyCalculator` to ensure correct penalty calculations and handling of edge cases.
- Added tests for symbol ID normalization in the reachability scanner.
- Enhanced console status service with comprehensive unit tests for connection handling and error recovery.
- Included Cosign tool version 2.6.0 with checksums for various platforms.
This commit is contained in:
StellaOps Bot
2025-12-02 21:08:01 +02:00
parent 6d049905c7
commit 47168fec38
146 changed files with 4329 additions and 549 deletions

View File

@@ -132,14 +132,21 @@ public static class SymbolId
}
/// <summary>
/// Creates a binary symbol ID from ELF/PE/Mach-O components.
/// Creates a binary symbol ID from ELF/PE/Mach-O components (legacy overload).
/// </summary>
/// <param name="buildId">Binary build-id (GNU build-id, PE GUID, Mach-O UUID).</param>
/// <param name="section">Section name (e.g., ".text", ".dynsym").</param>
/// <param name="symbolName">Symbol name from symbol table.</param>
public static string ForBinary(string buildId, string section, string symbolName)
=> ForBinaryAddressed(buildId, section, string.Empty, symbolName, "static", null);
/// <summary>
/// Creates a binary symbol ID that includes file hash, section, address, and linkage.
/// Aligns with {file:hash, section, addr, name, linkage} tuple used by richgraph-v1.
/// </summary>
public static string ForBinaryAddressed(string fileHash, string section, string address, string symbolName, string linkage, string? codeBlockHash = null)
{
var tuple = $"{Norm(buildId)}\0{Norm(section)}\0{Norm(symbolName)}";
var tuple = $"{Norm(fileHash)}\0{Norm(section)}\0{NormalizeAddress(address)}\0{Norm(symbolName)}\0{Norm(linkage)}\0{Norm(codeBlockHash)}";
return Build(Lang.Binary, tuple);
}
@@ -219,6 +226,40 @@ public static class SymbolId
return $"sym:{lang}:{hash}";
}
private static string NormalizeAddress(string? value)
{
if (string.IsNullOrWhiteSpace(value))
{
return "0x0";
}
var addrText = value.Trim();
var isHex = addrText.StartsWith("0x", StringComparison.OrdinalIgnoreCase);
if (isHex)
{
addrText = addrText[2..];
}
if (long.TryParse(addrText, isHex ? System.Globalization.NumberStyles.HexNumber : System.Globalization.NumberStyles.Integer, System.Globalization.CultureInfo.InvariantCulture, out var addrValue))
{
if (addrValue < 0)
{
addrValue = 0;
}
return $"0x{addrValue:x}";
}
// Fallback to normalized string representation
addrText = addrText.TrimStart('0');
if (addrText.Length == 0)
{
addrText = "0";
}
return $"0x{addrText.ToLowerInvariant()}";
}
private static string ComputeFragment(string tuple)
{
var bytes = Encoding.UTF8.GetBytes(tuple);