43 Commits
Author SHA1 Message Date
Dylan M. Taylor bc6eaa65d8 ci(sonar): don't cancel superseded runs on main, so coverage is published (#2249) 2026-10-23 17:00:24 -04:00
Dylan M. Taylor 357b4c5bd5 security: move the release workflow's write permission to the job level (SonarCloud githubactions:S8233) (#2241)
* security: move the release workflow's write permission to the job level (SonarCloud githubactions:S8233)

* release: the git-sources gate moves into craft-common-actions (storytold/craft-common-actions#78)

The check is shared at release.yml@main now; keep only the reusable call.
2026-10-23 15:14:34 -04:00
Dylan M. Taylor f6ef1a7906 Use chrono instead of hand-rolled UTC conversion (#2023)
* Use chrono for UTC/calendar conversion instead of hand-rolled copies

Replaces the hand-rolled civil_from_days / days_from_civil copies (log
timestamp, ISO metadata dates, Align Video to Data timestamp parsing, the
Numbers effect's date, the Home and Render Queue date columns, and the
benchmark report date) with chrono as a workspace dependency. Output formats
are unchanged and pinned by the existing tests. AGENTS.md now says time goes
through chrono.

Follow-up to storytold/cadcraft#1785

* Keep 5-digit years unprefixed; derive Numbers weekday from the same date

chrono's %Y writes a '+' before years past 9999, where the old code wrote
{y:04}. timestamp, iso_date, format_utc, utc_stamp and xtask's utc now write
the year with {:04} again and let chrono format the rest, so a far-future
clock keeps the plain zero-padded year.

date_from_days took its weekday from the raw input modulo while the
year/month/day fell back to the epoch for day counts outside chrono's range,
so an unrepresentable count printed a fallback date paired with the input's
weekday. The weekday now comes from the same resolved date, so both agree.

Tests cover the year-10000 timestamp and the out-of-range Numbers date.

* Keep the whole date in format_ago for five-digit years

format_ago cut format_utc to 10 bytes, so a year past 9999 lost its last
digit (10000-01-0). Take the date up to the space instead. Tested.

* Keep Numbers dates exact past chrono's range

date_from_days converted the day count by building a Unix timestamp and
calling DateTime::from_timestamp, which falls back to the epoch (and so
reads 1970-01-01, a Thursday) once the date leaves chrono's NaiveDate
range near year ±262143. Numbers' `value` slider is a plain scalar with
no range guard, so a keyframed count reaches that: Long Date of
100_000_000 showed "Thursday, January 1, 1970" instead of the real
"Monday, September 13, 275790" -- exactly the plausible unrelated-date
fallback the review rejects, and the derived weekday matched the stand-in
date, not the input.

Route it through the 400-year Gregorian cycle like pdfcraft 9d4cb3ca:
chrono converts the day within one cycle (num_days_from_ce of the rebased
rest, always in range) and the whole cycles are added back as years, in
i128 so i64::MIN/MAX can't overflow. chrono stays the only calendar
logic. The weekday still comes from the resolved date, so it always
agrees with it.

Tested: date_from_days_past_chrono_range pins the pre-chrono dates and
weekdays at/over chrono's bound on both sides of the 2000-01-01 epoch
(and that the extremes don't overflow); numbers_formats adds the same
through the public numbers_text entry (Long/Short Date). cargo test
-p effectcraft-effects, fmt --check and clippy -D warnings all clean.

* time: preserve out-of-range years instead of the epoch

`DateTime::from_timestamp(..).unwrap_or_default()` changed the existing output:
inputs the old hand-rolled civil-from-days converted (e.g. `10_000_000_000_000`
s → 318857-05-20 17:46:40) collapsed to the epoch. Restore the old conversion
domain with a cycle-based helper: reduce by whole 400-year Gregorian cycles
(146_097 days), convert the in-range remainder with chrono, and carry the year
back as i128 (saturating to the output type). Only the year leaves chrono's
range; month, day and time of day stay exact. chrono remains the only calendar
logic (NaiveDate::from_num_days_from_ce_opt); no new features.

Sites (UTC):
- crates/engine logging.rs `timestamp` (u64 ms): far-future clock keeps its year.
  10e12 s → "318857-05-20T17:46:40.000Z", u64::MAX ms → "584556019-04-03T14:25:51.615Z"
  (was "1970-01-01...").
- crates/engine media_browser.rs `iso_date` (u64): 10e12 s → "318857-05-20T17:46:40Z",
  u64::MAX → "584554051223-11-09T07:00:15Z".
- crates/ui-egui panels/home.rs `format_utc` (i64): 10e12 → "318857-05-20 17:46",
  i64::MIN → "-292277022657-01-27 08:29".
- crates/ui-egui panels/render_queue.rs `utc_stamp` (u64): 10e12 → "318857-05-20
  17:46:40", u64::MAX → "584554051223-11-09 07:00:15".
- xtask bench.rs `utc` (u64): 10e12 → "318857-05-20 17:46 UTC", u64::MAX →
  "584554051223-11-09 07:00 UTC"; added a test.

* Name the 400-year range extension as the one exception to the time rule

The rule said never to hand-roll calendar math, but the range fix
(shifting by whole 400-year Gregorian cycles so dates past chrono's year
range keep their old output) is cycle arithmetic, so the rule and the code
disagreed. The rule now names that exception: the library still computes
month, day and time, and only whole cycles are carried in the year.

* Say the library computes month and day; time-of-day is plain arithmetic

Narrows the range-extension wording: the date library computes the
calendar fields, and splitting seconds into hours, minutes and seconds
is ordinary arithmetic, which is what the code does.
2026-10-23 11:29:09 -04:00
Dylan M. Taylor 49d179738b packaging: use [[ tests, named locals and explicit returns (SonarCloud S7688/S7679/S7682) (#2187)
Switch the bash packaging scripts from [ to [[ for conditional tests,
give positional parameters descriptive local names, and end the shared
env.sh helpers with an explicit return. No behaviour change: every
comparison is against a literal, and a bare return keeps the last
command's status.
2026-10-23 11:17:22 -04:00
Dylan M. Taylor bd3ae8ab14 xtask: use unique temporary directories for bench tests (#2196) 2026-10-23 11:17:15 -04:00
Dylan M. Taylor dd325c7ab8 segment: bound checkpoint tensors and pickle work (#2192)
* segment: bound checkpoint tensors and pickle work

* segment: bound entry size, memo clones, and total tensor elements

* segment: cap cumulative decompressed storage bytes
2026-10-23 10:44:42 -04:00
Dylan M. Taylor 250b34174e Merge pull request #2218 from dylanmtaylor/sonar/checker-stat
fix: suppress the stat check's taint finding (SonarCloud)
2026-10-23 10:35:56 -04:00
Dylan M. Taylor 0c8d47f42a fix: suppress the stat check's taint finding (SonarCloud)
The stat is the validation that rejects anything but an existing regular
file; annotate it with that reasoning.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
2026-10-23 10:28:48 -04:00
Dylan M. Taylor 9b735dc687 Merge pull request #2217 from dylanmtaylor/sonar/checker-path-safety
fix: document the AE checker's operator-supplied CLI path (SonarCloud)
2026-10-23 10:18:29 -04:00
Dylan M. Taylor c75071dfb8 fix: document the AE checker's operator-supplied CLI path (SonarCloud)
The path is the developer's own CLI build, stat'ed as a regular file before
use; suppress the taint finding with that reasoning.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
2026-10-23 10:10:47 -04:00
Dylan M. Taylor 16c30830ef Merge pull request #2215 from dylanmtaylor/sonar/nosonar-placement
fix: put the NOSONAR marker on the spawnSync line (SonarCloud follow-up)
2026-10-23 09:53:46 -04:00
Dylan M. Taylor 400fbb79e9 fix: put the NOSONAR marker on the spawnSync line (SonarCloud)
Sonar applies NOSONAR to the line that carries the marker, so the
explanation above the call did not suppress anything.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
2026-10-23 09:44:38 -04:00
Dylan M. Taylor 9066b64150 Merge pull request #2214 from dylanmtaylor/sonar/security-reliability
fix: validate the CLI path in the AE ease checker (SonarCloud jssecurity:S8705)
2026-10-23 09:37:45 -04:00
Dylan M. Taylor d1d9849e2d fix: validate the CLI path in the AE ease checker (SonarCloud)
Resolve the argument and require a regular file before spawnSync, which
never uses a shell and only runs fixed binaries or that validated path.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
2026-10-23 09:29:39 -04:00
Dylan M. Taylor 23f11ab7cf expr: bound rewrite expansion and preserve assignment targets (#2195)
* expr: bound rewrite expansion and preserve assignment targets

* expr: bound rewritten output size and rewrite computed assignment targets
2026-10-23 09:14:49 -04:00
Dylan M. Taylor 09b9ebca34 roto: bound frozen matte decoding and serialization (#2194)
* roto: bound frozen matte decoding and serialization

* roto: address review (fallible RLE growth, pre-check plane bytes, saturate 32-bit limits)
2026-10-23 08:59:06 -04:00
Dylan M. Taylor 8a4ed77c4a pdf: bound image sample and mask allocations (#2191)
* pdf: bound image sample and mask allocations

* pdf: fallible mask allocations and JPEG header pixel cap
2026-10-23 08:56:15 -04:00
Dylan M. Taylor ca8043cbba text: bound layout and variable font metadata (#2193)
* text: bound layout and variable font metadata

* text: address review (intern once, f64 prefix sums, bounded item search, name fallback, consistent variation fallback)
2026-10-23 08:55:07 -04:00
Dylan M. Taylor 4b48482e8f ui: bound queued synthetic input gestures (#2197)
* ui: bound queued synthetic input gestures

* ui: reserve exact click event count
2026-10-23 08:45:10 -04:00
Dylan M. Taylor 2cf90507f3 svg: bound raster surfaces and handle duplicate gradient stops (#2190) 2026-10-23 08:38:10 -04:00
Dylan M. Taylor 0871135a6b Merge pull request #2062 from storytold/sonar-fix/js-css-reliability
fix: JS reliability bugs (SonarCloud S1764/S9383/S4275)
2026-10-22 19:27:57 -04:00
Dylan M. Taylor 645b683a77 Merge pull request #2061 from storytold/sonar-fix/js-csprng
security: use crypto.randomUUID for temp file suffix (SonarCloud S2245)
2026-10-22 19:27:53 -04:00
Dylan M. Taylor ec0cc83a29 fix(web): fall back to network when caches.open fails in service worker 2026-10-22 19:19:20 -04:00
Dylan M. Taylor 6871aa2236 security: check crypto.randomUUID availability in canMove 2026-10-22 19:19:19 -04:00
Dylan M. Taylor f37f20ffd0 Merge pull request #2059 from storytold/sonar-fix/enforce-https
security: enforce HTTPS on curl downloads (SonarCloud S6506)
2026-10-21 20:13:41 -04:00
Dylan M. Taylor 7983396692 fix: JS reliability bugs (SonarCloud S1764, S9383, S4275)
- scriptui.js: replace the self-comparison NaN check (o.max === o.max) with
  the explicit Number.isNaN(o.max) (S1764).
- sw.js: mark the fire-and-forget cache.put() with void and a .catch() so the
  promise rejection is handled (S9383).
- prelude.js: return __err(...) from the activeCamera getter so every path
  yields a value (S4275); __err always throws, so behavior is unchanged.
2026-10-21 17:20:35 -04:00
Dylan M. Taylor 887fe3a3a8 security: use crypto.randomUUID for temp file suffix (SonarCloud S2245)
Replace Math.random() with crypto.randomUUID() when generating the unique
suffix for the atomic write-then-move temp file. The value isn't security-
sensitive, but a CSPRNG gives a stronger uniqueness guarantee and resolves
SonarCloud javascript:S2245.
2026-10-21 17:14:27 -04:00
Dylan M. Taylor 5003351186 security: enforce HTTPS on curl downloads (SonarCloud S6506)
Add --proto '=https' to curl invocations so redirects cannot downgrade to
plaintext HTTP. Resolves SonarCloud S6506 (shell/docker/githubactions).
2026-10-21 17:06:49 -04:00
Dylan M. Taylor cee4c16c8a ci: add sonar-project.properties for CI-based analysis
Marks the project ineligible for SonarCloud Automatic Analysis, resolving the
CI-vs-automatic-analysis conflict so the SonarCloud workflow succeeds.
2026-10-21 16:00:34 -04:00
Dylan M. Taylor 714b6c29b0 ci: add SonarCloud scan via shared reusable workflow
Calls storytold/craft-common-actions/.github/workflows/sonarcloud.yml@main
with secrets: inherit. Adds SonarCloud badge to README where missing and
removes the redundant sonar-project.properties (config now passed by the
reusable workflow).
2026-10-21 15:46:55 -04:00
Dylan M. Taylor ec2d51a17a ci: add SonarCloud scan workflow and config 2026-10-21 13:55:18 -04:00
Dylan M. Taylor 4fdbc07ea5 Merge pull request #1773 from dylanmtaylor/chore/drop-competitor-references
docs: drop references to competing commercial software
2026-10-20 11:34:59 -04:00
Dylan M. Taylor 12feed5fb3 Merge pull request #1803 from dylanmtaylor/docs/add-sonar-coderabbit-badges
docs: add SonarCloud and CodeRabbit badges to README
2026-10-20 11:32:35 -04:00
Dylan M. Taylor 75fce6b2d8 docs: put SonarCloud and CodeRabbit badges on their own line 2026-10-18 14:47:37 -04:00
Dylan M. Taylor ef74d82902 ci: configure Dependabot for Cargo and GitHub Actions
Co-authored-by: Dylan M. Taylor <dylan@dylanmtaylor.com>
2026-10-18 12:31:27 -06:00
Dylan M. Taylor 20c03451c0 docs: describe color grading panel, scope SDK plug-in warning, qualify rendering tests, and link parity checklist 2026-10-18 12:51:59 -04:00
Dylan M. Taylor 99bdcde092 docs: add SonarCloud and CodeRabbit badges to README 2026-10-18 11:01:31 -04:00
Dylan M. Taylor cb70a0cdbe docs: replace Lumetri effect reference with generic color grading 2026-10-18 10:42:59 -04:00
Dylan M. Taylor c7d8824e09 docs: drop references to competing commercial software 2026-10-18 10:42:22 -04:00
Dylan M. Taylor 261c54d854 ci: switch to shared nix workflow from craft-common-actions 2026-10-15 23:57:34 -04:00
Dylan M. Taylor 6c45fec27d ci: add nix check workflow 2026-10-15 21:17:07 -04:00
Dylan M. Taylor 67434e9038 ci: refactor workflows to use storytold/craft-common-actions (#801)
* ci: refactor workflows to use reusable artcraft-common-actions

* ci: point reusable workflows to storytold/craft-common-actions

* ci: pin storytold/craft-common-actions to commit 27a978f and pass secrets explicitly

* ci: use @main (unpinned) for craft-common-actions with explanation comment
2026-10-11 11:51:43 -04:00
Dylan M. Taylor 675fc55303 chore: bump github actions to fix Node 20 deprecation warnings 2026-10-09 20:08:26 -04:00