beqforge 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. beqforge-0.1.0/.github/dependabot.yml +10 -0
  2. beqforge-0.1.0/.github/workflows/build-device-check.yml +75 -0
  3. beqforge-0.1.0/.github/workflows/build-executable.yml +172 -0
  4. beqforge-0.1.0/.github/workflows/dependabot-auto-merge.yaml +23 -0
  5. beqforge-0.1.0/.github/workflows/tests.yml +101 -0
  6. beqforge-0.1.0/.gitignore +270 -0
  7. beqforge-0.1.0/.idea/.gitignore +10 -0
  8. beqforge-0.1.0/.idea/beqforge.iml +11 -0
  9. beqforge-0.1.0/.idea/editor.xml +276 -0
  10. beqforge-0.1.0/.idea/jsonSchemas.xml +25 -0
  11. beqforge-0.1.0/.idea/misc.xml +6 -0
  12. beqforge-0.1.0/.idea/modules.xml +8 -0
  13. beqforge-0.1.0/.idea/vcs.xml +6 -0
  14. beqforge-0.1.0/AGENTS.md +87 -0
  15. beqforge-0.1.0/CLAUDE.md +25 -0
  16. beqforge-0.1.0/LICENCE.md +21 -0
  17. beqforge-0.1.0/PKG-INFO +399 -0
  18. beqforge-0.1.0/README.md +373 -0
  19. beqforge-0.1.0/TODO.md +341 -0
  20. beqforge-0.1.0/beq_common/AGENTS.md +34 -0
  21. beqforge-0.1.0/beq_common/__init__.py +6 -0
  22. beqforge-0.1.0/beq_common/biquad.py +427 -0
  23. beqforge-0.1.0/beq_common/provenance.py +44 -0
  24. beqforge-0.1.0/beq_common/publication.py +20 -0
  25. beqforge-0.1.0/beq_common/types.py +30 -0
  26. beqforge-0.1.0/beqforge/AGENTS.md +530 -0
  27. beqforge-0.1.0/beqforge/__init__.py +79 -0
  28. beqforge-0.1.0/beqforge/accept.py +739 -0
  29. beqforge-0.1.0/beqforge/beqd.py +202 -0
  30. beqforge-0.1.0/beqforge/biquad.py +27 -0
  31. beqforge-0.1.0/beqforge/cache.py +616 -0
  32. beqforge-0.1.0/beqforge/charts.py +375 -0
  33. beqforge-0.1.0/beqforge/cli.py +61 -0
  34. beqforge-0.1.0/beqforge/design.py +394 -0
  35. beqforge-0.1.0/beqforge/designer.py +624 -0
  36. beqforge-0.1.0/beqforge/diagnose.py +763 -0
  37. beqforge-0.1.0/beqforge/explain.py +248 -0
  38. beqforge-0.1.0/beqforge/extraction.py +469 -0
  39. beqforge-0.1.0/beqforge/filters.py +1161 -0
  40. beqforge-0.1.0/beqforge/harness.py +457 -0
  41. beqforge-0.1.0/beqforge/identify.py +295 -0
  42. beqforge-0.1.0/beqforge/material.py +187 -0
  43. beqforge-0.1.0/beqforge/pipeline.py +1995 -0
  44. beqforge-0.1.0/beqforge/record.py +525 -0
  45. beqforge-0.1.0/beqforge/reference.py +153 -0
  46. beqforge-0.1.0/beqforge/rolloff.py +138 -0
  47. beqforge-0.1.0/beqforge/verify.py +486 -0
  48. beqforge-0.1.0/beqforge-device-check.spec +63 -0
  49. beqforge-0.1.0/beqforge.spec +77 -0
  50. beqforge-0.1.0/beqforge_device_check/AGENTS.md +68 -0
  51. beqforge-0.1.0/beqforge_device_check/__init__.py +3 -0
  52. beqforge-0.1.0/beqforge_device_check/analyse.py +788 -0
  53. beqforge-0.1.0/beqforge_device_check/audio.py +205 -0
  54. beqforge-0.1.0/beqforge_device_check/catalogue.py +359 -0
  55. beqforge-0.1.0/beqforge_device_check/cli.py +956 -0
  56. beqforge-0.1.0/beqforge_device_check/coefficients.py +100 -0
  57. beqforge-0.1.0/beqforge_device_check/engines.py +531 -0
  58. beqforge-0.1.0/beqforge_device_check/evidence.py +245 -0
  59. beqforge-0.1.0/beqforge_device_check/manifest.py +337 -0
  60. beqforge-0.1.0/beqforge_device_check/measurement.py +353 -0
  61. beqforge-0.1.0/beqforge_device_check/profiles.py +117 -0
  62. beqforge-0.1.0/beqforge_device_check/qualification.py +548 -0
  63. beqforge-0.1.0/beqforge_device_check/report.py +727 -0
  64. beqforge-0.1.0/beqforge_device_check/transactions.py +708 -0
  65. beqforge-0.1.0/beqforge_device_check/verify.py +250 -0
  66. beqforge-0.1.0/beqoptimiser/AGENTS.md +74 -0
  67. beqforge-0.1.0/beqoptimiser/__init__.py +34 -0
  68. beqforge-0.1.0/beqoptimiser/cache.py +358 -0
  69. beqforge-0.1.0/beqoptimiser/cli.py +184 -0
  70. beqforge-0.1.0/beqoptimiser/core.py +356 -0
  71. beqforge-0.1.0/beqoptimiser/data/seed-manifest.json +40 -0
  72. beqforge-0.1.0/beqoptimiser/data/seed.json.gz +0 -0
  73. beqforge-0.1.0/docs/device-check-examples/minidsp-2x4hd-usb-loopback.json +317 -0
  74. beqforge-0.1.0/docs/device-check-examples/simulation.json +32 -0
  75. beqforge-0.1.0/docs/device-check.md +360 -0
  76. beqforge-0.1.0/docs/optimiser-report/README.md +92 -0
  77. beqforge-0.1.0/docs/optimiser-report/assets/aggregate-48000.png +0 -0
  78. beqforge-0.1.0/docs/optimiser-report/assets/aggregate-96000.png +0 -0
  79. beqforge-0.1.0/docs/optimiser-report/assets/example-1.png +0 -0
  80. beqforge-0.1.0/docs/optimiser-report/assets/example-2.png +0 -0
  81. beqforge-0.1.0/docs/optimiser-report/entry-results.json.gz +0 -0
  82. beqforge-0.1.0/docs/optimiser-report/statistics.json +17762 -0
  83. beqforge-0.1.0/docs/optimiser.md +168 -0
  84. beqforge-0.1.0/evidence_validation.json +395 -0
  85. beqforge-0.1.0/negative_corpus.json +1450 -0
  86. beqforge-0.1.0/packaging/device-check/NOTICE.txt +16 -0
  87. beqforge-0.1.0/plans/F2-catalogue-filter-optimisation.md +448 -0
  88. beqforge-0.1.0/plans/F2-device-precision-validation.md +904 -0
  89. beqforge-0.1.0/plans/F2-package-consolidation.md +94 -0
  90. beqforge-0.1.0/plans/R2a-server-stage-cache.md +208 -0
  91. beqforge-0.1.0/plans/done-baseline-evidence.md +89 -0
  92. beqforge-0.1.0/plans/done-design-and-pipeline.md +868 -0
  93. beqforge-0.1.0/plans/research-design-decisions.md +403 -0
  94. beqforge-0.1.0/plans/test-portability-and-runtime.md +68 -0
  95. beqforge-0.1.0/pyproject.toml +52 -0
  96. beqforge-0.1.0/tests/__init__.py +1 -0
  97. beqforge-0.1.0/tests/conftest.py +14 -0
  98. beqforge-0.1.0/tests/fixtures/optimiser_seed_entry.json +204 -0
  99. beqforge-0.1.0/tests/test_cli.py +37 -0
  100. beqforge-0.1.0/tests/test_design_accept.py +645 -0
  101. beqforge-0.1.0/tests/test_design_cache.py +300 -0
  102. beqforge-0.1.0/tests/test_design_cache_stores.py +194 -0
  103. beqforge-0.1.0/tests/test_design_channel_evidence.py +158 -0
  104. beqforge-0.1.0/tests/test_design_charts.py +113 -0
  105. beqforge-0.1.0/tests/test_design_corpus.py +97 -0
  106. beqforge-0.1.0/tests/test_design_design.py +75 -0
  107. beqforge-0.1.0/tests/test_design_designer.py +829 -0
  108. beqforge-0.1.0/tests/test_design_designer_server.py +467 -0
  109. beqforge-0.1.0/tests/test_design_device_rate.py +277 -0
  110. beqforge-0.1.0/tests/test_design_diagnose.py +303 -0
  111. beqforge-0.1.0/tests/test_design_evidence.py +247 -0
  112. beqforge-0.1.0/tests/test_design_evidence_excess.py +97 -0
  113. beqforge-0.1.0/tests/test_design_exclusions.py +208 -0
  114. beqforge-0.1.0/tests/test_design_explain.py +76 -0
  115. beqforge-0.1.0/tests/test_design_extraction.py +207 -0
  116. beqforge-0.1.0/tests/test_design_filters.py +725 -0
  117. beqforge-0.1.0/tests/test_design_frozen_cache.py +73 -0
  118. beqforge-0.1.0/tests/test_design_guard.py +282 -0
  119. beqforge-0.1.0/tests/test_design_harness.py +165 -0
  120. beqforge-0.1.0/tests/test_design_headroom.py +55 -0
  121. beqforge-0.1.0/tests/test_design_identify.py +110 -0
  122. beqforge-0.1.0/tests/test_design_jacobian.py +175 -0
  123. beqforge-0.1.0/tests/test_design_parallel.py +92 -0
  124. beqforge-0.1.0/tests/test_design_pipeline.py +555 -0
  125. beqforge-0.1.0/tests/test_design_playback.py +150 -0
  126. beqforge-0.1.0/tests/test_design_playback_headroom.py +251 -0
  127. beqforge-0.1.0/tests/test_design_publication.py +134 -0
  128. beqforge-0.1.0/tests/test_design_record.py +333 -0
  129. beqforge-0.1.0/tests/test_design_record_fingerprint.py +239 -0
  130. beqforge-0.1.0/tests/test_design_reference.py +269 -0
  131. beqforge-0.1.0/tests/test_design_references.py +147 -0
  132. beqforge-0.1.0/tests/test_design_rolloff.py +137 -0
  133. beqforge-0.1.0/tests/test_design_strategy_config.py +320 -0
  134. beqforge-0.1.0/tests/test_design_timings.py +67 -0
  135. beqforge-0.1.0/tests/test_design_verify.py +137 -0
  136. beqforge-0.1.0/tests/test_designer_server_startup.py +251 -0
  137. beqforge-0.1.0/tests/test_device_check_analyse.py +158 -0
  138. beqforge-0.1.0/tests/test_device_check_catalogue.py +84 -0
  139. beqforge-0.1.0/tests/test_device_check_catalogue_predict.py +97 -0
  140. beqforge-0.1.0/tests/test_device_check_cli.py +72 -0
  141. beqforge-0.1.0/tests/test_device_check_engines.py +208 -0
  142. beqforge-0.1.0/tests/test_device_check_evidence.py +77 -0
  143. beqforge-0.1.0/tests/test_device_check_examples.py +30 -0
  144. beqforge-0.1.0/tests/test_device_check_manifest.py +130 -0
  145. beqforge-0.1.0/tests/test_device_check_measurement.py +123 -0
  146. beqforge-0.1.0/tests/test_device_check_qualification.py +212 -0
  147. beqforge-0.1.0/tests/test_device_check_transactions.py +264 -0
  148. beqforge-0.1.0/tests/test_device_check_verify.py +92 -0
  149. beqforge-0.1.0/tests/test_extract_layout.py +179 -0
  150. beqforge-0.1.0/tests/test_optimiser.py +233 -0
  151. beqforge-0.1.0/tests/test_optimiser_cache.py +294 -0
  152. beqforge-0.1.0/tests/test_optimiser_report.py +160 -0
  153. beqforge-0.1.0/tests/test_package_boundaries.py +68 -0
  154. beqforge-0.1.0/tools/__init__.py +0 -0
  155. beqforge-0.1.0/tools/design_beq.py +499 -0
  156. beqforge-0.1.0/tools/designer_server.py +413 -0
  157. beqforge-0.1.0/tools/experiments/a1_sweep.py +307 -0
  158. beqforge-0.1.0/tools/experiments/compare_records.py +80 -0
  159. beqforge-0.1.0/tools/experiments/compare_verdicts.py +45 -0
  160. beqforge-0.1.0/tools/experiments/inject_variants.py +131 -0
  161. beqforge-0.1.0/tools/experiments/p14_compare.py +71 -0
  162. beqforge-0.1.0/tools/experiments/p14_jacobian.py +284 -0
  163. beqforge-0.1.0/tools/experiments/p14_run_pipeline.py +40 -0
  164. beqforge-0.1.0/tools/experiments/p14_surrogate.py +208 -0
  165. beqforge-0.1.0/tools/experiments/p18_compare_greedy.py +114 -0
  166. beqforge-0.1.0/tools/experiments/p18_compare_seeded.py +78 -0
  167. beqforge-0.1.0/tools/experiments/p18_compare_structure.py +73 -0
  168. beqforge-0.1.0/tools/experiments/p18_greedy.py +187 -0
  169. beqforge-0.1.0/tools/experiments/p18_seeded.py +139 -0
  170. beqforge-0.1.0/tools/experiments/p18_structure.py +86 -0
  171. beqforge-0.1.0/tools/experiments/p20_smooth_drift.py +97 -0
  172. beqforge-0.1.0/tools/experiments/probe.py +354 -0
  173. beqforge-0.1.0/tools/experiments/refit_probe.py +298 -0
  174. beqforge-0.1.0/tools/experiments/request_timing.py +229 -0
  175. beqforge-0.1.0/tools/experiments/score_injected.py +149 -0
  176. beqforge-0.1.0/tools/experiments/t8_floor_rules.py +106 -0
  177. beqforge-0.1.0/tools/extract.py +223 -0
  178. beqforge-0.1.0/tools/ledger_template.html +416 -0
  179. beqforge-0.1.0/tools/negative_corpus.py +192 -0
  180. beqforge-0.1.0/tools/optimiser_catalogue_report.py +550 -0
  181. beqforge-0.1.0/tools/prepare_device_check_helper.py +140 -0
  182. beqforge-0.1.0/tools/render_ledger.py +297 -0
  183. beqforge-0.1.0/tools/replay.py +109 -0
  184. beqforge-0.1.0/tools/seed_optimiser_cache.py +190 -0
  185. beqforge-0.1.0/tools/smoke_test_device_check.py +97 -0
  186. beqforge-0.1.0/tools/smoke_test_exe.py +281 -0
  187. beqforge-0.1.0/tools/smoke_test_install.py +163 -0
  188. beqforge-0.1.0/tools/summarise.py +124 -0
  189. beqforge-0.1.0/tools/validate_evidence.py +40 -0
  190. beqforge-0.1.0/uv.lock +981 -0
@@ -0,0 +1,10 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "github-actions"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
7
+ - package-ecosystem: "uv"
8
+ directory: "/"
9
+ schedule:
10
+ interval: "weekly"
@@ -0,0 +1,75 @@
1
+ name: Build device-check preview
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ push:
6
+ branches:
7
+ - '**'
8
+ pull_request:
9
+ paths:
10
+ - 'beqforge_device_check/**'
11
+ - 'beqforge-device-check.spec'
12
+ - 'tools/prepare_device_check_helper.py'
13
+ - 'tools/smoke_test_device_check.py'
14
+ - 'packaging/device-check/**'
15
+ - '.github/workflows/build-device-check.yml'
16
+ - 'pyproject.toml'
17
+ - 'uv.lock'
18
+
19
+ permissions:
20
+ contents: read
21
+
22
+ defaults:
23
+ run:
24
+ shell: bash
25
+
26
+ jobs:
27
+ build:
28
+ name: Preview (${{ matrix.target }})
29
+ runs-on: ${{ matrix.os }}
30
+ timeout-minutes: 30
31
+ strategy:
32
+ fail-fast: false
33
+ matrix:
34
+ include:
35
+ - os: ubuntu-22.04
36
+ target: linux-x86_64
37
+ executable: beqforge-device-check
38
+ - os: windows-2022
39
+ target: windows-x86_64
40
+ executable: beqforge-device-check.exe
41
+ - os: macos-15
42
+ target: macos-arm64
43
+ executable: beqforge-device-check
44
+ - os: macos-15-intel
45
+ target: macos-x86_64
46
+ executable: beqforge-device-check
47
+ steps:
48
+ - uses: actions/checkout@v7
49
+ - uses: astral-sh/setup-uv@v10.2.0
50
+ with:
51
+ enable-cache: true
52
+ - name: Install Linux audio and USB libraries
53
+ if: runner.os == 'Linux'
54
+ run: sudo apt-get update && sudo apt-get install -y libportaudio2 libusb-1.0-0
55
+ - name: Install locked measurement dependencies and pinned packager
56
+ run: |
57
+ uv sync --locked --extra device-check
58
+ uv pip install pyinstaller==6.22.3
59
+ - name: Prepare pinned native helper
60
+ run: uv run --extra device-check python tools/prepare_device_check_helper.py --target '${{ matrix.target }}' --out build/device-helper --cache build/helper-cache
61
+ - name: Diagnose folder build
62
+ env:
63
+ BEQFORGE_DEVICE_BUILD_MODE: onedir
64
+ run: |
65
+ uv run --extra device-check pyinstaller --clean --noconfirm --distpath dist/folder beqforge-device-check.spec
66
+ uv run --extra device-check python tools/smoke_test_device_check.py 'dist/folder/beqforge-device-check/${{ matrix.executable }}' --out 'build/folder test é'
67
+ - name: Build and verify single executable
68
+ run: |
69
+ uv run --extra device-check pyinstaller --clean --noconfirm --distpath dist/single beqforge-device-check.spec
70
+ uv run --extra device-check python tools/smoke_test_device_check.py 'dist/single/${{ matrix.executable }}' --out 'build/single test é' --package 'dist/preview-${{ matrix.target }}'
71
+ - uses: actions/upload-artifact@v7
72
+ with:
73
+ name: beqforge-device-check-preview-${{ matrix.target }}
74
+ path: dist/preview-${{ matrix.target }}
75
+ if-no-files-found: error
@@ -0,0 +1,172 @@
1
+ name: Build executable
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+ workflow_dispatch:
8
+
9
+ defaults:
10
+ run:
11
+ shell: bash
12
+
13
+ permissions:
14
+ contents: write # softprops/action-gh-release needs to create/attach to the release
15
+
16
+ jobs:
17
+ tests:
18
+ name: Release tests
19
+ uses: ./.github/workflows/tests.yml
20
+ permissions:
21
+ contents: read
22
+
23
+ package:
24
+ name: Build Python package
25
+ runs-on: ubuntu-latest
26
+ permissions:
27
+ contents: read
28
+ steps:
29
+ - uses: actions/checkout@v7
30
+ - uses: astral-sh/setup-uv@v10.2.0
31
+ with:
32
+ enable-cache: true
33
+ - name: Build wheel and source distribution
34
+ run: uv build --out-dir dist
35
+ - name: Check release version
36
+ if: startsWith(github.ref, 'refs/tags/')
37
+ env:
38
+ RELEASE_TAG: ${{ github.ref_name }}
39
+ run: |
40
+ uv run --no-project --python 3.13 python - <<'PY'
41
+ import email
42
+ import os
43
+ import pathlib
44
+ import zipfile
45
+
46
+ wheel, = pathlib.Path("dist").glob("*.whl")
47
+ with zipfile.ZipFile(wheel) as archive:
48
+ metadata, = (name for name in archive.namelist() if name.endswith(".dist-info/METADATA"))
49
+ version = email.message_from_bytes(archive.read(metadata))["Version"]
50
+ if os.environ["RELEASE_TAG"] != f"v{version}":
51
+ raise SystemExit(f"Release tag must be v{version}, matching the package version")
52
+ PY
53
+ - name: Validate package metadata
54
+ run: uvx twine check --strict dist/*
55
+ - name: Verify dependency profiles
56
+ run: |
57
+ for profile in base designer optimiser device-check all; do
58
+ uv run --no-project --python 3.13 python tools/smoke_test_install.py --wheel-dir dist --profile "$profile"
59
+ done
60
+ - name: Upload package distributions
61
+ uses: actions/upload-artifact@v7
62
+ with:
63
+ name: python-distributions
64
+ path: dist/*
65
+ if-no-files-found: error
66
+
67
+ create_release:
68
+ name: Create release
69
+ needs: [package, tests]
70
+ if: startsWith(github.ref, 'refs/tags/')
71
+ runs-on: ubuntu-latest
72
+ steps:
73
+ - uses: actions/checkout@v7
74
+ with:
75
+ fetch-depth: 0 # changelog-generator diffs against the previous tag
76
+
77
+ - name: Generate changelog
78
+ id: changelog
79
+ uses: metcalfc/changelog-generator@v5.0.1
80
+ with:
81
+ myToken: ${{ secrets.GITHUB_TOKEN }}
82
+
83
+ - name: Create release
84
+ uses: softprops/action-gh-release@v3
85
+ with:
86
+ body: ${{ steps.changelog.outputs.changelog }}
87
+ env:
88
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
89
+
90
+ build:
91
+ name: Build (${{ matrix.os }})
92
+ # Manual runs skip release creation, but still require tests and package validation.
93
+ needs: [create_release, package, tests]
94
+ if: >-
95
+ !cancelled() && needs.tests.result == 'success' && needs.package.result == 'success' &&
96
+ (needs.create_release.result == 'success' || needs.create_release.result == 'skipped')
97
+ runs-on: ${{ matrix.os }}
98
+ strategy:
99
+ fail-fast: false
100
+ matrix:
101
+ include:
102
+ - os: ubuntu-latest
103
+ asset_name: beqforge-linux-x86_64
104
+ built_path: dist/beqforge
105
+ - os: macos-latest
106
+ asset_name: beqforge-macos-x86_64
107
+ built_path: dist/beqforge
108
+ - os: windows-latest
109
+ asset_name: beqforge-windows-x86_64.exe
110
+ built_path: dist/beqforge.exe
111
+ steps:
112
+ - uses: actions/checkout@v7
113
+
114
+ - name: Install uv
115
+ uses: astral-sh/setup-uv@v10.2.0
116
+ with:
117
+ enable-cache: true
118
+
119
+ - name: Install dependencies
120
+ run: uv sync --locked --extra designer
121
+
122
+ - name: Install PyInstaller
123
+ run: uv pip install pyinstaller
124
+
125
+ - name: Build executable
126
+ run: uv run --extra designer pyinstaller --clean beqforge.spec
127
+
128
+ - name: Smoke-test the built executable
129
+ run: uv run --extra designer python tools/smoke_test_exe.py "${{ matrix.built_path }}"
130
+
131
+ - name: Rename artifact
132
+ run: cp "${{ matrix.built_path }}" "${{ matrix.asset_name }}"
133
+
134
+ - name: Upload workflow artifact
135
+ uses: actions/upload-artifact@v7
136
+ with:
137
+ name: ${{ matrix.asset_name }}
138
+ path: ${{ matrix.asset_name }}
139
+
140
+ - name: Attach to release
141
+ if: startsWith(github.ref, 'refs/tags/')
142
+ uses: softprops/action-gh-release@v3
143
+ with:
144
+ files: ${{ matrix.asset_name }}
145
+ env:
146
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
147
+
148
+ publish:
149
+ name: Publish Python package to PyPI
150
+ needs: [tests, package, build, create_release]
151
+ if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
152
+ runs-on: ubuntu-latest
153
+ environment:
154
+ name: pypi
155
+ url: https://pypi.org/project/beqforge/
156
+ permissions:
157
+ contents: write
158
+ id-token: write
159
+ steps:
160
+ - name: Download verified distributions
161
+ uses: actions/download-artifact@v8
162
+ with:
163
+ name: python-distributions
164
+ path: dist
165
+ - name: Attach distributions to release
166
+ uses: softprops/action-gh-release@v3
167
+ with:
168
+ files: dist/*
169
+ env:
170
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
171
+ - name: Publish distributions
172
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,23 @@
1
+ name: dependabot auto-merge
2
+ on: pull_request_target
3
+
4
+ permissions:
5
+ contents: write
6
+ pull-requests: write
7
+
8
+ jobs:
9
+ auto-merge:
10
+ if: github.actor == 'dependabot[bot]'
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Fetch dependabot metadata
14
+ id: metadata
15
+ uses: dependabot/fetch-metadata@v3
16
+ with:
17
+ github-token: "${{ secrets.GITHUB_TOKEN }}"
18
+ - name: Enable auto-merge for patch updates
19
+ if: steps.metadata.outputs.update-type == 'version-update:semver-patch'
20
+ run: gh pr merge --auto --squash "$PR_URL"
21
+ env:
22
+ PR_URL: ${{ github.event.pull_request.html_url }}
23
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,101 @@
1
+ name: Tests
2
+
3
+ # Fits already control their own process parallelism. Avoid multiplying each worker
4
+ # by a BLAS thread pool on the small hosted runners.
5
+ env:
6
+ OPENBLAS_NUM_THREADS: '1'
7
+ OMP_NUM_THREADS: '1'
8
+ MKL_NUM_THREADS: '1'
9
+ VECLIB_MAXIMUM_THREADS: '1'
10
+
11
+ on:
12
+ workflow_call:
13
+ push:
14
+ branches:
15
+ - '**'
16
+
17
+ jobs:
18
+ test:
19
+ name: Test (${{ matrix.os }})
20
+ runs-on: ${{ matrix.os }}
21
+ strategy:
22
+ fail-fast: false
23
+ matrix:
24
+ os: [ubuntu-latest, macos-latest, windows-latest]
25
+ steps:
26
+ - uses: actions/checkout@v7
27
+
28
+ # brew's and choco's default ffmpeg both lack the libsoxr resampler tools/extract.py
29
+ # prefers, unlike Ubuntu's apt package — but extract.py now detects that at runtime and
30
+ # falls back to ffmpeg's default resampler, so any ordinary ffmpeg install is fine here.
31
+ - name: Install ffmpeg (Linux)
32
+ if: runner.os == 'Linux'
33
+ run: |
34
+ if command -v ffmpeg >/dev/null && command -v ffprobe >/dev/null; then
35
+ exit 0
36
+ fi
37
+ # The Azure mirror took over eight minutes to download ffmpeg's
38
+ # dependencies on a hosted runner. Use Ubuntu's archive mirror.
39
+ sudo sed -i 's|http://azure.archive.ubuntu.com/ubuntu|http://archive.ubuntu.com/ubuntu|g' /etc/apt/apt-mirrors.txt
40
+ sudo apt-get update
41
+ sudo apt-get install -y --no-install-recommends ffmpeg
42
+
43
+ - name: Install ffmpeg (macOS)
44
+ if: runner.os == 'macOS'
45
+ run: brew install ffmpeg
46
+
47
+ - name: Install ffmpeg (Windows)
48
+ if: runner.os == 'Windows'
49
+ run: choco install ffmpeg -y
50
+
51
+ - name: Install uv
52
+ uses: astral-sh/setup-uv@v10.2.0
53
+ with:
54
+ enable-cache: true
55
+
56
+ - name: Install dependencies
57
+ run: uv sync --locked --all-groups --extra designer
58
+
59
+ # the device-check tests run in their own job below, in parallel, with the extra installed
60
+ - name: Run tests
61
+ run: uv run --extra designer pytest --durations=25 --ignore-glob='tests/test_device_check_*.py'
62
+
63
+ device-check:
64
+ name: Device check (${{ matrix.os }})
65
+ runs-on: ${{ matrix.os }}
66
+ strategy:
67
+ fail-fast: false
68
+ matrix:
69
+ os: [ubuntu-latest, macos-latest, windows-latest]
70
+ steps:
71
+ - uses: actions/checkout@v7
72
+
73
+ - name: Install uv
74
+ uses: astral-sh/setup-uv@v10.2.0
75
+ with:
76
+ enable-cache: true
77
+
78
+ # without the extra, most of these tests skip on importorskip('pyfar') rather than fail
79
+ - name: Install dependencies
80
+ run: uv sync --locked --all-groups --extra device-check
81
+
82
+ - name: Run device-check tests
83
+ shell: bash
84
+ run: uv run --extra device-check pytest --durations=25 tests/test_device_check_*.py
85
+
86
+ package-profiles:
87
+ name: Install profile (${{ matrix.profile }})
88
+ runs-on: ubuntu-latest
89
+ strategy:
90
+ fail-fast: false
91
+ matrix:
92
+ profile: [base, designer, optimiser, device-check, all]
93
+ steps:
94
+ - uses: actions/checkout@v7
95
+ - uses: astral-sh/setup-uv@v10.2.0
96
+ with:
97
+ enable-cache: true
98
+ - name: Build the single distribution
99
+ run: uv build --out-dir dist
100
+ - name: Verify isolated wheel installation and command
101
+ run: uv run --no-project --python 3.13 python tools/smoke_test_install.py --wheel-dir dist --profile '${{ matrix.profile }}'
@@ -0,0 +1,270 @@
1
+ ### JupyterNotebooks template
2
+ # gitignore template for Jupyter Notebooks
3
+ # website: http://jupyter.org/
4
+
5
+ .ipynb_checkpoints
6
+ */.ipynb_checkpoints/*
7
+
8
+ # IPython
9
+ profile_default/
10
+ ipython_config.py
11
+
12
+ # Remove previous ipynb_checkpoints
13
+ # git rm -r .ipynb_checkpoints/
14
+
15
+ ### Python template
16
+ # Byte-compiled / optimized / DLL files
17
+ __pycache__/
18
+ *.py[cod]
19
+ *$py.class
20
+
21
+ # C extensions
22
+ *.so
23
+
24
+ # Distribution / packaging
25
+ .Python
26
+ build/
27
+ develop-eggs/
28
+ dist/
29
+ downloads/
30
+ eggs/
31
+ .eggs/
32
+ lib/
33
+ lib64/
34
+ parts/
35
+ sdist/
36
+ var/
37
+ wheels/
38
+ share/python-wheels/
39
+ *.egg-info/
40
+ .installed.cfg
41
+ *.egg
42
+ MANIFEST
43
+
44
+ # PyInstaller
45
+ # Usually these files are written by a python script from a template
46
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
47
+ *.manifest
48
+ *.spec
49
+ !/beqforge.spec
50
+
51
+ # Installer logs
52
+ pip-log.txt
53
+ pip-delete-this-directory.txt
54
+
55
+ # Unit test / coverage reports
56
+ htmlcov/
57
+ .tox/
58
+ .nox/
59
+ .coverage
60
+ .coverage.*
61
+ .cache
62
+ nosetests.xml
63
+ coverage.xml
64
+ *.cover
65
+ *.py,cover
66
+ .hypothesis/
67
+ .pytest_cache/
68
+ cover/
69
+
70
+ # Translations
71
+ *.mo
72
+ *.pot
73
+
74
+ # Django stuff:
75
+ *.log
76
+ local_settings.py
77
+ db.sqlite3
78
+ db.sqlite3-journal
79
+
80
+ # Flask stuff:
81
+ instance/
82
+ .webassets-cache
83
+
84
+ # Scrapy stuff:
85
+ .scrapy
86
+
87
+ # Sphinx documentation
88
+ docs/_build/
89
+
90
+ # PyBuilder
91
+ .pybuilder/
92
+ target/
93
+
94
+ # Jupyter Notebook
95
+
96
+ # IPython
97
+
98
+ # pyenv
99
+ # For a library or package, you might want to ignore these files since the code is
100
+ # intended to run in multiple environments; otherwise, check them in:
101
+ # .python-version
102
+
103
+ # pipenv
104
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
105
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
106
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
107
+ # install all needed dependencies.
108
+ #Pipfile.lock
109
+
110
+ # poetry
111
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
112
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
113
+ # commonly ignored for libraries.
114
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
115
+ #poetry.lock
116
+
117
+ # pdm
118
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
119
+ #pdm.lock
120
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
121
+ # in version control.
122
+ # https://pdm.fming.dev/latest/usage/project/#working-with-version-control
123
+ .pdm.toml
124
+ .pdm-python
125
+ .pdm-build/
126
+
127
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
128
+ __pypackages__/
129
+
130
+ # Celery stuff
131
+ celerybeat-schedule
132
+ celerybeat.pid
133
+
134
+ # SageMath parsed files
135
+ *.sage.py
136
+
137
+ # Environments
138
+ .env
139
+ .venv
140
+ env/
141
+ venv/
142
+ ENV/
143
+ env.bak/
144
+ venv.bak/
145
+
146
+ # Spyder project settings
147
+ .spyderproject
148
+ .spyproject
149
+
150
+ # Rope project settings
151
+ .ropeproject
152
+
153
+ # mkdocs documentation
154
+ /site
155
+
156
+ # mypy
157
+ .mypy_cache/
158
+ .dmypy.json
159
+ dmypy.json
160
+
161
+ # Pyre type checker
162
+ .pyre/
163
+
164
+ # pytype static type analyzer
165
+ .pytype/
166
+
167
+ # Cython debug symbols
168
+ cython_debug/
169
+
170
+ # Covers JetBrains IDEs: IntelliJ, GoLand, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
171
+ # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
172
+
173
+ # User-specific stuff
174
+ .idea/**/workspace.xml
175
+ .idea/**/tasks.xml
176
+ .idea/**/usage.statistics.xml
177
+ .idea/**/dictionaries
178
+ .idea/**/shelf
179
+
180
+ # AWS User-specific
181
+ .idea/**/aws.xml
182
+
183
+ # Generated files
184
+ .idea/**/contentModel.xml
185
+
186
+ # Sensitive or high-churn files
187
+ .idea/**/dataSources/
188
+ .idea/**/dataSources.ids
189
+ .idea/**/dataSources.local.xml
190
+ .idea/**/sqlDataSources.xml
191
+ .idea/**/dynamic.xml
192
+ .idea/**/uiDesigner.xml
193
+ .idea/**/dbnavigator.xml
194
+
195
+ # Gradle
196
+ .idea/**/gradle.xml
197
+ .idea/**/libraries
198
+
199
+ # Gradle and Maven with auto-import
200
+ # When using Gradle or Maven with auto-import, you should exclude module files,
201
+ # since they will be recreated, and may cause churn. Uncomment if using
202
+ # auto-import.
203
+ # .idea/artifacts
204
+ # .idea/compiler.xml
205
+ # .idea/jarRepositories.xml
206
+ # .idea/modules.xml
207
+ # .idea/*.iml
208
+ # .idea/modules
209
+ # *.iml
210
+ # *.ipr
211
+
212
+ # CMake
213
+ cmake-build-*/
214
+
215
+ # Mongo Explorer plugin
216
+ .idea/**/mongoSettings.xml
217
+
218
+ # File-based project format
219
+ *.iws
220
+
221
+ # IntelliJ
222
+ out/
223
+
224
+ # mpeltonen/sbt-idea plugin
225
+ .idea_modules/
226
+
227
+ # JIRA plugin
228
+ atlassian-ide-plugin.xml
229
+
230
+ # Cursive Clojure plugin
231
+ .idea/replstate.xml
232
+
233
+ # SonarLint plugin
234
+ .idea/sonarlint/
235
+ # see https://community.sonarsource.com/t/is-the-file-idea-idea-idea-sonarlint-xml-intended-to-be-under-source-control/121119
236
+ .idea/sonarlint.xml
237
+
238
+ # Crashlytics plugin (for Android Studio and IntelliJ)
239
+ com_crashlytics_export_strings.xml
240
+ crashlytics.properties
241
+ crashlytics-build.properties
242
+ fabric.properties
243
+
244
+ # Editor-based HTTP Client
245
+ .idea/httpRequests
246
+ http-client.private.env.json
247
+
248
+ # Android studio 3.1+ serialized cache file
249
+ .idea/caches/build_file_checksums.ser
250
+
251
+ # Apifox Helper cache
252
+ .idea/.cache/.Apifox_Helper
253
+ .idea/ApifoxUploaderProjectSetting.xml
254
+
255
+ # Github Copilot persisted session migrations, see: https://github.com/microsoft/copilot-intellij-feedback/issues/712#issuecomment-3322062215
256
+ .idea/**/copilot.data.migration.*.xml
257
+
258
+ data/
259
+ !beqoptimiser/data/
260
+ !beqoptimiser/data/seed.json.gz
261
+ !beqoptimiser/data/seed-manifest.json
262
+
263
+ # generated debug charts (PNGs, regenerated per run)
264
+ charts/
265
+
266
+ # generated output — .beq exports, the correction ledger, anything under --out/--charts-dir
267
+ out/
268
+
269
+ # Dedicated, reviewed F2 packaging recipe
270
+ !/beqforge-device-check.spec
@@ -0,0 +1,10 @@
1
+ # Default ignored files
2
+ /shelf/
3
+ /workspace.xml
4
+ # Editor-based HTTP Client requests
5
+ /httpRequests/
6
+ # Ignored default folder with query files
7
+ /queries/
8
+ # Datasource local storage ignored files
9
+ /dataSources/
10
+ /dataSources.local.xml
@@ -0,0 +1,11 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="JAVA_MODULE" version="4">
3
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
4
+ <exclude-output />
5
+ <content url="file://$MODULE_DIR$">
6
+ <excludeFolder url="file://$MODULE_DIR$/.venv" />
7
+ </content>
8
+ <orderEntry type="inheritedJdk" />
9
+ <orderEntry type="sourceFolder" forTests="false" />
10
+ </component>
11
+ </module>