Skip to content

Commit f9d1eab

Browse files
committed
Initial commit
0 parents  commit f9d1eab

2,225 files changed

Lines changed: 232180 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.editorconfig

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
end_of_line = lf
6+
insert_final_newline = true
7+
trim_trailing_whitespace = true
8+
indent_style = space
9+
indent_size = 2
10+
11+
[*.{rs,toml}]
12+
indent_size = 4
13+
14+
[Makefile]
15+
indent_style = tab
16+
17+
[*.md]
18+
trim_trailing_whitespace = false

.gitattributes

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Catetus .gitattributes
2+
#
3+
# Local-only directives. These flags do NOT prevent `git push` — that
4+
# protection requires a pre-push hook (see
5+
# experiments/partnership-docs-audit/AUDIT.md §6 item 6). They:
6+
# - exclude these paths from `git archive` tarballs (export-ignore)
7+
# - mark them as documentation/strategy for linguist & language stats
8+
# - serve as a human-readable signal that these paths are pre-decisional
9+
#
10+
# docs/standards-outreach/** — pre-decisional outreach drafts, NEVER push to
11+
# public remotes until operator has explicitly authorized each file.
12+
docs/standards-outreach/** export-ignore linguist-documentation
13+
docs/standards-outreach/*.md export-ignore linguist-documentation
14+
15+
# Same handling for any future re-creation of docs/partnerships/ (the
16+
# original was removed in commit c003011 but the path is reserved so
17+
# accidental re-add carries the same protections).
18+
docs/partnerships/** export-ignore linguist-documentation
19+
docs/partnerships/*.md export-ignore linguist-documentation

.githooks/pre-push

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
#!/usr/bin/env bash
2+
# Catetus pre-push guard: block partnership/standards-outreach docs from
3+
# being pushed.
4+
#
5+
# Background: 2026-05-15 leak — docs/partnerships/{adobe-spz-memo,contact-map,
6+
# outreach-sequence}.md and docs/standards-outreach/{khronos-issue,
7+
# openusd-forum-post}.md were pushed to the public test-hero-fast branch
8+
# for ~4 days, leading to Khronos issue #2580 being closed citing the leaked
9+
# outreach doc as evidence the submission was premature.
10+
#
11+
# This hook reads the list of ref updates from stdin (git's pre-push protocol)
12+
# and, for each update, compares the new SHA against the remote SHA. Any added
13+
# or modified path under docs/partnerships/ or docs/standards-outreach/ aborts
14+
# the push.
15+
#
16+
# Override: CATETUS_PARTNERSHIP_OVERRIDE=1 git push ...
17+
# (Use ONLY for legitimate cases like deleting a leaked file from history.
18+
# An audit line is written to stderr when override fires.)
19+
#
20+
# Design notes:
21+
# - FAST: only runs `git diff --name-only` once per ref update.
22+
# - FAIL-OPEN on diff machinery errors (we don't want to block legit work
23+
# if the repo is in a weird state — CI is the belt-and-suspenders).
24+
# - First-push: when the remote SHA is all-zeros, we diff against
25+
# origin/HEAD (or origin/main / origin/master as fallback) to avoid
26+
# diffing the entire branch history against /dev/null.
27+
28+
set -u
29+
30+
remote="${1:-origin}"
31+
# shellcheck disable=SC2034 # url passed by git, unused
32+
url="${2:-}"
33+
34+
PROTECTED_PATTERN='^docs/(partnerships|standards-outreach)/'
35+
ZERO='0000000000000000000000000000000000000000'
36+
37+
# Fast bail-out: not pushing? nothing to do.
38+
if [ -t 0 ]; then
39+
exit 0
40+
fi
41+
42+
# Resolve a fallback base ref for first-push case.
43+
fallback_base=""
44+
for candidate in "${remote}/HEAD" "${remote}/main" "${remote}/master"; do
45+
if git rev-parse --verify --quiet "${candidate}" >/dev/null 2>&1; then
46+
fallback_base="${candidate}"
47+
break
48+
fi
49+
done
50+
51+
violations=""
52+
while read -r local_ref local_sha remote_ref remote_sha; do
53+
# Branch deletion: local_sha is zeros, nothing to check.
54+
if [ "${local_sha}" = "${ZERO}" ]; then
55+
continue
56+
fi
57+
58+
# Determine the diff range.
59+
if [ "${remote_sha}" = "${ZERO}" ]; then
60+
# First push of this branch. Diff against fallback base if available;
61+
# otherwise diff against the empty tree (covers the no-fallback case
62+
# without erroring out).
63+
if [ -n "${fallback_base}" ]; then
64+
range="${fallback_base}..${local_sha}"
65+
else
66+
# Empty tree SHA — every file becomes "added".
67+
empty_tree="$(git hash-object -t tree /dev/null 2>/dev/null || echo '4b825dc642cb6eb9a060e54bf8d69288fbee4904')"
68+
range="${empty_tree}..${local_sha}"
69+
fi
70+
else
71+
range="${remote_sha}..${local_sha}"
72+
fi
73+
74+
# FAIL-OPEN: if diff machinery errors, let the push through (CI catches it).
75+
changed="$(git diff --name-only --diff-filter=AM "${range}" 2>/dev/null)" || {
76+
echo "pre-push: warning — git diff failed for ${range}; skipping protection (CI will still check)" >&2
77+
continue
78+
}
79+
80+
hits="$(printf '%s\n' "${changed}" | grep -E "${PROTECTED_PATTERN}" || true)"
81+
if [ -n "${hits}" ]; then
82+
violations="${violations}${violations:+$'\n'}--- ${local_ref} -> ${remote_ref} ---"$'\n'"${hits}"
83+
fi
84+
done
85+
86+
if [ -z "${violations}" ]; then
87+
exit 0
88+
fi
89+
90+
if [ "${CATETUS_PARTNERSHIP_OVERRIDE:-}" = "1" ]; then
91+
who="$(git config user.email 2>/dev/null || echo 'unknown')"
92+
when="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
93+
echo "==============================================================" >&2
94+
echo "pre-push: OVERRIDE engaged (CATETUS_PARTNERSHIP_OVERRIDE=1)" >&2
95+
echo " user: ${who}" >&2
96+
echo " when: ${when}" >&2
97+
echo " remote: ${remote}" >&2
98+
echo " paths overridden:" >&2
99+
printf '%s\n' "${violations}" | sed 's/^/ /' >&2
100+
echo "==============================================================" >&2
101+
exit 0
102+
fi
103+
104+
cat >&2 <<EOF
105+
==============================================================
106+
pre-push: BLOCKED — partnership/outreach docs in push
107+
108+
The following paths are protected and MUST NOT be pushed to any
109+
remote (the repo flips public eventually; these docs never should):
110+
111+
${violations}
112+
113+
Why: a 2026-05-15 leak of docs/partnerships/* on the public
114+
test-hero-fast branch produced concrete external fallout
115+
(Khronos issue #2580 closed citing the leaked outreach doc).
116+
See experiments/partnership-docs-audit/AUDIT.md.
117+
118+
Options:
119+
1) Drop these paths from the push:
120+
git restore --staged docs/partnerships docs/standards-outreach
121+
git commit --amend # or rebase to remove the commits
122+
2) Legitimate exception (e.g. deleting a leaked file from
123+
history, intentional internal-only remote):
124+
CATETUS_PARTNERSHIP_OVERRIDE=1 git push ...
125+
(An audit line will be written to stderr.)
126+
==============================================================
127+
EOF
128+
exit 1

.github/CODEOWNERS

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Catetus code owners.
2+
#
3+
# Until there are more humans on the project, everything routes to the
4+
# project lead for review. Add path-scoped rules above the catch-all as
5+
# new maintainers come on board.
6+
7+
* @montabano1

.github/ISSUE_TEMPLATE/bug.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
name: Bug report
3+
about: Something is broken or behaves unexpectedly
4+
title: "bug: "
5+
labels: bug
6+
---
7+
8+
## What happened
9+
10+
<!-- Brief description. -->
11+
12+
## What you expected
13+
14+
## Reproduction
15+
16+
Steps:
17+
1.
18+
2.
19+
20+
If possible attach (or link to) a minimal PLY/SPZ/glTF fixture.
21+
22+
```bash
23+
catetus --version
24+
catetus analyze your-fixture.ply
25+
```
26+
27+
## Environment
28+
29+
- OS / arch: <!-- e.g. macOS arm64 14.5 -->
30+
- catetus version: <!-- catetus --version -->
31+
- Rust version: <!-- rustc --version -->
32+
- Browser (if viewer issue): <!-- e.g. Chromium 124 / Safari 17.5 -->
33+
34+
## Anything else
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
name: SplatBench corpus contribution
3+
about: Contribute a real splat scene to the public benchmark corpus
4+
title: "corpus: add <scene-name>"
5+
labels: corpus
6+
---
7+
8+
## Scene name
9+
10+
## Class
11+
12+
<!-- Choose one or more PRD corpus classes -->
13+
14+
- [ ] small product scan
15+
- [ ] people / characters
16+
- [ ] indoor real estate
17+
- [ ] outdoor scene
18+
- [ ] reflective / transparent failure case
19+
- [ ] noisy capture with floaters
20+
- [ ] dense large scene
21+
- [ ] mobile-friendly scene
22+
- [ ] glTF KHR conformance asset
23+
- [ ] SPZ test asset
24+
- [ ] OpenUSD test asset
25+
26+
## Source
27+
28+
<!-- Where did the capture come from? Capture device / app, capture date,
29+
post-processing pipeline (Inria 3DGS / Polycam / etc.). -->
30+
31+
## License / rights
32+
33+
- [ ] Public domain / CC0
34+
- [ ] Permissive (CC-BY, MIT-style)
35+
- [ ] Apache 2.0
36+
- [ ] Other open license: <!-- which -->
37+
- [ ] Private / design-partner (do not redistribute)
38+
39+
## Asset description
40+
41+
- Splat count (approx):
42+
- File size (raw PLY MB):
43+
- Bounding box (approx):
44+
- SH degree:
45+
- Known capture artifacts (floaters, missing geometry, etc.):
46+
47+
## Download
48+
49+
<!-- Direct URL or HuggingFace dataset reference. For private assets, link to
50+
a signed-URL contact channel. -->
51+
52+
## Reference images
53+
54+
<!-- A couple of reference renders are very helpful. -->

.github/ISSUE_TEMPLATE/feature.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
name: Feature request
3+
about: Suggest a new feature or improvement
4+
title: "feat: "
5+
labels: enhancement
6+
---
7+
8+
## What problem does this solve
9+
10+
<!-- Who benefits and why. -->
11+
12+
## Proposal
13+
14+
<!-- What you'd like to see. -->
15+
16+
## Alternatives considered
17+
18+
## Spec impact
19+
20+
- [ ] No spec change (refactor/perf only)
21+
- [ ] Amends existing spec: `specs/####-...md`
22+
- [ ] Requires a new spec
23+
24+
## Non-goals
25+
26+
<!-- What this is explicitly NOT trying to do. -->

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
## Summary
2+
3+
<!-- One-paragraph description of what this PR does. -->
4+
5+
## Related spec / issue
6+
7+
- spec: `specs/####-...md` (or "n/a — refactor")
8+
- closes #
9+
10+
## Checklist
11+
12+
- [ ] Tests added (unit / integration / snapshot / property as appropriate)
13+
- [ ] `cargo fmt --all -- --check` is clean
14+
- [ ] `cargo clippy --workspace --all-targets -- -D warnings` is clean
15+
- [ ] `cargo test --workspace` passes
16+
- [ ] `pnpm -r run lint && pnpm -r run test` passes
17+
- [ ] Public API changes documented in CHANGELOG.md under `## [Unreleased]`
18+
- [ ] If parser/format change: malformed fixture added in `fixtures/invalid/`
19+
- [ ] If optimizer change: before/after pass stats emitted
20+
- [ ] If renderer change: visual-regression snapshot updated only if spec required
21+
- [ ] Commits are `Signed-off-by:` (DCO)
22+
23+
## Notes for the reviewer
24+
25+
<!-- Anything tricky, anything you're unsure about, anything you punted on. -->
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
name: bench-regression-pr-comment
2+
3+
# On every PR opened/synced against main, run the bench matrix in DRY mode
4+
# first (so the PR comment shows up fast and free), and if the PR is
5+
# labeled `run-bench` (manual opt-in to spend ~$42 on Modal), re-run the
6+
# matrix live and post a real table.
7+
#
8+
# Comparison baseline: benches/reports/splatbench-v0.json's
9+
# continuousBench.latestCells from main's HEAD. Any cell that regresses
10+
# >= 0.3 dB PSNR (or > 5% larger output) is highlighted with a warning.
11+
#
12+
# This workflow informs only — it does NOT block merge. The user is the
13+
# final auto-ship arbiter per CLAUDE.md project policy.
14+
15+
on:
16+
pull_request:
17+
branches: [main]
18+
types: [opened, synchronize, reopened, labeled]
19+
20+
permissions:
21+
contents: read
22+
pull-requests: write
23+
24+
jobs:
25+
comment:
26+
runs-on: ubuntu-latest
27+
steps:
28+
- uses: actions/checkout@v4
29+
with: { fetch-depth: 2 }
30+
- uses: actions/setup-node@v4
31+
with: { node-version: "20" }
32+
- name: Build regression table from current main's continuousBench
33+
id: tbl
34+
shell: bash
35+
run: |
36+
set -euo pipefail
37+
node - <<'JS' > /tmp/bench-comment.md
38+
import { readFileSync, existsSync } from "node:fs";
39+
const path = "benches/reports/splatbench-v0.json";
40+
if (!existsSync(path)) {
41+
console.log("_SplatBench v3 has no continuous data yet — first run pending._");
42+
process.exit(0);
43+
}
44+
const r = JSON.parse(readFileSync(path, "utf8"));
45+
const cont = r.continuousBench ?? { latestCells: {}, commits: [] };
46+
const cells = cont.latestCells ?? {};
47+
const keys = Object.keys(cells);
48+
if (!keys.length) {
49+
console.log("_SplatBench v3 has no continuous cells yet (likely awaiting first successful workflow run)._");
50+
process.exit(0);
51+
}
52+
console.log("## SplatBench v3 — current main snapshot\n");
53+
console.log("This PR will run the full (preset × scene) matrix on merge (or on the `run-bench` label).");
54+
console.log(`Last bench commit: \`${cont.lastCommit?.slice(0,7) ?? "(unknown)"}\` (${cont.lastCommitAt ?? "n/a"})\n`);
55+
console.log("| Preset | Scene | ΔPSNR (dB) | PLY save (%) | Output |");
56+
console.log("|---|---|---:|---:|---|");
57+
for (const k of keys.sort()) {
58+
const c = cells[k];
59+
const dp = c.delta_psnr_db == null ? "—" : c.delta_psnr_db.toFixed(2);
60+
const sv = c.ply_save_pct == null ? "—" : (c.ply_save_pct * 100).toFixed(1);
61+
const link = c.output_url ? `[ply](${c.output_url})` : "—";
62+
console.log(`| \`${c.preset}\` | \`${c.scene}\` | ${dp} | ${sv} | ${link} |`);
63+
}
64+
if ((cont.lastRejections ?? []).length) {
65+
console.log("\n### Last cells rejected by ≤0.3 dB drop rule");
66+
for (const rj of cont.lastRejections) {
67+
console.log(`- \`${rj.key}\` — ${rj.reason}`);
68+
}
69+
}
70+
JS
71+
{
72+
echo "body<<EOF"
73+
cat /tmp/bench-comment.md
74+
echo "EOF"
75+
} >> "$GITHUB_OUTPUT"
76+
- name: Post sticky PR comment
77+
uses: marocchino/sticky-pull-request-comment@v2
78+
with:
79+
header: splatbench-v3
80+
message: ${{ steps.tbl.outputs.body }}

0 commit comments

Comments
 (0)