design.md 4.7 KB

Context

See proposal.md for motivation. The 0.1.0 package declared a committed launcher that imported ignored dist output and relied on prepack to compile before local tarball creation. npm Git installation therefore could not rely on the selected revision alone. The package must stay private, dependency-free at runtime, compatible with Node 24 or newer, and inert toward the shared App Server during installation and verification.

Goals / Non-Goals

Goals:

  • Make a pinned Git tag or full commit installable through normal global npm semantics without consumer compilation.
  • Keep the two committed runtime files mechanically synchronized with TypeScript source.
  • Preserve verified tarball distribution, the executable name, invocation contract, transport behavior, and Emacs integration.
  • Verify installation shape and launcher behavior without connecting to the actively used shared App Server.

Non-Goals:

  • Publishing to or selecting a private npm registry.
  • Treating mutable branches as reproducible release identifiers.
  • Adding runtime dependencies or supporting Node.js versions below 24.
  • Changing bridge transport, lifecycle, authentication, or endpoint behavior.
  • Restarting Emacs, agent-shell sessions, or the shared App Server during package verification.

Decisions

Commit only the runtime imported by the stable launcher

Track dist/cli.js and dist/config.js while ignoring every other dist path. Retain the existing executable in bin/ and make the npm files allowlist exact. This keeps Git revisions self-contained with less generated churn than tracking a whole output tree. A distribution branch would add synchronization machinery; consumer-side compilation would require lifecycle execution and development dependencies.

Avoid Git preparation lifecycle triggers

Rename the maintainer command from build to compile, remove prepack, and add no prepare, preinstall, install, or postinstall script. Use pack:verified for explicit maintainer release gates. This prevents npm from attempting to build a Git dependency in a temporary clone.

Verify freshness against the indexed release baseline

Compilation is followed by Git diff and untracked-file checks for the two runtime paths. Tests cover fresh and stale indexed fixtures. The release workflow stages the intended source/runtime pair before invoking freshness validation so generated output is compared with the exact candidate release.

Exercise installed packages offline

Both Git and tarball verifiers install into temporary prefixes with lifecycle scripts disabled, require real package storage and the declared runtime files, and invoke the installed launcher with unsupported arguments. That invocation imports the compiled runtime and reaches its deterministic usage error without opening a socket, so validation cannot affect the shared App Server.

Require an advertised default branch and immutable release revision

The canonical Gogs repository must advertise HEAD -> main because npm 11 resolves repository HEAD before cloning even an explicit tag. End-user commands pin v0.1.1 or a full commit. Both remotes must resolve the annotated tag to the intended release commit before global installation.

Risks / Trade-offs

  • Committed JavaScript can drift from TypeScript → require freshness verification and review source with runtime changes.
  • A mutable branch can change after verification → accept only release tags or full 40-character commits in the verifier and documentation.
  • The repository default branch can be invalid → preflight symbolic HEAD and keep Gogs configured with main as the default branch.
  • npm behavior can change → retain an end-to-end isolated verifier on the supported Node 24/npm 11 toolchain.
  • Global replacement could disturb active work → verification remains offline; installation does not signal processes; new agent-shell launches pick up the replacement while the shared server continues running.

Migration Plan

  1. Update metadata, ignore rules, runtime output, verifiers, tests, and documentation; validate source/runtime freshness and package contents.
  2. Commit the release, push both main refs, create annotated tag v0.1.1, and verify both tags peel to the release commit.
  3. Ensure the canonical Gogs repository advertises HEAD -> main, then run the isolated verifier against the actual tag.
  4. Replace the global 0.1.0 tarball installation with the exact Git tag and verify the real package directory, PATH executable, version, and offline invocation contract.
  5. Roll back by reinstalling the verified 0.1.0 tarball or a prior immutable Git revision; no Emacs or App Server configuration change is required.