feat: Phase 1 Go-module-style grader refs - #492
Closed
Shayne Boyer (spboyer) wants to merge 1 commit into
Closed
Conversation
Adds `ref:` support to grader entries in eval.yaml using
Go-module-style paths:
github.com/<owner>/<repo>[/path][#export]@<version>
Only exact semver tags (vX.Y.Z) or full 40-char commit SHAs are
accepted; floating selectors are rejected up front for reproducibility.
New:
- `waza get [eval.yaml]` — resolves every ref against its remote Git
source and writes waza.lock beside eval.yaml. `--verify` mode
checks the lock without modifying it.
- `waza.lock` — YAML lockfile pinning ref → commit SHA + sha256
content digest. Auto-verified by `waza run` before graders load.
- Module cache at `~/.waza/cache/{host}/{owner}/{repo}/{sha}/`.
- Remote grader presets are merged with local eval.yaml overrides
(scalar override, config deep-merge, list replace).
`waza run` first-run policy: if waza.lock is absent, refs are
auto-resolved and the lock is written. If waza.lock exists, refs are
verified strictly; digest mismatch or missing entry fails the run.
Phase 1 scope: github.com host + grader-preset artifact only. Design
in docs/research/waza-eval-registry-design.md.
Closes #15
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: c8007f65-5d5d-4ea9-aec4-f032d8443118
Contributor
There was a problem hiding this comment.
Pull request overview
Implements Phase 1 of “Go-module-style” remote grader preset references for eval.yaml, including parsing ref: strings, resolving remote YAML presets via GitHub raw-content fetches, caching + digest verification, and pinning resolutions in a waza.lock lockfile. This integrates into both waza get (explicit resolution) and waza run (auto-resolve on first run when no lock exists, strict verify once the lock exists).
Changes:
- Add
ref:support toGraderConfigYAML parsing, deferringtype/configvalidation until after remote resolution. - Introduce registry/ref parsing, manifest reading, lockfile format, resolver/cache, and preset expansion (remote base + local overrides).
- Add
waza getcommand and integrate resolver/lock policy intowaza run.
Show a summary per file
| File | Description |
|---|---|
| internal/registry/spec_resolve.go | Walks an EvalSpec and expands all ref: graders via resolver + lockfile, persisting lock updates when requested. |
| internal/registry/resolver.go | Fetches pinned preset YAML from GitHub, caches it, verifies sha256 digest, and updates lock entries. |
| internal/registry/resolver_test.go | Adds httptest-backed coverage for resolve/update/verify flows, cache usage, and digest mismatch behavior. |
| internal/registry/ref.go | Parses canonical host/owner/repo[/path][#export]@version refs with Phase 1 constraints (github.com + exact tag/SHA). |
| internal/registry/ref_test.go | Valid/invalid matrix tests for ref parsing and round-tripping. |
| internal/registry/manifest.go | Parses waza.registry.yaml and maps #export to preset file paths. |
| internal/registry/lockfile.go | Defines waza.lock schema and load/save/upsert behavior. |
| internal/registry/lockfile_test.go | Covers lockfile round-trip, sort stability, upsert behavior, and schema validation. |
| internal/registry/expand.go | Merges remote preset YAML with local overrides and re-validates via existing GraderConfig.UnmarshalYAML. |
| internal/registry/expand_test.go | Tests merge rules, scalar overrides, deep-merge semantics, and required remote type. |
| internal/models/spec.go | Adds GraderConfig.Ref and updates YAML decoding to preserve override config for ref-based graders. |
| internal/models/spec_test.go | Tests parsing a ref-based grader entry without inline type. |
| cmd/waza/root.go | Registers the new get subcommand. |
| cmd/waza/cmd_run.go | Resolves remote grader refs at run start; permissive first run (writes lock), strict verification after lock exists. |
| cmd/waza/cmd_get.go | Implements waza get [eval.yaml] to resolve refs and write/update waza.lock, plus --verify mode. |
Review details
- Files reviewed: 15/15 changed files
- Comments generated: 4
- Review effort level: Low
Comment on lines
+88
to
+97
| func sortedGraderNames(m *Manifest) []string { | ||
| if m == nil { | ||
| return nil | ||
| } | ||
| names := make([]string, 0, len(m.Exports.Graders)) | ||
| for n := range m.Exports.Graders { | ||
| names = append(names, n) | ||
| } | ||
| return names | ||
| } |
Comment on lines
+124
to
+126
| digest := computeDigest(presetYAML) | ||
| url := githubRawURL(ref, commit, "") // module-relative URL noted below | ||
| entry := LockModule{ |
Comment on lines
+73
to
+80
| if lock.SchemaVersion == 0 { | ||
| // Older/empty files: default to current schema for forward-compat. | ||
| lock.SchemaVersion = LockfileSchemaVersion | ||
| } | ||
| if lock.SchemaVersion != LockfileSchemaVersion { | ||
| return nil, fmt.Errorf("lockfile %s: unsupported schema_version %d (expected %d)", path, lock.SchemaVersion, LockfileSchemaVersion) | ||
| } | ||
| return &lock, nil |
Comment on lines
+185
to
+187
| if !strings.Contains(got, path.Join(".waza", "cache")) { | ||
| t.Fatalf("DefaultCacheDir() = %q, want to contain .waza/cache", got) | ||
| } |
Member
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #15
Summary
Phase 1 implementation of Go-module-style grader references in
eval.yaml, perdocs/research/waza-eval-registry-design.md.Adds a
ref:field to grader entries so an eval can pull a shared, versioned grader preset from a Git repo instead of duplicating the config inline:What's included
GraderConfig.Reffield; when set,typeandconfigvalidation are deferred to after ref resolution so the remote preset defines them (internal/models/spec.go).host/owner/repo[/path][#export]@versionparser. Phase 1 accepts onlygithub.comhost + exact semver tags or 40-char commit SHAs. Floating selectors (branches, ranges,latest) are rejected up front (internal/registry/ref.go).waza.lock(YAML, schema_version=1) pins each ref to a commit SHA and sha256 content digest. Sorted for stable diffs (internal/registry/lockfile.go).git archive/ full clone). Content-addressed disk cache at~/.waza/cache/{host}/{owner}/{repo}/{sha}/. Digest verification on every load (internal/registry/resolver.go). Fetcher is an interface, so tests usehttptest.waza.registry.yamlreader for#export-style refs (internal/registry/manifest.go).configdeep-merge, list replace) and round-trips through existingGraderConfig.UnmarshalYAMLso all strong-typed grader-kind validation runs unchanged (internal/registry/expand.go).waza get [eval.yaml]— resolves refs and writes/updates the lockfile.--verifymode checks the lock without modifying it (cmd/waza/cmd_get.go).waza runintegration — auto-resolves refs on first run if no lockfile exists, then writes the lock. If the lock exists, refs are verified strictly (missing entry or digest mismatch fails the run) (cmd/waza/cmd_run.go).Policy decisions
ParseRefalready enforces) and writes the lock. Once the lock exists, verification is strict.sha256:<hex>format.Tests
internal/models/spec_test.go— parsing aref:grader entry without inlinetype/config.internal/registry/ref_test.go— parser accept/reject matrix (tags, SHAs, floating refs, wrong host, path+export conflict).internal/registry/lockfile_test.go— round-trip, upsert-replace, missing-file, bad-schema.internal/registry/resolver_test.go—httptest-backed GitHub API + raw content servers; covers fresh resolve → cache → verify, ErrRefNotInLock, ErrDigestMismatch, and subpath refs that skip the manifest.internal/registry/expand_test.go— merge rules for scalar override, config deep-merge, default name, missing-typeguard.Verify
Draft until follow-up items land:
waza runagainst a fixture eval + real cachesite/src/content/docs/reference/for theref:syntax andwaza getwaza getin the Commands section