Skip to content

feat: Phase 0 — canonical Origin model (collapse six provenance representations)#212

Merged
aroff merged 7 commits into
mainfrom
feat/origin-model-phase0
Jul 21, 2026
Merged

feat: Phase 0 — canonical Origin model (collapse six provenance representations)#212
aroff merged 7 commits into
mainfrom
feat/origin-model-phase0

Conversation

@aroff

@aroff aroff commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Implements Phase 0 of spec 003 (browser skill management) — the canonical Origin model — per PRD #207.

What this does

Collapses the six overlapping provenance representations (SkillSource ×2, SourceType, SourceSpecificFields, the flat source_* fields on the lock entries, and the nine on SkillDefinition) into one canonical Origin (install intent) plus a lock-only Resolved (the facts a fetch produced). See ADR-0005 and the Origin glossary entry in CONTEXT.md.

  • Origin = Git{url, ref: GitRef, subdir?} | Local{path, editable} | ZipUrl{url} | Repository{repo, skill, version: Option<VersionConstraint>}. Internally-tagged; the common "install latest" case serializes minimally ({"type":"git","url":…}). GitRef is a sum type (Default|Branch|Tag|Commit) so illegal ref combos are unrepresentable.
  • Intent vs. resolved: Origin holds no commit SHA / resolved version / checksum — those live in the lock's Resolved. SkillEntry{id, origin, groups}; lock entries → {…, origin, resolved}.
  • VersionConstraint gains Display + serde that round-trips through parse, so ADR-0004 (bare version = exact pin) is enforced at the serde boundary (a stored constraint is =1.2.3).
  • Old-data guards (greenfield, no shim/migrator): the lock metadata.version is bumped to "3.0" and a pre-parse guard rejects older locks with an actionable LockError::UnsupportedVersion; loading a pre-Origin manifest appends a migration hint pointing at origin = { type = … }.

Breaking

On-disk manifest and lock serde formats change (greenfield break, no back-compat shim — per ADR-0005). CLI command behavior is otherwise unchanged.

aroff and others added 7 commits July 21, 2026 21:02
Newer nightly (1.99.0) clippy flags the nested `if` inside the "version"
match arm. Behavior-identical: fold the emptiness check into a match guard.
Needed because the nightly bump (for libsqlite3-sys 0.38.1) tightened lints.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`install` already means manifest-reconcile-with-dependencies here (CONTEXT.md:
"install = Manifest -> skills dir"). The per-Origin single-skill op is `add`
semantics -> `add_from_origin(origin, mode)`; note the update preflight gate.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Post-grill refinements: Origin is install intent (resolved facts live in the
Lock); `local` covers dir or .zip; repository variant always concrete. Lists
all collapsed representations.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…act)

Origin = install intent (git|local|zip-url|repository); GitRef sum type;
Resolved = lock-only resolved facts (version/commit/checksum). Internally-tagged
serde with minimal "latest" forms. VersionConstraint gains Display + serde
(round-trips through parse, enforcing ADR-0004 at the boundary). 7 serde tests.

Not yet wired into manifest/lock/SkillDefinition — that is the next commit.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…se 0, core)

Reshape fastskill-core onto the canonical Origin (intent) + lock-only Resolved:
- manifest: delete SkillSource/SourceSpecificFields/DependencySource;
  SkillEntry {id, origin, groups}; DependencySpec = Version | Inline{origin,groups}.
- skill_manager: delete SourceType; SkillDefinition/SkillUpdate carry `origin`
  (+ kept resolved facts commit_hash/fetched_at); SkillDefinition::new takes origin.
- lock: entries carry {origin, resolved}; version bumped to "3.0" with a
  pre-parse guard rejecting pre-Origin locks (LockError::UnsupportedVersion);
  build_skill_source deleted.
- consumers updated: reconciliation, service, update, http handlers, output.

BREAKING: on-disk manifest/lock serde formats change (greenfield, no shim).
Behavior-preserving for CLI outcomes; only new behavior is the lock old-data guard.

fastskill-cli intentionally does NOT compile yet — its pass is the next commit.
cargo build/test/clippy -p fastskill-core --all-targets all green (335+ tests).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
BREAKING CHANGE: on-disk lock/manifest formats change (greenfield, no shim).

Fix fastskill-cli against the reshaped core: build a concrete Origin at each
install site (add_from_git/folder/zip/registry), carry origin through the
lock<->manifest reconstructions (previously lossy — dropped source fields),
read resolved.version from lock entries, and delete the dead source-detection
trio (resolve_source_type/autodetect_source/ResolvedSource). SourceMeta and the
four per-path SkillUpdate builders collapse to one {origin} each.

Behavior-preserving (CLI outcomes unchanged; net -261 lines). lock_migration_test
rewritten: pre-3.0 locks are now rejected (UnsupportedVersion), not migrated.
Full workspace green: build + clippy -D warnings + 653 tests, 0 failures.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A pre-Origin `[dependencies]` entry (`source = "git"` + flat fields) no longer
parses; append a migration hint pointing at the `origin = { type = … }` shape
instead of surfacing a raw serde error. Completes the Phase-0 old-data guard
(the lock already rejects pre-3.0 formats).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@aroff
aroff merged commit 665cbd8 into main Jul 21, 2026
11 checks passed
@aroff
aroff deleted the feat/origin-model-phase0 branch July 21, 2026 22:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant