themesd advisories enhanced
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
- 13-Dec-2025 - Designing the Call‑Stack Reachability Engine
|
||||
- 03-Dec-2025 - Reachability Benchmarks and Moat Metrics
|
||||
- 09-Dec-2025 - Caching Reachability the Smart Way
|
||||
- 06-Dec-2025 - Reachability Methods Worth Testing This Week
|
||||
- 04-Dec-2025 - Ranking Unknowns in Reachability Graphs
|
||||
- 02-Dec-2025 - Designing Deterministic Reachability UX
|
||||
- 05-Dec-2025 - Design Notes on Smart‑Diff and Call‑Stack Analysis
|
||||
@@ -69,6 +70,48 @@
|
||||
- No machine-local files
|
||||
- No system clock inside algorithms
|
||||
|
||||
### 1.4 Build Once, Query Many (avoid all-pairs precompute)
|
||||
|
||||
Separate *graph construction* from *reachability queries*:
|
||||
|
||||
1. **Build step (once per artifact/version)**
|
||||
- Produce a deterministic call graph index: `CallGraph.v1.json` (or a binary format with an accompanying canonical JSON manifest and digest).
|
||||
- Persist it content-addressed and bind it into the `ReplayManifest`.
|
||||
|
||||
2. **Query step (per entrypoint/sink query)**
|
||||
- Run a bounded search (BFS / bidirectional BFS / A*) over the stored index.
|
||||
- Return: `reachable`, a canonical shortest path, and `why[]` evidence (callsite/method IDs).
|
||||
|
||||
Rule: never compute full transitive-closure tables unless the graph is proven small and bounded; prefer per-query search + caching keyed by immutable inputs.
|
||||
|
||||
### 1.5 Deterministic Reachability Cache Key
|
||||
|
||||
Cache *query results*, not graph construction:
|
||||
|
||||
```
|
||||
reachabilityCacheKey = (
|
||||
graphRevisionId,
|
||||
algorithmId,
|
||||
fromSymbolId,
|
||||
toSymbolId,
|
||||
contextHash // entrypoints, flags/env, runtime profile selector
|
||||
)
|
||||
```
|
||||
|
||||
Cache requirements:
|
||||
- Include the canonical path in cache entries; tie-break with stable neighbor ordering.
|
||||
- Cache negative results explicitly (`reachable=false`) and represent uncertainty (`reachable=null`) without coercion.
|
||||
- Invalidate by construction: when `graphRevisionId` changes, cache keys naturally change.
|
||||
|
||||
### 1.6 Compositional Library Summaries (ReachCheck-style option)
|
||||
|
||||
For third-party libraries, evaluate a compositional approach:
|
||||
- Precompute *library reachability summaries* once per `(purl, version, digest)` offline.
|
||||
- Merge summaries with the application graph at query time.
|
||||
- Store each summary as content-addressed evidence with its own digest and tool version.
|
||||
|
||||
If using matrix-based transitive-closure summaries, treat them as an optimization layer only: surface any unsoundness/unknowns explicitly and keep all outputs deterministic (no sampling, no nondeterministic parallel traversal ordering).
|
||||
|
||||
## 2. DATA CONTRACTS
|
||||
|
||||
### 2.1 CallGraph.v1.json Schema
|
||||
@@ -79,14 +122,14 @@
|
||||
"scanKey": "uuid",
|
||||
"language": "dotnet|java|node|python|go|rust|binary",
|
||||
"artifacts": [{
|
||||
"artifactKey": "…",
|
||||
"artifactKey": "<artifactKey>",
|
||||
"kind": "assembly|jar|module|binary",
|
||||
"sha256": "…"
|
||||
"sha256": "<sha256>"
|
||||
}],
|
||||
"nodes": [{
|
||||
"nodeId": "…",
|
||||
"artifactKey": "…",
|
||||
"symbolKey": "Namespace.Type::Method(…)",
|
||||
"nodeId": "<nodeId>",
|
||||
"artifactKey": "<artifactKey>",
|
||||
"symbolKey": "Namespace.Type::Method(<signature>)",
|
||||
"visibility": "public|internal|private|unknown",
|
||||
"isEntrypointCandidate": false
|
||||
}],
|
||||
@@ -98,7 +141,7 @@
|
||||
"weight": 1.0
|
||||
}],
|
||||
"entrypoints": [{
|
||||
"nodeId": "…",
|
||||
"nodeId": "<nodeId>",
|
||||
"kind": "http|grpc|cli|job|event|unknown",
|
||||
"route": "/api/orders/{id}",
|
||||
"framework": "aspnetcore|minimalapi|spring|express|unknown"
|
||||
@@ -115,19 +158,19 @@
|
||||
"collectedAt": "2025-12-14T10:00:00Z",
|
||||
"environment": {
|
||||
"os": "linux|windows",
|
||||
"k8s": {"namespace": "…", "pod": "…", "container": "…"},
|
||||
"imageDigest": "sha256:…",
|
||||
"buildId": "…"
|
||||
"k8s": {"namespace": "<namespace>", "pod": "<pod>", "container": "<container>"},
|
||||
"imageDigest": "sha256:<digest>",
|
||||
"buildId": "<buildId>"
|
||||
},
|
||||
"samples": [{
|
||||
"timestamp": "…",
|
||||
"timestamp": "<utc-iso8601>",
|
||||
"pid": 1234,
|
||||
"threadId": 77,
|
||||
"frames": ["nodeId","nodeId","nodeId"],
|
||||
"sampleWeight": 1.0
|
||||
}],
|
||||
"loadedArtifacts": [{
|
||||
"artifactKey": "…",
|
||||
"artifactKey": "<artifactKey>",
|
||||
"evidence": "loaded_module|mapped_file|jar_loaded"
|
||||
}]
|
||||
}
|
||||
@@ -140,12 +183,12 @@
|
||||
"schema": "stella.replaymanifest.v1",
|
||||
"scanId": "uuid",
|
||||
"inputs": {
|
||||
"sbomDigest": "sha256:…",
|
||||
"callGraphs": [{"language":"dotnet","digest":"sha256:…"}],
|
||||
"runtimeEvidence": [{"digest":"sha256:…"}],
|
||||
"concelierSnapshot": "sha256:…",
|
||||
"excititorSnapshot": "sha256:…",
|
||||
"policyDigest": "sha256:…"
|
||||
"sbomDigest": "sha256:<digest>",
|
||||
"callGraphs": [{"language":"dotnet","digest":"sha256:<digest>"}],
|
||||
"runtimeEvidence": [{"digest":"sha256:<digest>"}],
|
||||
"concelierSnapshot": "sha256:<digest>",
|
||||
"excititorSnapshot": "sha256:<digest>",
|
||||
"policyDigest": "sha256:<digest>"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user