Commit Graph
15 Commits
Author SHA1 Message Date
Quick 5df181f733 docs(v1): record the settings removal as a pre-lock exception
The design removes the legacy /api/v1/settings routes and the profile DTO
preference fields, while AGENTS.md states /api/v1 is additive-only and
removals go through Deprecation/Sunset. Read together those contradict.

They do not actually conflict: v1-scope.md scopes the additive-only rule to
"when the scope locks", and the scope is still open, so a removal taken now
is in scope and there is no amendment process to invoke yet. But that
reasoning lived only in the settings design, where nobody checking the API
policy would find it.

v1-scope.md now carries a pre-lock removals table naming what goes and why
waiting is worse, and states the deadline the argument depends on: a removal
listed there must ship before lock or fall back to Deprecation/Sunset.
AGENTS.md points at the table and says to treat an unlisted removal as a
mistake.

Reported by CodeRabbit review on #479.
2026-07-27 00:33:27 +00:00
Quick 6535203791 ci: gate Go lint on the lines a branch changes
AGENTS.md told contributors CI ran the same checks as `make lint`, and the Go
job ran only gofmt and vet. A change failing the documented Go lint gate
passed all three jobs.

Running the linter as-is is not an option: the tree has ~296 findings today,
which is why this half of `make lint` was never enforced. Blocking every PR
on a cleanup nobody has scheduled gets the gate deleted again, so CI runs
with --new-from-merge-base and only the lines a branch touches have to be
clean. The count can then only fall.

golangci-lint is built from source at a pinned version rather than
downloaded. A released binary refuses to run against a Go newer than the one
it was built with, and go.mod here tracks Go closely enough that the current
release already fails that way on 1.26.4.

.golangci.yml declared version 2 while still using v1's issues.exclude-rules
key. Current golangci-lint ignores it, so the "allow repeated strings and
unchecked cleanup errors in tests" exclusions silently did not apply — 16
findings in test files that the config says to skip. Moved to
linters.exclusions, which `golangci-lint config verify` accepts.

The four lines this surfaced in scantrigger are fixed rather than excluded:
its repeated status codes and messages are now named constants, so one
condition cannot end up worded two ways.

Also drops the workflow token to contents:read and stops persisting
credentials in the three checkouts, neither of which any job needs.

Reported by CodeRabbit and Codex review on #479.
2026-07-27 00:32:15 +00:00
QuickandClaude Opus 5 d8faf83c6e fix(settings): make the settings contract enforceable and fix the appearance cache
The contract manifest landed as a document nothing checked. This makes it a
mechanism, and fixes the one defect in the change set that hurt users on merge
rather than at cutover.

Web appearance cache. useTheme cleared the cache for any account whose stamp
did not match and never repopulated it — the only writers were the four
user-action setters — so every upgrading user lost their warm start on every
load, not once, and x-large-text and high-contrast users lost theirs too. The
owner-stamp protocol is replaced with per-account key namespacing
(`silo-theme:7`): a foreign value is absent rather than present-and-distrusted,
so nothing has to be deleted, the first account keeps its warm start, and there
is no shared stamp for a second tab, a stale debounce timer, or an out-of-order
effect to race on. Widening ownership to profile scope, which this manifest
requires, is now a change to appearanceCacheOwner alone. Adds the API-to-cache
mirror useTheme was missing, cancels pending debounced writes across an account
change, and re-seeds provider state during render so no frame paints the
previous account's look.

Canonicalization. writeCanonical used json.Marshal, which HTML-escapes < > and
&, and canonicalNumber used Go's 'g' format — both diverge from RFC 8785, so
the first label containing an ampersand or bound below 1e-4 would have forked
the server's ETag from every conforming client. Output is now byte-identical to
ECMAScript String() across the edge cases, verified against node. The ETag also
covers the value schemas, which decide what the server accepts and previously
could change while the tag stood still. All four derived representations are
memoized; a conditional GET no longer costs a full parse and re-serialize.

Validation. strictUnmarshal's decoder.More() answered false for a stray ] or },
so `true]` validated as a boolean. Enum matching compared fmt.Sprintf tokens, so
the string "3" satisfied an integer member. Declared steps were never enforced.
The language pattern rejected tags both mobile platforms emit unprompted
(en_US, ca-ES-valencia, ar-EG-u-nu-latn) and never normalized case, so en-US and
en-us were two rows for one preference; NormalizeValue now canonicalizes on the
shared path.

Manifest. show_forced_subtitles defaulted false where the server column is NOT
NULL DEFAULT true, which would have turned forced subtitles off for every
profile that never touched it. preferred_quality declared 13 members where the
planner speaks 6 and collapses the rest to auto. metadata_language's allowlist
was bound to the very column it migrates from. subtitle-appearance pinned
fontFamily to three families while Apple stores any installed system font.
Registers five user-facing settings the clients already ship, and corrects three
notes that described Android behaviour that was not true.

Enforcement. The package had no non-test callers, so MustLoad never ran; it now
loads and logs at startup. The inventory test compared the manifest against a
hand-copied map and could not see the drift it named; it now iterates
settingsRegistry and checks defaults too — both verified to fail on injected
drift. Adds .github/workflows/ci.yml, the repo's first CI that runs go test,
go vet, gofmt, and the frontend suite. Known pre-existing failures are named
individually in the Makefile so everything else stays gated and the list can
only shrink.

Part of #135

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 15:24:33 +00:00
QuickandClaude Opus 5 9e7fe79590 docs: record live TV, IPTV, and .strm as permanent non-goals
Live TV, OTA/DVB tuners, IPTV, EPG/XMLTV guide sync, DVR, and .strm
remote-URL shortcuts are permanently out of scope for Silo. The
deciding factor is app store distribution: the first-party iOS, tvOS,
macOS, and Android clients ship through Apple and Google, and a server
that plays arbitrary remote stream URLs puts the entire client suite at
risk of rejection or takedown, not just the feature. Secondarily, live
TV is a separate product surface whose reliability burden competes with
the core playback path.

This was an undocumented boundary until now, and contributors spent real
effort against it (#419, #420, #474). Write it down in docs/non-goals.md
and summarize it in AGENTS.md so both humans and agents see it before
proposing or implementing in this area.

Refs #474, #419, #295

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 15:07:42 +00:00
Quick 51ef906025 docs: add agent skills and silo-dev helper script
- Add skills for dev-environment debugging, jellycompat diagnosis, Discord triage, and web UI testing under .claude/skills (symlinked as .agents/skills)
- Add scripts/silo-dev plus .silo-dev.env.example for driving local or remote Silo deployments
- Ignore .silo-dev.env and reference the shared skill config in AGENTS.md
2026-07-25 05:16:19 +00:00
ece3578e91 docs: rightsize repo context for Claude 5 context engineering (#467)
Applies the practices from Anthropic's "new rules of context engineering
for Claude 5 generation models" to this repo's always-on context.

AGENTS.md (symlinked as CLAUDE.md) drops content derivable from the
filesystem — the module-by-module structure tour, the Makefile target
list, and most of the style section, all of which Claude reads directly
from internal/, the Makefile, .golangci and web/.prettierrc. What stays
is the part that isn't derivable: the Goose migration rules, the v1
additive-only API contract, multi-repo boundaries, and the workspace
gotchas. Also fixes a dead pointer to .claude/skills/deployment-debugging,
which does not exist; the runbook is the dev-environment-debugging skill.

The external-contributor AI disclosure block moves to
docs/ai-contributions.md, reached by a one-line pointer, so it costs
nothing in the common case where no external PR is being prepared.

issue-to-pr sheds the generic agent hygiene now covered by the harness
system prompt and keeps the Silo-specific gates. Its commit trailer no
longer pins a stale model name.

scripts/jellycompat-diff.sh replaces the hand-typed curl/python
one-liners the jellycompat-diagnosis skill used to carry as prose. It
unions item keys across all returned items rather than reading item[0],
which was hiding fields present on only some items.

Verified: make verify-local-paths, bash -n, shellcheck, and a mock
two-server run of the diff script.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-07-24 15:15:19 -04:00
Quick104 eee63772a7 feat: add AI disclosure requirements to contributing guidelines and issue templates 2026-07-23 14:37:38 -04:00
QuickandGitHub 98a22dafd2 docs: use canonical plugin repository names (#359) 2026-07-09 20:13:33 -04:00
87159b0a38 feat(collections): add profile-scoped display filters (#191)
* feat(collections): add profile-scoped display filters

* refactor(collections): dedup display-filter helpers per review

Address code-review feedback on the profile-scoped display filters
without changing behavior:

- Widen CompletedHistoryItemMap to accept ProgressCompletionStore and
  drop the duplicate completedHistoryItemMapForProgress copy.
- Extract the duplicated MDBList candidate retry loop into a generic
  collectionutil.FetchMDBListWithFallback helper, used by both the user
  and library collection syncers, and cover it with unit tests.
- Reuse validateOptionalLibraryIDs in HandleUpdateCollection instead of
  an inline positive-ID loop.
- Import the shared COLLECTION_{WATCH,MEDIA}_FILTER_OPTIONS in the
  template config form rather than redefining them locally.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(collections): sanitize query_definition library_ids fallback

readSourceConfigLibraryIDs validated source_config.library_ids (finite,
positive, truncated, deduplicated) but returned the query_definition
fallback raw, so legacy rows could surface zero/negative/duplicate IDs
that the backend now rejects on save. Extract a shared sanitizer and
apply it to both paths.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* refactor(docs): This makes the agents annoying to work with

* Improve playback session handling

* Support collection source order in catalog filters

* fix(collections): address display filter review feedback

* refactor(catalog): remove duplicate collection query params

* Hide episode media scope for collection overlays

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 11:03:38 -04:00
6f9427d613 docs(process): v1 scope-lock process — proposal template, CODEOWNERS gate, agent instructions (#145)
Implements the process layer of the v1 feature-lock planner: capability
proposals arrive uniform via issue form; the lock artifact
(docs/architecture/v1-scope.md) is CODEOWNERS-gated; the shared
CLAUDE.md/AGENTS.md guidelines gain the scope gate, additive-only API
rules, and pre-push checklist for agent-driven contributions.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 18:43:23 -04:00
QuickandGitHub 31b2716089 feat(database): adopt goose migrations (#62) 2026-06-06 23:51:30 -04:00
Silo Server MigrationandClaude Opus 4.7 e8143d5757 chore: tighten local-path-leak guard scope and tooling
- Narrow the worktree-id/T3-path check to docs/superpowers/specs and
  docs/superpowers/plans. Scanning the whole repo flagged any
  legitimate reference to .t3/worktrees or t3code-<hex> (fixtures,
  example configs) and would block unrelated commits.
- Switch the pre-commit hook shebang to bash and call the check via
  an absolute path derived from git rev-parse so the hook works
  regardless of the cwd git happens to invoke it from.
- install-hooks now warns when it overwrites an existing
  core.hooksPath rather than silently clobbering a custom setup.
- Add make verify-local-paths to the AGENTS.md pre-MR checklist so
  contributors run it explicitly even when --no-verify is used.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 00:27:29 -04:00
Silo Server Migration dcdf791c3c chore: add local path leak pre-commit guard 2026-05-24 19:58:22 -04:00
Silo Server Migration e37d753a0c Port collection templates with poster support and async syncs
- Add poster URLs through collection import and template apply flows
- Queue large template bundle syncs and preserve existing collection posters
- Update template bundle assets, docs, and limit handling
2026-05-23 12:31:08 -04:00
Silo Server Migration c085b12fd1 Initial Silo migration 2026-05-22 23:26:56 -04:00