design security scan and fixes, basically all trusted vs tainted input

This commit is contained in:
2026-05-25 01:28:43 -06:00
parent 44d9d2065c
commit d15e09504a
5 changed files with 56 additions and 22 deletions
@@ -17,8 +17,10 @@
## Edge Cases
- Bundle does not parse -> hard stop the slice because no trustworthy ingest artifacts can be emitted.
- Bundle exceeds configured size or parse budget -> hard stop the slice before deeper ingest work to reduce resource-exhaustion risk.
- An apparent boundary cannot be proven deterministically -> do not emit it as a separate segment record; keep only proven AST slice boundaries.
- Identical upstream snapshot is ingested again -> derive the same run identity inputs and emit the same deterministic machine artifacts.
- Previous run manifest is available but not verified -> do not use it for continuity hints.
- Previous run manifest is available but continuity is weak -> ingest may observe it for continuity hints, but the current run artifacts still come only from the current snapshot and deterministic ingest rules.
- Human-readable summary generation fails -> slice still succeeds if machine-readable artifacts were emitted correctly.
@@ -28,6 +30,8 @@
- Rule: A `Segment Record` may come from any deterministic AST slice boundary that can be proven stably.
- Rule: Ingest emits machine-readable artifacts as the source of truth for later phases.
- Rule: Human-readable summary output is optional relative to core ingest success.
- Rule: Bundle location input must be parsed into a trusted bundle location before ingest uses it.
- Rule: A previous run manifest must be verified before it may influence continuity hints.
- Invariant: If the bundle cannot be parsed, ingest hard-stops rather than emitting speculative artifacts.
- Invariant: The workflow does not guess segment boundaries that it cannot prove deterministically.
- Invariant: Identical upstream snapshot inputs produce identical deterministic ingest outputs.
@@ -14,7 +14,7 @@ State owned by `ingest-snapshot` and required to decide this workflow:
- `SelectedSnapshot`
- upstream snapshot identity
- upstream bundle location or source reference
- trusted bundle location derived from tainted ingest input
- optional upstream metadata intended for later release provenance
- `RunIdentityRules`
- deterministic derivation rules from upstream snapshot identity
@@ -30,7 +30,7 @@ State owned by `ingest-snapshot` and required to decide this workflow:
Snapshots or handoffs read but not owned by this context:
- optional previous `Run Manifest` reference used only for continuity hints
- optional verified previous `Run Manifest` reference used only for continuity hints
- upstream metadata needed later by `release-packaging`
## Policy Signature (Pseudo)
@@ -38,6 +38,12 @@ Snapshots or handoffs read but not owned by this context:
```text
deriveRunIdentity : SelectedSnapshot -> RunIdentity
parseBundleLocation :
TaintedBundleInput -> Result<TrustedBundleLocation, IngestRejected>
validatePreviousRunManifest :
RunManifest -> Result<VerifiedPreviousRunManifest, IngestRejected>
validateSnapshotIngest :
IngestUpstreamSnapshot -> SelectedSnapshot -> Result<SnapshotReady, IngestRejected>
@@ -77,5 +83,6 @@ performSnapshotIngest :
- The `ingest-snapshot` context decides only whether one snapshot can be deterministically ingested and which boundaries become `Segment Records`.
- It does not decide package identity, dependency externalization, context heuristics, lineage matching, naming, regularization, transform replay, or release publication.
- Observing a previous `Run Manifest` does not let this slice reuse or override current ingest decisions; cross-run lineage belongs to `snapshot-lineage`.
- A previous `Run Manifest` must be verified for schema and integrity before this slice may use it as a continuity hint.
- Human-readable summary generation is outside the hard success contract for this slice; required machine artifacts remain the source of truth.
- Feature-level orchestration decides when later phases may continue after downstream review-needed states; this slice only hard-stops when deterministic ingest itself is not trustworthy.
@@ -4,10 +4,14 @@ open IngestSnapshot.SharedModel
// 1. Primitives
type TaintedBundleInput = TaintedBundleInput of BundleSource
type TaintedBundleInput = TaintedBundleInput of TaintedBundleLocation
type DerivedRunIdentity = DerivedRunIdentity of RunIdentity
type MaxBundleBytes = MaxBundleBytes of int64
type ParseBudget = ParseBudget of int64
type BoundaryProof = BoundaryProof of string
type RequiredArtifact =
@@ -18,6 +22,9 @@ type RequiredArtifact =
type IngestFailureReason =
| BundleNotParseable
| RunIdentityCouldNotBeDerived
| PreviousRunManifestNotVerified
| BundleTooLarge of MaxBundleBytes
| ParseBudgetExceeded of ParseBudget
| NoDeterministicBoundaryProven
| RequiredArtifactMissing of RequiredArtifact
@@ -27,15 +34,15 @@ type IngestUpstreamSnapshot =
{ SnapshotIdentity: SnapshotIdentity
BundleInput: TaintedBundleInput
SnapshotMetadata: SnapshotMetadata option
PreviousRunManifest: RunManifest option }
PreviousRunManifest: VerifiedPreviousRunManifest option }
// 3. Events (Facts)
type UpstreamSnapshotIngested =
{ RunManifest: RunManifest
SegmentRecords: SegmentRecord list
CanonicalProjectionPath: CanonicalProjectionPath
SummaryPath: SummaryPath option }
CanonicalProjectionPath: TrustedCanonicalProjectionPath
SummaryPath: TrustedSummaryPath option }
type SnapshotIngestHardStopped =
{ SnapshotIdentity: SnapshotIdentity
@@ -54,17 +61,21 @@ type Error =
type AwaitingSnapshotSelection =
{ RunIdentityRulesDescription: string
BoundaryRulesDescription: string
RequiredArtifacts: RequiredArtifact list }
RequiredArtifacts: RequiredArtifact list
MaxBundleBytes: MaxBundleBytes
ParseBudget: ParseBudget }
type SnapshotReady =
{ SelectedSnapshot: SelectedSnapshot
PreviousRunManifest: RunManifest option
RequiredArtifacts: RequiredArtifact list }
PreviousRunManifest: VerifiedPreviousRunManifest option
RequiredArtifacts: RequiredArtifact list
MaxBundleBytes: MaxBundleBytes
ParseBudget: ParseBudget }
type DeterministicSegmentsReady =
{ RunIdentity: RunIdentity
SelectedSnapshot: SelectedSnapshot
PreviousRunManifest: RunManifest option
PreviousRunManifest: VerifiedPreviousRunManifest option
SegmentRecords: SegmentRecord list
BoundaryProofs: BoundaryProof list
RequiredArtifacts: RequiredArtifact list }
@@ -77,8 +88,12 @@ type State =
// 6. Contract Signatures
val parseBundleLocation : TaintedBundleInput -> Result<TrustedBundleLocation, Error>
val deriveRunIdentity : SelectedSnapshot -> Result<DerivedRunIdentity, Error>
val validatePreviousRunManifest : RunManifest -> Result<VerifiedPreviousRunManifest, Error>
val validateSnapshotSelection : State -> IngestUpstreamSnapshot -> Result<SnapshotReady, Error>
val decideSegmentRecords : SnapshotReady -> Result<DeterministicSegmentsReady, Error>
@@ -4,7 +4,9 @@ module IngestSnapshot.SharedModel
type SnapshotIdentity = SnapshotIdentity of string
type BundleSource = BundleSource of string
type TaintedBundleLocation = TaintedBundleLocation of string
type TrustedBundleLocation = TrustedBundleLocation of string
type RunIdentity = RunIdentity of string
@@ -20,13 +22,13 @@ type NormalizedHash = NormalizedHash of string
type ShapeHash = ShapeHash of string
type ManifestPath = ManifestPath of string
type TrustedManifestPath = TrustedManifestPath of string
type SegmentsPath = SegmentsPath of string
type TrustedSegmentsPath = TrustedSegmentsPath of string
type CanonicalProjectionPath = CanonicalProjectionPath of string
type TrustedCanonicalProjectionPath = TrustedCanonicalProjectionPath of string
type SummaryPath = SummaryPath of string
type TrustedSummaryPath = TrustedSummaryPath of string
// 2. Shared compounds
@@ -36,9 +38,11 @@ type SnapshotMetadata =
type SelectedSnapshot =
{ SnapshotIdentity: SnapshotIdentity
BundleSource: BundleSource
BundleLocation: TrustedBundleLocation
SnapshotMetadata: SnapshotMetadata option }
type VerifiedPreviousRunManifest = VerifiedPreviousRunManifest of RunManifest
type SegmentHashes =
{ RawHash: RawHash
NormalizedHash: NormalizedHash
@@ -54,7 +58,7 @@ type SegmentRecord =
type RunManifest =
{ RunIdentity: RunIdentity
SnapshotIdentity: SnapshotIdentity
ManifestPath: ManifestPath
SegmentsPath: SegmentsPath
CanonicalProjectionPath: CanonicalProjectionPath
SummaryPath: SummaryPath option }
ManifestPath: TrustedManifestPath
SegmentsPath: TrustedSegmentsPath
CanonicalProjectionPath: TrustedCanonicalProjectionPath
SummaryPath: TrustedSummaryPath option }