feat(play-ui): HARD/EXPERT adaptive hidden-rule builder (+ stacked difficulty features)#1
Open
irregular6612 wants to merge 20 commits into
Open
feat(play-ui): HARD/EXPERT adaptive hidden-rule builder (+ stacked difficulty features)#1irregular6612 wants to merge 20 commits into
irregular6612 wants to merge 20 commits into
Conversation
Thread easy/hard/expert into the signal_game task_config; validate against VALID_DIFFICULTIES (medium excluded). Default easy preserves current behavior. num_few_shot stays fixed at 2. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3-phase design: rebase worktree onto latest main (main untouched), add difficulty column to sessions table (sqlite+postgres, backfill 'easy'), wire campaign-level difficulty selector into the human Play UI, and fix /api/new_game to return 400 (not 500) on unknown difficulty. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
7-task plan: rebase onto main (Task 0), SQLite+Postgres difficulty column with idempotent migration (Task 1-2), tag write-sites (Task 3), /api/new_game 400 validation (Task 4), Play UI selector + campaign-level state + checkpoint (Task 5-6), regression + browser smoke (Task 7). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ration Add SessionRecord.difficulty (default easy). SQLite schema, idempotent ADD COLUMN migration (backfill 'easy'), INSERT and row-map wired. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Column, idempotent ADD COLUMN IF NOT EXISTS migration, INSERT, both SELECT column lists, and positional row-map unpack all carry difficulty. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LLM (seeding.build_session_record) reads season['difficulty']; human (api.new_game finish) reads SeasonResult.difficulty.value. Both flow into sessions.difficulty. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Validate req.difficulty against VALID_DIFFICULTIES before constructing HumanGameSession, matching /api/arena/run's style. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…point playScreen.difficulty (default easy) sent in /api/new_game body and persisted in the resume checkpoint (schema v2, easy fallback for v1). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reuses squidArenaHelpers.difficultyOptions + cond-card classes; lives inside the !started setup card so difficulty is locked once a campaign begins. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Rule-inference probe UI is currently EASY-only (single-attribute chip builder with no difficulty branching); HARD (2-attr conjunction) and EXPERT (+history override) players cannot express the correct rule. Backend score_probe already supports all three grammars, so the fix is frontend-only. Spec covers adaptive inline-sentence builder, exact grammar contract, state model, and a Python contract regression test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Dq7Rij3bV64YNZKLMBYkzX
4 tasks: (1) Python grammar contract test, (2) app.js difficulty-aware state + assembledRule, (3) index.html adaptive inline builder, (4) E2E localhost verification. Backend untouched. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Dq7Rij3bV64YNZKLMBYkzX
Subagent-driven execution prompt. Reuses the existing worktree (no new one), pins localhost E2E server commands, and restates global constraints. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Dq7Rij3bV64YNZKLMBYkzX
HARD/EXPERT probe strings the web rule-builder will emit must score 100 against score_probe. Constants are the SSOT for web/app.js assembledRule.
Add HARD/EXPERT probe slots (attr_2, val_2, partial action, override), valueOptions2/attr2Choices/setAttr2, and a difficulty-branched assembledRule emitting the conjunction / history-override grammars. Format kept in sync with the probe grammar contract test.
Wrap the single-attribute builder in an easy/medium branch and add hard/expert branches: two-attribute conjunction with a read-only attr_1 echo in the partial clause, plus an EXPERT history-override chip row. Gate hint now difficulty-aware.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
개요
웹 아레나 Play 플로우의 히든 룰 추측 UI를 HARD·EXPERT 난이도에서도 정답 룰을 구조적으로 표현할 수 있게 확장한다. 기존에는 EASY 단일 속성 4-칩 빌더에 고정되어, HARD(2속성 논리곱)·EXPERT(+히스토리 override)에서 플레이어가 정답 룰을 입력할 칸 자체가 없었다.
백엔드 무변경 — 채점기
SignalGameModule.score_probe는 이미 3개 문법(EASY 4슬롯 / HARD 7슬롯 / EXPERT 10슬롯)을 지원하므로 프론트엔드만 확장했다.이번 세션 변경 (HARD/EXPERT 룰 빌더)
tests/unit/test_signal_game_probe_contract.py, 신규): 프론트가 emit할 룰 문자열 포맷을 Python 상수(FRONTEND_HARD_FORMAT/FRONTEND_EXPERT_FORMAT)로 못박고, 그 문자열이 실제score_probe에서 100점을 받는지 검증. 프론트↔백엔드 문법 드리프트(조용한 0점)를 CI에서 차단하는 SSOT.web/app.js: 신규 상태 변수 4개(probeAttr2/probeValue2/probeActionPartial/probeOverride), gettervalueOptions2/attr2Choices, methodsetAttr2, helper_hardClause, 난이도 분기assembledRule(단일 속성 / 2속성 논리곱 / override+논리곱 문법 emit). EASY/MEDIUM 경로 무변경,medium은 방어적으로 EASY 경로.web/index.html+web/styles.css: 기존 단일 속성 빌더를 easy/mediumx-if로 감싸고(내부 마크업 무변경), hard/expertx-if블록 추가 — 2속성 논리곱 + partial 절의 attr_1/val_1 읽기 전용 echo(.chip-echo) + EXPERT 전용 히스토리 override 칩 행. gate 힌트 난이도 분기.문법 계약
If <a1> is <v1> and <a2> is <v2> then <both>; if only <a1> is <v1> then <partial>; otherwise <default>.If your previous action was correct then <override>; otherwise follow this rule:+ HARD검증
test_signal_game_probe_contract+test_signal_game_v3= 43 passed.app.js_hardClause/assembledRule↔ scorer 정규식(_score_medium_template/_score_hard_template) byte 일치. HARD→medium, EXPERT→hard dispatch 정확.POST /api/new_game·/api/action모두 HTTP 200(400/500 없음), Alpine 파싱 에러 없음.알려진 비차단 Minor (연기)
attr2Choices가 3속성 목록 하드코딩(현재ATTR_VALUES가 정확히 그 3개 → active bug 아님, 4번째 속성 추가 시 latent drift).aria-hidden없음(비상호작용 span, 기존 display-only 칩과 일관).rule_match_score는ActionResponse에 미반환 — 서버측task_metadata에만 계산.🤖 Generated with Claude Code