Skip to content

feat(kits): batch B-arch — Simple/Advanced color mode contract (no code)#24

Merged
simonsangla merged 1 commit intomainfrom
batch-b-arch-simple-mode-contract
Apr 16, 2026
Merged

feat(kits): batch B-arch — Simple/Advanced color mode contract (no code)#24
simonsangla merged 1 commit intomainfrom
batch-b-arch-simple-mode-contract

Conversation

@simonsangla
Copy link
Copy Markdown
Owner

Summary

Architecture-only spec for the deferred Batch B (Simple/Advanced color mode), per AGENT_HANDOFF.md Batch A "Next recommended batch" section. Locks the contract before any implementation code lands. Pure cavekit edits — zero source, schema, or test changes.

From AGENT_HANDOFF.md Batch A:
"Batch B — 2-color Simple mode + Advanced overrides (deferred). Ship the deterministic derivation from Primary + Neutral (secondary = primary hue-shifted +40°; background / text / muted / hairline / inkSoft / surfaceInvert / onInvert derived from neutral via fixed L values). Persist colorMode + per-slot colorOverrides as optional fields on PersistedRecord (no ThemeConfigSchema change). Advanced stays fully available; auto/override state shown per slot. Back-compat: legacy records load as Simple with empty override map."

Changes (4 files, all under context/kits/)

File Change
cavekit-editor.md New R11: Color Mode (Simple / Advanced) with 9 testable acceptance criteria. R1 annotated as mode-aware.
cavekit-persistence.md New R8: Optional Color-Mode Fields on Persisted Record (colorMode, colorOverrides — both omittable, no version bump, legacy records load as Simple with empty overrides). R6 clarified that wrapper-field additions don't bump version.
cavekit-product-boundary.md Changelog-only entry — Simple/Advanced confirmed in-scope under R1 capability "Theme design via interactive controls". R1/R2/R3/R4 text unchanged.
cavekit-overview.md Domain index counts updated (Editor R1–R11, Persistence R1–R8). Coverage Summary 53 → 55. New Editor→Persistence cross-ref.

Constraints honored

  • No code, no tests, no schema touchedgit diff --stat shows exactly 4 files, all under context/kits/
  • Boundary R2 unviolated — no backend, auth, DB, CMS, routing, SSR, drag-drop, plugin system, analytics, motion, theme marketplace
  • Schema version stays at 1 — back-compat via optional fields + read-time defaults
  • Catalog stays at 11 widget IDs in alphabetical order
  • Out of scope for this batch: preset redesign, new template/theme families, "modern/smooth/funny" template aesthetics — deferred to a later dedicated product batch after Batch B implementation

Preflight

  • gh pr list --author app/dependabot --state open — empty
  • Working tree clean on main before branching
  • AGENT_HANDOFF.md Batch A read for derivation rule

Verification

Gate Result
git diff --stat 4 files, all under context/kits/
grep -c '^### R' cavekit-editor.md 11 (was 10)
grep -c '^### R' cavekit-persistence.md 8 (was 7)
grep -c '^### R' cavekit-product-boundary.md 4 (unchanged)
npm run lint 0 errors
npm run typecheck pass
npm run test 267/267
npm run build pass (vite ~101ms, 21.39kB CSS / 295.78kB JS)

Test plan

  • Lint pass on new kit prose
  • Typecheck unchanged (no source touched)
  • All 267 existing tests still pass
  • Build pass
  • Re-read R11 and R8 end-to-end — structure matches cavekit format (Description, Acceptance Criteria, Dependencies, Changelog)
  • CI green
  • Per AGENTS.md: review PR comments + formal reviews + checks before merge

Next batch

Batch B-impl — wire R11 + R8 into editor/store/persistence. Add tests for derivation determinism and round-trip preservation. Stays within R1 capabilities; no new boundary revisions required.

Architecture-only spec for the deferred Batch B (Simple/Advanced color
mode), per AGENT_HANDOFF.md Batch A "next recommended batch" section.
Locks the contract before any implementation code lands.

Editor R11 (new): Simple shows 2 controls (Primary, Neutral) + derives
the other 7 deterministically; Advanced shows all 9 with no derivation.
Mode switches are undoable. R1 annotated as mode-aware.

Persistence R8 (new): optional `colorMode` and `colorOverrides` fields
on the PersistedRecord wrapper; both omittable; legacy records load as
Simple with empty overrides; schema version stays at 1. R6 clarified
that wrapper-field additions don't bump version.

Product Boundary: changelog-only confirmation that Simple/Advanced
falls under R1 capability "Theme design via interactive controls" —
no R revision required.

Overview: domain index counts updated (Editor R1–R11, Persistence
R1–R8, total reqs 53 → 55), Editor→Persistence cross-ref added.

Zero src/, tests/, or schema changes. Boundary R2 unviolated. Catalog
unchanged at 11 widget IDs.

Gates: lint 0, typecheck pass, test 267/267, build pass.
@vercel
Copy link
Copy Markdown

vercel bot commented Apr 16, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
theme-forge Ready Ready Preview, Comment Apr 16, 2026 5:47pm

@simonsangla simonsangla merged commit 0c1cbce into main Apr 16, 2026
3 checks passed
@simonsangla simonsangla deleted the batch-b-arch-simple-mode-contract branch April 16, 2026 17:48
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 75fc7c5f11

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +14 to 16
**Description:** The editor must expose one editable control per color slot defined by the schema. Each control must allow the user to set a valid hex color and reflect the current value. Control rendering is mode-aware per R11 (Simple shows 2 controls; Advanced shows all 9).
**Acceptance Criteria:**
- [ ] One control is rendered for each color slot in the active theme
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Align R1 acceptance criteria with Simple mode contract

R11 introduces a valid Simple mode where only two color controls are shown, but R1 still requires rendering one control for each color slot; these requirements cannot both be true in Simple mode. This creates an internally inconsistent spec that will cause implementers/tests to fail one requirement while satisfying the other, so R1’s acceptance criteria should be made explicitly mode-conditional (or scoped to Advanced mode only).

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new 'Simple/Advanced' color mode for the theme editor, allowing users to either derive secondary colors deterministically or edit all nine slots independently. The changes span the editor requirements, persistence schema, and the project overview. Feedback focuses on logical inconsistencies between the editor and persistence requirements regarding how overrides are handled and discarded, as well as potential data redundancy in the persistence layer. A suggestion was also provided to clarify the architectural relationship between the Editor and Persistence domains in the overview documentation.

**Dependencies:** none

### R11: Color Mode (Simple / Advanced)
**Description:** The editor must expose a Simple ↔ Advanced color-mode toggle. Simple mode renders exactly two color inputs (Primary, Neutral) and derives the remaining seven color slots deterministically from those two inputs (per the Batch A handoff rule: secondary = primary hue-shifted +40°; background, text, muted, hairline, inkSoft, surfaceInvert, onInvert derived from neutral via fixed L values; exact derivation values are intentionally left to the implementation cavekit-revision or to the implementation batch). Advanced mode renders all nine color controls with no derivation, each independently editable. Switching Advanced→Simple discards manual overrides for the seven derived slots and resumes derivation. Switching Simple→Advanced seeds the nine controls with the currently displayed (derived) values, treated as overrides going forward. The mode is persisted across sessions via cavekit-persistence.md R8.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

There is a logical inconsistency between the definition of Simple mode here and the persistence requirements in cavekit-persistence.md R8. This requirement states that switching from Advanced to Simple discards manual overrides. However, R8 describes colorOverrides as values applied "on top of" the derived base and requires persisting them even in Simple mode. If Simple mode is strictly deterministic and discards overrides upon entry, the colorOverrides field appears redundant or incorrectly defined.

**Dependencies:** R1, R2

### R8: Optional Color-Mode Fields on Persisted Record
**Description:** The PersistedRecord may carry two optional fields — `colorMode` (a string equal to `'simple'` or `'advanced'`) and `colorOverrides` (a partial map of `ColorTokens` representing user-edited slot values applied on top of the Simple-mode-derived base). Both fields are omittable. The persistence schema generation (version) stays at 1; legacy records lacking these fields load as Simple mode with an empty override map. `ThemeConfigSchema` is NOT extended — these fields live on the PersistedRecord wrapper around the theme.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The colorOverrides field seems redundant given the existing architecture. Since ThemeConfig (the theme field in the PersistedRecord) is the single source of truth for all domains and already contains all 9 color slots, any manual edits made in Advanced mode are already captured within that object. Storing them separately in colorOverrides introduces data duplication and potential synchronization risks between the theme and the overrides map.

**Description:** The PersistedRecord may carry two optional fields — `colorMode` (a string equal to `'simple'` or `'advanced'`) and `colorOverrides` (a partial map of `ColorTokens` representing user-edited slot values applied on top of the Simple-mode-derived base). Both fields are omittable. The persistence schema generation (version) stays at 1; legacy records lacking these fields load as Simple mode with an empty override map. `ThemeConfigSchema` is NOT extended — these fields live on the PersistedRecord wrapper around the theme.
**Acceptance Criteria:**
- [ ] PersistedRecord shape accepts records with or without the `colorMode` and `colorOverrides` fields without error
- [ ] At save time, when the editor is in Simple mode the record persists `colorMode='simple'` plus any active overrides; when in Advanced mode the record persists `colorMode='advanced'` plus the full override set
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This acceptance criterion specifies that in Simple mode, the record persists "any active overrides". This contradicts cavekit-editor.md R11, which states that switching to Simple mode discards all overrides. If the overrides are discarded by the editor, they cannot be persisted as "active" while in Simple mode.

| Export | Editor | Reads active theme on demand (read-only, no mutation) |
| Persistence | Schema | Validates records on save, restore, and import |
| Persistence | Editor | Saves active-theme changes; supplies restored or imported themes via the editor's external-adoption interface |
| Editor | Persistence | Persists `colorMode` + `colorOverrides` per cavekit-editor.md R11 / cavekit-persistence.md R8 |
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The interaction description "Persists colorMode + colorOverrides" suggests that the Editor domain is the active agent performing the persistence. However, the existing architecture (line 31) defines the Persistence domain as the actor that saves changes by observing the Editor. To maintain consistency, this should be phrased to show that Persistence reads these fields from the Editor.

Suggested change
| Editor | Persistence | Persists `colorMode` + `colorOverrides` per cavekit-editor.md R11 / cavekit-persistence.md R8 |
| Editor | Persistence | Supplies `colorMode` and `colorOverrides` for storage per cavekit-editor.md R11 / cavekit-persistence.md R8 |

simonsangla added a commit that referenced this pull request Apr 16, 2026
Records the merged kit-only batch (PR #24, commit 0c1cbce) that locks
the Simple/Advanced color mode contract via Editor R11 + Persistence
R8. Names Batch B-impl as the next recommended batch.
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