Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,29 @@ jobs:

- run: npm ci

# The wasm-pack output (crates/solver/pkg/) is build-only and gitignored,
# so it must be built here before typecheck/test/build consume it. This is
# the single source of truth for the WASM binding surface — building it in
# CI is what prevents the binary from silently drifting from the Rust
# source (the previous, committed-and-stale failure mode).
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable (2026-04-15)
with:
targets: wasm32-unknown-unknown

- name: Cache Rust dependencies
uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
with:
workspaces: 'crates/solver -> target'

- name: Install wasm-pack
uses: taiki-e/install-action@e49978b799e49ff429d162b7a30601a569ab6538 # v2.81.1
with:
tool: wasm-pack@0.13.1

- name: Build WASM
run: npm run build:wasm

- name: Cache build artifacts
uses: actions/cache@v5
with:
Expand Down
19 changes: 19 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,25 @@ jobs:

- run: npm ci

# pkg/ is build-only/gitignored — build it before typecheck/test consume it.
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable (2026-04-15)
with:
targets: wasm32-unknown-unknown

- name: Cache Rust dependencies
uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
with:
workspaces: 'crates/solver -> target'

- name: Install wasm-pack
uses: taiki-e/install-action@e49978b799e49ff429d162b7a30601a569ab6538 # v2.81.1
with:
tool: wasm-pack@0.13.1

- name: Build WASM
run: npm run build:wasm

- name: Format check
run: npm run format:check

Expand Down
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,14 @@ apps/*/dist/
packages/*/dist/
*.tsbuildinfo
.vite/
crates/solver/target/
# Rust build output and wasm-pack artifacts are build-only — never committed.
# (`crates/*/target` covers solver and any future crate; `pkg/` is the
# wasm-pack output, rebuilt by scripts/ensure-wasm.mjs.)
crates/*/target/
crates/*/pkg/
test/
.test_data/
.playwright-mcp/
.env
.env.local
.claude/
Expand Down
21 changes: 21 additions & 0 deletions apps/cadecon/src/lib/algorithm-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@ const [lpFilterEnabled, setLpFilterEnabled] = createSignal(false);
const [maxIterations, setMaxIterations] = createSignal(20);
const [convergenceTol, setConvergenceTol] = createSignal(0.01);

// Inner-loop solver parameters. These directly affect deconvolution output, so
// they are configurable (not hardcoded) and travel with the run; defaults match
// the previously hardcoded values. Per-trace FISTA:
const [traceFistaMaxIters, setTraceFistaMaxIters] = createSignal(500);
const [traceFistaTol, setTraceFistaTol] = createSignal(1e-4);
// Per-subset free-form kernel estimation FISTA:
const [kernelFistaMaxIters, setKernelFistaMaxIters] = createSignal(200);
const [kernelFistaTol, setKernelFistaTol] = createSignal(1e-4);
// TV-L1 smoothness penalty for kernel estimation (0 = no smoothness):
const [kernelSmoothLambda, setKernelSmoothLambda] = createSignal(0);

// --- Derived ---

const upsampleFactor = createMemo(() => {
Expand All @@ -28,5 +39,15 @@ export {
setMaxIterations,
convergenceTol,
setConvergenceTol,
traceFistaMaxIters,
setTraceFistaMaxIters,
traceFistaTol,
setTraceFistaTol,
kernelFistaMaxIters,
setKernelFistaMaxIters,
kernelFistaTol,
setKernelFistaTol,
kernelSmoothLambda,
setKernelSmoothLambda,
upsampleFactor,
};
7 changes: 6 additions & 1 deletion apps/cadecon/src/lib/community/cadecon-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
import { createSubmissionService } from '@calab/community';
import type { CadeconSubmission } from './types.ts';

const service = createSubmissionService<CadeconSubmission>('cadecon_submissions');
// Reads go through the PII-free public view (migration 010); writes/deletes
// target the base table under owner-scoped RLS.
const service = createSubmissionService<CadeconSubmission>(
'cadecon_submissions',
'cadecon_submissions_public',
);

export const submitParameters = service.submit;
export const fetchSubmissions = service.fetch;
Expand Down
31 changes: 15 additions & 16 deletions apps/cadecon/src/lib/iteration-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ import {
convergenceTol,
hpFilterEnabled,
lpFilterEnabled,
traceFistaMaxIters,
traceFistaTol,
kernelFistaMaxIters,
kernelFistaTol,
kernelSmoothLambda,
} from './algorithm-store.ts';
import {
parsedData,
Expand All @@ -54,15 +59,9 @@ import { dataIndex } from './data-utils.ts';
import { median } from './math-utils.ts';
import { reconvolveAR2 } from './reconvolve.ts';

/** Per-trace FISTA solver parameters (shared between subset and finalization passes). */
const TRACE_FISTA_MAX_ITERS = 500;
const TRACE_FISTA_TOL = 1e-4;

/** Per-subset kernel estimation solver parameters. */
const KERNEL_FISTA_MAX_ITERS = 200;
const KERNEL_FISTA_TOL = 1e-4;
/** TV-L1 smoothness penalty for free-form kernel estimation. */
const KERNEL_SMOOTH_LAMBDA = 0;
// Per-trace and per-kernel FISTA solver parameters are configurable via
// algorithm-store (traceFistaMaxIters/Tol, kernelFistaMaxIters/Tol,
// kernelSmoothLambda) so they are overridable and recorded with the run.
/** Number of early free-kernel samples to skip in bi-exponential fitting. */
export const BIEXP_FIT_SKIP = 0;

Expand Down Expand Up @@ -269,10 +268,10 @@ function dispatchKernelJobs(
baselines,
kernelLength,
fs,
maxIters: KERNEL_FISTA_MAX_ITERS,
tol: KERNEL_FISTA_TOL,
maxIters: kernelFistaMaxIters(),
tol: kernelFistaTol(),
refine: true,
smoothLambda: KERNEL_SMOOTH_LAMBDA,
smoothLambda: kernelSmoothLambda(),
biexpSkip: BIEXP_FIT_SKIP,
warmKernel,
warmBiexp,
Expand Down Expand Up @@ -512,8 +511,8 @@ export async function startRun(): Promise<void> {
tauD,
fs,
upFactor,
TRACE_FISTA_MAX_ITERS,
TRACE_FISTA_TOL,
traceFistaMaxIters(),
traceFistaTol(),
hpOn,
lpOn,
sparsityLambda,
Expand Down Expand Up @@ -793,8 +792,8 @@ export async function startRun(): Promise<void> {
tauDecay: tauD,
fs,
upsampleFactor: upFactor,
maxIters: TRACE_FISTA_MAX_ITERS,
tol: TRACE_FISTA_TOL,
maxIters: traceFistaMaxIters(),
tol: traceFistaTol(),
hpEnabled: hpOn,
lpEnabled: lpOn,
lambda: sparsityLambda,
Expand Down
7 changes: 6 additions & 1 deletion apps/catune/src/lib/community/catune-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
import { createSubmissionService } from '@calab/community';
import type { CatuneSubmission } from './types.ts';

const service = createSubmissionService<CatuneSubmission>('catune_submissions');
// Reads go through the PII-free public view (migration 010); writes/deletes
// target the base table under owner-scoped RLS.
const service = createSubmissionService<CatuneSubmission>(
'catune_submissions',
'catune_submissions_public',
);

export const submitParameters = service.submit;
export const fetchSubmissions = service.fetch;
Expand Down
98 changes: 0 additions & 98 deletions crates/solver/pkg/README.md

This file was deleted.

Loading
Loading