init: company-haness 설계

This commit is contained in:
DongHyeonka
2026-07-23 17:49:00 +09:00
parent 57d1bab894
commit f668d6a158
962 changed files with 98989 additions and 1 deletions
+51
View File
@@ -0,0 +1,51 @@
# Technology Atlas · Lost Update
기술을 정의 암기가 아니라 **예측 → 실행 관찰 → 증거 비교 → 인과 설명 → 새 사례 전이**로 깊이 학습하는 첫 번째 완성형 딥다이브입니다. 공개 범위는 `Transaction Isolation / Lost Update` 하나이며, 실제 장애나 특정 데이터베이스의 동작을 진단한다고 주장하지 않습니다.
## 바로 확인하기
Node.js 18 이상에서 별도 설치 없이 실행됩니다.
```bash
cd hyeonworks/app
npm run dev
```
브라우저에서 <http://127.0.0.1:4173>을 엽니다. 포트를 바꾸려면 `npm run dev -- --port 8080`처럼 실행합니다.
확인할 핵심 흐름은 다음과 같습니다.
1. 첫 화면에서 **개념을 알고 있어요** 또는 **증상만 알고 있어요** 중 하나를 선택합니다.
2. 서로 다른 준비 화면이 동일한 `Lost Update` Lab으로 합쳐지는지 확인합니다.
3. Predict에서 먼저 가설을 고르고, Observe에서 6개 실행 이벤트를 한 단계씩 진행합니다.
4. Compare에서 기대값 `120`과 관찰값 `70`을 대조합니다.
5. Explain에서 `같은 100 → B의 마지막 write 70 → A의 +50 소실`을 구성합니다.
6. Transfer에서 새 재고 사례의 사라진 변화까지 찾아 완료합니다.
증상 입구는 디버거처럼 관찰값에서 후보 메커니즘을 좁히지만, 실제 로그 분석·AI 장애 진단·원격 데이터베이스 실행 기능은 아닙니다. 제품 화면에도 이 경계를 명시했습니다.
## 검증하기
```bash
npm test
```
`npm test`는 두 검증을 순서대로 수행합니다.
- `npm run test:static`: 승인된 R4 산출물 해시, zero runtime dependency, 로컬 자산, 시맨틱 셸과 디자인 토큰을 확인합니다.
- `npm run test:e2e`: Chrome에서 360/768/1280px, 두 입구, 전체 5단계 루프, 키보드 조작, skip link 상태 보존, 한국어 줄바꿈, 가로 overflow 격리, 오류 후 재시도, 대비 수치를 검증합니다.
Production revision `verification-hardening-2`는 승인 R4를 기반으로, 진행 중인 부드러운 스크롤 도중 skip link를 눌러도 현재 `main`을 즉시 완전히 노출하고 짧은 안정화 구간 동안 이전 스크롤이 재개되지 않도록 보강했습니다. 변경 이유와 원본·현재 해시는 `verification/approved-r4.json`에 함께 기록돼 있습니다.
E2E는 로컬 `puppeteer-core`와 Chrome을 사용합니다. 필요하면 `PUPPETEER_CORE_PATH``CHROME_BIN`으로 위치를 지정할 수 있습니다. 실행 중 생성되는 화면은 `verification/screenshots/`에서 확인할 수 있습니다.
## 구조
- `dist/`: 그대로 배포 가능한 정적 HTML/CSS/JavaScript
- `scripts/serve.cjs`: 외부 의존성 없는 로컬 정적 서버와 보안 헤더
- `scripts/verify_static.cjs`: 승인 기준선 및 정적 품질 검사
- `scripts/verify_flow.cjs`: 실제 브라우저 전체 흐름 검사
- `verification/approved-r4.json`: 승인된 디자인 프로토타입과의 무결성 계약
- `verification/screenshots/`: E2E 상태별 확인 화면
검증용 `#/lab/tx-lost-update-inventory-fixture` route는 화면에서 노출하지 않습니다. 동일한 학습 엔진이 다른 데이터 record와도 섞이지 않는지 확인하는 회귀 fixture이며, 공개 콘텐츠의 두 번째 주제가 아닙니다.
+18
View File
@@ -0,0 +1,18 @@
{
"name": "technology-atlas-lost-update",
"private": true,
"version": "1.0.0",
"description": "Technology Atlas의 Transaction Isolation / Lost Update 인터랙티브 딥다이브",
"engines": {
"node": ">=18"
},
"scripts": {
"dev": "node scripts/serve.cjs",
"start": "node scripts/serve.cjs",
"preview": "node scripts/serve.cjs --host 127.0.0.1 --port 4173",
"test": "npm run test:static && npm run test:e2e",
"test:static": "node scripts/verify_static.cjs",
"test:e2e": "node scripts/verify_flow.cjs",
"verify": "npm test"
}
}
+139
View File
@@ -0,0 +1,139 @@
const fs = require('node:fs');
const http = require('node:http');
const path = require('node:path');
const defaultRoot = path.resolve(__dirname, '..', 'dist');
const mimeTypes = Object.freeze({
'.css': 'text/css; charset=utf-8',
'.html': 'text/html; charset=utf-8',
'.js': 'text/javascript; charset=utf-8',
'.json': 'application/json; charset=utf-8',
'.png': 'image/png',
'.svg': 'image/svg+xml',
});
const securityHeaders = Object.freeze({
'Content-Security-Policy': "default-src 'self'; base-uri 'none'; connect-src 'none'; font-src 'self'; form-action 'self'; frame-ancestors 'none'; img-src 'self' data:; object-src 'none'; script-src 'self'; style-src 'self'",
'Cross-Origin-Opener-Policy': 'same-origin',
'Referrer-Policy': 'no-referrer',
'X-Content-Type-Options': 'nosniff',
'X-Frame-Options': 'DENY',
});
function writePlain(response, status, message, extraHeaders = {}) {
const body = `${message}\n`;
response.writeHead(status, {
...securityHeaders,
...extraHeaders,
'Cache-Control': 'no-store',
'Content-Length': Buffer.byteLength(body),
'Content-Type': 'text/plain; charset=utf-8',
});
response.end(body);
}
function createStaticServer({ root = defaultRoot } = {}) {
const directory = path.resolve(root);
return http.createServer((request, response) => {
if (request.method !== 'GET' && request.method !== 'HEAD') {
writePlain(response, 405, 'Method not allowed', { Allow: 'GET, HEAD' });
return;
}
let pathname;
try {
pathname = decodeURIComponent(new URL(request.url, 'http://127.0.0.1').pathname);
} catch (_) {
writePlain(response, 400, 'Bad request');
return;
}
// Browsers probe this path even when the product intentionally ships no icon.
// A quiet no-content response prevents a false runtime error without adding
// an unreviewed visual asset to the approved interface.
if (pathname === '/favicon.ico') {
response.writeHead(204, {
...securityHeaders,
'Cache-Control': 'public, max-age=86400',
});
response.end();
return;
}
const relative = pathname === '/' ? 'index.html' : pathname.replace(/^\/+/, '');
const file = path.resolve(directory, relative);
if (!file.startsWith(`${directory}${path.sep}`)) {
writePlain(response, 404, 'Not found');
return;
}
let stat;
try {
stat = fs.statSync(file);
} catch (_) {
writePlain(response, 404, 'Not found');
return;
}
if (!stat.isFile()) {
writePlain(response, 404, 'Not found');
return;
}
response.writeHead(200, {
...securityHeaders,
'Cache-Control': 'no-cache',
'Content-Length': stat.size,
'Content-Type': mimeTypes[path.extname(file).toLowerCase()] || 'application/octet-stream',
});
if (request.method === 'HEAD') {
response.end();
return;
}
fs.createReadStream(file).pipe(response);
});
}
function readOption(args, name, fallback) {
const index = args.indexOf(name);
if (index === -1) return fallback;
if (!args[index + 1] || args[index + 1].startsWith('--')) throw new Error(`${name} requires a value`);
return args[index + 1];
}
function startFromCli() {
const args = process.argv.slice(2);
const known = new Set(['--host', '--port']);
for (let index = 0; index < args.length; index += 2) {
if (!known.has(args[index])) throw new Error(`Unknown option: ${args[index]}`);
}
const host = readOption(args, '--host', process.env.TECH_ATLAS_HOST || '127.0.0.1');
const portText = readOption(args, '--port', process.env.TECH_ATLAS_PORT || '4173');
const port = Number(portText);
if (!Number.isInteger(port) || port < 0 || port > 65535) throw new Error(`Invalid port: ${portText}`);
const server = createStaticServer();
server.on('error', error => {
console.error(`Technology Atlas server failed: ${error.message}`);
process.exitCode = 1;
});
server.listen(port, host, () => {
const address = server.address();
const actualPort = typeof address === 'object' && address ? address.port : port;
console.log(`Technology Atlas ready at http://${host}:${actualPort}`);
console.log('Public deep-dive: Transaction Isolation / Lost Update');
});
const stop = () => server.close(() => process.exit());
process.once('SIGINT', stop);
process.once('SIGTERM', stop);
}
if (require.main === module) {
try {
startFromCli();
} catch (error) {
console.error(error.message);
process.exitCode = 1;
}
}
module.exports = { createStaticServer, defaultRoot, securityHeaders };
+461
View File
@@ -0,0 +1,461 @@
const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const { createStaticServer } = require('./serve.cjs');
let puppeteer;
for (const candidate of [
'puppeteer-core',
process.env.PUPPETEER_CORE_PATH,
'/home/donghyeon/.bun/install/global/node_modules/puppeteer-core',
].filter(Boolean)) {
try {
puppeteer = require(candidate);
break;
} catch (_) {
// Try the next local harness installation. The product itself has no browser-test runtime dependency.
}
}
if (!puppeteer) throw new Error('puppeteer-core is required to run the local harness E2E');
const root = path.resolve(__dirname, '..', 'dist');
const stateShotDir = path.resolve(__dirname, '..', 'verification', 'screenshots');
async function selectedAndFocused(page, selector) {
await page.evaluate(() => new Promise(resolve => requestAnimationFrame(() => resolve())));
await page.focus(selector);
await page.keyboard.press('Space');
await page.waitForFunction(target => {
const element = document.querySelector(target);
return Boolean(element?.checked && document.activeElement === element);
}, {}, selector);
}
async function clickAndWait(page, selector, condition) {
await page.click(selector);
await page.waitForFunction(condition);
}
async function assertNoDocumentOverflow(page, label) {
const widths = await page.evaluate(() => ({
client: document.documentElement.clientWidth,
scroll: document.documentElement.scrollWidth,
}));
assert.equal(widths.scroll, widths.client, `${label}: document overflow ${widths.client} -> ${widths.scroll}`);
}
async function assertEntryShortcut(page, activation) {
if (activation === 'keyboard') {
await page.focus('[data-entry-jump]');
await page.keyboard.press('Enter');
} else {
await page.click('[data-entry-jump]');
}
await page.waitForFunction(() => {
const target = document.querySelector('#entry-title');
const top = target?.getBoundingClientRect().top;
return document.activeElement === target && top >= 0 && top <= 80;
});
const result = await page.evaluate(() => ({
activeId: document.activeElement?.id,
top: document.querySelector('#entry-title')?.getBoundingClientRect().top,
hash: location.hash,
}));
assert.equal(result.activeId, 'entry-title');
assert.ok(result.top >= 0 && result.top <= 80, `entry shortcut target top=${result.top}`);
assert.notEqual(result.hash, '#entry-title', 'local entry shortcut must not invoke the route renderer');
}
async function assertSkipLinkPreservesState(page, label) {
const main = await page.$('#main');
assert.ok(main, `${label}: current main must exist`);
const readState = element => ({
hash: location.hash,
scenarioId: element.dataset.scenarioId || null,
phase: element.dataset.phase || null,
cursor: element.dataset.cursor || null,
heading: element.querySelector('h1, h2')?.textContent.trim() || null,
trace: document.querySelector('.trace-note')?.textContent.trim() || null,
clues: document.querySelector('.clues')?.textContent.trim() || null,
});
const before = await page.evaluate(readState, main);
await page.focus('.skip-link');
await page.keyboard.press('Enter');
await page.waitForFunction(() => document.activeElement === document.querySelector('#main'));
const after = await page.evaluate((element, readerSource) => {
const reader = new Function(`return (${readerSource})`)();
return {
state: reader(element),
sameNode: element === document.querySelector('#main'),
active: document.activeElement === element,
tabIndex: element.tabIndex,
top: element.getBoundingClientRect().top,
firstHeadingTop: element.querySelector('h1, h2')?.getBoundingClientRect().top ?? null,
viewportHeight: innerHeight,
};
}, main, readState.toString());
assert.deepEqual(after.state, before, `${label}: skip link must preserve route and learning state`);
assert.equal(after.sameNode, true, `${label}: skip link must not rerender the route`);
assert.equal(after.active, true, `${label}: current main must receive focus`);
assert.equal(after.tabIndex, -1, `${label}: current main must be programmatically focusable`);
assert.ok(after.top >= -32 && after.top < after.viewportHeight, `${label}: current main start must be in view (top=${after.top})`);
assert.ok(after.firstHeadingTop !== null && after.firstHeadingTop >= 0 && after.firstHeadingTop < after.viewportHeight,
`${label}: first main heading must be visible (top=${after.firstHeadingTop})`);
await assertNoDocumentOverflow(page, `${label}:skip-link`);
await main.dispose();
}
async function assertSkipLinkAcrossViewports(page, label) {
const original = page.viewport();
for (const width of [360, 768, 1280]) {
await page.setViewport({ width, height: width === 360 ? 800 : 900, deviceScaleFactor: 1 });
await page.evaluate(() => new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve))));
await assertSkipLinkPreservesState(page, `${label}@${width}`);
}
await page.setViewport(original);
}
async function assertObserveContainment(page, label) {
const geometry = await page.evaluate(() => {
const workbench = document.querySelector('.workbench');
const trace = document.querySelector('.trace-scroll');
const action = document.querySelector('[data-action="advance"], [data-action="to-compare"]');
trace.scrollLeft = trace.scrollWidth;
const result = {
viewport: document.documentElement.clientWidth,
documentScroll: document.documentElement.scrollWidth,
workbenchRight: workbench.getBoundingClientRect().right,
actionRight: action.getBoundingClientRect().right,
traceClient: trace.clientWidth,
traceScroll: trace.scrollWidth,
traceScrollLeft: trace.scrollLeft,
};
trace.scrollLeft = 0;
return result;
});
assert.equal(geometry.documentScroll, geometry.viewport, `${label}: Observe must not widen the document`);
assert.ok(geometry.workbenchRight <= geometry.viewport + .5, `${label}: workbench right=${geometry.workbenchRight}`);
assert.ok(geometry.actionRight <= geometry.viewport + .5, `${label}: action right=${geometry.actionRight}`);
assert.ok(geometry.traceScroll > geometry.traceClient, `${label}: table overflow must remain inside trace-scroll`);
assert.ok(geometry.traceScrollLeft > 0, `${label}: trace-scroll must be horizontally operable`);
}
async function assertKoreanWordIntegrity(page, label) {
const result = await page.evaluate(() => {
const selectors = '.lab-brief > p, .workbench .lead, .choice span, .boundary p, .principle p, .feedback';
const elements = [...document.querySelectorAll(selectors)];
const broken = [];
const segmenter = new Intl.Segmenter('ko', { granularity: 'word' });
for (const element of elements) {
const walker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT);
for (let node = walker.nextNode(); node; node = walker.nextNode()) {
for (const segment of segmenter.segment(node.data)) {
if (!segment.isWordLike || !/[가-힣]/.test(segment.segment)) continue;
const range = document.createRange();
range.setStart(node, segment.index);
range.setEnd(node, segment.index + segment.segment.length);
const tops = [...range.getClientRects()].map(rect => Math.round(rect.top));
if (new Set(tops).size > 1) broken.push(segment.segment);
}
}
}
const sample = document.querySelector('.workbench .lead') || document.querySelector('.lab-brief > p');
const style = sample ? getComputedStyle(sample) : null;
return { broken, wordBreak: style?.wordBreak, overflowWrap: style?.overflowWrap };
});
assert.deepEqual(result.broken, [], `${label}: Korean words split across lines: ${result.broken.join(', ')}`);
assert.equal(result.wordBreak, 'keep-all', `${label}: Lab body must use keep-all`);
assert.equal(result.overflowWrap, 'anywhere', `${label}: long Latin tokens need a safe fallback`);
}
async function captureState(page, name) {
fs.mkdirSync(stateShotDir, { recursive: true });
for (const width of [360, 1280]) {
await page.setViewport({ width, height: 900, deviceScaleFactor: 1 });
if (width === 360) {
await assertNoDocumentOverflow(page, `${name}@360`);
await assertKoreanWordIntegrity(page, `${name}@360`);
}
await page.screenshot({ path: path.join(stateShotDir, `${name}.w${width}.png`), fullPage: true });
}
await page.setViewport({ width: 360, height: 800, deviceScaleFactor: 1 });
}
async function captureResponsiveRoute(page, name, widths = [360, 768, 1280]) {
const original = page.viewport();
fs.mkdirSync(stateShotDir, { recursive: true });
for (const width of widths) {
await page.setViewport({ width, height: width === 360 ? 800 : 900, deviceScaleFactor: 1 });
await assertNoDocumentOverflow(page, `${name}@${width}`);
await page.screenshot({ path: path.join(stateShotDir, `${name}.w${width}.png`), fullPage: true });
}
await page.setViewport(original);
}
function contrastRatio(foreground, background) {
const rgb = value => value.match(/[\d.]+/g).slice(0, 3).map(Number);
const luminance = value => {
const [red, green, blue] = rgb(value).map(channel => {
const normalized = channel / 255;
return normalized <= .03928 ? normalized / 12.92 : ((normalized + .055) / 1.055) ** 2.4;
});
return .2126 * red + .7152 * green + .0722 * blue;
};
const first = luminance(foreground);
const second = luminance(background);
return (Math.max(first, second) + .05) / (Math.min(first, second) + .05);
}
async function assertContrastContract(page, label, expected = {}) {
const colors = await page.evaluate(() => {
const effectiveBackground = element => {
for (let current = element; current; current = current.parentElement) {
const background = getComputedStyle(current).backgroundColor;
if (background && background !== 'rgba(0, 0, 0, 0)') return background;
}
return getComputedStyle(document.body).backgroundColor;
};
const textSample = element => ({
foreground: getComputedStyle(element).color,
background: effectiveBackground(element),
});
const borderSample = element => ({
foreground: getComputedStyle(element).borderTopColor,
background: effectiveBackground(element),
});
return {
labId: textSample(document.querySelector('.lab-brief .lab-id')),
boundaryLabel: textSample(document.querySelector('.lab-brief .boundary b')),
pending: [...document.querySelectorAll('.trace-event.pending')].map(textSample),
choices: [...document.querySelectorAll('.choice')].map(borderSample),
textareas: [...document.querySelectorAll('textarea')].map(borderSample),
};
});
const ratio = sample => contrastRatio(sample.foreground, sample.background);
const metrics = {
labId: ratio(colors.labId),
boundaryLabel: ratio(colors.boundaryLabel),
pendingMin: colors.pending.length ? Math.min(...colors.pending.map(ratio)) : null,
choiceMin: colors.choices.length ? Math.min(...colors.choices.map(ratio)) : null,
textareaMin: colors.textareas.length ? Math.min(...colors.textareas.map(ratio)) : null,
};
assert.ok(metrics.labId >= 4.5, `${label}: Lab id contrast ${metrics.labId.toFixed(2)} < 4.5`);
assert.ok(metrics.boundaryLabel >= 4.5, `${label}: dark boundary label contrast ${metrics.boundaryLabel.toFixed(2)} < 4.5`);
if (expected.pending) {
assert.ok(metrics.pendingMin !== null && metrics.pendingMin >= 4.5, `${label}: pending text contrast ${metrics.pendingMin?.toFixed(2)} < 4.5`);
}
if (expected.choices) {
assert.ok(metrics.choiceMin !== null && metrics.choiceMin >= 3, `${label}: choice border contrast ${metrics.choiceMin?.toFixed(2)} < 3`);
}
if (expected.textarea) {
assert.ok(metrics.textareaMin !== null && metrics.textareaMin >= 3, `${label}: textarea border contrast ${metrics.textareaMin?.toFixed(2)} < 3`);
}
return metrics;
}
(async () => {
const server = createStaticServer({ root });
await new Promise((resolve, reject) => {
server.once('error', reject);
server.listen(0, '127.0.0.1', resolve);
});
const port = server.address().port;
const browser = await puppeteer.launch({
executablePath: process.env.CHROME_BIN || '/usr/bin/google-chrome',
headless: true,
args: ['--no-sandbox', '--disable-dev-shm-usage'],
});
const page = await browser.newPage();
const runtimeErrors = [];
const consoleErrors = [];
const requestFailures = [];
page.on('pageerror', error => runtimeErrors.push(error.message));
page.on('console', message => {
if (message.type() === 'error') consoleErrors.push(message.text());
});
page.on('requestfailed', request => requestFailures.push(`${request.method()} ${request.url()}: ${request.failure()?.errorText}`));
try {
const contrastEvidence = {};
await page.setViewport({ width: 360, height: 800, deviceScaleFactor: 1 });
const homeResponse = await page.goto(`http://127.0.0.1:${port}/`, { waitUntil: 'networkidle0' });
assert.equal(homeResponse.status(), 200, 'production entry must return HTTP 200');
const responseHeaders = homeResponse.headers();
assert.match(responseHeaders['content-security-policy'], /default-src 'self'/);
assert.equal(responseHeaders['x-content-type-options'], 'nosniff');
assert.equal(responseHeaders['x-frame-options'], 'DENY');
await captureResponsiveRoute(page, 'home');
const mobileHealth = await page.evaluate(() => ({
overflow: document.documentElement.scrollWidth - document.documentElement.clientWidth,
jumpTop: document.querySelector('.entry-jump').getBoundingClientRect().top,
jumpVisible: getComputedStyle(document.querySelector('.entry-jump')).display !== 'none',
}));
assert.ok(mobileHealth.overflow <= 0, `mobile horizontal overflow=${mobileHealth.overflow}`);
assert.equal(mobileHealth.jumpVisible, true);
assert.ok(mobileHealth.jumpTop < 800, `entry jump is below first viewport: ${mobileHealth.jumpTop}`);
await assertEntryShortcut(page, 'keyboard');
await page.setViewport({ width: 768, height: 900, deviceScaleFactor: 1 });
await page.goto(`http://127.0.0.1:${port}/`, { waitUntil: 'networkidle0' });
const tabletColumns = await page.$eval('.hero', element => getComputedStyle(element).gridTemplateColumns.split(' ').length);
assert.equal(tabletColumns, 2, 'tablet hero must retain two-column editorial density');
await assertEntryShortcut(page, 'pointer');
await assertSkipLinkAcrossViewports(page, 'home');
await page.setViewport({ width: 360, height: 800, deviceScaleFactor: 1 });
await page.goto(`http://127.0.0.1:${port}/#/orient/concept`, { waitUntil: 'networkidle0' });
await captureResponsiveRoute(page, 'concept', [360, 1280]);
await assertSkipLinkAcrossViewports(page, 'concept');
await page.goto(`http://127.0.0.1:${port}/#/orient/symptom`, { waitUntil: 'networkidle0' });
await page.click('[data-reveal]');
await page.waitForFunction(() => /2 \/ 4/.test(document.querySelector('.folio-head')?.textContent || ''));
await captureResponsiveRoute(page, 'symptom', [360, 1280]);
await assertSkipLinkAcrossViewports(page, 'symptom-with-revealed-clue');
await page.goto(`http://127.0.0.1:${port}/`, { waitUntil: 'networkidle0' });
await page.click('a[href="#/orient/concept"]');
await page.waitForSelector('a[data-start-lab]');
await page.click('a[data-start-lab]');
await page.waitForSelector('input[name="prediction"]');
assert.equal(await page.$$eval('.progress-item', items => items.length), 5);
contrastEvidence.predict = await assertContrastContract(page, 'default-predict', { choices: true });
const hypothesis = 'input[name="prediction"][value="shared-stale-read"]';
await selectedAndFocused(page, hypothesis);
assert.equal(await page.$eval('[data-action="commit-prediction"]', button => button.disabled), false);
await clickAndWait(page, '[data-action="commit-prediction"]', () => document.querySelector('[data-action="advance"]'));
await assertObserveContainment(page, 'default@360');
await page.click('[data-action="advance"]');
await page.waitForFunction(() => document.activeElement?.dataset?.action === 'advance' && /실행 1\/6/.test(document.querySelector('#announcer').textContent));
await assertSkipLinkAcrossViewports(page, 'default-observe-cursor-1');
contrastEvidence.observe = await assertContrastContract(page, 'default-observe-cursor-1', { pending: true });
await captureState(page, 'observe');
for (let step = 1; step < 6; step += 1) {
await page.click('[data-action="advance"]');
const expectedAction = step === 5 ? 'to-compare' : 'advance';
await page.waitForFunction(action => document.activeElement?.dataset?.action === action, {}, expectedAction);
}
assert.equal(await page.$$eval('.trace-table thead th[scope="col"]', headers => headers.length), 4);
await clickAndWait(page, '[data-action="to-compare"]', () => document.querySelector('[data-action="to-explain"]'));
await captureState(page, 'compare');
await clickAndWait(page, '[data-action="to-explain"]', () => document.querySelector('[data-action="submit-explanation"]'));
await captureState(page, 'explain');
contrastEvidence.explain = await assertContrastContract(page, 'default-explain', { choices: true, textarea: true });
await selectedAndFocused(page, 'input[name="explanation-readBasis"][value="same-100"]');
await selectedAndFocused(page, 'input[name="explanation-finalWrite"][value="a-150"]');
await selectedAndFocused(page, 'input[name="explanation-lostChange"][value="a-plus-50"]');
await page.click('[data-action="submit-explanation"]');
await page.waitForFunction(() => document.activeElement?.id === 'explanation-feedback');
assert.match(await page.$eval('#explanation-feedback', element => element.textContent), /맞지 않습니다/);
assert.equal(await page.$('[data-action="to-transfer"]'), null);
await selectedAndFocused(page, 'input[name="explanation-finalWrite"][value="b-70"]');
assert.equal(await page.$('#explanation-feedback'), null, 'changed answer must reset submitted feedback');
await page.click('[data-action="submit-explanation"]');
await page.waitForFunction(() => document.activeElement?.id === 'explanation-feedback');
assert.ok(await page.$('[data-action="to-transfer"]'));
await clickAndWait(page, '[data-action="to-transfer"]', () => document.querySelector('[data-action="submit-transfer"]'));
await captureState(page, 'transfer');
await selectedAndFocused(page, 'input[name="transfer"][value="lost-restock"]');
await page.click('[data-action="submit-transfer"]');
await page.waitForFunction(() => document.activeElement?.id === 'transfer-feedback');
assert.match(await page.$eval('#transfer-feedback', element => element.textContent), /다시 비교하세요/);
assert.equal(await page.$('[data-action="complete"]'), null);
await selectedAndFocused(page, 'input[name="transfer"][value="lost-reservation"]');
assert.equal(await page.$('#transfer-feedback'), null, 'changed transfer must reset submitted feedback');
await page.click('[data-action="submit-transfer"]');
await page.waitForFunction(() => document.activeElement?.id === 'transfer-feedback');
await clickAndWait(page, '[data-action="complete"]', () => document.querySelector('.completion'));
await captureState(page, 'complete');
contrastEvidence.complete = await assertContrastContract(page, 'default-complete');
assert.match(await page.$eval('.completion h2', element => element.textContent), /세 인과 요소를 연결/);
assert.match(await page.$eval('.completion .lead', element => element.textContent), /자유 서술 능력이나 실제 장애 진단을 증명하지 않습니다/);
await clickAndWait(page, '[data-action="reset"]', () => document.querySelector('input[name="prediction"]'));
await captureState(page, 'predict');
assert.equal(await page.$eval('.lab-brief .value.observed b', element => element.textContent), '100');
const boundaryColors = await page.$eval('.lab-brief .boundary p', element => {
const style = getComputedStyle(element);
const background = getComputedStyle(element.closest('.boundary')).backgroundColor;
return { foreground: style.color, background };
});
assert.ok(contrastRatio(boundaryColors.foreground, boundaryColors.background) >= 4.5, 'Lab boundary contrast must be AA');
await page.goto(`http://127.0.0.1:${port}/#/orient/symptom`, { waitUntil: 'networkidle0' });
for (let clue = 1; clue < 4; clue += 1) await page.click('[data-reveal]');
await page.waitForSelector('a[data-start-lab]');
await page.click('a[data-start-lab]');
await page.waitForSelector('input[name="prediction"]');
assert.equal(await page.$eval('main[data-scenario-id]', element => element.dataset.scenarioId), 'tx-lost-update-01');
await page.setViewport({ width: 360, height: 800, deviceScaleFactor: 1 });
await page.goto(`http://127.0.0.1:${port}/#/lab/tx-lost-update-inventory-fixture`, { waitUntil: 'networkidle0' });
await page.waitForSelector('input[name="prediction"]');
assert.equal(await page.$eval('main[data-scenario-id]', element => element.dataset.scenarioId), 'tx-lost-update-inventory-fixture');
assert.match(await page.$eval('.lab-top .lab-id', element => element.textContent), /Inventory fixture/);
assert.deepEqual(await page.$$eval('.lab-brief .value b', elements => elements.map(element => element.textContent)), ['50', '60', '50']);
assert.match(await page.$eval('.choice span', element => element.textContent), /같은 50/);
const fixtureTokenWrap = await page.$eval('.lab-brief > p', element => ({ client: element.clientWidth, scroll: element.scrollWidth }));
assert.ok(fixtureTokenWrap.scroll <= fixtureTokenWrap.client, `fixture Latin token overflow ${fixtureTokenWrap.client} -> ${fixtureTokenWrap.scroll}`);
await assertNoDocumentOverflow(page, 'fixture-predict@360');
await assertKoreanWordIntegrity(page, 'fixture-predict@360');
await selectedAndFocused(page, 'input[name="prediction"][value="fixture-shared-50"]');
await clickAndWait(page, '[data-action="commit-prediction"]', () => document.querySelector('[data-action="advance"]'));
assert.equal(await page.$$eval('.trace-table tbody tr', rows => rows.length), 4, 'fixture schedule must not inherit the default six rows');
assert.match(await page.$eval('.trace-scroll', element => element.getAttribute('aria-label')), /Inventory fixture/);
await assertObserveContainment(page, 'fixture@360');
await page.click('[data-action="advance"]');
await page.waitForFunction(() => document.activeElement?.dataset?.action === 'advance' && /실행 1\/4/.test(document.querySelector('#announcer').textContent));
assert.match(await page.$eval('#announcer', element => element.textContent), /A가 재고 50/);
await assertSkipLinkAcrossViewports(page, 'fixture-observe-cursor-1');
contrastEvidence.fixtureObserve = await assertContrastContract(page, 'fixture-observe-cursor-1', { pending: true });
for (let step = 1; step < 4; step += 1) {
await page.click('[data-action="advance"]');
const expectedAction = step === 3 ? 'to-compare' : 'advance';
await page.waitForFunction(action => document.activeElement?.dataset?.action === action, {}, expectedAction);
}
await clickAndWait(page, '[data-action="to-compare"]', () => document.querySelector('[data-action="to-explain"]'));
const fixtureEvidence = await page.$eval('.causal-ledger', element => element.textContent);
assert.match(fixtureEvidence, /A=70 다음 B=40/);
assert.doesNotMatch(fixtureEvidence, /A=150/);
await clickAndWait(page, '[data-action="to-explain"]', () => document.querySelector('[data-action="submit-explanation"]'));
await selectedAndFocused(page, 'input[name="explanation-readBasis"][value="same-50"]');
await selectedAndFocused(page, 'input[name="explanation-finalWrite"][value="b-40"]');
await selectedAndFocused(page, 'input[name="explanation-lostChange"][value="a-plus-20"]');
await page.click('[data-action="submit-explanation"]');
await page.waitForFunction(() => document.activeElement?.id === 'explanation-feedback');
assert.match(await page.$eval('#explanation-feedback', element => element.textContent), /Fixture 인과/);
await clickAndWait(page, '[data-action="to-transfer"]', () => document.querySelector('[data-action="submit-transfer"]'));
assert.deepEqual(await page.$$eval('.value-comparison b', elements => elements.map(element => element.textContent)), ['100', '110', '115']);
await selectedAndFocused(page, 'input[name="transfer"][value="lost-use"]');
await page.click('[data-action="submit-transfer"]');
await page.waitForFunction(() => document.activeElement?.id === 'transfer-feedback');
assert.match(await page.$eval('#transfer-feedback', element => element.textContent), /Fixture 전이 성공/);
await clickAndWait(page, '[data-action="complete"]', () => document.querySelector('.completion'));
assert.match(await page.$eval('.completion h2', element => element.textContent), /Fixture의 세 인과 요소/);
assert.match(await page.$eval('.principle b', element => element.textContent), /원자적 재고 변경/);
await clickAndWait(page, '[data-action="reset"]', () => document.querySelector('input[name="prediction"]'));
assert.equal(await page.$eval('.lab-brief .value.observed b', element => element.textContent), '50');
assert.equal(await page.$eval('main[data-scenario-id]', element => element.dataset.scenarioId), 'tx-lost-update-inventory-fixture');
assert.deepEqual(runtimeErrors, []);
assert.deepEqual(consoleErrors, []);
assert.deepEqual(requestFailures, []);
console.log(`PASS contrast metrics ${JSON.stringify(contrastEvidence)}`);
console.log('PASS production E2E: secure static delivery, dual-entry, contained Observe, entry focus, route-safe skip link, Korean type, scenario binding, causal loop, semantics and contrast');
} finally {
await browser.close();
await new Promise(resolve => server.close(resolve));
}
})().catch(error => {
console.error(error.stack || error);
process.exitCode = 1;
});
+62
View File
@@ -0,0 +1,62 @@
const assert = require('node:assert/strict');
const crypto = require('node:crypto');
const fs = require('node:fs');
const path = require('node:path');
const root = path.resolve(__dirname, '..');
const read = relative => fs.readFileSync(path.join(root, relative), 'utf8');
const hash = relative => crypto.createHash('sha256').update(fs.readFileSync(path.join(root, relative))).digest('hex');
const packageJson = JSON.parse(read('package.json'));
const baseline = JSON.parse(read('verification/approved-r4.json'));
const html = read('dist/index.html');
const css = read('dist/styles.css');
const app = read('dist/app.js');
assert.equal(packageJson.private, true, 'the app must remain a private deployable package');
assert.equal(packageJson.dependencies, undefined, 'runtime must remain dependency-free');
assert.equal(packageJson.devDependencies, undefined, 'local verification must not require npm installation');
for (const script of ['dev', 'start', 'test', 'test:static', 'test:e2e', 'verify']) {
assert.equal(typeof packageJson.scripts[script], 'string', `missing npm script: ${script}`);
}
const actualHashes = {};
for (const [relative, expected] of Object.entries(baseline.files)) {
actualHashes[relative] = hash(relative);
assert.equal(actualHashes[relative], expected, `${relative} diverged from the declared production baseline`);
}
assert.match(html, /^<!doctype html>/i);
assert.match(html, /<html lang="ko">/);
assert.match(html, /<meta name="viewport"/);
assert.match(html, /<meta name="description"/);
assert.match(html, /<a class="skip-link" href="#main">본문으로 건너뛰기<\/a>/);
assert.match(html, /id="announcer"[^>]*aria-live="polite"/);
assert.match(html, /<script type="module" src="\.\/app\.js"><\/script>/);
assert.doesNotMatch(html, /<script(?![^>]*\bsrc=)[^>]*>/i, 'inline scripts are not allowed');
assert.doesNotMatch(`${html}\n${css}\n${app}`, /https?:\/\//i, 'the product must not make remote requests');
for (const marker of [
"'tx-lost-update-01'",
"'tx-lost-update-inventory-fixture'",
"href=\"#/orient/concept\"",
"href=\"#/orient/symptom\"",
'Predict → Observe → Compare → Explain → Transfer',
'실제 장애 원인을 확정하지 않습니다',
"window.addEventListener('hashchange'",
]) assert.ok(app.includes(marker), `missing approved behavior marker: ${marker}`);
for (const marker of [
'--coral: #ad4031',
'--accent-on-deep: #ff8873',
'--pending: #535c58',
'--control-border: #88877e',
'.skip-link',
'@media (max-width: 700px)',
]) assert.ok(css.includes(marker), `missing approved visual/accessibility marker: ${marker}`);
assert.equal(baseline.winnerPrototypeId, 'ENG-FE-20260718T144700Z');
assert.equal(baseline.winnerReportSha256, '8b208279e12f9aea0fa6d7a3c320811b0e72ddb74c6afac64cddadf4b157cf76');
assert.ok(Array.isArray(baseline.postApprovalChanges), 'production hardening provenance must be explicit');
console.log(`PASS static integrity ${JSON.stringify(actualHashes)}`);
console.log('PASS zero-runtime-dependency, local-only assets, semantic shell, approved scenario/token contracts and production-hardening provenance');
@@ -0,0 +1,18 @@
{
"source": "hyeonworks/design-direction/hyeonworks-vnext-v1/prototype",
"winnerPrototypeId": "ENG-FE-20260718T144700Z",
"winnerReportSha256": "8b208279e12f9aea0fa6d7a3c320811b0e72ddb74c6afac64cddadf4b157cf76",
"productionRevision": "verification-hardening-2",
"postApprovalChanges": [
{
"id": "route-safe-skip-link-scroll-cancellation",
"originalAppSha256": "b148057f4d25ba6afb4170c82f5c832263563feaf99a345a0d79e350d83fbed3",
"reason": "Cancel an in-flight smooth scroll, align the current main with direct coordinates, and retain auto behavior through the settle window without changing route or learning state."
}
],
"files": {
"dist/app.js": "ff85c317c9579e341a0f98cf4371a64937b13be2a21c2ac244466a630dfe6e17",
"dist/index.html": "6295b1cf4b5f44cd4e9a5242643712728709ac851d62c4587ef933830bd33861",
"dist/styles.css": "71e51b907f5b01c480eb348df35db17995fc45269db36ed6a1afd113e3f29f58"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

@@ -0,0 +1,50 @@
report-type: workflow-artifact
artifact-kind: decision-brief
artifact-version: 1
identity:
artifact-id: EXEC-CEO-20260718T105646Z
workflow-id: hyeonworks-company-bootstrap-v2
stage: intake
producer-role-id: EXEC-CEO
created-at: 20260718T105646Z
attempt-id: 1
payload:
mode: divergent
tier: standard
candidate-families: [FAM-STRATEGY, FAM-CEO, FAM-CPO, FAM-CTO, FAM-COO]
objective: >-
Hyeonworks를 기술의 작동 원리를 깊게 학습하는 mechanism-first Technology Atlas로 다시
설계하되, Concept Debugger를 별도 제품이 아니라 초기 증상 기반 진입 방식으로 결합한
회사·제품 전략을 새 증거 계보로 확정한다.
strategy-delta:
previous: "Concept Debugger를 초기 독립 제품 전략에서 보류"
new: >-
Technology Atlas를 제품 뼈대로 유지하고 Transaction Isolation 안의 제한된 증상 카드가
동일한 Predict → Observe → Compare → Explain → Transfer 실습으로 연결되게 한다.
scope-boundary:
in:
- "개념 기반 진입과 증상 기반 진입이 하나의 학습 모델로 합쳐지는 초기 전략"
- "Transaction Isolation 한 주제 안의 3~5개 대표 증상"
- "1인 운영·depth-before-breadth·self-serve 제약"
- "회사 전략, 제품 전략, 시장·학습 가설의 분리"
out:
- "여러 기술 도메인을 가로지르는 범용 장애 진단 엔진"
- "실제 운영 시스템 로그 수집·원격 DB 연결·AI 자동 진단"
- "검증 전 가격·매출·수요를 확정 사실로 취급하는 것"
report-header:
bottom-line: >-
CEO intake는 Technology Atlas와 제한된 Concept Debugger 진입을 결합한 하이브리드 전략을
표준 등급으로 처음부터 재검증하고, 이후 제품 cascade가 사용할 새 company context를 만든다.
decision-needed: { needed: false, approver: HUMAN-001 }
confidence: { value: Med, derived-from: founder-confirmed-strategy-and-explicit-scope }
risks:
- "증상 진입이 별도 제품 엔진으로 팽창하면 1인 운영성과 첫 주제 완성도가 무너질 수 있다."
- "학습 효과·수요·WTP는 아직 실측되지 않았으므로 제품 전략과 사업 성과를 혼동하면 안 된다."
- "기존 Hyeonworks는 초기화됐으므로 과거 제품 산출물을 새 구현 증거로 재사용하지 않는다."
evidence:
- source-uri: org-os/01-company/founder-context.yaml
grade: E2
note: "확정된 mechanism-first·active-learning·solo-operable 제약"
- source-uri: org-os/01-company/company-context.yaml
grade: E2
note: "기존 전략 기준선과 이번 debugger 결합 결정의 변경 대상"
@@ -0,0 +1,146 @@
report-type: workflow-artifact
artifact-kind: venture-validation
artifact-version: 1
tier: standard
identity:
artifact-id: EXEC-CEO-20260718T105950Z
workflow-id: hyeonworks-company-bootstrap-v2
stage: venture-validation
producer-role-id: EXEC-CEO
created-at: 20260718T105950Z
attempt-id: 2
payload:
source-artifact-refs:
- artifact-id: STR-ANALYST-20260718T105747Z
artifact-sha256: a7cb2ae28351c2f157fd4b7c4f5abbf565e6ba94aac2b607c160681f8b64c530
- artifact-id: STR-ANALYST-20260718T105748Z
artifact-sha256: 95ebb4e2a73b5c1d9464c1131b7577fb3fb9b7e31c61deec228cd33ac7074515
hypotheses:
- id: HYP-HYBRID-ENTRY
statement: "증상 기반 진입은 개념 기반 진입을 대체하지 않고 동일 실습으로 연결될 때 시작 동기와 관련성을 높인다"
- id: HYP-SHARED-CORE
statement: "두 진입이 동일 scenario와 상태 엔진을 공유하면 별도 Debugger 제품 없이 1인 운영성을 유지할 수 있다"
- id: HYP-LEARNING-TRANSFER
statement: "Predict → Observe → Compare → Explain → Transfer가 Lost Update의 인과 설명과 새 사례 전이를 높인다"
experiments:
- "처음 보는 사용자 5명에게 홈을 10초 보여주고 사이트 목적과 두 진입의 차이를 설명하게 한다"
- "개념 진입과 증상 진입 각각에서 동일 Lost Update scenario까지 완주 가능한지 관찰한다"
- "학습 후 재고 갱신 사례에서 동일 메커니즘을 판별하고 이유를 설명하게 한다"
- "두 진입의 콘텐츠·상태 엔진 중복 여부를 정적 검사한다"
evidence:
- "HUMAN-001은 기술의 작동 원리를 깊게 학습하는 사이트와 Debugger 방식의 초기 결합을 명시했다"
- "founder context는 solo-operable·depth-before-breadth·honest mechanics를 하드 제약으로 둔다"
- "새 제품 구현과 실제 사용자 결과는 아직 없으므로 기술·시장 결과는 unknown으로 유지한다"
option-evaluations:
- id: VOPT-ATLAS-ONLY
customer: "기술 개념명을 알고 내부 작동 원리를 체계적으로 이해하려는 개발자"
painful-job: "정적 설명을 실제 상태 변화와 인과관계로 연결하기 어렵다"
current-alternative: "문서·강의·블로그·개별 실험을 따로 소비한다"
wedge: "개념 지도에서 시작하는 단일 Transaction Isolation guided lab"
monetization: "unknown — 초기에는 학습·평판 자산 우선"
expected-price: "unknown"
reachable-customers: "unknown — 보유 채널 미확정"
rough-revenue-ceiling: "unknown"
acquisition-channel: "self-serve/organic 후보, 미검증"
build-cost: "세 안 중 가장 작지만 증상 기반 진입 요구를 반영하지 못한다"
operation-cost: "낮음 — 단일 콘텐츠 모델과 단일 실험"
founder-fit: "운영성은 높지만 최신 확정 전략과 부분 불일치"
defensibility: "깊은 교습 설계와 개념 연결의 누적"
kill-criteria:
- "사용자가 개념명을 몰라 첫 학습 경로를 찾지 못한다"
- "최신 founder 결정인 증상 진입 결합을 충족하지 못한다"
unresolved-assumptions: ["개념명 기반 탐색만으로 충분한가", "학습 효과", "수요와 WTP"]
validation-results:
- {option-id: VOPT-ATLAS-ONLY, gate: problem-intensity, verdict: unknown, evidence: ["직접 사용자 조사 없음"], dissent: []}
- {option-id: VOPT-ATLAS-ONLY, gate: competition-alternatives, verdict: unknown, evidence: ["문서·강의·AI가 강한 대안"], dissent: []}
- {option-id: VOPT-ATLAS-ONLY, gate: willingness-to-pay, verdict: unknown, evidence: ["결제 증거 없음"], dissent: []}
- {option-id: VOPT-ATLAS-ONLY, gate: revenue-unit-economics, verdict: unknown, evidence: ["가격·CAC·전환 미확정"], dissent: []}
- {option-id: VOPT-ATLAS-ONLY, gate: tech-feasibility-moat, verdict: unknown, evidence: ["초기화 후 새 구현 증거 없음"], dissent: ["일반 React 구현 가능성과 제품 해자는 다르다"]}
- {option-id: VOPT-ATLAS-ONLY, gate: operability, verdict: pass, evidence: ["한 주제·한 실험·한 콘텐츠 모델"], dissent: []}
- {option-id: VOPT-ATLAS-ONLY, gate: distribution, verdict: unknown, evidence: ["채널 미확정"], dissent: []}
- {option-id: VOPT-ATLAS-ONLY, gate: founder-fit, verdict: fail, evidence: ["Debugger 초기 결합이라는 최신 확정 방향을 누락"], dissent: []}
- {option-id: VOPT-ATLAS-ONLY, gate: kill-criteria, verdict: pass, evidence: ["진입 실패·학습 실패 기준 명시"], dissent: []}
- id: VOPT-DEBUGGER-FIRST
customer: "실제 동시성 이상 현상을 겪고 빠르게 원인 후보를 좁히려는 실무 개발자"
painful-job: "검색과 로그만으로 어떤 메커니즘이 결과를 만들었는지 재현하기 어렵다"
current-alternative: "검색·AI 답변·incident 문서·임시 재현 코드를 조합한다"
wedge: "여러 증상에서 시작하는 독립 Concept Debugger와 진단 흐름"
monetization: "unknown — 팀 진단/교육 가능성 미검증"
expected-price: "unknown"
reachable-customers: "unknown"
rough-revenue-ceiling: "unknown"
acquisition-channel: "증상 검색 유입 후보, 미검증"
build-cost: "높음 — 증상 taxonomy·다중 사례·별도 진단 UI와 설명 유지 필요"
operation-cost: "높음 — 기술·버전·사례별 지속 갱신과 오진 방지 필요"
founder-fit: "깊이 학습에는 맞지만 solo-operable·depth-before-breadth와 충돌"
defensibility: "사례 데이터가 쌓이면 가능하나 초기에는 없음"
kill-criteria:
- "별도 실험 엔진이나 중복 콘텐츠가 필요하다"
- "사용자가 실제 장애 확정 도구로 오인한다"
- "증상 분류 유지가 founder timebox를 넘는다"
unresolved-assumptions: ["증상 기반 수요", "실제 진단 오인", "다중 도메인 운영비", "WTP"]
validation-results:
- {option-id: VOPT-DEBUGGER-FIRST, gate: problem-intensity, verdict: unknown, evidence: ["직접 incident 사용자 조사 없음"], dissent: []}
- {option-id: VOPT-DEBUGGER-FIRST, gate: competition-alternatives, verdict: unknown, evidence: ["검색·관측도구·AI가 강한 대안"], dissent: []}
- {option-id: VOPT-DEBUGGER-FIRST, gate: willingness-to-pay, verdict: unknown, evidence: ["결제 증거 없음"], dissent: []}
- {option-id: VOPT-DEBUGGER-FIRST, gate: revenue-unit-economics, verdict: unknown, evidence: ["높은 콘텐츠 유지비와 미확정 가격"], dissent: []}
- {option-id: VOPT-DEBUGGER-FIRST, gate: tech-feasibility-moat, verdict: unknown, evidence: ["새 구현·사례 데이터 없음"], dissent: []}
- {option-id: VOPT-DEBUGGER-FIRST, gate: operability, verdict: fail, evidence: ["범용 증상·버전·사례 운영이 1인 범위를 초과"], dissent: ["한 사례로 제한하면 hybrid option으로 전환 가능"]}
- {option-id: VOPT-DEBUGGER-FIRST, gate: distribution, verdict: unknown, evidence: ["검색 유입 가설만 존재"], dissent: []}
- {option-id: VOPT-DEBUGGER-FIRST, gate: founder-fit, verdict: fail, evidence: ["solo-operable 하드 제약과 충돌"], dissent: []}
- {option-id: VOPT-DEBUGGER-FIRST, gate: kill-criteria, verdict: pass, evidence: ["오인·중복 엔진·운영비 중단 기준 명시"], dissent: []}
- id: VOPT-HYBRID-SHARED-CORE
customer: "개념명에서 시작하거나 실제 증상에서 시작해도 메커니즘을 설명 가능한 수준까지 배우려는 개발자"
painful-job: "체계적 개념과 실제 이상 현상을 하나의 재현 가능한 인과 모델로 연결하기 어렵다"
current-alternative: "개념 학습과 장애 검색을 서로 다른 도구·문서에서 수행한다"
wedge: "Atlas 뼈대 안에서 Lost Update 증상 카드가 동일 Transaction Isolation 학습 코어로 연결되는 이중 진입"
monetization: "unknown — 초기에는 학습·성장·평판 우선"
expected-price: "unknown"
reachable-customers: "unknown — self-serve organic 후보"
rough-revenue-ceiling: "unknown"
acquisition-channel: "개념 탐색과 증상 검색의 두 organic 경로 후보, 미검증"
build-cost: "중간 — 홈과 symptom triage는 추가되지만 scenario·상태 엔진·설명은 공유"
operation-cost: "낮음~중간 — Transaction Isolation/Lost Update 한 사례로 제한하고 중복 콘텐츠 금지"
founder-fit: "최신 전략과 solo/depth/self-serve 제약을 동시에 충족"
defensibility: "증상→관찰→메커니즘→전이의 정직한 교습 모델과 누적된 연결 구조"
kill-criteria:
- "두 진입이 별도 엔진이나 중복 설명을 요구한다"
- "사용자 5명 중 3명 이상이 실제 진단 도구로 오인한다"
- "사용자 5명 중 3명 이상이 Lost Update 인과를 설명하지 못한다"
- "모바일·키보드에서 어느 한 진입도 완주할 수 없다"
unresolved-assumptions: ["두 진입의 이해도", "학습 전이", "시작률·완주율", "운영비", "수요·WTP"]
validation-results:
- {option-id: VOPT-HYBRID-SHARED-CORE, gate: problem-intensity, verdict: unknown, evidence: ["founder 문제 확정, 직접 사용자 조사 없음"], dissent: []}
- {option-id: VOPT-HYBRID-SHARED-CORE, gate: competition-alternatives, verdict: unknown, evidence: ["문서·강의·AI·검색이 대안"], dissent: []}
- {option-id: VOPT-HYBRID-SHARED-CORE, gate: willingness-to-pay, verdict: unknown, evidence: ["결제 증거 없음"], dissent: []}
- {option-id: VOPT-HYBRID-SHARED-CORE, gate: revenue-unit-economics, verdict: unknown, evidence: ["가격·전환 미확정, 공유 코어로 비용만 제한"], dissent: []}
- {option-id: VOPT-HYBRID-SHARED-CORE, gate: tech-feasibility-moat, verdict: unknown, evidence: ["아키텍처 가설은 명확하지만 새 구현 전"], dissent: ["구현 가능성과 학습 차별성은 별도 검증 필요"]}
- {option-id: VOPT-HYBRID-SHARED-CORE, gate: operability, verdict: pass, evidence: ["한 주제·한 scenario·공유 엔진·증상 카드 1개로 제한"], dissent: ["후속 증상 확장은 timebox가 필요"]}
- {option-id: VOPT-HYBRID-SHARED-CORE, gate: distribution, verdict: unknown, evidence: ["두 organic 진입 가설, 채널 실측 없음"], dissent: []}
- {option-id: VOPT-HYBRID-SHARED-CORE, gate: founder-fit, verdict: pass, evidence: ["최신 승인 방향과 solo/depth/self-serve 제약 일치"], dissent: []}
- {option-id: VOPT-HYBRID-SHARED-CORE, gate: kill-criteria, verdict: pass, evidence: ["오인·학습·중복 엔진·접근성 중단 기준 명시"], dissent: []}
kill-criteria:
- "Hybrid가 동일 콘텐츠·실험 엔진을 공유하지 못하면 Debugger 진입을 제거한다"
- "사용자 5명 중 3명 이상이 제품을 실제 장애 확정 도구로 오인하면 표현과 범위를 축소한다"
- "학습 후 3명 이상이 동일 값 읽기→독립 계산→마지막 쓰기 덮어쓰기 인과를 설명하지 못하면 출시하지 않는다"
- "첫 사례가 모바일 또는 키보드로 완주되지 않으면 다음 단계로 진행하지 않는다"
recommendation: >-
VOPT-HYBRID-SHARED-CORE를 선택 후보로 유지한다. Atlas-only는 최신 founder 결정을 누락하고,
독립 Debugger-first는 operability와 founder-fit에서 실패한다. Hybrid는 Transaction Isolation/Lost Update
한 사례와 공유 학습 코어로 제한할 때만 진행하며, 학습 효과·수요·WTP는 계속 unknown으로 둔다.
report-header:
bottom-line: >-
3안×9-gate 결과, Atlas 뼈대와 제한된 symptom-first 진입을 같은 학습 코어로 결합한 안만 최신 전략과
1인 운영성을 함께 충족한다. 단 시장·학습 효과는 미검증이므로 제품 방향만 GO 후보로 둔다.
decision-needed: { needed: true, approver: EXEC-CPO }
confidence: { value: Med, derived-from: two-trusted-opportunity-clusters-and-explicit-unknowns }
risks:
- "사용자 증거 없이 symptom entry의 효용을 과대평가할 수 있다."
- "구현 중 공유 코어 원칙이 깨지면 사실상 두 제품이 되어 범위가 폭증한다."
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-company-bootstrap-v2/STR-ANALYST-20260718T105747Z.report.yaml
grade: E2
note: "deep mechanism learning opportunity"
- source-uri: hyeonworks/completion-records/hyeonworks-company-bootstrap-v2/STR-ANALYST-20260718T105748Z.report.yaml
grade: E2
note: "symptom-to-mechanism opportunity"
@@ -0,0 +1,101 @@
report-type: workflow-artifact
artifact-kind: venture-decision
artifact-version: 1
tier: standard
identity:
artifact-id: EXEC-CEO-20260718T110148Z
workflow-id: hyeonworks-company-bootstrap-v2
stage: venture-decision
producer-role-id: EXEC-CEO
created-at: 20260718T110148Z
attempt-id: 3
payload:
basis-artifact-id: EXEC-CEO-20260718T105950Z
basis-artifact-sha256: 4771fc627a0cfa20458dfe84662dfe258a99a190300a1b08dd7e8e0f1bff8634
recommendation: >-
GO — Hyeonworks vNext는 mechanism-first Technology Atlas를 제품 뼈대로 유지하면서 symptom-first
Concept Debugger를 초기 진입 레이어로 결합한다. 첫 공개 범위는 Transaction Isolation / Lost Update
한 scenario이며, 개념 진입과 증상 진입은 동일 콘텐츠 모델·실험 상태 엔진·Predict → Observe →
Compare → Explain → Transfer 루프를 공유한다. 범용 진단·다중 도메인 Debugger는 제외한다.
selected-option-id: VOPT-HYBRID-SHARED-CORE
evaluation-criteria:
- "최신 founder 승인 방향과의 정합성"
- "깊이 있는 학습 가치와 증상 기반 관련성의 결합"
- "1인 운영·depth-before-breadth 범위 지속 가능성"
- "실제 진단 도구로 오인시키지 않는 증거 정직성"
- "하나의 콘텐츠·상태 엔진을 재사용하는 구현 가능성"
option-evaluations:
- option-id: VOPT-ATLAS-ONLY
scores: {strategy-fit: 2, learning-depth: 5, operability: 5, honesty: 5, shared-core: 5}
evidence-refs:
- "EXEC-CEO-20260718T105950Z@4771fc627a0cfa20458dfe84662dfe258a99a190300a1b08dd7e8e0f1bff8634"
- option-id: VOPT-DEBUGGER-FIRST
scores: {strategy-fit: 3, learning-depth: 3, operability: 1, honesty: 2, shared-core: 1}
evidence-refs:
- "EXEC-CEO-20260718T105950Z@4771fc627a0cfa20458dfe84662dfe258a99a190300a1b08dd7e8e0f1bff8634"
- option-id: VOPT-HYBRID-SHARED-CORE
scores: {strategy-fit: 5, learning-depth: 5, operability: 4, honesty: 5, shared-core: 5}
evidence-refs:
- "EXEC-CEO-20260718T105950Z@4771fc627a0cfa20458dfe84662dfe258a99a190300a1b08dd7e8e0f1bff8634"
- "org-os/01-company/founder-context.yaml"
tradeoffs:
- "홈에 두 진입을 제공하되 활성 학습 콘텐츠는 Transaction Isolation/Lost Update 하나로 제한한다."
- "Debugger의 기억 가능성을 취하되 실제 장애 확정·로그 분석·자동 수정 기능은 명시적으로 포기한다."
- "증상 triage UI는 추가하지만 scenario·상태 전이·설명·mitigation·transfer 콘텐츠는 복제하지 않는다."
- "제품 방향은 확정하지만 학습 효과·수요·WTP·유통은 검증 전 가설로 유지한다."
dissent:
- "두 진입은 첫 화면의 선택 복잡도를 높여 오히려 시작률을 낮출 수 있다."
- "Lost Update 한 사례만으로 Technology Atlas 정체성이 충분히 전달되지 않을 수 있다."
- "정적 시뮬레이션은 실제 데이터베이스 스케줄과 격리 구현의 모든 차이를 대표하지 않는다."
kill-criteria:
- "개념 경로와 증상 경로가 동일 scenario ID와 상태 엔진을 공유하지 못한다."
- "사용자 5명 중 3명 이상이 실제 장애를 확정 진단하는 도구로 오인한다."
- "학습 후 3명 이상이 동일 초기값 읽기 → 독립 계산 → 마지막 쓰기 덮어쓰기 인과를 설명하지 못한다."
- "360px 또는 키보드 전용 경로에서 Transfer까지 완주할 수 없다."
- "두 번째 사례 추가가 founder가 나중에 확정할 authoring timebox를 초과한다."
revisit-conditions:
- "실사용자가 증상 기반 진입을 반복 선택하고 완주율·설명 정확도가 유지되면 두 번째 증상을 검토한다."
- "완성형 딥다이브가 3개 이상이면 Atlas 탐색·검색·연결 지도를 재평가한다."
- "실제 팀 교육·결제 요청이 관찰되면 별도 revenue decision을 연다."
- "founder 시간·자본·유통·운영 내성이 확인되면 확장 속도와 사업 모델을 다시 채점한다."
evidence-refs:
- "EXEC-CEO-20260718T105950Z@4771fc627a0cfa20458dfe84662dfe258a99a190300a1b08dd7e8e0f1bff8634"
- "STR-ANALYST-20260718T105747Z@a7cb2ae28351c2f157fd4b7c4f5abbf565e6ba94aac2b607c160681f8b64c530"
- "STR-ANALYST-20260718T105748Z@95ebb4e2a73b5c1d9464c1131b7577fb3fb9b7e31c61deec228cd33ac7074515"
- "org-os/01-company/founder-context.yaml"
method-execution:
role-id: EXEC-CEO
method-id: decide-direction
contract-sha256: b5d36495b0e7e9a82fab77979a91c0144b1c51dbe1e6153352b6162272bb0d46
step-results:
- {step-id: read-evidence, status: completed, output-binding: current-artifact}
- {step-id: evaluate-options, status: completed, output-binding: current-artifact}
- {step-id: converge-decision, status: completed, output-binding: current-artifact}
self-check-results:
- step-id: converge-decision
gate-id: single-direction
verdict: Passed
evidence-refs: ["payload.selected-option-id", "payload.option-evaluations", "payload.dissent"]
decisions:
- decision-id: HWCB2-VENTURE-DECISION-001
selected-option-id: VOPT-HYBRID-SHARED-CORE
alternatives:
- {option-id: VOPT-ATLAS-ONLY}
- {option-id: VOPT-DEBUGGER-FIRST}
- {option-id: VOPT-HYBRID-SHARED-CORE}
report-header:
bottom-line: >-
GO — Atlas와 제한된 symptom-first 진입을 하나의 공유 학습 코어로 결합한다. 독립 Debugger가 아니라
Transaction Isolation/Lost Update의 두 진입이며, 실제 사용자 효과와 시장성은 아직 가설이다.
decision-needed: { needed: true, approver: HUMAN-001 }
confidence: { value: Med, derived-from: standard-three-option-nine-gate-validation }
risks:
- "공유 코어 제약이 구현 중 느슨해지면 범위가 두 제품으로 갈라질 수 있다."
- "사용자 검증 없이 symptom-first가 더 낫다고 단정할 수 없다."
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-company-bootstrap-v2/EXEC-CEO-20260718T105950Z.report.yaml
grade: E2
note: "세 옵션의 정확한 9-gate 검증과 explicit unknowns"
- source-uri: org-os/01-company/founder-context.yaml
grade: E2
note: "founder hard constraints and confirmed preferences"
@@ -0,0 +1,40 @@
report-type: workflow-artifact
artifact-kind: opportunity-cluster
artifact-version: 1
identity:
artifact-id: STR-ANALYST-20260718T105747Z
workflow-id: hyeonworks-company-bootstrap-v2
stage: opportunity-discovery
producer-role-id: STR-ANALYST
created-at: 20260718T105747Z
attempt-id: 1
payload:
source-artifact-refs:
- artifact-id: EXEC-CEO-20260718T105646Z
artifact-sha256: 132a9767f2cd7b8d7e1a07329bc2b18a42d85b5ce24025030fd2569dd004908f
id: OC-DEEP-MECHANISM-LEARNING
problem-domain: "복잡한 기술의 내부 상태 변화와 인과관계를 설명 가능한 수준으로 학습하기"
target-user: "문서·강의·AI 답변을 소비했지만 새로운 상황에서 결과를 예측하고 원인을 설명하기 어려운 개발자"
triggering-event: "면접·설계·장애 분석에서 외운 정의가 아니라 실제 상태 전이를 설명해야 할 때"
current-alternative: "공식 문서, 블로그, 영상, 정적 다이어그램, 임시 실험 코드를 서로 분리해 소비한다"
why-now: "답과 코드를 빠르게 생성할수록 그 결과를 검증하고 내부 메커니즘을 설명하는 능력이 더 중요해진다"
founder-fit: >-
mechanism-first·active-learning·depth-before-breadth·solo-operable 선호와 직접 부합한다.
실제 주당 시간과 자본은 미확정이므로 첫 주제 하나로 범위를 제한해야 한다.
evidence:
- "창업자가 기술을 깊이 학습하는 사이트와 Transaction Isolation 첫 주제를 확정했다"
unresolved-questions:
- "능동 실습이 실제 설명 정확도와 전이 능력을 높이는가"
- "두 번째 기술 주제에도 같은 콘텐츠 모델이 재사용되는가"
report-header:
bottom-line: >-
첫 기회는 설명 자료를 더 쌓는 것이 아니라 학습자가 기술 결과를 먼저 예측하고 상태 변화를
관찰한 뒤 자기 언어로 원인을 설명하게 만드는 통제된 학습 경험이다.
decision-needed: { needed: false, approver: null }
confidence: { value: Med, derived-from: founder-confirmed-problem-and-untested-user-outcomes }
risks:
- "직접 사용자 학습 효과와 반복 방문은 아직 실측되지 않았다."
evidence:
- source-uri: org-os/01-company/founder-context.yaml
grade: E2
note: "확정된 mechanism-first와 active-learning 전략 선호"
@@ -0,0 +1,40 @@
report-type: workflow-artifact
artifact-kind: opportunity-cluster
artifact-version: 1
identity:
artifact-id: STR-ANALYST-20260718T105748Z
workflow-id: hyeonworks-company-bootstrap-v2
stage: opportunity-discovery
producer-role-id: STR-ANALYST
created-at: 20260718T105748Z
attempt-id: 2
payload:
source-artifact-refs:
- artifact-id: EXEC-CEO-20260718T105646Z
artifact-sha256: 132a9767f2cd7b8d7e1a07329bc2b18a42d85b5ce24025030fd2569dd004908f
id: OC-SYMPTOM-TO-MECHANISM
problem-domain: "개념명을 모르는 실무자가 관찰한 증상에서 관련 메커니즘과 통제된 실험으로 역추적하기"
target-user: "lost update·stale state처럼 결과는 보았지만 어떤 규칙과 상태 상호작용이 원인인지 모르는 개발자"
triggering-event: "예상과 다른 값·순서·상태가 나타나 빠른 처방보다 재현 가능한 원인 이해가 필요할 때"
current-alternative: "검색·로그·AI 답변을 오가며 증상별 해결책을 복사한 뒤 원리를 사후 추정한다"
why-now: "생성형 답변을 안전하게 적용하려면 증상과 관찰 증거를 메커니즘에 연결해 검증하는 과정이 필요하다"
founder-fit: >-
깊이 학습 전략과 맞고 기억 가능한 진입점을 제공한다. 다만 범용 진단 엔진은 1인 운영 범위를
넘으므로 Transaction Isolation 안의 제한된 증상 카드가 기존 학습 코어를 재사용해야 한다.
evidence:
- "창업자가 debugger 방식을 초기 전략에 포함하되 Atlas와 결합하는 방향을 승인했다"
unresolved-questions:
- "증상 기반 진입이 개념 기반 진입보다 시작률을 높이는가"
- "동일 학습 코어를 재사용하면서도 사용자가 실제 진단 도구로 오해하지 않는가"
report-header:
bottom-line: >-
두 번째 기회는 증상에서 메커니즘으로 역추적하는 진입이다. 독립 제품보다 Atlas의 제한된
진입 레이어로 설계할 때 차별성과 1인 운영성을 함께 보존할 수 있다.
decision-needed: { needed: false, approver: null }
confidence: { value: Med, derived-from: founder-confirmed-direction-and-untested-user-behavior }
risks:
- "증상 카탈로그가 여러 도메인으로 확장되면 별도 제품 엔진과 높은 콘텐츠 유지비가 생긴다."
evidence:
- source-uri: org-os/01-company/founder-context.yaml
grade: E2
note: "solo-operable·depth-before-breadth 제약"
@@ -0,0 +1,199 @@
schema-version: 2
status: provisional
candidate-status: bootstrap
company:
facts:
- id: FACT-HW2-RESET-001
statement: >-
Hyeonworks의 기존 활성 제품·설계·workflow 산출물은 2026-07-18에 active workspace에서 제거됐고,
새 workspace는 제품 구현이 없는 초기 상태에서 시작한다. 과거 구현은 새 제품의 완료 증거로 사용하지 않는다.
category: workspace-state
provenance:
- source-uri: hyeonworks/state/hyeonworks-company-bootstrap-v2/workflow.yaml
grade: E3
verified-at: "2026-07-18"
status: active
- id: FACT-HW2-STRATEGY-001
statement: >-
표준 3안×9-gate 검증과 HUMAN-001 exact-revision 승인을 거쳐 Atlas + 제한된 symptom-first
shared-core 전략이 선택됐다.
category: accepted-strategy-process
provenance:
- source-uri: hyeonworks/completion-records/hyeonworks-company-bootstrap-v2/EXEC-CEO-20260718T105950Z.report.yaml
grade: E3
- source-uri: hyeonworks/completion-records/hyeonworks-company-bootstrap-v2/EXEC-CEO-20260718T110148Z.report.yaml
grade: E3
verified-at: "2026-07-18"
status: active
- id: FACT-FOUNDER-UNKNOWN-002
statement: >-
창업자의 실제 주당 가용시간, 자본·런웨이, 목표 사업 규모, 보유 유통채널, 운영·리스크 내성은
아직 확인되지 않았으며 확장 속도·예산·매출 판단에서 추론하면 안 된다.
category: founder-information-gap
provenance:
- source-uri: org-os/01-company/founder-context.yaml
grade: E2
verified-at: "2026-07-18"
status: active
strategic-decisions:
- id: DEC-HW2-HYBRID-001
statement: >-
Hyeonworks는 mechanism-first Technology Atlas를 제품 뼈대로 유지하면서 symptom-first
Concept Debugger를 초기 진입 레이어로 결합한 하나의 제품으로 추진한다.
decision-type: company-product-strategy
accepted-by: HUMAN-001
accepted-at: "2026-07-18T11:03:01Z"
source-decision-id: EXEC-CEO-20260718T110148Z
supporting-evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-company-bootstrap-v2/EXEC-CEO-20260718T110148Z.report.yaml
grade: E3
status: active
- id: DEC-HW2-SCOPE-001
statement: >-
첫 공개 범위는 Transaction Isolation / Lost Update 한 scenario다. 개념으로 시작하기와
증상에서 시작하기는 동일 콘텐츠 모델·scenario ID·실험 상태 엔진을 공유한다.
decision-type: initial-product-scope
accepted-by: HUMAN-001
accepted-at: "2026-07-18T11:03:01Z"
source-decision-id: EXEC-CEO-20260718T110148Z
supporting-evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-company-bootstrap-v2/EXEC-CEO-20260718T110148Z.report.yaml
grade: E3
status: active
- id: DEC-HW2-LEARNING-001
statement: >-
핵심 학습 루프는 Predict → Observe → Compare → Explain → Transfer다. 증상 진입도 정답을
즉시 제시하지 않고 단서를 좁힌 뒤 같은 실습과 전이 과제로 연결한다.
decision-type: learning-product-model
accepted-by: HUMAN-001
accepted-at: "2026-07-18T11:03:01Z"
source-decision-id: EXEC-CEO-20260718T110148Z
supporting-evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-company-bootstrap-v2/EXEC-CEO-20260718T110148Z.report.yaml
grade: E3
status: active
- id: DEC-HW2-BOUNDARY-001
statement: >-
초기 제품은 실제 장애 확정·로그 분석·원격 DB 연결·AI 자동 진단·다중 도메인 증상 taxonomy를
제공하지 않는다. 시뮬레이션과 원인 후보의 한계를 화면에서 명확하게 표시한다.
decision-type: trust-and-scope-boundary
accepted-by: HUMAN-001
accepted-at: "2026-07-18T11:03:01Z"
source-decision-id: EXEC-CEO-20260718T110148Z
supporting-evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-company-bootstrap-v2/EXEC-CEO-20260718T110148Z.report.yaml
grade: E3
status: active
- id: DEC-HW2-OPERATING-001
statement: >-
depth-before-breadth·solo-operable·self-serve를 유지한다. 학습·성장·평판을 우선하고
실제 수요와 결제 행동 전에는 가격·매출을 확정 전략으로 다루지 않는다.
decision-type: operating-principle
accepted-by: HUMAN-001
accepted-at: "2026-07-18T11:03:01Z"
source-decision-id: EXEC-CEO-20260718T110148Z
supporting-evidence:
- source-uri: org-os/01-company/founder-context.yaml
grade: E2
- source-uri: hyeonworks/completion-records/hyeonworks-company-bootstrap-v2/EXEC-CEO-20260718T110148Z.report.yaml
grade: E3
status: active
hypotheses:
- id: HYP-HW2-ENTRY-001
statement: >-
제한된 symptom-first 진입은 실제 진단 도구로 오인시키지 않으면서 개념명만 제시하는 진입보다
사용자의 시작 동기와 문제 관련성을 높인다.
hypothesis-type: entry-value
confidence: Low
validation-status: untested
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-company-bootstrap-v2/EXEC-CEO-20260718T105950Z.report.yaml
grade: E2
promotion-criteria:
- "사용자 5명 중 4명 이상이 홈 10초 노출 후 두 진입의 차이와 사이트 목적을 설명한다"
falsification-criteria:
- "사용자 5명 중 3명 이상이 실제 장애 확정 도구로 오인하거나 두 진입의 차이를 설명하지 못한다"
- id: HYP-HW2-LEARNING-001
statement: >-
공유 학습 루프를 완주한 사용자는 Lost Update의 인과관계를 자기 언어로 설명하고 새로운 재고 사례에 전이할 수 있다.
hypothesis-type: learning-outcome
confidence: Low
validation-status: untested
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-company-bootstrap-v2/EXEC-CEO-20260718T105950Z.report.yaml
grade: E2
promotion-criteria:
- "사용자 5명 중 4명 이상이 인과관계를 설명하고 3명 이상이 새 사례를 정확히 판별한다"
falsification-criteria:
- "학습 후에도 3명 이상이 동일 값 읽기와 마지막 쓰기 덮어쓰기를 연결하지 못한다"
- id: HYP-HW2-SHARED-CORE-001
statement: >-
개념 진입과 증상 진입은 하나의 콘텐츠·scenario·상태 엔진을 공유해 별도 제품 수준의 운영비 없이 유지될 수 있다.
hypothesis-type: solo-operability
confidence: Med
validation-status: untested
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-company-bootstrap-v2/EXEC-CEO-20260718T105950Z.report.yaml
grade: E2
promotion-criteria:
- "정적 계약 검사에서 두 진입이 동일 scenario ID와 reducer/state engine을 사용하고 설명 중복이 없다"
falsification-criteria:
- "Debugger 진입을 위해 별도 실험 엔진이나 중복 콘텐츠가 필요하다"
- id: HYP-HW2-DEMAND-001
statement: >-
깊이 있는 양방향 기술 학습 경험에는 반복 방문과 향후 유료 옵션을 시험할 수 있는 organic 수요가 있다.
hypothesis-type: demand-and-willingness-to-pay
confidence: Low
validation-status: untested
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-company-bootstrap-v2/EXEC-CEO-20260718T105950Z.report.yaml
grade: E2
promotion-criteria:
- "공개 전 정한 유입·시작·완료·재방문 기준과 별도 가격 행동 기준을 실제 데이터가 충족한다"
falsification-criteria:
- "정한 관찰 기간에 최소 수요·재방문 또는 가격 행동 기준을 충족하지 못한다"
validation-state:
stage: pre-product
validated:
- "founder strategy direction and initial scope decision"
open:
- HYP-HW2-ENTRY-001
- HYP-HW2-LEARNING-001
- HYP-HW2-SHARED-CORE-001
- HYP-HW2-DEMAND-001
- "새 제품 구현·접근성·반응형·결정론적 학습 흐름 검증"
- "founder 실제 시간·자본·사업규모·유통·운영/리스크 내성"
refuted:
- "초기 독립 다중 도메인 Concept Debugger"
- "준비 중 콘텐츠를 완성 카탈로그처럼 보이는 전략"
projects:
- id: hyeonworks
product-purpose: >-
개념명 또는 실제 증상에서 시작해 기술 상태 변화를 예측·관찰·비교·설명하고 새 상황에 전이한다.
project-root: hyeonworks
application-root: hyeonworks/app
stage: reset-planning
stack:
- "미결정 — architecture/design 단계에서 재선정"
build: "cd app && npm run build"
test: "cd app && npm run verify"
lint: "cd app && npm run lint"
run: "cd app && npm run dev -- --host 127.0.0.1"
preview-out-dir: dist
users:
- "기술 정의를 읽었지만 내부 상태 변화와 인과관계를 설명하기 어려운 개발자"
- "동시성 이상 현상을 겪었지만 증상을 메커니즘에 연결하기 어려운 실무 개발자"
constraints:
- "활성 콘텐츠는 Transaction Isolation/Lost Update 한 scenario"
- "개념·증상 진입은 같은 콘텐츠와 상태 엔진을 사용"
- "실제 장애 진단·원격 DB·AI 자동 진단으로 표현하지 않음"
- "키보드·모바일·WCAG AA 품질선을 설계 단계부터 적용"
code-conventions:
- "scenario와 content data를 UI에서 분리하고 두 진입이 동일 ID를 참조"
- "상태 전이는 결정론적이며 Reset 시 같은 초기 상태로 복귀"
- "준비 중 주제는 비활성이고 완성 기능처럼 링크하지 않음"
sensitivity: public
recent-decisions:
- date: "2026-07-18"
decision: "Technology Atlas + limited symptom-first entry on one shared learning core"
evidence: EXEC-CEO-20260718T110148Z
@@ -0,0 +1,75 @@
report-type: workflow-artifact
artifact-kind: divergence-charter
artifact-version: 1
identity:
artifact-id: DES-DIRECTOR-20260718T111440Z-1
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-discovery
producer-role-id: DES-DIRECTOR
created-at: 20260718T111440Z
attempt-id: 2
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
representative-screen:
id: dual-entry-shared-lab
kind: first-entry
description: >-
두 출발점과 하나의 Lost Update Lab, 짧은 Atlas path, 학습 루프, guided-scenario 경계를 한 화면에서
이해하고 어느 출발점으로든 실제 학습을 시작할 수 있는 첫 화면.
directions:
- id: ledger-studio
design-question: "기술 인과를 전문 저널의 검증 가능한 실험 기록처럼 읽게 하면 깊이와 신뢰를 전달하는가?"
layout-topology: "비대칭 editorial spread; 왼쪽 큰 논제와 두 entry, 오른쪽 shared lab ledger 및 하단 causal path"
navigation-model: "두 entry anchor에서 공통 Lab Brief로 부드럽게 합류하는 세로 읽기; 명시적 skip link"
typography-voice: "humanist serif display + neutral grotesk body + mono evidence annotations"
imagery-strategy: "값 변화가 적힌 ledger lines, margin note, read/compute/write의 인쇄 도식"
motion-model: "합류선을 짧게 그리며 evidence row만 순차 강조; reduced motion에서는 정적 표시"
dominant-primitives: [entry-column, causal-ledger, evidence-margin]
exclusive-primitives: [merge-rule, ledger-folio, annotated-value]
forbidden-primitives: [node-canvas, terminal-window, glass-card-grid]
- id: signal-trace
design-question: "두 세션의 신호와 값 흐름을 계측 rail처럼 추적하면 Lost Update의 시간적 인과를 더 빨리 이해하는가?"
layout-topology: "상단 dual input bands가 중앙 merge bus로 수렴하고 아래 full-width transaction trace로 이어지는 rail topology"
navigation-model: "entry band 선택→공통 trace focus; 단계는 좌우가 아닌 위아래 rail과 native next controls로 이동"
typography-voice: "precise sans + tabular numeric + compact uppercase signal labels"
imagery-strategy: "solid signal rails, stamped state nodes, striped conflict region; 색 외 session labels 반복"
motion-model: "실행 단계에서 현재 rail segment만 pulse; reduced motion은 굵기·패턴 전환"
dominant-primitives: [entry-band, merge-bus, trace-rail]
exclusive-primitives: [signal-stamp, conflict-hatch, value-probe]
forbidden-primitives: [editorial-marginalia, detective-file, orbit-map]
- id: field-manual
design-question: "굵은 단계·규칙·체크포인트의 현장 매뉴얼처럼 구성하면 두 진입과 학습 행동을 가장 실행 가능하게 만드는가?"
layout-topology: "모듈형 poster stack; 상단 선언, 2-up entry panels, numbered common protocol, compact scenario preview"
navigation-model: "명시적 numbered checkpoints와 sticky progress; entry 후 공통 Protocol 01로 합류"
typography-voice: "condensed display labels + warm humanist sans instructions + mono commands"
imagery-strategy: "번호판·규칙 블록·값 토큰·인과 화살표를 사용한 field diagram"
motion-model: "checkpoint 완료 시 stamp 전환만 사용; reduced motion과 동일 정보 구조"
dominant-primitives: [protocol-panel, numbered-checkpoint, rule-block]
exclusive-primitives: [field-stamp, procedure-strip, transfer-ticket]
forbidden-primitives: [serif-folio, signal-oscilloscope, dashboard-metric-grid]
pairwise-separation:
- directions: [ledger-studio, signal-trace]
differing-axes: [layout-topology, navigation-model, typography-voice, imagery-strategy, motion-model, dominant-primitives]
allowed-overlap: "제품 카피·두 entry·shared scenario·접근성·학습 루프만 공유"
- directions: [ledger-studio, field-manual]
differing-axes: [layout-topology, navigation-model, typography-voice, imagery-strategy, motion-model, dominant-primitives]
allowed-overlap: "제품 카피·두 entry·shared scenario·접근성·학습 루프만 공유"
- directions: [signal-trace, field-manual]
differing-axes: [layout-topology, navigation-model, typography-voice, imagery-strategy, motion-model, dominant-primitives]
allowed-overlap: "제품 카피·두 entry·shared scenario·접근성·학습 루프만 공유"
report-header:
bottom-line: >-
Ledger Studio·Signal Trace·Field Manual은 동일 요구를 각각 편집 기록, 계측 rail, 실행 프로토콜이라는
상반된 정신 모델로 구현한다. 최소 여섯 축이 달라 표면적 변주가 아니다.
decision-needed: { needed: false, approver: null }
confidence: { value: Med, derived-from: accepted-preframing-and-discovery }
risks:
- "Signal Trace가 terminal/hacker 미학으로 기울 수 있어 밝고 정밀한 계측 언어로 제한해야 한다."
- "Field Manual의 굵은 모듈이 교육 도구보다 marketing poster로 보일 수 있다."
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-PROD-20260718T111439Z.report.yaml
grade: E3
note: "pre-direction framing"
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-DIRECTOR-20260718T111440Z.report.yaml
grade: E3
note: "direction discovery constraints"
@@ -0,0 +1,59 @@
report-type: workflow-artifact
artifact-kind: direction-discovery
artifact-version: 1
identity:
artifact-id: DES-DIRECTOR-20260718T111440Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-discovery
producer-role-id: DES-DIRECTOR
created-at: 20260718T111440Z
attempt-id: 1
payload:
direction-input-brief-sha256: 975a7713b1837576173aee1d9a349bb68afd652ed9d1166fd9d5efc39059d9b4
findings:
- id: F-TWO-ENTRIES-ONE-PRODUCT
observation: "제품 결정은 두 출발점을 요구하지만 합류 후 모든 학습 상태와 콘텐츠는 하나여야 한다."
implication: "대표 화면은 두 portal 사이에 공통 목적과 합류 지점을 시각적으로 먼저 보여줘야 한다."
evidence-ref: hyeonworks/completion-records/hyeonworks-vnext-v1/EXEC-CEO-20260718T111108Z.report.yaml
- id: F-HONEST-DEBUGGER
observation: "증상 기반 진입은 실제 로그나 사용자 환경을 분석하지 않는 고정 교육 시나리오다."
implication: "경고·incident 콘솔보다 관찰→후보→검증의 언어와 guided-scenario 라벨을 사용한다."
evidence-ref: org-os/01-company/company-context.yaml
- id: F-DEPTH-PROOF
observation: "활성 콘텐츠가 하나뿐이므로 카탈로그 규모가 아니라 한 사례의 인과 깊이로 가치를 증명해야 한다."
implication: "첫 화면에 100→150/70 값 변화와 read/compute/write 순서를 의미 있는 미리보기로 노출한다."
evidence-ref: hyeonworks/design/hyeonworks-vnext-v1/direction-input-brief.yaml
- id: F-ATLAS-HONESTY
observation: "완성 딥다이브가 하나뿐인 상태에서 큰 node map은 제품 규모를 과장한다."
implication: "Atlas는 Concurrency → Transaction Isolation → Lost Update의 짧은 breadcrumb로 제한한다."
evidence-ref: hyeonworks/completion-records/hyeonworks-vnext-v1/EXEC-CEO-20260718T111108Z.report.yaml
- id: F-ACCESSIBLE-DENSITY
observation: "timeline과 두 세션 비교는 시각적으로 유용하지만 모바일·스크린리더에서는 선형 대안이 필요하다."
implication: "모든 방향은 DOM 읽기 순서, 표/목록 대안, native button, 가시적 focus를 기본으로 설계한다."
evidence-ref: hyeonworks/design/hyeonworks-vnext-v1/direction-input-brief.yaml
constraints-restated:
- "대표 화면 id는 dual-entry-shared-lab으로 고정한다."
- "두 entry는 동일 tx-lost-update-01을 참조하고 합류 후 state 분기 금지."
- "360/768/1280px, 키보드, reduced-motion, WCAG AA를 모두 지원한다."
- "실제 장애 확정·원격 DB·AI 진단으로 오인되는 카피와 시각 언어를 금지한다."
- "세 방향은 layout·navigation·type·imagery·motion·primitive 중 최소 네 축이 다르다."
- "보라 SaaS gradient, neon hacker terminal, glass card grid, 과장된 atlas map을 금지한다."
opportunity-notes:
- "shared-core는 합류 rail·공통 lab seal·단일 progress 구조로 시각화할 수 있다."
- "Case File의 단서 전개는 교육용 hypothesis ledger로 번역하면 진단 오인을 피하면서 기억성을 얻는다."
report-header:
bottom-line: >-
디자인 핵심은 portal 두 개의 외형이 아니라 '다른 단서에서 시작해 같은 인과 실험으로 합류'하는 구조를
이해시키는 것이다. 세 방향은 이 합류를 편집 기록·신호 rail·현장 매뉴얼로 각각 다르게 푼다.
decision-needed: { needed: false, approver: null }
confidence: { value: Med, derived-from: accepted-decision-and-frozen-brief }
risks:
- "세 방향이 결국 카드 색상 변형으로 수렴할 위험이 있다."
- "시각적 개성이 학습 상태의 정밀성을 가릴 수 있다."
evidence:
- source-uri: hyeonworks/design/hyeonworks-vnext-v1/direction-input-brief.yaml
grade: E3
note: "frozen design input"
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1/EXEC-CEO-20260718T111108Z.report.yaml
grade: E3
note: "accepted product direction"
@@ -0,0 +1,83 @@
report-type: workflow-artifact
artifact-kind: selected-direction
artifact-version: 1
identity:
artifact-id: DES-DIRECTOR-20260718T115933Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-decision
producer-role-id: DES-DIRECTOR
created-at: 20260718T115933Z
attempt-id: 3
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
direction-set-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-VISUAL-20260718T113705Z.report.yaml
direction-set-sha256: ff7384a6a4977cd0bff7f0a19e4a5b0611010c287a80f9a230cca9566c7613d5
selected-direction-id: ledger-studio
parent-workflow-id: hyeonworks-vnext-v1
product-decision-id: EXEC-CEO-20260718T111108Z
direction-input-brief-sha256: 975a7713b1837576173aee1d9a349bb68afd652ed9d1166fd9d5efc39059d9b4
selection-acceptance-receipt: HUMAN-001-session-full-flow-authorization-20260718
rationale: >-
Hyeonworks의 최우선 약속은 많은 주제를 나열하는 것이 아니라 하나의 기술 메커니즘을 전문가 수준으로
깊게 이해시키는 것이다. Ledger Studio는 큰 기술 질문, 검증할 값, 실행 순서, 두 출발점과 공통 Lab을
한 편집 기록 구조로 묶어 이 약속을 가장 직접적으로 보여준다. 증상 진입도 monitoring/incident 제품처럼
보이지 않고 관찰값을 causal ledger에서 검증하게 하므로 Concept Debugger를 교육적 입구로 유지한다.
selection-criteria:
product-fit: "깊이 학습·mechanism-first backbone·symptom-first entry를 동시에 가장 정확히 표현"
trust: "실제 진단 도구가 아닌 guided learning scenario로 읽히는 정도가 가장 높음"
learning-flow: "Predict 이전의 질문과 Observe 이후의 evidence를 한 기록 위계로 연결"
accessibility: "DOM 순서·native anchors·mobile single column이 정신 모델을 거의 잃지 않음"
implementation-fit: "범용 diagram/runtime 없이 React와 CSS로 실제 reducer 상태를 명료하게 표현 가능"
rejected-directions:
- id: signal-trace
reason: >-
시간적 인과 판독은 빠르지만 channel·probe·online 상태 언어가 교육 도구보다 monitoring/debug console로
오인될 위험이 있다. 사용자가 요청한 debugger 입구는 제품 전체의 표면이 아니라 증상→후보→검증
흐름이어야 하므로 Signal의 계측 은유를 지배 방향으로 채택하지 않는다.
- id: field-manual
reason: >-
번호형 프로토콜은 행동 순서를 강하게 만들지만 대형 Module 01 cover가 실제 학습 control보다 먼저
보이며 marketing poster로 읽힐 위험이 있다. 또한 long-form 인과 설명과 evidence 비교를 수용하는
확장성이 Ledger보다 낮다.
locked-invariants:
- id: LI-EDITORIAL-EVIDENCE
invariant: >-
비대칭 editorial spread, serif 논제, mono evidence annotation, causal ledger가 화면 위계를 지배하며
일반 SaaS 카드 grid·dashboard·terminal shell로 후퇴하지 않는다.
- id: LI-DUAL-ENTRY-SHARED-CORE
invariant: >-
‘개념을 알고 있어요’와 ‘증상만 알고 있어요’는 orientation만 다르고 같은 tx-lost-update-01,
같은 reducer, 콘텐츠, 진행 상태로 합류한다.
- id: LI-EVIDENCE-LEARNING-LOOP
invariant: >-
정답을 먼저 설명하지 않고 Predict → Observe → Compare → Explain → Transfer 순서를 유지하며
100·120·150·70의 인과를 같은 ledger 안에서 대조한다.
- id: LI-HONEST-BOUNDARY
invariant: >-
증상 경로와 Lab은 고정 guided scenario 및 후보 메커니즘 검증이라고 명시하고 실제 로그 분석,
원격 DB 연결, 장애 원인 확정으로 표현하지 않는다.
- id: LI-ACCESSIBLE-READING
invariant: >-
360/768/1280에서 DOM 읽기 순서와 합류 의미를 보존하고 모든 활성 control은 키보드로 도달하며
값·세션·상태를 색 외 텍스트와 형태로 표시한다.
flexible-elements:
- "serif fallback과 세부 type scale은 한국어 렌더 품질에 맞게 조정 가능"
- "ledger 내부 행 간격과 section 길이는 실제 학습 상태 밀도에 맞게 조정 가능"
- "observed coral의 정확한 명도는 WCAG AA를 지키는 범위에서 조정 가능"
adopted-elements: []
report-header:
bottom-line: >-
Ledger Studio를 유일한 지배 방향으로 선택한다. 전문 저널의 질문과 causal ledger가 깊이 학습을
가장 잘 표현하며, debugger 방식은 증상 입구→후보 메커니즘→동일 Lab 검증 흐름으로 포함한다.
decision-needed: { needed: true, approver: HUMAN-001 }
confidence: { value: Med, derived-from: independent-coded-directions-and-hash-bound-comparison }
risks:
- "첫 화면의 편집 읽기량이 실행 진입을 늦출 수 있어 실제 앱에서는 두 entry를 첫 유효 viewport 가까이에 유지해야 한다."
- "사용자 이해도 비교는 아직 없으므로 선택의 학습 효과는 자동 검증 통과로 주장하지 않는다."
evidence:
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/previews/comparison.png
grade: E3
note: "세 방향의 1280/390 실제 Chrome 비교 렌더"
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-VISUAL-20260718T113705Z-1.report.yaml
grade: E3
note: "모든 pair 6축 분리와 primitive collision 부재를 확인한 accepted audit"
@@ -0,0 +1,160 @@
report-type: workflow-artifact
artifact-kind: design-review-panel
artifact-version: 1
identity:
artifact-id: DES-DIRECTOR-20260718T124159Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: DES-DIRECTOR
created-at: 20260718T124159Z
attempt-id: 4
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
target-prototype-id: ENG-FE-20260718T120840Z
target-prototype-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T120840Z.report.yaml
target-prototype-sha256: 1cfa4ff43762111f46b0088057f6b902375f86856558056aa5f11f117f107267
reviews:
- report-id: DES-PROD-20260718T121036Z
report-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-PROD-20260718T121036Z.report.yaml
report-sha256: f24b3a407ed6c5fca0c6b769c929b61185df88bb3eed6e8efb63691ce0ef388b
lens: product-fit
reviewer-role-id: DES-PROD
reviewer-run-id: hyeonworks-vnext-v1-direction-review-product-fit-20260718T1211Z
verdict: revise
- report-id: UX-RESEARCHER-20260718T121036Z
report-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/UX-RESEARCHER-20260718T121036Z.report.yaml
report-sha256: 544fe3dc7ed6d97f5aec5abd4125b8d1bb815876ed989ae734ef1f807779335d
lens: usability
reviewer-role-id: UX-RESEARCHER
reviewer-run-id: hyeonworks-vnext-v1-direction-review-usability-20260718T1211Z
verdict: revise
- report-id: DES-VISUAL-20260718T121036Z
report-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-VISUAL-20260718T121036Z.report.yaml
report-sha256: 67ab93d09890b049958e9ac3e44a2b9be8d65162ed827585e421be3e848d3910
lens: distinctiveness
reviewer-role-id: DES-VISUAL
reviewer-run-id: 2453b69fee7004f95eef43556a488b8f1230e84a2c9fe92cb7c6706e7bd515c1
verdict: pass
- report-id: DES-VISUAL-20260718T121851Z
report-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-VISUAL-20260718T121851Z.report.yaml
report-sha256: ed7411ada1c9023222710a3fe3107c2a3e572a9eea47fc66d6e311affc01b61a
lens: visual-craft
reviewer-role-id: DES-VISUAL
reviewer-run-id: hyeonworks-vnext-v1-direction-review-visual-craft-20260718T121347Z
verdict: revise
- report-id: DES-PLATFORM-20260718T121851Z
report-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-PLATFORM-20260718T121851Z.report.yaml
report-sha256: 98e9a52f4603557be6a2750e7d8bbb31f0acfdc3022225a421cd776e2fc071a5
lens: systematizability
reviewer-role-id: DES-PLATFORM
reviewer-run-id: cac14c7f6f176f94508730de72c5558f89165715d287f89229474ac6cc12eccd
verdict: revise
- report-id: GTM-PMM-20260718T121851Z
report-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/GTM-PMM-20260718T121851Z.report.yaml
report-sha256: d14c9cb1ff10f36d64d20e49ba7ffe2bc00f41d0ff57ebb7181bd4329224afe6
lens: market-memorability
reviewer-role-id: GTM-PMM
reviewer-run-id: a891c7a54da7771de16bb84cff76ab3c40f3c85b09374285a6656915211bddea
verdict: revise
- report-id: ENG-FE-20260718T121851Z
report-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T121851Z.report.yaml
report-sha256: a65a2f5a6ea2436566df5378acfebcc25842be24170c8802ac2aebcaeb477f49
lens: implementability
reviewer-role-id: ENG-FE
reviewer-run-id: 4b99a5f4d221f1fcf996194fa0c3e799311b102da9e544e518fb0b83693f5375
verdict: revise
synthesis:
verdict: minor-revision
role-id: DES-DIRECTOR
unresolved-dissent: []
rule-application: >-
7개 lens가 정확히 한 번씩 존재하고 blocking verdict는 없다. distinctiveness는 pass지만 veto lens인
visual-craft를 포함한 나머지 6개 lens가 revise이므로, 개별 판정을 낮추지 않고 panel verdict를
minor-revision으로 보존한다.
direction-decision: >-
Ledger Studio의 선택과 editorial-evidence, dual-entry/shared-core, evidence learning loop,
honest boundary, accessible reading의 잠긴 불변식은 유지한다. 발견사항은 방향 재선택이 아니라
학습 게이트, 접근성·조판, 메시지, 재사용 경계를 교정하는 범위다.
preserved-strengths:
- >-
distinctiveness review가 확인한 비대칭 editorial spread, mono evidence annotation,
100·120·70 causal ledger와 두 entry의 Same Lab 합류는 유지한다.
- >-
정적·결정론적 reducer와 network/storage/randomness 없는 guided-scenario 경계는 수정의 안전한 기반이다.
required-revisions:
- priority: P0
theme: learning-evidence-integrity
source-lenses: [product-fit, market-memorability]
scope: >-
Home/Predict에서 결과와 write trace를 선공개해 예측을 회상 문제로 만드는 구조를 고치고,
Explain은 제공 문장 선택만으로 인과 설명 능력을 주장하지 않도록 constructed causal task를 요구한다.
headline은 실제 Predict → Observe → Explain 순서와 일치시키되 100·120·70 회상 단서는 보존한다.
- priority: P0
theme: interaction-accessibility-and-legibility
source-lenses: [usability, visual-craft, implementability]
scope: >-
라디오 변경과 Observe 6/6 이후 focus target, live error feedback, 수정 답 재제출 상태를 명시하고
trace에 native/완전한 table semantics를 준다. Shared Lab boundary 대비와 한국어 display 어절 줄바꿈을
360/768/1280에서 교정하고 실제 keyboard state-flow E2E로 검증한다.
- priority: P1
theme: responsive-and-market-hierarchy
source-lenses: [usability, visual-craft, market-memorability]
scope: >-
360/768에서 entry 접근 거리를 줄이고 tablet 전용 hero/progress 밀도를 조정한다. 단일 public-facing
name과 개발자용 interactive mechanism Lab이라는 category descriptor를 정해 Atlas·Field note·Lab의
위계를 명료하게 한다.
- priority: P1
theme: production-system-boundaries
source-lenses: [systematizability, implementability]
scope: >-
다음 주제 추가 전에 id 기반 scenario registry/schema와 pure reducer, route/view를 분리하고,
spacing/type/stroke/elevation/breakpoint token 및 ledger-row/sheet/progress/value-comparison recipe를
추출한다. backend나 불필요한 상태 라이브러리는 추가하지 않는다.
exit-criteria:
- "6개 revise 원본의 required action이 수정 receipt에 trace되고 재리뷰에서 7개 lens가 모두 pass한다."
- "visual-craft veto finding의 Lab 대비·한국어 조판·tablet density가 실제 상태별 render로 재검수된다."
- "키보드 focus, live feedback, trace semantics와 전체 learning loop가 실제 Chrome E2E로 통과한다."
report-header:
bottom-line: >-
MINOR-REVISION — exact winner의 Ledger Studio 방향과 고유성은 유지하되, 7개 독립 lens 중
distinctiveness만 pass하고 visual-craft를 포함한 6개가 revise이므로 학습 증거, 접근성·조판,
시장 메시지, 재사용·production 경계를 수정한 뒤 전체 panel을 다시 통과해야 한다.
decision-needed: { needed: false, approver: null }
confidence:
value: Med
derived-from: exact-winner-and-seven-live-sha-bound-independent-review-originals
risks:
- >-
100·120·70과 full trace의 선공개를 고칠 때 distinctiveness가 확인한 숫자 기반 회상 단서까지 제거하면
학습 무결성을 회복하면서 브랜드 고유성을 잃을 수 있다.
- >-
focus·feedback·trace semantics와 Lab 대비는 실제 상태 상호작용에서 드러난 문제이므로 정적 preview만
다시 생성해서는 수정 완료를 증명할 수 없다.
- >-
scenario/component 경계 추출은 다음 주제 확장 전 필요하지만, 이번 minor revision에서 backend나
범용 runtime까지 도입하면 방향 검증보다 플랫폼화 범위가 커질 수 있다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T120840Z.report.yaml
grade: E3
note: "exact winner ENG-FE-20260718T120840Z, live SHA 1cfa4ff4… 결속"
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-PROD-20260718T121036Z.report.yaml
grade: E3
note: "product-fit revise 원본, live SHA f24b3a40…"
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/UX-RESEARCHER-20260718T121036Z.report.yaml
grade: E3
note: "usability revise 원본, live SHA 544fe3dc…"
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-VISUAL-20260718T121036Z.report.yaml
grade: E3
note: "distinctiveness pass 원본, live SHA 67ab93d0…"
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-VISUAL-20260718T121851Z.report.yaml
grade: E3
note: "visual-craft revise 원본, live SHA ed7411ad…"
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-PLATFORM-20260718T121851Z.report.yaml
grade: E3
note: "systematizability revise 원본, live SHA 98e9a52f…"
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/GTM-PMM-20260718T121851Z.report.yaml
grade: E3
note: "market-memorability revise 원본, live SHA d14c9cb1…"
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T121851Z.report.yaml
grade: E3
note: "implementability revise 원본, live SHA a65a2f5a…"
@@ -0,0 +1,132 @@
report-type: workflow-artifact
artifact-kind: design-review-panel
artifact-version: 1
identity:
artifact-id: DES-DIRECTOR-20260718T133900Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: DES-DIRECTOR
created-at: 20260718T133900Z
attempt-id: 5
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
target-prototype-id: ENG-FE-20260718T131305Z
target-prototype-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T131305Z.report.yaml
target-prototype-sha256: bcc557fcd7463349345bd06090868c4c2b6b792453d4e1dddd4ac60b0fa68674
reviews:
- report-id: DES-PROD-20260718T131443Z
report-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-PROD-20260718T131443Z.report.yaml
report-sha256: 6fd00e37a7ab68569f5ead21e68ea8ad6b70e47aea9fae92c97d876915995c50
lens: product-fit
reviewer-role-id: DES-PROD
reviewer-run-id: db69cd61af060c50804e694ae541d0106551b2025eb654b6947428de4e983bce
verdict: pass
- report-id: UX-RESEARCHER-20260718T131443Z
report-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/UX-RESEARCHER-20260718T131443Z.report.yaml
report-sha256: 08f434f9f1f4afca2cb3192fe566b846e9a803ca9c5dc788d33c848a6d6a948e
lens: usability
reviewer-role-id: UX-RESEARCHER
reviewer-run-id: b08974977a3f60b7b0ca23bb23d853bb5b2476387bd71a011e20ba145dd35d79
verdict: revise
- report-id: DES-VISUAL-20260718T131443Z
report-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-VISUAL-20260718T131443Z.report.yaml
report-sha256: 516867f7240a4e3abe2b778d9282d6fb98137c0f60e78a69c0693f60f6168199
lens: distinctiveness
reviewer-role-id: DES-VISUAL
reviewer-run-id: 44640b239eaefd6fe05ba540d1fda7cfa90498fef66a896228a1a91d9caa370a
verdict: pass
- report-id: DES-VISUAL-20260718T131448Z
report-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-VISUAL-20260718T131448Z.report.yaml
report-sha256: 9ebc7a2dc4bbef084614902c8afbde24451727828b6bce0f402e5f2903474477
lens: visual-craft
reviewer-role-id: DES-VISUAL
reviewer-run-id: d388e8cde4d3a732a077962455b842667dd4c7f2ee00b8222873f86d4790fe9e
verdict: revise
- report-id: DES-PLATFORM-20260718T131443Z
report-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-PLATFORM-20260718T131443Z.report.yaml
report-sha256: 02529b7e441b2d514e8ef8923b986e2ceb6348c73577d739606dc7f0352c2e46
lens: systematizability
reviewer-role-id: DES-PLATFORM
reviewer-run-id: 2336d0c343a10e89d7b2b419a9803c49a182646f7716ebf8dda1170857f0dc68
verdict: revise
- report-id: GTM-PMM-20260718T131443Z
report-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/GTM-PMM-20260718T131443Z.report.yaml
report-sha256: a2b1d4e457f0e14d149cd77aea76656802224d1a1fd54a8a64cec20699009b06
lens: market-memorability
reviewer-role-id: GTM-PMM
reviewer-run-id: a3aa4278f9c46ba6656fec6102f29d0cf2992dce7bd7fe1f1fb8c9c206c9addc
verdict: pass
- report-id: ENG-FE-20260718T131443Z
report-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T131443Z.report.yaml
report-sha256: 70f5a4db69565bb75f004d01fb47f2f716a97ac5317dbbe421869a3aa164484c
lens: implementability
reviewer-role-id: ENG-FE
reviewer-run-id: eab69987ab88f740e4c80ed8b5e1cbb0b9cfdbb61bb29e7535d1e42c368e49f3
verdict: pass
synthesis:
verdict: minor-revision
role-id: DES-DIRECTOR
unresolved-dissent: []
rule-application: >-
exact winner에 7개 lens가 정확히 한 번씩 결속되고 blocking은 없다. product-fit,
distinctiveness, market-memorability, implementability는 pass지만 usability, visual-craft,
systematizability가 revise이므로 개별 판정을 낮추지 않고 panel을 minor-revision으로 보존한다.
direction-decision: >-
Ledger Studio, Technology Atlas 공개명, 두 입구와 하나의 causal Lab, Predict→Observe→Compare→Explain→Transfer,
guided-scenario 경계는 그대로 유지한다. 발견사항은 반응형 containment, focus anchor, 한국어 조판,
registry-to-render 결속을 교정하는 국소 수정이며 방향 재선택 사유가 아니다.
preserved-strengths:
- 제품 약속과 constructed Explain·Transfer·정직한 completion은 product-fit pass 근거로 유지한다.
- 비대칭 editorial ledger와 100·120·70 회상 묶음은 distinctiveness·market pass 근거로 유지한다.
- 순수 reducer, native controls/table, deterministic static boundary는 implementability pass 근거로 유지한다.
required-revisions:
- priority: P0
theme: mobile-containment-and-entry-focus
source-lenses: [usability]
scope: >-
360px Observe에서 workbench를 viewport 안에 제한하고 table만 trace-scroll 내부에서 스크롤되게 한다.
entry shortcut은 router 재렌더 없이 entry-title에 실제 focus와 scroll을 주며 360/768 keyboard·pointer로 검증한다.
- priority: P1
theme: korean-responsive-typography
source-lenses: [visual-craft]
scope: >-
Lab body, lead, choices, boundary, principles에 한국어 keep-all을 적용하되 긴 Latin id에는 안전한
overflow fallback을 둔다. 5개 360 state render에서 조판과 zero document overflow를 다시 확인한다.
- priority: P0
theme: active-scenario-content-binding
source-lenses: [systematizability]
scope: >-
route/labState의 scenarioId에서 activeScenario를 해석해 render, dispatch, announcement에 전달한다.
최소 두 번째 fixture의 id·atlas·value·schedule·hypothesis·explanation·transfer·feedback을 DOM으로 검증하되
범용 plugin/runtime이나 backend는 추가하지 않는다.
exit-criteria:
- 360px Observe에서 document scrollWidth가 clientWidth와 같고 trace-scroll 자체는 내부 overflow를 가진다.
- entry shortcut 활성화 뒤 entry-title이 activeElement이고 목표가 viewport 상단 근처에 위치한다.
- 모든 Lab body copy가 Korean keep-all과 Latin overflow fallback을 사용하며 360 state renders를 갱신한다.
- 두 scenario fixture가 같은 reducer/view에서 각 record의 id, copy, values, schedule, answers, announcement를 렌더한다.
- 수정본에 대해 7개 독립 lens를 새 context-package와 run-id로 모두 다시 실행하여 전부 pass한다.
report-header:
bottom-line: >-
MINOR-REVISION — revision 2는 제품 적합성·차별성·시장성·구현 가능성을 통과했지만,
실제 360px overflow와 entry focus, 한국어 본문 조판, active scenario render 결속을 고친 뒤
7-lens 전체 pass가 필요하다.
decision-needed: { needed: false, approver: null }
confidence:
value: Med
derived-from: exact-winner-and-seven-sha-bound-independent-review-originals
risks:
- active scenario 결속을 고칠 때 범용 schema/runtime로 확대하면 단일 주제 방향 검증을 넘어 과설계가 된다.
- CSS만 보고 통과시키면 Observe live overflow와 anchor focus 결함을 재현하지 못하므로 Chrome state assertions가 필요하다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T131305Z.report.yaml
grade: E3
note: exact revision-2 winner SHA bcc557fc…
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/UX-RESEARCHER-20260718T131443Z.report.yaml
grade: E3
note: live 360 overflow와 anchor focus revise 원본
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-VISUAL-20260718T131448Z.report.yaml
grade: E3
note: 360 Korean body typography revise 원본
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-PLATFORM-20260718T131443Z.report.yaml
grade: E3
note: registry-to-render/content binding revise 원본
@@ -0,0 +1,125 @@
report-type: workflow-artifact
artifact-kind: design-review-panel
artifact-version: 1
identity:
artifact-id: DES-DIRECTOR-20260718T142500Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: DES-DIRECTOR
created-at: 20260718T142500Z
attempt-id: 6
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
target-prototype-id: ENG-FE-20260718T135811Z
target-prototype-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T135811Z.report.yaml
target-prototype-sha256: 735d588bef412dd3c59899d393562ae76a67a55bbe9f507ddf38eeab1481e9f0
reviews:
- report-id: DES-PROD-20260718T140000Z
report-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-PROD-20260718T140000Z.report.yaml
report-sha256: 65b079dff892848ca42d29796000146fc6ee741c77335bd99ea01bc3bb0783b6
lens: product-fit
reviewer-role-id: DES-PROD
reviewer-run-id: 1b92e14079e2752bac1d8c62f6d1ab73ee8d33aef646f22c0c76fe134f27c988
verdict: pass
- report-id: UX-RESEARCHER-20260718T140000Z
report-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/UX-RESEARCHER-20260718T140000Z.report.yaml
report-sha256: 4a1fbbe7f6ea61dc9ce9f8dc0523468aef9c4d893e075503946a2f867455ff69
lens: usability
reviewer-role-id: UX-RESEARCHER
reviewer-run-id: d304420508e13d58140002ade85a20b5ba65f76807bcb3e1ffb58b53fc944d89
verdict: pass
- report-id: DES-VISUAL-20260718T140000Z
report-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-VISUAL-20260718T140000Z.report.yaml
report-sha256: cfce4f2f395dc6fabf785b381b1af3366c3335a206c0f5450e5972965a838948
lens: distinctiveness
reviewer-role-id: DES-VISUAL
reviewer-run-id: 5164a2f325b97d437c17cff56ba421620b35ad25d4bde2bf00fb63b896b5db1c
verdict: pass
- report-id: DES-VISUAL-20260718T140005Z
report-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-VISUAL-20260718T140005Z.report.yaml
report-sha256: 28bf4a9a8eb12766f2430d394ed2086111f9983433fbeb664f2a2462cce94688
lens: visual-craft
reviewer-role-id: DES-VISUAL
reviewer-run-id: f5394225114da0620b2ba325651b249910844e048a2c55f1da9e1f8b4406f012
verdict: revise
- report-id: DES-PLATFORM-20260718T140000Z
report-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-PLATFORM-20260718T140000Z.report.yaml
report-sha256: db8253d62a742f8af2c03160ed979d54854df333309f72d50bfb9444f08b28a8
lens: systematizability
reviewer-role-id: DES-PLATFORM
reviewer-run-id: 4a130950494abd2e560e3ab7b5a591b9ab6b501e61da3604373623d3e6baf5bd
verdict: pass
- report-id: GTM-PMM-20260718T140000Z
report-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/GTM-PMM-20260718T140000Z.report.yaml
report-sha256: bfeef8eda24fdc4741ec8c5ceea8e19bdf2af00748b6060436bdb3fe8c792179
lens: market-memorability
reviewer-role-id: GTM-PMM
reviewer-run-id: ea3b9ab06b3aa423358b9d2966daed0ad18331593eefea8836521e0eb712342b
verdict: pass
- report-id: ENG-FE-20260718T140000Z
report-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T140000Z.report.yaml
report-sha256: b02f9c89fb797411d16633b4112db2cbd91e783fbcfbcd90c21423cf079b2d61
lens: implementability
reviewer-role-id: ENG-FE
reviewer-run-id: 3f768a15887862e2de9227f5e84c43b61c4133909ae49b96f7dcb5d3aabd010a
verdict: revise
synthesis:
verdict: minor-revision
role-id: DES-DIRECTOR
unresolved-dissent: []
rule-application: >-
exact revision-3 winner에 7개 lens가 정확히 한 번씩 결속되고 blocking은 없다. product-fit,
usability, distinctiveness, systematizability, market-memorability는 pass지만 visual-craft와
implementability가 revise이므로 두 판정을 낮추지 않고 panel을 minor-revision으로 보존한다.
direction-decision: >-
Ledger Studio의 editorial evidence visual thesis, dual-entry shared core, 동일한 causal Lab,
Predict→Observe→Compare→Explain→Transfer, guided-scenario 경계는 유지한다. 발견사항은 작은 텍스트와
필수 조작 경계의 대비, 그리고 router와 충돌하는 skip-link를 교정하는 국소 수정이며 방향 재선택 사유가 아니다.
preserved-strengths:
- 두 입구가 같은 scenario와 reducer로 수렴하고 정직한 완료 경계를 지키는 product-fit은 유지한다.
- 360/768/1280 containment, 한국어 단어 무결성, keyboard flow와 native semantics는 유지한다.
- 비대칭 ledger composition과 100·120·70 회상 묶음은 distinctiveness와 market memorability 근거로 유지한다.
- scenario registry와 explicit activeScenario 결속은 확장 가능한 최소 구현 경계로 유지한다.
required-revisions:
- priority: P0
theme: small-text-and-control-contrast
source-lenses: [visual-craft]
scope: >-
deep surface용 별도 accent token을 추가해 lab-id와 boundary 강조 텍스트가 각 실제 배경에서 4.5:1 이상이 되게 한다.
pending trace text도 실제 배경에서 4.5:1 이상, choice와 textarea의 필수 control border는 sheet 배경에서
3:1 이상이 되게 하되 decorative rule token과 분리한다.
- priority: P0
theme: route-safe-skip-link
source-lenses: [implementability]
scope: >-
skip link를 router hash navigation으로 보내지 않고 현재 렌더된 main에 local focus와 scroll을 적용한다.
home, concept, symptom, 기본 Lab, fixture Lab과 진행 중 phase에서 hash, scenario, phase, cursor를 보존하며
360/768/1280 keyboard activation으로 검증한다.
exit-criteria:
- lab-id와 boundary emphasis의 computed foreground/background 대비가 각각 4.5:1 이상이다.
- pending trace text의 computed 대비가 4.5:1 이상이고 choice 및 textarea border 대비가 각각 3:1 이상이다.
- 모든 공개 route와 두 Lab scenario에서 skip link 활성화 후 activeElement가 현재 main이고 location hash가 바뀌지 않는다.
- 진행 중 기본·fixture Lab에서 skip link 활성화 전후 scenario id, phase, cursor가 정확히 보존된다.
- 360/768/1280에서 위 동작과 zero document overflow를 Chrome assertion으로 재검증한다.
- 수정본에 대해 7개 독립 lens를 새 context-package와 run-id로 모두 다시 실행하여 전부 pass한다.
report-header:
bottom-line: >-
MINOR-REVISION — revision 3는 제품 적합성·사용성·차별성·시스템화·시장성을 통과했지만,
작은 텍스트·필수 control 대비와 route-safe skip link를 고친 뒤 7-lens 전체 pass가 필요하다.
decision-needed: { needed: false, approver: null }
confidence:
value: Med
derived-from: exact-r3-and-seven-sha-bound-independent-review-originals
risks:
- 기존 accent와 rule token을 전역 교체하면 의도한 시각 위계까지 흔들 수 있으므로 surface/control 전용 token으로 국소화해야 한다.
- skip link가 hashchange를 거치면 화면만 이동하는 것이 아니라 route와 Lab 진행 상태까지 초기화할 수 있다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T135811Z.report.yaml
grade: E3
note: exact revision-3 winner SHA 735d588b…
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-VISUAL-20260718T140005Z.report.yaml
grade: E3
note: computed small-text and essential-control contrast findings
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T140000Z.report.yaml
grade: E3
note: live skip-link router/state reset finding
@@ -0,0 +1,110 @@
report-type: workflow-artifact
artifact-kind: design-review-panel
artifact-version: 1
identity:
artifact-id: DES-DIRECTOR-20260718T150500Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: DES-DIRECTOR
created-at: 20260718T150500Z
attempt-id: 7
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
target-prototype-id: ENG-FE-20260718T144700Z
target-prototype-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T144700Z.report.yaml
target-prototype-sha256: 8b208279e12f9aea0fa6d7a3c320811b0e72ddb74c6afac64cddadf4b157cf76
reviews:
- report-id: DES-PROD-20260718T145000Z
report-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-PROD-20260718T145000Z.report.yaml
report-sha256: c83628e9a033e06dd3f3f2c5bbc052f5f6da9540c8de08bdd720cebf02ce5350
lens: product-fit
reviewer-role-id: DES-PROD
reviewer-run-id: 0cf87e457984c59af5b263a50024f493fa9caaf0fcf630273503befaf4033dd4
verdict: pass
- report-id: UX-RESEARCHER-20260718T145000Z
report-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/UX-RESEARCHER-20260718T145000Z.report.yaml
report-sha256: 6e8fb3055431769c1f4055ad9890cf906df3a0343f81ccc0539d85d50d0d52e9
lens: usability
reviewer-role-id: UX-RESEARCHER
reviewer-run-id: e821d474bc30c9a4d4b16925e1d596cfd8901397bb9d24b59b30f17ac0bd826c
verdict: pass
- report-id: DES-VISUAL-20260718T145000Z
report-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-VISUAL-20260718T145000Z.report.yaml
report-sha256: 5ba2fd228e1c7107dcaf2fcf8fc615adce137e7646efca302649a59de63e29aa
lens: distinctiveness
reviewer-role-id: DES-VISUAL
reviewer-run-id: aaa1e28340e08054588d1e93f3774136fe9ffe6f350b48afb3d060229f98447a
verdict: pass
- report-id: DES-VISUAL-20260718T145005Z
report-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-VISUAL-20260718T145005Z.report.yaml
report-sha256: a08a33d02a3821bc4fd5edf0a015793570f24c2adbe583cf8a9bcccc9a04d0ee
lens: visual-craft
reviewer-role-id: DES-VISUAL
reviewer-run-id: b81c982521b4fbc7e8acf73d84502d1dd84b4d081cfa5be74863decbb0d6ae61
verdict: pass
- report-id: DES-PLATFORM-20260718T145000Z
report-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-PLATFORM-20260718T145000Z.report.yaml
report-sha256: 11e1af20b2447d6143ef47b3da1916a5ffb038d43dcb5c9a4b1606fe05abceee
lens: systematizability
reviewer-role-id: DES-PLATFORM
reviewer-run-id: a21e644695cb706bb53b50622673bf1ac856552145a4bbb5948072a918d32da6
verdict: pass
- report-id: GTM-PMM-20260718T145000Z
report-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/GTM-PMM-20260718T145000Z.report.yaml
report-sha256: 53ce596ce8c15fb322286ab79c44d93ba54931742db5fec1e3032f36ca0e8657
lens: market-memorability
reviewer-role-id: GTM-PMM
reviewer-run-id: 82488e67545d8401fa217e7e28fc1f600dcbb378af719354f74a58a530c55388
verdict: pass
- report-id: ENG-FE-20260718T145000Z
report-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T145000Z.report.yaml
report-sha256: f84a3fdc5803b6ba8a9ecc4586e3c13307addff66492e7c342dda920f3d0d6c6
lens: implementability
reviewer-role-id: ENG-FE
reviewer-run-id: cfcfc3f64722c9f7ec5712bab3b38faa00026ef4e146f3f52829d37d410ac2ac
verdict: pass
synthesis:
verdict: pass
role-id: DES-DIRECTOR
unresolved-dissent: []
rule-application: >-
exact revision-4 winner에 필수 7개 lens가 고유한 reviewer run과 immutable SHA로 정확히 한 번씩
결속됐고 일곱 verdict가 모두 pass다. 따라서 개별 판정을 낮추거나 덮어쓰지 않고 panel을 pass로 확정한다.
direction-decision: >-
Ledger Studio의 editorial evidence thesis, dual-entry shared core, 동일 causal Lab,
Predict→Observe→Compare→Explain→Transfer 학습 루프와 guided-scenario 경계를 최종 방향으로 승인한다.
resolved-revisions:
- deep surface 작은 텍스트와 pending trace가 4.5:1 이상, 필수 control border가 3:1 이상으로 보정됐다.
- skip link가 hash router를 우회해 모든 공개 route와 진행 중 Lab에서 현재 main에 focus하면서 상태를 보존한다.
- 360/768/1280과 기본·fixture scenario를 포함한 독립 Chrome 재실행이 통과했다.
preserved-strengths:
- 개념 입구와 증상 디버거 입구가 같은 reducer와 인과 증거로 수렴한다.
- 100·120·70의 evidence sequence와 비대칭 ledger composition이 기억 단서를 만든다.
- 실제 로그·원격 DB·AI 진단을 가장하지 않고 guided simulation 경계를 명시한다.
- 한국어 단어 무결성, keyboard flow, responsive containment와 native semantics를 유지한다.
advisory:
- 세 번째 공개 주제를 추가할 때 scenario registry와 단일 app.js의 파일·schema 분리를 재검토한다.
exit-criteria:
- exact winner 및 7개 review SHA 결속 검증 통과
- 모든 lens pass와 unresolved dissent 없음
- 대비·skip-link·상태 보존의 브라우저 regression 통과
report-header:
bottom-line: >-
PASS — revision 4는 대비와 route-safe skip-link를 교정했고, exact winner에 결속된 7개 독립 lens가
실제 렌더·브라우저 재실행 근거로 모두 통과했다.
decision-needed: {needed: false, approver: null}
confidence:
value: High
derived-from: exact-r4-winner-seven-immutable-independent-pass-reviews
risks:
- 세 번째 주제 도입 시점에는 현재의 단일-file registry가 편집 병목이 될 수 있다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T144700Z.report.yaml
grade: E3
note: exact revision-4 winner and bound browser/CSS/preview receipts
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-VISUAL-20260718T145005Z.report.yaml
grade: E3
note: independent computed contrast and responsive visual-craft pass
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T145000Z.report.yaml
grade: E3
note: isolated-copy browser and source-integrity implementability pass
@@ -0,0 +1,79 @@
report-type: workflow-artifact
artifact-kind: approved-direction
artifact-version: 1
identity:
artifact-id: DES-DIRECTOR-20260718T151000Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-finalize
producer-role-id: DES-DIRECTOR
created-at: 20260718T151000Z
attempt-id: 1
payload:
parent-workflow-id: hyeonworks-vnext-v1
child-workflow-id: hyeonworks-vnext-v1-direction
product-decision-id: EXEC-CEO-20260718T111108Z
direction-input-brief-sha256: 975a7713b1837576173aee1d9a349bb68afd652ed9d1166fd9d5efc39059d9b4
selected-direction-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-DIRECTOR-20260718T115933Z.report.yaml
selected-direction-sha256: 90b64c99493f1789a134459813207291dfa4beafa794e3f861b4f28d23286a65
winner-prototype-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T144700Z.report.yaml
winner-prototype-sha256: 8b208279e12f9aea0fa6d7a3c320811b0e72ddb74c6afac64cddadf4b157cf76
visual-thesis: >-
Ledger Studio는 전문 기술 저널의 질문, causal ledger의 수치 증거, 비대칭 editorial spread를
하나의 읽기 위계로 묶는다. 일반 SaaS dashboard나 terminal을 흉내 내지 않고, 예측과 관찰의
불일치를 종이에 표시하듯 드러내 사용자가 메커니즘을 스스로 설명하게 한다.
interaction-model:
entries:
concept: 개념을 알고 있는 사용자가 격리 수준의 약속에서 시작한다.
symptom-debugger: 결과가 120이 아니라 70이 된 증상에서 후보 메커니즘을 좁힌다.
shared-core:
scenario-id: tx-lost-update-01
reducer: 두 입구가 같은 시나리오·상태·증거 순서로 합류한다.
learning-loop: [Predict, Observe, Compare, Explain, Transfer]
evidence-sequence: [100, 120, 150, 70]
state-contract:
- 각 단계는 앞 단계 완료 후에만 열린다.
- 관찰 trace와 사용자의 예측·설명은 색뿐 아니라 텍스트와 형태로 구분한다.
- skip link는 route hash와 진행 상태를 변경하지 않고 현재 main으로 이동한다.
honest-boundary: 고정 guided simulation이며 실제 로그 분석·원격 DB 연결·AI 장애 진단을 주장하지 않는다.
design-token-contract:
typography:
thesis: Korean-capable serif editorial heading
evidence: monospace numeric and causal annotations
body: readable Korean sans-serif system stack
color:
paper: '#f3efe4'
ink: '#1b201e'
deep: '#202724'
coral-observed: '#ad4031'
accent-on-deep: '#ff8873'
pending-on-deep: '#535c58'
control-border: '#88877e'
contrast-floor:
normal-text: '4.5:1'
essential-control-boundary: '3:1'
layout:
desktop: asymmetric editorial spread with causal ledger
mobile: single-column DOM reading order preserved at 360px
verified-viewports: [360, 768, 1280]
invariant-ids: [LI-EDITORIAL-EVIDENCE, LI-DUAL-ENTRY-SHARED-CORE, LI-EVIDENCE-LEARNING-LOOP, LI-HONEST-BOUNDARY, LI-ACCESSIBLE-READING]
acceptance-receipt-ref: exact-review-artifact:DES-DIRECTOR-20260718T151000Z:EXEC-CPO
approval-basis:
panel-id: DES-DIRECTOR-20260718T150500Z
panel-sha256: 0f5ae0e571d35c44392e18d1d07430167b950d94ad59973819458768867dad16
verdict: pass
report-header:
bottom-line: >-
Ledger Studio 방향과 revision-4 prototype을 최종 승인한다. 개념·증상 디버거의 두 입구는 동일한
Lost Update 인과 Lab으로 합류하며, 다섯 단계 학습 루프와 정직한 guided-simulation 경계를 고정한다.
decision-needed: {needed: false, approver: null}
confidence: {value: High, derived-from: selected-direction-exact-r4-and-seven-lens-pass-panel}
risks:
- 세 번째 공개 주제를 추가할 때 scenario schema와 콘텐츠 파일 분리를 다시 검토해야 한다.
- 실제 사용자 학습효과는 제품 분석 전까지 자동 검증 결과로 대신 주장하지 않는다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-DIRECTOR-20260718T150500Z.report.yaml
grade: E3
note: exact seven-lens pass synthesis
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
grade: E3
note: revision-4 manifest and bound verification receipts
@@ -0,0 +1,64 @@
report-type: workflow-artifact
artifact-kind: approved-direction
artifact-version: 1
identity:
artifact-id: DES-DIRECTOR-20260718T151100Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-finalize
producer-role-id: DES-DIRECTOR
created-at: 20260718T151100Z
attempt-id: 2
supersedes-report-id: DES-DIRECTOR-20260718T151000Z
payload:
parent-workflow-id: hyeonworks-vnext-v1
child-workflow-id: hyeonworks-vnext-v1-direction
product-decision-id: EXEC-CEO-20260718T111108Z
direction-input-brief-sha256: 975a7713b1837576173aee1d9a349bb68afd652ed9d1166fd9d5efc39059d9b4
selected-direction-ref: completion-records/hyeonworks-vnext-v1-direction/DES-DIRECTOR-20260718T115933Z.report.yaml
selected-direction-sha256: 90b64c99493f1789a134459813207291dfa4beafa794e3f861b4f28d23286a65
winner-prototype-ref: completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T144700Z.report.yaml
winner-prototype-sha256: 8b208279e12f9aea0fa6d7a3c320811b0e72ddb74c6afac64cddadf4b157cf76
visual-thesis: >-
Ledger Studio는 전문 기술 저널의 질문, causal ledger의 수치 증거, 비대칭 editorial spread를
하나의 읽기 위계로 묶는다. dashboard나 terminal을 흉내 내지 않고 예측과 관찰의 불일치를
종이에 표시하듯 드러내 사용자가 메커니즘을 스스로 설명하게 한다.
interaction-model:
entries:
concept: 격리 수준의 약속에서 시작한다.
symptom-debugger: 결과 70이라는 증상에서 후보 메커니즘을 좁힌다.
shared-core: {scenario-id: tx-lost-update-01, reducer: 두 입구가 같은 상태와 증거 순서로 합류한다.}
learning-loop: [Predict, Observe, Compare, Explain, Transfer]
evidence-sequence: [100, 120, 150, 70]
state-contract:
- 각 단계는 앞 단계 완료 후에만 열린다.
- 상태는 색뿐 아니라 텍스트와 형태로 구분한다.
- skip link는 route와 진행 상태를 바꾸지 않고 현재 main으로 이동한다.
honest-boundary: 고정 guided simulation이며 실제 로그·원격 DB·AI 장애 진단을 주장하지 않는다.
design-token-contract:
typography: {thesis: Korean-capable serif, evidence: monospace numeric annotation, body: Korean sans-serif system stack}
color: {paper: '#f3efe4', ink: '#1b201e', deep: '#202724', coral-observed: '#ad4031', accent-on-deep: '#ff8873', pending-on-deep: '#535c58', control-border: '#88877e'}
contrast-floor: {normal-text: '4.5:1', essential-control-boundary: '3:1'}
layout: {desktop: asymmetric editorial spread, mobile: single-column DOM order at 360px, verified-viewports: [360, 768, 1280]}
invariant-ids: [LI-EDITORIAL-EVIDENCE, LI-DUAL-ENTRY-SHARED-CORE, LI-EVIDENCE-LEARNING-LOOP, LI-HONEST-BOUNDARY, LI-ACCESSIBLE-READING]
acceptance-receipt-ref: exact-review-artifact:DES-DIRECTOR-20260718T151100Z:EXEC-CPO
approval-basis:
panel-id: DES-DIRECTOR-20260718T150500Z
panel-sha256: 0f5ae0e571d35c44392e18d1d07430167b950d94ad59973819458768867dad16
verdict: pass
revision-note: approved-direction 전용 resolver에 맞춰 selected/winner 참조를 hyeonworks 워크스페이스 상대경로로 정규화했다.
report-header:
bottom-line: >-
Ledger Studio revision 4를 최종 승인한다. 두 입구는 동일 Lost Update Lab으로 합류하며,
Predict→Observe→Compare→Explain→Transfer와 정직한 guided-simulation 경계를 고정한다.
decision-needed: {needed: false, approver: null}
confidence: {value: High, derived-from: exact-r4-seven-lens-pass-and-normalized-immutable-refs}
risks:
- 세 번째 공개 주제 도입 시 scenario schema와 콘텐츠 파일 분리를 재검토한다.
- 실제 사용자 학습효과는 별도 제품 분석 전까지 주장하지 않는다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-DIRECTOR-20260718T150500Z.report.yaml
grade: E3
note: exact seven-lens pass synthesis
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
grade: E3
note: revision-4 manifest and bound verification receipts
@@ -0,0 +1,90 @@
report-type: workflow-artifact
artifact-kind: design-lens-review
artifact-version: 1
identity:
artifact-id: DES-PLATFORM-20260718T121851Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: DES-PLATFORM
created-at: 20260718T121851Z
attempt-id: 1
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
target-prototype-id: ENG-FE-20260718T120840Z
target-prototype-sha256: 1cfa4ff43762111f46b0088057f6b902375f86856558056aa5f11f117f107267
reviewer-role-id: DES-PLATFORM
reviewer-run-id: cac14c7f6f176f94508730de72c5558f89165715d287f89229474ac6cc12eccd
lens: systematizability
verdict: revise
findings:
- finding-id: SYS-01
severity: major
area: "dist/app.js — scenario/state/router와 phase render 경계"
finding: >-
단일 scenario 객체와 pure reducer는 좋은 출발점이지만 다음 주제를 데이터만 바꿔 재사용할 수 있는
시스템은 아직 아니다. route는 어떤 #/lab/* 값도 동일 Lab으로 보내고, phase/action 집합은 Lost
Update에 고정되어 있다. 또한 100·120·70과 transfer 값, 선택지, 설명 문구가 scenario 객체와
renderHome·previewFolio·labBrief·compareView·transferView에 중복되어 있어 새 주제를 추가하면 상태,
라우팅, 템플릿, 콘텐츠를 함께 복제·수정해야 한다.
evidence: >-
app.js:1-72의 scenario/learningReducer, 78-88의 route, 103-178의 화면 함수가 동일 사실을 서로 다른
위치에 보유한다. scenario.transfer도 선언되어 있으나 transferView는 30·36·40과 정답을 다시
하드코딩한다.
required-revision: >-
다음 활성 주제를 만들기 전에 topic/scenario schema와 id 기반 registry를 정의하고, 공통 학습-loop
engine이 phase 콘텐츠·선택지·trace·비교값을 그 계약에서 읽도록 분리한다. orientation별 로컬 상태도
동일한 명시적 state 경계 안에 둔다.
- finding-id: SYS-02
severity: major
area: "dist/styles.css — token foundation과 반복 composite"
finding: >-
:root에는 역할 기반 색상과 최대 폭이 마련되어 있지만 spacing, type scale, line-height, stroke,
elevation, layout breakpoint는 대부분 raw literal이다. folio/note-ledger, 여러 mono label,
relations/clues/cause-row, loop-strip/progress가 같은 편집·ledger 문법을 별도 선언으로 반복하므로
후속 주제에서 조정이 분기될 가능성이 높다.
evidence: >-
styles.css:1-47에서 semantic color token은 일관되게 소비되지만 동일한 border, shadow, mono label,
row grid, 간격 값과 850px/480px breakpoint가 개별 selector에 결합되어 있다.
required-revision: >-
잠긴 editorial-evidence 인상은 유지하면서 spacing/type/stroke/elevation/breakpoint 토큰과
ledger-row, evidence-label, sheet, progress, value-comparison의 공통 recipe를 명명해 한 곳에서
변형 가능하게 만든다.
- finding-id: SYS-03
severity: strength
area: "core-flow.yaml, dist/app.js, dist/styles.css, 360/768/1280 previews"
finding: >-
재구성의 기반은 충분하다. paper/ink/muted/coral/focus 등 의미 기반 색상, 명시적 action guard를 가진
결정론적 reducer, 공통 values/button/boundary/comparison 패턴, 두 breakpoint의 단일-column 전환이
존재하며 세 preview에서 동일한 editorial/ledger 문법이 유지된다.
evidence: >-
core-flow.yaml의 deterministic-boundary와 파일 hash, app.js:1-69의 state transition,
styles.css:1-47의 semantic tokens/responsive rules, SHA가 결속된 360/768/1280 실제 렌더를 대조했다.
implication: >-
결함은 방향의 개념적 재선택이 아니라 데이터·상태·토큰 경계의 추출로 해결 가능하므로 blocking이
아닌 revise가 적절하다.
report-header:
bottom-line: >-
REVISE — Ledger Studio는 semantic color와 결정론적 학습 reducer라는 재사용 기반을 갖췄지만,
단일 Lost Update의 값·phase·콘텐츠·layout recipe가 코드에 결합되어 다음 주제를 일관되게 추가하기
전에 scenario registry와 공통 token/component 경계를 추출해야 한다.
decision-needed: { needed: false, approver: null }
confidence: { value: Med, derived-from: exact-winner-hash-source-and-three-viewport-render-inspection }
risks:
- "현재 구조로 MVCC·Deadlock·Cache stampede를 추가하면 route/reducer/render 복제와 콘텐츠 값 drift가 생길 수 있다."
- "색상 외 foundation token과 ledger composite가 추출되지 않으면 후속 화면의 type·spacing·border 규칙이 분기될 수 있다."
evidence:
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/app.js
grade: E3
note: "SHA 75f55418… source inspection: scenario, reducer, router, 모든 phase render의 재사용 경계 대조"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/styles.css
grade: E3
note: "SHA 93f14936… source inspection: semantic color token과 반복되는 raw foundation/composite 규칙 대조"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w360.png
grade: E3
note: "360px 실제 렌더에서 동일 editorial/ledger 패턴과 responsive collapse 확인"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w768.png
grade: E3
note: "768px 실제 렌더에서 동일 pattern hierarchy 확인"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w1280.png
grade: E3
note: "1280px 실제 렌더에서 shared sheet/value/entry/loop 문법 확인"
@@ -0,0 +1,149 @@
report-type: workflow-artifact
artifact-kind: design-lens-review
artifact-version: 1
identity:
artifact-id: DES-PLATFORM-20260718T131443Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: DES-PLATFORM
created-at: 20260718T131443Z
attempt-id: 2
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
target-prototype-id: ENG-FE-20260718T131305Z
target-prototype-sha256: bcc557fcd7463349345bd06090868c4c2b6b792453d4e1dddd4ac60b0fa68674
target-prototype-manifest-ref: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
target-prototype-manifest-sha256: 40876a12d2ab842568a76b3c2e2e50f6cd32614914805ecf3c6a00745266958c
reviewer-role-id: DES-PLATFORM
reviewer-run-id: 2336d0c343a10e89d7b2b419a9803c49a182646f7716ebf8dda1170857f0dc68
lens: systematizability
verdict: revise
system-assessment:
- boundary: deterministic-learning-reducer
verdict: pass
rationale: >-
learningReducer는 scenarioId로 registry를 조회하고 고정 action/phase 전이만 수행해 현재 5단계
학습 루프를 불필요한 runtime이나 범용 플랫폼 없이 재사용할 수 있다.
- boundary: scenario-registry-to-render-binding
verdict: revise
rationale: >-
route와 reducer는 id를 받지만 render, announcement, orientation은 module-level 기본 scenario를
사용하므로 registry에 다음 시나리오를 추가하는 것만으로는 해당 콘텐츠와 상태가 결속되지 않는다.
- boundary: foundation-tokens
verdict: pass
rationale: >-
paper/ink/state color, spacing, stroke, shadow, max-width와 evidence label 크기가 root token으로
모여 있고 360/768/1280 및 단계별 렌더에서 같은 기반을 유지한다.
- boundary: editorial-recipes
verdict: pass
rationale: >-
sheet, ledger-row, values, comparison, progress, choice, boundary가 반복 recipe로 실제 화면 전반에
재사용되며 다음 주제를 위해 별도 범용 컴포넌트 플랫폼을 먼저 만들 필요가 없다.
- boundary: abstraction-level
verdict: pass
rationale: >-
단일 registry와 순수 reducer라는 현재 추상화 수준은 적절하다. 수정은 active scenario 결속과
최소 콘텐츠 계약 완성에 한정할 수 있다.
findings:
- finding-id: SYS-R2-01
severity: High
blocking: false
area: scenario registry / active scenario resolution
summary: >-
registry와 reducer 사이에는 확장 seam이 생겼지만 render 계층이 default scenario에 고정되어
다음 scenario id를 실제 화면으로 끝까지 전달하지 못한다.
evidence:
- >-
dist/app.js:78-79는 scenario를 scenarioRegistry[defaultScenarioId]로 한 번 고정한다.
- >-
dist/app.js:155-161과 268-273은 registry의 다른 lab id를 인식하고 labState를 교체하지만,
dist/app.js:168-260의 atlas/home/orientation/phase render와 287-308의 announcement/orientation은
계속 기본 scenario를 읽는다.
- >-
dist/app.js:109-144의 reducer만 state.scenarioId의 active registry record를 사용한다. 따라서
다음 scenario의 state transition과 기본 Lost Update 화면이 서로 다른 record를 참조한다.
- >-
core-flow.yaml:46의 "registry-driven values/copy/choices" closure 주장과 실제 source가 일치하지 않는다.
impact: >-
다음 주제를 registry에 등록해 #/lab/<next-id>로 진입하면 data-scenario-id, atlas, 값, 선택지,
schedule 표와 피드백은 Lost Update를 표시하면서 reducer는 새 record로 전이한다. schedule 길이가
다르면 화면 cursor와 announcement가 어긋날 수도 있어 한 주제 추가가 안전한 데이터 작업이 아니다.
required-revision: >-
route/labState의 scenarioId에서 activeScenario를 한 번 해석해 모든 render helper, dispatch,
announcement에 명시적으로 전달한다. orientation state도 시나리오를 노출하는 경우 id별로 결속한다.
phase/reducer 계약은 유지하고 범용 plugin/runtime은 추가하지 않는다.
acceptance: >-
두 번째 최소 fixture id로 직접 lab route에 진입했을 때 id, atlas, values, schedule, hypotheses,
explanation, transfer와 announcement가 모두 그 fixture에서 나오고 기본 Lost Update flow가 그대로
통과하는 hash-bound browser test receipt를 남긴다.
- finding-id: SYS-R2-02
severity: Medium
blocking: false
area: scenario content contract / editorial templates
summary: >-
registry에 주요 값과 choices는 모였지만 shared templates 안에 Lost Update 전용 숫자·명칭·인과 문장이
남아 있어 다음 주제는 registry edit만으로 완성되지 않는다.
evidence:
- >-
dist/app.js:164-199는 Field note, Transaction Isolation/Lost Update, concept orientation과 홈 범위를
template literal에 직접 쓴다.
- >-
dist/app.js:224-248은 WRITE A=150, Delta +50, 설명 feedback, 재고 transfer feedback과 completion
principles를 직접 쓴다. registry 값으로 렌더하는 인접 영역과 경계가 섞여 있다.
- >-
preview.w360.png, preview.w768.png, preview.w1280.png와 state-previews는 sheet/ledger/value/progress
recipe의 시각 일관성은 증명하지만 모두 tx-lost-update-01 한 record뿐이라 콘텐츠 계약 확장을 증명하지 않는다.
impact: >-
다음 주제 추가 시 공통 view 함수를 여러 곳 수정해야 하며, 일부 숫자나 피드백만 기존 주제에서 남는
partial migration 위험이 있다.
required-revision: >-
실제 두 번째 fixture가 요구하는 최소 범위에서 header/atlas/orientation/compare evidence/feedback/
completion copy를 scenario record 또는 값에서 파생되는 formatter로 옮긴다. 모든 주제를 포괄하는
범용 schema를 선설계하지 않는다.
acceptance: >-
shared template의 Lost Update 전용 literal이 default record 밖에 남지 않고, 두 fixture의 phase별
snapshot 또는 DOM assertion이 서로 다른 copy/value를 검증한다.
receipt-bindings:
preview:
receipt-id: vr-1784380367-51a78e23c06f
receipt-sha256: 6e996418f85040bcf48a9354ad7488d9106e8b094a5f7ce8672a3aa30376b776
source-revision-sha256: 40876a12d2ab842568a76b3c2e2e50f6cd32614914805ecf3c6a00745266958c
assertion-status: passed
interaction:
receipt-id: vr-1784380160-b25beb2fef58
receipt-sha256: b5dae4455e6a73ee5801fedc3034bf0b23628bb5e59c1e47576b7ba32d5285fa
source-revision-sha256: 40876a12d2ab842568a76b3c2e2e50f6cd32614914805ecf3c6a00745266958c
assertion-status: passed
report-header:
bottom-line: >-
revise — exact winner ENG-FE-20260718T131305Z / bcc557fcd7463349345bd06090868c4c2b6b792453d4e1dddd4ac60b0fa68674의
reducer와 token/editorial recipe는 적정 수준이지만 default scenario에 고정된 render·copy 경계 때문에
registry만으로 다음 주제를 안전하게 추가할 수 없다.
decision-needed: { needed: false, approver: null }
confidence: { value: Med, derived-from: exact-hash-bound-source-manifest-renders-and-receipts }
risks:
- >-
실제 두 번째 scenario fixture가 없으므로 실패의 정확한 런타임 모양은 source-level 경로 분석이며,
다음 주제의 콘텐츠 구조에 따라 필요한 최소 record 필드는 달라질 수 있다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T131305Z.report.yaml
grade: E3
note: "winner id/SHA, manifest, preview·interaction receipt와 render refs의 정본"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
grade: E3
note: "sha256 40876a12...; source/render hash manifest와 systematizability closure 주장"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/app.js
grade: E3
note: "sha256 bbc82f68...; registry/reducer/render/announcement의 실제 active-scenario 경계"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/styles.css
grade: E3
note: "sha256 62fd9ea7...; root tokens와 shared editorial recipes"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w1280.png
grade: E3
note: "sha256 315eaa89...; sheet/ledger/value/progress recipe의 wide render"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews/transfer.w360.png
grade: E3
note: "mobile phase render에서 동일 recipe의 재사용 확인"
- source-uri: hyeonworks/evidence/ledger.jsonl
grade: E3
note: "preview vr-1784380367-51a78e23c06f와 interaction vr-1784380160-b25beb2fef58의 passed hash-bound receipts"
@@ -0,0 +1,129 @@
report-header:
bottom-line: >-
PASS — exact revision-3 target ENG-FE-20260718T135811Z에서 default 6-step record와
direct-route-only 4-step inventory fixture의 id·atlas·copy·value·schedule·hypothesis·
explanation answer·transfer·feedback·announcement가 하나의 active scenario를 통해
shared reducer/view에 끝까지 결속된다. 고정 5-phase 학습 계약만 공유하고 콘텐츠 차이는
두 registry record에 남긴 현재 추상화는 이 정적 prototype 범위에 비례하며 과하지 않다.
decision-needed: {needed: false, approver: null}
confidence:
value: Med
derived-from: exact-hash-must-read-source-inspection-plus-isolated-local-chrome-replay
risks:
- >-
scenario record shape는 정적 코드의 암묵 계약이다. 세 번째 record가 phase 수, actor 수,
explanation part 키를 바꾸는 시점에는 별도 schema validation이나 contract 확장이 필요하지만,
현재 두 bounded record의 통과를 막는 결함은 아니다.
- >-
inventory fixture는 registry 결속을 검증하는 direct-route-only test record다. 공개 콘텐츠의
확장성이나 실제 사용자 학습효과까지 입증하지 않는다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T135811Z.report.yaml
grade: E3
note: >-
sha256 735d588bef412dd3c59899d393562ae76a67a55bbe9f507ddf38eeab1481e9f0;
exact target identity와 revision 3, browser receipt refs를 확인했다.
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/app.js
grade: E3
note: >-
sha256 4bd59d70b8470263a84c3605db8f61bc88d86eef297dd0643f57365f300ace1b;
registry, scenarioId state, reducer, explicit render arguments, correctness lookup,
dispatch announcement binding을 직접 검사했다.
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/scripts/verify_flow.cjs
command: node scripts/verify_flow.cjs
exit-code: 0
grade: E3
note: >-
prototype 임시 복제본에서 Chrome flow를 재실행해 default full loop와 별도 4-step fixture의
row count, 50/60/40 values, fixture-only ids/copy/answers, feedback, live announcement와 reset을 통과했다.
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.state-fixture.png
grade: E3
note: >-
sha256 918b375e1bb8f4fb1b50e6f4eaa3d24b23609a9d004236d172f100c25312aa94;
fixture id·Inventory atlas·50/60/50 predict state·fixture copy가 한 화면에서 일치한다.
report-type: workflow-artifact
artifact-kind: design-lens-review
artifact-version: 1
identity:
artifact-id: DES-PLATFORM-20260718T140000Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: DES-PLATFORM
created-at: 20260718T140000Z
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
target-prototype-id: ENG-FE-20260718T135811Z
target-prototype-sha256: 735d588bef412dd3c59899d393562ae76a67a55bbe9f507ddf38eeab1481e9f0
reviewer-role-id: DES-PLATFORM
reviewer-run-id: 4a130950494abd2e560e3ab7b5a591b9ab6b501e61da3604373623d3e6baf5bd
lens: systematizability
verdict: pass
findings: []
review-basis:
context-package-ref: hyeonworks/state/context-packages/hyeonworks-vnext-v1-direction/DES-PLATFORM-20260718T135944Z.pkg.yaml
context-package-sha256: 4a130950494abd2e560e3ab7b5a591b9ab6b501e61da3604373623d3e6baf5bd
independence: >-
지정 context package와 그 must-read만 판단 근거로 사용했으며 다른 lens review는 열람하거나
재사용하지 않았다.
binding-assessment:
- area: id-atlas-copy
result: pass
source-observation: >-
route가 유효 registry id를 labState.scenarioId로 초기화하고 renderLab/header/atlas/labBrief에
같은 scenario argument를 전달한다. 두 record의 atlas와 copy는 record 내부에 분리돼 있다.
browser-observation: >-
default는 tx-lost-update-01·Lost Update 문장·100/120/100을, fixture는
tx-lost-update-inventory-fixture·Inventory fixture 문장·50/60/50을 렌더했다.
- area: values-schedule-hypothesis
result: pass
source-observation: >-
initialLabState는 active record initial을 사용하고 ADVANCE_TRACE는 active.schedule 길이와
WRITE value를 사용한다. Predict choices와 Compare의 선택 label도 active.hypotheses에서 나온다.
browser-observation: >-
default 6 rows와 fixture 4 rows가 각각 끝까지 진행됐고 fixture에서는 fixture-shared-50,
A=70 다음 B=40, 기대 60/관찰 40만 나타나며 default A=150 증거가 섞이지 않았다.
- area: explanation-answer-transfer
result: pass
source-observation: >-
explanationField/transferView는 active record choices를 렌더하고 explanationCorrect와
transferCorrect는 state.scenarioId의 answer를 조회한다.
browser-observation: >-
default same-100/b-70/a-plus-50 및 lost-reservation과 fixture
same-50/b-40/a-plus-20 및 lost-use가 각각 해당 성공 feedback을 열고 complete로 전이했다.
- area: feedback-announcement
result: pass
source-observation: >-
dispatch는 reducer 전이 뒤 currentScenario를 다시 구하고 schedule event 및 active copy의
explain/transfer feedback으로 announcer를 갱신한다. 선택 변경은 submitted feedback을 reset한다.
browser-observation: >-
fixture 첫 advance는 실행 1/4와 A가 재고 50을 발화했고, fixture explanation/transfer 성공
문구가 status feedback과 announcer 양쪽에 나타났다. default 오류→수정 성공 flow도 통과했다.
- area: route-reset-isolation
result: pass
source-observation: >-
scenario route 변경 시 state를 해당 id로 재초기화하고 RESET은 현 scenarioId를 보존한다.
browser-observation: >-
fixture complete 뒤 reset이 Current 50과 fixture data-scenario-id를 유지했다.
abstraction-assessment:
verdict: proportionate-not-excessive
rationale: >-
두 frozen data records, 하나의 reducer, 하나의 phase별 view 집합이라는 최소 분리다. 별도
plugin/runtime/schema engine이나 범용 component hierarchy를 도입하지 않았고, 공통인 학습 loop만
공유했다. CSS도 spacing·color·stroke·type tokens와 sheet/value/progress/ledger recipes까지만 재사용한다.
deliberately-fixed-contract:
- Predict → Observe → Compare → Explain → Transfer의 5 phases
- A/B 두 actor와 세 explanation parts
- 공개 home/orientation은 default scenario, fixture는 direct-route-only
expansion-trigger: >-
향후 콘텐츠가 다른 phase 구조, actor cardinality 또는 explanation key set을 요구할 때만
record schema와 renderer contract를 확장한다.
browser-replay:
isolation: prototype 전체를 /tmp의 임시 디렉터리로 복제해 screenshot write가 원본에 닿지 않게 실행
command: node scripts/verify_flow.cjs
result: pass
output: >-
PASS prototype E2E: dual-entry, contained Observe, entry focus, Korean type,
scenario binding, causal loop, semantics and contrast
prototype-modified: false
residual-dissent: []
@@ -0,0 +1,89 @@
report-type: workflow-artifact
artifact-kind: design-lens-review
artifact-version: 1
tier: standard
identity:
artifact-id: DES-PLATFORM-20260718T145000Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: DES-PLATFORM
created-at: 20260718T145000Z
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
target-prototype-id: ENG-FE-20260718T144700Z
target-prototype-sha256: 8b208279e12f9aea0fa6d7a3c320811b0e72ddb74c6afac64cddadf4b157cf76
reviewer-role-id: DES-PLATFORM
reviewer-run-id: a21e644695cb706bb53b50622673bf1ac856552145a4bbb5948072a918d32da6
lens: systematizability
verdict: pass
findings:
- finding-id: SYS-R4-P01
severity: pass
area: bounded-repeatability
observation: >-
scenarioRegistry가 값·문구·선택지 ID·정답·전이 사례·실행 schedule을 record 단위로 묶고,
route에서 고른 scenarioId를 state와 명시적 render/dispatch 인자로 전달한다.
evidence:
- "기본 시나리오는 initial 100과 6단계 schedule, fixture는 initial 50과 4단계 schedule을 사용한다."
- "verify_flow.cjs는 두 시나리오의 Predict부터 Complete와 Reset까지 각 record의 값·문구·정답이 유지되는지 검사한다."
assessment: >-
공통 reducer와 view recipe를 재사용하면서 두 번째 record의 다른 schedule 길이와 답 집합까지
독립적으로 결속하므로, 단순 복제보다 반복 가능하고 현재 두-scenario 증거 범위 안에서 충분하다.
required-revision: null
- finding-id: SYS-R4-P02
severity: pass
area: token-and-recipe-reuse
observation: >-
색상·간격·stroke·shadow·label 크기는 CSS custom properties로 제한하고 sheet, values,
ledger row, progress, choice, boundary 같은 화면 recipe를 두 경로와 두 시나리오가 공유한다.
evidence:
- "styles.css의 root token은 시각 기반과 R4 contrast 경계를 분리하며 같은 selector recipe가 모든 Lab phase에 적용된다."
- "app.js는 phase별 view만 두고 별도 component framework나 범용 theme engine을 만들지 않는다."
assessment: >-
변경점이 token 또는 좁은 recipe에 모이지만 제품 전체 design system이나 추상 component 계층을
선행 구축하지 않아, 디자인 방향 prototype에 맞는 최소 시스템 경계다.
required-revision: null
- finding-id: SYS-R4-A01
severity: advisory
area: expansion-threshold
observation: >-
scenario record의 필수 필드는 런타임 schema가 아니라 현재 두 record의 구조로 암묵적으로 정의되고,
registry·reducer·render 함수는 하나의 app.js에 함께 있다.
evidence:
- "initialLabState와 여러 view가 scenario.copy 및 answer 필드의 존재를 직접 전제한다."
- "현재 제품 범위는 하나의 활성 딥다이브와 direct-route-only 결속 fixture로 명시돼 있다."
assessment: >-
현재 범위에서는 오히려 검증 schema, plugin loader, backend, generic content runtime을 추가하는 편이
과설계다. 세 번째 공개 주제 또는 Lost Update와 다른 학습 구조를 넣을 때 누락 필드나 반복 수정이
실제로 나타나면 그때 schema 검증과 파일 분리를 도입하는 것이 적절하다.
trigger-for-revisit: "세 번째 production scenario, 다른 phase 구조, 또는 동일 변경의 2회 이상 중복 수정"
required-revision: null
report-header:
bottom-line: >-
PASS — R4는 registry + shared reducer/view + 제한된 CSS token/recipe로 두 시나리오의 반복 가능성을
증명했고, 범용 runtime·backend·framework를 선행하지 않아 현재 단일 활성 딥다이브 범위에 비례한다.
decision-needed: {needed: false, approver: null}
confidence: {value: Med, derived-from: exact-winner-source-inspection-and-bounded-two-scenario-E3-evidence}
risks:
- >-
두 record의 통과는 현재 구조의 결속을 보여주지만, 다른 학습 단계가 필요한 세 번째 실제 주제까지
일반화됐음을 증명하지는 않는다.
- >-
app.js 단일 파일은 현재 prototype에는 단순하지만 공개 주제가 늘면 변경 충돌점이 될 수 있으므로
SYS-R4-A01의 확장 임계점에서 다시 판단해야 한다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T144700Z.report.yaml
grade: E3
note: "exact winner SHA와 revision-4 browser/receipt 결속"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
grade: E3
note: "revision 4 shared-core, fixture, closure, verification 범위"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/app.js
grade: E3
note: "registry, reducer, explicit scenario binding과 제한된 runtime 경계의 직접 검사"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/styles.css
grade: E3
note: "token 및 shared visual recipe의 직접 검사"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/scripts/verify_flow.cjs
grade: E3
note: "기본 6단계와 독립 4단계 fixture의 full-flow assertion 직접 검사"
@@ -0,0 +1,65 @@
report-type: workflow-artifact
artifact-kind: pre-direction-framing
artifact-version: 1
tier: standard
identity:
artifact-id: DES-PROD-20260718T111439Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-discovery
producer-role-id: DES-PROD
created-at: 20260718T111439Z
attempt-id: 1
payload:
brief:
problem: >-
개념 기반과 증상 기반 두 출발점을 명확히 보여주면서도 두 제품이 아니라 하나의 Lost Update
학습 코어로 합류한다는 사실을 첫 화면과 실험 흐름에서 증명해야 한다.
audience: "기술 개념을 부분적으로 알거나 실제 이상 현상만 알고 있는 개발자"
success: >-
첫 방문자가 10초 안에 사이트 목적·두 출발점의 차이·같은 Lab으로 합류한다는 사실을 이해하고,
키보드와 360px 환경에서도 Transfer까지 완주한다.
representative-screen: dual-entry-shared-lab
experience-constraints:
- "두 portal은 orientation만 다르고 tx-lost-update-01과 reducer를 공유한다."
- "홈에 '두 입구, 하나의 Lost Update Lab'을 명시한다."
- "증상 경로는 진단·원인 확정이 아니라 가능한 메커니즘을 좁히는 교육용 단서다."
- "Atlas 정체성은 짧은 관계 경로로만 표현하고 큰 가짜 지도를 만들지 않는다."
- "대표 화면에서 실제 학습 깊이의 증거인 값·순서·예측·인과를 미리 보여준다."
- "두 세션과 충돌은 색뿐 아니라 이름·패턴·형태로 구분한다."
direction-input-brief:
path: hyeonworks/design/hyeonworks-vnext-v1/direction-input-brief.yaml
sha256: 975a7713b1837576173aee1d9a349bb68afd652ed9d1166fd9d5efc39059d9b4
frozen: true
divergence-axes:
- "전문 기술 저널처럼 읽는 편집형 흐름 vs 신호를 추적하는 계측형 흐름"
- "차분한 인과 기록 vs 실시간 상태 추적 vs 단계별 현장 매뉴얼"
- "여백 중심 세로 리듬 vs 고밀도 rail topology vs 굵은 모듈형 블록"
- "세리프+모노 편집 음성 vs 산세리프+numeric 계측 음성 vs 압축 display+humanist 안내 음성"
method-execution:
role-id: DES-PROD
method-id: pre-direction
contract-sha256: 1c62d7fb64879275e5610d65d29eeb88d3e841042ef5f6f991ff725442c614f3
step-results:
- {step-id: frame-brief, status: completed, output-binding: current-artifact}
- {step-id: discover, status: completed, output-binding: current-artifact}
- {step-id: author-input-brief, status: completed, output-binding: current-artifact}
decisions:
- decision-id: representative-surface
selected: dual-entry-shared-lab
alternatives: [dual-entry-shared-lab, merged-lab-only]
report-header:
bottom-line: >-
발산 대상은 단순 홈 색상 변형이 아니라 두 출발점과 공통 Lab의 관계를 표현하는 전체 시각·상호작용
문법이다. 세 방향은 같은 제품 계약을 서로 다른 정신 모델로 실제 구현한다.
decision-needed: { needed: false, approver: null }
confidence: { value: Med, derived-from: accepted-product-decision-and-frozen-brief }
risks:
- "두 portal을 강하게 분리하면 shared-core 메시지가 약해질 수 있다."
- "실험 미리보기의 데이터 밀도가 첫 방문자에게 과부하가 될 수 있다."
evidence:
- source-uri: hyeonworks/design/hyeonworks-vnext-v1/direction-input-brief.yaml
grade: E3
note: "accepted decision을 사용자·접근성·플랫폼 제약으로 동결한 brief"
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1/EXEC-CEO-20260718T111108Z.report.yaml
grade: E3
note: "HUMAN-001 accepted Dual Portal product decision"
@@ -0,0 +1,78 @@
report-type: workflow-artifact
artifact-kind: design-lens-review
artifact-version: 1
identity:
artifact-id: DES-PROD-20260718T121036Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: DES-PROD
created-at: 20260718T121036Z
attempt-id: 2
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
target-prototype-id: ENG-FE-20260718T120840Z
target-prototype-sha256: 1cfa4ff43762111f46b0088057f6b902375f86856558056aa5f11f117f107267
reviewer-role-id: DES-PROD
reviewer-run-id: hyeonworks-vnext-v1-direction-review-product-fit-20260718T1211Z
lens: product-fit
verdict: revise
findings:
- severity: major
area: "Home preview and shared Lab / Predict"
evidence: >-
The home preview exposes Observed 70 and the write order "A writes 150 / B writes 70" before either
entry is chosen. The shared Lab then repeats that both sessions read the same initial value and write
in A-then-B order before Predict asks for the final value. This makes 70 available by recall rather
than prediction, and is especially tautological for the symptom entry whose starting clue is already
"expected 120, observed 70."
action: >-
Preserve one shared Lab but change Predict to a causal hypothesis that remains unresolved after both
orientations—for example, which read/write relationship could make a successful update disappear.
Keep the full write trace and resulting 70 behind Observe, or reduce the home folio to the question
and input facts needed to form that hypothesis.
- severity: major
area: "Shared Lab / Explain and completion claim"
evidence: >-
Compare supplies the full same-read → independent-compute → last-write-overwrite explanation. Explain
can then be passed by selecting that same prewritten sentence; the learner's one-sentence explanation
is optional and is neither required nor used by the reducer. Nevertheless completion states that the
learner can now explain 70 causally. The implemented gate therefore demonstrates recognition, not the
product's promised ability to articulate the mechanism.
action: >-
Require a compact constructed explanation before completion, such as ordering the three causal links
or filling explicit read-basis, overwritten-write, and lost-change fields. Base completion wording on
that observable task, while keeping the free-form reflection optional if it cannot be evaluated
honestly in this browser-local prototype.
report-header:
bottom-line: >-
REVISE — the prototype clearly delivers two orientations into one deterministic Lost Update Lab and
represents all five named stages, but it reveals the predicted result before Predict and treats recognition
of a supplied explanation as proof of causal articulation; those gaps weaken the core deep-mechanism
learning promise without requiring a direction change.
decision-needed: { needed: false, approver: null }
confidence:
value: Med
derived-from: exact-hash-bound-source-and-render-inspection-without-learner-outcome-evidence
risks:
- >-
Learners may complete Predict by recalling the already displayed 70, so completion data could be mistaken
for evidence of a formed causal hypothesis.
- >-
The completion statement may overstate what the prototype has observed because the required Explain
interaction only verifies selection of a supplied answer.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T120840Z.report.yaml
grade: E3
note: "Exact winner artifact ENG-FE-20260718T120840Z; live SHA-256 matched the assigned target hash."
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-DIRECTOR-20260718T115933Z.report.yaml
grade: E3
note: "Selected Ledger Studio rationale and locked product invariants used as the comparison contract."
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/app.js
grade: E3
note: "Direct source inspection of both orientations, shared reducer state, and all five Lab phase gates."
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w1280.png
grade: E3
note: "Direct desktop render inspection of the product promise, two entries, shared-Lab marker, and exposed folio trace."
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w360.png
grade: E3
note: "Direct mobile render inspection confirming the same promise and pre-entry result/trace disclosure."
@@ -0,0 +1,54 @@
report-type: workflow-artifact
artifact-kind: design-lens-review
artifact-version: 1
identity:
artifact-id: DES-PROD-20260718T131443Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: DES-PROD
created-at: 20260718T131443Z
attempt-id: 3
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
target-prototype-id: ENG-FE-20260718T131305Z
target-prototype-sha256: bcc557fcd7463349345bd06090868c4c2b6b792453d4e1dddd4ac60b0fa68674
reviewer-role-id: DES-PROD
reviewer-run-id: db69cd61af060c50804e694ae541d0106551b2025eb654b6947428de4e983bce
lens: product-fit
verdict: pass
findings: []
report-header:
bottom-line: >-
PASS — revision 2 turns Predict into an unresolved causal hypothesis before Observe, requires learners to
construct the three causal elements before Transfer, blocks incorrect constructions in the live flow, and
limits completion to exactly those observed tasks; the two orientations still converge on one five-stage Lab.
decision-needed: { needed: false, approver: null }
confidence:
value: Med
derived-from: exact-winner-source-state-renders-and-live-browser-flow-without-learner-outcome-evidence
risks:
- >-
This verdict confirms product-promise-to-interaction alignment, not learning efficacy; comprehension,
retention, and transfer with actual developers remain unmeasured.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T131305Z.report.yaml
grade: E3
note: "Exact revision-2 winner ENG-FE-20260718T131305Z; live SHA-256 matched the assigned target hash."
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-DIRECTOR-20260718T115933Z.report.yaml
grade: E3
note: "Selected Ledger Studio product rationale and five locked invariants used as the review contract."
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
grade: E3
note: "Hash-bound revision-2 manifest defining the shared causal-hypothesis learning loop and completion boundary."
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/app.js
grade: E3
note: "Direct source inspection confirmed shared scenario state, causal Predict, three-part Explain gate, Transfer gate, and scoped completion copy."
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews
grade: E3
note: "Direct inspection of Predict, Compare, Explain, Transfer, and Complete renders at 360 and 1280."
- command: node scripts/verify_flow.cjs
exit-code: 0
grade: E3
note: >-
Re-run from an exact /tmp copy to avoid modifying the prototype; verified both entries, shared core,
wrong-answer blocking, correct constructed explanation, transfer, scoped completion, and reset.
@@ -0,0 +1,164 @@
report-header:
bottom-line: >-
PASS — exact Revision 3 winner ENG-FE-20260718T135811Z는 개념·증상 두 진입을 같은
Lost Update Lab에 합류시키고, 구체 write 순서를 Predict 뒤에 공개한 다음
Predict → Observe → Compare → 세 요소 Explain → 새 사례 Transfer를 실제 상태 gate로
강제한다. Complete가 구성·전이 통과만 기록하도록 한계를 명시하므로, 한 메커니즘을
증거로 이해시키려는 제품 약속과 prototype이 관찰하는 학습 신호가 정합한다.
decision-needed: {needed: false, approver: null}
confidence:
value: Med
derived-from: exact-target-hash-bound-source-and-360-1280-state-render-inspection
risks:
- >-
must-read에는 실사용자 연구·행동 데이터·학습 전후 평가가 없으므로, 이 pass는 실제
학습효과나 전문가 수준 도달을 인증하지 않고 prototype 내부의 약속-흐름-완료조건
정합만 판정한다.
- >-
tx-lost-update-inventory-fixture는 shared engine 결속을 확인하는 direct-route fixture이며,
두 번째 공개 딥다이브나 콘텐츠 폭의 증거로 보지 않았다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T135811Z.report.yaml
grade: E3
note: >-
live file SHA-256 735d588bef412dd3c59899d393562ae76a67a55bbe9f507ddf38eeab1481e9f0;
exact Revision 3 winner identity, core-flow/app hashes, state-preview set과 검증 범위를 결속한다.
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-DIRECTOR-20260718T115933Z.report.yaml
grade: E3
note: >-
Ledger Studio의 deep-mechanism 제품 논리와 LI-DUAL-ENTRY-SHARED-CORE,
LI-EVIDENCE-LEARNING-LOOP, LI-HONEST-BOUNDARY를 판정 기준으로 제공한다.
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
grade: E3
note: >-
Revision 3의 route, shared state, five-phase learning-evidence와 제한된 completion
claim을 명세한다(SHA-256 bd2bf67bddde92ae4fa0d329bd21e078625aa343ba59b78fec75f248111d22a1).
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/app.js
grade: E3
note: >-
reducer transition, hidden/pending Observe rows, three-part explanation correctness,
transfer correctness와 bounded Complete copy의 실제 구현을 확인했다
(SHA-256 4bd59d70b8470263a84c3605db8f61bc88d86eef297dd0643f57365f300ace1b).
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews
grade: E3
note: >-
predict, observe, compare, explain, transfer, complete의 360px·1280px 총 12개 렌더를
직접 대조해 단계 위계와 사용자에게 노출되는 주장 범위를 확인했다.
report-type: workflow-artifact
artifact-kind: design-lens-review
artifact-version: 1
identity:
artifact-id: DES-PROD-20260718T140000Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: DES-PROD
created-at: 20260718T140000Z
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
target-prototype-id: ENG-FE-20260718T135811Z
target-prototype-sha256: 735d588bef412dd3c59899d393562ae76a67a55bbe9f507ddf38eeab1481e9f0
target-prototype-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T135811Z.report.yaml
reviewer-role-id: DES-PROD
reviewer-run-id: 1b92e14079e2752bac1d8c62f6d1ab73ee8d33aef646f22c0c76fe134f27c988
lens: product-fit
verdict: pass
assessment-scope: >-
고객 문제가 이해 가능한 흐름으로 해결되는지와 deep-mechanism 약속이 observable
learning gates에 결속되는지만 평가했다. 사용성·시각완성도·시스템화·시장성·구현성의
독립 verdict는 내리지 않았다.
product-fit-checks:
- check-id: PF-R3-C01
criterion: 두 출발점이 orientation만 달리하고 동일한 메커니즘 학습으로 합류하는가
result: pass
evidence:
- >-
app.js renderConcept/renderSymptom은 모두 #/lab/tx-lost-update-01로 이동하고,
render()는 route scenario id와 initialLabState를 동일 shared reducer에 결속한다.
- >-
core-flow.yaml shared-core.entry-invariant가 두 orientation의 동일 id 기반 Lab 합류를
명시한다.
- check-id: PF-R3-C02
criterion: 관찰 전에 원인 가설을 고정하고 이후 증거로 검증하는가
result: pass
evidence:
- >-
app.js previewFolio는 write order를 hidden으로 두고 predictView는 read/write 관계
가설만 먼저 고정하며, COMMIT_PREDICTION 뒤에만 Observe로 전이한다.
- >-
observeView는 미래 행을 대기/다음 단계로 숨기고 schedule을 한 단계씩 공개한 뒤에만
Compare 진입을 허용한다.
- check-id: PF-R3-C03
criterion: deep-mechanism 약속을 뒷받침하는 관찰 가능한 Explain·Transfer gate가 있는가
result: pass
evidence:
- >-
Compare가 same read basis, final write order, lost delta를 노출한 뒤 Explain은
read basis·final write·lost change 세 요소를 별도로 제출하게 하고 정확한 세 id가
모두 맞아야 Transfer로 진행시킨다(app.js explanationCorrect/CONTINUE_TO_TRANSFER).
- >-
Transfer는 30→expected 36/observed 40의 새 재고 사례에서 사라진 변화를 다시
식별해야 하고, transferCorrect를 통과해야만 Complete가 된다.
- >-
360px·1280px state-previews에서 Compare → Explain → Transfer → Complete의 동일
학습 위계와 과제 내용이 확인된다.
- check-id: PF-R3-C04
criterion: 완료 기록이 실제로 관찰한 신호보다 넓은 능력을 주장하지 않는가
result: pass
evidence:
- >-
completeView와 complete state renders는 자유 서술 능력·실제 장애 진단을 증명하지
않는다고 명시하고, 통제된 시나리오의 세 인과 요소 구성과 전이 통과만 기록한다.
- >-
guided scenario boundary는 특정 DB 동작이나 실제 장애 원인 확정을 반복해서 배제한다.
findings:
- finding-id: PF-R3-01
severity: informational
blocking: false
status: satisfied
area: end-to-end learning journey
summary: >-
두 entry가 orientation 차이를 보존하면서 같은 scenario와 reducer로 합류해,
concept-first와 symptom-first 사용자가 하나의 causal evidence loop를 완주한다.
evidence-refs:
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml#shared-core
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/app.js#renderConcept-renderSymptom-render
product-impact: >-
고객이 가진 출발 단서와 무관하게 제품의 핵심 가치인 메커니즘 이해로 빠지지 않고
연결된다.
- finding-id: PF-R3-02
severity: informational
blocking: false
status: satisfied
area: Predict-to-Complete learning gates
summary: >-
구체 실행 순서를 미리 노출하지 않은 Predict, 단계별 Observe, evidence Compare,
세 요소 Explain, 새 수치 Transfer가 순차 correctness gate로 결속돼 있다.
evidence-refs:
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/app.js#learningReducer
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/app.js#compareView-explainView-transferView
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews
product-impact: >-
단순 결과 회상보다 read basis → final write → lost change 관계를 관찰·대조·재적용하는
행동을 완료조건으로 삼아 deep-mechanism 약속을 화면 흐름으로 만든다.
- finding-id: PF-R3-03
severity: informational
blocking: false
status: satisfied-with-evidence-boundary
area: completion claim
summary: >-
완료 문구가 자동 검증된 구성·전이 신호만 말하고 자유 서술·실제 장애 진단·특정 DB
보장을 제외해, prototype 증거보다 큰 학습효과를 주장하지 않는다.
evidence-refs:
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml#learning-evidence
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/app.js#completeView
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews/complete.w360.png
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews/complete.w1280.png
product-impact: >-
guided learning product와 실제 진단 도구의 경계를 지켜 신뢰를 해치지 않으면서도,
현재 핵심 흐름이 증명한 가치를 정확히 전달한다.
required-revisions: []
residual-evidence-gap: >-
실제 사용자 학습효과와 전문가 수준 도달은 이 prototype audit의 근거 범위 밖이며 후속
사용자 연구가 필요하다. 현재 UI도 그 결과를 주장하지 않으므로 product-fit revision
사유로 승격하지 않았다.
@@ -0,0 +1,89 @@
report-type: workflow-artifact
artifact-kind: design-lens-review
artifact-version: 1
identity:
artifact-id: DES-PROD-20260718T145000Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: DES-PROD
created-at: 20260718T145000Z
attempt-id: 1
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
lens: product-fit
target-prototype-id: ENG-FE-20260718T144700Z
target-prototype-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T144700Z.report.yaml
target-prototype-sha256: 8b208279e12f9aea0fa6d7a3c320811b0e72ddb74c6afac64cddadf4b157cf76
context-package-ref: hyeonworks/state/context-packages/hyeonworks-vnext-v1-direction/DES-PROD-20260718T144800Z.pkg.yaml
context-package-sha256: b0a5758b357ea46d16d64ed700b44c3ec365c18979c93a4b0c257db83575081c
reviewer-role-id: DES-PROD
reviewer-run-id: 0cf87e457984c59af5b263a50024f493fa9caaf0fcf630273503befaf4033dd4
verdict: pass
findings: []
assessment:
promise-fit: >-
활성 범위를 Lost Update 한 메커니즘으로 명시적으로 제한하고, 정의 열람이 아니라
Predict → Observe → Compare → Explain → Transfer를 완주하게 하므로 “기술을 깊이
학습한다”는 현재 제품 약속과 직접 맞는다.
dual-entry-fit: >-
concept 경로는 개념 관계를, symptom 경로는 기대 120/관찰 70과 단서를 출발점으로
제공하지만 둘 다 같은 tx-lost-update-01과 같은 reducer 상태의 Lab으로 합류한다.
debugger 방식은 실제 진단 도구로 확장되지 않고 후보 메커니즘을 통제 실행으로
검증하는 교육적 입구로 유지된다.
observable-learning-gates: >-
관찰 전에 read/write 원인 가설을 고정하고, 6단계 실행에서 공유값 변화를 직접
진행한 뒤 READ/WRITE/Delta 증거와 대조한다. Explain은 read 기준·마지막 write·사라진
변화를 세 부분으로 구성해 제출하게 하며, Transfer는 30→36 기대/40 관찰의 새 재고
사례에서 사라진 −4를 식별하게 하므로 단순 결과 회상보다 강한 메커니즘 게이트다.
boundary-fit: >-
orientation, Lab brief, completion 모두 고정 guided scenario임을 반복해 밝히고 실제
로그 분석·특정 DB 보장·장애 원인 확정·자유 서술 능력·사용자 학습효과를 주장하지
않는다. 따라서 debugger 진입의 매력과 현재 증거 범위 사이의 신뢰 경계가 유지된다.
revision-4-impact: >-
R4의 대비 보정과 skip-link 상태 보존은 학습 모델을 바꾸지 않으면서 작은 evidence
label과 선택 경계의 판독성, 진행 중 Lab 상태의 연속성을 보강한다. exact winner에
결속된 browser receipt는 두 scenario와 전 상태 흐름이 실행 가능함을 뒷받침한다.
non-blocking-limitations:
- >-
Predict 선택지는 개념·증상 orientation의 단서와 가까워 평가 변별력은 제한적이다.
그러나 이후의 단계별 실행, 세 부분 인과 구성, 새로운 수치 사례 전이가 보완하므로
현재 core-flow 승인 차단 사유는 아니다.
- >-
자동 통과 기록은 실제 사용자의 장기 기억, 자유 서술, 현업 장애 진단 능력을
입증하지 않는다. 해당 효과를 주장하려면 별도의 사용자 연구가 필요하다.
evidence-assessment:
- claim: dual-entry가 하나의 메커니즘 학습 core로 합류한다.
grade: E3
source-ref: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/app.js
basis: scenarioRegistry, route, initialLabState, learningReducer와 두 orientation의 동일 Lab 링크
- claim: 깊이 학습 약속이 관찰 가능한 다섯 단계 게이트로 구현됐다.
grade: E3
source-ref: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
basis: learning-evidence와 exact R4 browser-e2e coverage
- claim: Predict부터 Complete까지 360/1280에서 동일한 causal ledger 위계가 유지된다.
grade: E3
source-ref: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews
basis: 열두 상태 렌더의 독립 육안 대조
report-header:
bottom-line: >-
PASS — R4는 concept-first와 symptom-first debugger 입구를 같은 Lost Update Lab에
합류시키고, 가설·실행·증거 대조·인과 구성·새 사례 전이로 깊이 학습 약속을 실제
상호작용에 결속한다. 제품 효과를 과장하지 않는 guided-scenario 경계도 일관된다.
decision-needed: { needed: false, approver: null }
confidence: { value: Med, derived-from: exact-r4-source-state-renders-and-bound-browser-receipt }
risks:
- Predict 선택의 평가 변별력은 orientation 단서 때문에 제한적이다.
- 실제 사용자 학습효과와 현업 진단 전이는 아직 검증되지 않았다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T144700Z.report.yaml
grade: E3
note: exact R4 winner와 hash-bound preview/browser/CSS receipts
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
grade: E3
note: dual-entry shared core, five-step learning evidence, honest completion boundary
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/app.js
grade: E3
note: scenario registry, reducer, orientation 합류와 실제 gate 구현
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews
grade: E3
note: Predict·Observe·Compare·Explain·Transfer·Complete의 360/1280 렌더 확인
@@ -0,0 +1,83 @@
report-type: workflow-artifact
artifact-kind: comparative-divergence-audit
artifact-version: 1
identity:
artifact-id: DES-VISUAL-20260718T113705Z-1
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-divergence
producer-role-id: DES-VISUAL
created-at: 20260718T113705Z
attempt-id: 2
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
divergence-charter-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-DIRECTOR-20260718T111440Z-1.report.yaml
divergence-charter-sha256: 24e3f75377c8a255664a7487e81269aa3639819b00685756f26fecb60a5b8e78
direction-set-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-VISUAL-20260718T113705Z.report.yaml
direction-set-sha256: ff7384a6a4977cd0bff7f0a19e4a5b0611010c287a80f9a230cca9566c7613d5
reviewer-role-id: DES-VISUAL
reviewer-run-id: hyeonworks-vnext-v1-direction-comparison-audit-20260718T1152Z
verdict: pass
pairwise-comparisons:
- directions: [ledger-studio, signal-trace]
differing-axes: [layout-topology, navigation-model, typography-voice, imagery-strategy, motion-model, dominant-primitives]
primitive-collisions: []
observed-separation: >-
Ledger는 큰 serif 논제와 오른쪽 folio에서 아래 2열 entry로 읽는 인쇄형 spread이고,
Signal은 두 input band가 merge bus와 full-width trace rail로 수렴하는 계측 구조다.
색을 제거해도 folio/rule/marginalia와 band/bus/probe/hatch가 겹치지 않는다.
- directions: [ledger-studio, field-manual]
differing-axes: [layout-topology, navigation-model, typography-voice, imagery-strategy, motion-model, dominant-primitives]
primitive-collisions: []
observed-separation: >-
Ledger는 자율적인 편집 읽기와 causal folio를 중심에 두지만 Manual은 Module 01 cover,
vertical instruction rail, A/B 번호판과 0105 procedure strip으로 행동 순서를 지시한다.
serif folio와 condensed-numbered protocol은 시선 경로·위계·조작 기대가 다르다.
- directions: [signal-trace, field-manual]
differing-axes: [layout-topology, navigation-model, typography-voice, imagery-strategy, motion-model, dominant-primitives]
primitive-collisions: []
observed-separation: >-
Signal은 입력 채널과 실행 시간을 연속 rail로 추적하고 current segment 강조를 전제로 한다.
Manual은 불연속 numbered checkpoint와 rule block을 순서대로 완료한다. channel geometry,
tabular trace, hatch와 module plate, procedure cell, field stamp가 구조적으로 분리된다.
full-size-previews:
- direction-id: ledger-studio
ref: hyeonworks/design-direction/hyeonworks-vnext-v1/previews/ledger-desktop.png
sha256: 8b898b688836f325d40a204ae241989c09672d33e683596b56963fdb487f226c
- direction-id: signal-trace
ref: hyeonworks/design-direction/hyeonworks-vnext-v1/previews/signal-desktop.png
sha256: 072e4402128ea6043037a20bc6ab4a5a1dc9e0f6629547401f1ca1c5c2b1d0f5
- direction-id: field-manual
ref: hyeonworks/design-direction/hyeonworks-vnext-v1/previews/manual-desktop.png
sha256: 861270acfbfcd3bdc5b541e6a8613d13c20658d933666e761a45e53a4dcbe854
responsive-previews:
- {direction-id: ledger-studio, ref: hyeonworks/design-direction/hyeonworks-vnext-v1/previews/ledger-mobile.png, sha256: 70ce29b23854d9811605cf547d1878fe21d9d02a78623847a1cbb543603c0760}
- {direction-id: signal-trace, ref: hyeonworks/design-direction/hyeonworks-vnext-v1/previews/signal-mobile.png, sha256: 00bab0cbb8b13bc716c9358efadee7e5490941ceb8734241b9ae8af945002ac7}
- {direction-id: field-manual, ref: hyeonworks/design-direction/hyeonworks-vnext-v1/previews/manual-mobile.png, sha256: 0459010168f0098958eddae74448c877c022fa980263bc8c37052647b1dac575}
shared-product-invariants:
- "개념·증상 두 entry"
- "하나의 tx-lost-update-01 Lab"
- "Predict→Observe→Compare→Explain→Transfer"
- "guided-scenario 경계"
reference-overlap-audit:
result: pass
maximum-name-overlap-per-pair: 0
blocking-findings: []
tradeoffs:
ledger-studio: "전문성과 인과 기록이 가장 강하지만 첫 실행 전 텍스트가 가장 많다."
signal-trace: "시간적 인과 판독이 가장 빠르지만 교육 도구보다 monitoring UI로 읽힐 위험이 있다."
field-manual: "절차 실행 가능성이 가장 강하지만 cover의 시각 비중이 marketing poster로 오인될 수 있다."
report-header:
bottom-line: >-
PASS — 세 방향은 모든 pair에서 6개 조형 축이 실제 1280/390 렌더로 분리되며 exclusive primitive
충돌과 reference name 중복이 없다. 공통 요소는 제품 불변식뿐이므로 단일 방향 선택이 가능하다.
decision-needed: { needed: false, approver: null }
confidence: { value: Med, derived-from: exact-hash-bound-source-and-browser-renders }
risks:
- "스크린샷 비교는 사용자 이해도·학습 효과를 증명하지 않으므로 선택 효과 확신은 Med로 제한한다."
evidence:
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/previews/comparison.png
grade: E3
note: "세 방향 desktop/mobile contact sheet"
- source-uri: hyeonworks/evidence/ledger.jsonl
grade: E3
note: "vr-1784375368-f87086d0b444: preview 크기와 source/concept/PNG hash verification"
@@ -0,0 +1,154 @@
report-type: workflow-artifact
artifact-kind: direction-set
artifact-version: 1
identity:
artifact-id: DES-VISUAL-20260718T113705Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-divergence
producer-role-id: DES-VISUAL
created-at: 20260718T113705Z
attempt-id: 1
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
divergence-charter-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-DIRECTOR-20260718T111440Z-1.report.yaml
divergence-charter-sha256: 24e3f75377c8a255664a7487e81269aa3639819b00685756f26fecb60a5b8e78
representative-screen:
id: dual-entry-shared-lab
kind: first-entry
description: >-
개념·증상 두 출발점, 하나의 tx-lost-update-01 Lab, 짧은 Atlas path, 공통 학습 루프와
guided-scenario 경계를 첫 화면에서 이해하고 어느 경로로든 학습을 시작하는 화면.
comparison-preview:
receipt-ref: hyeonworks/design-direction/hyeonworks-vnext-v1/previews/comparison.png
receipt-sha256: da8d10b579e97e17a087ca1490531e1b3f8de7a7a327919ebeb9d6d16426f8cd
verification-receipt-id: vr-1784375368-f87086d0b444
gallery-path: hyeonworks/design-direction/hyeonworks-vnext-v1/previews
representative-screen-id: dual-entry-shared-lab
viewports: [390, 1280]
shots:
- hyeonworks/design-direction/hyeonworks-vnext-v1/previews/ledger-desktop.png
- hyeonworks/design-direction/hyeonworks-vnext-v1/previews/ledger-mobile.png
- hyeonworks/design-direction/hyeonworks-vnext-v1/previews/signal-desktop.png
- hyeonworks/design-direction/hyeonworks-vnext-v1/previews/signal-mobile.png
- hyeonworks/design-direction/hyeonworks-vnext-v1/previews/manual-desktop.png
- hyeonworks/design-direction/hyeonworks-vnext-v1/previews/manual-mobile.png
directions:
- id: ledger-studio
producer-role-id: DES-VISUAL
producer-run-id: hyeonworks-vnext-v1-direction-divergence-ledger-20260718T1135Z
context-package-id: 52ef4f1c5e433157bc23eb801d3fb122923d7f50d667af41019be3b4b1489c83
concept-artifact: hyeonworks/design-direction/hyeonworks-vnext-v1/directions/ledger-studio/concept.yaml
reference-cluster:
- name: Scientific lab notebook
signal: "가설·관찰·결과가 rule과 여백 주석으로 이어지고 사실과 해석이 분리된다."
why-relevant: "Predict부터 Explain까지를 수동 독서가 아닌 검증 기록으로 만든다."
- name: Long-form technical journal
signal: "큰 serif 논제, 짧은 dek, 넓은 여백과 folio가 한 주제의 읽기 깊이를 만든다."
why-relevant: "콘텐츠 수를 과장하지 않고 활성 딥다이브 하나의 전문성을 먼저 전달한다."
- name: Double-entry ledger
signal: "Initial·Expected·Observed 숫자가 고정 열과 기준선 위에 정렬된다."
why-relevant: "100·120·70과 두 세션의 쓰기를 같은 장부에서 감사하게 한다."
visual-thesis: >-
Lost Update를 장애 콘솔이나 카드 모음이 아니라 가설과 관찰값을 대조하는 편집형 기술 저널로
보여준다. 두 entry는 orientation에서만 분리되고 merge rule 아래 같은 causal ledger로 합류한다.
layout-grammar: >-
비대칭 editorial spread, 오른쪽 ledger folio, 두 개의 orientation column, 하나의 merge rule과
단일 학습 loop. 모바일은 DOM 순서를 유지한 한 열로 재배치한다.
interaction-grammar: >-
native anchor 두 개가 같은 #shared-lab으로 이동한다. skip link, focus-visible, reduced-motion을
제공하고 이후 실행은 키보드 가능한 단일 Predict→Transfer 흐름으로 확장한다.
typography-token-direction: >-
논제는 Georgia 계열 serif, 본문은 neutral system sans, id·값·evidence는 mono. paper/ink 바탕에서
coral은 observed 결과에만 제한하고 rule은 인과·비교 경계에만 쓴다.
primitive-inventory: [entry-column, causal-ledger, evidence-margin, merge-rule, ledger-folio, annotated-value]
reference-board-ref: hyeonworks/design-direction/hyeonworks-vnext-v1/directions/ledger-studio/concept.yaml
reference-board-sha256: d402206b77e2e1af6642c74a453a34fd107d1e91d10bf247802129a71f04f0dd
full-size-preview-ref: hyeonworks/design-direction/hyeonworks-vnext-v1/previews/ledger-desktop.png
full-size-preview-sha256: 8b898b688836f325d40a204ae241989c09672d33e683596b56963fdb487f226c
coded-slice: hyeonworks/design-direction/hyeonworks-vnext-v1/directions/ledger-studio/index.html
coded-slice-sha256: ad92b3c6676292267ea590d1d96e789a4d978e42d640e97c779c8846b314b5da
- id: signal-trace
producer-role-id: DES-VISUAL
producer-run-id: hyeonworks-vnext-v1-direction-divergence-signal-20260718T1135Z
context-package-id: f2a89ef290b57ed34610b08e30b2a23d07e7244fec0991de81d61ca157d8ccf6
concept-artifact: hyeonworks/design-direction/hyeonworks-vnext-v1/directions/signal-trace/concept.yaml
reference-cluster:
- name: Railway junction schematic
signal: "두 입력선이 이름 붙은 junction에서 하나의 선로로 합류한다."
why-relevant: "개념·증상 진입의 차이와 합류 후 하나의 Lab이라는 구조를 직접 설명한다."
- name: Logic analyzer timing sheet
signal: "공통 시간축에 채널별 read·compute·write 상태를 행으로 정렬한다."
why-relevant: "동시 실행의 선후 관계와 마지막 쓰기의 overwrite를 빠르게 비교하게 한다."
- name: Calibration instrument panel
signal: "숫자 probe와 짧은 역할 label이 장식 없이 값을 비교한다."
why-relevant: "Initial 100·Expected 120·Observed 70의 차이를 계측값처럼 판독하게 한다."
visual-thesis: >-
두 입력 단서를 밝은 계측 band로 분리하고 merge bus에서 하나의 Lab으로 수렴시킨 뒤,
동일 초기값을 읽고 150과 70을 쓰는 과정을 단일 transaction trace로 판독하게 한다.
layout-grammar: >-
dual input bands→center merge bus→full-width shared Lab→trace rail→common loop 구조.
모바일은 step→A→B 순서로 선형화하고 DOM 읽기 순서를 보존한다.
interaction-grammar: >-
두 native entry가 같은 shared target을 참조하며 합류 후 하나의 trace만 존재한다. 세션은
circle/diamond·label·hatch로 중복 부호화하고 reduced-motion에서는 굵기와 패턴으로 대체한다.
typography-token-direction: >-
precise grotesk sans와 tabular mono 숫자/신호 label. 밝은 계측 바탕에서 blue=A,
red+hatch=B/overwrite, green=merge로 제한하며 색 단독 의미 전달을 금지한다.
primitive-inventory: [entry-band, merge-bus, trace-rail, signal-stamp, conflict-hatch, value-probe]
reference-board-ref: hyeonworks/design-direction/hyeonworks-vnext-v1/directions/signal-trace/concept.yaml
reference-board-sha256: 91373c402d4708774f5385647b84a8393e440796ba1add1b8242b2686bbcaf44
full-size-preview-ref: hyeonworks/design-direction/hyeonworks-vnext-v1/previews/signal-desktop.png
full-size-preview-sha256: 072e4402128ea6043037a20bc6ab4a5a1dc9e0f6629547401f1ca1c5c2b1d0f5
coded-slice: hyeonworks/design-direction/hyeonworks-vnext-v1/directions/signal-trace/index.html
coded-slice-sha256: 0e588d75ae7e4615021d20f65802a4d2b2743c072c9f40c4a301be28b5de8771
- id: field-manual
producer-role-id: DES-VISUAL
producer-run-id: hyeonworks-vnext-v1-direction-divergence-manual-20260718T1145Z
context-package-id: eedcf6c839f69f3df7a30e7ea18b52ed5be3136c2699a2f7fe183eb27e877b30
concept-artifact: hyeonworks/design-direction/hyeonworks-vnext-v1/directions/field-manual/concept.yaml
reference-cluster:
- name: Aircraft quick-reference procedure
signal: "행동 순서와 경계 조건을 굵은 단계 번호와 짧은 imperative로 분리한다."
why-relevant: "공통 학습 루프를 읽는 설명이 아니라 실행할 프로토콜로 만든다."
- name: Industrial field service manual
signal: "module 번호·revision·적용 범위를 좁은 metadata rail과 rule block으로 구분한다."
why-relevant: "활성 딥다이브 하나를 Module 01로 정직하게 표현하고 교육 범위를 명시한다."
- name: Swiss instructional poster
signal: "비대칭 대형 숫자와 고정 grid가 읽기·행동 주행 방향을 만든다."
why-relevant: "Entry A/B와 합류 Protocol 01의 위계를 색보다 크기·위치·선으로 설명한다."
visual-thesis: >-
두 단서를 한 장의 현장 매뉴얼에서 Entry A/B와 하나의 Protocol 01로 편성한다. 굵은 번호는
장식이 아니라 다음 학습 행동을 지시하고 큰 선언 뒤에는 즉시 검증 가능한 값과 절차가 따른다.
layout-grammar: >-
modular poster stack, Module 01 cover, 2-up entry panels, full-width numbered procedure strip,
compact schedule과 boundary rule. 모바일은 같은 순서를 한 열로 재배치한다.
interaction-grammar: >-
두 native entry가 같은 protocol로 이동한다. 0105 단계는 번호·verb·state marker를 함께 쓰고
Tab/Enter/Space와 aria-live를 전제로 하며 drag-only 조작을 금지한다.
typography-token-direction: >-
condensed display는 module·step 번호에만, warm humanist sans는 한국어 지시에, mono는 scenario id와
값에만 사용한다. yellow=active module, green=instruction, orange=symptom evidence로 제한한다.
primitive-inventory: [protocol-panel, numbered-checkpoint, rule-block, field-stamp, procedure-strip, transfer-ticket]
reference-board-ref: hyeonworks/design-direction/hyeonworks-vnext-v1/directions/field-manual/concept.yaml
reference-board-sha256: f3fa0b0d1c89a87b89d2c924a1cd1875b822ced954fa1a428c6c4210fb8ccd3b
full-size-preview-ref: hyeonworks/design-direction/hyeonworks-vnext-v1/previews/manual-desktop.png
full-size-preview-sha256: 861270acfbfcd3bdc5b541e6a8613d13c20658d933666e761a45e53a4dcbe854
coded-slice: hyeonworks/design-direction/hyeonworks-vnext-v1/directions/field-manual/index.html
coded-slice-sha256: 2b408325b9e1e8faaf7cd6062af5d69300ce83c9660d200d1b162e2cadf6dbce
report-header:
bottom-line: >-
세 방향은 같은 카드 shell의 색상 변형이 아니다. Ledger는 편집 기록, Signal은 계측 rail,
Manual은 번호형 실행 프로토콜이라는 서로 다른 정신 모델을 독립 context와 실제 렌더로 증명했다.
decision-needed: { needed: false, approver: null }
confidence: { value: Med, derived-from: evidence }
risks:
- "Ledger는 첫 Lab 실행 전 읽기량이 가장 많다."
- "Signal은 밝은 계측 언어를 유지하지 않으면 모니터링 제품처럼 오인될 수 있다."
- "Manual은 큰 cover가 학습 도구보다 marketing poster로 보일 위험이 있다."
evidence:
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/previews/comparison.png
grade: E3
note: "세 방향의 동일 1280/390 viewport 비교 렌더"
- source-uri: hyeonworks/evidence/ledger.jsonl
grade: E3
note: "vr-1784375368-f87086d0b444: coded slice, concept, PNG dimension/hash 검증"
@@ -0,0 +1,110 @@
report-type: workflow-artifact
artifact-kind: design-lens-review
artifact-version: 1
identity:
artifact-id: DES-VISUAL-20260718T121036Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: DES-VISUAL
created-at: 20260718T121036Z
attempt-id: 3
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
target-prototype-id: ENG-FE-20260718T120840Z
target-prototype-sha256: 1cfa4ff43762111f46b0088057f6b902375f86856558056aa5f11f117f107267
reviewer-role-id: DES-VISUAL
reviewer-run-id: 2453b69fee7004f95eef43556a488b8f1230e84a2c9fe92cb7c6706e7bd515c1
lens: distinctiveness
verdict: pass
assessment:
visual-thesis: >-
기술 학습을 강의 목록이나 진단 dashboard가 아니라, 큰 편집 질문과 수치·실행 순서를 대조하는
field note / causal ledger로 다룬다.
internet-average-separation: >-
rounded-card grid, hero illustration, gradient, KPI dashboard, terminal chrome 없이 비대칭 editorial spread,
한국어 serif 논제, mono evidence ID, hard rule, 100·120·70 trace가 화면 위계를 만든다.
brand-recall: >-
Hyeonworks / Technology Atlas, Field Note, Same Lab, scenario ID와 causal values의 반복 결속으로
"한 메커니즘을 증거 기록처럼 끝까지 해부하는 곳"이라는 회상 단서가 생긴다.
cliche-pressure: >-
paper·serif·mono·offset shadow만 떼면 익숙한 editorial/brutalist web 관습이다. 현재는 Lost Update의
구체 값, 두 입구의 합류, 실행 trace와 causal ledger가 장식을 제품 고유 문법으로 바꾸므로 수정 게이트는 아니다.
inspected-surfaces:
- {viewport: 360, route: "#/", artifact: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w360.png}
- {viewport: 768, route: "#/", artifact: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w768.png}
- {viewport: 1280, route: "#/", artifact: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w1280.png}
- {viewport: 1280, route: "#/orient/concept", artifact: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist}
- {viewport: 1280, route: "#/orient/symptom", artifact: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist}
- {viewport: 1280, route: "#/lab/tx-lost-update-01", artifact: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist}
- {viewport: 360, route: "#/lab/tx-lost-update-01", artifact: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist}
findings:
- finding-id: DIST-01
severity: info
screen-area: "home · 1280 hero와 우측 scenario folio, entry 합류부"
evidence: >-
preview.w1280.png에서 초대형 serif 질문과 작은 mono atlas가 좌측 논제를 만들고, 우측 folio의
Initial 100 / Expected 120 / Observed 70 및 4행 trace가 즉시 검증 대상을 만든다. 아래 두 entry는
독립 카드 모음이 아니라 한 외곽선 안에서 Same Lab label로 다시 합쳐진다.
judgment: >-
편집 외형과 인과 증거가 같은 첫 화면에 결속되어 일반 기술교육 landing page나 SaaS grid와 구별된다.
- finding-id: DIST-02
severity: info
screen-area: "home · 768 및 360 responsive render"
evidence: >-
preview.w768.png에서는 논제→folio→entry가 단일 독서 흐름으로 재배치되고, preview.w360.png에서는
세 값이 행형 ledger로 바뀌어도 serif 질문, mono 번호, hard rule, coral observed 값과 offset sheet가 남는다.
judgment: >-
좁은 화면에서 단순 카드 stack으로 익명화되지 않고 동일한 field-note/ledger 인상을 보존한다.
- finding-id: DIST-03
severity: info
screen-area: "concept·symptom orientation과 shared Lab의 Predict 화면"
evidence: >-
dist를 실제 Chrome으로 렌더한 결과 concept는 3행 relation note, symptom은 순차 clue ledger로 같은
sheet 문법을 변주한다. Lab은 1280에서 dark scenario brief와 light workbench의 비대칭 split,
360에서 scenario ID·100/120/current ledger 뒤 작업대를 잇는 순서로 유지된다.
judgment: >-
signature가 home의 일회성 art direction에 머물지 않고 서로 다른 entry와 핵심 학습 화면까지 확장된다.
- finding-id: DIST-04
severity: minor
screen-area: "shared Lab · 5단계 progress와 radio choice rows"
evidence: >-
progress strip과 bordered radio rows 자체는 범용 courseware/form 관습이다. 다만 현재 화면에서는
scenario ID, dark evidence brief, explicit values, phase label과 이후 cause rows가 더 강한 상위 문법으로 묶는다.
judgment: >-
현재 winner의 고유성을 무너뜨리지는 않지만, 후속 확장에서 generic control이 커지고 ledger 증거가
줄면 가장 먼저 인터넷 평균으로 퇴행할 지점이다.
report-header:
bottom-line: >-
PASS — ENG-FE-20260718T120840Z@1cfa4ff43762111f46b0088057f6b902375f86856558056aa5f11f117f107267는
360/768/1280과 orientation/Lab에서 editorial evidence와 causal ledger를 제품 고유 문법으로 유지하며,
일반 SaaS 카드 grid나 평균적 기술교육 화면으로 퇴행하지 않았다.
decision-needed: { needed: false, approver: null }
confidence:
value: Med
derived-from: exact-winner-sha-dist-source-three-bound-preview-and-live-route-renders
risks:
- >-
paper·serif·mono·hard rule·offset shadow 조합 자체는 널리 쓰이는 editorial/brutalist 관습이므로,
구체 scenario ID·값·trace·cause row를 약화하면 브랜드 회상성이 빠르게 평준화될 수 있다.
- >-
Lab의 progress와 radio rows는 범용 UI다. 후속 콘텐츠에서도 evidence brief와 causal ledger가
지배 위계를 유지해야 현재의 pass가 보존된다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T120840Z.report.yaml
grade: E3
note: "exact target winner id/SHA 및 dist·preview binding"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w1280.png
grade: E3
note: "desktop 비대칭 hero/folio, dual-entry merge, five-step ledger strip 실제 render"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w768.png
grade: E3
note: "tablet single-reading-flow에서도 field-note/ledger signature 유지"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w360.png
grade: E3
note: "mobile에서 값 행·trace·serif/mono hierarchy가 보존된 실제 render"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/app.js
grade: E3
note: "concept relation, symptom clue, shared Lab phase와 causal row의 화면별 구현"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/styles.css
grade: E3
note: "editorial spread, folio/note-ledger, evidence typography 및 responsive 변환 구현"
@@ -0,0 +1,113 @@
report-type: workflow-artifact
artifact-kind: design-lens-review
artifact-version: 1
identity:
artifact-id: DES-VISUAL-20260718T121851Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: DES-VISUAL
created-at: 20260718T121851Z
attempt-id: 4
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
target-prototype-id: ENG-FE-20260718T120840Z
target-prototype-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T120840Z.report.yaml
target-prototype-sha256: 1cfa4ff43762111f46b0088057f6b902375f86856558056aa5f11f117f107267
prototype-path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
prototype-sha256: 5df1bc1ff6ab253fa35d3d0f9c6a373f206d03e59fe4c4c2dbb0cbd2d9494c7c
selected-direction-id: ledger-studio
selected-direction-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-DIRECTOR-20260718T115933Z.report.yaml
selected-direction-sha256: 90b64c99493f1789a134459813207291dfa4beafa794e3f861b4f28d23286a65
reviewer-role-id: DES-VISUAL
reviewer-run-id: hyeonworks-vnext-v1-direction-review-visual-craft-20260718T121347Z
lens: visual-craft
verdict: revise
strengths:
- >-
1280 홈의 비대칭 hero와 ledger folio, 얇은 rule, paper/ink/coral 제한 팔레트는
선택 방향의 편집형 evidence 위계를 선명하게 유지한다.
- >-
360에서 folio의 값·행 정렬은 가로 넘침 없이 보존되고 100·120·70의 숫자 위계도
색에만 의존하지 않고 label과 함께 읽힌다.
findings:
- id: VC-01-lab-boundary-contrast
severity: high
scope: [360, 768, 1280, shared-lab]
finding: >-
Shared Lab의 어두운 brief 안에 놓인 Guided scenario 블록에서 본문이 밝은 베이지
바탕과 거의 같은 명도로 렌더되어 세 viewport 모두 육안 판독이 어렵다.
evidence:
- >-
실제 #/lab/tx-lost-update-01 Chrome 렌더에서 label은 보이지만 경계 설명은
360·768·1280 모두 희미하게 소실된다.
- >-
dist/styles.css의 .lab-brief p { color:#dbe1df }가 밝은
.boundary { background:#e9e2d4 } 내부 p에도 상속되고 .boundary p는 color를
다시 지정하지 않는다.
required-revision: >-
boundary 본문에 명시적인 dark text token을 적용하거나 dark-panel 전용 boundary
변형을 만들고 세 viewport의 실제 Lab 렌더로 다시 확인한다.
- id: VC-02-korean-display-line-breaks
severity: high
scope: [360, 768, 1280, home, shared-lab]
finding: >-
display headline의 폭과 줄바꿈이 한국어 어절을 고려하지 않아 홈에서는 '먼/저'와
'예/측합니다'가, Lab에서는 핵심 구문이 음절 중간에서 끊긴다. 큰 serif 논제가
지배하는 방향인 만큼 이 rag는 의도적 편집 조형보다 미완성 조판으로 보인다.
evidence:
- >-
preview.w360.png, preview.w768.png, preview.w1280.png 모두 홈 제목의 동일한
어절 중간 분리를 보여준다.
- >-
dist/styles.css가 h1에 max-width:10ch와 line-height:.88을, .lab-brief h1에
max-width:9ch를 적용하지만 한국어 keep-all 또는 제어된 line break를 두지 않는다.
required-revision: >-
의미 단위 span/br 또는 word-break:keep-all과 viewport별 폭·크기 조합으로 headline
rag를 직접 설계하고 홈·orientation·Lab 제목을 360/768/1280에서 재검수한다.
- id: VC-03-tablet-density-collapse
severity: medium
scope: [768, home, shared-lab]
finding: >-
850px breakpoint 하나가 hero, learning loop, Lab progress를 모두 단일 열로 바꾸어
768에서는 넓은 빈 가로 공간과 과도하게 긴 5행 progress가 생긴다. 360의 안전한
reflow와 1280의 편집 밀도 사이에 tablet 전용 조정이 없다.
evidence:
- >-
preview.w768.png에서 hero thesis와 folio가 긴 단일 흐름으로 분리되고 entry까지의
vertical rhythm이 급격히 늘어난다.
- >-
실제 768 Lab 렌더에서 5단계 progress가 각 한 줄 전체 폭을 점유하지만 동일 요소는
1280에서 압축된 5열 strip으로 읽힌다.
required-revision: >-
home hero와 loop, Lab progress에 서로 다른 tablet breakpoint/column 규칙을 두어
768의 가로 면적과 scan rhythm을 회복한다.
report-header:
bottom-line: >-
revise — Ledger Studio의 1280 편집 위계와 제한 팔레트는 강하지만, Shared Lab 경계문이
세 viewport에서 사실상 사라지고 한국어 display가 어절 중간에서 끊기며 768 구성이 너무 일찍
단일 열로 붕괴한다. 방향 재선택 없이 조판·색 cascade·tablet breakpoint 수정이 필요하다.
decision-needed: { needed: false, approver: null }
confidence: { value: Med, derived-from: evidence }
risks:
- >-
기존 render-health의 css-contrast pass가 Lab 내부 상속 cascade로 생긴 실제 저대비를
포착하지 못했으므로 수정 후 상태별 픽셀 검수가 필요하다.
- >-
저장된 세 preview는 홈만 보여주므로 이후 Observe·Compare·Explain·Transfer 상태의
시각 밀도는 별도 상태 렌더 전까지 미검수 위험으로 남는다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T120840Z.report.yaml
grade: E3
note: "winner artifact id/SHA와 prototype·preview exact binding"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w360.png
grade: E3
note: "360 홈 실제 Chrome 렌더의 hierarchy, type rag, spacing"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w768.png
grade: E3
note: "768 홈 실제 Chrome 렌더의 tablet reflow와 density"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w1280.png
grade: E3
note: "1280 홈 실제 Chrome 렌더의 editorial hierarchy와 palette"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/styles.css
grade: E3
note: "Lab boundary color inheritance, headline width, 850px breakpoint의 직접 근거"
@@ -0,0 +1,132 @@
report-type: workflow-artifact
artifact-kind: design-lens-review
artifact-version: 1
identity:
artifact-id: DES-VISUAL-20260718T131443Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: DES-VISUAL
created-at: 20260718T131443Z
attempt-id: 5
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
target-prototype-id: ENG-FE-20260718T131305Z
target-prototype-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T131305Z.report.yaml
target-prototype-sha256: bcc557fcd7463349345bd06090868c4c2b6b792453d4e1dddd4ac60b0fa68674
reviewer-role-id: DES-VISUAL
reviewer-run-id: 44640b239eaefd6fe05ba540d1fda7cfa90498fef66a896228a1a91d9caa370a
lens: distinctiveness
verdict: pass
assessment:
visual-thesis: >-
Technology Atlas는 시스템 메커니즘 학습을 일반 course catalog나 진단 dashboard가 아니라,
큰 편집 질문에서 가설을 고정하고 scenario ID·수치·실행·인과 증거를 한 ledger로 축적하는 기록물로 표현한다.
internet-average-separation: >-
rounded card grid, gradient hero, icon dashboard, terminal shell 없이 paper/ink/coral 팔레트,
한국어 serif 논제, mono atlas·phase·evidence label, hard rule과 dark scenario brief가 지배 위계를 만든다.
특히 100·120·70, Same Lab, READ/WRITE/Delta evidence가 인쇄물풍 표면을 Lost Update 학습에 결속한다.
recognizable-signature: >-
Technology Atlas by Hyeonworks → topic breadcrumb → Shared Lab scenario ID → Predict/Observe/Compare/Explain/Transfer의
반복 순서가 home, 두 orientation, 다섯 상태에서 같은 회상 구조를 만든다.
cliche-pressure: >-
paper·serif·mono·offset sheet 조합만 보면 익숙한 editorial/brutalist web 관습이다. 현재 화면은 구체적인
causal values와 ledger row, 가설/증거/인과의 상태별 변주가 관습을 제품 고유 문법으로 바꾸므로 수정 게이트는 아니다.
inspected-surfaces:
home:
- {viewport: 360, artifact: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w360.png}
- {viewport: 768, artifact: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w768.png}
- {viewport: 1280, artifact: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w1280.png}
orientations:
- {route: "#/orient/concept", inspected-viewports: [360, 768, 800], bound-artifact: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.state-concept.png}
- {route: "#/orient/symptom", inspected-viewports: [360, 768, 800], bound-artifact: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.state-symptom.png}
lab-states:
- {state: predict, viewports: [360, 1280]}
- {state: compare, viewports: [360, 1280]}
- {state: explain, viewports: [360, 1280]}
- {state: transfer, viewports: [360, 1280]}
- {state: complete, viewports: [360, 1280]}
- {artifact-directory: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews}
findings:
- finding-id: R2-DIST-01
severity: info
screen-area: "home · 360/768/1280 hero, scenario folio, dual-entry merge"
evidence: >-
1280은 초대형 serif 가설 문장과 우측 evidence folio의 비대칭 spread를 만들고, 768은 이를 두 열로
압축하면서도 논제/증거 관계를 보존한다. 360은 Technology Atlas, coral category descriptor,
mono folio와 Initial 100 / Expected 120 / Observed 70을 단일 독서 흐름으로 유지한다.
judgment: >-
첫 화면이 범용 교육 hero나 SaaS 카드 모음으로 읽히지 않고 "가설을 세우고 증거로 설명하는 atlas entry"로 식별된다.
- finding-id: R2-DIST-02
severity: info
screen-area: "concept·symptom orientation · 360/768/800"
evidence: >-
concept는 세 개의 relation ledger row와 학습 질문을, symptom은 흐림 처리된 순차 clue ledger와 현재 판단을
같은 offset sheet 문법으로 변주한다. 실제 360/768 Chrome render에서도 큰 serif 질문→guided boundary→ledger
순서와 Technology Atlas header가 남고, 768에서는 비대칭 두 열을 유지한다.
judgment: >-
두 입구가 단순히 문구만 바꾼 동일 카드가 아니라 관계 정렬과 단서 공개라는 서로 다른 evidence 행위로 구분되면서
동일 브랜드 문법에 합류한다.
- finding-id: R2-DIST-03
severity: info
screen-area: "Shared Lab · predict/compare/explain/transfer/complete, 360 및 1280"
evidence: >-
모든 상태가 dark scenario brief, mono phase rail, serif task headline과 light workbench의 split을 유지한다.
Compare는 hypothesis/value/cause ledger, Explain은 세 evidence 조각 builder, Transfer는 새 수치 대조,
Complete는 core-loop record와 원칙 sheet로 같은 문법을 상태 의미에 맞게 바꾼다. 360에서도 dark ledger가
먼저 앵커가 되고 각 workbench가 이어져 장문의 form stack만으로 익명화되지 않는다.
judgment: >-
고유성이 home art direction에 머물지 않고 핵심 상호작용의 시작·대조·구성·전이·완료까지 제품 문법으로 작동한다.
- finding-id: R2-DIST-04
severity: minor
screen-area: "Shared Lab · Explain/Transfer의 bordered choice rows"
evidence: >-
radio choice와 textarea 자체는 범용 form/courseware primitive이며 360 Explain에서는 긴 세로 비중을 차지한다.
그러나 phase ID, persistent dark evidence brief, explicit read/write/value vocabulary와 causal grouping이
상위 구조를 계속 지배한다.
judgment: >-
현재 exact winner의 고유성을 무너뜨리지는 않는다. 후속 scenario에서 ledger anchor를 줄이고 choice row만
늘리면 인터넷 평균으로 가장 먼저 퇴행할 지점이므로 비차단 위험으로 추적한다.
report-header:
bottom-line: >-
PASS — ENG-FE-20260718T131305Z@bcc557fcd7463349345bd06090868c4c2b6b792453d4e1dddd4ac60b0fa68674는
home 360/768/1280, 두 orientation, 다섯 Lab 상태 360/1280에서 Technology Atlas의
editorial-evidence/causal-ledger 문법을 일관되게 유지하며 일반 SaaS·courseware 화면으로 퇴행하지 않았다.
decision-needed: { needed: false, approver: null }
confidence:
value: Med
derived-from: exact-r2-winner-sha-dist-source-home-orientation-and-ten-bound-state-renders
risks:
- >-
paper·serif·mono·hard rule 조합만 남고 scenario ID·수치·READ/WRITE/Delta row가 약화되면
현재의 고유성은 익숙한 editorial/brutalist template로 평준화될 수 있다.
- >-
360 Explain/Transfer에서 generic choice rows의 세로 비중이 크므로 후속 주제도 dark evidence brief,
phase label과 causal grouping을 지배 위계로 유지해야 한다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T131305Z.report.yaml
grade: E3
note: "exact revision-2 winner id/SHA와 home, route, state preview binding"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w360.png
grade: E3
note: "360 home의 Technology Atlas hierarchy, causal folio, single-column signature"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w768.png
grade: E3
note: "768 home의 비대칭 editorial spread와 entry/loop hierarchy"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w1280.png
grade: E3
note: "1280 home의 hero/folio, dual-entry merge와 five-phase strip"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.state-concept.png
grade: E3
note: "concept orientation의 relation note 실제 render; dist는 360/768에서도 직접 렌더 점검"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.state-symptom.png
grade: E3
note: "symptom orientation의 sequential clue ledger 실제 render; dist는 360/768에서도 직접 렌더 점검"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews
grade: E3
note: "predict/compare/explain/transfer/complete 각 360·1280, 총 10개 exact state render"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/app.js
grade: E3
note: "Technology Atlas, scenario registry, orientation variants와 state별 evidence vocabulary 구현"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/styles.css
grade: E3
note: "editorial/ledger recipes와 360/768/1280 responsive hierarchy 구현"
@@ -0,0 +1,131 @@
report-header:
bottom-line: >-
REVISE — exact winner ENG-FE-20260718T131305Z / sha256
bcc557fcd7463349345bd06090868c4c2b6b792453d4e1dddd4ac60b0fa68674는 편집형 위계,
AA 색 경계, 768px 2열 밀도와 단계별 상태 구분은 출시 방향 수준이지만, 360px Lab 본문에서
한국어 단어가 음절 중간에 반복 절단되어 선언된 Korean keep-all 마감이 아직 닫히지 않았다.
decision-needed: { needed: false, approver: null }
confidence:
value: Med
derived-from: hash-bound-winner-files-render-previews-and-verification-receipts
risks:
- >-
렌더 판정은 receipt에 결속된 Chrome 환경의 캡처 기준이며, 배포 환경의 한국어 fallback font가
달라지면 줄바꿈 위치는 추가로 변할 수 있다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T131305Z.report.yaml
grade: E3
note: >-
exact reviewed winner ENG-FE-20260718T131305Z; file sha256
bcc557fcd7463349345bd06090868c4c2b6b792453d4e1dddd4ac60b0fa68674
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
grade: E3
note: >-
revision 2 manifest sha256 40876a12d2ab842568a76b3c2e2e50f6cd32614914805ecf3c6a00745266958c;
declared Korean keep-all, Lab contrast and tablet-density closure
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews
grade: E3
note: >-
exact predict/compare/explain/transfer/complete renders at 360 and 1280 inspected; 360 body copy
exposes repeated intra-word Korean breaks while hierarchy, spacing and state distinction remain coherent
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/styles.css
grade: E3
note: >-
sha256 62fd9ea7af1fb2710d8497f814502eec1271aff9eeace7214e6d246266967cd6;
keep-all is scoped to heading/serif selectors and loop labels, not Lab body, lead, choice or principle copy
- source-uri: hyeonworks/evidence/ledger.jsonl
grade: E3
note: >-
preview receipt vr-1784380367-51a78e23c06f sha256
6e996418f85040bcf48a9354ad7488d9106e8b094a5f7ce8672a3aa30376b776 and interaction receipt
vr-1784380160-b25beb2fef58 sha256
b5dae4455e6a73ee5801fedc3034bf0b23628bb5e59c1e47576b7ba32d5285fa both passed against source revision
40876a12d2ab842568a76b3c2e2e50f6cd32614914805ecf3c6a00745266958c
report-type: workflow-artifact
artifact-kind: design-lens-review
artifact-version: 1
identity:
artifact-id: DES-VISUAL-20260718T131448Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: DES-VISUAL
created-at: 20260718T131448Z
attempt-id: 6
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
target-prototype-id: ENG-FE-20260718T131305Z
target-prototype-sha256: bcc557fcd7463349345bd06090868c4c2b6b792453d4e1dddd4ac60b0fa68674
reviewer-role-id: DES-VISUAL
reviewer-run-id: d388e8cde4d3a732a077962455b842667dd4c7f2ee00b8222873f86d4790fe9e
lens: visual-craft
verdict: revise
review-context:
context-package-ref: hyeonworks/state/context-packages/hyeonworks-vnext-v1-direction/DES-VISUAL-20260718T131418Z.pkg.yaml
context-package-sha256: d388e8cde4d3a732a077962455b842667dd4c7f2ee00b8222873f86d4790fe9e
selected-direction-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-DIRECTOR-20260718T115933Z.report.yaml
selected-direction-sha256: 90b64c99493f1789a134459813207291dfa4beafa794e3f861b4f28d23286a65
source-prototype-ref: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
source-prototype-sha256: 40876a12d2ab842568a76b3c2e2e50f6cd32614914805ecf3c6a00745266958c
audit-summary:
hierarchy-and-art-direction:
result: pass
basis: >-
360/768/1280 home and 800 route renders preserve the asymmetric editorial spread, serif thesis,
mono evidence annotations and single causal-ledger visual grammar without dashboard or terminal-shell drift.
color-and-boundary:
result: pass
basis: >-
paper/ink/coral/violet/mint roles remain consistent; the dark Lab brief is a clear single boundary,
the static CSS check reports on-deep/deep 11.66:1 and the E2E receipt enforces its runtime ratio at 4.5:1 or higher.
spacing-and-responsive-density:
result: pass
basis: >-
1280 spacing sustains the editorial asymmetry, 768 retains the intended two-column hero and Lab density,
and 360 stacks values, comparisons and controls without horizontal overflow.
interactive-state-polish:
result: pass
basis: >-
current/done progress, disabled controls, selected choices, alert comparisons, success/error feedback and
completion treatment use distinct text, form and color roles; the full interaction receipt passed.
korean-responsive-typography:
result: revise
basis: >-
heading keep-all works, but 360 Lab body, lead, choice and completion copy repeatedly breaks Korean words
inside the word, contradicting the revision-closure claim for Korean typography.
findings:
- id: VC-R2-01
severity: minor-revision
status: open
area: korean-responsive-typography
observation: >-
Exact 360 state renders show repeated intra-word breaks: predict.w360.png breaks “구체/적인” and
“확/인합니다” in the dark Lab brief and “변/화를” in a hypothesis; complete.w360.png breaks
“장/애”, “시나리/오”, “변/화” and “뜻입/니다” in completion copy. Comparable breaks recur in
compare, explain and transfer states.
file-cause: >-
styles.css applies `word-break: keep-all; overflow-wrap: normal` to h1/h2/h3/.serif and keep-all to
.loop-item span, while .lab-brief > p, .workbench .lead, .choice span, .boundary p and .principle p
inherit the browser's Korean intra-word breaking behavior.
impact: >-
The direction remains structurally sound, but narrow-screen reading rhythm and typographic finish fall
below the declared revision-2 closure; this requires a bounded type-rule correction, not a direction redraw.
required-change: >-
Apply a Korean-aware keep-all rule to semantic body copy with a safe fallback for long Latin tokens/IDs,
then regenerate all five 360 Lab state renders and verify zero intra-word Korean breaks and zero horizontal overflow.
evidence:
- path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews/predict.w360.png
sha256: 49e393591fb9d492638715da495538ba2b566ae55e0cb29aad4e582122bd5674
- path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews/compare.w360.png
sha256: 421d991301f0ccc8f7234ee45747ac920e21ab16b83085f57aa201f2e3017160
- path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews/explain.w360.png
sha256: c1d98a5337ba14d89d7e447f45aaaec6535763a7fa8b073eb91330830f467792
- path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews/transfer.w360.png
sha256: a9f747ba9ad76fe170544da647092abd4fb5a8cdd3c899381d7a4578f7552893
- path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews/complete.w360.png
sha256: 5e9b9f9a1852b9506768e0b56480e8edd822f65c5e328335fd187c1ca46c0374
- path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/styles.css
sha256: 62fd9ea7af1fb2710d8497f814502eec1271aff9eeace7214e6d246266967cd6
scope-note: >-
This report judges visual-craft only; it does not issue product-fit, usability, distinctiveness,
market, system or implementation verdicts.
@@ -0,0 +1,96 @@
report-header:
bottom-line: >-
PASS — exact Revision 3는 비대칭 editorial thesis, field-note annotation, causal ledger와
persistent evidence folio를 360/768/1280 및 Predict→Complete 전 상태에서 지배 문법으로 유지한다.
conventional stepper·radio form은 이 문법에 종속되어 있어 generic dashboard나 terminal shell로의
회귀를 만들지 않으며, 두 진입점은 SAME LAB 표식과 동일 shared-core ledger로 명시적으로 수렴한다.
decision-needed: {needed: false, approver: null}
confidence: {value: Med, derived-from: exact-hash-bound-renders-and-independent-distinctiveness-review}
risks:
- >-
Lab의 progress strip과 radio/form controls 자체는 관습적이다. 향후 persistent dark ledger,
serif 논제, mono evidence annotation 중 하나라도 제거되면 학습 wizard나 dashboard로 희석될 수 있다.
- >-
이 판정은 제공된 exact render와 구조에 대한 distinctiveness 감사이며 외부 시장 비교나
사용자 기억 효과를 주장하지 않는다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T135811Z.report.yaml
grade: E3
note: >-
live SHA256 735d588bef412dd3c59899d393562ae76a67a55bbe9f507ddf38eeab1481e9f0;
revision 3 manifest가 core-flow와 360/768/1280 render를 exact hash로 결속한다.
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-DIRECTOR-20260718T115933Z.report.yaml
grade: E3
note: >-
live SHA256 90b64c99493f1789a134459813207291dfa4beafa794e3f861b4f28d23286a65;
editorial evidence와 dual-entry shared core를 distinctiveness 기준으로 잠근 selected direction이다.
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
grade: E3
note: >-
live SHA256 bd2bf67bddde92ae4fa0d329bd21e078625aa343ba59b78fec75f248111d22a1;
SAME LAB convergence와 Predict→Observe→Compare→Explain→Transfer shared-core 구조를 명시한다.
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w1280.png
grade: E3
note: >-
large serif thesis, asymmetric ledger specimen, twin entry spread와 SAME LAB bridge가
dashboard card grid보다 editorial evidence hierarchy를 우선한다.
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w768.png
grade: E3
note: >-
tablet에서도 thesis/ledger 비대칭과 two-entry convergence가 유지된다.
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w360.png
grade: E3
note: >-
mobile stack에서도 serif thesis, receipt-like ledger와 entry framing이 보존되어 generic card feed로 평탄화되지 않는다.
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews
grade: E3
note: >-
Predict·Observe·Compare·Explain·Transfer·Complete의 360/1280 12개 render 모두에서
dark evidence folio, serif task thesis, mono labels/numerals와 rule-based ledger가 지속된다.
report-type: workflow-artifact
artifact-kind: design-lens-review
artifact-version: 1
identity:
artifact-id: DES-VISUAL-20260718T140000Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: DES-VISUAL
created-at: 20260718T140000Z
attempt-id: 3
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
target-prototype-id: ENG-FE-20260718T135811Z
target-prototype-sha256: 735d588bef412dd3c59899d393562ae76a67a55bbe9f507ddf38eeab1481e9f0
reviewer-role-id: DES-VISUAL
reviewer-run-id: 5164a2f325b97d437c17cff56ba421620b35ad25d4bde2bf00fb63b896b5db1c
lens: distinctiveness
verdict: pass
review-context:
context-package-ref: hyeonworks/state/context-packages/hyeonworks-vnext-v1-direction/DES-VISUAL-20260718T135945Z.pkg.yaml
context-package-sha256: 5164a2f325b97d437c17cff56ba421620b35ad25d4bde2bf00fb63b896b5db1c
previous-lens-reviews-read: false
findings:
- finding-id: DIST-R3-01
severity: pass
claim: "editorial evidence grammar remains dominant"
evidence: >-
Landing renders pair the oversized Korean serif question with an asymmetric receipt-like causal ledger,
mono field-note labels, sparse rules and a single coral observed-value accent; no navigation rail,
metric-card grid, chart chrome or terminal prompt becomes the organizing shell.
disposition: pass
- finding-id: DIST-R3-02
severity: pass
claim: "two-entry convergence is visually explicit"
evidence: >-
Concept and Symptom are framed as parallel starts, joined by the SAME LAB · TX-LOST-UPDATE-01 bridge;
every Lab state repeats SHARED CORE/SHARED LAB and the same ledger identity rather than branching into
visually separate products.
disposition: pass
- finding-id: DIST-R3-03
severity: watch
claim: "conventional interaction controls stay subordinate"
evidence: >-
The progress strip, native table and radio choices use familiar patterns, but across all twelve state renders
they sit under the persistent dark evidence folio, serif task thesis, mono evidence labels and ledger rules.
Their presence does not currently overturn the selected visual grammar.
disposition: no-revision-required
@@ -0,0 +1,143 @@
report-header:
bottom-line: >-
revise — exact R3 target ENG-FE-20260718T135811Z는 360px Lab의 한국어 어절 보존과
내부 스크롤 containment, 768/1280의 편집 위계와 상태 구분을 실제 렌더에서 유지한다.
그러나 dark Lab의 소형 coral 라벨이 3.18:1 및 2.50:1, Observe의 pending 텍스트가
4.24:1, 입력 경계가 2.33:1에 머물러 inherited AA boundary를 닫지 못했으므로
token-level contrast 보정 후 재확인이 필요하다.
decision-needed: {needed: false, approver: null}
confidence:
value: Med
derived-from: exact-sha-bound-css-and-360-768-1280-state-render-inspection
risks:
- >-
정적 state previews는 hover·focus·error 조합을 모두 포착하지 않는다. focus-visible 규칙은
CSS에서 확인했지만 제품별 실제 브라우저/디스플레이의 시각 편차까지 주장하지 않는다.
- >-
fixture는 긴 Latin token의 안전한 줄바꿈과 shared visual recipe 경계 확인용이며,
공개 콘텐츠 품질이나 사용자 학습 효과의 근거로 사용하지 않았다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T135811Z.report.yaml
grade: E3
note: >-
exact target SHA 735d588bef412dd3c59899d393562ae76a67a55bbe9f507ddf38eeab1481e9f0와
hash-bound 360/768/1280 preview 및 route/state manifest를 대조했다.
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews
grade: E3
note: >-
Predict·Observe·Compare·Explain·Transfer·Complete의 360/1280 실제 렌더에서
위계, 한국어 어절, active/done/current/disabled 상태와 overflow를 독립 시각 검토했다.
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/styles.css
grade: E3
note: >-
실제 렌더에 적용된 type, breakpoint, min-width/overflow, deep/on-deep, focus 및
state selector를 확인하고 선언 색상으로 대비비를 계산했다.
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.state-fixture.png
grade: E3
note: >-
별도 fixture 렌더에서 Lab recipe 유지와 unbroken Latin token containment를 확인했다.
report-type: workflow-artifact
artifact-kind: design-lens-review
artifact-version: 1
identity:
artifact-id: DES-VISUAL-20260718T140005Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: DES-VISUAL
created-at: 20260718T140005Z
attempt-id: 3
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
target-prototype-id: ENG-FE-20260718T135811Z
target-prototype-sha256: 735d588bef412dd3c59899d393562ae76a67a55bbe9f507ddf38eeab1481e9f0
target-prototype-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T135811Z.report.yaml
exact-target:
artifact-id: ENG-FE-20260718T135811Z
artifact-sha256: 735d588bef412dd3c59899d393562ae76a67a55bbe9f507ddf38eeab1481e9f0
reviewer-role-id: DES-VISUAL
reviewer-run-id: f5394225114da0620b2ba325651b249910844e048a2c55f1da9e1f8b4406f012
context-package-ref: hyeonworks/state/context-packages/hyeonworks-vnext-v1-direction/DES-VISUAL-20260718T135952Z.pkg.yaml
context-package-sha256: f5394225114da0620b2ba325651b249910844e048a2c55f1da9e1f8b4406f012
lens: visual-craft
verdict: revise
scope-boundary: >-
visual-craft만 판정했다. 이전 lens review와 다른 lens 결론은 읽거나 재사용하지 않았고,
prototype은 수정하지 않았다.
acceptance-assessment:
- criterion: 360px Lab Korean word integrity
result: pass
evidence: >-
여섯 state의 semantic heading, lead, choice, causal row, feedback 및 boundary 문구가
어절 단위로 줄바꿈된다. 긴 Latin fixture token만 overflow-wrap:anywhere fallback으로
안전하게 감싸며 한국어 음절 중간 분할은 관찰되지 않았다.
- criterion: 360px contained layout
result: pass
evidence: >-
lab-grid/workbench/trace-scroll의 min-width:0 및 max-width:100% 경계가 유지되고,
560px native trace table은 문서 폭을 넓히지 않은 채 trace-scroll 내부에서만 잘린다.
360 state renders에도 우측 clip이나 document-level overflow 징후가 없다.
- criterion: 768/1280 hierarchy
result: pass
evidence: >-
768은 editorial hero·folio와 두 entry를 두 열로 유지하고, 701900px Lab은 brief/workbench와
5-column progress를 보존한다. 1280에서는 논제→evidence sheet→entry/loop 및
Lab brief→workbench의 읽기 우선순위가 크기·여백·stroke로 명료하다.
- criterion: contrast and state polish
result: revise
evidence: >-
current/done/observed/feedback/focus의 형태·텍스트 중복 표시는 명료하지만,
아래 두 contrast finding이 AA boundary와 state legibility를 충족하지 못한다.
strengths:
- >-
360의 단일 열 전환은 dark brief와 light workbench를 명확히 분리하면서 모든 state에서
동일한 인과 ledger 시각 문법을 유지한다.
- >-
768/1280은 serif 논제, mono evidence annotation, 얇은 rule과 비대칭 여백의 위계가
일반 카드 dashboard로 무너지지 않고 선택된 editorial-evidence 방향을 보존한다.
- >-
active progress는 dark fill, 완료 단계는 check+success color, 관찰값은 coral+숫자로
중복 부호화되어 색만으로 상태를 전달하지 않는다.
findings:
- id: VC-R3-01
severity: major
status: open
title: Dark Lab의 소형 coral 라벨 대비가 AA boundary 아래다
observation: >-
.lab-id는 0.68rem/800의 #b94735를 .lab-brief #17201f 위에 사용해 3.18:1이고,
.lab-brief .boundary b는 같은 #b94735를 #283330 위에 사용해 2.50:1이다.
두 라벨은 360/1280 모든 Lab state의 scenario identity와 guided boundary를 표시하지만
small text 기준 4.5:1에 미달하고 실제 dark render에서도 주변 on-deep copy보다 현저히 흐리다.
evidence:
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/styles.css
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews/predict.w360.png
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews/complete.w1280.png
required-change: >-
coral의 의미는 유지하되 dark surface 전용 accent token을 도입해 두 조합을 4.5:1 이상으로
올리고, 360/1280의 predict와 complete에서 scenario id 및 GUIDED SCENARIO 라벨을 재확인한다.
acceptance-test: >-
computed foreground/background contrast >= 4.5:1 for .lab-id on .lab-brief and
.lab-brief .boundary b on .lab-brief .boundary in the exact rerender.
- id: VC-R3-02
severity: moderate
status: open
title: Pending trace와 form boundary의 저대비가 상태 판독을 약화한다
observation: >-
.trace-event.pending의 #737c78은 sheet #fffdfa 위에서 4.24:1로 4.5:1에 못 미친다.
또한 choice/textarea에 공통 사용된 1px --rule #aaa99f는 #fffdfa 위에서 2.33:1이라
Explain의 입력 영역과 Observe의 아직 실행되지 않은 행을 빠르게 구분하기 어렵다.
disabled CTA의 의도적 약화와 달리 pending 설명과 textarea 경계는 내용을 읽고 입력 위치를
식별하는 데 필요한 활성 정보다.
evidence:
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/styles.css
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews/observe.w360.png
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews/explain.w360.png
required-change: >-
pending text를 4.5:1 이상으로 조정하고, 입력/선택 control의 식별 경계는 주변 sheet와
3:1 이상이 되도록 별도 control-border token을 사용한다. decorative rule은 기존 명도를 유지해도 된다.
acceptance-test: >-
pending text contrast >= 4.5:1 and essential choice/textarea boundary contrast >= 3:1
in Observe and Explain at 360 and 1280, without collapsing pending/current distinction.
release-condition: >-
VC-R3-01과 VC-R3-02의 token-level contrast를 보정하고 exact target의 360/1280 Lab state를
다시 렌더해 비율과 상태 위계를 확인하면 visual-craft 재검토 가능하다.
@@ -0,0 +1,80 @@
report-type: workflow-artifact
artifact-kind: design-lens-review
artifact-version: 1
identity:
artifact-id: DES-VISUAL-20260718T145000Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: DES-VISUAL
created-at: 20260718T145000Z
attempt-id: 8
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
review-lens: distinctiveness
target-artifact-id: ENG-FE-20260718T144700Z
target-artifact-sha256: 8b208279e12f9aea0fa6d7a3c320811b0e72ddb74c6afac64cddadf4b157cf76
target-prototype-id: ENG-FE-20260718T144700Z
target-prototype-sha256: 8b208279e12f9aea0fa6d7a3c320811b0e72ddb74c6afac64cddadf4b157cf76
reviewer-role-id: DES-VISUAL
lens: distinctiveness
reviewer-run-id: aaa1e28340e08054588d1e93f3774136fe9ffe6f350b48afb3d060229f98447a
verdict: pass
summary: >-
R4는 일반 강의 카드·코스 목차·터미널 또는 대시보드의 문법이 아니라, 편집 논제와
dark shared Lab, mono causal ledger, coral observed value를 하나의 반복 가능한 시각 문법으로
결속한다. 홈의 100·120·70 증거 표지부터 PredictComplete의 모든 상태까지 같은 문법이
역할을 바꾸며 이어져 Technology Atlas만의 식별 가능한 학습 표면을 만든다.
distinctive-signals:
- id: DST-R4-01
signal: "대형 한국어 serif 논제와 좁은 mono evidence annotation의 의도적인 대비"
evidence: "preview.w1280.png와 preview.w360.png에서 브랜드 약속과 100·120·70 ledger가 첫 인상을 공동 소유한다."
judgment: ownable
- id: DST-R4-02
signal: "dark shared Lab을 고정 증거 척추로 두고 밝은 작업지를 상태별로 교체하는 구조"
evidence: "predict/observe/compare/explain/transfer/complete의 360·1280 이미지 모두 같은 Lab 표지를 유지한다."
judgment: ownable
- id: DST-R4-03
signal: "관찰값 coral, 인과 단계의 번호, native-looking ledger rule이 만드는 evidence grammar"
evidence: "Observe의 실행 ledger, Compare의 세 증거 행, Complete의 전이 제안이 같은 시각 어휘로 연결된다."
judgment: ownable
- id: DST-R4-04
signal: "두 진입점을 하나의 scenario/Lab으로 수렴시키는 editorial spread"
evidence: "홈 1280에서 양분된 두 entry가 SAME LAB 띠와 5단계 evidence loop로 수렴하며 일반 course catalog와 구분된다."
judgment: ownable
generic-template-collision-check:
course-card-grid: absent
video-lesson-shell: absent
terminal-pastiche: absent
monitoring-dashboard: absent
generic-saas-card-stack: absent
residual-convention: >-
단계 탭, radio 선택지, 사각 작업지는 익숙한 control이지만 dark Lab과 causal ledger의
종속 요소로 쓰여 지배 문법을 일반 학습 템플릿으로 되돌리지 않는다.
responsive-recall-check:
wide: "1280에서는 editorial thesis와 evidence sheet의 비대칭 spread가 즉시 인식된다."
narrow: "360에서는 동일한 serif/mono/coral/dark-Lab 어휘를 단일 열로 재배열해 식별성이 보존된다."
state-continuity: "6개 학습 상태 모두 증거 척추와 단계 표식을 유지해 화면별 브랜드 단절이 없다."
findings: []
report-header:
bottom-line: >-
PASS — R4의 editorial-evidence grammar는 360·1280과 여섯 학습 상태에서 일관되게 회상되며,
generic learning template와 구분되는 ownable한 Technology Atlas 표면이다.
decision-needed: {needed: false, approver: null}
confidence: {value: Med, derived-from: independent-exact-r4-responsive-and-six-state-image-inspection}
risks:
- >-
후속 주제에서 dark shared Lab, serif thesis, mono ledger, coral observed value 중 일부만
선택적으로 사용하면 현재의 식별성이 일반 editorial template로 희석될 수 있다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T144700Z.report.yaml
grade: E3
note: "exact winner SHA 8b208279e12f9aea0fa6d7a3c320811b0e72ddb74c6afac64cddadf4b157cf76"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w1280.png
grade: E3
note: "wide home SHA f1b3918774289e2a2353ba4fc2d5deb6d6001777fef30ea83da7126df45cabd7"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w360.png
grade: E3
note: "narrow home SHA db1af7ce77da4a9780a08ef4ad812485476f8ba5a6e3f3820a7c5d188356528a"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews
grade: E3
note: "predict, observe, compare, explain, transfer, complete at 360 and 1280 independently inspected"
@@ -0,0 +1,76 @@
report-type: workflow-artifact
artifact-kind: design-lens-review
artifact-version: 1
identity:
artifact-id: DES-VISUAL-20260718T145005Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: DES-VISUAL
created-at: 20260718T145005Z
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
target-prototype-id: ENG-FE-20260718T144700Z
target-prototype-sha256: 8b208279e12f9aea0fa6d7a3c320811b0e72ddb74c6afac64cddadf4b157cf76
reviewer-role-id: DES-VISUAL
reviewer-run-id: b81c982521b4fbc7e8acf73d84502d1dd84b4d081cfa5be74863decbb0d6ae61
lens: visual-craft
verdict: pass
findings:
- finding-id: VC-R4-P01
severity: informational
blocking: false
status: passed
summary: >-
실제 배경을 따라 계산한 작은 텍스트 대비가 모두 AA를 충족한다. Lab ID는
#ff8873/#17201f에서 7.14:1, dark boundary label은 #ff8873/#283330에서
5.62:1, 현재 peach 행까지 포함한 pending text 최솟값은 5.44:1이다.
light coral도 paper에서 5.24:1, sheet에서 5.82:1로 작은 라벨 기준을 넘는다.
evidence:
- "Chrome computed style 재측정: labId 7.1437, boundaryLabel 5.6157, pendingMin 5.4403"
- "CSS 토큰 대조: --coral #ad4031, --accent-on-deep #ff8873, --pending #535c58"
- finding-id: VC-R4-P02
severity: informational
blocking: false
status: passed
summary: >-
필수 입력 경계가 장식용 rule과 분리되어 있다. choice와 textarea의
#88877e/#fffdfa 계산 대비는 각각 3.56:1로 비텍스트 UI 경계 3:1 기준을 넘고,
focus-visible은 별도의 3px focus token으로 식별된다.
evidence:
- "Chrome computed style 재측정: choiceMin 3.5575, textareaMin 3.5575"
- "styles.css: --control-border와 :focus-visible의 독립 계약"
- finding-id: VC-R4-P03
severity: informational
blocking: false
status: passed
summary: >-
360·768·1280 실제 렌더에서 cream/ink/coral/violet 팔레트와 serif display,
mono evidence label, sans body의 계층이 일관된다. 360은 명료한 단일 열,
768과 1280은 Lab brief/workbench의 편집적 2열 밀도를 유지하며, Predict부터
Complete까지 상태 강조·완료 표식·증거 표의 리듬에 충돌이나 문서 폭 넘침이 없다.
evidence:
- "preview.w360.png, preview.w768.png, preview.w1280.png 육안 대조"
- "state-previews의 Predict/Observe/Compare/Explain/Transfer/Complete 360·1280 전수 대조"
- "임시 복제본 Chrome 재실행: tablet two-column, Korean word integrity, internal table scroll, document overflow 단언 통과"
report-header:
bottom-line: >-
PASS. R4는 실제 배경 기준의 작은 텍스트·필수 컨트롤 대비를 수치로 충족하고,
360·768·1280 및 여섯 학습 상태에서 편집적 위계와 반응형 완성도를 안정적으로 유지한다.
decision-needed: {needed: false, approver: null}
confidence: {value: Med, derived-from: exact-winner-hash-static-token-audit-full-state-image-review-and-fresh-chrome-rerun}
risks:
- Linux Chrome과 현재 serif fallback에서 검토했으므로 Safari·Windows의 다른 한글 font metrics는 후속 production QA에서 재확인해야 한다.
- 상태 스냅샷은 360·1280 전수를 보존하고 768은 실제 Lab 렌더와 브라우저 단언으로 확인했지만, 모든 hover·오답 feedback 조합의 별도 시각 스냅샷까지 보존한 것은 아니다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T144700Z.report.yaml
grade: E3
note: "exact winner SHA 8b208279…와 revision-4 receipt/closure 결속 대조"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/styles.css
grade: E3
note: "exact CSS SHA 71e51b90…; computed color/control-token audit"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/scripts/verify_flow.cjs
grade: E3
note: "exact script SHA a0910543…를 임시 복제본에서 재실행해 computed contrast와 responsive browser assertions 통과"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews
grade: E3
note: "Predict부터 Complete까지 360·1280 상태 이미지 전수 육안 검토"
@@ -0,0 +1,59 @@
report-type: workflow-artifact
artifact-kind: winner-prototype
artifact-version: 1
identity:
artifact-id: ENG-FE-20260718T120840Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-prototype
producer-role-id: ENG-FE
created-at: 20260718T120840Z
attempt-id: 1
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
selected-direction-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-DIRECTOR-20260718T115933Z.report.yaml
selected-direction-sha256: 90b64c99493f1789a134459813207291dfa4beafa794e3f861b4f28d23286a65
source-artifact-refs:
- artifact-id: DES-DIRECTOR-20260718T115933Z
artifact-sha256: 90b64c99493f1789a134459813207291dfa4beafa794e3f861b4f28d23286a65
prototype-path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
prototype-sha256: 5df1bc1ff6ab253fa35d3d0f9c6a373f206d03e59fe4c4c2dbb0cbd2d9494c7c
preview-receipt-ref: vr-1784376508-cab84b212040
preview-receipt-sha256: 7e30d89efcc4798134d23976b321d591a79f540a9689a8a677785618862ff996
revision: 1
preview-shots:
- {viewport: 360, path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w360.png, sha256: ee18b5109276328285b606bbdcc27f6dcbbe970187a69e6f07d1e0cf2502900e}
- {viewport: 768, path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w768.png, sha256: fa19f6b9677a5203c7539555287201a825f82a71572a8a61fe8f8065601b6f4c}
- {viewport: 1280, path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w1280.png, sha256: 68e20861bfe87f34ed3da17d9a1da47a593d9d2391478cd2c06ce12668c7bf00}
core-flow:
- "홈에서 두 입구와 하나의 Lost Update Lab, 활성 범위와 교육 경계를 이해한다."
- "개념 entry에서 Concurrency→Isolation→Lost Update 관계를 정리한다."
- "증상 entry에서 기대 120·관찰 70·동시 실행·같은 100 read 단서를 순차 공개한다."
- "두 entry가 동일 #/lab/tx-lost-update-01과 동일 initialLabState로 합류한다."
- "Predict→6-step Observe→Compare→Explain→Transfer를 하나의 pure reducer로 완주한다."
- "Reset으로 어느 상태에서든 결정론적 초기 상태로 돌아간다."
implemented-invariants:
- LI-EDITORIAL-EVIDENCE
- LI-DUAL-ENTRY-SHARED-CORE
- LI-EVIDENCE-LEARNING-LOOP
- LI-HONEST-BOUNDARY
- LI-ACCESSIBLE-READING
implementation-boundary:
- "교육용 고정 시나리오이며 실제 DB·로그·네트워크에 연결하지 않음"
- "React 생산 구현 전의 browser-local coded prototype"
- "학습 효과·사용자 이해도를 자동 검증했다고 주장하지 않음"
report-header:
bottom-line: >-
Ledger Studio의 잠긴 불변식을 홈·두 orientation·단일 Lost Update Lab·5단계 완주 흐름으로 확장했다.
실제 DOM과 360/768/1280 Chrome 렌더, CSS 대비와 focus-visible 게이트를 통과했다.
decision-needed: { needed: false, approver: null }
confidence: { value: Med, derived-from: selected-direction-hash-and-live-render-receipt }
risks:
- "프로토타입 상호작용은 실제 브라우저 전체 키보드 E2E와 screen-reader 수동 검토 전이다."
- "최종 React 구현은 부모 spec의 acceptance criteria와 다시 결속해야 한다."
evidence:
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w1280.png
grade: E3
note: "선택된 방향의 실제 데스크톱 렌더"
- source-uri: hyeonworks/evidence/ledger.jsonl
grade: E3
note: "vr-1784376508-cab84b212040: DOM 및 360/768/1280 render-health pass"
@@ -0,0 +1,76 @@
report-type: workflow-artifact
artifact-kind: design-lens-review
artifact-version: 1
identity:
artifact-id: ENG-FE-20260718T121851Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: ENG-FE
created-at: 20260718T121851Z
attempt-id: 2
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
target-prototype-id: ENG-FE-20260718T120840Z
target-prototype-sha256: 1cfa4ff43762111f46b0088057f6b902375f86856558056aa5f11f117f107267
reviewer-role-id: ENG-FE
reviewer-run-id: 4b99a5f4d221f1fcf996194fa0c3e799311b102da9e544e518fb0b83693f5375
lens: implementability
verdict: revise
findings:
- finding-id: IMP-01
severity: major
area: "dist/app.js — production handoff boundary"
finding: >-
브라우저 로컬·무의존 prototype으로는 구현 가능성이 높지만, scenario data, reducer, hash router,
HTML template, focus management가 단일 app.js에 결합되어 product code로 그대로 이관하면 변경 영향과
회귀 지점을 격리하기 어렵다.
evidence: >-
app.js는 pure learningReducer와 네 hash route를 제공해 서버/API 없이 실행되지만, 모든 phase view와
event binding을 같은 파일의 전역 labState·innerHTML re-render에 연결한다.
required-revision: >-
production handoff 전에 scenario registry, pure reducer, route/view layer를 최소 모듈로 분리하고 reducer
transition 및 두 entry의 same-core 합류를 자동 테스트한다. 상태 라이브러리나 backend는 추가하지 않는다.
- finding-id: IMP-02
severity: major
area: "interactive verification and accessibility behavior"
finding: >-
preview receipt는 build·DOM·세 viewport·정적 focus/contrast를 확인하지만 실제 라디오 선택, 6단계 trace,
오답 수정, reset의 keyboard focus와 live feedback을 자동 검증하지 않는다. 현재 전체 re-render 방식은
구현은 단순하나 상태별 접근성 회귀를 만들 수 있다.
evidence: >-
app.js의 dispatch는 selection에도 전체 render를 실행하고 preserveFocus는 advance 버튼 하나만 찾는다.
feedback div에는 live-region semantic이 없고 submitted flag는 선택 변경 때 초기화되지 않는다.
required-revision: >-
action별 focus target과 live feedback contract를 구현하고, causal Predict→6-step Observe→Compare→constructed
Explain→Transfer→Complete 및 reset을 실제 Chrome E2E로 검증한다.
- finding-id: IMP-03
severity: strength
area: "delivery complexity and runtime boundary"
finding: >-
정적 index/CSS/ES module, 결정론적 reducer, network·storage·randomness 부재, 명시적 guided-scenario 경계는
초기 릴리스의 빌드·호스팅·디버깅 복잡성을 낮춘다. 수정은 방향 재선택이나 backend 도입 없이 가능하다.
evidence: >-
prototype은 dist 세 파일로 실행되고 scenario schedule과 guarded actions만으로 결과를 재현하며
360/768/1280 preview receipt가 존재한다.
report-header:
bottom-line: >-
REVISE — 정적·결정론적 구조라 구현 자체는 단순하지만, product code 이관 전 scenario/reducer/view 경계를
최소 모듈로 분리하고 실제 상호작용·키보드 E2E를 추가해야 품질을 증명할 수 있다.
decision-needed: { needed: false, approver: null }
confidence: { value: Med, derived-from: exact-winner-source-receipt-and-three-viewport-inspection }
risks:
- "단일 innerHTML re-render 구조를 그대로 확장하면 focus와 submitted state 회귀가 phase 추가 때 반복될 수 있다."
- "이 평가는 구현 가능성 감사이며 실제 학습 효과나 production 배포 성능을 주장하지 않는다."
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T120840Z.report.yaml
grade: E3
note: "exact winner id/SHA, prototype and preview receipt binding"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/app.js
grade: E3
note: "scenario, reducer, route, render, focus and feedback implementation inspected"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
grade: E3
note: "deterministic boundary and declared shared-core contract"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w360.png
grade: E3
note: "mobile render evidence; 768 and 1280 bound previews also inspected"
@@ -0,0 +1,65 @@
report-type: workflow-artifact
artifact-kind: winner-prototype
artifact-version: 1
identity:
artifact-id: ENG-FE-20260718T131048Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-prototype
producer-role-id: ENG-FE
created-at: 20260718T131048Z
attempt-id: 3
supersedes-report-id: ENG-FE-20260718T120840Z
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
selected-direction-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-DIRECTOR-20260718T115933Z.report.yaml
selected-direction-sha256: 90b64c99493f1789a134459813207291dfa4beafa794e3f861b4f28d23286a65
source-artifact-refs:
- artifact-id: DES-DIRECTOR-20260718T115933Z
artifact-sha256: 90b64c99493f1789a134459813207291dfa4beafa794e3f861b4f28d23286a65
- artifact-id: DES-DIRECTOR-20260718T124159Z
artifact-sha256: cfdf252bcf10777a79558fa261bc4ecef9cd4d3f007fb2702ead2b1aea18a141
prototype-path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
prototype-sha256: 40876a12d2ab842568a76b3c2e2e50f6cd32614914805ecf3c6a00745266958c
preview-receipt-ref: vr-1784380200-287125ca8f22
preview-receipt-sha256: 177fce3fe9079da9a5a705ac0fb089330be554862687c36a26833297cfcd1ada
interaction-receipt-ref: vr-1784380160-b25beb2fef58
interaction-receipt-sha256: b5dae4455e6a73ee5801fedc3034bf0b23628bb5e59c1e47576b7ba32d5285fa
revision: 2
preview-shots:
- {viewport: 360, path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w360.png, sha256: 0dcfc9446659c936dbd7ccfb9943ae79c3e12abad5431482ced6a99eb74bc444}
- {viewport: 768, path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w768.png, sha256: 5de39c29fc6ad908852ff8e4f0fc36aa5d354b56fa77c609881795dfb5c7bc83}
- {viewport: 1280, path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w1280.png, sha256: 315eaa89dfe4d65b279196448f7864b621d4a426982093f16118eb9c2138b88b}
state-preview-directory: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews
revision-closure:
learning-evidence: "causal hypothesis Predict and three-part constructed Explain"
accessibility: "focus restoration, role=status feedback, native trace table, AA Lab boundary"
responsive-craft: "Korean keep-all typography, mobile entry jump, tablet two-column density"
market-hierarchy: "Technology Atlas canonical name and developer mechanism Lab descriptor"
system-boundary: "scenario registry, registry-driven copy/state, tokenized editorial recipes"
verification: "full Chrome E2E plus home/route/state renders"
implemented-invariants:
- LI-EDITORIAL-EVIDENCE
- LI-DUAL-ENTRY-SHARED-CORE
- LI-EVIDENCE-LEARNING-LOOP
- LI-HONEST-BOUNDARY
- LI-ACCESSIBLE-READING
report-header:
bottom-line: >-
Ledger Studio revision 2가 1차 panel의 minor-revision 항목을 원인 가설 Predict, 구성형 Explain,
접근성 focus/feedback/table, 한국어·tablet craft, Technology Atlas hierarchy, registry/token 경계로 닫았다.
실제 Chrome에서 전체 학습 흐름과 360/768/1280·상태별 렌더를 통과했다.
decision-needed: { needed: false, approver: null }
confidence: { value: Med, derived-from: hash-bound-panel-closure-live-render-and-browser-e2e }
risks:
- "전문가·자동 검증 결과이며 실제 학습자 효과나 screen-reader별 발화 차이는 아직 주장하지 않는다."
- "현재 registry에는 의도적으로 활성 주제 하나만 있으며 두 번째 주제 추가 전 schema compatibility를 다시 확인한다."
evidence:
- source-uri: hyeonworks/evidence/ledger.jsonl
grade: E3
note: "vr-1784380160-b25beb2fef58 full browser flow pass; vr-1784380200-287125ca8f22 DOM and responsive route render pass"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews
grade: E3
note: "Predict, Compare, Explain, Transfer, Complete at 360 and 1280"
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-DIRECTOR-20260718T124159Z.report.yaml
grade: E3
note: "exact minor-revision panel and required-revision trace"
@@ -0,0 +1,51 @@
report-type: workflow-artifact
artifact-kind: winner-prototype
artifact-version: 1
identity:
artifact-id: ENG-FE-20260718T131305Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-prototype
producer-role-id: ENG-FE
created-at: 20260718T131305Z
attempt-id: 4
supersedes-report-id: ENG-FE-20260718T131048Z
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
selected-direction-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-DIRECTOR-20260718T115933Z.report.yaml
selected-direction-sha256: 90b64c99493f1789a134459813207291dfa4beafa794e3f861b4f28d23286a65
source-artifact-refs:
- {artifact-id: DES-DIRECTOR-20260718T115933Z, artifact-sha256: 90b64c99493f1789a134459813207291dfa4beafa794e3f861b4f28d23286a65}
- {artifact-id: DES-DIRECTOR-20260718T124159Z, artifact-sha256: cfdf252bcf10777a79558fa261bc4ecef9cd4d3f007fb2702ead2b1aea18a141}
prototype-path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
prototype-sha256: 40876a12d2ab842568a76b3c2e2e50f6cd32614914805ecf3c6a00745266958c
preview-receipt-ref: vr-1784380367-51a78e23c06f
preview-receipt-sha256: 6e996418f85040bcf48a9354ad7488d9106e8b094a5f7ce8672a3aa30376b776
interaction-receipt-ref: vr-1784380160-b25beb2fef58
interaction-receipt-sha256: b5dae4455e6a73ee5801fedc3034bf0b23628bb5e59c1e47576b7ba32d5285fa
revision: 2
preview-shots:
- {viewport: 360, path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w360.png, sha256: 0dcfc9446659c936dbd7ccfb9943ae79c3e12abad5431482ced6a99eb74bc444}
- {viewport: 768, path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w768.png, sha256: 5de39c29fc6ad908852ff8e4f0fc36aa5d354b56fa77c609881795dfb5c7bc83}
- {viewport: 1280, path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w1280.png, sha256: 315eaa89dfe4d65b279196448f7864b621d4a426982093f16118eb9c2138b88b}
state-preview-directory: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews
revision-closure:
learning-evidence: "causal hypothesis Predict and three-part constructed Explain"
accessibility: "focus restoration, live status feedback, native trace table, AA Lab boundary"
responsive-craft: "Korean keep-all typography, mobile entry jump, tablet two-column density"
system-boundary: "Technology Atlas hierarchy, scenario registry, tokenized editorial recipes"
implemented-invariants: [LI-EDITORIAL-EVIDENCE, LI-DUAL-ENTRY-SHARED-CORE, LI-EVIDENCE-LEARNING-LOOP, LI-HONEST-BOUNDARY, LI-ACCESSIBLE-READING]
report-header:
bottom-line: >-
Revision 2가 minor-revision 항목을 닫고 exact prototype directory에 결속된 DOM·360/768/1280·route
preview receipt와 전체 Chrome interaction receipt를 모두 통과했다.
decision-needed: { needed: false, approver: null }
confidence: { value: Med, derived-from: hash-bound-panel-closure-live-render-and-browser-e2e }
risks:
- "전문가·자동 검증 결과이며 실제 학습자 효과나 screen-reader별 발화 차이는 아직 주장하지 않는다."
evidence:
- source-uri: hyeonworks/evidence/ledger.jsonl
grade: E3
note: "vr-1784380367-51a78e23c06f bound render receipt and vr-1784380160-b25beb2fef58 full browser flow receipt"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews
grade: E3
note: "five interactive states at 360 and 1280"
@@ -0,0 +1,172 @@
report-header:
bottom-line: >-
PASS — exact winner ENG-FE-20260718T131305Z / bcc557fcd7463349345bd06090868c4c2b6b792453d4e1dddd4ac60b0fa68674는
단일 scenario registry와 reducer, known-id hash route, native control/table semantics, 명시적 focus/live feedback,
360/768/1280 responsive contract 및 전체 Chrome flow 검증으로 production 구현 handoff가 가능하다.
두 번째 scenario를 추가할 때 active-scenario alias를 state에서 유도하고 CI에서 browser harness를 pin하는 일은
구현 단계의 국소 handoff note이며 방향 수정 사유는 아니다.
decision-needed:
needed: false
approver: null
confidence:
value: Med
derived-from: exact-hash-bound-source-render-receipts-and-independent-temp-clone-browser-run
risks:
- >-
현재 화면 renderer는 module-level default scenario alias를 사용하므로 두 번째 registry 항목을 추가할 때는
labState.scenarioId에서 active scenario를 유도해야 한다. 현재 명시된 단일 활성 scenario에서는 오동작하지 않는다.
- >-
E2E harness는 puppeteer-core와 Chrome이 실행 환경에 있다고 가정한다. production CI에서는 devDependency와
CHROME_BIN/PUPPETEER_CORE_PATH를 pin해야 재현 가능한 bootstrap이 된다.
- >-
자동 검증은 keyboard focus, live status, native table, contrast와 overflow를 다루지만 실제 screen reader별
발화와 장기 학습 성과를 증명하지 않는다.
evidence:
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
grade: E3
note: >-
SHA-256 40876a12d2ab842568a76b3c2e2e50f6cd32614914805ecf3c6a00745266958c에 결속된
route/state/reducer/accessibility/test contract와 dist 파일 해시 manifest.
- source-uri: hyeonworks/evidence/ledger.jsonl
grade: E3
note: >-
source revision 40876a12d2ab842568a76b3c2e2e50f6cd32614914805ecf3c6a00745266958c에 결속된
vr-1784380367-51a78e23c06f render-health pass와 vr-1784380160-b25beb2fef58 browser-flow pass.
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w360.png
grade: E3
note: >-
SHA-256 0dcfc9446659c936dbd7ccfb9943ae79c3e12abad5431482ced6a99eb74bc444;
mobile single-column render와 first-viewport entry jump의 실제 Chrome 결과.
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w768.png
grade: E3
note: >-
SHA-256 5de39c29fc6ad908852ff8e4f0fc36aa5d354b56fa77c609881795dfb5c7bc83;
tablet two-column density가 보존된 실제 Chrome 결과.
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w1280.png
grade: E3
note: >-
SHA-256 315eaa89dfe4d65b279196448f7864b621d4a426982093f16118eb9c2138b88b;
desktop editorial/Lab composition의 실제 Chrome 결과.
report-type: workflow-artifact
artifact-kind: design-lens-review
artifact-version: 1
identity:
artifact-id: ENG-FE-20260718T131443Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: ENG-FE
created-at: 20260718T131443Z
attempt-id: 1
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
target-prototype-id: ENG-FE-20260718T131305Z
target-prototype-sha256: bcc557fcd7463349345bd06090868c4c2b6b792453d4e1dddd4ac60b0fa68674
reviewer-role-id: ENG-FE
reviewer-run-id: eab69987ab88f740e4c80ed8b5e1cbb0b9cfdbb61bb29e7535d1e42c368e49f3
lens: implementability
verdict: pass
findings:
- finding-id: IMP-R2-STATE-ROUTE
severity: info
blocking: false
status: satisfied
area: state-and-route-boundary
finding: >-
한 개의 immutable scenarioRegistry, 명시적 initialLabState, action-guarded learningReducer와 known-id
hash route가 Predict→Observe→Compare→Explain→Transfer 전이를 network/storage/time 의존 없이 결정적으로
표현한다. concept와 symptom 입구는 동일 tx-lost-update-01 route와 동일 reducer state로 합류하므로 React
reducer/component로 옮길 때 별도 runtime이나 backend가 필요 없다.
evidence:
- kind: code
source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/app.js
sha256: bbc82f68ffbba2b4ff41e9188ad0fa6c197de7a09a8872de6a9501c10802bded
detail: >-
scenarioRegistry, initialLabState, learningReducer, known-id route parser와 data-scenario-id boundary가
한 파일에서 추적 가능하며 reflection은 escapeHtml로 DOM 삽입 전에 escaping된다.
- kind: contract
source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
sha256: 40876a12d2ab842568a76b3c2e2e50f6cd32614914805ecf3c6a00745266958c
detail: routes, shared-core, fixed learning loop와 deterministic boundary가 코드 해시에 결속된다.
- kind: browser-receipt
source-uri: hyeonworks/evidence/ledger.jsonl
receipt-id: vr-1784380160-b25beb2fef58
assertion-status: passed
source-revision-sha256: 40876a12d2ab842568a76b3c2e2e50f6cd32614914805ecf3c6a00745266958c
detail: dual entry, shared core, full causal loop, reset과 runtime-error-free flow를 Chrome에서 검증했다.
handoff-note: >-
두 번째 scenario를 등록하기 전 module-level `scenario` alias를 labState.scenarioId 기반 selector로 바꾼다.
현재 product scope는 활성 deep dive 한 개라고 명시되어 있어 이번 winner의 실행 가능성을 낮추지 않는다.
- finding-id: IMP-R2-A11Y-RESPONSIVE
severity: info
blocking: false
status: satisfied
area: accessibility-and-responsive-boundary
finding: >-
native anchors/buttons/radios/fieldset/textarea와 caption·thead·scope를 갖춘 table, skip link, polite live region,
phase/feedback focus restoration이 상호작용 상태에 포함된다. CSS는 360 single-column, 701900 two-column,
desktop grid를 명시하고 focus-visible·reduced-motion·dark-boundary tokens를 제공하므로 구현 복잡도가 낮다.
evidence:
- kind: code
source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/index.html
sha256: 6295b1cf4b5f44cd4e9a5242643712728709ac851d62c4587ef933830bd33861
detail: lang=ko, skip link와 aria-live announcer가 정적 DOM boundary에 존재한다.
- kind: code
source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/styles.css
sha256: 62fd9ea7af1fb2710d8497f814502eec1271aff9eeace7214e6d246266967cd6
detail: focus-visible, semantic breakpoints, overflow-safe trace region과 reduced-motion contract가 명시된다.
- kind: browser-receipt
source-uri: hyeonworks/evidence/ledger.jsonl
receipt-id: vr-1784380160-b25beb2fef58
assertion-status: passed
source-revision-sha256: 40876a12d2ab842568a76b3c2e2e50f6cd32614914805ecf3c6a00745266958c
detail: >-
Space radio selection, focus retention/handoff, live feedback, native table headers, AA Lab boundary,
360 no-overflow/entry jump와 768 two-column density를 실제 Chrome에서 검증했다.
- kind: render-receipt
source-uri: hyeonworks/evidence/ledger.jsonl
receipt-id: vr-1784380367-51a78e23c06f
assertion-status: passed
source-revision-sha256: 40876a12d2ab842568a76b3c2e2e50f6cd32614914805ecf3c6a00745266958c
detail: concept, symptom, Lab routes를 360/768/1280에서 hash-bound render했다.
- finding-id: IMP-R2-TEST-HANDOFF
severity: low
blocking: false
status: handoff-note
area: verification-and-performance-boundary
finding: >-
189-line browser harness 하나가 happy path뿐 아니라 wrong-answer feedback/reset, keyboard focus, table semantics,
runtime contrast, mobile overflow와 tablet density를 검증한다. 앱은 외부 network, storage, runtime dependency가
없고 작은 static registry/reducer/CSS로 구성되어 이 방향을 production stack으로 옮길 성능·운영 복잡성은 낮다.
다만 clean CI bootstrap을 위해 browser test dependency와 executable path를 production repository에서 pin해야 한다.
evidence:
- kind: test-code
source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/scripts/verify_flow.cjs
sha256: 5b28470c7c1a5ab40a81386a3e29eac9fd0d6baca88f221cc9dda392cf52713f
detail: >-
local static server와 headless Chrome assertions만 사용하며 complete/reset 및 두 entry를 한 flow에서 다룬다.
- kind: browser-receipt
source-uri: hyeonworks/evidence/ledger.jsonl
receipt-id: vr-1784380160-b25beb2fef58
assertion-status: passed
exit-code: 0
source-revision-sha256: 40876a12d2ab842568a76b3c2e2e50f6cd32614914805ecf3c6a00745266958c
detail: exact script hash와 source revision에 결속된 full Chrome interaction pass이다.
handoff-note: >-
package.json의 test:e2e contract는 유지하되 puppeteer-core/Chrome version 및 CI environment variable을 pin한다.
review-basis:
context-package-ref: hyeonworks/state/context-packages/hyeonworks-vnext-v1-direction/ENG-FE-20260718T131418Z.pkg.yaml
context-package-sha256: eab69987ab88f740e4c80ed8b5e1cbb0b9cfdbb61bb29e7535d1e42c368e49f3
winner-report-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T131305Z.report.yaml
winner-report-id: ENG-FE-20260718T131305Z
winner-report-sha256: bcc557fcd7463349345bd06090868c4c2b6b792453d4e1dddd4ac60b0fa68674
prototype-ref: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
prototype-sha256: 40876a12d2ab842568a76b3c2e2e50f6cd32614914805ecf3c6a00745266958c
preview-receipt-id: vr-1784380367-51a78e23c06f
interaction-receipt-id: vr-1784380160-b25beb2fef58
independent-check: >-
원본을 수정하지 않고 /tmp 복제본에서 node --check와 scripts/verify_flow.cjs를 재실행했으며 Chrome E2E가 PASS했다.
@@ -0,0 +1,60 @@
report-type: workflow-artifact
artifact-kind: winner-prototype
artifact-version: 1
identity:
artifact-id: ENG-FE-20260718T135811Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-prototype
producer-role-id: ENG-FE
created-at: 20260718T135811Z
attempt-id: 5
supersedes-report-id: ENG-FE-20260718T131305Z
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
selected-direction-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-DIRECTOR-20260718T115933Z.report.yaml
selected-direction-sha256: 90b64c99493f1789a134459813207291dfa4beafa794e3f861b4f28d23286a65
source-artifact-refs:
- {artifact-id: DES-DIRECTOR-20260718T115933Z, artifact-sha256: 90b64c99493f1789a134459813207291dfa4beafa794e3f861b4f28d23286a65}
- {artifact-id: DES-DIRECTOR-20260718T133900Z, artifact-sha256: 3bda81f80df43de009c67fbaa79a69df4129bc157f69750bc6af7faa2e94aa76}
prototype-path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
prototype-sha256: bd2bf67bddde92ae4fa0d329bd21e078625aa343ba59b78fec75f248111d22a1
preview-receipt-ref: vr-1784383017-9ca3005d47a5
preview-receipt-sha256: aa79aff403326e006fb642188a250562d4066c94695b31b628b3b407d1122ee4
interaction-receipt-ref: vr-1784382985-e736dc497b11
interaction-receipt-sha256: 36e44523cba5c655388abef8ca07068b64070b761bb8b60c3cc7e14474a6f7e0
css-receipt-ref: vr-1784383046-099953298097
css-receipt-sha256: 3cafd505cf3acb25a1d21719dd9c92bacc4b31630e0e0b669b413b59a60adaf4
revision: 3
preview-shots:
- {viewport: 360, path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w360.png, sha256: 0dcfc9446659c936dbd7ccfb9943ae79c3e12abad5431482ced6a99eb74bc444}
- {viewport: 768, path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w768.png, sha256: 5de39c29fc6ad908852ff8e4f0fc36aa5d354b56fa77c609881795dfb5c7bc83}
- {viewport: 1280, path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w1280.png, sha256: 315eaa89dfe4d65b279196448f7864b621d4a426982093f16118eb9c2138b88b}
route-previews:
- {state: concept, path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.state-concept.png, sha256: b4e48f6165ef72f5594132a64cee20b3f9a8745c340b8fc0bea989f907d6f9ed}
- {state: symptom, path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.state-symptom.png, sha256: a622e4e2b9ac4b0a9397c183afeaa6dad06d3ed0a42f459e524c6486b827cc5c}
- {state: lab, path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.state-lab.png, sha256: b6ac8332fac2549f857cf339cfaa6860d5b85c21cca36e9b44cce9ad34bfdbf8}
- {state: fixture, path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.state-fixture.png, sha256: 918b375e1bb8f4fb1b50e6f4eaa3d24b23609a9d004236d172f100c25312aa94}
state-preview-directory: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews
revision-closure:
mobile-containment: "360 Observe keeps document width at 360 while the 560px native table scrolls inside trace-scroll"
entry-focus: "360 keyboard and 768 pointer shortcut focus/scroll entry-title without hash route rerender"
korean-craft: "Range-based Chrome assertions prove no Korean word splits; long Latin fixture token wraps safely"
system-boundary: "active scenario is passed to render/dispatch/announcement; an independent four-step 50/60/40 fixture completes through the shared reducer"
implemented-invariants: [LI-EDITORIAL-EVIDENCE, LI-DUAL-ENTRY-SHARED-CORE, LI-EVIDENCE-LEARNING-LOOP, LI-HONEST-BOUNDARY, LI-ACCESSIBLE-READING]
report-header:
bottom-line: >-
Revision 3가 실제 360px containment·entry focus·한국어 단어 조판과 scenario-to-render 결속 결함을 닫았다.
기본 6-step Lab과 독립 4-step fixture가 같은 reducer/view에서 전체 Chrome flow를 통과했고,
360/768/1280·route render와 CSS 대비/focus receipt도 exact manifest SHA에 결속됐다.
decision-needed: { needed: false, approver: null }
confidence: { value: Med, derived-from: hash-bound-panel-closure-live-render-browser-e2e-and-css-receipts }
risks:
- "두 번째 record는 확장 경계 검증용 fixture이지 공개 학습 콘텐츠나 실제 사용자 학습효과의 증거가 아니다."
- "screen-reader 제품별 수동 발화는 아직 수행하지 않았으며 native semantics와 keyboard/focus 자동 검증까지만 주장한다."
evidence:
- source-uri: hyeonworks/evidence/ledger.jsonl
grade: E3
note: "vr-1784382985-e736dc497b11 full browser flow, vr-1784383017-9ca3005d47a5 bound render, vr-1784383046-099953298097 CSS health"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews
grade: E3
note: "predict·observe·compare·explain·transfer·complete at 360 and 1280"
@@ -0,0 +1,103 @@
report-header:
bottom-line: >-
Revision 3의 source hash 결속, deterministic reducer, 360 containment, 768 editorial density,
기본 6-step flow와 독립 4-step fixture는 production port에 충분히 구체적이고 재현 검증도 통과했다.
다만 현재 skip link가 Lab에서 `#main`으로 hash route를 덮어 홈을 재렌더하며 scenario와 진행 상태를
잃으므로 접근 가능한 production handoff 전 수정과 회귀 검증이 필요하다. Verdict는 revise다.
decision-needed: {needed: false, approver: null}
confidence: {value: Med, derived-from: exact-source-hash-review-and-local-browser-reproduction}
risks:
- "skip link 활성화가 non-home route와 진행 중 Lab state를 버리는 접근성·routing 결함이 열려 있다."
- "768px 검증은 route render와 home density를 덮지만 모든 Lab phase의 phase-by-phase E2E는 아니다."
- "native semantics, keyboard focus와 live feedback은 자동 검증됐지만 screen-reader 제품별 수동 발화는 범위 밖이다."
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T135811Z.report.yaml
grade: E3
note: "exact target SHA 735d588bef412dd3c59899d393562ae76a67a55bbe9f507ddf38eeab1481e9f0; preview/interaction/CSS receipt refs와 각 SHA가 명시됨"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
grade: E3
note: "core-flow SHA bd2bf67bddde92ae4fa0d329bd21e078625aa343ba59b78fec75f248111d22a1 및 네 source file manifest SHA가 실제 파일과 일치"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/app.js
grade: E3
note: "registry/state/action 기반 reducer와 active-scenario render/dispatch 결속; hashchange fallback이 #main을 home으로 해석하는 결함 근거"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/index.html
grade: E3
note: "skip link href=#main과 hash-router 충돌의 시작점"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/scripts/verify_flow.cjs
grade: E3
note: "전체 Chrome E2E 재실행 exit 0; dual-entry, 360 containment, focus/live feedback, native table, Korean wrapping, 기본/fixture 완주를 검증하지만 skip link는 미포함"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/styles.css
grade: E3
note: "CSS contrast/focus-visible health 재실행 exit 0; 360/701-900/desktop containment recipes 확인"
report-type: workflow-artifact
artifact-kind: design-lens-review
artifact-version: 1
identity:
artifact-id: ENG-FE-20260718T140000Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: ENG-FE
created-at: 20260718T140000Z
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
target-prototype-id: ENG-FE-20260718T135811Z
target-prototype-sha256: 735d588bef412dd3c59899d393562ae76a67a55bbe9f507ddf38eeab1481e9f0
target-prototype-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T135811Z.report.yaml
context-package-ref: hyeonworks/state/context-packages/hyeonworks-vnext-v1-direction/ENG-FE-20260718T135945Z.pkg.yaml
context-package-sha256: 3f768a15887862e2de9227f5e84c43b61c4133909ae49b96f7dcb5d3aabd010a
reviewer-role-id: ENG-FE
reviewer-run-id: 3f768a15887862e2de9227f5e84c43b61c4133909ae49b96f7dcb5d3aabd010a
lens: implementability
verdict: revise
review-results:
source-and-exact-receipts:
status: pass
basis: >-
Package와 exact target SHA가 지정값과 일치하고 core-flow manifest의 index/app/styles/harness SHA도
모두 실제 source와 일치한다. Target가 명시한 preview, interaction, CSS receipt ref/SHA와 동일한
source에서 JS check, Chrome E2E, CSS health를 재현했다.
deterministic-reducer:
status: pass
basis: >-
learningReducer는 phase guard와 registry record, state, action만으로 새 state를 만들며
Date.now, Math.random, network, storage가 없다. schedule length와 answers는 active scenario에서 읽는다.
accessibility:
status: revise
basis: >-
fieldset/legend, native table headers, scroll-region tabindex, focus restoration, role=status,
live announcer, reduced motion, focus-visible과 runtime contrast는 구현·검증됐다. 그러나 skip link가
hash router와 충돌해 non-home context를 파괴한다.
responsive:
status: pass-with-risk
basis: >-
minmax(0,1fr), contained trace overflow와 360 document-width assertions가 전 phase에서 통과했고
701-900px two-column rules와 768 home density assertion도 존재한다. 768 전체 Lab phase E2E는 후속
회귀 묶음에 추가하는 편이 안전하다.
second-fixture:
status: pass
basis: >-
direct route가 inventory record를 선택하고 50/60/40 values, fixture copy/choice ids, 4-row schedule,
explanation, 100/110/115 transfer, completion과 reset까지 같은 reducer/view로 완주한다.
findings:
- finding-id: IMP-R3-01
severity: high
blocking: false
area: accessibility-routing
title: "Skip link activation destroys the current hash route and Lab state"
evidence:
- "index.html의 `.skip-link`는 `href=#main`이다."
- "app.js route()는 #/ prefix가 아닌 #main을 home fallback으로 반환하고 hashchange는 render()를 호출한다."
- "Chrome에서 fixture Lab의 skip link를 keyboard Enter로 활성화하자 hash=#main, data-scenario-id=null, home h1 상태로 재현됐다."
impact: >-
키보드·screen-reader 사용자가 반복 navigation을 건너뛰려 할 때 현재 route, scenario와 학습 진행을
잃는다. bypass mechanism이 오히려 task context를 파괴하므로 production accessibility contract로
넘길 수 없다.
required-revision: >-
skip link를 local focus/scroll 동작으로 처리해 route hash를 바꾸지 않고 현재 main을 focusable하게
만든다. home, concept, symptom, default Lab, fixture Lab과 진행 중 phase에서 route/scenario/reducer
state가 보존되는 keyboard 회귀 검증을 추가한다.
acceptance-checks:
- "Enter로 skip link 활성화 후 document.activeElement가 현재 main(또는 그 시작 heading)이다."
- "location.hash, main[data-scenario-id], phase와 cursor가 활성화 전후 동일하다."
- "default와 fixture, 360/768/1280에서 검증하며 document overflow가 없다."
@@ -0,0 +1,66 @@
report-type: workflow-artifact
artifact-kind: winner-prototype
artifact-version: 1
identity:
artifact-id: ENG-FE-20260718T144500Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-prototype
producer-role-id: ENG-FE
created-at: 20260718T144500Z
attempt-id: 6
supersedes-report-id: ENG-FE-20260718T135811Z
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
selected-direction-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-DIRECTOR-20260718T115933Z.report.yaml
selected-direction-sha256: 90b64c99493f1789a134459813207291dfa4beafa794e3f861b4f28d23286a65
source-artifact-refs:
- {artifact-id: DES-DIRECTOR-20260718T115933Z, artifact-sha256: 90b64c99493f1789a134459813207291dfa4beafa794e3f861b4f28d23286a65}
- {artifact-id: DES-DIRECTOR-20260718T142500Z, artifact-sha256: b381e71bfe662dd5b342e708131440c435a7a2fc82ff33a7fa20b5fbb220bc89}
prototype-path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
prototype-sha256: 287bc732d7ddf9076ae8377e9a6824ff1495513a2011b8521fae8036e2c33b77
preview-receipt-ref: vr-1784385861-b369f346f270
preview-receipt-sha256: bfc0154becad9a91b74ea403a2bac8f19a70f01051c5cf796acc508564b3bc07
interaction-receipt-ref: vr-1784385837-b85a6b1f7d4f
interaction-receipt-sha256: 1f52f11aee0efed720c0e1d4b87d67eaa6f17c6d6e49da04c9981dec33a7c71d
css-receipt-ref: vr-1784385869-42e22f004643
css-receipt-sha256: 1c9105e466be0829fa807d27b0d9e38a0be0758c0ac6b4ac5ac796b950700612
revision: 4
preview-shots:
- {viewport: 360, path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w360.png, sha256: db1af7ce77da4a9780a08ef4ad812485476f8ba5a6e3f3820a7c5d188356528a}
- {viewport: 768, path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w768.png, sha256: 51ce61cff0ba2ddc9fd5dcd661f7c51e624f3d6ff3db000de0d4e6b57dfa5aee}
- {viewport: 1280, path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w1280.png, sha256: f1b3918774289e2a2353ba4fc2d5deb6d6001777fef30ea83da7126df45cabd7}
route-previews:
- {state: concept, path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.state-concept.png, sha256: 778688488272718c02ae528f9be358f5a97fc7a0f2034487d992d9e4bd03c2c9}
- {state: symptom, path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.state-symptom.png, sha256: 08069f9de4f2e3290bf2643c55c9fcf24e54d0aa241732889b494f28328f8569}
- {state: lab, path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.state-lab.png, sha256: 530cdd1e9393e5374269e127c61b5882633b623791b713bdb5a592647d704007}
- {state: fixture, path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.state-fixture.png, sha256: afd27057f15a1b7ec6a57b6143f3cb355efe52880a736209ab2315a528bc7739}
state-preview-directory: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews
revision-closure:
accessible-contrast: >-
dark Lab id 7.14:1, dark boundary label 5.62:1, pending trace minimum 5.44:1,
choice and textarea borders 3.56:1을 actual computed foreground/background로 검증했다.
route-safe-skip-link: >-
persistent skip link가 hash를 바꾸거나 router를 재실행하지 않고 현재 main을 focus/scroll한다.
home, concept, revealed symptom, 기본 Observe cursor 1, fixture Observe cursor 1을 360/768/1280에서 검증했다.
state-preservation: >-
skip link 전후 main node identity, location hash, scenario id, phase, cursor, trace와 clue state가 동일하다.
proportionate-system-boundary: >-
기존 static scenario registry와 reducer를 유지하고 backend, storage, framework 또는 범용 runtime을 추가하지 않았다.
implemented-invariants: [LI-EDITORIAL-EVIDENCE, LI-DUAL-ENTRY-SHARED-CORE, LI-EVIDENCE-LEARNING-LOOP, LI-HONEST-BOUNDARY, LI-ACCESSIBLE-READING]
report-header:
bottom-line: >-
Revision 4가 R3 panel의 dark-surface·pending·control 대비와 skip-link route/state 손실을 국소적으로 닫았다.
두 Lab의 진행 중 state와 세 공개 route가 360/768/1280 Chrome matrix에서 hash·scenario·phase·cursor를 보존했고,
exact manifest SHA에 interaction·render·CSS 영수증이 결속됐다.
decision-needed: { needed: false, approver: null }
confidence: { value: Med, derived-from: exact-panel-closure-live-browser-matrix-computed-contrast-and-hash-bound-receipts }
risks:
- screen-reader 제품별 수동 발화는 아직 수행하지 않았으며 native semantics, keyboard focus와 route-safe skip 동작까지만 주장한다.
- 검증 fixture는 구현 결속을 증명할 뿐 공개 학습 콘텐츠의 완성도나 실제 사용자 학습효과의 증거가 아니다.
evidence:
- source-uri: hyeonworks/evidence/ledger.jsonl
grade: E3
note: "vr-1784385837-b85a6b1f7d4f browser matrix, vr-1784385861-b369f346f270 responsive routes, vr-1784385869-42e22f004643 CSS health"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
grade: E3
note: "revision 4 exact manifest SHA 287bc732…"
@@ -0,0 +1,49 @@
report-type: workflow-artifact
artifact-kind: winner-prototype
artifact-version: 1
identity:
artifact-id: ENG-FE-20260718T144700Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-prototype
producer-role-id: ENG-FE
created-at: 20260718T144700Z
attempt-id: 7
supersedes-report-id: ENG-FE-20260718T144500Z
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
selected-direction-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-DIRECTOR-20260718T115933Z.report.yaml
selected-direction-sha256: 90b64c99493f1789a134459813207291dfa4beafa794e3f861b4f28d23286a65
source-artifact-refs:
- {artifact-id: DES-DIRECTOR-20260718T115933Z, artifact-sha256: 90b64c99493f1789a134459813207291dfa4beafa794e3f861b4f28d23286a65}
- {artifact-id: DES-DIRECTOR-20260718T142500Z, artifact-sha256: b381e71bfe662dd5b342e708131440c435a7a2fc82ff33a7fa20b5fbb220bc89}
prototype-path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
prototype-sha256: 287bc732d7ddf9076ae8377e9a6824ff1495513a2011b8521fae8036e2c33b77
preview-receipt-ref: vr-1784385993-ed403209d073
preview-receipt-sha256: 31d74e201403280a6f3ff855e2e77a3ba64ffc026f396e4569a9351f7a56e60f
interaction-receipt-ref: vr-1784385837-b85a6b1f7d4f
interaction-receipt-sha256: 1f52f11aee0efed720c0e1d4b87d67eaa6f17c6d6e49da04c9981dec33a7c71d
css-receipt-ref: vr-1784385869-42e22f004643
css-receipt-sha256: 1c9105e466be0829fa807d27b0d9e38a0be0758c0ac6b4ac5ac796b950700612
revision: 4
revision-closure:
- "dark Lab id 7.14:1, dark boundary label 5.62:1, pending minimum 5.44:1"
- "choice and textarea essential borders 3.56:1; decorative rule remains separate"
- "home, concept, revealed symptom, default/fixture Observe cursor 1에서 360/768/1280 skip-link state preservation"
- "main node, hash, scenario, phase, cursor, trace/clue state unchanged; current main focused and scrolled"
implemented-invariants: [LI-EDITORIAL-EVIDENCE, LI-DUAL-ENTRY-SHARED-CORE, LI-EVIDENCE-LEARNING-LOOP, LI-HONEST-BOUNDARY, LI-ACCESSIBLE-READING]
report-header:
bottom-line: >-
Revision 4 exact manifest가 절대 prototype 경로를 포함한 실제 preview receipt에 다시 결속됐다.
R3의 두 required revision은 computed contrast와 5-route×3-viewport Chrome state matrix로 닫혔다.
decision-needed: { needed: false, approver: null }
confidence: { value: Med, derived-from: exact-panel-closure-live-browser-matrix-and-three-hash-bound-receipts }
risks:
- screen-reader 제품별 수동 발화와 실제 사용자 학습효과는 아직 검증 범위가 아니다.
- direct-route fixture는 registry 결속 검증용이며 공개 콘텐츠로 주장하지 않는다.
evidence:
- source-uri: hyeonworks/evidence/ledger.jsonl
grade: E3
note: "absolute-path preview vr-1784385993-ed403209d073, browser vr-1784385837-b85a6b1f7d4f, CSS vr-1784385869-42e22f004643"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
grade: E3
note: "exact revision 4 manifest SHA 287bc732…"
@@ -0,0 +1,80 @@
report-type: workflow-artifact
artifact-kind: design-lens-review
artifact-version: 1
identity:
artifact-id: ENG-FE-20260718T145000Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: ENG-FE
created-at: 20260718T145000Z
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
lens: implementability
reviewer-run-id: cfcfc3f64722c9f7ec5712bab3b38faa00026ef4e146f3f52829d37d410ac2ac
reviewer-role-id: ENG-FE
target-prototype-id: ENG-FE-20260718T144700Z
target-prototype-sha256: 8b208279e12f9aea0fa6d7a3c320811b0e72ddb74c6afac64cddadf4b157cf76
target-artifact-id: ENG-FE-20260718T144700Z
target-artifact-sha256: 8b208279e12f9aea0fa6d7a3c320811b0e72ddb74c6afac64cddadf4b157cf76
verdict: pass
findings: []
strengths:
- >-
scenarioRegistry record, scenario-id state, deterministic learningReducer, and explicit scenario arguments
separate content binding from the shared learning engine without a backend, network, storage, time, or randomness dependency.
- >-
The default six-step and independent four-step fixture both traverse Predict, Observe, Compare, Explain,
Transfer, Complete, and Reset, reducing the risk that production extraction silently retains default-scenario constants.
- >-
The persistent skip handler prevents hash routing, targets the current tabindex=-1 main, and the browser matrix
verifies node identity, route, scenario, phase, cursor, trace, and revealed-clue preservation at 360, 768, and 1280.
- >-
Native controls/table semantics, deterministic focus restoration, live status feedback, responsive containment,
Korean word integrity, long-token fallback, and runtime contrast assertions are encoded as executable handoff contracts.
portability-assessment:
production-portable: true
bounded-scope: >-
A zero-dependency static production shell can port the registry, reducer, render contract, and browser suite directly.
Broader content authoring, persistence, analytics, authentication, and remote diagnosis remain intentionally outside this prototype.
extraction-seams:
- scenario record schema and registry lookup
- pure reducer and initial state factory
- phase-specific views and explicit active scenario binding
- local route/focus handlers
- browser acceptance matrix and CSS health gate
residual-risks:
- app.js is a single prototype module; production growth should split scenario data, reducer, route shell, and phase views while preserving behavior.
- Browser automation depends on a locally available Chrome and puppeteer-core harness, so CI must provision and pin those runner prerequisites.
- Manual assistive-technology behavior and actual learning outcomes are not established by the automated suite.
evidence-reviewed:
- {ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T144700Z.report.yaml, sha256: 8b208279e12f9aea0fa6d7a3c320811b0e72ddb74c6afac64cddadf4b157cf76}
- {ref: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml, sha256: 287bc732d7ddf9076ae8377e9a6824ff1495513a2011b8521fae8036e2c33b77}
- {ref: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/index.html, sha256: 6295b1cf4b5f44cd4e9a5242643712728709ac851d62c4587ef933830bd33861}
- {ref: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/app.js, sha256: b148057f4d25ba6afb4170c82f5c832263563feaf99a345a0d79e350d83fbed3}
- {ref: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/styles.css, sha256: 71e51b907f5b01c480eb348df35db17995fc45269db36ed6a1afd113e3f29f58}
- {ref: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/scripts/verify_flow.cjs, sha256: a0910543e412b73cd5c7c87fefe3a871feb0c0308fac45fcefab42357218cfc8}
receipt-checks:
- {receipt-id: vr-1784385837-b85a6b1f7d4f, line-sha256: 1f52f11aee0efed720c0e1d4b87d67eaa6f17c6d6e49da04c9981dec33a7c71d, source-revision-sha256: 287bc732d7ddf9076ae8377e9a6824ff1495513a2011b8521fae8036e2c33b77, status: passed}
- {receipt-id: vr-1784385869-42e22f004643, line-sha256: 1c9105e466be0829fa807d27b0d9e38a0be0758c0ac6b4ac5ac796b950700612, source-revision-sha256: 287bc732d7ddf9076ae8377e9a6824ff1495513a2011b8521fae8036e2c33b77, status: passed}
- {receipt-id: vr-1784385993-ed403209d073, line-sha256: 31d74e201403280a6f3ff855e2e77a3ba64ffc026f396e4569a9351f7a56e60f, source-revision-sha256: 287bc732d7ddf9076ae8377e9a6824ff1495513a2011b8521fae8036e2c33b77, status: passed}
independent-checks:
- {command: "node --check dist/app.js", result: pass}
- {command: "preview_ui.py --contrast-only dist/styles.css", result: pass}
- {command: "node scripts/verify_flow.cjs (isolated temporary copy)", result: pass}
report-header:
bottom-line: >-
PASS. Revision 4 is production-portable within its declared static learning-Lab boundary: its scenario seam,
deterministic reducer, route-safe focus behavior, full dual-scenario flow, responsive/accessibility contracts,
and manifest-bound receipts are coherent and independently reproducible.
decision-needed: {needed: false, approver: null}
confidence: {value: High, derived-from: exact-source-hashes-receipt-binding-code-inspection-and-independent-browser-replay}
risks:
- Production expansion still needs module extraction and a pinned browser-test runner, but neither blocks this bounded handoff.
- Manual screen-reader behavior and real learner outcomes remain future validation, not implementation defects in this prototype.
evidence:
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
grade: E3
note: "Exact manifest 287bc732… binds source files and three passing receipts."
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/scripts/verify_flow.cjs
grade: E3
note: "Independent temporary-copy replay passed full default/fixture flow, skip-state matrix, semantics, responsive containment, and runtime contrast."
@@ -0,0 +1,112 @@
report-type: workflow-artifact
artifact-kind: design-lens-review
artifact-version: 1
identity:
artifact-id: GTM-PMM-20260718T121851Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: GTM-PMM
created-at: 20260718T121851Z
attempt-id: 1
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
target-prototype-id: ENG-FE-20260718T120840Z
target-prototype-sha256: 1cfa4ff43762111f46b0088057f6b902375f86856558056aa5f11f117f107267
reviewer-role-id: GTM-PMM
reviewer-run-id: a891c7a54da7771de16bb84cff76ab3c40f3c85b09374285a6656915211bddea
lens: market-memorability
selected-direction:
id: ledger-studio
artifact-id: DES-DIRECTOR-20260718T115933Z
artifact-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-DIRECTOR-20260718T115933Z.report.yaml
artifact-sha256: 90b64c99493f1789a134459813207291dfa4beafa794e3f861b4f28d23286a65
reviewed-winner:
artifact-id: ENG-FE-20260718T120840Z
artifact-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T120840Z.report.yaml
artifact-sha256: 1cfa4ff43762111f46b0088057f6b902375f86856558056aa5f11f117f107267
prototype-id: hyeonworks-ledger-core-flow-r1
prototype-ref: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
prototype-sha256: 5df1bc1ff6ab253fa35d3d0f9c6a373f206d03e59fe4c4c2dbb0cbd2d9494c7c
render-refs:
- { viewport: 360, path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w360.png, sha256: ee18b5109276328285b606bbdcc27f6dcbbe970187a69e6f07d1e0cf2502900e }
- { viewport: 768, path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w768.png, sha256: fa19f6b9677a5203c7539555287201a825f82a71572a8a61fe8f8065601b6f4c }
- { viewport: 1280, path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w1280.png, sha256: 68e20861bfe87f34ed3da17d9a1da47a593d9d2391478cd2c06ce12668c7bf00 }
reviewer:
role-id: GTM-PMM
run-id: a891c7a54da7771de16bb84cff76ab3c40f3c85b09374285a6656915211bddea
lens: market-memorability
verdict: revise
review-boundary: >-
exact winner source와 제공된 360/768/1280 렌더의 메시지·범주 단서·이름·첫인상만 감사했다.
제품 적합성, 사용성, 시각 craft, 구현성, 실제 사용자 회상이나 시장 반응은 판정하지 않았다.
findings:
- id: MM-01
severity: high
area: public-name-salience-and-brand-hierarchy
evidence: >-
세 렌더의 최상단에는 “Hyeonworks / Technology Atlas”, “Field note 001”, “Lost Update Lab”,
“Shared scenario”가 함께 노출되고, index title도 “Hyeonworks · Lost Update Lab”이다. 반면 선택된
방향의 고유명 “Ledger Studio”는 app.js, index.html, 세 렌더 어디에도 노출되지 않는다. 따라서
100·120·70 미스터리를 다시 떠올릴 단서는 있어도 어느 고유명과 결속해 기억해야 하는지는 정해지지 않는다.
action: >-
public-facing 고유명을 하나 정한다. Ledger Studio를 공개 이름으로 쓸 경우 header, document title,
hero 또는 lab return point에 반복 노출하고 Technology Atlas는 범주 설명자로 종속한다. Ledger Studio가
내부 이름이라면 동일 위치에 대체 공개 이름을 일관되게 두고 “두 요청은 성공했는데 왜 70일까?”와 결속한다.
- id: MM-02
severity: high
area: headline-to-product-mechanic-alignment
evidence: >-
모든 렌더에서 가장 큰 headline은 “결과보다 먼저, 원인을 예측합니다.”라고 약속한다. 그러나 같은 화면의
loop와 app.js의 실제 순서는 결과를 Predict한 뒤 Observe·Compare하고 네 번째 단계에서 원인을 Explain한다.
Lab의 첫 질문도 “최종값은 무엇일까요?”이고 원인 선택은 04 Explain에 있다. 첫인상으로 기억될 문장이
대표 동작의 순서를 반대로 압축한다.
action: >-
headline을 실제 고유 동작과 같은 순서로 고친다. 예를 들어 “결과를 먼저 예측하고, 원인을 끝까지
설명합니다.”처럼 Predict → evidence → Explain을 한 문장에 담고, hero·loop·Lab 완료 문구에서 같은
핵심 동사를 반복한다.
- id: MM-03
severity: medium
area: category-coding
evidence: >-
Concurrency / Transaction Isolation / Lost Update breadcrumb, “Mechanism-first learning”, 단계형 Lab,
Guided scenario 경계 덕분에 개발자 교육이라는 범주는 추론할 수 있고 실제 진단 제품으로 과장하지도 않는다.
다만 첫 화면은 Atlas·Field note·Lab·scenario라는 네 가지 은유를 병렬 사용하며, 누구를 위한 어떤 형태의
제품인지 한 번에 재진술할 수 있는 고정 category descriptor는 없다. 360 렌더에서도 topic과 Lab은 보이지만
대상과 형식은 “기술 개념”이라는 넓은 표현에 머문다.
action: >-
brand 바로 아래에 “개발자를 위한 인터랙티브 시스템 메커니즘 Lab”처럼 대상·형식·가치를 묶은 한 줄을
고정하고, Atlas·Field note·scenario는 그 아래 콘텐츠 체계 용어로만 사용한다. Guided scenario 경계와
Lost Update breadcrumb은 신뢰를 주는 범주 단서로 유지한다.
- id: MM-04
severity: low
area: distinctive-recall-anchor-to-preserve
evidence: >-
세 viewport 모두 “두 요청은 성공했는데, 왜 70일까요?”와 Initial 100 / Expected 120 / Observed 70을
첫 주요 구획에 배치한다. app.js는 같은 수치를 hero preview, symptom entry, Compare에 반복하고
“두 입구, 하나의 Lost Update Lab”으로 두 출발점을 하나의 구조에 묶는다. 정적 artifact 기준으로는
이 구체적 숫자 대비와 질문이 가장 고유하고 압축 가능한 회상 단서다.
action: >-
이름과 headline을 수정할 때도 100·120·70 질문과 “두 입구, 하나의 Lab”을 보존하고, 선택한 단일
public-facing 이름 가까이 반복해 제품명·문제·학습 동작이 하나의 기억 묶음이 되게 한다.
report-header:
bottom-line: >-
REVISE — 100·120·70의 Lost Update 미스터리는 강한 회상 단서지만, 사용자에게 보이는 단일 고유명이 없고
첫 headline이 실제 학습 순서를 다르게 약속해 현재 상태로는 명확하고 기억 가능한 시장 메시지로 통과시키기 어렵다.
decision-needed: { needed: false, approver: null }
confidence: { value: Med, derived-from: exact-winner-source-and-three-static-renders }
risks:
- "이 평가는 exact source와 360/768/1280 정적 렌더에 대한 전문가 감사이며 사용자 회상 테스트나 실제 시장 반응을 포함하지 않는다."
- "Ledger Studio가 내부 direction 이름일 가능성은 있으나, 그 경우에도 현재 표면에는 대신 기억시킬 단일 public-facing 고유명이 없다."
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T120840Z.report.yaml
grade: E3
note: "exact winner ENG-FE-20260718T120840Z (artifact SHA-256 1cfa4ff43762111f46b0088057f6b902375f86856558056aa5f11f117f107267)와 prototype/render refs"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
grade: E3
note: "exact prototype hyeonworks-ledger-core-flow-r1, SHA-256 5df1bc1ff6ab253fa35d3d0f9c6a373f206d03e59fe4c4c2dbb0cbd2d9494c7c"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/app.js
grade: E3
note: "user-facing name, headline, category cues, dual-entry promise, and five-step loop inspected at declared SHA-256 75f55418ba5c232856878f6a537a1ae56682c1a0b06321badeed5b7b8e495c38"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w1280.png
grade: E3
note: "1280 render directly inspected together with declared 768 and 360 renders; numeric mystery, brand hierarchy, headline, entry promise, and visible boundary compared"
@@ -0,0 +1,109 @@
report-header:
bottom-line: >-
Revision 2의 Technology Atlas는 단일 공개 이름, 개발자용 시스템 메커니즘 Lab descriptor,
행동 중심 headline, 100/120/70 수치 대비를 하나의 반복 가능한 회상 묶음으로 결속하므로
market-memorability verdict는 pass다.
decision-needed: {needed: false, approver: null}
confidence:
value: Med
derived-from: hash-bound-source-three-home-renders-and-preview-receipt
risks:
- >-
이 판정은 코드와 360/768/1280 렌더에서 메시지의 명료성·반복성·수치 anchor를 감사한 결과이며,
실제 시장의 비보조 회상률이나 선호도를 측정한 주장은 아니다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T131305Z.report.yaml
grade: E3
note: "exact winner ENG-FE-20260718T131305Z / bcc557fcd7463349345bd06090868c4c2b6b792453d4e1dddd4ac60b0fa68674와 prototype·preview hash binding"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/app.js
grade: E3
note: "단일 public name, category descriptor, headline, 100/120/70 home anchor의 exact source"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w360.png
grade: E3
note: "360px home에서 name→descriptor→headline→100/120/70→entry 순서 확인"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w768.png
grade: E3
note: "768px home에서 동일 회상 묶음 확인"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w1280.png
grade: E3
note: "1280px home에서 동일 회상 묶음 확인"
- source-uri: hyeonworks/evidence/ledger.jsonl
grade: E3
note: "vr-1784380367-51a78e23c06f가 세 viewport render를 core-flow SHA 40876a12d2ab842568a76b3c2e2e50f6cd32614914805ecf3c6a00745266958c에 결속"
report-type: workflow-artifact
artifact-kind: design-lens-review
artifact-version: 1
identity:
artifact-id: GTM-PMM-20260718T131443Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: GTM-PMM
created-at: 20260718T131443Z
attempt-id: 2
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
target-prototype-id: ENG-FE-20260718T131305Z
target-prototype-sha256: bcc557fcd7463349345bd06090868c4c2b6b792453d4e1dddd4ac60b0fa68674
reviewer-role-id: GTM-PMM
reviewer-run-id: a3aa4278f9c46ba6656fec6102f29d0cf2992dce7bd7fe1f1fb8c9c206c9addc
lens: market-memorability
verdict: pass
findings:
- finding-id: MM-R2-01
severity: info
blocking: false
disposition: pass
screen-area: global-header-and-home-hero
observation: >-
Technology Atlas가 header, document title, footer와 Lab breadcrumb에서 같은 공개 이름으로 반복되고,
내부 방향명 Ledger Studio는 공개 UI에 노출되지 않는다. by Hyeonworks는 제작자 표기로 분리되어
이름 경쟁 없이 단일 회상 대상을 만든다.
code-evidence:
- "dist/index.html:6-7 — meta description과 title이 Technology Atlas로 고정"
- "dist/app.js:165,177,190,261 — header·footer·home·Lab에서 Technology Atlas 반복"
render-evidence:
- {viewport: 360, path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w360.png, sha256: 0dcfc9446659c936dbd7ccfb9943ae79c3e12abad5431482ced6a99eb74bc444}
- {viewport: 768, path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w768.png, sha256: 5de39c29fc6ad908852ff8e4f0fc36aa5d354b56fa77c609881795dfb5c7bc83}
- {viewport: 1280, path: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w1280.png, sha256: 315eaa89dfe4d65b279196448f7864b621d4a426982093f16118eb9c2138b88b}
- finding-id: MM-R2-02
severity: info
blocking: false
disposition: pass
screen-area: home-hero-copy
observation: >-
“개발자를 위한 인터랙티브 시스템 메커니즘 Lab”이 대상·형식·학습 대상을 한 줄에 규정하고,
바로 이어지는 “실행 전에 원인 가설을 세우고, 증거로 설명합니다.”가 사용자가 기억할 행동과
결과를 제시한다. “두 입구, 하나의 Lost Update Lab”이 이를 구체적 mechanic으로 다시 묶는다.
code-evidence:
- "dist/app.js:190 — descriptor, headline, supporting promise가 같은 hero source에 인접"
render-evidence:
- "360/768/1280 home 모두 descriptor→headline→Lost Update promise 순서를 보존"
- finding-id: MM-R2-03
severity: info
blocking: false
disposition: pass
screen-area: shared-scenario-folio
observation: >-
“두 요청은 성공했는데, 왜 70일까요?”라는 질문과 Initial 100 / Expected 120 / Observed 70의
세 칸 대비가 추상적인 메커니즘을 구체적인 숫자 이야기로 압축한다. 홈에서는 다른 계산값을
전면에 섞지 않아 100→120≠70 anchor가 단일하게 유지된다.
code-evidence:
- "dist/app.js:12-14,181 — scenario 값과 folio의 Initial/Expected/Observed mapping"
render-evidence:
- "세 viewport 모두 headline 근처의 Shared scenario folio에서 100/120/70을 같은 label로 노출"
- finding-id: MM-R2-04
severity: info
blocking: false
disposition: pass
screen-area: responsive-home-message-sequence
observation: >-
768/1280에서는 headline과 수치 folio가 한 시야에 결합되고, 360에서는 같은 요소가 headline 다음,
entry 선택 이전에 순차 배치된다. 따라서 viewport에 따라 카피가 바뀌거나 핵심 수치가 entry 뒤로
분리되지 않아 회상 묶음의 순서와 의미가 유지된다.
code-evidence:
- "dist/app.js:190 — 모든 viewport가 같은 home message source를 사용"
render-evidence:
- "preview.w360.png / preview.w768.png / preview.w1280.png의 hash-bound home 비교"
limitation: >-
외부 네트워크·경쟁 비교·사용자 회상 테스트 없이 artifact 내부의 명료성, 반복성, mechanic-aligned
anchor만 판정했다.
@@ -0,0 +1,124 @@
report-type: workflow-artifact
artifact-kind: design-lens-review
artifact-version: 1
identity:
artifact-id: GTM-PMM-20260718T140000Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: GTM-PMM
created-at: 20260718T140000Z
attempt-id: 1
verdict: pass
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
target-prototype-id: ENG-FE-20260718T135811Z
target-prototype-sha256: 735d588bef412dd3c59899d393562ae76a67a55bbe9f507ddf38eeab1481e9f0
target-prototype-ref: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T135811Z.report.yaml
reviewer-role-id: GTM-PMM
reviewer-run-id: ea3b9ab06b3aa423358b9d2966daed0ad18331593eefea8836521e0eb712342b
context-package-ref: hyeonworks/state/context-packages/hyeonworks-vnext-v1-direction/GTM-PMM-20260718T135945Z.pkg.yaml
context-package-sha256: ea3b9ab06b3aa423358b9d2966daed0ad18331593eefea8836521e0eb712342b
lens: market-memorability
verdict: pass
review-scope:
surface: public-home
viewports: [360, 768, 1280]
excluded-from-message-judgment:
- tx-lost-update-inventory-fixture
claim-boundary: >-
렌더에 나타난 메시지 위계와 반복 단서로 구조적 회상 가능성만 판정하며,
실제 사용자 회상률이나 학습 효과는 주장하지 않는다.
public-message-bundle:
name: Technology Atlas
byline: by Hyeonworks
category: 개발자를 위한 인터랙티브 시스템 메커니즘 Lab
headline: 실행 전에 원인 가설을 세우고, 증거로 설명합니다.
mechanic-question: 두 요청은 성공했는데, 왜 70일까요?
mechanic-anchor:
initial: 100
expected: 120
observed: 70
reinforcement:
- 두 입구, 하나의 Lost Update Lab
- Same Lab · tx-lost-update-01
- Predict → Observe → Compare → Explain → Transfer
viewport-assessment:
- viewport: 360
verdict: pass
observation: >-
Technology Atlas, 카테고리, 헤드라인, Lost Update 설명, 두 입구·하나의 Lab 약속,
100/120/70 folio가 같은 순서로 온전히 보인다. folio는 세로 적층되지만 입구 선택 영역보다
먼저 배치되어 메시지와 수치 단서의 결속을 유지한다.
- viewport: 768
verdict: pass
observation: >-
이름과 카테고리·헤드라인이 왼쪽, 100/120/70 질문 folio가 오른쪽에 동시 노출된다.
바로 아래 두 entry와 Same Lab 표지가 숫자 모순을 하나의 Lost Update 학습 메커니즘으로 회수한다.
- viewport: 1280
verdict: pass
observation: >-
넓은 hero에서도 동일한 이름·카테고리·헤드라인과 100/120/70 folio가 한 시야에 유지되고,
추가 제품명이나 경쟁 약속 없이 두 entry와 5단계 학습 루프로 이어진다.
assessment:
- criterion: single-public-name
verdict: pass
rationale: >-
세 렌더의 최상단 이름은 Technology Atlas 하나이며 by Hyeonworks는 명확한 보조 서명이다.
Lost Update Lab과 Shared/Same Lab은 시나리오·mechanic 표지로 읽혀 별도 제품명과 경쟁하지 않는다.
- criterion: category-clarity
verdict: pass
rationale: >-
개발자 대상, 인터랙티브 형식, 시스템 메커니즘이라는 세 요소가 헤드라인 직전에 고정되어
Atlas라는 넓은 이름을 구체적인 제품 카테고리로 좁힌다.
- criterion: headline-ownability
verdict: pass
rationale: >-
실행 전에 가설을 고정하고 증거로 설명한다는 동사 쌍이 Predict/Observe/Compare/Explain/Transfer와
직접 이어져 장식적 슬로건이 아니라 실제 사용 방식으로 재확인된다.
- criterion: mechanic-anchor
verdict: pass
rationale: >-
Initial 100, Expected 120, Observed 70과 “두 요청은 성공했는데 왜 70인가”라는 모순이
Lost Update를 설명 없이도 질문 형태로 기억하게 하는 가장 구체적인 단서다.
- criterion: cross-viewport-consistency
verdict: pass
rationale: >-
360은 세로 적층, 768·1280은 좌우 병치로 레이아웃만 달라지고 이름·카테고리·헤드라인·수치·순서는
바뀌지 않는다. 따라서 viewport별 copy drift나 mechanic 분리는 없다.
findings:
- id: MM-R3-01
severity: non-blocking
disposition: monitor
finding: >-
360에서는 100/120/70 folio가 headline과 같은 가로 장면이 아니라 hero copy와 약속 뒤에 적층되어
넓은 화면보다 즉시 동시 노출이 약하다.
verdict-impact: >-
수치 folio가 입구 선택보다 앞에 있고 문구·값이 손실되지 않아 현재 판정을 revise로 낮출 정도는 아니다.
report-header:
bottom-line: >-
PASS — 공개 home은 360/768/1280 모두 Technology Atlas라는 단일 이름, 개발자용 인터랙티브
시스템 메커니즘 Lab이라는 카테고리, “실행 전에 원인 가설을 세우고, 증거로 설명합니다”라는 약속,
Initial 100 / Expected 120 / Observed 70 질문을 하나의 위계로 유지한다. 숫자 모순이 Lost Update와
두 입구·같은 Lab mechanic을 구체화하므로 구조적 회상 가능성이 충분하다.
decision-needed: { needed: false, approver: null }
confidence: { value: Med, derived-from: three-hash-bound-home-renders-and-default-public-render-source }
risks:
- "실제 사용자 회상 테스트가 없으므로 관찰된 메시지 위계를 실제 회상률로 확대 해석할 수 없다."
- "360에서는 수치 folio가 hero 본문 뒤에 세로 적층되어 768·1280보다 첫 장면의 즉시 동시 노출이 약하다."
- "Technology Atlas라는 이름만 떼어 쓰면 범위가 넓으므로 현재 카테고리·헤드라인·100/120/70 anchor를 한 묶음으로 유지해야 한다."
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T135811Z.report.yaml
grade: E3
note: "exact target ENG-FE-20260718T135811Z / 735d588bef412dd3c59899d393562ae76a67a55bbe9f507ddf38eeab1481e9f0 및 세 preview SHA 결속"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w360.png
grade: E3
note: "sha256 0dcfc9446659c936dbd7ccfb9943ae79c3e12abad5431482ced6a99eb74bc444; 공개 home의 단일 이름·카테고리·headline·100/120/70 세로 위계"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w768.png
grade: E3
note: "sha256 5de39c29fc6ad908852ff8e4f0fc36aa5d354b56fa77c609881795dfb5c7bc83; 동일 메시지와 수치 folio의 좌우 병치"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w1280.png
grade: E3
note: "sha256 315eaa89dfe4d65b279196448f7864b621d4a426982093f16118eb9c2138b88b; 동일 묶음과 두 entry·Same Lab·5단계 reinforcement"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/app.js
grade: E3
note: "default public scenario가 tx-lost-update-01이고 renderHome이 Technology Atlas/category/headline/100·120·70 bundle을 동일 데이터로 구성함"
@@ -0,0 +1,90 @@
report-type: workflow-artifact
artifact-kind: design-lens-review
artifact-version: 1
identity:
artifact-id: GTM-PMM-20260718T145000Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: GTM-PMM
created-at: 20260718T145000Z
attempt-id: 1
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
target-prototype-id: ENG-FE-20260718T144700Z
target-prototype-sha256: 8b208279e12f9aea0fa6d7a3c320811b0e72ddb74c6afac64cddadf4b157cf76
reviewer-role-id: GTM-PMM
reviewer-run-id: 82488e67545d8401fa217e7e28fc1f600dcbb378af719354f74a58a530c55388
lens: market-memorability
verdict: pass
findings:
- id: MM-R4-01
severity: note
area: "home header, hero descriptor, Lab breadcrumb"
evidence: >-
360·1280 home에서 TECHNOLOGY ATLAS BY HYEONWORKS가 최상단에 고정되고,
'개발자를 위한 인터랙티브 시스템 메커니즘 LAB'과
TECHNOLOGY ATLAS / CONCURRENCY / TRANSACTION ISOLATION / LOST UPDATE가
제품명→카테고리→이번 주제 순서로 반복된다.
assessment: >-
포괄적인 제품명 Technology Atlas가 구체적인 developer mechanism Lab 카테고리와
결합돼 무엇을 위한 제품인지 회수할 단서가 충분하다. 이름과 카테고리가 충돌하지 않는다.
- id: MM-R4-02
severity: note
area: "home promise and five-phase learning loop"
evidence: >-
home의 '실행 전에 원인 가설을 세우고, 증거로 설명합니다.'가 Lab의
Predict → Observe → Compare → Explain → Transfer 순서와 각 상태의 실제 동사형 과제로
끝까지 이어진다.
assessment: >-
추상적인 '깊이 학습' 대신 가설을 먼저 고정하고 증거로 설명한다는 행동 약속이
반복 경험으로 입증된다. 제품 약속과 핵심 사용 흐름이 같은 문장으로 기억될 수 있다.
- id: MM-R4-03
severity: note
area: "shared scenario sheet and persistent dark Lab ledger"
evidence: >-
home의 100 initial / 120 expected / 70 observed 시트가 모든 Lab 상태에서
어두운 causal ledger로 지속되고, coral 70과 read/write evidence가 Compare·Explain·Transfer까지
같은 대비 규칙으로 재등장한다.
assessment: >-
100·120·70의 값 차이와 밝은 편집지 위 어두운 증거 원장은 Lost Update를 회상시키는
구체적인 visual mnemonic이다. 장식이 아니라 학습 메커니즘과 직접 결속돼 있다.
- id: MM-R4-04
severity: note
area: "guided-scenario boundary in Lab and completion"
evidence: >-
Lab 원장에는 '고정된 실행 순서를 재현하는 학습용 시나리오'이며 실제 장애 원인을
확정하지 않는다고 명시하고, 완료 화면도 자유 서술 능력이나 실제 장애 진단을
증명하지 않는다고 다시 제한한다.
assessment: >-
debugger 감각은 증상·가설·증거의 학습 방식으로만 쓰이고 원격 DB 분석이나 자동 진단
약속으로 팽창하지 않는다. 이름·약속·mnemonic을 훼손하지 않으면서 신뢰 경계를 보존한다.
residual-observation: >-
Technology Atlas라는 이름만 단독 노출되면 범위가 넓게 읽힐 수 있으므로 향후 주제 확장에서도
developer mechanism Lab descriptor와 evidence-loop 언어를 함께 유지해야 한다. 현재 R4 화면에서는
이 결속이 일관돼 승인 차단 사유가 아니다.
report-header:
bottom-line: >-
R4는 Technology Atlas라는 이름을 developer mechanism Lab 카테고리, '가설을 세우고 증거로
설명한다'는 약속, 100·120·70 causal ledger mnemonic에 일관되게 결속하며 guided scenario 경계도
반복해 시장 기억성 렌즈를 통과한다.
decision-needed: {needed: false, approver: null}
confidence: {value: Med, derived-from: exact-R4-home-and-six-state-responsive-renders-without-external-market-claims}
risks:
- >-
실제 고객의 비보조 회상률·카테고리 이해도·선호도는 사용자 조사 없이 검증됐다고 주장할 수 없다.
- >-
향후 주제가 늘 때 Technology Atlas만 남고 mechanism Lab·evidence-loop descriptor가 사라지면
넓은 이름이 카테고리 구체성을 약화할 수 있다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T144700Z.report.yaml
grade: E3
note: "exact R4 winner SHA 8b208279… and revision-4 closure"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w360.png
grade: E3
note: "mobile name, category, promise, shared-scenario mnemonic and entry hierarchy"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w1280.png
grade: E3
note: "desktop name/category/promise hierarchy and dual-entry shared-Lab framing"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews
grade: E3
note: "Predict through Complete at 360 and 1280; persistent ledger mnemonic and honest boundary"
@@ -0,0 +1,36 @@
report-type: workflow-artifact
artifact-kind: method-judgment-review
artifact-version: 1
identity:
artifact-id: UX-RESEARCHER-20260718T111657Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-discovery
producer-role-id: UX-RESEARCHER
created-at: 20260718T111657Z
attempt-id: 1
payload:
method-role-id: DES-PROD
method-id: pre-direction
step-id: discover
gate-id: evidence-grounded
criterion: "제약이 미적 형용사가 아니라 사용자 과업·accepted decision·접근성·제품 경계에 접지됐는가"
reviewed-artifact-id: DES-PROD-20260718T111439Z
reviewed-artifact-sha256: 5305736dbd0a856159732067c0ddcbe4f092fb2124460e4c7988ffeec5e74b13
reviewer-role-id: UX-RESEARCHER
verdict: Passed
findings:
- severity: note
finding: "10초 이해·같은 Lab 합류·키보드/360px 완주가 관찰 가능한 사용자 기준으로 정의됐다."
- severity: note
finding: "구체 visual solution을 선결정하지 않고 네 개의 divergence axis를 보존했다."
- severity: note
finding: "실제 진단 도구 오인을 명시적으로 차단해 symptom entry의 trust boundary가 접지됐다."
report-header:
bottom-line: "PASS — pre-direction framing은 accepted 제품 결정과 구체 사용자 과업·접근성·정직성 기준에 접지됐고 시각 해법을 미리 고정하지 않았다."
decision-needed: { needed: false, approver: null }
confidence: { value: Med, derived-from: exact-artifact-review }
risks: []
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-PROD-20260718T111439Z.report.yaml
grade: E3
note: "exact id+sha reviewed artifact"
@@ -0,0 +1,147 @@
report-type: workflow-artifact
artifact-kind: design-lens-review
artifact-version: 1
identity:
artifact-id: UX-RESEARCHER-20260718T121036Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: UX-RESEARCHER
created-at: 20260718T121036Z
attempt-id: 2
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
target-prototype-id: ENG-FE-20260718T120840Z
target-prototype-sha256: 1cfa4ff43762111f46b0088057f6b902375f86856558056aa5f11f117f107267
reviewer-role-id: UX-RESEARCHER
reviewer-run-id: hyeonworks-vnext-v1-direction-review-usability-20260718T1211Z
lens: usability
verdict: revise
method:
type: expert-usability-inspection
participants: 0
contexts:
- "winner source와 360/768/1280 supplied render 직접 대조"
- "실제 Chrome에서 concept entry와 symptom entry 실행"
- "360px에서 Predict→Observe→Compare→Explain→Transfer 완주"
- "키보드 focus, 오류 회복, mobile overflow, accessibility tree 점검"
inspected-artifacts:
prototype-source: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
implementation:
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/index.html
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/app.js
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/styles.css
renders:
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w360.png
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w768.png
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w1280.png
strengths:
- area: "Home → orientations → shared Lab mental model"
evidence: >-
concept와 symptom 모두 exact #/lab/tx-lost-update-01로 합류했고 fresh run의 initial/current 값은
100/120/100으로 같았다. Home, symptom orientation, Lab에서 guided scenario 경계도 반복됐다.
- area: "Task gates and recovery baseline"
evidence: >-
선택 전 primary action은 disabled이고, Observe 6회를 끝내기 전 Compare로 갈 수 없으며,
오답은 다음 phase를 열지 않았다. Reset은 어느 phase에서도 01 Predict의 동일 초기값으로 복귀했다.
- area: "Responsive completion"
evidence: >-
360px concept entry에서 complete까지 직접 실행했고 home/concept/symptom/lab의 360/768/1280
document scrollWidth가 clientWidth를 넘지 않았다. skip link는 H1로 포커스를 옮겼다.
findings:
- finding-id: UX-U01
severity: high
area: "Lab keyboard focus continuity — choice inputs and Observe 6/6 transition"
evidence:
- >-
Chrome 1280에서 prediction radio에 포커스한 뒤 Space로 120을 고르면 activeElement가 INPUT에서
phase H2로 이동했다. 같은 re-render 경로가 explanation·transfer radio change에도 적용된다.
- >-
Observe 5/6까지는 activeElement가 다음 실행 단계 BUTTON으로 유지됐지만, 6/6 직후에는 BODY가 됐다.
다음 Tab은 새 ‘예측과 결과 비교하기’가 아니라 header brand로 이동했다.
- >-
dist/app.js:180-225에서 모든 choice change가 전체 render를 호출하고, preserveFocus는
[data-action="advance"]만 다시 찾으므로 마지막 advance에서 새 to-compare control로 인계하지 못한다.
action: >-
action별 focus target을 명시한다. choice 변경 시 같은 name/value input을 유지하고, Observe 마지막
event 뒤에는 [data-action="to-compare"]로 포커스를 옮긴다. prediction/explanation/transfer의
Arrow·Space 조작과 6번째 advance를 포함한 keyboard regression test를 추가한다.
- finding-id: UX-U02
severity: medium
area: "Explain/Transfer error feedback and correction consistency"
evidence:
- >-
Chrome에서 잘못된 explanation을 확인하면 시각적 feedback은 삽입되지만 activeElement는 phase H2,
feedback의 role과 aria-live는 null이고 live announcer는 결과가 아닌 Explain 단계.’만 말했다.
- >-
오답 제출 후 정답 radio로 바꾸면 explanationSubmitted가 true로 남아 별도 ‘설명 확인’ 없이
성공 feedback과 to-transfer 버튼이 즉시 나타났다. transfer도 같은 state/render 구조다.
- >-
dist/app.js:51-62,145-156,187-216은 submitted flag를 선택 변경 시 초기화하지 않고 feedback을
일반 div로 렌더하며, non-trace dispatch에는 phase 이름만 announce한다.
action: >-
feedback을 role="status" 또는 동등한 live region으로 연결해 정오·다음 행동을 구체적으로 알리고,
결과로 포커스를 안전하게 이동하거나 설명과 연계한다. 답 변경 시 submitted flag를 false로 되돌려
모든 수정 답을 같은 확인 동작으로 제출하게 한다.
- finding-id: UX-U03
severity: medium
area: "Home mobile/tablet first-entry discoverability"
evidence:
- >-
실제 Chrome 첫 로드에서 first entry card top은 360x800에서 1252.8px(1.57 viewports),
768x900에서 1107.9px(1.23 viewports)였다. 1280x900에서는 834.4px로 첫 viewport 안이었다.
- >-
supplied preview.w360.png와 preview.w768.png에서도 큰 논제와 scenario folio가 entry controls보다
먼저 길게 점유한다. 첫 viewport의 동작 가능한 link는 본문 선택이 아닌 header/skip뿐이다.
action: >-
850px 이하에서는 hero 안에 ‘입구 선택으로 이동’ anchor를 두거나 scenario folio를 entry 뒤로 옮겨
첫 과제 행동을 첫 viewport 가까이에 노출한다. 두 entry의 동일 Lab 약속은 그대로 유지한다.
- finding-id: UX-U04
severity: medium
area: "Observe trace comprehension for assistive and 360px reading"
evidence:
- >-
dist/app.js:136-138의 role=table header row는 span에 columnheader role을 주지 않는다.
Chrome accessibility tree에서 desktop header의 STEP/SESSION/OPERATION/VALUE 노드는 role none으로
ignored됐고 data cells와 header association이 없었다.
- >-
dist/styles.css:46은 360px에서 .trace-head를 display:none 처리해 accessibility tree에서도 네 열
이름이 완전히 사라졌다. 각 행은 cell 값만 남아 ‘—’와 숫자의 열 의미를 재확인하기 어렵다.
action: >-
native table/thead/th(scope=col)/tbody/td를 사용하거나 완전한 ARIA table 관계를 구현한다.
mobile에서는 header를 display:none하지 말고 visually-hidden header 또는 각 cell의 명시적 label로
Step·Session·Operation·Value 의미를 보존한다.
limitations:
- "이 평가는 usability expert inspection이며 모집 사용자 관찰이나 인터뷰가 아니다."
- "학습 성과, 초심자 terminology 이해, 실제 screen reader별 발화 차이는 결론 범위 밖이다."
report-header:
bottom-line: >-
Expert usability inspection에서 concept·symptom 두 입구와 5단계 Lab은 360/768/1280에서
완주 가능했고 상태·교육 경계도 이해 가능했다. 그러나 라디오 선택과 Observe 마지막 단계에서
키보드 포커스가 이탈하고 오류 피드백이 보조기술에 전달되지 않아, panel pass 전 수정이 필요하다.
decision-needed: { needed: false, approver: null }
confidence:
value: Med
derived-from: exact-target-hash-source-review-and-live-chrome-expert-inspection-without-user-participants
risks:
- >-
참여자를 모집한 사용자 테스트가 아니므로 실제 초심자의 이해도, 과제 성공률, 학습 효과와
재방문 기억은 검증하지 않았다.
- >-
screen reader 수동 세션은 수행하지 않았으며 Chrome accessibility tree와 키보드 동작으로만
보조기술 영향을 점검했다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T120840Z.report.yaml
grade: E3
note: "target ENG-FE-20260718T120840Z의 live SHA256=1cfa4ff43762111f46b0088057f6b902375f86856558056aa5f11f117f107267 확인"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/app.js
grade: E3
note: "두 entry, reducer gates, focus/announce/error 경로를 소스와 실제 Chrome 상태 전이로 대조"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w360.png
grade: E3
note: "360px 실제 렌더 직접 점검"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w768.png
grade: E3
note: "768px 실제 렌더 직접 점검"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w1280.png
grade: E3
note: "1280px 실제 렌더 직접 점검"
@@ -0,0 +1,135 @@
report-type: workflow-artifact
artifact-kind: design-lens-review
artifact-version: 1
identity:
artifact-id: UX-RESEARCHER-20260718T131443Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: UX-RESEARCHER
created-at: 20260718T131443Z
attempt-id: 3
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
target-prototype-id: ENG-FE-20260718T131305Z
target-prototype-sha256: bcc557fcd7463349345bd06090868c4c2b6b792453d4e1dddd4ac60b0fa68674
reviewer-role-id: UX-RESEARCHER
reviewer-run-id: b08974977a3f60b7b0ca23bb23d853bb5b2476387bd71a011e20ba145dd35d79
lens: usability
verdict: revise
method:
type: expert-usability-inspection
participants: 0
contexts:
- "exact revision-2 source와 supplied 360/768/1280 및 state previews 직접 대조"
- "실제 Chrome에서 concept·symptom entry와 전체 Lab 실행"
- "360px에서 Tab·Space keyboard-only completion 및 오류 회복 점검"
- "360/768/1280 responsive geometry와 Chrome accessibility tree 점검"
inspected-artifacts:
prototype-source: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
implementation:
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/index.html
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/app.js
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/styles.css
renders:
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w360.png
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w768.png
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w1280.png
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.state-concept.png
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.state-symptom.png
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.state-lab.png
- hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews
strengths:
- area: "Dual entry and learning-loop comprehension"
evidence: >-
concept와 symptom 모두 exact #/lab/tx-lost-update-01로 합류했다. symptom 단서 1/4→4/4는
같은 control에 포커스를 유지했고, Predict의 원인 가설이 Compare에 그대로 다시 제시된 뒤
Explain의 세 인과 요소와 Transfer로 이어졌다.
- area: "Keyboard focus, error recovery, and feedback"
evidence: >-
360px Chrome에서 Tab·Space만으로 concept entry부터 Complete까지 완주했다. choice 변경은 선택한
input에 포커스를 유지했고 Observe 6/6은 to-compare 버튼으로 인계했다. Explain·Transfer의 오답
feedback은 role=status로 포커스됐으며 답 수정 시 feedback이 사라지고 재제출을 요구했다.
- area: "Trace semantics"
evidence: >-
Observe accessibility tree에서 STEP/SESSION/OPERATION/VALUE가 columnheader로, 단계 번호가
rowheader로 노출됐다. native table과 phase별 text labels가 색에 의존하지 않고 현재 상태를 전달했다.
findings:
- finding-id: UX-R2-U01
severity: high
area: "360px Lab / Observe responsive trace and primary action"
evidence:
- >-
실제 360x800 Chrome에서 Predict를 고정해 Observe로 들어가면 document clientWidth는 360px인데
scrollWidth는 612px가 됐다. workbench는 596px, trace-scroll은 562px, table은 560px로 viewport를
크게 벗어나 전체 페이지를 좌우로 밀어야 했다.
- >-
이 상태에서 trace-scroll의 clientWidth와 scrollWidth가 모두 560px라, aria-label이 안내하는
container 내부 가로 스크롤은 발생하지 않았다. Next action도 늘어난 workbench 폭을 따라 잘렸다.
- >-
dist/styles.css:241,256-257,311-323에서 table min-width:560px와 overflow-x:auto를 두었지만,
mobile .lab-grid를 1fr로 전환하면서 workbench/grid item의 min-width를 0으로 제한하지 않았다.
action: >-
mobile .lab-grid track을 minmax(0,1fr)로 만들고 .workbench 및 .trace-scroll에 min-width:0과
max-width:100%를 적용해 table만 내부에서 스크롤되게 한다. 360px Observe에서 document
scrollWidth===clientWidth, trace-scroll scrollWidth>clientWidth를 동시에 검증하고 Observe state
preview와 regression assertion을 추가한다.
- finding-id: UX-R2-U02
severity: medium
area: "Home / mobile-tablet ‘입구부터 선택하기’ shortcut"
evidence:
- >-
360x800에서 entry title은 처음 1195.7px 아래에 있었고 shortcut은 첫 viewport 안에 보였다.
그러나 keyboard activation 뒤 hash는 #entry-title이 됐어도 activeElement는 hero H1,
scrollY는 256px, entry title의 viewport top은 939.7px여서 목표가 여전히 화면 밖이었다.
- >-
768x900 pointer activation도 scrollY 0, entry title top 706.9px, activeElement H1으로 남아
shortcut이 entry 선택 위치를 유의미하게 열지 못했다.
- >-
dist/app.js:184-190의 href=#entry-title이 hash를 바꾸면 lines 268-279,351의 global hashchange
render가 Home DOM을 다시 만들고 data-focus-heading H1에 포커스를 주어 anchor 이동을 덮어쓴다.
action: >-
shortcut activation에서 route render를 일으키지 말고 #entry-title을 tabindex=-1 target으로
직접 focus/scroll한다. 또는 local-anchor hash를 hashchange router에서 별도로 처리한다.
360/768의 keyboard와 pointer에서 target이 viewport 상단 근처에 있고 activeElement가 target인지
회귀 검증한다.
limitations:
- "이 결과는 usability expert inspection이며 모집 사용자 관찰·인터뷰가 아니다."
- "학습 효과와 실제 초심자의 용어 이해, screen-reader별 발화 차이는 검증하지 않았다."
report-header:
bottom-line: >-
Revision 2의 dual-entry, 인과 학습 루프, keyboard focus·feedback·table semantics는 실제 Chrome에서
완주 가능했다. 그러나 360px Observe가 612px document overflow를 만들고 mobile entry shortcut도
목표로 이동하지 않아, usability pass 전 responsive·anchor routing 수정이 필요하다.
decision-needed: { needed: false, approver: null }
confidence:
value: Med
derived-from: exact-winner-hash-supplied-state-renders-and-live-chrome-expert-inspection-without-participants
risks:
- >-
참여자를 모집하지 않았으므로 초심자의 실제 과제 성공률, 이해도, 인지 부담과 학습 효과는
이 verdict가 검증하지 않는다.
- >-
Chrome accessibility tree와 keyboard flow는 점검했지만 screen reader 제품별 수동 발화 세션은
수행하지 않았다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T131305Z.report.yaml
grade: E3
note: "exact target id와 live SHA256=bcc557fcd7463349345bd06090868c4c2b6b792453d4e1dddd4ac60b0fa68674 확인"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/app.js
grade: E3
note: "dual-entry, reducer gates, focus restoration, feedback와 hash routing을 실제 Chrome 동작과 대조"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/styles.css
grade: E3
note: "360/768/1280 live geometry와 Observe min-content overflow 원인을 대조"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews
grade: E3
note: "Predict/Compare/Explain/Transfer/Complete의 360·1280 supplied state renders 직접 점검"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w360.png
grade: E3
note: "360px Home supplied render 직접 점검"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w768.png
grade: E3
note: "768px Home supplied render 직접 점검"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/preview.w1280.png
grade: E3
note: "1280px Home supplied render 직접 점검"
@@ -0,0 +1,150 @@
report-header:
bottom-line: >-
PASS — exact R3 target ENG-FE-20260718T135811Z /
735d588bef412dd3c59899d393562ae76a67a55bbe9f507ddf38eeab1481e9f0는 usability gate를 통과한다.
Chrome 150 독립 재현에서 360 Observe는 document 폭 360px를 유지한 채 trace만 292→560px로
내부 스크롤됐고, 360 keyboard·768 pointer entry shortcut, 양 entry의 shared Lab 합류,
Predict→Complete→Reset 전체 keyboard flow와 native/AX semantics가 모두 작동했다.
decision-needed: {needed: false, approver: null}
confidence: {value: Med, derived-from: exact-hash-bound-must-read-plus-independent-live-chrome-and-ax-tree}
risks:
- "Chrome AX tree와 native semantics는 확인했지만 screen-reader 제품별 실제 발화 품질은 수동 검증하지 않았다."
- "통제된 task completion만 검증했으며 모집 사용자 이해도·학습 효과는 주장하지 않는다."
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/ENG-FE-20260718T135811Z.report.yaml
grade: E3
note: "검토 대상 manifest; sha256 735d588bef412dd3c59899d393562ae76a67a55bbe9f507ddf38eeab1481e9f0를 재계산해 exact target을 결속했다."
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews
grade: E3
note: "must-read predict·observe·compare·explain·transfer·complete의 360/1280 12개 렌더를 전부 직접 확인했다."
- command: "node -e <independent usability harness; /usr/bin/google-chrome Chrome/150.0.7871.128; no screenshot writes>"
exit-code: 0
grade: E2
note: "독립 로컬 HTTP/Chrome 세션에서 shortcut, containment, 양 entry, full keyboard, error correction, reset, DOM과 CDP AX tree를 assertion했다."
report-type: workflow-artifact
artifact-kind: design-lens-review
artifact-version: 1
identity:
artifact-id: UX-RESEARCHER-20260718T140000Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: UX-RESEARCHER
created-at: 20260718T140000Z
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
target-prototype-id: ENG-FE-20260718T135811Z
target-prototype-sha256: 735d588bef412dd3c59899d393562ae76a67a55bbe9f507ddf38eeab1481e9f0
reviewer-role-id: UX-RESEARCHER
reviewer-run-id: d304420508e13d58140002ade85a20b5ba65f76807bcb3e1ffb58b53fc944d89
lens: usability
verdict: pass
findings: []
independence:
context-package-ref: hyeonworks/state/context-packages/hyeonworks-vnext-v1-direction/UX-RESEARCHER-20260718T135944Z.pkg.yaml
context-package-sha256: d304420508e13d58140002ade85a20b5ba65f76807bcb3e1ffb58b53fc944d89
prior-lens-reviews-consulted: false
prototype-modified: false
basis: "context package 전체와 그 must-read만 판단 근거로 사용했다."
exact-target-binding:
artifact-id: ENG-FE-20260718T135811Z
artifact-sha256: 735d588bef412dd3c59899d393562ae76a67a55bbe9f507ddf38eeab1481e9f0
prototype-id: hyeonworks-ledger-core-flow-r3
prototype-revision: 3
prototype-sha256: bd2bf67bddde92ae4fa0d329bd21e078625aa343ba59b78fec75f248111d22a1
runtime-files:
app-js-sha256: 4bd59d70b8470263a84c3605db8f61bc88d86eef297dd0643f57365f300ace1b
styles-css-sha256: 1fdf73a63e2d59019ae5a9c348b66858ecc7176daf9f3cc46fee4f91b84a0e10
verify-flow-sha256: e84666f38a7d672c75655b3ed8298e951a139436c84732e27eecad749dd5645e
live-browser-evidence:
browser: Chrome/150.0.7871.128
executable: /usr/bin/google-chrome
mode: "headless=new, actual Chrome, local-only HTTP"
viewport-360-observe:
document: {client-width: 360, scroll-width: 360, window-scroll-x: 0}
workbench-bounds: {left: 16, right: 344}
action-right: 327
trace-before: {client-width: 292, scroll-width: 560, scroll-left: 0}
trace-after-keyboard-arrow-right: {client-width: 292, scroll-width: 560, scroll-left: 120}
focus-after-scroll: trace-scroll
judgment: pass
entry-shortcuts:
viewport-360-keyboard:
visible-in-first-viewport: true
initial-top: 598.1875
tabs-from-document-start: 3
result: {active-id: entry-title, target-top: 37.6875, scroll-y: 1158, same-node: true, hash: ""}
document: {client-width: 360, scroll-width: 360}
focus-ring: {style: solid, width: 3px, color: "rgb(7, 93, 88)"}
judgment: pass
viewport-768-pointer:
shortcut-visible: true
initial-top: 555.875
result: {active-id: entry-title, target-top: 37.9375, scroll-y: 669, same-node: true, hash: ""}
document: {client-width: 768, scroll-width: 768}
judgment: pass
dual-entry:
concept-keyboard-result: {scenario-id: tx-lost-update-01, phase: "01 · Predict"}
symptom-keyboard-result:
revealed-clues-by-button: 4
final-focus-handoff: "a[data-start-lab]"
scenario-id: tx-lost-update-01
judgment: pass
full-keyboard-flow:
path: "home → symptom clues → shared Lab → Predict → Observe(6 steps) → Compare → Explain(error→keyboard correction→success) → Transfer(error→keyboard correction→success) → Complete → Reset"
phase-heading-focus:
- {phase: Predict, focused: "관찰 전에 원인 가설을 고정하세요."}
- {phase: Observe, focused: "두 세션을 한 단계씩 실행하세요."}
- {phase: Compare, focused: "가설과 실행 증거를 대조하세요."}
- {phase: Explain, focused: "세 증거 조각으로 인과를 구성하세요."}
- {phase: Transfer, focused: "새 재고 사례에 적용하세요."}
- {phase: Complete, focused: "세 인과 요소를 연결하고 새 사례에 적용했습니다."}
observe-announcements:
first: "실행 1/6. A가 공유값 100을 읽습니다. 현재 공유값 100."
last: "실행 6/6. B가 공유값을 70으로 덮어씁니다. 현재 공유값 70."
feedback-focus:
explain-error: {role: status, tabindex: -1, focused: true}
explain-success: {role: status, tabindex: -1, focused: true}
transfer-error: {role: status, tabindex: -1, focused: true}
transfer-success: {role: status, tabindex: -1, focused: true}
stale-feedback-after-keyboard-correction: absent
reset-result: {phase: Predict, focused-phase-heading: true, current-value: 100}
runtime-errors: []
judgment: pass
semantics:
chrome-ax-table:
name: "Lost Update의 단계별 세션, 연산, 값"
column-headers: [STEP, SESSION, OPERATION, VALUE]
row-header-count: 6
trace-region:
tabindex: 0
aria-label: "Lost Update 실행 표, 가로로 스크롤할 수 있습니다"
explanation:
fieldset-count: 3
ax-group-names:
- "1. 두 계산이 시작한 read 기준"
- "2. 공유값에 마지막으로 반영된 write"
- "3. 그 결과 보존되지 않은 변화"
ax-radio-count: 9
announcements: {aria-live: polite, aria-atomic: true}
feedback-role: status
skip-link-target: "#main"
focused-radio-ring: {style: solid, width: 3px, color: "rgb(7, 93, 88)"}
judgment: pass
usability-judgment:
containment: pass
entry-focus-and-scroll: pass
keyboard-operability-and-focus-restoration: pass
feedback-and-error-recovery: pass
native-and-accessibility-tree-semantics: pass
honest-guided-scenario-boundary: pass
blocking-findings: []
rationale: >-
요구된 R3 closure를 독립 Chrome에서 재현했으며 task completion을 막거나 오도하는 usability 결함을
발견하지 못했다. 남은 screen-reader 제품별 발화와 실제 사용자 학습 효과는 검증 범위 밖의 residual risk이지
이 prototype gate를 revise 또는 blocking으로 바꿀 근거가 아니다.
@@ -0,0 +1,98 @@
report-type: workflow-artifact
artifact-kind: design-lens-review
artifact-version: 1
identity:
artifact-id: UX-RESEARCHER-20260718T145000Z
workflow-id: hyeonworks-vnext-v1-direction
stage: design-direction-critique
producer-role-id: UX-RESEARCHER
created-at: 20260718T145000Z
attempt-id: 1
payload:
direction-cycle-id: hyeonworks-vnext-direction-cycle-1
target-prototype-id: ENG-FE-20260718T144700Z
target-prototype-sha256: 8b208279e12f9aea0fa6d7a3c320811b0e72ddb74c6afac64cddadf4b157cf76
reviewer-role-id: UX-RESEARCHER
reviewer-run-id: e821d474bc30c9a4d4b16925e1d596cfd8901397bb9d24b59b30f17ac0bd826c
lens: usability
verdict: pass
findings: []
review-scope:
- task-continuity
- keyboard-and-focus
- accessible-interaction-semantics
- responsive-containment
- route-safe-skip-link
checks:
exact-target-integrity:
result: pass
evidence: >-
winner report SHA 8b208279…와 그 보고서가 지목한 revision-4 manifest SHA
287bc732…를 로컬 바이트에서 다시 대조했다.
dual-entry-and-task-continuity:
result: pass
evidence: >-
concept와 symptom 진입은 동일 scenario-id의 Predict로 합류한다. Predict → Observe →
Compare → Explain → Transfer → Complete 전체 루프와 기본 6-step, fixture 4-step을
Chrome에서 완주했고, 오답 뒤 수정·재제출과 reset의 상태 경계도 통과했다.
keyboard-and-focus:
result: pass
evidence: >-
native radio/fieldset/legend, button과 link 활성화, 선택 후 동일 control 복귀,
단계 전환 시 heading 이동, Observe 실행 후 다음 action 이동, 오류·성공 feedback 이동을
실제 activeElement assertion으로 확인했다.
skip-link-state-preservation:
result: pass
evidence: >-
home, concept, 단서 2/4가 공개된 symptom, 기본 Lab Observe cursor 1, fixture Lab Observe
cursor 1에서 360/768/1280 keyboard activation을 실행했다. main node identity, hash,
scenario, phase, cursor, trace/clue text가 보존되고 현재 main이 tabindex=-1 focus와
viewport scroll target이 됐다.
responsive-and-table-access:
result: pass
evidence: >-
360px의 모든 학습 상태에서 document 폭이 viewport와 같고 Korean word가 음절 중간에서
갈라지지 않았다. Observe의 native table은 thead, scope=col/row, caption과 이름 있는
tabindex=0 내부 scroll region을 가지며 table만 가로 스크롤되고 작업대와 action은
viewport 안에 남았다. 768px와 1280px에서도 route/focus 흐름을 재검증했다.
feedback-and-boundaries:
result: pass
evidence: >-
aria-live announcer와 role=status feedback이 선택·실행·오답·정답 상태를 침묵 없이 전달하고,
답 변경 시 오래된 제출 feedback이 제거된다. 완료 문구는 통제된 구성·전이 통과와 실제 장애
진단·자유 서술 능력을 구분한다.
browser-run:
command: node scripts/verify_flow.cjs
result: pass
routes:
- home
- concept
- symptom-with-revealed-clue
- default-lab-observe-cursor-1
- fixture-lab-observe-cursor-1
viewports: [360, 768, 1280]
runtime-errors: 0
reviewed-state-images:
directory: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews
states: [predict, observe, compare, explain, transfer, complete]
viewports: [360, 1280]
report-header:
bottom-line: >-
exact R4는 두 진입에서 같은 학습 과제로 합류하고, 키보드 포커스·피드백·모바일 내부 스크롤과
5-route×3-viewport skip-link 상태 보존을 실제 Chrome에서 통과했다. usability와
accessibility interaction 관점의 필수 수정은 남지 않아 pass로 판정한다.
decision-needed: {needed: false, approver: null}
confidence: {value: High, derived-from: exact-target-source-inspection-live-chrome-e2e-and-twelve-state-renders}
risks:
- 실제 사용자 학습효과와 보조기기 제품별 발화 품질은 이번 prototype usability 검증 범위 밖이다.
- 360px Observe 표의 가로 스크롤은 키보드·터치로 조작 가능하지만 플랫폼별 scrollbar 노출성은 후속 사용자 관찰 항목이다.
evidence:
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/scripts/verify_flow.cjs
grade: E3
note: "fresh Chrome pass: full learning loop, keyboard focus, semantics, overflow and 5-route×3-viewport state preservation"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/dist/app.js
grade: E3
note: "native interaction structure, reducer transitions, focus restoration and persistent local skip handler inspected"
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/state-previews
grade: E2
note: "Predict through Complete at 360 and 1280 visually inspected for readable sequence and containment"
@@ -0,0 +1,89 @@
report-type: workflow-artifact
artifact-kind: overall-design
artifact-version: 1
tier: standard
identity:
artifact-id: ARCH-SOLUTION-20260718T151500Z
workflow-id: hyeonworks-vnext-v1
stage: design
producer-role-id: ARCH-SOLUTION
created-at: 20260718T151500Z
attempt-id: 1
payload:
basis-artifact-id: EXEC-CEO-20260718T111108Z
basis-artifact-sha256: 59aa01ae31c922475055d80a11a8facf298c6c7a0b900bbd086cd98324d326a4
source-artifact-refs:
- artifact-id: EXEC-CEO-20260718T111108Z
artifact-sha256: 59aa01ae31c922475055d80a11a8facf298c6c7a0b900bbd086cd98324d326a4
- artifact-id: DES-DIRECTOR-20260718T151300Z
artifact-sha256: ad2120ba2b214a58adc17aac5620c6e19bd727ac4cfd1a48a41c2a75327ff885
summary: >-
Technology Atlas v1은 Lost Update 하나를 깊이 학습하는 zero-dependency 정적 웹 앱이다.
hash route와 명시적 scenario registry, 하나의 reducer가 홈·개념·증상·Lab·완료를 연결한다.
서버·계정·원격 데이터 없이 브라우저 내부 deterministic state만 사용해 제품 약속과 운영 범위를 일치시킨다.
architecture-boundaries:
- id: static-delivery
owns: HTML, CSS, JavaScript와 로컬 정적 서버
excludes: SSR, backend, account, API gateway, remote database
- id: route-controller
owns: hash route 해석, 화면 렌더, route-safe focus 이동
invariant: skip link는 hashchange를 발생시키지 않는다.
- id: scenario-registry
owns: tx-lost-update-01의 단계·trace·clue·transfer 콘텐츠
invariant: concept와 symptom entry가 동일 scenario object를 참조한다.
- id: lab-reducer
owns: entryMode, phase, cursor, prediction, explanation, transfer 상태 전이
invariant: entryMode는 orientation 메타데이터이고 합류 후 reducer를 분기하지 않는다.
- id: verification-fixture
owns: reducer 일반성과 route-state 회귀를 확인하는 짧은 fixture
excludes: 공개 학습 콘텐츠 주장
quality-attributes:
- {attribute: learning-integrity, target: Predict→Observe→Compare→Explain→Transfer 순서와 100·120·150·70 인과 증거 고정}
- {attribute: accessibility, target: 360·768·1280에서 keyboard completion, visible focus, semantic controls, no horizontal overflow}
- {attribute: honesty, target: guided simulation을 실제 진단·로그·원격 DB로 표현하지 않음}
- {attribute: reliability, target: network 없는 로컬 실행에서 deterministic full flow 반복 통과}
- {attribute: maintainability, target: 첫 공개 주제 동안 framework·schema platform 없이 읽을 수 있는 정적 모듈 유지}
- {attribute: performance, target: third-party runtime과 remote asset 요청 0개}
decisions:
- id: ADR-001-STATIC-SPA
choice: zero-dependency hash-routed static app
rationale: 현재 한 주제·로컬 상태 범위에 서버와 framework는 비용만 늘린다.
revisit: 콘텐츠가 세 개를 넘거나 server-backed progress가 승인될 때
- id: ADR-002-SHARED-REDUCER
choice: 두 entry가 동일 scenario와 reducer를 사용
rationale: CEO kill criterion인 두 제품화와 지식 불일치를 구조적으로 막는다.
revisit: 하지 않음; 제품 불변식
- id: ADR-003-STATE-IN-MEMORY
choice: 진행 상태는 현재 세션 메모리에만 유지
rationale: persistence·privacy·migration 설계를 만들지 않고 정직한 범위를 유지한다.
revisit: 사용자 계정/재방문 진행 저장이 별도 결정으로 승인될 때
- id: ADR-004-NATIVE-CONTROLS
choice: button, textarea, anchor, main을 native semantics로 사용
rationale: custom widget의 접근성 복잡도를 피한다.
revisit: 기능적으로 native control로 표현할 수 없는 상호작용이 생길 때
dependencies: []
compatibility-assumptions:
- 최신 evergreen Chrome 계열에서 ES2019 수준 JavaScript와 hashchange를 지원한다.
- 배포 호스트는 정적 파일과 index.html을 제공하며 원격 서비스는 필요하지 않다.
- approved-design-direction의 exact token·interaction·accessibility 계약이 ui-design과 일치한다.
- 실제 사용자 학습성과 측정은 후속 제품 분석이며 v1 자동 검증 범위가 아니다.
conflicts: []
handoff:
implementation: hyeonworks/app 아래의 독립 실행 가능한 정적 앱
required-verification: full dual-entry browser flow, viewport matrix, contrast, keyboard/focus, static network boundary
report-header:
bottom-line: >-
v1은 하나의 deterministic reducer를 중심으로 한 zero-dependency 정적 앱으로 설계한다.
현재 범위에 backend·persistence·범용 콘텐츠 플랫폼을 추가하지 않으면서 학습 깊이와 접근성을 코드로 검증한다.
decision-needed: {needed: false, approver: null}
confidence: {value: High, derived-from: accepted-ceo-basis-approved-direction-and-live-prototype}
risks:
- 단일 app module은 세 번째 주제부터 편집 충돌이 늘 수 있다.
- 메모리 진행 상태는 새로고침 뒤 복구되지 않으며 이는 의도된 v1 경계다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1/EXEC-CEO-20260718T111108Z.report.yaml
grade: E3
note: exact accepted product decision and scope boundaries
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
grade: E3
note: browser-tested implementation evidence for the architecture
@@ -0,0 +1,68 @@
report-type: workflow-artifact
artifact-kind: approved-design-direction
artifact-version: 1
tier: standard
identity:
artifact-id: DES-DIRECTOR-20260718T151300Z
workflow-id: hyeonworks-vnext-v1
stage: design
producer-role-id: DES-DIRECTOR
created-at: 20260718T151300Z
attempt-id: 1
payload:
basis-artifact-id: EXEC-CEO-20260718T111108Z
basis-artifact-sha256: 59aa01ae31c922475055d80a11a8facf298c6c7a0b900bbd086cd98324d326a4
direction-approval:
child-workflow-id: hyeonworks-vnext-v1-direction
approved-direction-id: DES-DIRECTOR-20260718T151100Z
approved-direction-sha256: ce8414dff0472e61961ea77b5930e1e706cf7e4596f8a7d230f3cb4ac18f9abb
selected-direction-id: ledger-studio
winner-prototype-id: ENG-FE-20260718T144700Z
winner-prototype-sha256: 8b208279e12f9aea0fa6d7a3c320811b0e72ddb74c6afac64cddadf4b157cf76
seven-lens-panel-id: DES-DIRECTOR-20260718T150500Z
panel-verdict: pass
visual-thesis: >-
전문 저널의 질문과 causal ledger를 결합해 사용자의 예측과 실제 실행 증거의 차이를 읽게 한다.
비대칭 editorial spread가 제품의 깊이를 표현하고 일반 dashboard·terminal 은유는 사용하지 않는다.
locked-invariants:
- LI-EDITORIAL-EVIDENCE
- LI-DUAL-ENTRY-SHARED-CORE
- LI-EVIDENCE-LEARNING-LOOP
- LI-HONEST-BOUNDARY
- LI-ACCESSIBLE-READING
interaction-contract:
entries: [concept, symptom-debugger]
shared-scenario: tx-lost-update-01
shared-loop: [Predict, Observe, Compare, Explain, Transfer]
route-safe-skip-link: true
fixture-boundary: verification-only
token-contract:
paper: '#f3efe4'
ink: '#1b201e'
deep: '#202724'
observed: '#ad4031'
accent-on-deep: '#ff8873'
pending: '#535c58'
control-border: '#88877e'
normal-text-contrast-min: '4.5:1'
essential-control-contrast-min: '3:1'
scope-boundary:
included: [static educational UI, deterministic Lost Update scenario, local progress state, browser accessibility]
excluded: [real log ingestion, remote database connection, AI diagnosis, accounts, server persistence, public API]
handoff-rule: ui-design과 구현은 이 exact basis와 interaction/token/accessibility 계약을 바꾸지 않는다.
report-header:
bottom-line: >-
7-lens를 통과한 Ledger Studio revision 4를 부모 설계의 유일한 UI 방향으로 승격한다.
두 입구·하나의 Lab, 다섯 단계 학습 루프, 정직한 guided simulation 경계를 구현 계약으로 고정한다.
decision-needed: {needed: false, approver: null}
confidence: {value: High, derived-from: exact-approved-direction-and-seven-lens-browser-backed-panel}
risks:
- 구현 단계가 두 entry를 별도 reducer로 분기하면 승인 방향이 훼손된다.
- 세 번째 주제 전까지는 범용 콘텐츠 플랫폼을 미리 설계하지 않는다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-DIRECTOR-20260718T151100Z.report.yaml
grade: E3
note: exact accepted approved-direction bound to parent
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-DIRECTOR-20260718T150500Z.report.yaml
grade: E3
note: exact seven-lens pass panel
@@ -0,0 +1,86 @@
report-type: workflow-artifact
artifact-kind: ui-design
artifact-version: 1
tier: standard
identity:
artifact-id: DES-VISUAL-20260718T151500Z
workflow-id: hyeonworks-vnext-v1
stage: design
producer-role-id: DES-VISUAL
created-at: 20260718T151500Z
attempt-id: 1
payload:
basis-artifact-id: EXEC-CEO-20260718T111108Z
basis-artifact-sha256: 59aa01ae31c922475055d80a11a8facf298c6c7a0b900bbd086cd98324d326a4
user-flows:
- id: FLOW-CONCEPT
steps: [홈에서 개념 입구 선택, 격리 수준 orientation 읽기, 같은 Lab 시작, Predict, Observe, Compare, Explain, Transfer]
completion: 사용자가 Lost Update 인과를 서술하고 새 사례 전이를 제출한다.
- id: FLOW-SYMPTOM-DEBUGGER
steps: [홈에서 증상 입구 선택, 결과 70 단서 공개, 후보 메커니즘 확인, 같은 Lab 시작, Predict, Observe, Compare, Explain, Transfer]
completion: 실제 진단이 아니라 guided scenario 검증임을 이해한 채 같은 Lab을 완주한다.
- id: FLOW-KEYBOARD
steps: [skip link로 현재 main 이동, 모든 control을 Tab·Enter·Space로 조작, 입력 focus 유지, Transfer 완료]
completion: pointer 없이 전체 경로가 완주된다.
screen-inventory:
- {screen-id: HOME, purpose: 제품 약속과 두 입구를 한 화면에서 제시, route: '#/'}
- {screen-id: ORIENT-CONCEPT, purpose: isolation 약속에서 질문을 형성, route: '#/orient/concept'}
- {screen-id: ORIENT-SYMPTOM, purpose: 70이라는 증상과 후보 단서를 단계적으로 공개, route: '#/orient/symptom'}
- {screen-id: LAB, purpose: 다섯 단계 학습 루프와 causal ledger 실행, route: '#/lab/tx-lost-update-01'}
- {screen-id: COMPLETE, purpose: 설명과 transfer의 완료 상태를 정직하게 요약, route: same Lab state}
state-matrix:
- {state: home, required: [two distinct entries, shared-Lab statement, guided-learning boundary]}
- {state: symptom-hidden, required: [single reveal control, no premature diagnosis claim]}
- {state: symptom-revealed, required: [70 clue, candidate mechanism, same-Lab CTA]}
- {state: predict, required: [editable prediction, locked future evidence]}
- {state: observe-running, required: [100·120·150·70 trace, cursor progression, pending labels]}
- {state: compare, required: [prediction versus observation, lost write causal relation]}
- {state: explain, required: [user-authored causal explanation, prompt does not reveal full answer first]}
- {state: transfer, required: [new-case prompt, user-authored transfer, completion boundary]}
accessibility:
landmarks: skip link targets the currently rendered main without route mutation
keyboard: every interactive state is reachable and operable with native controls
focus: visible focus ring and deterministic focus restoration after render
contrast: normal text 4.5:1 minimum and essential control boundary 3:1 minimum on actual surface
color-independence: value, transaction, observed, pending, and completion have text/shape labels
responsive: 360·768·1280 DOM order preserved with zero document overflow
motion: essential meaning does not depend on animation; reduced motion remains usable
language: Korean words are not split into single-character vertical fragments
design-system-bindings:
- {token: surface.paper, value: '#f3efe4', use: reading canvas}
- {token: content.ink, value: '#1b201e', use: primary paper text}
- {token: surface.deep, value: '#202724', use: evidence Lab}
- {token: evidence.observed, value: '#ad4031', use: observed evidence on light surfaces}
- {token: evidence.on-deep, value: '#ff8873', use: highlighted evidence on deep surface}
- {token: evidence.pending, value: '#535c58', use: pending trace with computed AA contrast}
- {token: control.border, value: '#88877e', use: essential field and choice boundary}
- {component: editorial-spread, rule: asymmetric thesis and ledger; no generic card grid}
- {component: causal-ledger, rule: mono evidence sequence with semantic labels}
- {component: phase-rail, rule: five ordered phases; current and complete text labels}
visual-rationale: >-
기술을 깊게 배운다는 약속을 화려한 dashboard 대신 읽고 표시하고 대조하는 편집 기록으로 표현한다.
serif 논제는 질문의 무게를, mono ledger는 실행 증거의 정밀함을, coral은 예측과 다른 관찰 순간을 담당한다.
모바일에서는 장식적 비대칭보다 인과 읽기 순서를 우선해 단일 열로 수렴한다.
approved-direction-binding:
artifact-id: DES-DIRECTOR-20260718T151300Z
artifact-sha256: ad2120ba2b214a58adc17aac5620c6e19bd727ac4cfd1a48a41c2a75327ff885
prototype-binding:
manifest: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
manifest-sha256: 287bc732d7ddf9076ae8377e9a6824ff1495513a2011b8521fae8036e2c33b77
winner-id: ENG-FE-20260718T144700Z
report-header:
bottom-line: >-
홈·두 orientation·공통 Lab·완료를 하나의 editorial evidence 시스템으로 명세했다.
다섯 단계 상태, keyboard/focus, 실제 surface 대비와 3601280px 읽기 순서를 구현 가능한 계약으로 고정한다.
decision-needed: {needed: false, approver: null}
confidence: {value: High, derived-from: approved-direction-and-r4-browser-viewport-contrast-matrix}
risks:
- editorial 밀도가 모바일에서 과해지지 않도록 각 phase에는 현재 필요한 control만 노출해야 한다.
- fixture route는 검증 전용으로 공개 제품 내비게이션에 노출하지 않는다.
evidence:
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
grade: E3
note: exact R4 manifest with three bound receipts
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1-direction/DES-VISUAL-20260718T145005Z.report.yaml
grade: E3
note: independent visual-craft pass across viewports and states
@@ -0,0 +1,66 @@
report-type: workflow-artifact
artifact-kind: ui-implementation
artifact-version: 1
tier: standard
identity:
artifact-id: ENG-FE-20260718T152400Z
workflow-id: hyeonworks-vnext-v1
stage: build
producer-role-id: ENG-FE
created-at: 20260718T152400Z
attempt-id: 1
payload:
summary: >-
승인된 Ledger Studio revision 4를 hyeonworks/app의 독립 실행 가능한 zero-dependency 정적 앱으로 승격했다.
배포 dist, 로컬 서버, static integrity 검증, 실제 Chrome full-flow 검증과 확인 스크린샷을 포함한다.
source-revision:
kind: source-bundle
sha256: e27731ba712e1c6e7bde4d8600d9ff5abefea09f6909e5b8cbd7153958196ea6
input-bindings:
overall-design: {artifact-id: ARCH-SOLUTION-20260718T151500Z, sha256: 5217e3b3b8b9e3e33d13cd58e88112c32d93cbe9b51af9f919594d9be5f58d83}
approved-design-direction: {artifact-id: DES-DIRECTOR-20260718T151300Z, sha256: ad2120ba2b214a58adc17aac5620c6e19bd727ac4cfd1a48a41c2a75327ff885}
ui-design: {artifact-id: DES-VISUAL-20260718T151500Z, sha256: c1ed02e6b2b128c47f8dd3406f81b690b3d80636fc74eacbf442be7d667c8a4e}
prd: {artifact-id: PROD-PM-20260718T152100Z, sha256: b9f162e7f26dff79e79f018488ad96d839701eec29b5eb5d15e1aad7f59bd627}
acceptance-criteria: {artifact-id: PROD-PO-20260718T152300Z, sha256: ee4ac8fb7807c047b655c1b012b7604431cf075980aa9b41c4018ad2c5681176}
delivered:
app-root: hyeonworks/app
deployable: hyeonworks/app/dist
local-server: hyeonworks/app/scripts/serve.cjs
static-verifier: hyeonworks/app/scripts/verify_static.cjs
browser-verifier: hyeonworks/app/scripts/verify_flow.cjs
screenshots: hyeonworks/app/verification/screenshots
implementation-contract:
runtime-dependencies: 0
remote-assets: 0
public-scenarios: [tx-lost-update-01]
entries: [concept, symptom-debugger]
shared-state-engine: learningReducer
phases: [Predict, Observe, Compare, Explain, Transfer]
supported-viewports: [360, 768, 1280]
honest-boundary: guided simulation only; no live diagnosis, log ingestion, AI, or remote DB
non-goals-preserved: [backend, persistence, account, public API, multi-topic platform, real incident diagnosis]
rollback: hyeonworks/app은 승인 prototype을 변경하지 않은 독립 디렉터리이므로 app 디렉터리만 제외하면 원형이 보존된다.
method-execution:
role-id: ENG-FE
method-id: frontend-implementation
contract-sha256: 0464eead5e973155d003539b00b7b4b5c8b392de952ee16fd22eb63997a38f2d
step-results:
- {step-id: implement-ui, status: completed, output-binding: current-artifact}
report-header:
bottom-line: >-
승인 prototype을 그대로 보존하면서 hyeonworks/app에 배포 가능 dist·zero-dependency 서버·정적/E2E 검증을 갖춘 실제 앱을 구현했다.
decision-needed: {needed: false, approver: null}
confidence: {value: High, derived-from: accepted-spec-byte-identical-r4-dist-and-independent-app-audit}
risks:
- 자동 접근성 실행은 Chrome 중심이며 실제 스크린리더 발화는 잔여 수동 검증 범위다.
- verification fixture hash route는 내비게이션에 노출되지 않지만 dist에 포함돼 있다.
evidence:
- source-uri: hyeonworks/app/README.md
grade: E3
note: runnable production handoff
- source-uri: hyeonworks/app/scripts/verify_flow.cjs
grade: E3
note: full browser regression suite
- source-uri: hyeonworks/app/verification/approved-r4.json
grade: E3
note: exact approved winner file hashes
@@ -0,0 +1,97 @@
report-type: workflow-artifact
artifact-kind: completion-record
artifact-version: 1
tier: standard
identity:
artifact-id: ENG-FE-20260718T152600Z
workflow-id: hyeonworks-vnext-v1
stage: build
producer-role-id: ENG-FE
created-at: 20260718T152600Z
attempt-id: 1
payload:
summary: >-
Technology Atlas의 첫 공개 딥다이브를 hyeonworks/app에 완성했다. 두 entry는 동일 Lost Update Lab과
reducer로 합류하고 Predict→Observe→Compare→Explain→Transfer를 완주한다. 실제 앱 source bundle은
정적 integrity와 headless Chrome 전체 흐름으로 검증됐다.
source-revision:
kind: source-bundle
sha256: e27731ba712e1c6e7bde4d8600d9ff5abefea09f6909e5b8cbd7153958196ea6
primary-artifacts:
- {path: hyeonworks/app/dist/index.html, kind: deployable-html, sha256: 6295b1cf4b5f44cd4e9a5242643712728709ac851d62c4587ef933830bd33861}
- {path: hyeonworks/app/dist/styles.css, kind: production-css, sha256: 71e51b907f5b01c480eb348df35db17995fc45269db36ed6a1afd113e3f29f58}
- {path: hyeonworks/app/dist/app.js, kind: production-javascript, sha256: b148057f4d25ba6afb4170c82f5c832263563feaf99a345a0d79e350d83fbed3}
- {path: hyeonworks/app/scripts/serve.cjs, kind: local-static-server, sha256: 7d60ac663b8e91d19a94fb90a3e1fb4564bcd56fce631e7cb0a998565a5f17e7}
- {path: hyeonworks/app/scripts/verify_static.cjs, kind: static-verifier, sha256: 6bc257fae1b72ce4206f02021f122965833a8d959124cb23e690c401ed7dd842}
- {path: hyeonworks/app/scripts/verify_flow.cjs, kind: browser-e2e-verifier, sha256: b552c6fe5b2336a58a9867d08190aa8d94378f33c697b7712834459f4af2f160}
- {path: hyeonworks/app/package.json, kind: runnable-package-manifest, sha256: ad1a4310e6802db564a23969045fc52d09109190f6fa0fdb78d73798d4cf5aea}
- {path: hyeonworks/app/README.md, kind: operator-handoff, sha256: 9dd5adfc0dc7593a23d2b578edca13bec0384a615f210fd54dd3c31abc96bc9e}
- {path: hyeonworks/app/verification/approved-r4.json, kind: approved-baseline-binding, sha256: e83e47797fb8871cd0dbbdefc5acac2c4b9e9f418f7446d28eb7f27139a6f91f}
acceptance-criteria-coverage:
- criterion-id: AC-DUAL-ENTRY-SHARED-LAB
status: Passed
evidence-receipt-ids: [vr-1784388271-d3001b5d8706]
- criterion-id: AC-FULL-LEARNING-LOOP
status: Passed
evidence-receipt-ids: [vr-1784388271-d3001b5d8706]
- criterion-id: AC-CAUSAL-LEDGER-VALUES
status: Passed
evidence-receipt-ids: [vr-1784388271-d3001b5d8706]
- criterion-id: AC-SYMPTOM-DEBUGGER-HONESTY
status: Passed
evidence-receipt-ids: [vr-1784388271-d3001b5d8706, vr-1784388251-82db6d30415d]
- criterion-id: AC-A11Y-RESPONSIVE-STATE
status: Passed
evidence-receipt-ids: [vr-1784388271-d3001b5d8706]
- criterion-id: AC-DETERMINISTIC-OFFLINE
status: Passed
evidence-receipt-ids: [vr-1784388251-82db6d30415d, vr-1784388271-d3001b5d8706]
verification-receipt-ids:
- vr-1784388251-82db6d30415d
- vr-1784388271-d3001b5d8706
verification-summary:
static: approved R4 file hashes, zero runtime dependency, local-only assets, semantic shell and token markers passed.
browser: dual entry, complete default and fixture loops, error/retry, 360·768·1280, keyboard/focus/skip state, contrast and zero browser errors passed.
contrast: {lab-id: 7.1437, dark-boundary: 5.6157, pending: 5.4403, choice-border: 3.5575, textarea-border: 3.5575}
remaining-risks:
- severity: Low
item: 자동 browser 검증은 Chrome 엔진 중심이며 실제 스크린리더 발화는 수동 잔여 검증이다.
blocking: false
- severity: Low
item: 검증 전용 fixture hash route가 dist에 포함되지만 공개 내비게이션에는 노출되지 않는다.
blocking: false
method-execution:
role-id: ENG-FE
method-id: frontend-implementation
contract-sha256: 0464eead5e973155d003539b00b7b4b5c8b392de952ee16fd22eb63997a38f2d
step-results:
- step-id: implement-ui
status: completed
output-binding: trusted-artifact
artifact-refs:
- {report-id: ENG-FE-20260718T152400Z, sha256: 849cde3678402dcc84fb4020de2b1f53f34139af5e2e6073769b3389352a053a}
- {step-id: verify-ui, status: completed, output-binding: current-artifact}
self-check-results:
- step-id: verify-ui
gate-id: ui-verified
verdict: Passed
evidence-refs: [vr-1784388251-82db6d30415d, vr-1784388271-d3001b5d8706, payload.acceptance-criteria-coverage]
report-header:
bottom-line: >-
COMPLETED — 실제 production source bundle e27731ba…가 여섯 수용 기준을 모두 통과했고,
배포 파일·서버·검증기·실행 안내까지 hyeonworks/app에 완성됐다.
decision-needed: {needed: false, approver: null}
confidence: {value: High, derived-from: typed-static-and-full-browser-receipts-plus-independent-temp-copy-audit}
risks:
- Chrome 이외 엔진과 실제 스크린리더 발화는 비차단 잔여 위험이다.
- 실제 사용자 학습효과는 출시 후 관찰 대상이며 이 완료 기록이 대신 주장하지 않는다.
evidence:
- source-uri: hyeonworks/evidence/ledger.jsonl
grade: E3
note: typed build receipts bound to workflow and source revision
- source-uri: hyeonworks/app/scripts/verify_flow.cjs
grade: E3
note: executable full-flow assertions
- source-uri: hyeonworks/app/verification/approved-r4.json
grade: E3
note: exact approved baseline hashes
@@ -0,0 +1,86 @@
report-type: workflow-artifact
artifact-kind: completion-record
artifact-version: 1
tier: standard
identity:
artifact-id: ENG-FE-20260718T153900Z
workflow-id: hyeonworks-vnext-v1
stage: build
producer-role-id: ENG-FE
created-at: 20260718T153900Z
attempt-id: 2
supersedes-report-id: ENG-FE-20260718T152600Z
payload:
summary: >-
verification에서 발견한 responsive reflow와 진행 중 smooth scroll 사이의 skip-link 타이밍 회귀를 닫은
production hardening revision이다. 현재 main focus·route·학습 상태 보존은 그대로 유지하고,
main 시작과 첫 제목의 실제 가시성을 viewport layout 안정화 뒤 검증한다.
source-revision:
kind: source-bundle
sha256: 276b49194885f7f2c7072732095294c36f804512032e20af54c1234ca3de26cb
primary-artifacts:
- {path: hyeonworks/app/dist/index.html, kind: deployable-html, sha256: 6295b1cf4b5f44cd4e9a5242643712728709ac851d62c4587ef933830bd33861}
- {path: hyeonworks/app/dist/styles.css, kind: production-css, sha256: 71e51b907f5b01c480eb348df35db17995fc45269db36ed6a1afd113e3f29f58}
- {path: hyeonworks/app/dist/app.js, kind: production-javascript, sha256: ff85c317c9579e341a0f98cf4371a64937b13be2a21c2ac244466a630dfe6e17}
- {path: hyeonworks/app/scripts/serve.cjs, kind: local-static-server, sha256: 7d60ac663b8e91d19a94fb90a3e1fb4564bcd56fce631e7cb0a998565a5f17e7}
- {path: hyeonworks/app/scripts/verify_static.cjs, kind: static-verifier, sha256: 888f43084a2a9fdd4678868bdb4f6289556c0d5e4d4a9e74442e19c9d9925e26}
- {path: hyeonworks/app/scripts/verify_flow.cjs, kind: browser-e2e-verifier, sha256: 3b3816cd70e5f6061059cc667feb10d8b0a84c1dbbe2d734c950dc7e37c47147}
- {path: hyeonworks/app/package.json, kind: runnable-package-manifest, sha256: ad1a4310e6802db564a23969045fc52d09109190f6fa0fdb78d73798d4cf5aea}
- {path: hyeonworks/app/README.md, kind: operator-handoff, sha256: 8ec55a62f70fc7e3b8c1e794b96fd9ab22681be30e43ba391360ccd79fb74ad9}
- {path: hyeonworks/app/verification/approved-r4.json, kind: baseline-and-hardening-provenance, sha256: 08a414ab22b97394477106df6ab2794b3f55b2914b51ed3191527f503993a8e1}
acceptance-criteria-coverage:
- {criterion-id: AC-DUAL-ENTRY-SHARED-LAB, status: Passed, evidence-receipt-ids: [vr-1784389079-234063b3e56d]}
- {criterion-id: AC-FULL-LEARNING-LOOP, status: Passed, evidence-receipt-ids: [vr-1784389079-234063b3e56d]}
- {criterion-id: AC-CAUSAL-LEDGER-VALUES, status: Passed, evidence-receipt-ids: [vr-1784389079-234063b3e56d]}
- {criterion-id: AC-SYMPTOM-DEBUGGER-HONESTY, status: Passed, evidence-receipt-ids: [vr-1784389079-234063b3e56d, vr-1784389087-77f25d28672d]}
- {criterion-id: AC-A11Y-RESPONSIVE-STATE, status: Passed, evidence-receipt-ids: [vr-1784389079-234063b3e56d]}
- {criterion-id: AC-DETERMINISTIC-OFFLINE, status: Passed, evidence-receipt-ids: [vr-1784389087-77f25d28672d, vr-1784389110-f7cccb4db1b0]}
verification-receipt-ids:
- vr-1784389079-234063b3e56d
- vr-1784389087-77f25d28672d
- vr-1784389110-f7cccb4db1b0
revision-closure:
detected-by: vr-1784388413-a071334f9199 and reliability reruns
cause: exact-pixel assertion raced responsive header reflow while an earlier smooth scroll was still active.
production-fix: skip activation cancels smooth behavior, directly aligns current main, and holds auto scrolling through a settle window.
verifier-fix: viewport layout settles for two animation frames and checks main-start tolerance plus first-heading visibility instead of brittle exact-zero pixels.
repeat-proof: two unwrapped npm test passes followed by source-bound AC, static, and reliability receipts.
contrast: {lab-id: 7.1437, dark-boundary: 5.6157, pending: 5.4403, choice-border: 3.5575, textarea-border: 3.5575}
remaining-risks:
- {severity: Low, item: Chrome 중심 자동화이며 실제 스크린리더 발화와 비-Chromium 엔진은 수동 잔여 검증이다., blocking: false}
- {severity: Low, item: 검증 fixture hash route가 dist에 포함되지만 공개 내비게이션에는 노출되지 않는다., blocking: false}
method-execution:
role-id: ENG-FE
method-id: frontend-implementation
contract-sha256: 0464eead5e973155d003539b00b7b4b5c8b392de952ee16fd22eb63997a38f2d
step-results:
- step-id: implement-ui
status: completed
output-binding: trusted-artifact
artifact-refs:
- {report-id: ENG-FE-20260718T152400Z, sha256: 849cde3678402dcc84fb4020de2b1f53f34139af5e2e6073769b3389352a053a}
- {step-id: verify-ui, status: completed, output-binding: current-artifact}
self-check-results:
- step-id: verify-ui
gate-id: ui-verified
verdict: Passed
evidence-refs: [vr-1784389079-234063b3e56d, vr-1784389087-77f25d28672d, vr-1784389110-f7cccb4db1b0, payload.revision-closure]
report-header:
bottom-line: >-
COMPLETED revision 2 — verification에서 발견된 skip-link/reflow 타이밍 회귀를 재현·교정했고,
최종 source 276b4919…가 전체 flow·static integrity·반복 reliability를 모두 통과했다.
decision-needed: {needed: false, approver: null}
confidence: {value: High, derived-from: reproduced-failure-source-bound-fix-and-consecutive-full-suite-passes}
risks:
- 비-Chromium과 실제 스크린리더 발화는 비차단 잔여 위험이다.
- 실제 사용자 학습효과는 출시 후 관찰 대상이며 자동 검증으로 대신 주장하지 않는다.
evidence:
- source-uri: hyeonworks/evidence/ledger.jsonl
grade: E3
note: final source-bound AC, test and reliability receipts plus preserved failure receipts
- source-uri: hyeonworks/app/scripts/verify_flow.cjs
grade: E3
note: responsive layout settle, main-state preservation and first-heading visibility assertions
- source-uri: hyeonworks/app/verification/approved-r4.json
grade: E3
note: approved winner provenance and explicit post-approval production hardening
@@ -0,0 +1,50 @@
report-type: workflow-artifact
artifact-kind: workload-profile
artifact-version: 1
identity:
artifact-id: EXEC-CEO-20260718T110454Z-1
workflow-id: hyeonworks-vnext-v1
stage: intake
producer-role-id: EXEC-CEO
created-at: 20260718T110454Z
attempt-id: 2
payload:
surfaces:
ui: true
public-api: false
persistence: false
infrastructure: false
risk:
security-bearing: false
data-migration: false
external-side-effect: false
risk-level: Med
reversibility: two-way-door
blast-radius: single-role
privacy: false
regulatory: false
slo-impact: false
pii: false
data-residency: false
customer-impact: false
revenue-impact: false
required-capabilities: [product-strategy, learning-design, product-design, frontend-engineering, accessibility-qa]
product-feature: true
context-scope: company
delivery-profile:
target-repo: hyeonworks
application-root: hyeonworks/app
implementation: "browser-local deterministic learning product"
verification: [static-contract, production-build, browser-e2e, keyboard-a11y, responsive-render]
report-header:
bottom-line: >-
UI-bearing 표준 제품 작업이다. 외부 API·영속성·인프라·개인정보는 범위 밖이며, frontend와 학습 설계,
접근성 QA에 집중한다.
decision-needed: { needed: false, approver: EXEC-CEO }
confidence: { value: Med, derived-from: explicit-company-context-and-bounded-surface-contract }
risks:
- "브라우저 로컬 시뮬레이션을 실제 데이터베이스 동작 보증처럼 표현하면 신뢰를 훼손한다."
evidence:
- source-uri: org-os/01-company/company-context.yaml
grade: E2
note: "공식 제품 범위·trust boundary·project manifest"
@@ -0,0 +1,48 @@
report-type: workflow-artifact
artifact-kind: decision-brief
artifact-version: 1
identity:
artifact-id: EXEC-CEO-20260718T110454Z
workflow-id: hyeonworks-vnext-v1
stage: intake
producer-role-id: EXEC-CEO
created-at: 20260718T110454Z
attempt-id: 1
payload:
mode: divergent
tier: standard
candidate-families: [FAM-STRATEGY, FAM-PRODUCT, FAM-DESIGN, FAM-ARCHITECTURE-TECH, FAM-ENG-FRONTEND, FAM-QA]
objective: >-
확정된 Atlas + limited symptom-first shared-core 전략을 실제로 학습 가능한 Hyeonworks vNext 제품으로
설계·구현한다. 첫 범위는 Transaction Isolation / Lost Update이며 두 진입은 동일 실험을 공유한다.
company-context-ref: org-os/01-company/company-context.yaml
venture-decision-id: EXEC-CEO-20260718T110148Z
company-decision-ids:
- DEC-HW2-HYBRID-001
- DEC-HW2-SCOPE-001
- DEC-HW2-LEARNING-001
- DEC-HW2-BOUNDARY-001
required-outcomes:
- "홈에서 개념으로 시작하기와 증상에서 시작하기의 차이가 명확하다"
- "두 진입이 동일 Lost Update scenario와 학습 상태 엔진으로 합류한다"
- "Predict → Observe → Compare → Explain → Transfer를 키보드와 모바일로 완주한다"
- "증상 단서를 단계적으로 좁히되 실제 장애 확정 도구로 표현하지 않는다"
non-goals:
- "다중 도메인 증상 taxonomy, 실제 로그·DB 연결, AI 진단, 계정·결제·CMS"
- "완성되지 않은 기술 주제를 활성 콘텐츠처럼 표시"
report-header:
bottom-line: >-
새 제품 cascade는 과거 UI를 복원하지 않고, 승인된 hybrid 전략을 바탕으로 discovery부터 새 옵션을
발산한 뒤 디자인 방향·설계·개발·브라우저 검증까지 표준 등급으로 진행한다.
decision-needed: { needed: false, approver: HUMAN-001 }
confidence: { value: Med, derived-from: accepted-company-strategy-with-unbuilt-product }
risks:
- "두 진입이 별도 flow와 콘텐츠로 갈라지면 과도한 설계가 된다."
- "Lost Update 한 사례의 깊이가 부족하면 Atlas도 Debugger도 피상적으로 보일 수 있다."
evidence:
- source-uri: org-os/01-company/company-context.yaml
grade: E2
note: "새 HUMAN-001 승인 hybrid 전략의 공식 SoT"
- source-uri: hyeonworks/completion-records/hyeonworks-company-bootstrap-v2/EXEC-CEO-20260718T110148Z.report.yaml
grade: E3
note: "표준 3안×9-gate 기반 venture decision"
@@ -0,0 +1,99 @@
report-type: workflow-artifact
artifact-kind: executive-decision-packet
artifact-version: 1
tier: standard
identity:
artifact-id: EXEC-CEO-20260718T111108Z
workflow-id: hyeonworks-vnext-v1
stage: decide
producer-role-id: EXEC-CEO
created-at: 20260718T111108Z
attempt-id: 3
payload:
basis-artifact-id: STR-ANALYST-20260718T110705Z
basis-artifact-sha256: df12abd3b459747fbcd396cdb1fb203351e39b79b130c44fe76a3a3facf1fda3
recommendation: >-
GO — OPT-DUAL-PORTAL을 선택한다. 홈은 "개념을 알고 있어요"와 "증상만 알고 있어요"라는
두 출발점을 명확히 제공하되, 짧은 orientation 뒤 동일 tx-lost-update-01 Lab Brief로 합류한다.
이후 URL·scenario data·reducer·학습 콘텐츠·진행 상태·Transfer 과제는 완전히 동일하다.
Case File의 단서 전개는 공통 Lab 서사에만 차용하고, 큰 Atlas 지도는 완성 딥다이브 3개 전까지 보류한다.
selected-option-id: OPT-DUAL-PORTAL
evaluation-criteria:
- "처음 보는 사용자가 10초 안에 제품 목적과 두 출발점의 차이를 이해하는가"
- "두 진입이 하나의 shared core로 합류해 1인 운영성을 지키는가"
- "Lost Update의 깊이 있는 학습과 새 사례 전이를 가능하게 하는가"
- "실제 장애 확정 도구로 오인되지 않는가"
- "360px·키보드·reduced motion까지 단순하고 견고하게 구현 가능한가"
option-evaluations:
- option-id: OPT-DUAL-PORTAL
scores: {clarity: 5, learning-depth: 4, scope-control: 4, shared-core: 5, accessibility: 5}
evidence-refs:
- "STR-ANALYST-20260718T110705Z@df12abd3b459747fbcd396cdb1fb203351e39b79b130c44fe76a3a3facf1fda3"
- "EXEC-CEO-20260718T110148Z@cb7e0e18a80cf6f25bd8be4eeea3933e616e24976b3b27f5c352f93f9bfccf8c"
- option-id: OPT-CASE-FILE
scores: {clarity: 3, learning-depth: 5, scope-control: 5, shared-core: 5, accessibility: 4}
evidence-refs:
- "STR-ANALYST-20260718T110705Z@df12abd3b459747fbcd396cdb1fb203351e39b79b130c44fe76a3a3facf1fda3"
- option-id: OPT-ATLAS-WITH-DEBUG-DOCK
scores: {clarity: 3, learning-depth: 4, scope-control: 3, shared-core: 4, accessibility: 3}
evidence-refs:
- "STR-ANALYST-20260718T110705Z@df12abd3b459747fbcd396cdb1fb203351e39b79b130c44fe76a3a3facf1fda3"
tradeoffs:
- "두 출발점의 명확성을 얻는 대신 홈 선택 부담을 감수하고, '두 입구, 하나의 Lab' 문구로 완화한다."
- "Atlas의 장기 확장성을 짧은 breadcrumb와 roadmap으로만 보여주고 과장된 지도를 만들지 않는다."
- "Case File의 기억 가능한 단서 전개를 취하지만 탐정·incident·확정 진단 시각 언어는 사용하지 않는다."
- "entryMode는 유입 메타데이터로만 유지하고 합류 후 reducer 동작을 분기하지 않는다."
dissent:
- "순수 구현 효율은 OPT-CASE-FILE이 더 높으며 Dual Portal이 두 제품처럼 보이면 선택 근거가 사라진다."
- "사용자 실측 전에는 두 카드가 실제 시작률을 높이는지 알 수 없다."
- "한 주제로 Atlas라는 이름을 쓰는 것 자체가 과장으로 느껴질 가능성이 있다."
kill-criteria:
- "두 진입에 별도 URL progress·scenario·reducer·설명 콘텐츠가 생긴다."
- "사용자 5명 중 3명 이상이 두 출발점의 차이 또는 같은 Lab으로 합류한다는 사실을 설명하지 못한다."
- "사용자 5명 중 3명 이상이 실제 장애 확정 도구로 오인한다."
- "학습 후 3명 이상이 동일 값 읽기 → 독립 계산 → 마지막 쓰기 덮어쓰기 인과를 설명하지 못한다."
- "360px 또는 키보드 전용 환경에서 Transfer까지 완주되지 않는다."
revisit-conditions:
- "Dual Portal 선택 혼란이 관찰되면 OPT-CASE-FILE 단일 화면으로 축소한다."
- "완성형 딥다이브가 3개 이상 쌓이면 OPT-ATLAS-WITH-DEBUG-DOCK 또는 실제 Atlas map을 재평가한다."
- "증상 진입 완주율과 학습 전이가 유지되면 같은 콘텐츠 모델의 두 번째 증상을 검토한다."
evidence-refs:
- "STR-ANALYST-20260718T110705Z@df12abd3b459747fbcd396cdb1fb203351e39b79b130c44fe76a3a3facf1fda3"
- "EXEC-CEO-20260718T110148Z@cb7e0e18a80cf6f25bd8be4eeea3933e616e24976b3b27f5c352f93f9bfccf8c"
- "org-os/01-company/company-context.yaml"
method-execution:
role-id: EXEC-CEO
method-id: decide-direction
contract-sha256: b5d36495b0e7e9a82fab77979a91c0144b1c51dbe1e6153352b6162272bb0d46
step-results:
- {step-id: read-evidence, status: completed, output-binding: current-artifact}
- {step-id: evaluate-options, status: completed, output-binding: current-artifact}
- {step-id: converge-decision, status: completed, output-binding: current-artifact}
self-check-results:
- step-id: converge-decision
gate-id: single-direction
verdict: Passed
evidence-refs: ["payload.selected-option-id", "payload.option-evaluations", "payload.dissent"]
decisions:
- decision-id: HWVNEXT-PRODUCT-DIRECTION-001
selected-option-id: OPT-DUAL-PORTAL
alternatives:
- {option-id: OPT-DUAL-PORTAL}
- {option-id: OPT-CASE-FILE}
- {option-id: OPT-ATLAS-WITH-DEBUG-DOCK}
report-header:
bottom-line: >-
CEO는 Dual Portal을 선택한다. 두 입구를 명확히 보여주되 orientation 직후 하나의 Lost Update Lab으로
합류하고, Case File은 공통 Lab 서사에만 차용하며 큰 Atlas 지도는 보류한다.
decision-needed: { needed: true, approver: HUMAN-001 }
confidence: { value: Med, derived-from: three-independent-lens-reviews-and-accepted-grounding }
risks:
- "두 개의 카드가 두 제품으로 인식될 수 있다."
- "사용자 행동 데이터가 없어 선택 명확성은 디자인·브라우저 검증 후에도 실제 사용자 테스트가 필요하다."
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1/STR-ANALYST-20260718T110705Z.report.yaml
grade: E3
note: "세 experience option과 tradeoff가 보존된 accepted grounding"
- source-uri: hyeonworks/completion-records/hyeonworks-company-bootstrap-v2/EXEC-CEO-20260718T110148Z.report.yaml
grade: E3
note: "accepted company strategy and shared-core boundaries"
@@ -0,0 +1,45 @@
report-type: workflow-artifact
artifact-kind: release-decision
artifact-version: 1
tier: standard
identity:
artifact-id: HUMAN-001-20260718T155500Z
workflow-id: hyeonworks-vnext-v1
stage: acceptance
producer-role-id: HUMAN-001
created-at: 20260718T155500Z
payload:
release-decision: {status: Approved}
unresolved-critical-risks: false
reviewed-completion-artifact-id: ENG-FE-20260718T153900Z
reviewed-completion-artifact-sha256: cec169bd196221d1fe42f29d8f570f277a1872331eb88c489b4477aff1271d44
reviewed-quality-event-id: wfe-20260718T155340Z-3d57e932
reviewed-quality-artifact-id: QA-20260718T155400Z
reviewed-quality-artifact-sha256: 9882d710d65c85ef18ba45deb148a535f1c399b8f3a87ccbb02e42afd99bdfe8
approval-basis:
- full learning flow and responsive keyboard behavior passed on the corrected exact source revision
- static production integrity and deterministic repeat suite passed in the new verification epoch
- the previously blocking skip-link timing regression is resolved with no open blocker
residual-risks:
- {severity: Low, blocking: false, item: non-Chromium engines and actual screen-reader speech remain manual follow-up coverage}
- {severity: Low, blocking: false, item: learning outcome effectiveness requires post-release user observation}
authority-note: >-
The user explicitly requested that the complete workflow be run under an assumed approval so the finished result can be inspected.
report-header:
bottom-line: >-
APPROVED — the corrected completion and its exact current quality event satisfy the standard-tier release gates;
no unresolved Critical risk or open blocker remains.
decision-needed: {needed: false, approver: HUMAN-001}
confidence: {value: High, derived-from: exact-completion-quality-binding-and-user-assumed-approval}
risks:
- Remaining coverage gaps are Low and explicitly non-blocking.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1/ENG-FE-20260718T153900Z.report.yaml
grade: E3
note: accepted corrected completion exact revision
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1/QA-20260718T155400Z.report.yaml
grade: E3
note: current Passed quality gate with resolved blocker
- source-uri: hyeonworks/evidence/ledger.jsonl
grade: E3
note: fresh source-bound verification receipts
@@ -0,0 +1,114 @@
report-type: workflow-artifact
artifact-kind: opportunity-solution-tree
artifact-version: 1
tier: standard
identity:
artifact-id: PROD-PM-20260718T151700Z
workflow-id: hyeonworks-vnext-v1
stage: spec
producer-role-id: PROD-PM
created-at: 20260718T151700Z
attempt-id: 1
payload:
root-outcome:
id: OUTCOME-LOST-UPDATE-TRANSFER
statement: >-
사용자는 guided Lost Update 사례를 끝낸 뒤, 동일 값 읽기 → 독립 계산 → 마지막 쓰기 덮어쓰기라는
인과를 증거 값으로 설명하고 새로운 재고 사례에서 사라진 변경을 스스로 찾아낸다.
observable-completion:
- 예측을 관찰 전에 기록한다.
- 100·120·150·70과 여섯 실행 단계를 근거로 예상과 관찰을 비교한다.
- read basis, final write, lost change를 사용해 인과 설명을 구성한다.
- 별도 재고 사례에서 사라진 변화를 식별해 Transfer를 제출한다.
target-job:
actor: 트랜잭션 동시성 개념을 이름만 알거나 이상한 최종값만 본 학습자
situation: Lost Update를 암기가 아니라 실행 순서와 값의 변화로 이해하고 싶을 때
motivation: 원인을 재구성하고 다른 사례에서도 같은 메커니즘을 판별하고 싶다.
opportunities:
- id: OPP-EVIDENCE-GAP
problem: 용어 설명만으로는 최종값 70이 왜 직렬 기대값 120과 다른지 재구성하기 어렵다.
desired-change: 예측과 실제 READ/WRITE ledger를 나란히 비교한다.
priority: 1
- id: OPP-ENTRY-GAP
problem: 개념명을 아는 사람과 결과 증상만 아는 사람은 시작 질문이 다르다.
desired-change: 두 orientation을 제공하되 하나의 scenario와 reducer로 즉시 합류한다.
priority: 2
- id: OPP-TRANSFER-GAP
problem: 정답 선택만으로는 새 사례에 지식을 옮길 수 있는지 알 수 없다.
desired-change: 설명 구성과 새 재고 사례의 Transfer를 완료 경계로 둔다.
priority: 3
- id: OPP-TRUST-GAP
problem: 증상 진입이 실제 로그 분석이나 장애 확정 기능으로 오인될 수 있다.
desired-change: 모든 증상 단서를 guided simulation으로 명시한다.
priority: 4
solution-hypotheses:
- id: SOL-DUAL-PORTAL-SHARED-LAB
addresses: [OPP-ENTRY-GAP, OPP-EVIDENCE-GAP, OPP-TRANSFER-GAP, OPP-TRUST-GAP]
hypothesis: >-
개념·증상 두 입구와 하나의 deterministic Lab을 결합하면 시작 맥락을 존중하면서도
중복 없이 Predict→Observe→Compare→Explain→Transfer의 깊은 학습을 제공할 수 있다.
selected: true
smallest-testable-scope: Lost Update 한 주제, 브라우저 로컬 상태, 원격 의존성 없음
- id: SOL-SINGLE-CASE-FILE
addresses: [OPP-EVIDENCE-GAP, OPP-TRANSFER-GAP]
hypothesis: 하나의 사건 화면만 제공하면 구현은 단순하지만 두 시작 맥락의 차이가 약해진다.
selected: false
- id: SOL-ATLAS-MAP
addresses: [OPP-ENTRY-GAP]
hypothesis: 관계 지도를 먼저 제공하면 장기 확장은 보이지만 한 주제 v1에서는 범위를 과장한다.
selected: false
scope-boundary:
in:
- tx-lost-update-01 한 주제
- 두 orientation과 동일 Lab 합류
- causal ledger와 다섯 단계 학습 루프
- 키보드·360/768/1280·skip-link 상태 보존
- deterministic offline 실행
out:
- 실제 로그 수집·장애 원인 확정·AI 진단
- 계정·진행 저장·원격 데이터베이스·서버 API
- 세 주제 전에 범용 콘텐츠 플랫폼이나 Atlas map 구축
evidence-bindings:
product-decision:
artifact-id: EXEC-CEO-20260718T111108Z
artifact-sha256: 59aa01ae31c922475055d80a11a8facf298c6c7a0b900bbd086cd98324d326a4
overall-design:
artifact-id: ARCH-SOLUTION-20260718T151500Z
artifact-sha256: 5217e3b3b8b9e3e33d13cd58e88112c32d93cbe9b51af9f919594d9be5f58d83
method-execution:
role-id: PROD-PM
method-id: product-discovery
contract-sha256: 26952bd19d4b39ecf35f674ba2abbcbf5ec14294911ef7f973bd63dc7666ed4a
step-results:
- step-id: frame-outcome
status: completed
output-binding: current-artifact
decisions:
- decision-id: HWVNEXT-SOLUTION-HYPOTHESIS-001
alternatives:
- option-id: SOL-DUAL-PORTAL-SHARED-LAB
evidence-refs: [payload.opportunities, payload.evidence-bindings]
- option-id: SOL-SINGLE-CASE-FILE
evidence-refs: [payload.solution-hypotheses]
- option-id: SOL-ATLAS-MAP
evidence-refs: [payload.scope-boundary]
selected-option-id: SOL-DUAL-PORTAL-SHARED-LAB
rejection-rationales:
SOL-SINGLE-CASE-FILE: 두 시작 맥락을 명확히 지원하지 못한다.
SOL-ATLAS-MAP: 한 주제 v1에 구조와 표현을 과잉 설계한다.
report-header:
bottom-line: >-
v1의 루트 성과는 Lost Update의 인과를 증거로 재구성하고 새 사례로 전이하는 것이다.
이를 위해 두 입구가 하나의 deterministic Lab으로 합류하는 최소 가설을 선택했다.
decision-needed: {needed: false, approver: null}
confidence: {value: High, derived-from: accepted-product-decision-overall-design-and-browser-tested-direction}
risks:
- 실제 사용자 학습성과는 출시 후 별도 관찰이 필요하다.
- 두 입구가 두 제품처럼 보이면 shared-Lab 문구와 orientation 길이를 다시 줄여야 한다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1/EXEC-CEO-20260718T111108Z.report.yaml
grade: E3
note: accepted dual-portal product decision and kill criteria
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1/ARCH-SOLUTION-20260718T151500Z.report.yaml
grade: E3
note: accepted architecture and explicit scope boundary
@@ -0,0 +1,70 @@
report-type: workflow-artifact
artifact-kind: opportunity-solution-tree
artifact-version: 1
tier: standard
identity:
artifact-id: PROD-PM-20260718T152000Z
workflow-id: hyeonworks-vnext-v1
stage: spec
producer-role-id: PROD-PM
created-at: 20260718T152000Z
attempt-id: 1
payload:
outcome: >-
개발자가 Lost Update를 정의로 외우는 데 그치지 않고, 실행 전 결과를 예측한 뒤 100·120·150·70의
read/write 증거로 어긋남을 찾아 세 인과 요소를 설명하고 새 동시성 사례에 전이한다.
opportunities:
- id: OPP-ENTRY-CONTEXT
problem: 사용자는 격리 개념을 알거나 이상 결과만 아는 서로 다른 상태에서 시작한다.
solutions:
- id: SOL-DUAL-ENTRY
hypothesis: 두 orientation이 같은 scenario와 reducer로 합류하면 시작 맥락은 맞추면서 제품 분열을 막는다.
- id: SOL-SINGLE-ARTICLE
hypothesis: 한 문서 입구는 단순하지만 증상 기반 질문을 잃는다.
- id: OPP-PASSIVE-UNDERSTANDING
problem: 정답을 먼저 읽으면 실제 실행 순서와 마지막 write의 영향을 스스로 재구성하기 어렵다.
solutions:
- id: SOL-EVIDENCE-LOOP
hypothesis: Predict→Observe→Compare→Explain→Transfer gate가 능동적 인과 구성을 유도한다.
- id: SOL-REFERENCE-ONLY
hypothesis: 긴 설명은 깊이를 주지만 예측·전이 행동을 증명하지 못한다.
- id: OPP-DEBUGGER-TRUST
problem: 증상에서 시작하는 흐름이 실제 장애 진단 도구로 오인될 수 있다.
solutions:
- id: SOL-GUIDED-DEBUGGER
hypothesis: 단서→후보→고정 Lab 검증과 명시적 guided boundary가 디버거 사고법만 제공한다.
- id: SOL-REAL-LOG-INGESTION
hypothesis: 실제 로그 수집은 v1 범위·보안·데이터 설계를 과도하게 늘려 제외한다.
selected-solution-set: [SOL-DUAL-ENTRY, SOL-EVIDENCE-LOOP, SOL-GUIDED-DEBUGGER]
evidence-basis:
overall-design-id: ARCH-SOLUTION-20260718T151500Z
overall-design-sha256: 5217e3b3b8b9e3e33d13cd58e88112c32d93cbe9b51af9f919594d9be5f58d83
approved-prototype-id: ENG-FE-20260718T144700Z
method-execution:
role-id: PROD-PM
method-id: product-discovery
contract-sha256: 26952bd19d4b39ecf35f674ba2abbcbf5ec14294911ef7f973bd63dc7666ed4a
step-results:
- {step-id: frame-outcome, status: completed, output-binding: current-artifact}
decisions:
- decision-id: HWVNEXT-SOLUTION-SET
selected-option-id: SOL-EVIDENCE-LOOP
alternatives:
- {option-id: SOL-EVIDENCE-LOOP}
- {option-id: SOL-REFERENCE-ONLY}
- {option-id: SOL-REAL-LOG-INGESTION}
report-header:
bottom-line: >-
제품 outcome을 Lost Update 인과를 증거로 설명하고 전이한다’로 고정하고,
두 입구·evidence learning loop·guided debugger를 최소 솔루션 집합으로 선택한다.
decision-needed: {needed: false, approver: null}
confidence: {value: Med, derived-from: accepted-overall-design-and-browser-tested-prototype-without-user-outcome-data}
risks:
- 실제 사용자 학습 성과는 아직 측정하지 않았으므로 자동 완주를 학습효과로 과장하지 않는다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1/ARCH-SOLUTION-20260718T151500Z.report.yaml
grade: E3
note: accepted architecture and quality boundaries
- source-uri: hyeonworks/design-direction/hyeonworks-vnext-v1/prototype/core-flow.yaml
grade: E3
note: browser-tested shared learning loop
@@ -0,0 +1,106 @@
report-type: workflow-artifact
artifact-kind: prd
artifact-version: 1
tier: standard
identity:
artifact-id: PROD-PM-20260718T152100Z
workflow-id: hyeonworks-vnext-v1
stage: spec
producer-role-id: PROD-PM
created-at: 20260718T152100Z
attempt-id: 1
payload:
basis-artifact-id: ARCH-SOLUTION-20260718T151500Z
basis-artifact-sha256: 5217e3b3b8b9e3e33d13cd58e88112c32d93cbe9b51af9f919594d9be5f58d83
problem: >-
기술 학습자는 Transaction Isolation과 Lost Update의 정의를 읽어도, 두 세션이 같은 값을 읽고
독립 계산한 뒤 마지막 write가 앞선 변화를 덮는 실행 인과를 스스로 재구성하기 어렵다.
개념을 아는 사람과 결과 70이라는 증상만 아는 사람 모두에게 맞는 출발점이 필요하지만,
두 개의 제품·진단 엔진·콘텐츠 사본을 만들면 품질과 정직성이 무너진다.
outcomes:
- 사용자가 정답을 보기 전에 기대 결과를 예측한다.
- 사용자가 100→120/150→70 실행 증거에서 동일 read basis, 독립 계산, 마지막 write라는 세 요소를 연결한다.
- 개념·증상 입구 모두 동일 Lost Update Lab과 진행 모델을 완주한다.
- 사용자가 새 재고 사례에서 사라진 변화를 같은 인과 구조로 전이한다.
- 제품이 guided simulation 경계를 명확히 유지한다.
non-goals:
- 실제 로그 수집·분석 또는 장애 원인 확정
- 원격 데이터베이스 연결·쿼리 실행·벤더별 보장 판정
- AI 진단, 계정, 서버 진행 저장, 공개 API
- 여러 기술 주제를 빈 카드나 지도에 미리 채우는 것
- 자동 테스트 통과를 실제 사용자 학습효과로 주장하는 것
user-stories:
- id: US-CONCEPT
story: 격리 개념을 아는 개발자로서 약속과 실행 결과의 차이를 검증해 Lost Update 인과를 정확히 설명하고 싶다.
- id: US-SYMPTOM
story: 기대 120 대신 70이라는 증상만 아는 개발자로서 단서를 공개하고 후보 메커니즘을 고정 Lab에서 검증하고 싶다.
- id: US-PRACTICE
story: 학습자로서 예측부터 전이까지 순서대로 행동해 수동적 읽기가 아니라 내 설명을 만들고 싶다.
- id: US-KEYBOARD
story: 키보드·작은 화면 사용자로서 route나 진행 상태를 잃지 않고 전체 Lab을 완주하고 싶다.
success-metrics:
- id: QUALITY-DUAL-ENTRY
launch-threshold: 두 공개 entry의 browser E2E가 동일 scenario-id와 reducer state에 합류해 100% 통과한다.
- id: QUALITY-CAUSAL-LOOP
launch-threshold: 기본 6-step과 회귀 fixture 4-step이 Predict→Transfer를 deterministic하게 반복 완주한다.
- id: QUALITY-A11Y
launch-threshold: 360·768·1280에서 문서 overflow 0, keyboard completion 100%, normal text 4.5:1 및 control 3:1 이상이다.
- id: QUALITY-HONESTY
launch-threshold: 모든 공개 진입과 완료 상태에 guided scenario 경계가 있고 remote request가 0건이다.
- id: LEARNING-HYPOTHESIS
post-launch-measure: 사용자 5명 중 3명 이상이 세 인과 요소와 새 사례를 설명하는지 별도 관찰한다; 출시 자동 게이트가 아니다.
constraints:
- zero runtime dependency와 정적 배포를 유지한다.
- 주제는 Transaction Isolation / Lost Update 하나로 제한한다.
- concept와 symptom entry는 scenario data·reducer·학습 콘텐츠를 복제하지 않는다.
- 360px, keyboard, visible focus, reduced motion, 한국어 읽기 순서를 보존한다.
- 실제 로그·원격 DB·AI 진단처럼 표현하지 않는다.
prioritized-requirements:
- {id: R1, priority: P0, requirement: 두 입구가 하나의 tx-lost-update-01 Lab에 합류한다.}
- {id: R2, priority: P0, requirement: Predict→Observe→Compare→Explain→Transfer 순서와 gate를 유지한다.}
- {id: R3, priority: P0, requirement: 100·120·150·70과 read/write 순서를 causal ledger로 관찰한다.}
- {id: R4, priority: P0, requirement: symptom debugger는 단서·후보·검증을 제공하되 실제 진단을 주장하지 않는다.}
- {id: R5, priority: P0, requirement: 반응형·keyboard·focus·skip-link state·contrast를 자동 검증한다.}
- {id: R6, priority: P1, requirement: static local-only delivery와 deterministic regression fixture를 유지한다.}
delivery-boundary:
inspectable-app: hyeonworks/app
first-public-topic: Transaction Isolation / Lost Update
method-execution:
role-id: PROD-PM
method-id: product-discovery
contract-sha256: 26952bd19d4b39ecf35f674ba2abbcbf5ec14294911ef7f973bd63dc7666ed4a
step-results:
- step-id: frame-outcome
status: completed
output-binding: trusted-artifact
artifact-refs:
- {report-id: PROD-PM-20260718T152000Z, sha256: f8af0e1bbaedf87dd955d663cad887545c1efc7347f0908942400707000b0045}
- {step-id: write-prd, status: completed, output-binding: current-artifact}
self-check-results:
- step-id: write-prd
gate-id: outcome-grounded
verdict: Passed
evidence-refs: [payload.outcomes, payload.success-metrics, payload.prioritized-requirements, PROD-PM-20260718T152000Z]
decisions:
- decision-id: HWVNEXT-V1-SCOPE
selected-option-id: DUAL-ENTRY-SHARED-LAB
alternatives:
- {option-id: DUAL-ENTRY-SHARED-LAB}
- {option-id: SINGLE-ARTICLE}
- {option-id: REAL-DEBUGGING-PLATFORM}
report-header:
bottom-line: >-
v1은 두 출발점이 하나의 Lost Update causal Lab으로 합류하는 깊이 학습 제품이다.
출시 범위는 예측·관찰·비교·설명·전이와 접근성·정직한 경계이며 backend·실제 진단은 명시적으로 제외한다.
decision-needed: {needed: false, approver: null}
confidence: {value: Med, derived-from: accepted-strategy-design-and-browser-proof-with-user-learning-still-a-hypothesis}
risks:
- 실제 사용자에게 두 입구의 차이가 명확한지는 별도 사용성 관찰이 필요하다.
- 한 주제에서 Atlas라는 명칭의 기대가 과할 수 있어 roadmap은 inactive로 정직하게 표시한다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1/PROD-PM-20260718T152000Z.report.yaml
grade: E3
note: exact opportunity-solution tree
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1/ARCH-SOLUTION-20260718T151500Z.report.yaml
grade: E3
note: accepted overall design
@@ -0,0 +1,52 @@
report-type: workflow-artifact
artifact-kind: product-goal
artifact-version: 1
tier: standard
identity:
artifact-id: PROD-PO-20260718T152200Z
workflow-id: hyeonworks-vnext-v1
stage: spec
producer-role-id: PROD-PO
created-at: 20260718T152200Z
attempt-id: 1
payload:
goal: >-
개념 또는 증상에서 출발한 개발자가 같은 Lost Update Lab에서 정답을 먼저 보지 않고 예측하고,
실제 read/write 증거를 관찰·비교해 세 인과 요소를 설명한 뒤 새 사례에 전이할 수 있는
첫 번째 완성형 Technology Atlas 딥다이브를 출시한다.
prd-binding:
artifact-id: PROD-PM-20260718T152100Z
artifact-sha256: b9f162e7f26dff79e79f018488ad96d839701eec29b5eb5d15e1aad7f59bd627
backlog-order:
- {order: 1, item: shared scenario and reducer across two entries, risk: product split}
- {order: 2, item: gated five-phase causal learning loop, risk: passive answer reveal}
- {order: 3, item: exact 100·120·150·70 ledger and transfer case, risk: causal inaccuracy}
- {order: 4, item: debugger clue flow plus guided boundary, risk: diagnosis misrepresentation}
- {order: 5, item: responsive keyboard focus contrast and skip-state preservation, risk: inaccessible completion}
- {order: 6, item: dependency-free local delivery and deterministic regression, risk: unnecessary operations}
definition-of-done:
- 여섯 수용 기준이 각각 실행 가능한 검증 방법과 expected result를 가진다.
- actual production files와 전체 browser flow가 동일 source revision에 결속된다.
- 독립 QA가 verification stage에서 새 영수증으로 quality gate를 통과한다.
exclusions: [real diagnosis, remote database, account, persistence, public API, additional public topic]
method-execution:
role-id: PROD-PO
method-id: backlog-definition
contract-sha256: 2e233338fb4f316efbd68ae3af77b36474ecec9683f759bfbbb51bd55eecb34e
step-results:
- {step-id: set-goal, status: completed, output-binding: current-artifact}
report-header:
bottom-line: >-
Product Goal은 두 입구에서 동일한 Lost Update 인과 Lab을 완주하고 새 사례로 전이하는 첫 딥다이브 출시다.
백로그는 제품 분열·인과 오류·진단 오인·접근성 회귀 위험 순으로 정렬한다.
decision-needed: {needed: false, approver: null}
confidence: {value: Med, derived-from: accepted-prd-and-explicit-testable-done-boundary}
risks:
- 실제 학습성과는 출시 품질 게이트와 별개로 후속 관찰해야 한다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1/PROD-PM-20260718T152100Z.report.yaml
grade: E3
note: exact accepted PRD
- source-uri: hyeonworks/app/README.md
grade: E3
note: inspectable production flow and honest scope
@@ -0,0 +1,114 @@
report-type: workflow-artifact
artifact-kind: acceptance-criteria
artifact-version: 1
tier: standard
identity:
artifact-id: PROD-PO-20260718T152300Z
workflow-id: hyeonworks-vnext-v1
stage: spec
producer-role-id: PROD-PO
created-at: 20260718T152300Z
attempt-id: 1
payload:
basis-artifact-id: ARCH-SOLUTION-20260718T151500Z
basis-artifact-sha256: 5217e3b3b8b9e3e33d13cd58e88112c32d93cbe9b51af9f919594d9be5f58d83
prd-binding:
artifact-id: PROD-PM-20260718T152100Z
artifact-sha256: b9f162e7f26dff79e79f018488ad96d839701eec29b5eb5d15e1aad7f59bd627
criteria:
- criterion-id: AC-DUAL-ENTRY-SHARED-LAB
preconditions: [앱이 홈 route에서 실행 중이다.]
input:
routes: ['#/orient/concept', '#/orient/symptom']
action: 각 orientation에서 Lab 시작 control을 활성화한다.
expected-result: >-
두 경로는 모두 동일 '#/lab/tx-lost-update-01'로 이동하고 main의 scenario-id가
tx-lost-update-01이며 동일한 initial state·phase order·learning reducer를 사용한다.
risk-level: High
verification-method: automated-test
- criterion-id: AC-FULL-LEARNING-LOOP
preconditions: [tx-lost-update-01 Lab이 초기화돼 있다.]
input:
actions: [prediction 선택, Observe 6단계 실행, Compare 확인, causal explanation 제출, transfer answer 제출]
negative-paths: [설명 오답 제출 후 재시도, transfer 오답 제출 후 재시도]
expected-result: >-
Predict→Observe→Compare→Explain→Transfer만 순서대로 열리고 오답은 구체적 피드백과 focus를 제공하며,
정답 후 완료 화면과 같은 Lab 재실행 control이 나타난다.
risk-level: High
verification-method: automated-test
- criterion-id: AC-CAUSAL-LEDGER-VALUES
preconditions: [Observe phase가 시작됐다.]
input:
scenario: A는 +50, B는 -30을 같은 initial 100에서 계산한다.
expected-trace: [A read 100, B read 100, A computes 150, B computes 70, A writes 150, B writes 70]
expected-result: >-
serial expected 값은 120, 최종 observed 값은 70이며 Compare·Explain은 동일 read basis,
독립 계산, B의 마지막 write가 A의 +50을 덮었다는 세 인과 요소에 결속된다.
risk-level: Critical
verification-method: automated-test
- criterion-id: AC-SYMPTOM-DEBUGGER-HONESTY
preconditions: [증상 orientation route가 열려 있다.]
input:
action: 단서 4개를 차례로 공개하고 후보 메커니즘에서 Lab을 시작한다.
expected-result: >-
결과 70에서 후보 Lost Update로 좁힌 뒤 공통 Lab으로 합류하고, 화면은 고정 guided scenario이며
실제 로그 분석·AI 진단·원격 DB 실행·장애 원인 확정이 아님을 명시한다.
risk-level: High
verification-method: automated-test
- criterion-id: AC-A11Y-RESPONSIVE-STATE
preconditions: [Chrome에서 360px·768px·1280px viewport를 사용할 수 있다.]
input:
modes: [keyboard-only, pointer]
skip-link-states: [home, concept, revealed-symptom, default-observe-cursor-1, fixture-observe-cursor-1]
expected-result: >-
모든 control이 키보드로 동작하고 focus가 가시적이며 skip link가 같은 main node에 focus하되
hash·scenario·phase·cursor·trace/clue state를 보존한다. 문서 overflow는 0이고 표 overflow는
내부 scroll container에만 격리되며 normal text 대비 4.5:1, essential control 경계 3:1 이상이다.
risk-level: Critical
verification-method: automated-test
- criterion-id: AC-DETERMINISTIC-OFFLINE
preconditions: [배포 dist와 Node.js 18 이상이 있다.]
input:
actions: [설치 없이 정적 서버 실행, full-flow 반복 실행, verification fixture 실행, remote request 감시]
expected-result: >-
runtime dependency와 remote asset/request가 0이고 기본·fixture scenario가 서로 섞이지 않으며
반복 실행의 상태·값·완료 결과가 동일하다. 서버는 정적 파일과 최소 보안 헤더만 제공한다.
risk-level: Med
verification-method: automated-test
coverage-rule: completion-record는 여섯 criterion-id를 그대로 사용하고 각 Passed 상태를 typed receipt에 결속한다.
method-execution:
role-id: PROD-PO
method-id: backlog-definition
contract-sha256: 2e233338fb4f316efbd68ae3af77b36474ecec9683f759bfbbb51bd55eecb34e
step-results:
- step-id: set-goal
status: completed
output-binding: trusted-artifact
artifact-refs:
- {report-id: PROD-PO-20260718T152200Z, sha256: 588440aaf0e7a7b41e05675b6b8ab98ae419b58c62ff46f76412cfc9257a77ea}
- {step-id: define-acceptance, status: completed, output-binding: current-artifact}
self-check-results:
- step-id: define-acceptance
gate-id: testable-criteria
verdict: Passed
evidence-refs:
- payload.criteria.AC-DUAL-ENTRY-SHARED-LAB
- payload.criteria.AC-FULL-LEARNING-LOOP
- payload.criteria.AC-CAUSAL-LEDGER-VALUES
- payload.criteria.AC-SYMPTOM-DEBUGGER-HONESTY
- payload.criteria.AC-A11Y-RESPONSIVE-STATE
- payload.criteria.AC-DETERMINISTIC-OFFLINE
report-header:
bottom-line: >-
여섯 수용 기준이 제품 핵심·인과 정확성·디버거 정직성·접근성·오프라인 결정성을 실행 가능한 browser/static 검증으로 닫는다.
decision-needed: {needed: false, approver: null}
confidence: {value: High, derived-from: exact-prd-product-goal-and-existing-browser-assertion-coverage}
risks:
- 실제 스크린리더 발화와 비-Chromium 엔진은 이 자동 기준 밖이며 독립 잔여 위험으로 남긴다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1/PROD-PM-20260718T152100Z.report.yaml
grade: E3
note: exact accepted PRD
- source-uri: hyeonworks/app/scripts/verify_flow.cjs
grade: E3
note: executable browser assertions covering the six criteria
@@ -0,0 +1,50 @@
report-type: workflow-artifact
artifact-kind: compatibility-review
artifact-version: 1
tier: standard
identity:
artifact-id: QA-20260718T151700Z
workflow-id: hyeonworks-vnext-v1
stage: design
producer-role-id: QA
created-at: 20260718T151700Z
attempt-id: 1
payload:
left:
artifact-kind: approved-design-direction
artifact-id: DES-DIRECTOR-20260718T151300Z
artifact-sha256: ad2120ba2b214a58adc17aac5620c6e19bd727ac4cfd1a48a41c2a75327ff885
right:
artifact-kind: ui-design
artifact-id: DES-VISUAL-20260718T151500Z
artifact-sha256: c1ed02e6b2b128c47f8dd3406f81b690b3d80636fc74eacbf442be7d667c8a4e
dimensions: [interaction, tokens, accessibility]
findings: []
verdict: Passed
reviewer-role-id: QA
checks:
interaction:
verdict: Passed
evidence: 두 entry가 동일 tx-lost-update-01과 reducer, 동일 다섯 단계 루프에 합류하며 skip link가 route state를 보존한다.
tokens:
verdict: Passed
evidence: paper·ink·deep·observed·on-deep·pending·control-border 값과 surface별 대비 floor가 정확히 일치한다.
accessibility:
verdict: Passed
evidence: native controls, visible focus, current-main skip target, color-independent labels, 360·768·1280 읽기 순서 계약이 일치한다.
independence: QA는 두 endpoint producer DES-DIRECTOR·DES-VISUAL과 다르며 exact immutable revision을 검토했다.
report-header:
bottom-line: >-
PASS — 승인 방향과 UI 설계는 interaction·token·accessibility 세 계약에서 exact하게 일치하며
구현 전달을 막는 finding이 없다.
decision-needed: {needed: false, approver: null}
confidence: {value: High, derived-from: exact-endpoint-sha-contract-comparison-and-r4-browser-evidence}
risks:
- 구현 중 token 이름만 복사하고 실제 surface 사용처가 달라지는 회귀는 브라우저 computed-style 검증으로 다시 잡아야 한다.
evidence:
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1/DES-DIRECTOR-20260718T151300Z.report.yaml
grade: E3
note: exact approved design direction endpoint
- source-uri: hyeonworks/completion-records/hyeonworks-vnext-v1/DES-VISUAL-20260718T151500Z.report.yaml
grade: E3
note: exact UI design endpoint

Some files were not shown because too many files have changed in this diff Show More