55 Commits
Author SHA1 Message Date
XingfenD d70991b0ad docs: book P15-B as delivered (wrapper 0.3.9, ROADMAP ledger section)
P15-B merged to crearte master as 7f91fa3 (0.27.0, merge-base f823195, thirteen
commits across two fix-forward rounds). P15 is now fully landed.

Three things this entry records that a routine booking would omit.

The whole-branch review blocked the batch - the second time it has done so after
P11 - and its critical finding was in the guard layer rather than the product:
maskSourceComments() compared a two-character slice against the four-character
'<!--', so its HTML-comment branch never ran, producing two false greens and
three false reds and making two already-committed claims false. Product code
needed no change; one added line and one changed comparison closed it.

The second round was executed by the controller rather than the dispatched
subagent, which ran 1h25s and failed with no output, leaving nothing to salvage.
The controller produced one false green of its own on the way - a mutation round
whose anchor failed to match was scored as meeting an expectation that happened
to be an empty list, the same defect the reviewer had caught in itself.

The e2e suite carries a pre-existing flaky leg at roughly one run in three
(core.spec.ts's worker leg: helpers.ts reads an async-postMessage attribute with
a bare getAttribute and no retry). Every file involved has zero diff against the
batch base and all four legs this batch added were green in all three review
runs. Recorded so the next red CI run is not attributed to this release.

ROADMAP also gains a standing ledger section, which the roadmap never had: the
cross-batch items accumulated by P15's two review rounds and the branch review,
each with its measured basis rather than an aspirational note. It includes the
revival of feat/submission-preview - the inline play-test preview for the submit
form and the review page, which the user asked about and which turns out to be
delivered work sitting unmerged in two paired remote branches (crearte a3cb5e3,
crearte-server 6b072d6, 27 tests, zero residue on master), together with the two
hard collisions that make reviving it a real batch rather than a rebase.
2026-10-04 04:14:09 +08:00
XingfenD 51bed55704 docs(spec): close the P15-B branch review's document-side findings
The P15-B branch review returned "needs fixing before merge" on a critical gap
in the guard layer. The code side is with a second fix-forward; this commit
closes the document side, which is the controller's.

F-FINAL-4 - the leg-8 cell carried a one-line regex that the controller wrote
into the spec during re-pin. It was worse than the version in the adjudication
it copied: 4 of 7 attribute forms fail rather than 2, because markdown escaping
turned the alternation bar into a literal bar and `'[^']*'` was mistyped as
`'[^'*]`. The controller had checked that every table row has the same number of
pipes as the header, but never checked that the escaped code was still the code
it came from. The cell now describes the implemented approach (extract every
style attribute value in all three quoting forms, strip quotes, test each for
color:) and deliberately carries no regex literal, with the reason stated: an
escaped bar inside a table cell is a literal character in the regex. Read the
code entity for the pattern.

§6-1 - leg 9 was never re-pinned: the spec still said "length > 500" while the
code says 4000 plus three structural preconditions. Corrected, with the unit
spelled out (source characters 4423, not the built artifact's 7056/7588).

§6-2 - "the only discriminating grid" survived re-pin in four places; the
review measured two legs reddening on a real decision-order defect. Narrowed to
"the only discriminating grid on the child-side direct-visit path" here and in
the plan. The two occurrences in code comments belong to the fix-forward.

§6-3/§6-4/§6-5 - the §1.2 count now states which tree it came from (base 66,
HEAD 67, the extra one being this batch's own note text quoting the figure); the
§4 boundary table lists the e2e spec it had omitted; D-G says "form aligns"
rather than "aligns verbatim", since the script bodies differ by design (the
main app has one more level, 16 token-level differences).

F-FINAL-1 - two claims already committed are corrected rather than deleted. The
§3.1(a) annotation and the §7 risk row both rested on "maskSourceComments()
neutralises the trap comment, so the guard does not depend on the implementer's
wording discipline". That is true for the file in question, but only because the
trap comment happens to use `//`: the function's HTML-comment branch compared a
2-character slice against a 4-character literal and never ran. Merely rewording
a comment reddened up to four legs while the e2e suite stayed green.

§8 gains the census case for discipline 15 (an unlanded census script is why the
48-versus-47 discrepancy is still untraceable), plus disciplines 16 and 17:
every evidence file a report cites must be ls-checked before delivery, and
executable details in a spec must be grepped from the code entity or recomputed,
never hand-written. Discipline 17 records this batch's three instances, one of
them a contrast ratio cited twice by two documents and recomputed by nobody
(3.0269; the actual value is 2.5519, which no grey background produces).

Post-write checks: 25/25 assertions, 11 table blocks with 0 column anomalies,
16 code fences paired, 25 headings with no duplicates, copyable-block cleanliness
scanned across 8 blocks.
2026-10-04 02:53:53 +08:00
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 9061c39ef3 docs(spec): close the P15-A branch review's A1 and A3 advisories
A1 - the four-gate line said `internal/api ~11.0s 含真库集成`. It does not
include the real-database integration tests: without TEST_DATABASE_URL they
skip silently, and the 11s is the mock path. The wording mattered because it
hid the fact that every run in this batch - implementer, task reviewer,
fix-forward and controller alike - skipped them, including the two
concurrency/TOCTOU guards that §1.6 names as the behavioural evidence for
phase six. Replaced with the measured picture: 4 skips in internal/api, 26
`--- SKIP` lines repo-wide, and the full list of the 11 Test functions gated
on that variable (cmd 2, api 4, repository 2, service 3). Also recorded the
branch review's DB-parity run - base fe810dd 194 PASS/0 FAIL versus HEAD
b15c2a8 199 PASS/0 FAIL, +5 being exactly this batch's new guards, state
multisets identical - which is the first runtime proof of zero behaviour
change on the postgres path; everything before it was static. The
pre-merge checklist now has to include a DB-enabled comparison or the next
batch skips them again.

A3 - fix-evidence/rv-t3-v2-filtered.py prints 6 ORDER VIOLATIONS while the
fix report's prose says both trees have 0. The prose is right and the script
is the artefact: it assigns repeated text lines to destinations with a greedy
pop(0), so identically-named lines land in the wrong bucket. The branch review
redid the check with an unambiguous-unique-text method and got pre=0, post=0.
Annotated the archived script in place (it lives in the gitignored evidence
area, kept for auditability) so nobody cites its violation count as evidence
again, and pointed at the review's §12 reproduction method.

Post-write checks: 20/20 assertions, 12 table blocks with 0 column anomalies,
8 code fences paired, 28 headings with no duplicates, and the annotated script
still passes py_compile.
2026-10-04 02:18:08 +08:00
XingfenD 37a0a8ddd1 docs(spec): close the P15-A branch review's N1-N4 staleness in the A spec
The full-branch review of chore/p15a-approve-phases returned APPROVE with
notes: the merged branch code itself has zero defects, but four places in this
spec disagreed with the code it describes. All four came from the controller
writing executable details from memory during the first re-pin.

N1 - applyApprovalInTx parameter order, three places (D-C row, the §3.1
skeleton call site, the §3.2 phase-six signature). The spec said
`plan approvePlan, submissionID`; the code has always been
`submissionID string, plan approvePlan`. The implementer's order is legal and
better: a scalar identifier before an aggregate matches Go convention.

N2 - §3.2 migration ranges the first re-pin claimed to have fixed but had not:
48-85 -> 48-86 (86 is the closing brace of the coverUpload block) and
87-100 -> 88-101 (87 is a blank line, 88 is `switch sub.Kind`).

N3 - the §1.2 difference-table header: phase four 87-100 -> 88-101, phase six
136-186 -> 136-199 (186 is a mid-branch line inside MetadataChange; 199 is the
closing brace of the switch).

N4 - §T1.4 said the CG2 needle's only hit is `:196`, which is the pre-F9 line
number from dda3fe8; HEAD measures `:201`. The (b) blind-spot note said
"126-200 = 77 lines"; 126-200 is 75 lines - 77 belongs to the §1.1 range
125-201 and was carried over by mistake.

Every corrected value was re-derived from the base tree fe810dd and HEAD
b15c2a8 line by line rather than copied from the review, and the two
derivations agree. A RE-PIN note at §3.2 phase six records the true values and
the lesson, which §8 discipline 11 now states as a rule: executable details in
a spec (regexes, signatures, literals, line ranges) must be grepped out of the
code entity and pasted, never hand-written.

Post-write checks: 20/20 assertions, table column counts unchanged (12 blocks,
0 anomalies), 8 code fences paired, 28 headings with no duplicates.

Closes N1-N4 of crearte-server/.superpowers/sdd-p15a/final-review-report.md.
N5 (the verification artifact's fake rigor) is closed separately in the
gitignored evidence area: verify-fix-v8.py now runs 106 real checks with zero
bare prints, and the v2 output it cites is archived on disk.
2026-10-04 02:00:45 +08:00
XingfenD 02188eb3e0 docs: re-pin both P15 specs after task-level review adjudication
Twenty-four pinned corrections across the two specs and their plans, every one
traced to a measured finding. Both task-level reviewers overturned claims I had
written into the specs, and I reproduced each against the base tree before
accepting it (git show, never the working tree, which already carries the fix).

P15-A spec gains two sections. T1.4 records the reviewer's candidate guard for
phase-independence: the spec called "do not merge phases four and six" the most
important constraint in the batch, yet its only stated mitigation was the
byte-level comparison, which is one-shot evidence — after the report is filed,
nothing reddens when someone merges them. The reviewer built CG1/CG2/CG3 and
verified them both ways: green on the legal tree, red on four distinct merge and
degeneration forms, all assertion-red rather than compile-red, while the three
shipped guards stayed green throughout. T4 records the adjudication of nine
findings, including two that undercut the guard the batch itself added: a
half-finished dir parameter that redirects which files are counted but not which
are read, so a scan pointed elsewhere can satisfy its own precondition while the
169-line function it exists to catch stays invisible; and a span scanner keyed to
line-initial func, which means a 125-line package-level closure passes all four
gates and all three guards. Also pinned: the gofmt gate in the four-gate recipe.
gofmt -l lists unformatted files and still exits zero, so the recipe everyone ran
reported gofmt_exit=0 as evidence of formatting cleanliness. Implementer and I
shared that recipe, which is why the same blind spot was computed twice and
caught by neither.

Phase intervals are corrected to the real base-tree line numbers. The prior text
told the implementer to move lines 212-213 into a helper; 213 is the slog.Info
the same spec requires to stay in the caller, so following it would have swapped
what moves with what stays. Phases six and seven also overlapped, each claiming
the transaction error mapping. The skeleton now passes a pointer where its own
note eighteen lines later demanded a pointer receiver, and the transaction
helper's signature carries submissionID, which removes the batch's dependence on
a cross-repository equality argument for the only acceptance criterion it has.

P15-B spec corrects the artifact criterion I had backwards. I wrote that deleting
a token should change the var(--color-*) count; that count measures usage, the
token had zero usage across seven utility suffixes, and it stayed at 75. Had it
moved, that would have meant something referenced the token, contradicting the
dead-token premise. Definition-side and usage-side are separate measures and the
spec now says so.

Leg five is re-pinned as critical. It was the sole enforcement point for the
non-reactive injection decision, and it only pinned literal form: two
type-legal variants that establish the dependency elsewhere in the computed body
pass all ten legs with vue-tsc clean, and the reviewer proved by effectScope
evaluation counting that both really do make the iframe src flip on a theme
change, reloading a running game. The narrowing was introduced by the
implementer's own fix, to avoid a trap comment that spells out the forbidden
literal; but comment masking already neutralizes that comment, so the narrowing
was unnecessary and the second line of defense created the gap. Same shape as
the P14 final review finding a hole in the first round's fix.

Also pinned: the rejected deviation five, with the corrected root cause (all four
freeze attempts used page.route, which does not intercept service worker
registration, worker-issued requests, or navigations synthesized by respondWith;
context.route holds the loading screen past 25 seconds); the missing
dark-system-times-light-hash grid that one mutation slipped past all ten source
legs and all five e2e legs simultaneously; the fourth tautology class the spec's
three warnings omitted, where emptying a loop's driving collection makes it
vacuously true; legs seven and eight, which respectively substring-searched a
hex that occurs three times in the file and matched only double-quoted style
attributes; the copyable code block's comment, which now avoids the three
literals that would false-redden a correct implementation, with the annotation
moved outside the block; and three new discipline entries covering untested
method scope, measurement units, and retaining one-off verification scripts.

Every correction was checked by a script asserting both directions — the pinned
text present and the superseded text gone — plus table column integrity, fence
pairing, and code-block cleanliness. Three earlier attempts at this re-pin failed
on my own errors and were fixed before commit; the working tree was never left in
a half-edited state.
2026-10-03 19:48:48 +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 33c2d8d4b8 docs: re-pin the P14 spec after branch-review adjudication
The branch review approved with notes but overturned two universal claims I had
already committed to the spec. Both overturns were independently reproduced
before acting on them, and both were correct.

FR-1 (important): assertion 5's source scan required a NAMED receiver, but Go
permits omitting an unused one, and a shadowing body is exactly the case that
often needs none. Under func (*ContentService) CoverURL(...) the old pattern
matched nothing, so build, vet and all seven assertions stayed green while the
shadow was effective. The regex literal in §5-T1.5 is corrected to the optional
group now in the code, and the claim that assertion 5 is the only mechanical way
to catch shadowing is scoped: it was false before the fix, and after it the
assertion's reach is wider than the original text said, because NumMethod()
exposes only exported names — so an unexported root method is also caught by the
source scan alone.

FR-5: my adjudication of F4 said the two layers 'cover completely'. That is a
universal claim and an orphan private helper on the wrong line is its
counterexample (assertion 2 filters on IsExported, and Go does not report unused
methods). The wording is narrowed to what the layers actually cover, with the
reason the verdict still holds: the third layer can only ever produce dead code.

Both are recorded as instances of the same defect I keep committing — stating a
conclusion before establishing its range. §8 rule 5 already required universal
claims to have universal-range evidence; these were two places I did not follow
my own rule.

The lesson is written into the spec rather than only the ledger: when claiming a
guard is the only thing that catches a failure mode, enumerate the forms first
(named/unnamed receiver, value/pointer, exported/unexported), or the claim
becomes the next reviewer's counterexample.
2026-10-03 12:26:55 +08:00
XingfenD 11fa1e2d26 docs: re-pin the P14 spec after task-review adjudication
The task-level review rated the split PASS with notes and found that the
architecture guard did not cover one of the three purposes spec D-J states for
it. Six places are corrected here before the branch review reads the spec, so
the reviewer works against a frozen target rather than a moving one.

- D-J is amended from three assertions to seven. The original three each have
  teeth (verified by mutation) but together they missed an entire dimension:
  nothing enumerated the composition root's own method set, so adding a method
  there left all three assertions PASS, go build/vet clean, and the full
  11-package suite green. The god object could regrow silently.
- The mutation list gains d through h, and mutation (a) is annotated with the
  bypass the review found in my own positive control: (a) turns red because it
  REMOVES CoverURL from CatalogService, not because anything detects the extra
  root method. Rewritten as a copy that keeps the original — the shadowing form
  (e) — mutation (a)'s design would have passed green.
- Two fixes the review proposed are recorded as rejected, with the spike
  measurements, so they are not retried: asserting NumMethod()==0 on the value
  type is unsatisfiable because embedding *T puts its methods in both method
  sets (the legal tree already reports 22 — vacuously false, the mirror image of
  P13's vacuously true assertion), and Method.Func identity cannot detect
  shadowing because promoted methods are forwarding wrappers that already differ
  on the legal tree (5153408 vs 5148192 unshadowed, 5148288 vs 5148192
  shadowed).
- Line counts are pinned to the wc -l convention, verified against the same
  convention used for the 856 baseline and auth.go's 234. The metrics table gains
  a measured column: content.go 82, largest of the six files 298 (moderation.go,
  not submission.go as the spec predicted).
- D-D records that ErrSubmissionConflict is also used by AccountService at
  account.go:136, outside the submission and moderation lines, which makes the
  SHARED ruling necessary rather than merely correct.
- The risk table gains two Route C properties that were previously only in
  controller notes: the root has no named fields so s.objects is an ambiguous
  selector (a compile-time barrier earlier than the guard, and the reason the
  guard is the ONLY barrier against adding a concrete field), and go vet stays
  silent on a root method shadowing a promoted one (vet_exit=0 measured), which
  is why assertion 5 cannot be replaced by a reflect-based check.
2026-10-03 10:36:58 +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 015c2b9696 docs: P9-B spec §1/D-F th count corrected to element-level 24 (19 was line-count; adopted from T3 review note 3) 2026-10-01 22:49:51 +08:00
XingfenD 35b50539c6 docs: P9-B spec D-I re-pinned — persistent sr-only announcer (live region must pre-exist its text; per-toast role=status would mute the first message) 2026-10-01 21:43:31 +08:00
XingfenD 0a7eba2682 docs: P9-B spec + implementation plan (a11y/keyboard batch — WCAG contrast tokens, toast live-region restructure, skip-link, SPA focus management, table column-header scope, star accessible names) 2026-10-01 21:26:32 +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 67f7a802d1 docs: P9 batch-1 plan (U1-U7 anchors) + implementer brief — feat/p9-ux-titles on crearte, five-leg acceptance 2026-10-01 12:03:09 +08:00
XingfenD 1fca6f1c53 docs: P9 UX batch-1 spec — browser feedback pack (router-level document.title two-phase + game-page description + skeleton variant align); B/C batches parked (owner picked A from UX survey) 2026-10-01 12:01:44 +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 f1d8d9858b docs: P8 batch-2 spec+plan — account deletion (tombstone migration 0011, DELETE /api/auth/account, user delete CLI) + catalog export CLI (static fallback feed) + P7 error-copy tail; P3 relanding recorded as history-replay (owner's 3rd roadmap directive: implement everything pending) 2026-10-01 04:06:56 +08:00
XingfenD 5d20189d46 docs: crearte-deploy 0.5.2 chore — backups/ gitignored (wrapper 0.2.9) 2026-10-01 02:41:09 +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 820914f0f1 Merge branch 'master' of git.yoresee.cc:XingfenD/crearte-monorepo 2026-09-30 11:27:23 +08:00
XingfenD 34fbbe608d docs: creator center implementation plan; fix spec changelog version to 0.17.0 (master top is 0.16.0) 2026-09-30 11:26:42 +08:00
XingfenD f8fe8482d8 docs: fix typo in creator-center spec 2026-09-30 11:23:27 +08:00
XingfenD 7a6262f5ce docs: P2 CI+test baseline design + 5-task plan (e2e-stack hosts in server repo per private/public token asymmetry) 2026-09-30 10:39:16 +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 a6b4328edf docs: P5 favorites/ratings design + implementation plan (7 tasks, dockerized go tests) 2026-09-30 02:32:38 +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 cc2156b44d fix(clone): pin master as the bootstrap branch for crearte and crearte-server
The pins still named the feat/submission-preview work branch, so fresh
clones landed on WIP instead of the integration branch.
2026-09-29 21:38:48 +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