LogoSkills

e2e:lock

Lock step-implemented scenarios into the CI regression suite: register test_bundle.dart, delete journals, write lock records (E2E authoring final stage 5).

ํ•ญ๋ชฉ๋‚ด์šฉ
Invoke/e2e:lock
Aliases/e2e:l
Categorye2e-authoring
Complexitymoderate

/e2e:lock โ€” ํ†ต๊ณผํ•œ ํ…Œ์ŠคํŠธ๋ฅผ "๊ณต์‹ ์‹œํ—˜์ง€"๋กœ ๋ฐ•์ œ#

ํ•œ๋งˆ๋””๋กœ#

๊ฒ€์ฆ์„ ํ†ต๊ณผํ•œ ์ž๋™ํ™” ํ…Œ์ŠคํŠธ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ํšŒ๊ท€ ์‹œํ—˜์ง€(CI ํšŒ๊ท€ ์Šค์œ„ํŠธ)์— ๋„์žฅ ์ฐ์–ด ๋“ฑ๋กํ•˜๋Š” ๋‹จ๊ณ„์ž…๋‹ˆ๋‹ค. ํ•œ ๋ฒˆ ํ•ฉ๊ฒฉํ•œ ๋ชจ์˜๊ณ ์‚ฌ ๋ฌธ์ œ๋ฅผ "์ด์ œ๋ถ€ํ„ฐ ๋งค๋ฒˆ ํ‘ธ๋Š” ์ •์‹ ์‹œํ—˜ ๋ฌธ์ œ"๋กœ ํ™•์ •ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์•„์š”. ๋“ฑ๋ก ํ›„์—๋Š” ํ•จ๋ถ€๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค(๋˜๋Œ๋ฆฌ๋ ค๋ฉด ๋ช…์‹œ์ ์ธ unlock์ด ํ•„์š”).

๋ˆ„๊ฐ€ยท์–ธ์ œ ์“ฐ๋‚˜์š”#

  • ํ…Œ์ŠคํŠธ ์‹œ๋‚˜๋ฆฌ์˜ค ์ž‘์„ฑ(step-implement)์„ ๋๋‚ด๊ณ , ์ž๋™ ์‹คํ–‰ ๊ฒฐ๊ณผ๊ฐ€ PASS(ํ•ฉ๊ฒฉ) ๋กœ ๋‚˜์˜จ ์งํ›„
  • ๊ทธ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ CI ํšŒ๊ท€ ํ…Œ์ŠคํŠธ(์ฝ”๋“œ๊ฐ€ ๋ฐ”๋€” ๋•Œ๋งˆ๋‹ค ์ž๋™์œผ๋กœ ๋„๋Š” ๊ฒ€์‚ฌ)์— ์ •์‹์œผ๋กœ ํฌํ•จ์‹œํ‚ค๊ณ  ์‹ถ์„ ๋•Œ

๋ฌด์—‡์„ ํ•ด์ฃผ๋‚˜์š”#

ํ†ต๊ณผํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ๊ฒ€์ฆํ•œ ๋’ค, ์ •์‹ ํ…Œ์ŠคํŠธ ๋ชฉ๋ก์— ๋“ฑ๋กํ•˜๊ณ  ์ž„์‹œ ์ž‘์—… ๊ธฐ๋ก์„ ์ •๋ฆฌํ•ด ์ค๋‹ˆ๋‹ค. ๋๋‚˜๋ฉด ๋‹ค์Œ์ด ๋‚จ์Šต๋‹ˆ๋‹ค.

  • test_bundle.dart ์ˆ˜์ • โ€” ์ „์ฒด ํ…Œ์ŠคํŠธ ๋ฌถ์Œ์— ์‹œ๋‚˜๋ฆฌ์˜ค ์ถ”๊ฐ€
  • run_all_scenarios.sh ์ˆ˜์ • โ€” ํ•œ ๋ฒˆ์— ์‹คํ–‰ํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ ๊ฐฑ์‹ 
  • .claude/e2e-lock.json ๊ฐฑ์‹  โ€” "์–ด๋–ค ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ๋ฐ•์ œํ–ˆ๋Š”์ง€" ๊ธฐ๋ก (์ปค๋ฐ‹ ๋Œ€์ƒ)
  • ์ž„์‹œ ์ž‘์—… ๊ธฐ๋ก(์ €๋„)์„ ์‚ญ์ œํ•˜๊ฑฐ๋‚˜ ๋ณด๊ด€ํ•จ(archive)์œผ๋กœ ์ด๋™
  • ์ถ”์ฒœ ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€ ์ œ์•ˆ: test(e2e): lock {feature}/{scenario}

์–ด๋–ป๊ฒŒ ์“ฐ๋‚˜์š”#

# ๋‹จ์ผ ์‹œ๋‚˜๋ฆฌ์˜ค ๋ฐ•์ œ
/e2e:lock sign_in email_login_success

# feature ์ „์ฒด ๋ฐ•์ œ (ํ•ด๋‹น feature์˜ ๋ชจ๋“  ์‹œ๋‚˜๋ฆฌ์˜ค)
/e2e:lock sign_in --all

# pre-lock ๊ฒ€์ฆ๋งŒ ์ˆ˜ํ–‰ (์‹ค์ œ lock ์•ˆํ•จ)
/e2e:lock sign_in email_login_success --dry-run

# ์ €๋„์„ archive ๋กœ ๋ณด๊ด€ํ•˜๋ฉฐ lock
/e2e:lock sign_in email_login_success --archive-journal
  • feature(ํ•„์ˆ˜): ๊ธฐ๋Šฅ ์ด๋ฆ„ (์˜ˆ: sign_in)
  • scenario(ํ•„์ˆ˜): ์‹œ๋‚˜๋ฆฌ์˜ค ์ด๋ฆ„. ๋‹จ, --all์„ ์“ฐ๋ฉด ์ƒ๋žต ๊ฐ€๋Šฅ
  • --all: ํ•ด๋‹น ๊ธฐ๋Šฅ์˜ ๋ชจ๋“  ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ํ•œ๊บผ๋ฒˆ์— ๋ฐ•์ œ
  • --dry-run: ์‹ค์ œ๋กœ ๋“ฑ๋กํ•˜์ง€ ์•Š๊ณ  "ํ†ต๊ณผํ•˜๋Š”์ง€ ๊ฒ€์ฆ๋งŒ" ๋ฏธ๋ฆฌ ํ•ด๋ณด๊ธฐ
  • --archive-journal: ์ž‘์—… ๊ธฐ๋ก์„ ์ง€์šฐ์ง€ ์•Š๊ณ  ๋ณด๊ด€ํ•จ์œผ๋กœ ์˜ฎ๊ธฐ๊ธฐ (๊ธฐ๋ณธ์€ ์‚ญ์ œ)

์•ˆ์—์„œ ๋ฌด์Šจ ์ผ์ด ๋ฒŒ์–ด์ง€๋‚˜์š”#

ํฌ๊ฒŒ ๊ฒ€์ฆ โ†’ ๋“ฑ๋ก โ†’ ์ •๋ฆฌ โ†’ ๊ธฐ๋ก โ†’ ๋ณด๊ณ  ์ˆœ์„œ๋กœ ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค.

  1. ์‚ฌ์ „ ์ ๊ฒ€ โ€” ์‹œ๋‚˜๋ฆฌ์˜ค ํŒŒ์ผ์ด ์ œ์ž๋ฆฌ์— ์žˆ๋Š”์ง€, ๋น ์ง„ ๋ถ€๋ถ„์€ ์—†๋Š”์ง€, ๋งˆ์ง€๋ง‰ ์ž๋™ ์‹คํ–‰์ด ํ•ฉ๊ฒฉ์ด์—ˆ๋Š”์ง€ ๋“ฑ์„ ๊ผผ๊ผผํžˆ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค. ํ•˜๋‚˜๋ผ๋„ ๋ฏธ๋‹ฌ์ด๋ฉด ๋“ฑ๋กํ•˜์ง€ ์•Š๊ณ  ๋ฉˆ์ถฅ๋‹ˆ๋‹ค(๊ฐ•์ œ ๋“ฑ๋ก ๊ธˆ์ง€).
  2. ์ •์‹ ๋ชฉ๋ก ๋“ฑ๋ก โ€” ์ „์ฒด ํ…Œ์ŠคํŠธ ๋ฌถ์Œ๊ณผ ์‹คํ–‰ ์Šคํฌ๋ฆฝํŠธ์— ์ด ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
  3. CI ์—ฐ๊ฒฐ ํ™•์ธ โ€” ์ž๋™ ๊ฒ€์‚ฌ ์„ค์ •(.github/workflows/e2e-patrol.yml)์ด ์ž˜ ์—ฐ๊ฒฐ๋ผ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ํ•„์š”ํ•œ ๋ณด์™„์„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค.
  4. ์ž„์‹œ ๊ธฐ๋ก ์ •๋ฆฌ โ€” ์ž‘์—…ํ•˜๋ฉด์„œ ๋‚จ๊ธด ์ €๋„์„ ์‚ญ์ œํ•˜๊ฑฐ๋‚˜ ๋ณด๊ด€ํ•จ์œผ๋กœ ์˜ฎ๊น๋‹ˆ๋‹ค.
  5. ๋ฐ•์ œ ๊ธฐ๋ก ์ž‘์„ฑ โ€” "๋ฌด์—‡์„ ๋“ฑ๋กํ–ˆ๋Š”์ง€"๋ฅผ .claude/e2e-lock.json์— ๋‚จ๊น๋‹ˆ๋‹ค.
  6. ๊ฒฐ๊ณผ ๋ณด๊ณ  โ€” ๋“ฑ๋ก ๊ฒฝ๋กœ, CI ์‹คํ–‰ ๋ช…๋ น, ์ถ”์ฒœ ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€๋ฅผ ์ •๋ฆฌํ•ด ์•Œ๋ ค์ค๋‹ˆ๋‹ค.

๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ๋ฉด(์˜ˆ: ์‚ฌ์ „ ์ ๊ฒ€ ์‹คํŒจ, ๋งˆ์ง€๋ง‰ ์‹คํ–‰์ด ๋ถˆํ•ฉ๊ฒฉ, ์ด๋ฆ„ ์ค‘๋ณต) ๊ทธ ์›์ธ์„ ์•Œ๋ ค์ฃผ๊ณ  ๋‹ค์Œ์— ๋ฌด์—‡์„ ํ•ด์•ผ ํ• ์ง€ ์•ˆ๋‚ดํ•ฉ๋‹ˆ๋‹ค.


โš™๏ธ ์ƒ์„ธ ์˜ต์…˜ยท์‹คํ–‰ ๋ช…์„ธ (๊ฐœ๋ฐœ์ž / AI ์—์ด์ „ํŠธ์šฉ)

Triggers#

  • step-implement ์™„๋ฃŒ ํ›„ patrol_mcp run ๊ฒฐ๊ณผ๊ฐ€ PASS
  • ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ CI ํšŒ๊ท€์— ํฌํ•จ์‹œํ‚ค๋ ค ํ•  ๋•Œ

์‚ฌ์šฉ๋ฒ•#

# ๋‹จ์ผ ์‹œ๋‚˜๋ฆฌ์˜ค ๋ฐ•์ œ
/e2e:lock sign_in email_login_success

# feature ์ „์ฒด ๋ฐ•์ œ (ํ•ด๋‹น feature์˜ ๋ชจ๋“  ์‹œ๋‚˜๋ฆฌ์˜ค)
/e2e:lock sign_in --all

# pre-lock ๊ฒ€์ฆ๋งŒ ์ˆ˜ํ–‰ (์‹ค์ œ lock ์•ˆํ•จ)
/e2e:lock sign_in email_login_success --dry-run

# ์ €๋„์„ archive ๋กœ ๋ณด๊ด€ํ•˜๋ฉฐ lock
/e2e:lock sign_in email_login_success --archive-journal

ํŒŒ๋ผ๋ฏธํ„ฐ#

ํŒŒ๋ผ๋ฏธํ„ฐํ•„์ˆ˜์„ค๋ช…๊ธฐ๋ณธ
featureโœ…feature ์ด๋ฆ„โ€”
scenarioโœ…*์‹œ๋‚˜๋ฆฌ์˜ค ์Šฌ๋Ÿฌ๊ทธโ€”
--allโŒfeature ๋‚ด ๋ชจ๋“  ์‹œ๋‚˜๋ฆฌ์˜ค lockfalse
--dry-runโŒ๊ฒ€์ฆ๋งŒ ์ˆ˜ํ–‰false
--archive-journalโŒ์ €๋„์„ .claude/e2e-journal/archive/ ๋กœ ์ด๋™ (๊ธฐ๋ณธ์€ ์‚ญ์ œ)false

*--all ๋ฏธ์‚ฌ์šฉ ์‹œ ํ•„์ˆ˜

์‹คํ–‰ ๋‹จ๊ณ„#

  1. Pre-lock ๊ฒ€์ฆ (skills/scenario-lock/SKILL.md ์ฐธ์กฐ)
    • ์‹œ๋‚˜๋ฆฌ์˜ค ํŒŒ์ผ ์กด์žฌ + ์œ„์น˜
    • step ํ•จ์ˆ˜ ๋งคํ•‘ ์™„์ „์„ฑ
    • semantic ref ์ž”์กด ๊ฒ€์‚ฌ
    • flutter-skill import ์ž”์กด ๊ฒ€์‚ฌ
    • patrol_mcp ๋งˆ์ง€๋ง‰ run PASS
    • canonical step ๊ทœ์•ฝ ์ค€์ˆ˜
  2. Bundle ๋“ฑ๋ก โ€” test_bundle.dart, run_all_scenarios.sh ์—…๋ฐ์ดํŠธ
  3. CI ์—ฐ๊ฒฐ ์ ๊ฒ€ โ€” .github/workflows/e2e-patrol.yml ํ™•์ธ + ์ œ์•ˆ
  4. ์ €๋„ ์ •๋ฆฌ โ€” ์‚ญ์ œ ๋˜๋Š” archive ์ด๋™
  5. Lock ๋ ˆ์ฝ”๋“œ ์ž‘์„ฑ โ€” .claude/e2e-lock.json ์—…๋ฐ์ดํŠธ (์ปค๋ฐ‹ ๋Œ€์ƒ)
  6. ๋ฆฌํฌํŠธ โ€” ๋“ฑ๋ก ๊ฒฝ๋กœ, CI ๋ช…๋ น, ์ œ์•ˆ ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€

์ถœ๋ ฅ#

  • test_bundle.dart ์ˆ˜์ •
  • run_all_scenarios.sh ์ˆ˜์ •
  • .claude/e2e-lock.json ๊ฐฑ์‹  (์ปค๋ฐ‹ ๋Œ€์ƒ)
  • ์ €๋„ ์‚ญ์ œ or archive ์ด๋™
  • ์ œ์•ˆ ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€: test(e2e): lock {feature}/{scenario}

์‹คํŒจ ์ผ€์ด์Šค#

์›์ธ๋Œ€์‘
Pre-lock ๊ฒ€์ฆ ์‹คํŒจ์›์ธ ๋ฆฌํฌํŠธ + ์ค‘๋‹จ (๊ฐ•์ œ lock ๊ธˆ์ง€)
patrol_mcp ๋งˆ์ง€๋ง‰ run FAILstep-implement ์žฌ์ง„์ž… ์•ˆ๋‚ด
semantic ref ์ž”์กดํ•ด๋‹น ์ฝ”๋“œ ์œ„์น˜ ์ถœ๋ ฅ + key-hardening ์žฌ์‹คํ–‰ ์•ˆ๋‚ด
์‹œ๋‚˜๋ฆฌ์˜ค๋ช… ์ค‘๋ณต๊ธฐ์กด lock ๋ ˆ์ฝ”๋“œ์™€ ์ถฉ๋Œ ๋ฆฌํฌํŠธ

๊ด€๋ จ#

  • skills/scenario-lock/SKILL.md
  • commands/e2e/draft.md โ€” ์ด์ „ ๋‹จ๊ณ„
  • rules/selector-policy.md, rules/feature-file-conventions.md