Skip to content

feat(utp): port utopia naming, description, and image-host rules to the site profile - #303

Open
maksii wants to merge 1 commit into
chore/log-rename-signalfrom
feat/utp-tracker-v2
Open

feat(utp): port utopia naming, description, and image-host rules to the site profile#303
maksii wants to merge 1 commit into
chore/log-rename-signalfrom
feat/utp-tracker-v2

Conversation

@maksii

@maksii maksii commented Aug 2, 2026

Copy link
Copy Markdown
Collaborator

sites/utp on main carried taxonomy only, so UTP uploaded with the shared Unit3D release name, the
shared description, and no site policy. UTP prescribes its own space-delimited naming
(utp.to/pages/33) and hosts its own image host, so every upload needed
manual correction.

Stacked on #262. This targets chore/log-rename-signal, not main, because
internal/trackers/rules.go genuinely collides: UTP hoists registry.LookupRules and wraps the
modified-release block in a SkipModifiedReleaseCheck gate, while #262 replaces that block's body
with typed detection plus a debug log. The interleave is resolved here rather than left for merge
time. GitHub retargets this to main once #262 merges.

Naming

name.go builds UTP's space-delimited name behind SiteProfile.BuildName with BuildNameVersion
"v1". Token order is byte-identical to the previous catalog implementation. An unsupported category
falls back to the generic dotted base name, which mandatory Unit3D constructibility blocks before
upload regardless.

Description

description.go renders the shared Unit3D description with each screenshot's full-size original as
the [url] link target and the medium thumbnail as the displayed [img], which is what UTP expects.
Images without a medium thumbnail are left unchanged and the input slice is never mutated.

Rules and audio

rules.go declares SkipModifiedReleaseCheck, a new declarative RuleSet opt-out: because UTP
prescribes space-delimited naming, a renamed source is expected there rather than a rename violation,
so neither the heuristic nor the srrdb signal may block. AudioPolicy allows Ukrainian and English as
additional audio languages, since UTP releases always carry Ukrainian plus the original audio.

UTPPM image host

UTPPM becomes a UTP-owned conditional host rather than a generic selectable one, matching the reelflix
conversion precedent: a new UTPPMEnabled toggle gates it, and existing configs that placed utppm in
a generic slot lose that selection. UTPPMAPI already existed and is already covered by config secret
encryption. The utppm uploader now rejects a response carrying no image URL instead of returning an
empty upload result, with the remote message sanitized.

taxonomy.go lowercases the resolution key before mapping, so a differently cased prepared resolution
no longer falls through to the unknown fallback ID.

Tests

name_test.go covers name construction, type inference when the type field is empty, the title
preference chain, suppression overrides, and the unsupported-category fallback. taxonomy_test.go
covers every type and resolution mapping. description_test.go covers the URL swap including the
no-thumbnail passthrough and input immutability. rules_test.go proves the skip opt-out for both
rename signals, that a non-exempt tracker still fails, and that the gate also suppresses the
rule-match debug log. registry_test.go covers the rules, audio policy, and conditional-host wiring.
useSettingsState.test.ts covers the UTPPM settings conversion both ways.

go build ./..., the full no-race go test ./..., make lint (architecture/path/literal policy +
workflow-contracts-check + golangci-lint, 0 issues), make logpolicy, make gofix-check-changed,
make backend, git diff --check, and the full frontend check set (lint, lint:dead, typecheck,
test:unit — 194 pass, format:check) all pass. -race is not runnable locally (no C compiler); CI
supplies that pass.

The embedded WebUI was exercised by running the built server and loading it in a browser: the UTPPM
toggle and its API-key field render under Settings → Image Hosting, and utppm no longer appears in
the generic host-priority dropdown. make e2e-web reports 12 passed / 1 failed; the failure is
web-full-upload.spec.ts:275 (Client injection: completed), which reproduces on unmodified main
and is unrelated to this change.

…he site profile

main's sites/utp carried taxonomy only, so UTP uploaded with the shared Unit3D
release name, the shared description, and no site policy. UTP prescribes its own
space-delimited naming (utp.to/pages/33) and hosts its own image host, so every
upload needed manual correction.

name.go builds UTP's space-delimited name behind SiteProfile.BuildName with
BuildNameVersion "v1"; token order is byte-identical to the previous catalog
implementation. An unsupported category falls back to the generic dotted base
name, which mandatory Unit3D constructibility blocks before upload regardless.

description.go renders the shared Unit3D description with each screenshot's
full-size original as the link target and the medium thumbnail as the displayed
image, which is what UTP expects. Images without a medium thumbnail are left
unchanged and the input slice is never mutated.

rules.go declares SkipModifiedReleaseCheck, a new declarative RuleSet opt-out:
because UTP prescribes space-delimited naming, a renamed source is expected
there rather than a rename violation, so neither the heuristic nor the srrdb
signal may block. AudioPolicy allows Ukrainian and English as additional audio
languages, since UTP releases always carry Ukrainian plus the original audio.

UTPPM becomes a UTP-owned conditional image host rather than a generic
selectable one, matching the reelflix conversion precedent: a new UTPPMEnabled
toggle gates it, and existing configs that placed utppm in a generic slot lose
that selection. The utppm uploader now rejects a response carrying no image URL
instead of returning an empty upload result, with the remote message sanitized.

taxonomy.go lowercases the resolution key before mapping, so a differently
cased prepared resolution no longer falls through to the unknown fallback ID.
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2a3bdf9e-b17d-43e0-a837-057abaf32a83

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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