Commit Graph
34 Commits
Author SHA1 Message Date
XingfenD dd5d0fabf9 docs: book P15-A as delivered (wrapper 0.3.8, ROADMAP rows + third-wave table)
P15-A merged to crearte-server master as e70e99b (0.19.0, merge-base fe810dd,
eight commits on the branch). Both review rounds came back with notes and both
caught the controller's own verification method rather than the refactor: the
gofmt gate in the shared four-gate recipe was exit-code blind, and identifier
counting cannot prove behaviour is unchanged (whole files rather than function
bodies, a hand-picked list read as a universal claim, and no visibility into
control flow at all).

The branch review's most valuable contribution was an evidence layer all four
earlier runs had silently skipped: the five real-database guards the spec names
were SKIPPED everywhere because nobody set TEST_DATABASE_URL, and the ~11s
internal/api timing reported as "including real-database integration" was the
mock path. Running postgres against both trees gave base 194 PASS versus HEAD
199 PASS with identical state multisets - the first runtime proof of unchanged
behaviour on the production database path.

Five of its notes concerned controller artefacts, not code. Four were spec
staleness introduced during re-pin, every one from writing executable details
from memory instead of grepping them out of the code; the fifth was the
fake-rigour form of the vacuous-assertion defect this project keeps finding - a
verification script printing nineteen [OK] lines with no checking logic behind
them while citing an output file that was never archived. Both are now fixed in
37a0a8d and 9061c39, and the lesson is a spec discipline: executable details in
a spec must be grepped from the code entity and pasted, never hand-written.

ROADMAP also gains a correction of my own omission: P15-A and P15-B were
registered in the document index but never added to the third-wave status
table, which still ended at P14.

P15-B is deliberately excluded from this entry. Its branch review returned
"needs fixing before merge" - the second time a branch review has blocked a
batch after P11 - on a critical gap in the guard layer: maskSourceComments()
compares a two-character slice against the four-character '<!--', so its HTML
comment branch is dead code. A second fix-forward is in flight; P15-B books as
0.3.9 when it merges.
2026-10-04 02:42:03 +08:00
XingfenD 82f0a6d360 docs: add P15-A and P15-B specs and plans, register both in ROADMAP
Two batches, one per repo, so they can run in parallel under the one-writer-per-repo
rule: P15-A refactors crearte-server's Approve function, P15-B fixes a dark-mode gap
in crearte's game loading screen plus two guard items.

P15-A splits a 169-line function whose seven phases are mapped here with real line
numbers — the base-tree mapping logged during P14 is void, since that batch moved the
function into moderation.go. The spec's central constraint is that phases four and six
look alike but must not be merged: four is an optimistic pre-check that runs unlocked
before any object copy, six is a pessimistic re-check under a row lock after the copies
have happened. They differ in four concrete ways (kind coverage, the NewVersion runtime
and bundle checks, whether entities are created, and the error wrapping), so the
apparent duplication is deliberate TOCTOU defence rather than removable redundancy.
A measurement also overturned the survey's claim about helper shape: both an unexported
method and a package-level function leave all seven P14 assertions green, because
IsExported filtering and NumMethod's exported-only view put neither in scope. The
choice is therefore about needing receiver fields, not about the guard.

P15-B fixes a gap P13 left: its token work covered only the src/index.html entry and
missed the second Vite entry, bootstrap, so the game loading screen hardcodes light
values and dark-theme users see a white flash on every virtual game launch. The fix
rides the hash channel bootstrap already parses rather than inventing a postMessage
protocol, which would be async and so repaint light first — the very flash being
removed. The spec records the trap that makes this easy to get wrong: GameHost builds
targets in a computed, so injecting the reactive theme ref would make a theme switch
recompute the iframe src and reload a game in progress; the non-reactive snapshot is
required, and a guard leg plus a mutation exist solely to hold that line. It also
records two pre-existing contrast violations found on the way, where inline style
attributes override conforming stylesheet values with lower-contrast ones, and why
noHardcodedColor cannot be extended to cover this file: it only collects .vue and
blanks out style blocks, so widening its roots would scan nothing while looking
like coverage.

Every line number and quoted signature in both specs was checked against source
before commit; two claims the survey had asserted from reasoning were measured
instead, and one of them was wrong.
2026-10-03 13:28:33 +08:00
XingfenD 163b0d703a docs: record P14 as delivered (wrapper 0.3.7, ROADMAP row + backlog)
The ContentService split landed in crearte-server 0.18.0 as merge fe810dd off
merge-base dbf7fe5. The third-wave table gains the P14 row and the doc index
marks it executed against the merge commit, per the P12/P13 convention of citing
the merge rather than the accounting commit.

The row records the batch's actual result, which is not the split but the two
review rounds that each caught the controller's own error: the task review found
that the guard purpose the spec states was covered by no assertion at all and
that the spec's own positive control had a bypass; the branch review then found a
hole in the first round's fix, where the source-scan pattern required a named
receiver and so let an unnamed-receiver shadow pass all seven assertions while
the shadow was effective. It also overturned two universal claims I had already
committed to the spec, both reproduced before acting on them.

Backlog gains the 169-line Approve function with its line range relocated after
the split (the base-tree mapping is void), plus six smaller items. It also logs a
dark-mode gap found while surveying the next batch: P13's token work covered only
the src/index.html entry and missed the second Vite entry, bootstrap, whose
loading screen hardcodes light values, so dark-theme users see a white flash on
every virtual game launch.
2026-10-03 12:37:10 +08:00
XingfenD 9965fd73ee docs: add the collision constraint to the GameHost a11y backlog item
The P13 final review logged GameHost's degraded-link badge (paper on accent =
3.2590 in light, below the 4.5 required for an 11px bold label) to the
accessibility polish batch. The obvious one-line fix — switching the badge to
bg-accent-ink — was falsified by measurement before it could be logged as if it
worked: light paper on accent-ink does pass at 4.8700, but accent and
accent-ink are only 1.4943 apart in light, and the badge shares the showcase
title bar with the phase status dot whose 'load failed' state already uses
bg-accent-ink. Recolouring the badge would collapse 'degraded to external link'
and 'load failed' into one visual signal, trading a contrast defect for a
semantic one.

Recorded as a design decision rather than a one-line change, so the next batch
does not walk into it. This extends the P12 lesson that a parked backlog item
must be falsified or confirmed before being implemented: what needs falsifying
is not only whether the item is worth doing, but whether the obvious way to do
it works.
2026-10-03 08:14:52 +08:00
XingfenD ba1fe3ecb0 docs: P14 design + plan for splitting the ContentService god object
Registers the next batch before implementation starts, so the design is
versioned and reviewable rather than living only on disk.

Scope: crearte-server only. content.go is 856 lines / 30 functions, the sole
outlier in internal/service (next largest production file auth.go is 234 lines;
content.go alone is 22% of the directory) and carries five unrelated
responsibility lines in one struct whose five fields are all shared repository
dependencies with no mutable internal state.

Three survey findings make the split low-risk rather than aspirational:
- the seven cross-line calls all target package-level helper functions, with
  zero method-to-method cross-line calls, so splitting creates no cross-service
  callbacks and no import cycle;
- each of the five handlers uses exactly one line's methods with zero overlap,
  so each dependency face narrows from 22 methods to its own 2-6 with no adapter;
- 11 of the 19 test construction sites only construct and never call methods,
  and a Go embedding spike (H1-H4, run in golang:1.24-alpine, vet clean)
  confirmed the promoted method set satisfies consumer-defined narrow
  interfaces — so the composite root keeps every construction site and all five
  serve.go wirings unchanged while handlers still narrow.

The survey also found ContentService.now is a dead field: zero s.now references
in the file, no test seam injecting it, while the sibling services that share
the pattern do use theirs (auth.go reads s.now(), cleanup.go has SetNow). It is
removed as part of the split rather than being assigned a line.

Two risks were falsified by measurement before designing: no code inside the
package reads ContentService's private fields (AccountService holds
repository.ContentStore, not *ContentService, so it is untouched), and the type
is never interface-ised, type-asserted, or used as a method value.

Deliberately out of scope: the 170-line Approve function (its seven phases are
mapped and logged for a later batch — one concern per batch), memory_content.go
(814 lines but a test double with zero non-test references), and handler
error-mapping dedup (92 WriteError sites but only 2 errors.Is checks, so the
duplication does not justify itself).

Verification plan: four gates in the dockerized toolchain plus structural
metrics (content.go under 120 lines, largest of the six files under 300, zero
service.ContentService references left in handlers, zero existing test files
modified) and three mutations the new architecture guard must fail on.
2026-10-03 08:02:53 +08:00
XingfenD 14d029e61b docs: register P13 dark mode (crearte 0.26.0) + server micro-batch (0.17.2)
Brings the P13 batch into this wrapper's version control: spec and plan enter
the repo, ROADMAP gains the P13 row and its document-index entry, and the four
stale 'C dark mode' backlog mentions carried since P9/P10/P9-B/P12 are marked
cleared in place — following the P12 precedent of annotating the historical row
rather than rewriting it, since those entries were true when written.

Wrapper CHANGELOG 0.3.6 records the crearte-only dark-mode delivery
(983e7c4, merge-base e59a171), the parallel server micro-batch delivered during
the survey phase while the implementer owned crearte exclusively (dbf7fe5,
0.17.2: a real uploads.go error-fallthrough defect with zero prior coverage,
plus a decision-record comment on the bundle-key route after grep overturned the
initial suspicion of a hole), and three lessons:

- max(a,b) >= k is a vacuous-assertion hot zone: when the two sides are
  complementary the max has a non-trivial lower bound (here sqrt(16.50) =
  4.0621), so any threshold below it can never fail. The controller's own first
  correction to the scrim guard shipped exactly that, and the same
  one-directional verification recurred in the alpha fallback. Fixing a guard
  now requires proving both no false-red on legal values and no false-green
  under mutation.
- Tailwind v4 scans every source file including test files, so a class-name
  literal in a test comment burns a dead utility into the artifact.
- A universal claim needs a universal grep: 'accent is the only background use'
  was false because both the spike-0 grep and the new guard covered app/ while
  runtime/ sits beside it. That blind spot cost a false spec fact and hid a real
  pre-existing WCAG violation (paper on accent = 3.2590 in light, since P9-B).

ROADMAP's P13 row cites merge commit 983e7c4 per the P12 convention, with the
bookkeeping commits named separately so the reference cannot be mistaken for
them.
2026-10-03 07:30:12 +08:00
XingfenD b9e59aee83 docs: P12 narrow-viewport batch delivered (crearte 0.25.0 / server 0.17.1 / deploy 0.7.1)
Register the P12 spec and plan in the ROADMAP doc index, add the P12 batch row,
and update two backlog lines that this batch's measurements settled:

- The 'mobile header / hamburger menu' backlog entry carried since P9-B is
  falsified and removed: nav content width is only 74-158px and measures zero
  horizontal overflow at 320/360/375/412/768/1280px. Building it would have
  shipped a hamburger menu nobody needs.
- Nav links wrapping per-character at phone widths stays parked pending a
  design decision, not a CSS tweak: it is cosmetic only (no overflow, no
  clipping, no lost function), whitespace-nowrap costs +11px at 320px, and all
  seven gap-reduction variants measured fail at 320px + long name because
  logo 77px + nowrap nav 138-158px + truncated name 96px do not fit. It
  competes for the same pixels as the header fix.
- The P11 polish backlog is partially retired: three of P9-B's four items plus
  P11-N5/N6 are closed by this batch; the remaining nine P11 minor notes are
  documentation-only with no actionable change.

Merged and pushed: crearte e59a171 (0.25.0), crearte-server d56c593 (0.17.1),
crearte-deploy 529a988 (0.7.1). Three task-level reviews plus a whole-branch
final review verdict APPROVE with notes, zero critical and zero important; all
notes adjudicated before merge. The final reviewer independently reproduced
three mutations rather than accepting the controller's claims.
2026-10-02 21:16:43 +08:00
XingfenD 708f95eb3d docs: P11 server-hardening delivered (server 0.17.0 / deploy 0.7.0 / crearte 0.24.1)
ROADMAP P11 row -> 完成 with the D-A->D-A' re-pin narrative; doc index updated;
CHANGELOG 0.3.4 (Done section, bilingual) recording the endpoint-verification
catch: the original subnet-trust design was a rate-limit bypass under compose's
docker SNAT, corrected to an empty TRUSTED_PROXIES default. Register the P11
spec + plan in the doc index.
2026-10-02 03:54:41 +08:00
XingfenD 0e63dc2448 docs: P9-B UX batch-2 bookkeeping — ROADMAP row + doc index + CHANGELOG 0.3.3 (crearte 0.24.0, merged 338acbf) 2026-10-01 23:15:05 +08:00
XingfenD 9226926ebb docs: P10 UX batch-1 booked — ROADMAP P10 row + spec/plan index entry, CHANGELOG 0.3.2 (crearte ee4edf7 / 0.23.0: toast system, dirty-form guard, clickable tags, copy-link, recently-played strip, header dropdown; five legs green vitest 601 / e2e 77+1skip / noauth 4; four review pins) 2026-10-01 20:18:27 +08:00
XingfenD 3eec67513c docs: P9 batch-1 accepted and landed — crearte 26cd625 0.22.0 (five-leg green, review PASS with notes, ISSUE-1/2 pinned pre-merge); spec/roadmap counts corrected to six non-grid consumers (wrapper 0.3.1) 2026-10-01 12:23:19 +08:00
XingfenD 115dfd5fdf docs: ROADMAP P9 row (UX batch-1 browser-feedback pack implemented, pending acceptance; B/C parked) 2026-10-01 12:08:52 +08:00
XingfenD d6e08e1d03 docs: closeout wave landed — P8 batch-2 (server 12b8ffb 0.15.0 / crearte 7d5f338 0.21.0) + P3 reland (deploy 12f7c10 0.6.0 / server d627e12 0.16.0); ROADMAP P0-P8 all closed; spec pinned to reachable 409 semantics (wrapper 0.3.0) 2026-10-01 05:07:56 +08:00
XingfenD 88163fdbcb docs: P8 batch-1 complete — server 921443a 0.14.0, crearte 70ba10c 0.20.0; six-leg green, dual review PASS (note pinned by ee5b960 before merge) 2026-10-01 02:07:36 +08:00
XingfenD 77f4695fbe docs: P8 batch-1 spec+plan (triaged 400s, admin slug guard, race test, CHANGELOG copy, feature-flags UI) + roadmap 2026-10-01 00:59:56 +08:00
XingfenD c7af5d0830 docs: P6 D-D follow-up landed — crearte 9bd9372 0.19.1, four-leg green; review-vs-spec lesson noted 2026-09-30 23:21:11 +08:00
XingfenD 7095ad3775 docs: P6 complete — hosted submission plan A delivered (server 3e11446 0.13.0 / crearte fee5f3b 0.19.0), six-leg green; D-D gap noted 2026-09-30 23:10:19 +08:00
XingfenD d22672a1e4 docs: P6 hosted submission (plan A, self-hosted embed) spec + plan + roadmap status 2026-09-30 22:53:53 +08:00
XingfenD 36286b8a25 docs: P7 complete — admin console delivered (server ca24805 0.12.0 / crearte 900f13a 0.18.0), six-leg host acceptance green 2026-09-30 22:13:32 +08:00
XingfenD eec902b743 docs: P7 admin console spec + plan — audit via admin route group (owner call), last-admin guard, user list w/ role ops 2026-09-30 19:01:45 +08:00
XingfenD 256f0d91b7 Revert "docs: P3 complete — backup+observability delivered (server 7b4e5c8 0.12.0 / deploy e07c9f8 0.6.0), host-verified metrics+logs+backup+drill+full-loop"
This reverts commit 979026e181.
2026-09-30 18:36:31 +08:00
XingfenD 979026e181 docs: P3 complete — backup+observability delivered (server 7b4e5c8 0.12.0 / deploy e07c9f8 0.6.0), host-verified metrics+logs+backup+drill+full-loop 2026-09-30 18:20:05 +08:00
XingfenD e08cd7e7b3 docs: P3 backup+observability spec + implementation plan (design decisions D1/D2/D3 defaulted after unanswered consult) 2026-09-30 17:38:33 +08:00
XingfenD 21dc520a4e docs: creator center executed — plan marked done, changelog 0.2.5 (crearte e2fab8a, pure frontend 0.17.0) 2026-09-30 14:13:23 +08:00
XingfenD 7180dbfdaa docs: P2 complete — CI+test baseline delivered in all three repos (server 7b97108 / crearte 711b6de / deploy 522545d), serve-runtime subdomain fix found by first real-stack run 2026-09-30 12:44:49 +08:00
XingfenD f8fe8482d8 docs: fix typo in creator-center spec 2026-09-30 11:23:27 +08:00
XingfenD 7e7d1ab142 docs: P5 delivered — favorites/ratings full-stack (server e3da246 / crearte eb5fbed), roadmap+changelog 0.2.3 2026-09-30 05:09:23 +08:00
XingfenD 20f5308116 docs: P1 delivered — prod write-side drill merged; plan registered, changelog 0.2.2 2026-09-30 00:47:06 +08:00
XingfenD 8af7ef3501 docs(plan): P1 prod write-side implementation plan (7 tasks, TDD on nginx template)
- docs/plans/2026-09-29-prod-write-side.md: crearte nginx template ->
  crearte-deploy compose/.env/README -> four-profile config gate -> prod
  live run + curl smoke chain (write side + wildcard subdomain runtime)
  -> merges with --no-ff -> wrapper bookkeeping
- docs/ROADMAP.md: register plan in doc index
- facts pinned from recon: no .env/no crearte volumes on this box (fresh
  env), :? guards are file-wide (not per-profile), curl needs --resolve
  for *.localhost, set-role invalidates tokens (re-login required)
2026-09-29 23:08:18 +08:00
XingfenD 0131d21ea4 docs(spec): P1 prod write-side design (self-contained local drill, option A)
- docs/specs/2026-09-29-prod-write-side-design.md: minio-prod on 9001,
  api-prod STORAGE_S3_*/GAMES_BASE_DOMAIN/CORS env, POSTGRES_PASSWORD
  default removed chain-wide, nginx wildcard block templated + /api/
  proxy (guarded repo-yaml.test.ts updated), TLS explicitly out of scope
- docs/ROADMAP.md: P1 status -> spec written, doc index registered
2026-09-29 22:22:01 +08:00
XingfenD bab22940bd docs: roadmap P0 and P4 delivered and merged
- ROADMAP.md: P0 (server a8ea755 / deploy 27044be) and P4 (crearte
  f12cbf1) marked complete with merge commits; plan index annotated
- CHANGELOG.md: 0.2.0 delivery entry
2026-09-29 19:23:23 +08:00
XingfenD d814914e21 docs(plan): P4 author page implementation plan
- docs/plans/2026-09-29-author-page.md: 3 TDD tasks (AuthorView+route,
  entry links, e2e+changelog) with containerized npm commands per
  HANDOFF toolchain notes
- docs/ROADMAP.md: register plan in doc index, P4 status update
2026-09-29 16:04:20 +08:00
XingfenD 2f3bade817 docs(spec): P4 author page design (pure frontend aggregation)
- docs/specs/2026-09-29-author-page-design.md: /users/:user pure
  aggregation page, minimal list, zero backend/migration changes
- docs/ROADMAP.md: P4 scope refined per design (frontend filtering
  instead of API author filter), register spec in doc index
2026-09-29 15:40:27 +08:00
XingfenD 0b25a39e7b docs: add cross-repo roadmap and centralize doc conventions
- docs/ROADMAP.md: decompose enhancement work into sub-projects P0-P8
  (ops foundation -> product value -> governance) with ordering rationale
- docs/CHANGELOG.md: start the wrapper changelog
- AGENTS.md: monorepo wrapper role, master-direct commits scoped to the
  wrapper, all specs/plans live in this repo's docs/ from now on
2026-09-29 15:12:15 +08:00