Skip to content

feat(generator): per-project generator pin with checksum, plus an unpinned local-jar override - #175

Merged
clabonte merged 3 commits into
mainfrom
feat/project-generator-pin
Oct 29, 2026
Merged

clabonte merged 3 commits into
mainfrom
feat/project-generator-pin

Conversation

@clabonte

@clabonte clabonte commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator

Closes #169.

Problem. specfuse authoring generate only read the kit's generator.lock. The only way for a project to use a different generator was to bypass the CLI, which RestoManager does today: it commits its jar and has no checksum.

Changes

  • Project pin, .specfuse/generator.lock.
    • The CLI looks for it from the working directory upward and stops at the repo root, so a pin in a parent checkout can't leak in.
    • Only version and sha256 are required. asset, release_tag and release_repo default to the dist repo's naming, and min_java defaults to the kit's.
    • The jar is downloaded, checked and cached the same way as the kit pin, and a wrong checksum stops the run.
    • The CLI warns when the project's version differs from the kit's tested version.
    • upgrade never touches the file, because it isn't in the overlay manifest.
  • SPECFUSE_GENERATOR_JAR=/path.jar runs a local jar as-is and warns on every run that it is unpinned. It reuses the variable check-extension-vocabulary.py already reads.
  • Every run prints which pin it used. That line is now flushed, so it appears before the generator's output instead of after it.
  • check-extension-vocabulary.py now checks the project-pinned jar instead of the newest jar in the shared cache, which could belong to a different project.
  • docs/generator-access.md gets a new section, troubleshooting rows and a security note. The scripts README has a one-line update.
  • New CI step covering the cases that need no network: incomplete lock, malformed JSON, the repo-root boundary, and a missing local jar.

Tested locally (from source, with a separate SPECFUSE_HOME):

  • no lock: kit pin, 0.19.0
  • project pin 0.18.0: version warning, runs 0.18.0
  • missing sha256 or malformed JSON: clear error
  • env jar: unpinned warning, runs it
  • env path missing: error
  • lock above .git: ignored
  • vocabulary check: picks the project-pinned jar, and returns none when that version isn't cached

The new CI step passes locally against this branch.

Not covered: a checksum mismatch on a fresh download (needs network); that code is unchanged apart from naming the pin source in the message. No compatibility.md row yet; that's added at release time.

Rebased on main (2026-10-29, kit 0.30.0, generator 0.21.0). The rebase was clean. Since this PR opened, generate.sh (#176) and add-component (#180) shipped already saying the project pin is honoured, so until this merges those claims are false. One follow-up commit:

  • add-component now finds the project pin through generator.find_project_lock, so it searches up to the repo root like generate does, rather than looking only in <spec-dir>/.specfuse/.
  • getting-started.md and the generate skill mention the project pin.

Re-tested from source: the #169 CI step passes, and so do check-shipped-docs.py and check-flows-page.py. add-component resolves the project pin from the spec dir and from a subdirectory.

🤖 Generated with Claude Code

clabonte and others added 2 commits October 29, 2026 10:41
…override (#169)

The generator version was fixed by the kit's own generator.lock, so a
project could not move to a newer or older generator without bypassing
`specfuse authoring generate` and losing checksum verification.

- A project may commit .specfuse/generator.lock. It is found by walking up
  from the working directory, stopping at the repo root. Only version and
  sha256 are required; asset, release_tag and release_repo default to the
  dist repo's conventions, min_java to the kit's. It is downloaded,
  verified and cached exactly like the kit pin, and warns when it differs
  from the kit's tested version.
- SPECFUSE_GENERATOR_JAR runs a local jar as-is, warning on every run that
  it is unpinned. It is the variable check-extension-vocabulary.py already
  honoured.
- Every run names the pin it used. The status line is flushed so it
  precedes the generator's own output.
- check-extension-vocabulary.py examines the project-pinned jar when one is
  set, instead of the newest jar in the shared cache.
- generator-access.md documents both; CI covers the offline paths.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…does

add-component read only <spec-dir>/.specfuse/generator.lock, while
specfuse authoring generate searches upward to the repo root. Reuse
generator.find_project_lock so both name the same pin. Mention the
project pin in getting-started and the generate skill.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@clabonte
clabonte force-pushed the feat/project-generator-pin branch from 22f32af to fe53e73 Compare October 29, 2026 14:42
With no project pin the CLI falls back to the kit pin. Its download fails
in CI, and bash -e exited the step without a message. The check only
greps the output, so the exit status is ignored.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@clabonte
clabonte merged commit 214733d into main Oct 29, 2026
7 checks passed
@clabonte
clabonte deleted the feat/project-generator-pin branch October 29, 2026 14:46
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.

Per-project generator pin override (with checksum) for specfuse authoring generate

1 participant