Codex handoff for BTRC Hub / タグ広場
This document transfers project-specific context from prior ChatGPT-assisted design and review work to Codex.
Use this file as project background.
Use AGENTS.md, backend/AGENTS.md, and frontend/AGENTS.md for concrete coding rules and verification commands.
Project identity
BTRC Hub / タグ広場 is a collaborative knowledge base for collecting, tagging, explaining, and rediscovering Bocchi the Rock creature-related works.
It is not a generic SNS.
It is not a comment board.
It is not a service for rehosting external content.
It is primarily a structured link, tag, wiki, material, and viewing-party system.
Core domains:
- Posts
- Tags
- Wiki pages
- Materials
- Theatre / watch-party features
The project is already publicly accessible and indexed by search engines, but it has not been broadly announced. Treat it as a small public production system, not a private prototype.
Current stack
Backend:
- Ruby 3.2.2
- Rails 8.0.2 API
- MySQL 8
- Active Storage
- Cloudflare R2 / S3-compatible storage is expected for uploaded files
- RSpec
Frontend:
- React 19.1
- Vite 6.3
- TypeScript 5.8
- Axios
- TanStack Query
- Tailwind CSS
- Framer Motion
- shadcn-like local components
- react-markdown
- react-markdown-editor-lite
- remark-wiki-autolink
Batch / background-like tasks:
- Rake tasks
- Nico sync
- YouTube sync
- Similarity calculation tasks
Repository working principle
Before editing, inspect the existing implementation.
Do not invent a new architecture when the current repo already has an established convention.
Keep changes scoped to the requested issue.
Prefer small, reviewable changes over broad rewrites.
Do not perform unrelated cleanup in the same patch.
When a task has design ambiguity, first produce a short investigation and recommended plan. Do not silently choose a risky design.
User coding preferences
General:
- Prefer single quotes for strings unless interpolation, escaping, or framework convention makes double quotes better.
- Do not add production dependencies without explicit approval.
- Do not perform broad formatting churn.
- Do not convert unrelated files to a different style.
Ruby:
- Do not put a space before method-call parentheses.
- Do not use
%w.
- Do not use
%i.
- Keep Rails code idiomatic, but preserve the user’s style where the repo already uses it.
TypeScript / Python:
- The user prefers GNU-style spacing before parentheses where syntactically valid.
- Preserve existing project formatting if a formatter or nearby code dictates otherwise.
Current authentication model
The system does not use normal email/password authentication.
Users are authenticated by inheritance code.
Frontend:
- Stores the code in
localStorage.user_code.
- Sends it as the
X-Transfer-Code header.
Backend:
- Looks up
users.inheritance_code.
- Sets
current_user.
Roles:
Important helper:
User#gte_member? returns true for member and admin.
Never introduce a conventional login assumption unless the issue explicitly asks for it.
BAN / abuse-control model
The backend currently enforces BAN at API level.
The relevant before_action order is conceptually:
- Reject banned IP address.
- Authenticate user if transfer code exists.
- Reject banned user.
Entities:
users.banned_at
ip_addresses.banned_at
user_ips
IP addresses are stored as binary values using IPAddr#hton.
Do not weaken BAN behavior.
Do not move BAN checks behind optional authentication.
Do not make preview, theatre, verify, user creation, or public-looking endpoints bypass BAN without an explicit design decision.
Public-operation assumptions
Current practical operation:
- A few editor accounts exist.
- Meaningful editing is mostly done by the owner.
- Read access is already public.
- Search engines have indexed the site.
- Future editor applications are expected through Discord.
- Prospective editors are likely people known in the Bocchi creature community.
This means security and moderation issues matter even if traffic is still small.
Core domain summary
Posts
Posts are external URL-based link records.
Important properties:
url is required and unique.
- URLs are normalized.
- Only HTTP / HTTPS are allowed.
- Posts can have thumbnails through Active Storage.
uploaded_user_id may be NULL for synced or bot-created posts.
original_created_from and original_created_before represent a time range for original content creation.
- When both original time bounds exist,
from < before is required.
Parent/child posts:
- Current implementation uses
post_implications.
- It is many-to-many.
- Do not assume
posts.parent_id.
- Frontend/API clients must send
parent_post_ids, even when empty.
parent_post_ids is parsed as a space-separated ID string.
- Self-parenting is invalid.
- Missing parent IDs are invalid.
Versions:
post_versions stores snapshots.
version_no is a per-post sequence.
- Snapshot includes title, URL, thumbnail base, tags, parent post IDs, original time bounds, event type, and actor.
- Optimistic locking for posts is planned / important, but do not assume it is fully implemented unless the code proves it.
Tags
Tags are central.
There is separation between tag names and tag entities:
Categories:
deerjikist
meme
character
general
material
nico
meta
Alias model:
tag_names.canonical_id expresses aliases.
canonical_id = NULL means canonical name.
canonical_id != NULL means alias.
- An alias must not point to another alias.
- A tag name that already has a tag or wiki page generally must not be aliasified.
Tag normalization:
- User-entered tags are normalized through existing backend logic.
- Known aliases are canonicalized.
- Parent tags are expanded recursively.
nico: is normally rejected for manual entry.
- Special tags such as tag-request / bot / unknown-deerjikist / video / niconico / youtube must be protected.
Do not casually change tag normalization, alias resolution, or parent expansion. These affect search, wiki, sync, and historical data.
Nico tags
Nico tags use the nico category and have separate versioning.
Important relation:
nico_tag_relations maps external Nico tags to internal tags.
nico_tag_id must be a Nico category tag.
tag_id must not be Nico category.
Do not allow ordinary manual tag editing to create or corrupt Nico tags.
Deerjikists
Deerjikists map external platform identities to internal deerjikist tags.
Known platforms include:
YouTube handles may be normalized to UC... channel IDs.
Do not treat user-facing handles and canonical channel IDs as interchangeable without checking existing code.
Wiki
Wiki pages are a major knowledge layer.
Important points:
- Wiki pages are tied to tag-like titles.
- Title handling, aliases, and canonical tag names matter.
- There is line-level storage / revision-oriented behavior in the current implementation.
- There has been design tension between wiki revisions and wiki versions.
- Wiki conflict detection using
base_revision_id exists on the backend side.
- Frontend support for conflict detection must be verified before assuming it is complete.
Do not redesign Wiki storage casually.
Do not add a second competing history system.
Do not break existing wiki URLs.
Materials
Materials connect files or reference URLs to material or character tags.
Important properties:
- A material has a
tag_id.
- The tag must be
material or character.
- A material requires either
url or attached file.
- Active Storage is involved.
- Upload/security policy matters more than plain link posting.
Important unresolved/risky area:
- Material creation permissions have historically been risky because upload endpoints can be abused.
- Prefer
member or higher for material creation unless the issue explicitly says otherwise.
Theatre
Theatre is an experimental watch-party style feature.
Known pieces include:
- Display
- Presence
- Next post
- Comments
- Host-like control
Do not assume theatre has complete CRUD/admin support unless the code proves it.
Theatre may become expensive if next-item selection uses random DB ordering.
Current high-risk areas
Treat these areas with extra care.
Security
- Preview API SSRF protection.
- External iframe / embed CSP.
- Markdown link safety.
- BAN / IP BAN bypass.
- Transfer-code leakage.
- Guest write access.
- Upload endpoints.
- Admin-only tag operations.
- System tag mutation.
Data integrity
- Tag alias canonicalization.
- Tag parent expansion.
- Post parent many-to-many relationships.
- Version tables.
version_no synchronization.
- Schema drift from branch migration contamination.
- Wiki revision/version split.
- Material version recording.
Frontend correctness
- React Hooks must not be called conditionally.
- Role guards are currently spread across components/pages.
- TanStack Query keys must not collide between ID/name or ID/title variants.
- URL path segments containing tag names or wiki titles must use
encodeURIComponent.
- API response types may allow
null users for bot or migration data.
- Tag autocomplete has had duplicated logic and stale state hazards.
Performance
- Avoid unbounded
limit.
- Avoid
order('RAND()') for growing tables.
- Avoid loading full relations just to count.
- Avoid Ruby-side sorting/paging for large histories.
- Tag sidebar client-side aggregation can become expensive.
- Wiki full-text search needs deliberate indexing/design.
Current priority order
Use this as the default priority unless an issue says otherwise.
P0: Safety before broad announcement
- Preview API SSRF hardening.
- Material creation permission tightening.
- System tag mutation holes.
GET /users/me transfer-code leakage through query params.
- Limit caps for index/history/comment APIs.
- CSP / iframe sandbox policy.
- Confirm BAN enforcement remains global.
P1: Core correctness
- Post optimistic locking with
version_no.
- Wiki edit conflict handling.
- Wiki history/revision model clarification.
- Wiki search truthfulness: implement body search or remove false UI.
- Tag alias/canonical/wiki interaction.
- Tag URL encoding.
- TanStack Query key separation.
- Frontend null-user handling.
- React Hooks rule fixes.
- Material version policy.
P2: Operational/admin usability
- Admin screens for users, IPs, bans, aliases, and settings.
- Settings table and user settings usage.
- Better tag sidebar.
- Better role guard helpers.
- Better frontend tests.
- Better issue triage and closure of already-implemented issues.
P3: Future features
- Theatre list/create/edit/admin flow.
- Muted/hidden tags.
- Tag category custom colors.
- Responsive refinements.
- Watch-party improvements.
- Broader embed support.
Known issue triage notes
Some existing issues may already be partially or mostly implemented.
Before implementing an issue, check code first.
Examples:
- Tag search and OR/NOT search may already be mostly implemented.
- BAN enforcement may have been implemented after earlier issue drafts.
- YouTube sync exists and should not be treated as purely planned.
- Parent posts are many-to-many in current schema, even if older issues mention one-to-many.
- Some issues may reflect old schema or old branch state.
When in doubt:
- Inspect current code.
- Inspect schema.
- Inspect routes.
- Inspect frontend usage.
- Report whether the issue is implemented, partially implemented, not implemented, or obsolete.
- Only then edit.
Verification expectations
Backend changes:
- Run RSpec when possible.
- Add request specs for API behavior changes.
- Add model specs for validation / normalization changes.
- Check migrations and schema consistency.
- Do not silently ignore pending migrations.
Frontend changes:
- Run build.
- Run lint if configured.
- Run tests if configured.
- Add tests for important behavior when the test framework exists.
- If frontend tests are not yet installed, state that clearly.
Full-stack changes:
- Verify both backend and frontend compile/test paths where possible.
- Confirm API response shapes match TypeScript types.
- Confirm authorization behavior on both server and UI.
If commands cannot be run because dependencies are missing, report that explicitly. Do not pretend verification passed.
Branch / migration caution
The project has previously suffered from schema contamination caused by running migrations from another branch.
Be careful when touching:
db/schema.rb
- migration files
- parent post schema
- banned / banned_at schema
- version_no migrations
- wiki asset schema
Before changing migrations:
- Inspect current schema.
- Inspect existing migrations.
- Confirm whether the intended branch already includes related migrations.
- Prefer additive migrations for shared branches.
- Do not edit already-applied production migrations unless explicitly instructed.
API design principles
Prefer explicit server-side authorization.
Do not rely only on frontend hiding.
Do not return sensitive codes unnecessarily.
Use 403 for authorization failures.
Use 422 for validation failures.
Use 409 for edit conflicts.
Do not expose internal exception messages to users.
Clamp or reject abusive limits consistently.
Keep response shape stable unless the issue explicitly includes a breaking API change.
Frontend design principles
Use existing route and query-key conventions.
Use TanStack Query enabled rather than conditional hook calls.
Do not let role-based early returns change hook order.
Centralize repeated tag autocomplete logic when touching it.
Use encodeURIComponent for tag names and wiki titles in URL path segments.
Prefer graceful fallback for nullable actors:
- bot operation
- deleted user
- migration-created data
- external sync
Do not assume all API user fields are non-null.
Testing priorities to add over time
Frontend tests are especially important because the backend already has more mature RSpec coverage.
Suggested first frontend tests:
- Tag autocomplete.
- Post form tag editing.
- Tag URL encoding.
- Wiki edit conflict UI.
- Role guard behavior.
- Null-user history rendering.
- Dialog behavior.
- Top navigation responsive behavior.
Backend test priorities:
- BAN enforcement across public-looking endpoints.
- Material permissions.
- Preview SSRF rejection.
- System tag protection.
- Post optimistic locking.
- Wiki conflict detection.
- Tag alias/canonical behavior.
- Limit caps.
- Parent post parsing.
- Version recorder behavior.
What Codex should not do without explicit approval
Do not:
- Replace Rails.
- Replace React.
- Replace TanStack Query.
- Redesign the database.
- Rewrite Wiki storage.
- Remove version tables.
- Change authentication model.
- Change role names.
- Change tag category names.
- Add background job infrastructure.
- Add a new UI framework.
- Add a new test framework if one already exists.
- Add major dependencies.
- Change public URL design.
- Change production storage configuration.
- Remove historical data behavior.
- Simplify BAN/security checks.
- Treat the site as private-only.
Good first Codex tasks
Start with investigation-only tasks.
Example:
Inspect the repository and summarize the Rails, React, TypeScript, and test setup.
Do not modify files.
List commands that actually exist in this repository.
List risks Codex should know before editing.
Then small safe patches:
Fix a React Hooks rule violation in one file.
Keep behavior unchanged.
Run the relevant frontend verification commands.
Add encodeURIComponent around one tag-name URL path segment.
Add or update a test if the project has a frontend test setup.
Run build/lint.
Add a request spec for a known authorization rule.
Do not change implementation unless the spec fails for the expected reason.
Avoid starting with:
- Wiki history redesign.
- Post versioning redesign.
- Full admin screen suite.
- Broad frontend refactor.
- Database cleanup.
- Authentication rewrite.
Relationship with ChatGPT
ChatGPT has been used for:
- Design review.
- Risk analysis.
- Prioritization.
- Specification reconstruction.
- Migration/locking discussions.
- Codex migration planning.
Codex should be used mainly for:
- Repository inspection.
- Localized implementation.
- Test addition.
- Running verification commands.
- Producing small reviewable diffs.
For ambiguous architecture, Codex should stop and present options rather than implement a guessed design.
Current strategic stance
The project should not be rewritten from scratch.
The current Rails + React system is acceptable.
The immediate goal is not elegance.
The immediate goal is safe public operation, data integrity, and maintainable incremental improvement.
Priority is:
- Prevent abuse/security incidents.
- Preserve data correctness.
- Make editing safe for multiple users.
- Add tests around fragile frontend behavior.
- Improve admin/operation workflows.
- Optimize performance after obvious dangerous patterns are removed.
Final rule
When current code, old specs, issue drafts, and memory disagree, current code wins.
When current code is unsafe, write that explicitly and propose a small safe fix.
When the task is too broad, split it.
When verification cannot be performed, say exactly what was not verified.