Skip to content

chore: untrack the built engine (CHORE-UNTRACK-BUILT-ENGINE) - #110

Merged
davidp57 merged 4 commits into
developfrom
chore/untrack-built-engine
Aug 8, 2026
Merged

chore: untrack the built engine (CHORE-UNTRACK-BUILT-ENGINE)#110
davidp57 merged 4 commits into
developfrom
chore/untrack-built-engine

Conversation

@davidp57

@davidp57 davidp57 commented Aug 8, 2026

Copy link
Copy Markdown
Member

Why

CTLD.lua is generated by merge_CTLD.ps1 and committed anyway. .gitignore called it deliberate — "intentionally tracked — available at repo root for DCS missions" — a reason from the repository bootstrap that no longer holds:

  • nothing points at the repository file (no link in the README or docs/);
  • VMCT, the consumer everyone assumed depended on it, does not. Its vendored.yaml pins 2.0.0-rc3 with manual_steps: "(verbatim) re-download the CTLD.lua asset from the matching VEAF/CTLD release" and watches github-release;
  • Zip confirmed nothing else consumes it directly.

Meanwhile the cost lands on every code change: 26 of the 28 merges touching src/ over 30 days carried the regenerated file — a one-megabyte generated diff nobody reviews, and a guaranteed conflict between parallel PRs.

It is safe now because FEAT-DEV-BUILD-CHANNEL (#109) publishes the engine where people take it: attached to every release, and to the floating dev pre-release rebuilt on each merge. Confirmed on that channel's first run — CTLD.lua attached, declaring ctld.VERSION = "2.0.0-rc6-182ec25".

The trap this PR leads with

python-quality runs on ubuntu, checks out, and runs pytest — it never built the engine. 27 tests guarded by skipif(not CTLD.lua) ran only because the artifact was committed. Measured by removing it:

Result
With CTLD.lua 262 passed
Without 234 passed, 27 skipped, 1 failed

Deleting the file alone would have left CI green while the whole .miz installation suite stopped running. So the build comes first (ticket 01), the deletion last (ticket 03).

What changed

  • merge_CTLD.ps1 runs on Linux. Three literal Windows paths, not the two the ticket listed: generate_i18n_dicts.ps1:36 carries the same "..\.." and the merge script calls it. All three now compose one segment at a time. It stays the single build path — a lookalike built for the tests would drift.
  • python-quality builds the engine before pytest, and its paths: filter gains src/** and tools/build/**, since the job now depends on both.
  • test_inject_into_miz gains the guard its neighbours have. It failed with KeyError: 'injected' when no engine was built — an error naming neither the engine nor the build. Without CTLD.lua the suite now reports 234 passed / 28 skipped / 0 failed.
  • git rm --cached CTLD.lua plus a .gitignore entry replacing the old "do NOT ignore this" comment, next to the precedent already there (/src/CTLD_config_default_yaml.lua, generated the same way).
  • Docs where the assumption lived: CLAUDE.md now says never commit as well as never hand-edit; building-and-testing.{md,fr.md} gain a table saying where to get an engine per role (contributor / Mission Maker / tester).

No history rewriting — the 471 past blobs weigh 2.8 MiB packed out of a 93 MiB .git.

What this PR's own CI proves

That pwsh is present on the ubuntu image (the fallback, if not, is windows-latest) and that python-quality reports 262 passed, 0 skipped with the file absent from the repository. Both acceptance boxes are left unticked until then rather than ticked on a hunch.

🤖 Generated with Claude Code

Summary by Sourcery

Untrack the generated CTLD.lua engine file by updating build and CI to create it on demand, tightening tests to handle its absence cleanly, and revising documentation and backlog entries to reflect the new distribution and usage model.

Bug Fixes:

  • Ensure the web app injection test skips when CTLD.lua is missing instead of failing with a KeyError.

Enhancements:

  • Make the PowerShell build and i18n scripts portable across Windows and Linux runners.
  • Update developer documentation to explain that CTLD.lua is a generated, git-ignored artifact and where different roles should obtain it.
  • Document the CHORE-UNTRACK-BUILT-ENGINE lot and its tickets in the backlog, including the dependency on the dev build channel.

Build:

  • Adjust the python-quality workflow triggers to run when either src or tools/build change.

CI:

  • Have the python-quality GitHub Actions job build CTLD.lua via merge_CTLD.ps1 before running pytest so engine-dependent tests execute correctly.

Documentation:

  • Extend EN/FR building-and-testing guides and CLAUDE.md to cover the new CTLD.lua build and distribution model and to forbid committing the generated file.

Tests:

  • Add a skip guard to test_inject_into_miz so it is consistent with other engine-dependent tests.

Chores:

  • Stop tracking the generated CTLD.lua file in git and ignore it via .gitignore, relying on releases and the dev pre-release to distribute built engines.

davidp57 and others added 3 commits August 8, 2026 22:37
…-ENGINE)

CTLD.lua is generated and committed anyway; .gitignore calls it
deliberate, for a bootstrap-era reason that no longer holds. Nothing
points at the repository file, and VMCT — the consumer everyone assumed
depended on it — takes the release asset instead (vendored.yaml pins
2.0.0-rc3 and watches github-release).

The cost is paid on every code change: 26 of the 28 merges touching src/
over 30 days carried the regenerated file.

The lot leads with the trap rather than the deletion. python-quality
runs on ubuntu and never builds the engine, so removing the file alone
takes the suite from 262 passed to 234 passed / 27 skipped / 1 failed
with CI still green — measured, not assumed. Build first, delete second.
The failure is a separate defect the measurement exposed:
test_inject_into_miz crashes where its neighbours skip.

Depends on FEAT-DEV-BUILD-CHANNEL: a release and the dev pre-release
both attach CTLD.lua, which is what makes the removal safe.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…UNTRACK-BUILT-ENGINE 01)

python-quality runs on ubuntu and never built CTLD.lua: 27 tests guarded
by skipif(not CTLD.lua) only ran because the artifact is committed.
Measured by removing the file — 262 passed becomes 234 passed, 27
skipped, 1 failed, with CI still green. The build has to come first, so
that untracking the artifact later cannot silently drop a whole suite.

merge_CTLD.ps1 stays the single build path; it now runs on Linux too.
Three literal Windows paths were in the way, not the two the ticket
listed: generate_i18n_dicts.ps1 carries the same "..\.." and is called
by the merge script. All three are composed one segment at a time, which
Join-Path resolves per platform.

python-quality's paths: filter gains src/** and tools/build/** — the job
now builds the engine, so a change to either can break it.

Local Windows build unchanged: same command, and the rebuilt CTLD.lua
differs by no line.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
CTLD.lua is generated by merge_CTLD.ps1 and was committed anyway, on a
bootstrap-era ground — "available at repo root for DCS missions" — that
no longer holds: nothing points at the repository file, and VMCT, the
consumer everyone assumed depended on it, takes the release asset
(vendored.yaml: "re-download the CTLD.lua asset from the matching
release"). Meanwhile 26 of the 28 merges touching src/ over 30 days
carried the regenerated file: a one-megabyte generated diff in almost
every code PR, and a guaranteed conflict between parallel branches.

Untracking is safe now because FEAT-DEV-BUILD-CHANNEL publishes the
engine where people take it: attached to each release, and to the
floating dev pre-release rebuilt on every merge. Verified on the first
dev build — CTLD.lua attached, declaring 2.0.0-rc6-182ec25.

test_inject_into_miz gains the guard its neighbours have. It used to
fail with KeyError: 'injected' when no engine was built, naming neither
the engine nor the build; without CTLD.lua the suite now reports 234
passed / 28 skipped / 0 failed, and 262 passed with it.

No history rewriting: the 471 past blobs weigh 2.8 MiB packed.

Docs updated where the assumption lived: CLAUDE.md now says never commit
as well as never hand-edit, and building-and-testing (EN + FR) says
where to get an engine per role.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@sourcery-ai

sourcery-ai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Reviewer's Guide

This PR stops committing the generated CTLD.lua engine by making the PowerShell build scripts portable to Linux, ensuring CI builds the engine before tests, adding a missing skip guard in a web-app test, updating documentation to reflect that CTLD.lua is git-ignored and obtained from releases/dev builds, and finally untracking/ignoring CTLD.lua in git.

Sequence diagram for python-quality CI building CTLD.lua before tests

sequenceDiagram
    participant GitHubActions as python-quality_job
    participant MergeScript as merge_CTLD.ps1
    participant I18nScript as generate_i18n_dicts.ps1
    participant Pytest as pytest

    GitHubActions->>MergeScript: run ./tools/build/merge_CTLD.ps1
    MergeScript->>MergeScript: Resolve-Path scriptDir
    MergeScript->>MergeScript: Resolve-Path repoRoot (Join-Path ".." "..")
    MergeScript->>MergeScript: Join-Path repoRoot src
    MergeScript->>MergeScript: Join-Path repoRoot CTLD.lua
    MergeScript->>MergeScript: Join-Path (Join-Path repoRoot tools) ctld-tools
    MergeScript->>I18nScript: generate_i18n_dicts.ps1 -Apply
    I18nScript->>I18nScript: Resolve-Path repoRoot (Join-Path ".." "..")
    I18nScript-->>MergeScript: i18n dicts synced
    MergeScript-->>GitHubActions: CTLD.lua built at repo root

    GitHubActions->>Pytest: poetry run pytest
    alt CTLD.lua present
        Pytest->>Pytest: run all tests (262 passed, 0 skipped)
    else CTLD.lua missing
        Pytest->>Pytest: [skipif(not CTLD.lua)]
        Pytest->>Pytest: tests using .miz installation skipped
    end
Loading

File-Level Changes

Change Details Files
Make the PowerShell build scripts portable across Windows and Linux so CI can build the engine from the single canonical path.
  • Replace hard-coded Windows-only "...." path in merge_CTLD.ps1 with segment-by-segment Join-Path composition.
  • Replace hard-coded Windows-only "tools\ctld-tools" join in merge_CTLD.ps1 with Join-Path-based composition.
  • Update generate_i18n_dicts.ps1 to use segment-by-segment Join-Path instead of a literal "...." so it works on Linux when called from merge_CTLD.ps1.
  • Add comments explaining the cross-platform path handling and its relation to the CHORE-UNTRACK-BUILT-ENGINE lot.
tools/build/merge_CTLD.ps1
tools/build/generate_i18n_dicts.ps1
Ensure the python-quality GitHub Actions job actually builds CTLD.lua before running pytest, and is triggered when build-related files change.
  • Extend workflow trigger paths from a single config file to src/** and tools/build/** so changes to engine sources or build scripts trigger python-quality.
  • Insert a PowerShell step that runs tools/build/merge_CTLD.ps1 with pwsh before the pytest step.
  • Document in comments that the tests install the real engine and that merge_CTLD.ps1 remains the single build path to avoid drift.
.github/workflows/python-quality.yml
Align test behavior with the rest of the suite when CTLD.lua is missing by skipping instead of failing.
  • Import pathlib.Path in test_web_app.py to detect the presence of CTLD.lua at the repo root.
  • Add a pytest.mark.skipif decorator to test_inject_into_miz that checks for CTLD.lua and skips with a clear reason if the engine is not built.
  • Remove the now-redundant local Path import inside test_inject_into_miz and leave its assertions unchanged when the engine is present.
tools/ctld-tools/tests/test_web_app.py
Untrack CTLD.lua from the repository and make sure git ignores future builds while documenting how users should obtain the engine.
  • Remove CTLD.lua from version control (git rm --cached) so it no longer contributes large generated diffs or merge conflicts.
  • Add CTLD.lua to .gitignore, replacing the previous comment that explicitly exempted it, and reference the fact that releases and the dev pre-release publish the engine.
  • Update CLAUDE.md to emphasize that CTLD.lua is generated, git-ignored, and must never be hand-edited or committed; local rebuilds are only for testing.
  • Revise building-and-testing.md and building-and-testing.fr.md to clarify that CTLD.lua is not part of the repo, is built to the root as an ignored artifact, and to provide a role-based table explaining where contributors, mission makers, and testers obtain an engine.
  • Add backlog documentation for the CHORE-UNTRACK-BUILT-ENGINE lot and its tickets, describing rationale, scope, and acceptance criteria, and mark FEAT-DEV-BUILD-CHANNEL as merged with its role in keeping CTLD.lua downloadable.
.gitignore
CTLD.lua
CLAUDE.md
docs/developer/building-and-testing.md
docs/developer/building-and-testing.fr.md
.backlog/README.md
.backlog/CHORE-UNTRACK-BUILT-ENGINE/PRD.md
.backlog/CHORE-UNTRACK-BUILT-ENGINE/tickets/01-build-the-engine-where-the-tests-need-it.md
.backlog/CHORE-UNTRACK-BUILT-ENGINE/tickets/02-a-missing-engine-skips-it-does-not-crash.md
.backlog/CHORE-UNTRACK-BUILT-ENGINE/tickets/03-untrack-the-engine.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • In test_inject_into_miz, the skipif condition recomputes the repo root via parents[3]; consider reusing the same repo-root helper/path used by the other CTLD.lua-guarded tests to avoid brittle path assumptions.
  • The new python-quality path filters (src/** and tools/build/**) significantly broaden when the workflow runs; double-check this won't cause unnecessary CI runs compared to a more targeted subset of build-related files.
  • Since merge_CTLD.ps1 is now run on Linux via pwsh, it might be worth adding an explicit failure message or check when PowerShell is unavailable to make CI issues easier to diagnose if the runner image changes.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `test_inject_into_miz`, the `skipif` condition recomputes the repo root via `parents[3]`; consider reusing the same repo-root helper/path used by the other CTLD.lua-guarded tests to avoid brittle path assumptions.
- The new `python-quality` path filters (`src/**` and `tools/build/**`) significantly broaden when the workflow runs; double-check this won't cause unnecessary CI runs compared to a more targeted subset of build-related files.
- Since `merge_CTLD.ps1` is now run on Linux via `pwsh`, it might be worth adding an explicit failure message or check when PowerShell is unavailable to make CI issues easier to diagnose if the runner image changes.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

The skipif guard and the mission fixture each recomputed
parents[3]. One REPO constant instead, which is what every other test
module in this directory does — there is no shared helper to reuse.

CI proved the two acceptance criteria left open: pwsh is on the ubuntu
image (`shell: /usr/bin/pwsh`, then 32 files merged) and python-quality
reports 262 passed, 0 skipped with CTLD.lua absent from the repository.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@davidp57

davidp57 commented Aug 8, 2026

Copy link
Copy Markdown
Member Author

Thanks — one taken, two declined with reasons.

1. parents[3] recomputed in test_inject_into_miz — taken (ea7ad86). The guard and the mission fixture each recomputed it; there is now one REPO constant at the top of the file. Note there is no shared helper to reuse: ten test modules each declare their own REPO/ROOT/SRC from parents[3] (test_install, test_resources, test_miz, test_oracle, …). One constant per file is the convention here, and introducing a conftest.py to centralise it would touch nine files this PR has no business editing.

2. Broader paths: filters — kept. src/** and tools/build/** are not incidental: the job now builds the engine, so a change to any merged Lua module or to the build scripts can break it, and a filter that let those through would mean discovering the breakage in a later PR. The run costs about 1.5 min on a free public-repo runner. A narrower subset would have to predict which src/ file can break a full merge build — it cannot, since listToMerge.txt concatenates all 32 of them.

3. Explicit check for a missing pwsh — declined. The runner already fails the step with Unable to locate executable file: pwsh, which names the cause precisely; a hand-rolled probe would restate it less well. And the question is now settled empirically: this PR's CI logs shell: /usr/bin/pwsh followed by Merged : 32 file(s). The windows-latest fallback documented in ticket 01 stays written down for the day the image changes.

For the record, the two acceptance criteria that were left unticked are now proven by this PR's own run: 262 passed, 0 skipped on ubuntu with CTLD.lua absent from the repository.

🤖 Addressed by Claude Code

@davidp57
davidp57 merged commit 29131a9 into develop Aug 8, 2026
8 checks passed
@davidp57
davidp57 deleted the chore/untrack-built-engine branch August 8, 2026 20:51
davidp57 added a commit that referenced this pull request Aug 9, 2026
Carried here rather than into a one-line PR of its own, per Zip. The
convention is to set the index line inside the lot's own PR; #110
shipped without it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
davidp57 added a commit that referenced this pull request Aug 9, 2026
…CON-SOUNDS) (#112)

* chore(backlog): mark CHORE-UNTRACK-BUILT-ENGINE merged (PR #110)

Carried here rather than into a one-line PR of its own, per Zip. The
convention is to set the index line inside the lot's own PR; #110
shipped without it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* feat(tool): a beacon sound the Mission Maker chooses (FEAT-CUSTOM-BEACON-SOUNDS)

radioSound and radioSoundFC3 were text boxes: typing a name changed what
the engine plays without putting any such file in the mission, so using
your own beacon tone meant editing the .miz by hand — the manual step
FEAT-ONE-CLICK-INSTALL exists to remove.

Each now gets a Default / Custom picker. A chosen .ogg is read at
selection, kept in the session, and written into the archive with its
resource key and preload trigger like the bundled ones.

The model, per ADR 0012: a chosen file enters the mission under a
reserved name (CTLD_beacon_custom.ogg), so the configuration value
itself says the sound is customised — no second key that could
contradict the engine, and no misreading of a Mission Maker whose own
file is called beacon.ogg. The name it had on disk survives as a
schema-only label, never catalogued: a catalogue entry would be a
parameter under ADR 0011 Addendum 1, so completeness would demand it and
every pre-lot configuration would report a missing setting at mission
start (FIX-TOOL-I18N-LANG's wall).

Reading the bytes at selection rather than at install is what makes an
installed mission reconfigurable: reopening the .miz recovers the sound,
so it reinstalls on another machine with the original file deleted. A
.yaml cannot carry a binary, so reopening one blocks the install with a
validation error naming the file to pick again — unless the target
mission already holds it. An OggS signature check catches the renamed
.mp3 that would give silent beacons discovered in flight; no size cap,
the size is reported instead.

The picker is bound to `editor: sound` in the schema, never to a setting
name in a component (FEAT-EDITOR-COVERAGE), and `hidden: true` keeps the
labels out of the families and out of search.

Typing a file name by hand still works for a sound added through the
Mission Editor. Documented EN + FR, in the tool guide and the
configuration reference.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* chore(backlog): mark FEAT-CUSTOM-BEACON-SOUNDS merged (PR #112)

Set in the lot's own PR, per the convention — not left for a post-merge
commit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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