Skip to content

Latest commit

 

History

History
51 lines (37 loc) · 2.57 KB

File metadata and controls

51 lines (37 loc) · 2.57 KB

PURL Identity Model (OriginalPURL / EffectivePURL / CanonicalKey)

← Back to README.md

A 3-layer structure to balance stable internal matching with complete preservation of user input.

3-Layer Overview

Field Persistence Scope Mutation Purpose Example
OriginalPURL Returned externally Write-once Exact user input (preserving case / collapsed forms). For audit logs & reproducibility pkg:npm/React
EffectivePURL Returned externally Updated during resolution Resolved/normalized form used for API calls (may add version, expand coordinates) pkg:npm/react@18.3.1
CanonicalKey Internal only Lazily generated Stable key with version stripped + lowercased (dedup / EOL matching). Not exposed to users pkg:npm/react

Helper Methods

  • DisplayPURL() — Prefers OriginalPURL, falls back to EffectivePURL
  • IsVersionResolved() — True if EffectivePURL contains @version
  • EnsureCanonical() — Generates CanonicalKey if empty (uses Original preferentially)

Rationale for Separation

  1. Case preservation: Prevents corruption in case-sensitive ecosystems (Maven paths / Go import paths)
  2. User input preservation: Maintains original input for audit and reproducible reruns
  3. Non-destructive rewrites: Version resolution and path expansion do not modify the original request
  4. Centralized matching: Consolidates internal maps / EOL matching to a single deterministic transform (CanonicalKey)

Common Divergence Scenarios

Scenario OriginalPURL EffectivePURL
npm Mixed Case pkg:npm/React pkg:npm/react@18.3.1
Maven collapsed coordinates pkg:maven:org.slf4j:slf4j-api@2.0.16 pkg:maven/org.slf4j/slf4j-api@2.0.16
GitHub URL base + version resolution pkg:golang/github.com/gin-gonic/gin pkg:golang/github.com/gin-gonic/gin@v1.10.0
Resolution failure (no version) pkg:pypi/Django pkg:pypi/Django

Operating Rules

  1. Record raw input as OriginalPURL exactly once at ingestion
  2. Reflect transformation results in EffectivePURL only
  3. Call EnsureCanonical() immediately before storing in internal maps / merge logic
  4. Arbitrary lowercasing is performed only via CanonicalKey utilities

Quick Reference

OriginalPURL  = Exact input as-is
EffectivePURL = Final resolved/fetched form
CanonicalKey  = Internal versionless lowercase key (generated by EnsureCanonical())
DisplayPURL() = Display form (Original preferred)