Skip to content

feat(codegen): wire [[codegen]].options through to tx3c, re-cut #128 regressions - #131

Open
scarmuega wants to merge 1 commit into
mainfrom
plan/trix-codegen-options-wiring
Open

feat(codegen): wire [[codegen]].options through to tx3c, re-cut #128 regressions#131
scarmuega wants to merge 1 commit into
mainfrom
plan/trix-codegen-options-wiring

Conversation

@scarmuega

Copy link
Copy Markdown
Contributor

Plan

plans/trix-codegen-options-wiring.md (tx3 domain root) — a
code-change-request scoped to this repository only.

Done criterion: met. Both parts land, the full suite is green, and each
ported regression was verified to fail when its fix is reverted.

What changed

Part 1 — wire the dead [[codegen]].options field

The field has been dead config since it was introduced: written None at
src/commands/codegen.rs and src/commands/init.rs, never read, and
src/spawn/tx3c.rs::codegen() forwarded only tii/template/output. A project
setting options got silence.

  • src/config/convention.rsKnownCodegenPlugin::default_options()
    and CodegenConfig::resolved_options(). Plugin defaults with the
    project's options merged on top, key by key, user values winning
    (including setting a default's key back to false). Plugin knowledge
    stays in trix's config layer; tx3c remains generic. The one default
    today is ts-client → {standalone: true} — the knob the
    codegen-v1beta0 templates gate package.json.hbs and
    tsconfig.json.hbs on. BTreeMap, so the JSON on the wire is stable.
  • src/spawn/tx3c.rscodegen() takes the resolved map and forwards
    it as one JSON object under --options. An empty map omits the flag
    entirely
    , so a project that asks for nothing produces exactly the argv
    trix sent before the channel existed.
  • src/commands/codegen.rs — resolves once per [[codegen]] entry and
    passes it to every protocol in that entry.

Part 2 — PR #128's regression value, re-cut onto the #129 layout

#128 is built entirely on the tests/e2e/ layer #129 deleted and cannot
merge. Its three surviving regressions are re-homed at the layers the
current policy puts them:

#128's package.json fixture lock and #[ignore]d live test are deliberately
not ported — emission verification moves to the e2e journey, and the
trix layer asserts argv only (the #129 policy).

Closing #128 as superseded is the owner's act, not mine — flagging it
here per the plan.

Test placement note

The plan asks for the ts-client default to be asserted at the contract
layer. Reaching a known plugin's argv normally means fetching the web-sdk
templates from GitHub, which the hermeticity policy forbids. Both contract
tests that need ts-client use the existing local-template seam instead:
plugin.repo is treated as a local template root whenever it names a
directory, and repo resolves relative to the process CWD, so
stage_local_ts_client_templates() materializes
tx3-lang/web-sdk/.trix/client-lib/ inside the test project. No network, no
production seam added. The merge rule is additionally unit-tested next to
itself in src/config/convention.rs, per the "rules go innermost" doctrine.

tests/README.md gains a section on the OCI stub and the layering rule for
pull-path tests.

Verification

All run locally on macOS at 20eeebc, using CI's exact commands:

  • cargo fmt --all -- --check — clean
  • cargo clippy --all-targets --all-features -- -D warnings — clean
  • cargo test --workspace --all-targets --all-features --locked
    115 passed, 0 failed (83 unit, 13 CLI, 19 contract)

Regression spot-checks — each fix reverted locally in turn, only its own
test failing:

Reverted Result
image/png dropped from oci::pull's accepted media types use_accepts_image_with_png_logo_layer FAILED, other passed
scope/name no longer lowercased in oci::reference_for use_addresses_registry_repo_path_in_lowercase FAILED, other passed
@ added to refs::validate_ident's charset use_rejects_npm_style_at_version_separator FAILED

The tests/README.md invariant holds: no test in the repo spawns a real
helper binary (the only Command::new outside the harness's fake-tx3c
wiring is the rustc that compiles that fake).

Release ordering — please read before merging

--options is a flag tx3c does not have yet; its side is
plans/lang-tx3c-options-channel.md against tx3-lang/tx3, still ready.
The two are independent to develop (this repo's contract layer stubs tx3c)
but not independent to release:

  • Projects with no [[codegen]].options and a plugin with no defaults are
    unaffected — trix omits the flag, so the argv is byte-identical to today.
  • ts-client projects are not: they now always carry
    {"standalone":true}, so a released trix carrying this change paired with
    a released tx3c predating the options input would fail trix codegen
    for every TypeScript user.

The compat floor (src/spawn/compat.rs, tx3c min 0.22.0) is not
raised here — the version that carries the flag does not exist yet, and
raising the floor is the toolchain release train's step, not this plan's.
Filed as a follow-up draft plan in the domain root
(plans/trix-compat-floor-tx3c-options.md) for the owner to release. Merging
this PR is safe; shipping a trix release from it before the tx3c side is
released is not.

Not in this PR

Per the plan's boundary, the remaining parent-plan work stays where it is:
the web-sdk codegen-check.sh extension, the 07-codegen-consume journey
amendment, and the release-train note.

🤖 Generated with Claude Code

…regressions

Part 1 — the options channel. `[[codegen]].options` has been dead config
since it was introduced: written `None` by `codegen`/`init`, never read,
and `spawn::tx3c::codegen` forwarded only tii/template/output. It now
resolves and forwards.

- `config/convention.rs` gains `KnownCodegenPlugin::default_options` and
  `CodegenConfig::resolved_options`: plugin defaults with the project's
  `options` merged on top, user values winning. Plugin knowledge lives in
  trix's config layer — `tx3c` stays generic. The one default today is
  `ts-client → {standalone: true}`, the knob the codegen-v1beta0
  templates gate `package.json.hbs` / `tsconfig.json.hbs` on.
- `spawn::tx3c::codegen` takes the resolved map and forwards it as one
  JSON object under `--options`. An empty map omits the flag entirely, so
  a project that asks for nothing sends exactly the argv it sent before.
- Unit tests on the merge rule; contract tests on the wire (argv against
  the fake tx3c): default injects `standalone: true`, explicit
  `standalone = false` overrides it, a plugin with no defaults forwards
  user options unchanged, no options means no flag.

Part 2 — PR #128's regression value, re-cut onto the #129 layout. #128 is
built on the deleted `tests/e2e/` layer and cannot merge; these are the
three defects worth locking, at the layers the current policy puts them:

- `@`→`:` forbidden-character rejection → `tests/cli/refs.rs`. Parse-time,
  zero registry traffic.
- `image/png` logo-layer pull (regression of #118) and lowercase OCI repo
  addressing with case-preserving identity (regression of #120) →
  `tests/cli/registry.rs`, against `tests/harness/oci_stub.rs` — #128's
  in-process registry stub, ported. Pulls are trix's own code, not a
  helper binary, so they belong to the CLI layer and the suite stays
  offline.

#128's package.json fixture lock and `#[ignore]`d live test are not
ported: emission verification belongs to the e2e journey, and the trix
layer asserts argv only.

Each of the three was spot-checked by reverting its fix locally; each
fails and only that one fails.

Plan: plans/trix-codegen-options-wiring.md
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