doing individual items not entire groups

This commit is contained in:
2026-05-26 19:49:10 -06:00
parent 2c4df3998a
commit 8fca79e968
2 changed files with 63 additions and 56 deletions
@@ -5,8 +5,8 @@
## Command
- `IdentifyVendoredPackages`
- Meaning: evaluate deterministic ingest artifacts to decide which bundled code should be treated as a `Vendored Package` and recorded as accepted, rejected, or unresolved for later `Externalization`.
- `IdentifyVendoredPackage`
- Meaning: evaluate one recovered vendored candidate boundary against deterministic evidence so this context can record a single `Dependency Decision` for later `Externalization`.
## Required State
@@ -32,45 +32,47 @@ State owned by `dependency-recovery` and required to decide this workflow:
Snapshots or handoffs read but not owned by this context:
- `Run Manifest` from `ingest-snapshot`
- `Segment Record` set and canonical source projection from `ingest-snapshot`
- optional runtime traces used only as additional or tie-break evidence
- optional registry, tarball, or CDN package evidence used to compare candidate matches
- one recovered `Vendored Package` candidate boundary derived from `ingest-snapshot` artifacts by outer orchestration
- the relevant `Run Manifest` facts and canonical source projection from `ingest-snapshot` for that candidate boundary
- optional runtime traces for that candidate boundary used only as additional or tie-break evidence
- optional registry, tarball, or CDN package evidence used to compare matches for that candidate boundary
## Policy Signature (Pseudo)
```text
identifyCandidateBoundaries :
RunManifest -> SegmentRecords -> CandidateDiscoveryRules -> NonEmptyList<VendoredCandidate>
scoreVendoredCandidate :
VendoredCandidate -> EvidenceSources -> ConfidenceScoringRules -> RankedCandidateMatches
VendoredCandidateBoundary
-> CandidateEvidenceSources
-> ConfidenceScoringRules
-> RankedCandidateMatches
decideDependencyDecision :
RankedCandidateMatches
VendoredCandidateBoundary
-> RankedCandidateMatches
-> AcceptanceThresholdPolicy
-> DependencyDecision
validateDecisionManifest :
DependencyDecisionSet -> DependencyDecisionRequirements -> Result<DependencyDecisionsRecorded, DependencyDecisionRejected>
validateDecisionRecord :
DependencyDecision
-> DependencyDecisionRequirements
-> Result<DependencyDecisionRecorded, DependencyDecisionRejected>
performVendoredPackageIdentification :
IdentifyVendoredPackages
IdentifyVendoredPackage
-> DependencyRecoveryState
-> Result<VendoredPackagesIdentified, VendoredPackageIdentificationHardStopped>
-> Result<VendoredPackageIdentified, VendoredPackageIdentificationHardStopped>
```
## Events
### Success Event
- `VendoredPackagesIdentified`
- `VendoredPackageIdentified`
- run identity reference
- accepted dependency decisions
- rejected dependency decisions
- unresolved dependency decisions
- emitted decision manifest reference
- evidence artifact references
- evaluated candidate boundary reference
- emitted single dependency decision
- emitted decision record reference
- evidence artifact references for that candidate
### Failure Event
@@ -81,9 +83,9 @@ performVendoredPackageIdentification :
## Boundary Notes
- The `dependency-recovery` context decides package candidacy, confidence ranking, and dependency decision state only for this slice.
- The `dependency-recovery` context decides one candidate boundary's package candidacy, confidence ranking, and dependency decision state per workflow invocation.
- Outer orchestration is responsible for discovering, selecting, and iterating across multiple candidate boundaries; this slice must not batch those decisions itself.
- This slice does not externalize accepted packages; that belongs to `dependency-recovery/externalize-accepted-dependencies`.
- `ingest-snapshot` remains the source of truth for run manifest, segment boundaries, and canonical projection; this slice must not reopen ingest decisions.
- Optional runtime traces and package-source comparisons act only as evidence inputs here and must not turn this slice into cross-context orchestration.
- Feature-level orchestration decides whether unresolved or review-needed outcomes slow later phases; this slice only records accepted, rejected, and unresolved decisions with audit-ready evidence.
- Threshold tuning and scoring-weight configuration stay inside this context's policy setup, but later feature phases consume only the emitted decisions and artifacts.
- Feature-level orchestration decides whether unresolved or review-needed outcomes slow later phases; this slice only records one audit-ready dependency decision at a time.
@@ -90,20 +90,24 @@ type AuditabilityRule =
// 2. Commands (Inputs)
type IdentifyVendoredPackages = {
type TaintedCandidateBoundaryReference = TaintedCandidateBoundaryReference of string
type TrustedCandidateBoundaryReference = TrustedCandidateBoundaryReference of string
type IdentifyVendoredPackage = {
runManifest: TaintedRunManifestReference
segmentRecords: TaintedSegmentRecordReference
canonicalProjection: TaintedCanonicalProjectionReference
candidateBoundary: TaintedCandidateBoundaryReference
runtimeTraces: TaintedRuntimeTraceReference option
}
// 3. Observed inputs and owned state
type TrustedIngestArtifacts = {
type TrustedCandidateInput = {
runIdentity: RunIdentity
runManifest: TrustedRunManifestReference
segmentRecords: TrustedSegmentRecordReference
canonicalProjection: TrustedCanonicalProjectionReference
candidateBoundary: TrustedCandidateBoundaryReference
runtimeTraces: TrustedRuntimeTraceReference option
}
@@ -139,24 +143,31 @@ type DependencyRecoveryState = {
// 4. Events (Facts)
type VendoredPackagesIdentified = {
type DecisionRecordReference = DecisionRecordReference of string
type VendoredPackageIdentified = {
runIdentity: RunIdentity
acceptedDecisions: DependencyDecision list
rejectedDecisions: DependencyDecision list
unresolvedDecisions: DependencyDecision list
decisionManifest: EvidenceReference
candidateBoundary: TrustedCandidateBoundaryReference
dependencyDecision: DependencyDecision
decisionRecord: DecisionRecordReference
evidenceArtifacts: EvidenceReference list
}
type VendoredPackageIdentificationStage =
| CandidateInputParsingStage
| CandidateScoringStage
| DependencyDecisionStage
| DecisionRecordValidationStage
type VendoredPackageIdentificationFailureReason =
| MissingIngestArtifacts
| InvalidIngestArtifactReference
| NoCandidateBoundariesRecovered
| InvalidDecisionManifestRequirements
| InvalidCandidateBoundaryReference
| InvalidDecisionRecordRequirements
type VendoredPackageIdentificationHardStopped = {
runIdentity: RunIdentity option
failedStage: string
failedStage: VendoredPackageIdentificationStage
reason: VendoredPackageIdentificationFailureReason
}
@@ -164,46 +175,40 @@ type VendoredPackageIdentificationHardStopped = {
type DependencyIdentificationState =
| AwaitingVendoredPackageIdentification of DependencyRecoveryState
| VendoredPackageDecisionsRecorded of VendoredPackagesIdentified
| VendoredPackageDecisionRecorded of VendoredPackageIdentified
// 6. Parse and decision contracts
val parseIngestArtifacts :
IdentifyVendoredPackages
-> Result<TrustedIngestArtifacts, VendoredPackageIdentificationHardStopped>
val identifyCandidateBoundaries :
TrustedIngestArtifacts
-> VendoredCandidateDiscoveryRules
-> Result<CandidateBoundary list, VendoredPackageIdentificationHardStopped>
val parseCandidateInput :
IdentifyVendoredPackage
-> Result<TrustedCandidateInput, VendoredPackageIdentificationHardStopped>
val scoreCandidateMatches :
CandidateBoundary
-> TrustedIngestArtifacts
TrustedCandidateInput
-> ConfidenceScoringRules
-> Result<CandidateMatch list, VendoredPackageIdentificationHardStopped>
val decideDependencyDecision :
AcceptanceThresholdPolicy
-> CandidateBoundary
-> TrustedCandidateBoundaryReference
-> CandidateMatch list
-> Result<DependencyDecision, VendoredPackageIdentificationHardStopped>
val validateDecisionManifest :
val validateDecisionRecord :
DependencyDecisionRequirements
-> DependencyDecision list
-> Result<EvidenceReference, VendoredPackageIdentificationHardStopped>
-> DependencyDecision
-> Result<DecisionRecordReference, VendoredPackageIdentificationHardStopped>
val decide :
DependencyIdentificationState
-> IdentifyVendoredPackages
-> Result<VendoredPackagesIdentified, VendoredPackageIdentificationHardStopped>
-> IdentifyVendoredPackage
-> Result<VendoredPackageIdentified, VendoredPackageIdentificationHardStopped>
val apply :
DependencyIdentificationState
-> VendoredPackagesIdentified
-> VendoredPackageIdentified
-> DependencyIdentificationState
val workflow :
IdentifyVendoredPackages
-> Effect.Effect<Result<VendoredPackagesIdentified, VendoredPackageIdentificationHardStopped>>
IdentifyVendoredPackage
-> Effect.Effect<Result<VendoredPackageIdentified, VendoredPackageIdentificationHardStopped>>