ํ๋ก์ ํธ ๋ฌด๊ด(project-agnostic) AI ์ฝ๋ฉ ์ฌ์ด๋์นด โ ์ด๋ repo ์๋ ๋๋กญ์ธ. ์คํยทํ์ผยทํ๋กฌํํธ ๋จ๊ณ์ ๋ผ์ด๋ค์ด ๊ท์น์ ๊ฐ์ ํ๊ณ , ๋ชจ๋ ๊ฒฐ๊ณผ๋ฅผ append-only JSONL ๋ก ๋จ๊ธด๋ค.
๐ง ์ฌ์ด๋์นด = "AI ์ฝ๋ฉ ๋ณด์๊ฒ์๋" โ AI ์์ด์ ํธ(Claude Code / Codex ๋ฑ)๊ฐ ๋ช ๋ น์ ์คํํ๊ฑฐ๋ ํ์ผ์ ๊ณ ์น๊ธฐ ์ง์ ยท์งํ์ ๊ฒ์ดํธ๋ฅผ ํต๊ณผ์์ผ, ์ํํ ๋์์ ๋ง๊ณ (block) ์ ๊ธ ํ์ผ ์์ ์ ๊ฒฝ๊ณ (warn)ํ๋ฉฐ ๊ฒ์ฆยท์ธ๊ณ๋ฅผ ์๋ํํ๋ค. ESLint ๊ฐ "์ฝ๋ ๋ฌธ๋ฒ"๋ง ๋ณธ๋ค๋ฉด, ์ฌ์ด๋์นด๋ ์์ ํ๋ฆ ์ ์ฒด(๋ช ๋ น ์คํยทํ์ผ ์ ๊ธยท๊ฒ์ฆยท์ธ์ ์ธ๊ณ)๋ฅผ ๋จ์ํ๋ค.
์ด ์ ์ฅ์๋ dancinlab ์ ๋ชจ๋ repo(edge ยท anima ยท โฆ)๊ฐ ๊ณต์ ํ๋ ์์ง์ด๋ค. ํ๋ก์ ํธ๋ง๋ค ๋ฌ๋ผ์ง๋ ๊ฒ์ harness.config.json + .harness/*.json(๊ท์น ๋ฐ์ดํฐ)๋ฟ์ด๊ณ , .ts ์์ง ์ฝ๋๋ ์ ๋ถ ๊ณต์ ํ๋ค.
๐ ์ธ์ด ๋ฌด๊ด: ์น๋ฟ ์๋๋ผ Python ยท Rust ยท C/C++ ยท Go ยท Swift ยท hexa ๋ก์ปฌ/๋ชจ๋ฐ์ผ ์ฑ์๋ ์ด๋ค.
init์ด ์คํ์ ๊ฐ์งํด ๊ฒ์ฆ ๋ช ๋ น(cargo/pytest/swift build/โฆ)๊ณผ ๋ค๊ตญ์ด ์ฐํํจํด(# type: ignoreยท#[allow]ยทswiftlint:disableโฆ)์ ์๋ ์ ์ฉ. ์์ง ์คํ์ ๊ฐ๋ฐ๋จธ์ Node 1๊ฐ๋ง ํ์(ํ๊น ๋น๋์ ๋ฌด๊ด). โ docs/languages.md
[ edge repo ]โโโ
[ anima repo ]โโผโโโถ ๊ฐ์ .ts ์์ง (์ด repo)
[ ๋ค๋ฅธ repo ]โโโ โฒ
โ ๊ฐ์ harness.config.json + .harness/*.json ์ผ๋ก
โโ ๊ท์น๋ง ๋ค๋ฅด๊ฒ ์ฃผ์
| # | ์์น | ์๋ฏธ |
|---|---|---|
| H1 | ์ฑ๊ณต์ ์กฐ์ฉ, ์คํจ๋ ์๋๋ฝ๊ฒ | ํต๊ณผ ์ stdout ์นจ๋ฌต, ์คํจ๋ง stderr (JSON) |
| H2 | ์๋ ์์ ์ ํจ | ์ ์ยท์ฐจ๋จยท๊ฒฝ๊ณ ๋ง. ๊ณ ์น๋ ๊ฑด ์ฌ๋/์์ด์ ํธ |
| H3 | bitter-gate | ์ ๊ท์น ์ถ๊ฐ ์ , ์ ์ฐ๋(dormant) ๊ท์น ๋จผ์ ํ๊ธฐ |
| H4 | config ์ฃผ๋ | ๋ชจ๋ ํ๋ก์ ํธ ์์ฑ๋ ๋ฐ์ดํฐ(JSON)๋ก. ์์ง ์ฝ๋๋ ๋ถ๋ณ |
| H5 | AI-native | ๋ชจ๋ ์ฐ์ถ๋ฌผ JSONL append-only (.harness/logs/*.jsonl) |
sidecar/
โโโ bin/sidecar ์คํ ์
๊ตฌ (bash โ tsx ๋ฐํ์ ์๋ํ์)
โโโ cli/index.ts ๋์คํจ์ฒ (sidecar lint โ lint.ts)
โโโ lib/ ๊ณต์ฉ ๋ถํ
โ โโโ paths.ts repo-root ์๋ํ์ (harness.config.json / .git ์ํฅ ํ์)
โ โโโ config.ts harness.config.json ๋ก๋ + ๊ธฐ๋ณธ๊ฐ ๋จธ์ง
โ โโโ lockdown.ts L0(์ ๊ธ) ํ์ผ ๋ชฉ๋ก (config + ๐ด ๋งํฌ๋ค์ด ๋ธ๋ก ํ์ฑ)
โ โโโ log.ts json.ts exec.ts
โโโ modules/ ๊ธฐ๋ฅ 12์ข
(์๋ ํ)
โโโ config/ ๋ฒ๋ค ๊ธฐ๋ณธ ๊ท์น (๋๋ฉ์ธ-๋ฌด๊ด)
โ โโโ enforcement.json ์คํ/์ฐ๊ธฐ ์ฐจ๋จ ๊ท์น + ํ๋กฌํํธ ํํธ
โ โโโ keywords.json ํ๋กฌํํธ ํค์๋ ํธ๋ฆฌ๊ฑฐ
โ โโโ severity-map.json ์ค๋ฅ severity ๋ถ๋ฅ
โโโ harness.config.example.json
| ๋ช ๋ น | ์ญํ | hook ๋จ๊ณ |
|---|---|---|
pre bash / pre write |
์ฝ๋๋ ๋ฒจ ๊ฐ๋(force-push{blind --force/-f/+refspec ์ฐจ๋จ ยท --force-with-lease๋ ํ์ฉ ยท # force-ok ์์ธ} ยท cloud-raw c11 ยท commit-lint{COMMIT-LINT โ agent git commit ๊ฐ๋ก์ฑ sidecar-managed repo(harness.config.json)์์ lint ๊ฒ์ดํธ ์คํ(collectViolationsโlintBlockers)ยทblock ์๋ฐ์ด๋ฉด ์ฐจ๋จ โ per-repo git pre-commit ํ
๊ณผ ๋์ผ lint ๋ฅผ ๊ธ๋ก๋ฒ settings.json ๊ฒฝ๋ก๋ก ํ
-๋ฏธ์ค์น repo ๊น์ง ๊ฐ์ ยท -a/-am=tracked-modified ์ค์ฝํ ํ์ฅ ยท --no-verify/# no-verify-ok escape ๊ณต์ (danger ๊ฐ๋์ ๋์ผ)} ยท danger{--no-verifyยทreset --hardยทcurl|sh ๋ ์์ always-on ยท rm -rf ๋ฃจํธ(/ยท/*ยท~ยท$HOMEยท*)๋ config dangerGuard.rmRfRoot ํ ๊ธ ยท ๊ธฐ๋ณธ OFF(opt-out)} ยท secret-literal c1 ยท handoff-scatter ยท naming{๋ฒ์ /๋ณต์ฌ ์ ๋ฏธ์ฌ ํ์ผยทํด๋๋ช
_v2ยท_finalยท_copyยทfoo 2 โ ์ ์์ฑ BLOCK(Write/Edit + Bash mv/cp/touch/mkdir) ยท ๊ธฐ์กด ๋นํ์ค ํ์ผ ํฐ์น๋ warn(Read=preTouch ยท Edit/Write=๊ธฐ์กดํ์ผ์ด๋ฉด block ๋์ warn โ ํธ์ง ํ์ฉํด ๊ณ ์น๊ฒ) โ canonical ๋จ์ผํ์ผ update-in-place ๊ฐ์ ยท ์ด๋ ฅ์ git history ยท c25 ยท @canonical-ok(write)/# canonical-ok(bash) ๋ฉด์ } ยท state{scatter ๋๋ ํ ๋ฆฌ .verdictsยทbenchยทexperimentsยทscripts/scratch ์์ฑ BLOCK(Write/Edit + Bash mkdir/touch/cp/mv) โ ๋จ์ผ state/ ๋ฃจํธ ๊ฐ์ ยท state/ยทbuild/ยท.harness/ ํต๊ณผ ยท @state-ok/# state-ok ๋ฉด์ ยท preserve-state} ยท single-doc{scatter ํ์ผ๋ช
*-report/summary/notes/plan/guide.mdยทUPPERCASE.mdยท๋ ์ง์ ๋ ์์ฑ BLOCK(scope ๋ฌด๊ด) โ ARCHITECTURE+CHANGELOG ํตํฉ ยท docs.allow/docs.enforce:off ๋ฉด์ }) โ ๊ทธ๋ค์ config enforcement ์ ๊ท์. ์ฝ๋ ๊ฐ๋๋ config๋ณด๋ค ๋จผ์ ์คํ(profile ํธ์ง ๋ฌด๋ ฅํ ๋ฐฉ์ง) ยท ์ธ๋ผ์ธ # โฆ-ok/// @secret-ok ๋ง์ปค + dangerGuard.rmRfRoot ํ ๊ธ๋ง ์์ธ |
PreToolUse |
post bash <exit> / post edit <file> |
๊ฒฐ๊ณผ ๊ธฐ๋ก, 0โ exit ๋ผ์ฐํ , L0 ํธ์ง ๊ฒฝ๊ณ | PostToolUse |
| ์ปดํฉ์ ์์กด ์ฌ์ฃผ์ | ์ธ์
-์ค์ฝํ inject(architectureยทgit-contextยทtoolkitยทcompanionsยทing)๋ SessionStart ์์๋ง ๋ ์๋ ์ปดํฉ์
์ ์ฆ๋ฐ โ PreCompact+PostCompact ์ ๊ทธ 6๊ฐ๋ฅผ ์ฌ์ฃผ์
ํด ์ค๊ณํธ๋ฆฌยท๋ช
๋ น์นดํ๋ก๊ทธยทING ๋ณด๋๊ฐ ์ธ์
์ค๋ฐ ์ด์๋จ๊ฒ ํจ(sidecar project-tape ๋ํ) |
PreCompact ยท PostCompact |
pre write skill-desc ๊ฐ๋ |
commands/*.mdยทSKILL.md ์ description: ์ด 1400์ skill-listing cap ์ด๊ณผ๋ฉด ์ฐ๊ธฐ ์ฐจ๋จ(SKILL-DESC-CAP deny โ ์ด๊ณผ ์ ์ํธ๋ฆฌ๊ฐ ์๋ ค ๋ช
๋ น ์ธ์ง๊ฐ ์ฃฝ์), ๊ทธ ์๋๋ผ๋ lint.cmdDescCap(๊ธฐ๋ณธ 320) ๋ฏธ๋๋ฉ cap ์ด๊ณผ๋ฉด ์ฐจ๋จ(CMD-DESC-LONG deny โ ํ๋ ์ผ+Triggers โ ๋ง ๋๊ณ ํ๋๊ทธํ/์นดํ๋ก๊ทธ๋ --help/argument-hint ๋ก) ยท Triggers โ ์ ์์ผ๋ฉด warn(lint 4f ๊ฐ ์ปค๋ฐ ๋ฐฑ์คํฑ). sidecar skill-desc-guard s18 ์ด์ |
PreToolUse(Write) |
pre tool annotation ๊ฐ๋ |
MCP ํด ํธ์ถ ๊ฐ๋(matcher mcp__.*) โ MCP ํด์ ๊ทธ๊ฐ ๋ฌด๊ฐ๋์๋ค(Bash/Write ๋ง). ํ
ํ์ด๋ก๋์ MCP annotation(readOnlyHintยทdestructiveHintโฆ)์ด ์ ์ค๋ ค ๋ผ์ด๋ธ๋ก ๋ชป ์ฝ์ผ๋ฏ๋ก, sidecar ๊ฐ config ์ ์ธํ ๋ ์ง์คํธ๋ฆฌ(config/tool-annotations.json ยท repo override .harness/tool-annotations.json)๋ก tool๋ช
์ ๊ท์โhint(readOnlyยทdestructiveยทopenWorldยทsensitive)๋ฅผ ๋ถ๋ฅํ๊ณ ๊ทธ ํ์ผ์ Rule-of-Two ์ ์ฑ
์ ์ ์ฉ โ destructive ๋จ๋
=warn, destructive+openWorld(์ํ๋ณ๊ฒฝ โง ์ธ๋ถ๋๋ฌ = ๋น๊ฐ์ญ ์ธ๋ถ๋ถ์์ฉ)=block. ๋ฏธ์ง/๋ฌด์ ํธ ํด์ ํต๊ณผ(ํ๋ฆ ์ ๊นธ) ยท toggle annotationGuard(๊ธฐ๋ณธ ON ยท modules/annotation-guard.ts) |
PreToolUse(mcp\\.*) |
prompt <text> |
ํค์๋ ํธ๋ฆฌ๊ฑฐ + ํ๋กฌํํธ ํํธ ์ฃผ์ | UserPromptSubmit |
architecture {inject|show|search <q>|stop-check} |
repo-root ARCHITECTURE.json(์ฐ์ )/.md ์ ์ค์ผ๋ ํค(title+summary+2๋จ๊ณ ๋ชฉ์ฐจ ยท ~5KB)์ ์ปจํ
์คํธ๋ก ์ฃผ์
โ ๋์ฉ๋ ์ ์ -doc canonical ํจํด: ํธ๋ฆฌ๋ commons ์ฒ๋ผ ์์ฃผํ๋ ์ธ๋ถ(์์ธ์
ยท์ ์ฒด ํธ๋ฆฌยทconvergence)๋ ํ์ผ์ ๋๊ณ show/search/Read ๋ก ์จ๋๋งจ๋ pull(๋งค-ํด ํ-์ฃผ์
์ํฐํจํด ํํผ โ 10KB additionalContext ํ๋ ์ด๊ณผโํ๋ค์ค ํ์ผ-ํด๋ฐฑ+๋งคํด ํ ํฐ ์ฌ์ง๋ถ). ์ ์ doc ์ด๋ผ per-turn ์๋: SessionStart + PreCompact/PostCompact ๋ง(๋ถ์ฌ ์ ๋ฌด์). ์ค์ผ๋ ํค ๋ค์ ํด-๋ง๊ฐ ๊ฒ์ดํธ. stop-check(Stop ํ
ยท decision:block) = ์ค๊ณํ enforce โ working tree ์ ๋ฏธ์ปค๋ฐ ์ฝ๋/ARCHITECTURE ๋ณ๊ฒฝ์ด ์๋๋ฐ ์๋ต์ ๐๏ธ ARCHITECTURE ์ค(๊ฐฑ์ :โฆ/๋ณ๋ ์์)์ด ์์ผ๋ฉด ์ฐจ๋จ(์ฝ๋โARCHITECTURE drift ๋ฐฉ์ง ยท clean tree=no-op ยท ing stop-check ์ ์กฐ๊ฑด๋ถํ). search <q> = id/name/role/detail ๋์๋ฌธ์๋ฌด์ substring โ ๋งค์นญ ๋
ธ๋ id + breadcrumb (๊ฐ ๋
ธ๋ ๊ณ ์ kebab-case id = ๊ฒ์ํค ยท ๋ ๊ฑฐ์ slug/ํ๊ธํค(์ด๋ฆยท์ญํ ยท์์ธ)๋ read-fallback, ์นดํ
๊ณ ๋ฆฌ๋ guard-/module-โฆ id prefix ๋ก ํก์ ยท lint ๊ฐ id ๋ถ์ฌ/์ค๋ณต/ํ์ block) |
SessionStart + Compact + Stop |
claudemd {inject|show} |
repo-root CLAUDE.md(ํ๋ก์ ํธ ๊ท์น)๋ฅผ ๋งค ํด ์ฌ์ฃผ์
โ commons ์ฒ๋ผ salience ์ ์งํด ๊ท์น์ด ๋ฌปํ์ง ์๊ฒ (์ ํ์ <!-- enforce:start/end --> ๋ธ๋ก๋ง, 80KB ์ ๋จ, ๋ถ์ฌ ์ ๋ฌด์) |
UserPromptSubmit |
model {list|show|add|set|gate|feat|verify|prune|rm} |
๋ชจ๋ธ ๋ ์ง์คํธ๋ฆฌ โ ๋ชจ๋ธ/ckpt ๋ฅผ repo-root ARCHITECTURE.json top-level models[](๋จ์ผ-doc SSOT)์ ๋ฑ๋ก. ํ๋ idยทarchยทparamsยทbaseยทtierยทsha256ยทpathยทhfยทvisibility + 3์ถ(gates ๊ฒ์ฆ์ถฉ์กฑ๋ยทprogress ์งํยทfeatures ํน์ง). verify=weight sha256 ์ฌ๊ณ์ฐ ๋์กฐ(๋ฌด๊ฒฐ์ฑ) ยท prune=HF ์
๋ก๋+sha ์ผ์น ํ์ธ ํ ๋ก์ปฌ weight ์ญ์ (registry ๋ณด์กด). writer=byte-๋ถ๋ณ top-level splice ยท dataset ๊ณผ splice writerยทflag ํ์ ๊ณต์ (ํํ ๋ ์ง์คํธ๋ฆฌ) |
๋ชจ๋ธ ๋ฑ๋กยท์กฐํ ์ |
dataset {list|show|add|set|feat|rm} [--lang ko|en] [--register general|sns] |
๋ฐ์ดํฐ์
๋ ์ง์คํธ๋ฆฌ โ ์ฝํผ์ค/๋ฐ์ดํฐ์
์ repo-root ARCHITECTURE.json top-level datasets[](๋จ์ผ-doc SSOT ยท models[] ๋ ์ง์คํธ๋ฆฌ์ ๋ฐ์ดํฐ-์ง)์ ๋ฑ๋ก. ํ๋ idยทrepo_id(hf)ยทlangยทregisterยทrowsยทsizeยทvisibilityยทroleยทlang_verifiedยทfeatures[]ยทnoteยทupdated. list=4์นธ langรregister ๊ทธ๋ฆฌ๋ ยท writer=byte-๋ถ๋ณ top-level splice(datasets ๋ธ๋ก๋ง ๊ต์ฒด, ๋๋จธ์ง ํธ๋ฆฌ byte-๋์ผ โ ๊ฑฐ๋ ํธ๋ฆฌ reformat 0). model ๊ณผ ๋์ผ splice writerยทflag ํ์ยทidiom ์ผ๋ก ๋ฏธ๋ฌ |
๋ฐ์ดํฐ์ ๋ฑ๋กยท์กฐํ ์ |
toolkit {list|inject|json|write|check} |
๋ช
๋ น ์นดํ๋ก๊ทธ โ agent ๊ฐ ์ ๋ช
๋ น์ ์ธ์งยท์ฌ์ฉํ๊ฒ SessionStart ์ id โ use โจtriggersโฉ compact ์ฃผ์
(ํค์๋ ๋ฐ์ํ ์ฌ๊ฐ์ง๋ ๋ณด์). SSOT=HELP(ํ์ฑ) โ write=TOOLKIT.jsonl ์ฐ์ถ, check=์ dispatch ๋ช
๋ น ์นดํ๋ก๊ทธ ์๋ก ์ปค๋ฒ๋ฆฌ์ง + HELPโํ์ผ drift(lint ๊ฐ TOOLKIT-DRIFT warn) |
SessionStart |
companions {inject|list} |
์ด์ CLI ๋ช
๋ น surface โ toolkit ์ ์๋งค(toolkit=sidecar ์์ , companions=์ด์ CLI). DOMAIN-AGNOSTIC: ๋์ธ CLI ๋ ๋ฐ์ดํฐ(repo harness.config.json ์ companions + host-wide ~/.sidecar/companions.json, cmd unionยทrepo ์ฐ์ )๋ผ ์์ง์ hexa ๋ฏธํ๋์ฝ๋ฉ โ ์ ์ญ 1๊ณณ์ผ๋ก ๋ชจ๋ repo ๊ฐ hexa cloud ์กด์ฌ๋ฅผ ๋๋ฌ์ง ์๊ณ ์ธ์ง. ๊ฐ companion ์ ์นดํ๋ก๊ทธ ๋ช
๋ น(default --help)์ ์คํยท์ ๋จํด ์ฃผ์
, ๋ถ์ฌ/์คํจ๋ฉด skipยท์ ๋ถ ์์ผ๋ฉด ๋ฌด์ |
SessionStart |
load {inject|show} |
๋งคํด ์์ readout โ ๋ต๋ณ ๋งจ ์์ macOS ๋ถํ ํ ์ค ์ฃผ์
: CPU(loadรทcores) ยท RAM(used%+์ปค๋ ์๋ฐ๋ ๋ฒจ) ยท swap ยท wt(์ถ๊ฐ worktree ์) ์ ํธ๋ฑ. ์ด๋ ์ถ์ด๋ ๐ด/pressureโฅwarn ์ด๋ฉด โ ๏ธ + ๋ฌด๊ฑฐ์ด ์์
์์ ๊ฐ๋. ๋ถํ๋ก ์ฃฝ๋ ๋งฅ์ CPU ์๋ MEMORY(compressor+swap)๋ก ์ฃฝ์ผ๋ฏ๋ก RAMยทswap ๋์ ํ์ ยท worktree ๋ ๊ฒฉ๋ฆฌ agent stranded ๋์ ๊ฐ์ํ(๐ข0-2 ๐ก3-9 ๐ดโฅ10). sysctl+vm_stat+git worktree list๋ง(๊ฐ๋ฒผ์), ๋น-macOS ๋ฌด์ |
UserPromptSubmit |
recommend {inject|show|set-default|get-default|stop-check} |
4์ถ ์ถ์ฒ ๋ฃจ๋ธ๋ฆญ(์์ฑ๋ยท๋จ์ยท์์ ยทํ์ค)์ ๋งค ํด ์ฃผ์
+ standing default mode(present/auto/complete/simple/safe/std) ์ด๋ฐ. fixed/auto ๋ชจ๋๋ ๋ฐ์ค๋ฅผ ์ ๋ณด์ฉ์ผ๋ก๋ง ๋์ฐ๊ณ ์ฑํผ์ธ์ ๊ทธ ํด์ auto-proceed. stop-check(Stop ํ
)๋ ๊ทธ auto-proceed ์ ์ด๋นจ โ ๋ต๋ณ์ด ์ง์ง ๋ฐ์ค/๐ค ... auto-pick ์ค๋ก ๋๋ฌ์ผ๋ฉด(endsOnBox=๋ง์ง๋ง ~2 ๋น์ด์์ง์์ ์ค) decision:block ์ผ๋ก ๋ชจ๋ธ์ ์ฌํธ์ถํด ๊ฐ์ ์งํ. ์ ๋ฐ: tail=2 ๋ผ ๋ฐ์ค ๋ค์ ์์
/์์ฝ์ด ๋ฐ๋ผ์ค๋ ์ ์ ํด์ ๋ฌด๋ฐํ โ ์ ์ ๋์ ๋ 'Stop hook error' ๊ฐ ์ ๋จ๊ณ , ์ง์ง ๋ฐ์ค์์ ๋ฉ์ถ ๊ฒฝ์ฐ๋ง ๊ฐ์ (์๋ฌ โ ๋
ธ์ด์ฆ). ๋ฃจํ ๊ฐ๋๋ ๋ค์ดํฐ๋ธ stop_hook_active, ์ฒด์ธ๋น 1ํ ยท present/๋ฐ์ค์์/์์
์ํํ๋ no-op |
UserPromptSubmit + Stop |
lint [all|fast] |
staged-L0 + ์ ์ ๋ + CHANGELOG ๋๋ฝ + convergence ๋ ์ฝ๋ ์์(CONVERGENCE-MALFORMED block โ ARCHITECTURE.json convergence.records ์ id+state) + ๋ช
๋ น desc ์ธ์ง(SHADOW-DESC warn โ commands/.md ๊ฐ โค1400์ cap + Triggers โ ์ ๋ณด์ ) + ๋ช
๋ น desc ๋ฏธ๋๋ฉ(CMD-DESC-LONG block โ commands/.md description codepoint โค cmdDescCap(320) ยท 1400 ์ฒ์ฅ๊ณผ ๋ณ๊ฐ์ ๋นก๋นกํ ๋ฏธ๋๋ฉ ์ ยท ํ๋๊ทธ ์นดํ๋ก๊ทธ๋ --help/argument-hint ๋ก) + folder-guide(FOLDER-GUIDE-MISSING block โ staged ํด๋์ CLAUDE.md) + commonsยทCLAUDE ์์(COMMONS-PROSE/COMMONS-NO-DODONT/COMMONS-DODONT-INCOMPLETE block โ commons.md + ๋ฃจํธ CLAUDE.md ์ ๊ฐ ## <slug> ์น์
= do/dont-onlyยท๋ ๋ค ํ์ยท์ฐ๋ฌธ๊ธ์ง ยท ์ฒซ ## ์ preamble ๋ฉด์ ยท ์๋ธํด๋ CLAUDE.md ๋ ์์ ์์) + do/dont ๊ธธ์ด(DODONT-LONG block โ commons.md + ๋ฃจํธ CLAUDE.md ์ do/dont ์ค >dodontCap(200) ์ ๊ท/์ฆ๊ฐ ยท diff-aware ยท ์๋ธํด๋ CLAUDE.md(folder-docs ๋ก์ปฌ ๊ฐ์ด๋)๋ ์์ ์์์ด๋ผ ์ ์ธ) + HELP ๋ฐฑํฑ(HELP-BACKTICK block โ cli/index.ts HELP ๋ฆฌํฐ๋ด ๋ด ์ด์ค์ผ์ดํ ์ ๋ ๋ฐฑํฑ) + inject๋ณ ๊ฐ๋ณ ํฌ๊ธฐ(INJECT-OVERSIZED block โ agent ์ ์ฃผ์
๋๋ ๊ฐ inject ์์ค๊ฐ ์๊ธฐ cap ์ดํ์ธ์ง ยท lint.injectCaps ๋งต(recommend.md 7000ยทstyles/*.md ๊ฐ 9000ยทprefs.json 2000) ยท ์ฐ๋ฌธ ๋น๋=๋งค ํด context ์ธ๊ธ โ ์์ค๋ฅผ lean ํ๊ฒ ํธ๋ฆผ์ผ๋ก ํด๊ฒฐ, emit ์ ๋จ ๊ธ์ง(๋ด์ฉ ์์ค) ยท commons/CLAUDE/ARCHITECTURE ๋ ๊ฐ์ format lint ๊ฐ ๊ทธ๋ค์ inject lint) ์ฒดํฌ |
commit ์ (git pre-commit hook) |
naming audit [path] [--ing] [--gate] |
repo ์ ์ ๋น-canonical ์ด๋ฆ ๊ฐ์ฌ โ git ls-files ํธ๋ฆฌ์์ ๋ฒ์ /๋ณต์ฌ/์ค๋ณต ์ ๋ฏธ์ฌ(_v2ยทconfig copyยทutils_oldโฆ) ์ค์บ. write-guard ๊ฐ ๋ชป ๋ณธ ๊ธฐ์กด backlog ์ฉ(canonical-naming). ์ํ๊ณ-native ๋ฉด์ : Android res ํ์ ์ -v<API>ยทbare _versionยทarchive/ยท.verdicts/(native-canonical-first). --gate=์๋ฐ ์ exit 1 ยท --ing=์์ฝ์ ๊ทธ repo ์๊ธฐ ING ๋ณด๋์ add(cross-repo ์์) |
repo ์ ๋ฆฌยท๊ฐ์ฌ ์ |
ci [all|fast|list|scaffold [--force]] |
config ์ ๊ฒ์ฆ ๋ช
๋ น ๋ณ๋ ฌ ์คํ (์คํจ 1๊ฐ๋ผ๋ โ exit 1; ์ ์ด๋ฆ verify ๋ณ์นญ ์ ์ง, config ํค๋ verify.checks). scaffold = .github/workflows/ci.yml ๋ฐฉ์ถ โ checkout โ stack setup(config ci.setup, ์์ผ๋ฉด node/hexa/python ์๋๊ฐ์ง) โ sidecar ์ค์น โ sidecar ci(repo verify.checks) + sidecar lint. ๋ฌ๋=config ci.runner(๊ธฐ๋ณธ ubuntu-latest ยท ๋ฌ๋-๋ธ๋๋ ๊ฐ์ ์์, ์ด๋ค runs-on: ๋ผ๋ฒจ๋ OK). config ci.fallback ์ค์ ์ cost-free fast ๊ฒฝ๋ก โ pick-runner dispatch ์ก์ด self-hosted pool ONLINE+idle ์ด๋ฉด ๊ทธ๊ฑธ(public repo ๋ฌด๋ฃ 12-core), ์๋๋ฉด ci.fallback(๋ฌด๋ฃ github-hosted) ์ฌ์ฉ. probe ์๋ฌโfallback ์ด๋ผ CI ํ ์๊ตฌ๋๊ธฐ 0(pool ์ ํธ๋ secret RUNNER_PROBE_TOKEN admin:read PAT ยท Blacksmith ๋ถ์). config ci.cachePaths โ actions/cache@v4 warm ์ฌ์ฌ์ฉ. create-if-absent(--force ๋ฎ์ด์ฐ๊ธฐ). sidecar init ๋ ์๋ ๋ฐฉ์ถ |
commit/push ์ ยท ์ repo CI |
ci-track <pr|branch> [--watch] [--merge-on-green] [-R owner/repo] |
์๊ฒฉ PR/CI ์ฒดํฌ ์ถ์ โ gh pr checks --json โ pass/fail/pending ์ง๊ณ + ๐ขGREEN/๐ดRED/๐กPENDING/โชNONE verdict(exit 0/2/1/0). --watch = CLI-๋ด๋ถ ํด๋ง์ผ๋ก terminal ๊น์ง ๋๊ธฐ(์์ ์ง gh pr checks|grep + /tmp monitor sleep ๋ฃจํ ๋์ฒด), --merge-on-green = ๊ทธ๋ฆฐ์ด๋ฉด ์๋ squash-merge |
merge-on-green ยท CI ๋๊ธฐ ์ |
worktree {scan|gc|guard <cmd>} |
no-pileup ๊ฐ์ โ scan=stranded(๋ฏธ์ปค๋ฐ/๋ฏธํธ์) ์ํฌํธ๋ฆฌ ์ ๋ฐ(exit 1 ๊ฒ์ดํธ) ยท gc=agent ์ํฌํธ๋ฆฌ ์๋ ์๊ฑฐ: [gone] ๋จธ์ง๋ถ + age ๋ฐฑ์คํฑ(HEAD>worktree.maxAgeDays ๊ธฐ๋ณธ 3์ผ โ ๋ฏธํธ์ ํ์ refs/reaped/<br> ๋ณด์กด ํ reap). dirty/locked/recent(<1h)๋ ์ ๋ ์ ๊ฑด๋๋ฆผ. squash-mergeยทno-push ๋ก [gone] ์ ๋จ๋ fleet ์ํฌํธ๋ฆฌ ๋์ ์ ๋ง์ |
SessionStart |
errors {route|list|drain_check|mark_fixed} |
์ค๋ฅ severity ๋ถ๋ฅ + ํ | ์์ |
ledger {register|complete|list|gc|dup_check} |
๋ฐฑ๊ทธ๋ผ์ด๋ ์์ด์ ํธ ์์ ๋ฑ๋ก(์ค๋ณต ๋ฐฉ์ง) | Agent ์ /ํ |
bitter-gate audit [window] |
๊ท์น ํํธ ๋น๋ โ dormant ๊ท์น ํ๊ธฐ ๊ฒํ | ๊ท์น ์ถ๊ฐ ์ |
audit [full|summary|json] |
6์ถ ์๊ฐ ์ค์ฝ์ด์นด๋ (/60) | ์ฃผ๊ธฐ์ |
gc [scan|drift] |
๊ฐ์ด๋ ๋งํฌ๋ค์ด์ ๊นจ์ง ๋งํฌ ํ์ง | ์ฃผ๊ธฐ์ |
folders [scan|scaffold <dir>] |
์๋ธํด๋๋ณ CLAUDE.md ๋๋ฝ ํ์ง + ํ
ํ๋ฆฟ ์์ฑ (ํธ์ง ์ ์๋ ๋์ง) ยท ๊ฐ์ : lint ๊ฐ staged ํ์ผ์ ํด๋์ ๊ฐ์ด๋ ์์ผ๋ฉด FOLDER-GUIDE-MISSING(block ยท commons folder-docs) โ ์กด์ฌ๋ง ๊ฒ์ฌ, ๋ด์ฉ ์์ ์์ |
์ฃผ๊ธฐ์ /์์ ์ค ยท commit |
architecture convergence {list|add|rm|edit|stop-check} |
์ฌ๋ฐ๋ฐฉ์ง ํ์ต store CRUD โ ํ์ต์ ARCHITECTURE.json ์ convergence.records[](idยทstateยทvalueยทthresholdยทsource) ๋จ์ผ SSOT ์ ์ฐ๋ค(๊ตฌ convergence ๋ช
๋ นยท์ธ๋ผ์ธ @convergence ๋ง์ปค ํ๊ธฐ). add=upsert(id-keyed) ยท edit <id> ๋ถ๋ถ ํจ์น ยท rm <id> ยท value/threshold ์
ธํน์๋ฌธ์๋ --value - stdin. stop-check(Stop ํ
ยท ์ฌ๋ฐ ํธ๋ฆฌ๊ฑฐ) โ ์์ด์ ํธ ์์ ์ ๋ง์ง๋ง ์๋ต(user ์
๋ ฅ ์๋)์ ์ฌ๋ฐ-์ ํธ ํค์๋(config/convergence-triggers.json ยท ๋/๋ค์/์คํจ/๋์ผ/์ฌ๋ฐ/segfault/panic/๐ดโฆ ยท per-repo .harness override)๋ก ์ค์บ โ ๋งค์น ์ enforce(config.convergenceEnforce ยท ๊ธฐ๋ณธ ON): ์๋ต์ ๐งฌ CONVERGENCE ๊ณ์ ์ค์ด ์์ผ๋ฉด decision:block ์ผ๋ก ์ฐจ๋จํด โ ์ง์ง ์ฌ๋ฐ์ด๋ฉด ๐งฌ CONVERGENCE ๊ธฐ๋ก: <id>(+convergence add), ์ฒซ ๋ฐ์ยท์คํ์ด๋ฉด ๐งฌ CONVERGENCE: ํด๋น ์์ ์ ๊ฐ์ (ing/architecture stop-check ์ ๋ํ response-marker ๊ฒ์ดํธ ยท stop_hook_active loop-guard ์ฒด์ธ๋น 1๋ธ๋ก anti-wedge ยท enforce off ๋ฉด ๋ ๊ฑฐ์ stderr warn). ํค์๋=๋์ ๊ทธ๋ฌผ, ์ ๋ฐ๋๋ ์์ด์ ํธ ํ๋จ โ ๋ง์ปค๊ฐ ๊ณง ๊ธฐ๋ก/๊ธฐ๊ฐ ํ์ (์๋ ๊ธฐ๋ก ์๋). once-๊ฐ๋=์ ํธ๋ณ 1ํ(transcript+matched ํค ยท convergence-nudge.json) โ ์คํ ๋ ๊ฐ ์ง์ง segfault ๋์ง๋ฅผ ์์ง ์ ํจ ยท ๋ฌด๋งค์น/ํ์ฑ์คํจ silent. ํ์ผ-ํฐ์น ์ ํ์ต ์ฃผ์
(convergenceForFile)์ ํ์ฌ ๋นํ์ฑ(pre.ts ํธ์ถ ์ฃผ์ ยท store/CRUD/lintยทํจ์ ์ ์ง, ์ฃผ์ ํด์ ๋ก ์ฌํ์ฑ) ยท sidecar lint ๊ฐ ๋ ์ฝ๋ well-formed(id+state) ๊ฐ์ ยท architecture inject ์ค์ผ๋ ํค์ records ์ ์ธ(์ธ๋ถ๋ convergence list ์จ๋๋งจ๋) |
์ฌ๋ฐ ํ์ต ๊ธฐ๋ก + Stop ํธ๋ฆฌ๊ฑฐ |
ing {show|add|next|done|pod|inject|staleness-check|stop-check} |
์งํ๋ณด๋(ING.jsonl ยท ์ ์ฉ ing git ref) โ add/next/done(์๋ฃ=scrubโCHANGELOG)ยทpod GPU ์ถ์ ยทinject(๋งค ํด ๋ณด๋+ํด๋ง๊ฐ ๊ฒ์ดํธ ์ฃผ์
). stop-check(Stop ํ
ยท decision:block) โ ๋งค ์๋ต์ ๐ ING ์ค(๐ ING ๊ฐฑ์ : โฆ ๋๋ ๐ ING: ๋ณ๋ ์์)์ด ์์ผ๋ฉด ์ฐจ๋จํด ๊ฐ์ . ์ฝ๋ํธ์ง ์๋ ์ธก์ ยทverdictยท๋ฒค์นยท์์ด์ ํธ ์ฐฉ๋ฅ ์งํ๋ ํฌ์ฐฉ(ํ์ผ-edit ๋ฌด๊ดยทresponse-marker ๊ธฐ๋ฐ ยท recommend stop-check ๋ํ) ยท sidecar-managed repo ํ์ ยท stop_hook_active loop-guard ์ฒด์ธ๋น 1ํ. staleness-check(์ฝ๋ โฅeditThreshold ํธ์ง์ธ๋ฐ ๋ณด๋ ๋ฌด๋ณ๋ = warn-only)๋ ๋ณด์กฐ ์ ํธ |
UserPromptSubmit + Stop |
changelog {add "<title>"|list [N]|render [N]|prune --keep N|--older-than D|autoprune|migrate} |
์ด๋ ฅ SSOT = CHANGELOG.jsonl(freeform .md ํ๊ธฐ โ newest-first JSONL ยท {ts,title,body}). add=append(body=stdinยทts=today) + keep-N ์๋ ํธ๋ฆผ(config lint.changelog.keepยท๊ธฐ๋ณธ 30) ยท list/render(markdown ๋ทฐ) ยท prune=์ค๋๋ ์ํธ๋ฆฌ ์ญ์ (--keep N/--older-than D) ยท autoprune=SessionStart ์๋ ํธ๋ฆผ(cap ์ด๊ณผ์๋งยท์ ์ํธ๋ฆฌ๋ git ์ด๋ ฅ ๋ณด์กด) ยท migrate=mdโjsonl 1ํ. CHANGELOG-MISSING ๊ฒ์ดํธ(lintยทpr-cycleยทcommit-gate)๊ฐ CHANGELOG.jsonl staged ๋ฅผ ์๊ตฌ |
๋งค ์ฌ์ดํด doc + ์ด๋ ฅ ์ ๋ฆฌ |
sync {run|diff} |
(์ ํ) repo ์์ฒด ๊ณต์ ํ์ผ sync ์คํฌ๋ฆฝํธ ์คํ | ๊ณต์ ํ์ผ ๋ณ๊ฒฝ ํ |
pool {list|add|rm|on <h> <cmd>|status|specs [h]} |
ํธ์คํธ ๋ก์คํฐ + ์๊ฒฉ ์คํ. shared:false ํธ์คํธ๋ ์ ํ ํธ์คํธ โ allow ํ๋ก์ ํธ ์ปจํ
์คํธ ๋ฐ์์ on ์ฐจ๋จ(๊ณต์ฉ ์ปดํจํธ๋ก ๋ชป ์). on ์ ssh ๋ฅผ ์ง์ spawn(argv)ํด cmd ์ $/$(...) ๊ฐ ๋ก์ปฌ์ด ์๋๋ผ ์๊ฒฉ ์
ธ์์ ์ ๊ฐ๋จ. specs ๋ ํธ์คํธ๋ณ ์ฝ์ด/๋ฉ๋ชจ๋ฆฌ/GPU ๋ฅผ ssh ํ๋ก๋ธํด ๋ก์คํฐ์ ์บ์(listยทstatus ์ ใ12c ยท 30G ยท GPU:โฆใ ์ธ๋ผ์ธ ํ๊ธฐ) โ ์ ํ ํธ์คํธ๋ ํ๋ก๋ธํ์ง ์์. listยทstatus ๋ ๋ผ์ด๋ธ ์ ์ ์จ โก๋ฑ์ง(CPU 19%ยทRAM 9%ยท5.4/30GยทGPU 0%ยท0/12GiB)๋ SSH ๋ณ๋ ฌ ํ๋ก๋ธ(status ๋ ์ด ํ๋ก๋ธ๋ก ๋๋ฌ์ฌ๋ถ๊น์ง ๊ฒธํจ ยท ์บ์ ์ ํจ ยท RAM=totalโavailable) |
์๊ฒฉ ์คํ ยท ์์ ํ์ธ ์ |
mem-guard {status|check|install|uninstall} |
OOM(๋ฉ๋ชจ๋ฆฌ๋ถ์กฑ ๊ฐ์ ์ข
๋ฃ) ์๋ฐฉ. PreToolUse ํ๋ฆฌํ๋ผ์ดํธ(์์): background-spawn(โฆ &/nohup/disown/setsid) ์ง์ ์์คํ
free RAM ์ vm_stat ๋ก ์ฝ์ด warnPct(๊ธฐ๋ณธ 15%) ์ดํ warn ยท blockPct(๊ธฐ๋ณธ 0=off) ์ดํ spawn block โ ๋ณ๋ ฌ fan-out ๋์ ์ด macOS jetsam ์ ํธ๋ฆฌ๊ฑฐํ๋ ๊ทผ๋ณธ์์ธ ์ฐจ๋จ. launchd ์์น๋
(install ๋ก opt-in): watchdogIntervalSec(45s)๋ง๋ค ๋ฉ๋ชจ๋ฆฌ ํด๋ง โ ๋ฎ์ผ๋ฉด macOS ์๋ฆผ(5๋ถ throttle). ์๋ฆผ ์ ์ฉ ยท ํ๋ก์ธ์ค kill ์์ ยท ๋ค์ค Claude ์ธ์
๋์ ์ ๋ณด๋ ์ ์ผํ ์ธต |
๋งฅ์ด ์๊พธ ์ฃฝ์ ๋ ยท OOM ์๋ฐฉ |
pod / dojo [<slug>] |
GPU ํด๋ผ์ฐ๋ ๋ฐ๋ถ + dojo ํ์ต์ก ์ค์บํด๋. dojo ๊ธฐ๋ณธ ์คํ์ config.dojo(์์ง ๋ฌดํ๋์ฝ๋ฉ)๊ฐ ์ด๋ฐ โ ์ค์ ์ hexa dojo <delegate> ์์. ๋ค์ค๋ ๋ฐฐ์น๋ hexa cloud fire-shards (์์ launcher.sh ๋ CLOUD-HANDROLLED-FANOUT warn ์ผ๋ก ๋ฆฌ๋ค์ด๋ ํธ) |
GPU ๋์คํจ์น ยท ํ์ต ์ค์บํด๋ |
pod {poll|watch|unwatch|list} |
GPU pod ์๋ ํด๋ง(>=10๋ถ cadence) โ ๋ฐ์ฌ ํ ์๋ ssh ํ์ธ์ canonical ๋ช
๋ น์ผ๋ก ์ผ๋ฐํ. ๋ชจ๋ ์๊ฒฉ op ์ hexa cloud ๊ฒฝ์ (aliveยทexecยทcopy-fromยทrm ยท ์ง์ ssh/curl ๊ธ์ง). poll <id> = one-shot read-only(aliveโGPU-util/--ssh-check); --teardown-on-done/--pull "<remote> <local>" ์์ ๋๋ง ํ์ ํ teardown(pull-then-destroy, a_fire_recover_complete). watch <id> [--interval 600] [--cron] = ๋ ์ง์คํธ๋ฆฌ(~/.sidecar/pod-watch.json) ๋ฑ๋ก + cadence ๊ตฌ๋: --cron(์์คํ
crontab */10) ๋๋ agent ScheduleWakeup fallback(๊ธฐ๋ณธ ๋นํ๊ดด ยท crontab write ๋ถ๊ฐ ํ๊ฒฝ ์๋ fallback). unwatch/list = ๋ ์ง์คํธ๋ฆฌ ๊ด๋ฆฌ |
GPU pod ํด๋ง ยท ํ์ |
imagine <prompt-file> <out.{png|mp4}> [-i img] |
AI ์ด๋ฏธ์ง+์์ ์์ฑ โ ์ถ๋ ฅ ํ์ฅ์๋ก ๋ถ๊ธฐ: ์ด๋ฏธ์ง(.png)=fal openai/gpt-image-2(image2 ํ) ยท ์์(.mp4/.mov)=fal Seedance 2.0 ํ โ -i ์์ผ๋ฉด โฆ/text-to-video, -i <์ด๋ฏธ์ง> ๋ฉด โฆ/image-to-video(์ด๋ฏธ์ง ์ ๋๋ฉ์ดํธ). ํค๋ secret get ๊ฒฝ์ ยท ํ๋กฌํํธ๋ FILE ๋ก ยท -m ๋ก override |
ํ์งยทfigureยท์์ ์์ฑ ์ |
email send --to <a> --subject <s> [--text <f>|-m <s>] [--html <f>] [--attach <f>] [--dry] |
Postmark ํธ๋์ญ์
๋ฉ์ผ ๋ฐ์ก(POST /email) โ ์๋ฒ ํ ํฐ secret get postmark.server_token ยท -K curl config ๋ก argv ๋์ถ 0 ยท ๋ณธ๋ฌธ์ FILE(๋๋ -m ์ธ๋ผ์ธ). history(Postmark outbound API/--local) ยท list ยท --dry |
์๋ฆผยทํธ๋์ญ์ ๋ฉ์ผ ๋ฐ์ก ์ |
paper {new|build|cover|list|publish|update|unpublish|status} |
demiurge ํ์ฐ์ค ๋
ผ๋ฌธ ๋๊ตฌ โ new ์ค์บํด๋(NeuroLM ์ ๋ต์ง[templates/paper/_reference_samples/] ๋ฏธ๋ฌ: IntroยทBackgroundยทMethodยทExperimentsยทAblationยทDiscussion + g5 tier-badge + TikZ/pgfplots ๊ฒฐ๊ณผ๊ทธ๋ฆผ ยท fal.ai ํ์ง ํ์ฉ) โ imagine ํ์ง โ build(xelatex+bibtexร3 ยท ํ๋ 2๊ฒ์ดํธ: โฅ10p[g51] + โฅ9 result figs[=NeuroLM๋ฐ] ยท --min-pages/--min-figures 0=ํด์ ยท ๋ฏธ๋ฌ exit3). ๋ฐฐํฌ: publish --to zenodo|arxiv|both [--sandbox][--source](Zenodo ์์ RESTโDOI ยท arXiv๋ ์ ์ถ API ์์โ์ ์ถ tarball+๊ฐ์ด๋) ยท update(Zenodo new-version) ยท unpublish(Zenodo draft ์ญ์ ) ยท status(๋ฐํ์์ฅ). ํค๋ secret(zenodo.token). ์ ์กฐ๋ฆฝ ๊ท์จ์ ๋๊ตฌ๋ก ๋ฐ์ |
๋ ผ๋ฌธ ์์ฑยท์ปดํ์ผยท๋ฐฐํฌ ์ |
commands/*.md โ ์ ์ฒด ์ฌ์ฉ์-๋๋ฉด ๋ช
๋ น์ด bare /cmd ์ฌ๋์ ๋ช
๋ น์ผ๋ก ๋
ธ์ถ๋๋ค(/paperยท/imagineยท
/pr-cycleยท/shipยท/sbsยท/fleetยท/fleet-labยท/fleet-abstractยท/fleet-fullยท/ingยท/ci โฆ). ์ผ๋ถ๋ ์ด์ CLI hexa ์์์๋ค(/hexaยท/cloud=hexa cloudยท/dojo=hexa dojoยท/deck=hexa deckยท/verifyยท/atlas โ hexa ๋ถ์ฌ ์ graceful echo; sidecar ์์ฒด ํ๋ จ์ก ์ค์บํด๋๋ /hdojo). ๊ฐ .md ๋ ํ๋ฐํธ๋งคํฐ(description +
Triggers ์์ฐ์ด๊ตฌ + argument-hint + allowed-tools: Bash)์ !sidecar $ARGUMENTS`` ๋ณธ๋ฌธ์ ์์
์์์ โ Claude Code ๊ฐ description/Triggers ๋ก ์ธ์งํ๋ค(ํ๊ตญ์ดยท์์ด ํธ๋ฆฌ๊ฑฐ ์์ชฝ).
๋
ธ์ถ ๊ฒฝ๋ก = sidecar shadow (bare ยท user-scope): Claude Code ๋ ํ๋ฌ๊ทธ์ธ ๋ช
๋ น์ ๋ฌด์กฐ๊ฑด /plugin:cmd
๋ค์์คํ์ด์ค๋ก ๋์ฐ๋ฏ๋ก, ๊ทธ๋๋ก ๋๋ฉด sidecar shadow ์ bare /fleet ์ ํ๋ฌ๊ทธ์ธ /sidecar:fleet ๊ฐ picker ์
2์ค๋ก ์ค๋ณต๋๋ค. ๊ทธ๋์ .claude-plugin/plugin.json ์ด commands: [] (๊ธฐ๋ณธ commands/ ์ค์บ์ ๋น ๋ชฉ๋ก์ผ๋ก
๋์ฒด)๋ก ํ๋ฌ๊ทธ์ธ ๋ช
๋ น ๋ฑ๋ก์ ๋๊ณ , ์ฌ๋์ ๋
ธ์ถ์ sidecar shadow ๊ฐ commands/*.md ๋ฅผ ~/.claude/commands/ ์
bare /cmd ์์์๋ก ๋ฏธ๋ฌํ๋ ๋จ์ผ ๊ฒฝ๋ก๋ง ์ด๋ค(๋ง์ปค ์ถ์ ยท ์์ ์์ฑํ ๋๋ช
ํ์ผ์ ๋ณด์กด ยท ํ๊ธฐ๋ ๋ช
๋ น์ orphan shadow ๋ regen ์ ์๋ prune ยท shadow remove ๋ก ์ ์ฒด ์ ๋ฆฌ)
โ picker ์ bare 1์ค. SHADOW_MARKER ์ถ์ ์ฃผ์์ frontmatter ๋ซ๋ --- ๋ค์ ์ฝ์
ํ๋ค โ Claude Code ๋ --- ๊ฐ
1ํ์ผ ๋๋ง description: ์ ์ฝ์ผ๋ฏ๋ก, ์์ ๋ถ์ด๋ฉด picker ๊ฐ ๋ง์ปค ์ฃผ์์ ์ค๋ช
์ผ๋ก ํ์ํ๋ค. shadow --force ๋
๋ง์ปค-์๋ ์ถฉ๋(๋ง์ปค ๋์
์ ์์ฑ๋ stale shadow)๋ source ๋ก ๋ฎ์ด์จ heal ํ๋ค โ ์ shadow ๊ฐ ์์์์ฑ์ผ๋ก ์คํ๋ผ
skip ๋๋ฉด source ์ Triggers โ ์ค์ ์์ด ๋งจ-ํ
์คํธ ๋ช
๋ น ์ธ์ง๊ฐ ์ฃฝ๊ธฐ ๋๋ฌธ(sidecar lint 4f SHADOW-DESC ๊ฐ
desc ์ capยทTriggers ๋ณด์ ๋ฅผ warn ์ผ๋ก ๊ฒ์ดํธ).
์๊ธฐ์๊ฒฐ(self-contained) ํ๋ฌ๊ทธ์ธ ยท ํ๋ก์ ํธ ๋ฌด๊ด: marketplace source: "." ๋ผ repo ๋ฃจํธ๊ฐ ๊ณง ํ๋ฌ๊ทธ์ธ โ
ํ
๋ฟ ์๋๋ผ sidecar CLI ๋ณธ์ฒด(bin/ยทcli/ยทlib/ยทmodules/ยทconfig/ยทcommands/)๊น์ง ํ ๋ฉ์ด๋ฆฌ๋ก ์ค๋ฆฐ๋ค
(commands/ ๋ shadow ๊ฐ ๋ฏธ๋ฌํ๋ SOURCE ๋ก ์ค๋ฆด ๋ฟ, ํ๋ฌ๊ทธ์ธ ๋ช
๋ น์ผ๋ก ๋ก๋๋์ง ์๋๋ค). ํ
์
${CLAUDE_PLUGIN_ROOT}/bin/sidecar(ํ๋ฌ๊ทธ์ธ ์๊ธฐ ๋ฒ๋ค)๋ฅผ ์คํํ๋ฏ๋ก, /plugin update + ๋ฆฌ๋ก๋ ํ ๋ฒ์
CLIยทhooks ๊ฐ ์ต์ ํ๋๋ค โ ํ๋ก์ ํธ๋ง๋ค ๋ณต์ฌยท๊ฐฑ์ ๋, ๋ณ๋ sidecar self-update ๋ ๋ถํ์(์ฌ๋์๋ ๊ฐฑ์ ํ
sidecar shadow ์ฌ์คํ์ผ๋ก ๋ฐ์). (์ ์ญ sidecar on PATH ๋ ํด๋ฐฑ.) ์ฌ์์ฑ๊ธฐ = _tools/gen_commands.py.
hook-๋ด๋ถ ์ ์ฉ(pre/post/prompt)์ ์ฌ๋์๋ก ๋
ธ์ถํ์ง ์๋๋ค.
ing add์์ ํ ์คํธ์ ์ ธ ํน์๋ฌธ์(๊ดํธยท๋ฐ์ดํยท$ยทโ)๊ฐ ์์ผ๋ฉด ์ฌ๋์$ARGUMENTS๋ฌด์ธ์ฉ ํ์ฅ์ด ๊นจ์ง๋ค โprintf '%s' "<text>" \| sidecar ing add --stdin(STDIN ๊ฒฝ๋ก)๋ก ์์ ํ๊ฒ ๋ฑ๋กํ๋ค. ING ๋ณด๋๋ ๋ด ํ์ฌ repo ์ ์ฉ์ด๋ค โ cross-repo ์ ๋ฌ(--to <repo>) ๊ธฐ๋ฅ์ ํ๊ธฐ๋๋ค(์ง์ ์์ ์์น ยท commonsupstream-fix). upstream(hexa/hexa-lang/demiurge) ๊ฒฐํจ์ ๊ทธ ์ธ์ ์์ ์ง์ ๊ณ ์ณ ๊ทธ repo ์pr-cycle๋ก ๋จธ์งํ๋ค.
๋จธ์ ์ ์ฌ์ด๋์นด๋ฅผ ๊ณต์ฉ ๋ช ๋ น์ผ๋ก ๊น๊ณ ์ ์ญ ํ ๊น์ง ํ ๋ฐฉ์ ๋ฐฐ์ ํ๋ค(ํน์ repo ๋จ๋ ์ธํ ์๋). ๋ถํธ์คํธ๋ฉ one-liner:
curl -fsSL https://raw.githubusercontent.com/dancinlab/sidecar/main/scripts/install.sh | bashํ๋ ์ผ(๋ฉฑ๋ฑ โ ์ฌ์คํ = ์ต์ ์ผ๋ก ๊ฐฑ์ ):
โฌ clone dancinlab/sidecar โ ~/.sidecar/cli
๐ link sidecar ๋ํผ โ ~/.local/bin/sidecar (PATH ์๋ด)
๐ช hooks sidecar install-hooks --global (๋ชจ๋ Claude Code ์ธ์
์ ๊ฐ๋/์ฃผ์
)
์ดํ ๊ฐฑ์ ์ sidecar self-update, ์ด๋ฏธ ์ฌ์ด๋์นด๊ฐ ๊น๋ ค ์์ผ๋ฉด sidecar install ๋ก๋ ๋์ผ ๋์. ํ
์์ด ๊น๋ ค๋ฉด --no-hooks, ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ --dry-run. ๊ทธ๋ค์ ํน์ repo ์ ์ ์ฉํ๋ ค๋ฉด ์๋ 1ยท2 ๋จ๊ณ(๋๋ sidecar init).
cd your-repo
git submodule add https://github.com/dancinlab/sidecar .harness-engine
# ๋๋ ๊ทธ๋ฅ clone / vendor ํด๋ ๋จbash .harness-engine/bin/sidecar init์ด ํ ์ค์ด ๋ง๋ ๋ค (๊ธฐ์กด ํ์ผ์ ๋ณด์กด, --force ๋ง ์์ธ ยท --dry-run ์ผ๋ก ๋ฏธ๋ฆฌ๋ณด๊ธฐ):
โ harness.config.json ํ๋ก์ ํธ๋ช
์๋๊ฐ์ง
โ .harness/enforcement.json ๋ฒ๋ค ๊ธฐ๋ณธ ๊ท์น ๋ณต์ฌ (repo ๊ฐ ์์ )
โ .harness/keywords.json
โ .harness/severity-map.json
โ .gitignore ๋ก๊ทธ ๋ฌด์ ์ถ๊ฐ
โ scripts/sidecar ์์ ๋ํผ
๐ช ํ ์ ์ ์ญ 1๋ฒ ์ ์ฉ (global-only): per-repo
.claude/settings.json์ ์ฐ์ง ์๋๋ค(์ ์ญ ์ค์น์ ์ค๋ณต๋ผ ์ปจํ ์คํธ๊ฐ 2~3์ค ์ฃผ์ ๋๋ ๋ฒ๊ทธ). ํ ๋ฐฐ์ ์ ํธ์คํธ๋น ํ ๋ฒsidecar install(๋๋sidecar install-hooks) ๋ก ๋๋ธ๋ค โ ๊ทธ๋ฌ๋ฉด ๋ชจ๋ repo ์์ ๊ฐ๋/์ธ์ ํธ๊ฐ ๋ฐ์ฌ๋๋ค.
์์ฑ ํ harness.config.json ์ verify.checks ยท lockdown.files ๋ง repo ์ ๋ง๊ฒ ์ฑ์ฐ๋ฉด ๋๋ค.
๐งช ์ฐ๊ตฌ/์ค๊ณ ์บ ํ์ธ ๊ณจ๊ฒฉ์
sidecar lab init <dir>: lumen/rtsc/carbon-capture ์๋งค-repo ์ค์ผ๋ ํค(srcยทstateยทARCHITECTURE+๋ทฐ์ด+serveยทHYPOTHESES pre-registerโfalsifyโrunโverdictยทtool/.py harness)์ ํ ๋ฐฉ์ ๋ฐฉ์ถ. ์์ฑCLAUDE.md๋ demiurge ๊ต์ฐจ-repo ๊ท์ฝ์ ๋ช ์ํ๋ค โ ๊ตฌํ์ฝ๋=canonicalhexa-langstdlib(repo ๋ docs/manifest ๋ง consume, d3) + ์ปดํจํธ ๊ธฐ๋ณธ์์ง=QFORGE-native(QE ๋ ๋ฏธ์ ํ ์กฐ๊ฐ fallbackยทโค1% gate, d_qforge_default).init(๊ฑฐ๋ฒ๋์ค ์ค์น)๊ณผ ๋ณ๊ฐ ยท files-only(git init/push ์์).
์๋ ์ค์ ๋ ๊ฐ๋ฅ:
.harness/*.json์ ๋์ง ์์ผ๋ฉด ๋ฒ๋ค ๊ธฐ๋ณธ ๊ท์น(config/*.json)์ด ์๋ ์ ์ฉ๋๋ค.์ ๊ฑฐ:
sidecar uninstall(์ฃผ์ ๋ฌผ๋ง ์ ๊ฑฐ, ์ฌ์ฉ์ ์ฝํ ์ธ ๋ณด์กด ยท--dry-run๋ฏธ๋ฆฌ๋ณด๊ธฐ). ์์ธ docs/install.md.
bash .harness-engine/bin/sidecar audit
bash .harness-engine/bin/sidecar ci list.claude/settings.json:
ํ๊ฒฝ๋ณ์ ์ด๋ฆ(
CLAUDE_TOOL_INPUT๋ฑ)์ ๋ฐํ์ ๋ฒ์ ์ ๋ฐ๋ผ ๋ค๋ฅผ ์ ์๋ค. ์ฌ์ด๋์นด๋CLAUDE_TOOL_INPUT์CODEX_TOOL_INPUT๋ ๋ค ์ฝ๋๋ค. JSON ํ์:{"command":"...","file_path":"...","content":"..."}.
๐ก
sidecar install-hooks [--global|--repo]๋ hook ๋ฐฐ์ ๊ณผ ํจ๊ปsettings.json์env์CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1๋ ์ธํ ํ๋ค โ ๋ฐฑ๊ทธ๋ผ์ด๋ subagent ์SendMessage(agent-teams)๋ฅผ ๊ธฐ๋ณธ ํ์ฑํ. ์ด๋ฏธ ๊ทธ ํค๊ฐ ์์ผ๋ฉด ์ฌ์ฉ์ ๊ฐ์ ๋ณด์กดํ๋ค(๋ฎ์ด์ฐ์ง ์์). ๋๋ ค๋ฉด ๊ทธ ํค๋ฅผ"0"์ผ๋ก ๋๋ฉด ๋๋ค.
์ฌ์ฉ์ ํ๋กฌํํธ โโถ [prompt] ํค์๋ ํธ๋ฆฌ๊ฑฐ + ํํธ ์ฃผ์
์์ด์ ํธ Bash โโถ [pre bash] โ ๋งค์นญ? โโถ block(stdout JSON) / warn(stderr) / ํต๊ณผ(์นจ๋ฌต)
โ
โผ (์คํ ํ)
[post bash <exit>] โ 0โ exit โโถ errors ํ ๋ผ์ฐํ
์์ด์ ํธ Edit โโถ [pre write] โ ๊ฒฝ๋ก/๋ด์ฉ ๊ท์น โโถ block/warn
[post edit <file>] โ L0? โโถ ๊ฒฝ๊ณ
์์ด์ ํธ MCPํด โโถ [pre tool] โ ๋ ์ง์คํธ๋ฆฌ ๋ถ๋ฅ โ Rule-of-Two โโถ block/warn/ํต๊ณผ
์ปค๋ฐ ์ โโถ [lint] + [verify]
์ธ์
์ข
๋ฃ โโถ [ing]
๋ชจ๋ ๋จ๊ณ๋ .harness/logs/*.jsonl ์ ํ ์ค์ฉ ์์ธ๋ค โ audit ์ด ์ด๋ฅผ ์ฝ์ด ๊ฑด๊ฐ๋๋ฅผ ์ ์ํํ๋ค.
- docs/languages.md โ ์ธ์ด/ํ๋ซํผ ๋ฒ์ฉ์ฑ (PythonยทRustยทCยทGoยทSwiftยทhexa ํ๋ฆฌ์ + Node ๋ฐํ์ ์๊ตฌ)
- ARCHITECTURE.json โ ์ฌ์ด๋์นด ์ํคํ
์ฒ ํธ๋ฆฌ SSOT (์ปฌ๋ผํ ๋
ธ๋: nameยทroleยทidยทdetail ยท ๊ฐ ๋
ธ๋ ๊ณ ์ kebab-case id=๊ฒ์ํค,
sidecar architecture search <q>). ์ฌ๋์ฉ ๋ทฐ์ด๋ ARCHITECTURE.html โ ๋ก์ปฌ์python3 serve.py(์๋ฒ + ๋ธ๋ผ์ฐ์ ์๋ ์คํ), ์๊ฒฉ์ raw.githack.com / GitHub Pages - docs/install.md โ repo ํตํฉ ์์ธ (submodule / vendor / ๋ฉํฐ repo)
- docs/extending.md โ ๊ท์น ์ถ๊ฐ, ๋๋ฉ์ธ ๋ชจ๋ ํ์ฅ ํจํด
์ด repo ์์ฒด๊ฐ ์ฌ์ด๋์นด๋ฅผ ์ด๋ค(dogfooding) โ harness.config.json + .claude/settings.json self hooks + pre-commit bin/sidecar lint. ์ฝ์ด(.ts) ๋ณ๊ฒฝ ์ CHANGELOG ๋์ ๊ฐฑ์ ์ด ๊ฐ์ ๋๊ณ , ๋ฒ๋ค enforcement(root-causeยทsecretยทforce-push)๊ฐ ์๊ธฐ ์ฝ๋์๋ ์ ์ฉ๋๋ค. ๋จ protectedBranches ๋ฏธ์ค์ ์ผ๋ก ์๊ธฐ ๊ฐ๋ฐ ํ๋ฆ(main ์ง์ push)์ ๋ง์ง ์๋๋ค.
๋งค ์ฌ์ดํด(sidecar pr-cycle)์ doc-gate ๋ ์๋ฏธ์๋ ๋ณ๊ฒฝ์ ๋ํด CHANGELOG.jsonl(append) + (์กด์ฌ ์) ARCHITECTURE.jsonยทREADME.md ํํํ๋ฅผ ์๊ตฌํ๋ค โ ์
์ค ๋ฏธ๊ฐฑ์ ์ด ์์ผ๋ฉด ๋จธ์ง๋ฅผ ๊ฑฐ๋ถํ๋ค(--no-doc ๋ ์ง์ง ๋ฌธ์ ๋ถํ์ํ ๋๋ง). ์ด README ๋ ๊ทธ ๋์์ด๋ฏ๋ก ๋งค ์ฌ์ดํด ์ต์ ์ํ๋ก ์ ์ง๋๋ค. (commons cycle-docs-pr)
๐ README = ํ์ฌ์ํ SSOT, ์ด๋ ฅ ๋ก๊ทธ ์๋ (ARCHITECTURE ์ ๋๊ธ ๊ท์จ ยท commons
single-doc). README ํํํ๋ ์ง๊ธ์ ๊ธฐ๋ฅยท์ฌ์ฉ๋ฒยท๊ตฌ์กฐ๋ฅผ ์ ์๋ฆฌ ๋ฎ์ด์ฐ๊ธฐ(update-in-place) ํ๋ ๊ฒ์ด์ง, ๋ณ๊ฒฝ์ด๋ ฅ์ ๋ง๋ถ์ด๋ ๊ฒ ์๋๋ค. README ์ ๋ฒ์ ๋ก๊ทธยท๋ ์งยท์ด์ ์โฆ/deprecated/"v0.x ์์ ์ถ๊ฐ" ์ ๋์ ๊ธ์ง โ ์ด๋ ฅ์ CHANGELOG.jsonl + git ์ด SSOT.
๐ณ ARCHITECTURE.json ํธ๋ฆฌ ์์ ๊ฐ์ (
architecture lintยท commonssingle-doc): ์ค๊ณ ํธ๋ฆฌ๋ ์๊ฒ ๋ถํด๋ ๋ฑ๋ฑํ ๋ ธ๋๋ก ์ ์ง๋๋ค โ์์ธ/์ญํ์ ์ดlint.archCellCap(๊ธฐ๋ณธ 300์ ยท config-driven ยท 0=off)์ ๋๊ฑฐ๋(ARCH-BIG-CELL),ยท๋ก ๋ฌถ์ธ ํญ๋ชฉ์ดlint.archPiledMax(6)๋ฅผ ๋์ผ๋ฉด(ARCH-PILED), ๋๋ history ์ฑ ํค(previous/deprecated/โฆ=ARCH-HISTORY)๊ฐ ์์ผ๋ฉดsidecar lint(pre-commit)๊ฐ ์ปค๋ฐ์ ๋ง๋๋ค(severity-mapARCH-*=block). ๊ฐ ๋ ธ๋๋ ๊ณ ์ kebab-case id ๋ ํ์(๋ถ์ฌ/์ค๋ณต/ํ์ = ARCH-ID-MISSING/DUPE/FORMAT=block ยท ๋ ๊ฑฐ์slug/ํ๊ธํค read-fallback). ๋จ, ์ด ๊ฒ์ดํธ๋ค์ canonicalname/childrenํธ๋ฆฌ๋ง ์ธ์ํ๋ฏ๋ก,name(๋ ๊ฑฐ์์ด๋ฆ)-๋ ธ๋๊ฐ 0์ธ ๋น-canonical ์คํค๋ง(์:sections/blocks/title)๋ id ๊ฒ์ดํธ๊ฐ ์กฐ์ฉํ ํต๊ณผํ๋ ์ฌ๊ฐ์ง๋์๋ค โ ์ด์ ARCH-SCHEMA-UNRECOGNIZED(warn)๊ฐ "id ๊ฒ์ดํธ ๋นํ์ฑ" ์ ํ๋ฉดํํ๋ค(off-schema ์ค๊ณ๋ฌธ์๊ฐ id ๊ฐ์ ๋ฅผ ๋ชฐ๋ ์ฐํ ๋ชป ํจ). ํฐ ์ ์ ์ฐ๋ฌธ leaf ๊ฐ ์๋๋ผ ์ปค๋๋ง ๋จ๊ธฐ๊ณ (์ฐ๋ฌธยท๋ฉ์ปค๋์ฆยทprecedent ๋ CHANGELOG/git/์ฝ๋๋ก) ๋๋ ํ ์ฌ์ค๋น ํ child ๋ ธ๋๋ก ์ชผ๊ฐ ๋ค.
sidecar pr-cycle ์ ๊ฒ์ฆ๋ ๋จธ์ง ์งํ ๋ก์ปฌ base(main) ๋ฅผ origin/base ๋ก ff-sync ํ๋ค(feature ๋ธ๋์น์์ git fetch origin <base>:<base> โ checkout ์ ํ ์์ด ๋ก์ปฌ main ๋ค์ฒ์ง ๋ฐฉ์ง, non-ff ๊ฑฐ๋ถ=์์ ) โ ๋ค์ ์์
๋ธ๋์น๋ ํญ์ ์ต์ base ์์ ๋ถ๊ธฐ๋๋ค. (commons cycle-docs-pr)
๋ฃจํธ CLAUDE.md ๋ ์ง์
ํฌ์ธํฐ(ํ๋ก์ ํธ ์ค๋ช
+ SSOT ํฌ์ธํฐ + ์์
๊ท์น)๋ค โ ๋๋ ํ ๋ฆฌยท๋ชจ๋ ํธ๋ฆฌ๋ ARCHITECTURE.json ๋จ์ผ SSOT ๋ผ CLAUDE.md ์ ์ค๋ณตํ์ง ์๋๋ค(docs.ts ์ CLAUDE-MD-NO-TREE ๊ฒ์ฌ๋ ๊ตฌ์กฐ SSOT ์กด์ฌ ์ ๋ฉด์ ยท ํธ๋ฆฌ drift ๋ฐฉ์ง).
๊ฑฐ๋ฒ๋์ค SSOT config/commons.md ์ ๋ฃจํธ CLAUDE.md ๋ slug ํค do/dont ํ์์ด๋ค โ ๊ฐ ๊ท์น์ ## <slug> โ <title> + - do:/- dont: ๋ ์ค(๋ฒํธ ID ์์ ยท ์์ ๋ฌด๊ด ยท ์ฒซ ## ์ preamble ์ ๋ฉด์ ยท ์๋ธํด๋ CLAUDE.md ๋ folder-docs ์์ ์์์ด๋ผ ์ ์ธ). ๋ฉ์ปค๋์ฆยท์ค์ฆ์ ์ฝ๋ hook + CHANGELOGยทgit ์ด ๋ด๊ณ , ๊ท์น์ do/dont ํต์ฌ๋ง ์ด๋ฐํ๋ค. ํ์์ 2์ธต์ผ๋ก ๊ฐ์ ๋๋ค(sidecar ๋ํ): โ write-time โ pre write ๊ฐ commons.md/๋ฃจํธ CLAUDE.md ์ ์ฒด-๋ฌธ์ Write ๊ฐ do/dont-only ์๋๋ฉด(๋๋ ์น์
์ด do+dont ๋ ๋ค ๊ฐ์ง ์์ผ๋ฉด) ์ฆ์ permissionDecision: deny(์ฐ๋ฌธ/ํ์ชฝ-๋๋ฝ์ด๋ฉด ์ฐ๊ธฐ ์์ฒด๊ฐ ์ฐจ๋จ) ยท โก commit-time โ sidecar lint 4g(COMMONS-PROSE/COMMONS-NO-DODONT/COMMONS-DODONT-INCOMPLETE ยท block ยท commons.md + ๋ฃจํธ CLAUDE.md ๋ ๋ค ์ค์บ)๊ฐ backstop. ๋์ด commons.ts:lintCommonsText ์ฝ์ด๋ฅผ ๊ณต์ ํ๋ค.
do/dont ๊ธธ์ด cap (archive_sidecar tape-lint #2 ํฌํ
): commons.md + ๋ฃจํธ CLAUDE.md(ํ๋ก์ ํธ ๊ท์น SSOT) ์ ๊ฐ do/dont ์ํธ๋ฆฌ(=- do: ์ค + ๋ค๋ฐ๋ฅด๋ ๋ค์ฌ์ฐ๊ธฐ ์ฐ์์ค ์ ๋ถ ํฉ์ฐ โ ์ฐ์์ค๋ก ์ชผ๊ฐ cap ์ฐํ ์ฐจ๋จ)๋ codepoint ๊ธธ์ด lint.dodontCap(๊ธฐ๋ณธ 200 ยท config-driven ยท 0=off)์ ๋์ผ๋ฉด ์ ๋๋ค (์๋ธํด๋ CLAUDE.md = folder-docs ๋ก์ปฌ ๊ฐ์ด๋๋ ์์ ์์์ด๋ผ cap ๋์ ์๋) โ ํ ๊ท์น์ ํ ์ค๋ก ์งง๊ฒ, ๋์น๋ฉด ๋ณ๋ rule ๋ก ์ชผ๊ฐ๊ฑฐ๋ ๋ํ
์ผ์ ์ฝ๋+CHANGELOG ๋ก. diff-aware: slug|kind|idx ํค๋ก baseline ๊ณผ ๋์กฐํด ์๋ก/๋ ๊ธธ์ด์ง ์ค๋ง ์ฐจ๋จํ๊ณ ๊ธฐ์กด ๊ธด ์ค์ grandfather(์ค์ด๋ฉด ํต๊ณผ). write-๊ฐ๋(์ ์ฒด Write ์กฐ๊ธฐ์ฐจ๋จ DODONT-LONG) + sidecar lint 4h(HEAD ์ diff-aware โ WriteยทEdit ๋ชจ๋ ์ปค๋ฒ)์ 2์ธต.
์ด์ด์ stale-PR reaper ๊ฐ ๋๋ค โ ๊ฒ์ฆ ๋จธ์ง ์งํ ๋ด ๋ค๋ฅธ ์ด๋ฆฐ PR ์ ์ ์ ์ ๊ฒํด ๋จธ์ง๊ฐ๋ฅ(MERGEABLE)์ ์๋ squash-๋จธ์ง(์๊ธฐ PR ยท admin ยท delete-branch โ ๋ฉ์ธ ํ๋ฆ๊ณผ ๋์ผ ์ ๋ขฐ๋ชจ๋ธ), ๊ธฐ๊ณ๊ฐ ์์ ํ๊ฒ ๋ชป ๋ฟ๋ ๊ฒ(CONFLICTING/blocked)์ ์กฐ์น์(rebase ๋๋ gh pr close)๊ณผ ํจ๊ป ํฐ์๋ฆฌ๋ก ๋ณด๊ณ ํ๋ค. pr-cycle ์ด ์๋ ์๊ธฐ PR ๋ง ๋ค๋ค ์ค๋จยท์คํจํ ๋จธ์ง๊ฐ ์ด๋ฆฐ ์ฑ ์ฉ๋ ๋ฌธ์ ๋ฅผ ๋ง๋๋ค โ ๋ง๋ค์ด์ง PR ์ ๋งค ์ฌ์ดํด ์ฒ๋ฆฌ๋๊ฑฐ๋ ๊ฒฝ๋ณด๋๋ค. --no-reap ์ผ๋ก ๋๋ค.
๊ฐ์ doc-gate ๊ฐ pre-commit sidecar lint ์์๋ ๋ฐํํ๋ค โ pr-cycle ์ ์ ๊ฑฐ์ณ๋, ์๋ฏธ์๋ ์ฝ๋๊ฐ staged ์ธ๋ฐ CHANGELOG / (์กด์ฌ ์) ARCHITECTUREยทREADME ๊ฐ ๊ฐ์ด staged ์ ๋์ผ๋ฉด commit ์ ์ฐจ๋จํ๋ค(CHANGELOG-MISSINGยทARCHITECTURE-MISSINGยทREADME-MISSING, ๋ชจ๋ block). ์ง์ง ๋ฌธ์ ๋ถํ์ํ ๋ณ๊ฒฝ๋ง git commit --no-verify.
MIT
{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [{ "type": "command", "command": "CLAUDE_TOOL_INPUT=\"$CLAUDE_TOOL_INPUT\" bash .harness-engine/bin/sidecar pre bash" }] }, { "matcher": "Write|Edit", "hooks": [{ "type": "command", "command": "CLAUDE_TOOL_INPUT=\"$CLAUDE_TOOL_INPUT\" bash .harness-engine/bin/sidecar pre write" }] } ], "PostToolUse": [ { "matcher": "Write|Edit", "hooks": [{ "type": "command", "command": "bash .harness-engine/bin/sidecar post edit \"$CLAUDE_FILE_PATH\"" }] } ], "UserPromptSubmit": [ { "hooks": [{ "type": "command", "command": "bash .harness-engine/bin/sidecar prompt \"$CLAUDE_USER_PROMPT\"" }] } ] } }