edits from review skill, merged policies, moved brand constructors

This commit is contained in:
2026-05-25 20:15:26 -06:00
parent 57a691236e
commit 281c2a8a94
7 changed files with 124 additions and 171 deletions
+7 -5
View File
@@ -19,21 +19,23 @@ export type {
TrustedBundleLocation,
RunIdentity,
} from "./models/shared.js"
export {
makeSnapshotIdentity,
makeTaintedBundleInput,
makeTaintedBundleLocation,
makeVerifiedPreviousRunManifest,
} from "./models/factories.js"
export {
makeAstNodeKind,
makeNormalizedHash,
makeRawHash,
makeRunIdentity,
makeShapeHash,
makeSnapshotIdentity,
makeTaintedBundleInput,
makeTaintedBundleLocation,
makeTrustedCanonicalProjectionPath,
makeTrustedManifestPath,
makeTrustedSegmentsPath,
makeTrustedSummaryPath,
makeVerifiedPreviousRunManifest,
} from "./models/factories.js"
} from "./models/ops.js"
export { workflow } from "./workflows/ingestSnapshot.js"
export {
apply,
@@ -1,47 +1,19 @@
import type {
DerivedRunIdentity,
Error,
IngestFailureReason,
TaintedBundleInput,
VerifiedPreviousRunManifest,
} from "./types.js"
import type {
AstNodeKind,
NormalizedHash,
RawHash,
RunIdentity,
RunManifest,
ShapeHash,
SnapshotIdentity,
TaintedBundleLocation,
TrustedBundleLocation,
TrustedCanonicalProjectionPath,
TrustedManifestPath,
TrustedSegmentsPath,
TrustedSummaryPath,
} from "./shared.js"
const asBrand = <T>(value: string): T => value as T
export const makeSnapshotIdentity = (value: string): SnapshotIdentity => asBrand(value)
export const makeSnapshotIdentity = (value: string): SnapshotIdentity =>
value as SnapshotIdentity
export const makeTaintedBundleLocation = (value: string): TaintedBundleLocation =>
asBrand(value)
export const makeTrustedBundleLocation = (value: string): TrustedBundleLocation =>
asBrand(value)
export const makeRunIdentity = (value: string): RunIdentity => asBrand(value)
export const makeAstNodeKind = (value: string): AstNodeKind => asBrand(value)
export const makeRawHash = (value: string): RawHash => asBrand(value)
export const makeNormalizedHash = (value: string): NormalizedHash => asBrand(value)
export const makeShapeHash = (value: string): ShapeHash => asBrand(value)
export const makeTrustedManifestPath = (value: string): TrustedManifestPath =>
asBrand(value)
export const makeTrustedSegmentsPath = (value: string): TrustedSegmentsPath =>
asBrand(value)
export const makeTrustedCanonicalProjectionPath = (
value: string,
): TrustedCanonicalProjectionPath => asBrand(value)
export const makeTrustedSummaryPath = (value: string): TrustedSummaryPath =>
asBrand(value)
value as TaintedBundleLocation
export const makeVerifiedPreviousRunManifest = (
manifest: RunManifest,
@@ -51,10 +23,6 @@ export const makeTaintedBundleInput = (
location: TaintedBundleLocation,
): TaintedBundleInput => ({ _tag: "TaintedBundleInput", location })
export const makeDerivedRunIdentity = (
value: RunIdentity,
): DerivedRunIdentity => ({ _tag: "DerivedRunIdentity", value })
export const foldFailure = (
snapshotIdentity: SnapshotIdentity,
reason: IngestFailureReason,
+60 -17
View File
@@ -2,36 +2,48 @@ import { Either } from "effect"
import {
isNonEmptyString,
type AstNodeKind,
type NormalizedHash,
type RawHash,
type RunIdentity,
type SegmentRecord,
type SelectedSnapshot,
type ShapeHash,
type SnapshotIdentity,
type TrustedBundleLocation,
type TrustedCanonicalProjectionPath,
type TrustedManifestPath,
type TrustedSegmentsPath,
type TrustedSummaryPath,
} from "./shared.js"
import {
foldFailure,
makeAstNodeKind,
makeDerivedRunIdentity,
makeNormalizedHash,
makeRawHash,
makeRunIdentity,
makeShapeHash,
makeTrustedBundleLocation,
makeTrustedCanonicalProjectionPath,
makeTrustedManifestPath,
makeTrustedSegmentsPath,
makeTrustedSummaryPath,
} from "./factories.js"
import { foldFailure } from "./factories.js"
import type {
DerivedRunIdentity,
Error,
IngestableSnapshot,
RequiredArtifact,
TaintedBundleInput,
TrustedSnapshotSelected,
} from "./types.js"
export const makeTrustedBundleLocation = (value: string): TrustedBundleLocation =>
value as TrustedBundleLocation
export const makeRunIdentity = (value: string): RunIdentity => value as RunIdentity
export const makeAstNodeKind = (value: string): AstNodeKind => value as AstNodeKind
export const makeRawHash = (value: string): RawHash => value as RawHash
export const makeNormalizedHash = (value: string): NormalizedHash =>
value as NormalizedHash
export const makeShapeHash = (value: string): ShapeHash => value as ShapeHash
export const makeTrustedManifestPath = (value: string): TrustedManifestPath =>
value as TrustedManifestPath
export const makeTrustedSegmentsPath = (value: string): TrustedSegmentsPath =>
value as TrustedSegmentsPath
export const makeTrustedCanonicalProjectionPath = (
value: string,
): TrustedCanonicalProjectionPath => value as TrustedCanonicalProjectionPath
export const makeTrustedSummaryPath = (value: string): TrustedSummaryPath =>
value as TrustedSummaryPath
const parseBundleLocationText = (location: string): string | null => {
const trimmedLocation = location.trim()
return trimmedLocation.length === 0 || !trimmedLocation.includes("/")
@@ -63,19 +75,19 @@ const decideSegmentRecordFailure = (
export const parseBundleLocation = (
snapshotIdentity: SnapshotIdentity,
input: TaintedBundleInput,
): Either.Either<ReturnType<typeof makeTrustedBundleLocation>, Error> => {
): Either.Either<TrustedBundleLocation, Error> => {
const location = parseBundleLocationText(input.location as string)
return location === null
? Either.left(foldFailure(snapshotIdentity, "BundleNotParseable"))
: Either.right(makeTrustedBundleLocation(location))
}
export const applyRunIdentityRules = (
const deriveRunIdentity = (
selectedSnapshot: SelectedSnapshot,
): Either.Either<DerivedRunIdentity, Error> => {
const snapshotIdentity = selectedSnapshot.SnapshotIdentity as string
return isNonEmptyString(snapshotIdentity)
? Either.right(makeDerivedRunIdentity(makeRunIdentity(`run:${snapshotIdentity}`)))
? Either.right({ _tag: "DerivedRunIdentity", value: makeRunIdentity(`run:${snapshotIdentity}`) })
: Either.left(
foldFailure(
selectedSnapshot.SnapshotIdentity,
@@ -136,6 +148,37 @@ export const validateRequiredArtifacts = (
)
}
export const decideIngestableSnapshot = (
trustedSnapshot: TrustedSnapshotSelected,
): Either.Either<IngestableSnapshot, Error> =>
Either.flatMap(deriveRunIdentity(trustedSnapshot.SelectedSnapshot), (derivedRunIdentity) =>
Either.flatMap(validateSegmentRecords(trustedSnapshot.SelectedSnapshot), (segmentRecords) =>
Either.flatMap(
validateBoundaryProofs(
trustedSnapshot.SelectedSnapshot.SnapshotIdentity,
segmentRecords,
),
(boundaryProofs) =>
Either.map(
validateRequiredArtifacts(
trustedSnapshot.SelectedSnapshot.SnapshotIdentity,
trustedSnapshot.RequiredArtifacts,
segmentRecords,
),
() => ({
_tag: "IngestableSnapshot" as const,
RunIdentity: derivedRunIdentity.value,
SelectedSnapshot: trustedSnapshot.SelectedSnapshot,
PreviousRunManifest: trustedSnapshot.PreviousRunManifest,
SegmentRecords: segmentRecords,
BoundaryProofs: boundaryProofs,
RequiredArtifacts: trustedSnapshot.RequiredArtifacts,
}),
),
),
),
)
export const deriveRequiredArtifactPaths = (
runIdentity: RunIdentity,
): {
@@ -1,20 +1,58 @@
import { Either } from "effect"
import { deriveRequiredArtifactPaths } from "../models/ops.js"
import { foldFailure, makeVerifiedPreviousRunManifest } from "../models/factories.js"
import {
decideIngestableSnapshot,
deriveRequiredArtifactPaths,
parseBundleLocation,
} from "../models/ops.js"
import type {
AwaitingTrustedBundle,
Error,
Event,
IngestableSnapshot,
IngestUpstreamSnapshot,
State,
TrustedSnapshotSelected,
UpstreamSnapshotIngested,
} from "../models/types.js"
import type { RunManifest } from "../models/shared.js"
import { decideIngestableSnapshot } from "./segments.js"
import {
selectTrustedSnapshot,
validatePreviousRunManifest,
} from "./selection.js"
export const validatePreviousRunManifest = (
manifest: RunManifest,
): Either.Either<ReturnType<typeof makeVerifiedPreviousRunManifest>, Error> =>
manifest.ManifestPath && manifest.SegmentsPath && manifest.CanonicalProjectionPath
? Either.right(makeVerifiedPreviousRunManifest(manifest))
: Either.left(
foldFailure(manifest.SnapshotIdentity, "PreviousRunManifestNotVerified"),
)
const selectTrustedSnapshot = (
state: State,
command: IngestUpstreamSnapshot,
): Either.Either<TrustedSnapshotSelected, Error> => {
if (state._tag !== "AwaitingTrustedBundle") {
return Either.left(
foldFailure(command.SnapshotIdentity, "RunIdentityCouldNotBeDerived"),
)
}
return Either.map(
parseBundleLocation(command.SnapshotIdentity, command.BundleInput),
(bundleLocation) => ({
_tag: "TrustedSnapshotSelected" as const,
SelectedSnapshot: {
SnapshotIdentity: command.SnapshotIdentity,
BundleLocation: bundleLocation,
SnapshotMetadata: command.SnapshotMetadata,
},
PreviousRunManifest: command.PreviousRunManifest,
RequiredArtifacts: state.RequiredArtifacts,
MaxBundleBytes: state.MaxBundleBytes,
ParseBudget: state.ParseBudget,
}),
)
}
export const emitSnapshotIngested = (
ingestableSnapshot: IngestableSnapshot,
@@ -71,8 +109,4 @@ export const makeAwaitingTrustedBundle = (
...overrides,
})
export {
decideIngestableSnapshot,
selectTrustedSnapshot,
validatePreviousRunManifest,
}
export { decideIngestableSnapshot }
@@ -1,44 +0,0 @@
import { Either } from "effect"
import {
applyRunIdentityRules,
validateBoundaryProofs,
validateRequiredArtifacts,
validateSegmentRecords,
} from "../models/ops.js"
import type {
Error,
IngestableSnapshot,
TrustedSnapshotSelected,
} from "../models/types.js"
export const decideIngestableSnapshot = (
trustedSnapshot: TrustedSnapshotSelected,
): Either.Either<IngestableSnapshot, Error> =>
Either.flatMap(applyRunIdentityRules(trustedSnapshot.SelectedSnapshot), (derivedRunIdentity) =>
Either.flatMap(validateSegmentRecords(trustedSnapshot.SelectedSnapshot), (segmentRecords) =>
Either.flatMap(
validateBoundaryProofs(
trustedSnapshot.SelectedSnapshot.SnapshotIdentity,
segmentRecords,
),
(boundaryProofs) =>
Either.map(
validateRequiredArtifacts(
trustedSnapshot.SelectedSnapshot.SnapshotIdentity,
trustedSnapshot.RequiredArtifacts,
segmentRecords,
),
() => ({
_tag: "IngestableSnapshot" as const,
RunIdentity: derivedRunIdentity.value,
SelectedSnapshot: trustedSnapshot.SelectedSnapshot,
PreviousRunManifest: trustedSnapshot.PreviousRunManifest,
SegmentRecords: segmentRecords,
BoundaryProofs: boundaryProofs,
RequiredArtifacts: trustedSnapshot.RequiredArtifacts,
}),
),
),
),
)
@@ -1,47 +0,0 @@
import { Either } from "effect"
import { foldFailure, makeVerifiedPreviousRunManifest } from "../models/factories.js"
import { parseBundleLocation } from "../models/ops.js"
import type {
Error,
IngestUpstreamSnapshot,
State,
TrustedSnapshotSelected,
} from "../models/types.js"
import type { RunManifest } from "../models/shared.js"
export const validatePreviousRunManifest = (
manifest: RunManifest,
): Either.Either<ReturnType<typeof makeVerifiedPreviousRunManifest>, Error> =>
manifest.ManifestPath && manifest.SegmentsPath && manifest.CanonicalProjectionPath
? Either.right(makeVerifiedPreviousRunManifest(manifest))
: Either.left(
foldFailure(manifest.SnapshotIdentity, "PreviousRunManifestNotVerified"),
)
export const selectTrustedSnapshot = (
state: State,
command: IngestUpstreamSnapshot,
): Either.Either<TrustedSnapshotSelected, Error> => {
if (state._tag !== "AwaitingTrustedBundle") {
return Either.left(
foldFailure(command.SnapshotIdentity, "RunIdentityCouldNotBeDerived"),
)
}
return Either.map(
parseBundleLocation(command.SnapshotIdentity, command.BundleInput),
(bundleLocation) => ({
_tag: "TrustedSnapshotSelected" as const,
SelectedSnapshot: {
SnapshotIdentity: command.SnapshotIdentity,
BundleLocation: bundleLocation,
SnapshotMetadata: command.SnapshotMetadata,
},
PreviousRunManifest: command.PreviousRunManifest,
RequiredArtifacts: state.RequiredArtifacts,
MaxBundleBytes: state.MaxBundleBytes,
ParseBudget: state.ParseBudget,
}),
)
}
+9 -12
View File
@@ -3,11 +3,7 @@ import { describe, expect, it } from "vitest"
import {
type IngestUpstreamSnapshot,
makeAstNodeKind,
makeNormalizedHash,
makeRawHash,
makeRunIdentity,
makeShapeHash,
makeSnapshotIdentity,
makeTaintedBundleInput,
makeTaintedBundleLocation,
@@ -42,9 +38,9 @@ describe("ingestSnapshot workflow", () => {
const event = await Effect.runPromise(workflow(makeCommand()))
expect(event._tag).toBe("UpstreamSnapshotIngested")
expect(event.payload.RunManifest.RunIdentity).toBe(makeRunIdentity("run:snapshot-001"))
expect(event.payload.RunManifest.RunIdentity).toBe("run:snapshot-001")
expect(event.payload.RunManifest.ManifestPath).toBe(
makeTrustedManifestPath("runs/run:snapshot-001/manifest.json"),
"runs/run:snapshot-001/manifest.json",
)
expect(event.payload.SegmentRecords).toHaveLength(1)
})
@@ -71,10 +67,10 @@ describe("ingestSnapshot workflow", () => {
expect(nextState._tag).toBe("SnapshotIngested")
if (nextState._tag === "SnapshotIngested") {
expect(nextState.RunManifest.CanonicalProjectionPath).toBe(
makeTrustedCanonicalProjectionPath("runs/run:snapshot-001/canonical.ts"),
"runs/run:snapshot-001/canonical.ts",
)
expect(nextState.SummaryPath).toBe(
makeTrustedSummaryPath("runs/run:snapshot-001/summary.json"),
"runs/run:snapshot-001/summary.json",
)
}
}
@@ -115,12 +111,13 @@ describe("ingestSnapshot workflow", () => {
expect(event.payload.SegmentRecords[0]).toMatchObject({
SegmentId: "snapshot-001:root",
AstNodeKind: makeAstNodeKind("Program"),
AstNodeKind: "Program",
Hashes: {
RawHash: makeRawHash("raw:snapshot-001"),
NormalizedHash: makeNormalizedHash("normalized:snapshot-001"),
ShapeHash: makeShapeHash("shape:snapshot-001"),
RawHash: "raw:snapshot-001",
NormalizedHash: "normalized:snapshot-001",
ShapeHash: "shape:snapshot-001",
},
})
expect(event.payload.SegmentRecords[0]?.Hashes.RawHash).toBe("raw:snapshot-001")
})
})