Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
{
"name": "goax",
"description": "AI 에이전트 결과 일관성을 환경으로 통제하는 4계층 하네스 (Triage·Constitution·Module·Spec/ADR) + Spirit·Mistake Loop. bash+markdown only, 자연어로 도입. Claude Code·OpenCode 지원.",
"version": "0.6.1",
"version": "0.6.2",
"author": {
"name": "bluecheat",
"email": "itsinil@gmail.com"
Expand All @@ -30,5 +30,5 @@
]
}
],
"version": "0.6.1"
"version": "0.6.2"
}
2 changes: 1 addition & 1 deletion .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "goax",
"version": "0.6.1",
"version": "0.6.2",
"description": "AX 4-Layer harness — Triage / Constitution / Module / Spec·ADR + Spirit·Mistake Loop. Bash + Markdown only, with Claude-driven onboarding. Multi-CLI: Claude Code (native) + OpenCode (Hybrid compat via AGENTS.md SSOT + opencode.json).",
"author": {
"name": "bluecheat",
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ There is no `npm`/`make`/`gradle`. Anything more complex is invoked through Clau
- `scripts/provision.sh` — the installer. `up` calls it with `--json`; it reads MANIFEST and copies `templates/default/` into the user project. Lives at the plugin root (not `templates/default/.ax/scripts/`) because it *creates* `.ax/` — it cannot live inside what it installs. Root `install.sh` is an unrelated legacy stub that only prints install instructions.
- `templates/default/` — **everything that gets copied into a user project** when the `up` skill runs.
- `templates/default/MANIFEST` — installer SSOT. `up` reads this line-by-line; lines ending in `/` are recursive directory copies, `src -> dst` lines do rename copies. **When you add anything under `templates/default/`, update MANIFEST or the installer will not copy it.** Conditional copies (CLAUDE.md, settings.json, config.yml, mistakes/README.md, .gitignore) are intentionally outside MANIFEST and live in `skills/up/SKILL.md` §5–§6.
- `templates/default/.ax/scripts/bash/` — deterministic shell tooling (37 scripts). All follow the standard in `templates/default/.ax/scripts/bash/README.md`: `set -euo pipefail`, `--json --dry-run --help` options, `[goax]` stderr prefix, exit codes `0` ok / `1` error / `2` skipped. Their `--json` shape is `{status, result, next_step, warnings, errors}`. SKILL.md files invoke these and parse the JSON; they do not reimplement the logic inline.
- `templates/default/.ax/scripts/bash/` — deterministic shell tooling (38 scripts). All follow the standard in `templates/default/.ax/scripts/bash/README.md`: `set -euo pipefail`, `--json --dry-run --help` options, `[goax]` stderr prefix, exit codes `0` ok / `1` error / `2` skipped. Their `--json` shape is `{status, result, next_step, warnings, errors}`. SKILL.md files invoke these and parse the JSON; they do not reimplement the logic inline.
- `templates/default/.ax/hooks/{user-prompt,pre-bash,pre-edit,post-edit,pre-commit,subagent-start,stop}/*.sh` — sensors. The companion `.claude/settings.json.template` registers them; `doctor` cross-checks installed hooks against this template (it is the SSOT for which hooks *and which event keys* should be registered). `subagent-start/harness-pointer.sh` hands Constitution/Spirit/active-spec/handoff **pointer** to every non-goax subagent (the harness used to stop at the main session); `stop/spec-gate.sh` blocks the end of a turn once when an `implementing`/`review` spec fails `tasks-gate.sh`, unless `current-task.json.handoff.now` records it within 24h (`now_at`) (bounded by `stop_hook_active` and an 8-per-session counter). The two pre-edit injection hooks dedupe per session via `goax_inject_fresh` (`.ax/.session/<sid>/`, 4h TTL) — measured 1,200 repeat injections / 529KB in one real session before this.
- `templates/default/.ax/spirit/{values.md,tone.md,README.md}` — cross-cut Spirit (shared agent personality), the trio the plugin ships. `spirit/rules/` is user-curated (no plugin-shipped instances) — categories get added via onboarding/audit, seeded from `_templates/spirit/ops.md` as an opt-in baseline. Spirit rule headers must match `## SP-<CAT>-<NNN>: text` — `doctor` lints this.
- `templates/default/.ax/_templates/{spec,adr,module,spirit,mistakes}/` — SDD templates the user copies into their own work. `_templates/spec/.origin` is a sha snapshot the installer writes; `check-templates-drift.sh` diffs current vs `.origin` to detect user edits vs plugin updates.
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.6.1
0.6.2
40 changes: 40 additions & 0 deletions changelog/0.6.2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# 0.6.2 — 완료 마킹이 본문에 언급된 다른 task 까지 켜던 것 (spec-implement §5 인라인 sed → `mark-task.sh`)

## 달라지는 것

> 체감 범위: `spec-implement` 로 task 를 하나씩 끝내는 모든 프로젝트. tasks.md 본문이 다른 task 를 언급하는
> 게 권장 관행("T009 가 해소" · "T005 의 상수와 맞춤")이라, 그런 줄이 있는 spec 은 전부 해당해요.

- **완료 마킹이 그 task 한 줄만 켜요.** 전에는 §5 의 인라인 sed 가 `.*T013` 으로 줄 어디에든 ID 가 있으면
매칭해서, 아직 시작도 안 한 task 의 본문에 `T013` 이 적혀 있으면 그 줄까지 `[x]` 로 뒤집혔어요. 실측 —
T005·T007·T009 셋을 켜자 T008·T014·T058 이 검증 없이 완료가 됐고, `tasks-gate.sh` 는 그걸 정상으로
읽었어요(코디네이터가 켠 체크박스는 원장 없이도 정상이라 구분이 없어요). 이제 `mark-task.sh` 가 **줄 앞**
의 ID 만 보고(`- [ ] T013 ` · `**T013**` · `[T013]`), 코드 펜스 안은 건너뛰고, 쓰기 전후 `[x]` 개수가
정확히 1 늘었는지 확인해요 — 어긋나면 error 로 멈춰요.
- **"다음 task" 가 템플릿 예시를 집지 않아요.** §1 의 `grep -m1 '^- \[ \]'` 는 tasks.md 템플릿의 "한 줄 형식"
코드 펜스 안 예시(`- [ ] T001 [P] [AC2] <한 줄 설명>`)를 첫 미완료 task 로 돌려줬어요. `mark-task.sh --next`
는 펜스 밖 줄만 봐요.
- **마킹이 락을 잡아요.** 인라인 sed 는 `tasks.md.lock` 을 안 잡아서 같은 파일을 쓰는 `lanes-dispatch.sh`·
`tasks-gate.sh` 와 lost-update 가 날 수 있었어요. writer 계약(README §쓰기 규약)대로 같은 락 문자열을 써요.
- `spec-review.sh --merge --json` 이 합본 경로 `merged_file` 을 돌려줘요 (텍스트 모드만 찍던 것).

## 메인테이너용

- 결정론 경계 원칙(CLAUDE.md §Architecture 1) 위반이 하나 더 스크립트로 내려갔어요 — SKILL.md 에 남아 있던
마지막 `tasks.md` 인라인 writer 예요.
- `mark-task.sh` 는 `--state '~'` 로 의도적 보류도 켜요(사유는 손으로). bash `case` 패턴의 맨 `~` 는 홈으로
틸드 확장돼서 `"~"` 로 묶었어요.

## 세부 (스크립트)

- 신설 `templates/default/.ax/scripts/bash/mark-task.sh` — `--task T013 [--state x|~] [--dry-run] [--json]` ·
`--next [--json]`. 표준 옵션·`goax_help`·`goax_lock`·`goax_mktemp`·exit 0/1/2.
- `skills/spec-implement/SKILL.md` §1 `NEXT_TASK` · §5 마킹 → 스크립트 호출.
- `templates/default/.ax/scripts/bash/README.md` 목록 1행 · `spec-review.sh` JSON `merged_file`.

## 검증

- 픽스처(펜스 예시 + 본문 언급 3줄 + `**T014**`·`[T058]` 장식 + `[~]`): `--next` 가 펜스 밖 T001 · T009 마킹
뒤 T008 그대로 · T005 마킹 뒤 T014·T058 그대로 · idempotent `changed:false` · 없는 ID error · `--state '~'` ·
`--dry-run` 무변경 · 락 파일 잔존 0.
- `bash tests/smoke.sh` 통과.
1 change: 1 addition & 0 deletions changelog/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

## 버전

- [0.6.2](0.6.2.md) — 완료 마킹이 본문에 언급된 다른 task 까지 켜던 것 (`spec-implement` §5 인라인 sed → `mark-task.sh`, 펜스 안 예시를 다음 task 로 집던 것, 마킹 락)
- [0.6.1](0.6.1.md) — external 룰의 "자동 실행 안 됨" 경고(I6)가 git 프로젝트에서 한 번도 안 뜨던 것 + 임시 파일·git 이 막힌 환경에서 doctor·`up` 이 틀리게 통과하던 것 (일반 환경 체감 없음) + eval 이 hook·스크립트 층까지
- [0.6.0](0.6.0.md) — 룰의 `검출 패턴:` 마커를 실제로 집행 (grep 룰의 승격 = 집행)
- [0.5.13](0.5.13.md) — `spec-completion-gate.sh` 가 spec 없는 triage 직후 매 커밋마다 jq 에러를 찍던 것
Expand Down
19 changes: 10 additions & 9 deletions skills/spec-implement/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,11 @@ for f in spec.md tasks.md; do
[ ! -f "$SPEC_DIR/$f" ] && { echo "$f 누락 — 먼저 작성"; exit 1; }
done

# 다음 미완료 task 찾기 — 없으면 끝난 게 아니라 §8 완료 게이트로 가요 (게이트가 완료를 판정해요)
NEXT_TASK=$(grep -m1 '^- \[ \]' "$SPEC_DIR/tasks.md" || true)
# 다음 미완료 task 찾기 — 없으면 끝난 게 아니라 §8 완료 게이트로 가요 (게이트가 완료를 판정해요).
# 맨 grep 을 쓰지 않아요 — 템플릿 "한 줄 형식" 코드 펜스 안의 예시(`- [ ] T001 [P] [AC2] <한 줄 설명>`)를
# 다음 task 로 집어요. mark-task.sh --next 는 펜스 밖 줄만 봐요.
NEXT=$(bash .ax/scripts/bash/mark-task.sh --spec "$SPEC" --next --json)
NEXT_TASK=$(printf '%s' "$NEXT" | jq -r '.result.task // empty')
[ -z "$NEXT_TASK" ] && echo "미완료 task 없음 → §8 완료 게이트로"
```

Expand Down Expand Up @@ -204,13 +207,11 @@ RECURRENCE=$(grep -lE "^category:.*\\b${TASK_DOMAIN}\\b" .ax/mistakes/*.md 2>/de
# 방금 끝낸 task 의 ID 를 변수로 — 예시값을 그대로 쓰면 엉뚱한 task 가 체크돼요.
TASK_ID="$COMPLETED_TASK_ID" # 예: T013

# 체크박스만 뒤집어요. task 줄 형식이 `**T013**`·`[T013]`·`T013 [P]` 중 무엇이든
# ID 만 찾으면 되도록 했어요 (출고 템플릿은 `- [ ] **T013** — ...` 형식).
# ID 뒤에 영숫자가 오면 매칭 안 함 → T001 이 T0011 을 건드리지 않아요.
# `\b` 는 GNU sed 전용이라 안 써요 (BSD/macOS 비호환).
sed -E "/^- \[ \] .*${TASK_ID}([^0-9A-Za-z]|\$)/ s/^- \[ \]/- [x]/" \
"$SPEC_DIR/tasks.md" > "$SPEC_DIR/tasks.md.tmp" \
&& mv "$SPEC_DIR/tasks.md.tmp" "$SPEC_DIR/tasks.md"
# 체크박스는 mark-task.sh 가 켜요 — 줄 **앞** 의 ID 만 보고(`- [ ] T013 `·`**T013**`·`[T013]`),
# 코드 펜스 안은 건너뛰고, tasks.md.lock 을 잡고, 쓰기 전후 [x] 개수가 정확히 1 늘었는지 확인해요.
# 인라인 sed(`.*T013`)로 하면 본문에 다른 task 를 언급한 줄("T009 가 해소")까지 켜져요 — 실측 3건.
bash .ax/scripts/bash/mark-task.sh --spec "$SPEC" --task "$TASK_ID" --json
# 의도적 보류는 --state '~' (사유는 task 줄에 `보류: <사유>` 로 손으로 적어요)
```

각 task 완료 후 1줄 보고 (대화 [y/n] X):
Expand Down
1 change: 1 addition & 0 deletions templates/default/.ax/scripts/bash/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
| `lanes-hotfiles.sh` | tasks.md 에서 핫 파일(여러 미완료 task 가 쓰는 파일) + `files:` 누락 task 추출 | `lane` |
| `spec-review.sh` | spec 합의 리뷰 원장 — `--snapshot`(sha 고정·라운드) / `--status`(리뷰어별 `review-spec.{architect,evaluator}.md` 의 verdict·sha 집계 → pass) / `--merge`(합본). 필수 여부는 Size 축만 | `spec-validate` |
| `lanes-dispatch.sh` | 레인 디스패치 원장 — `--assign / --dispatch / --report / --status`. tasks.md 의 `레인:`·`디스패치:`·`보고:` 필드를 쓰고, 파일 소유 충돌이면 dispatch 거부 | `lane`, `spec-implement` |
| `mark-task.sh` | tasks.md 체크박스 하나를 켜요 — `--task T013 [--state x\|~]` · `--next`(펜스 밖 첫 미완료). 줄 **앞** ID 만 매칭(본문 언급 무시), 코드 펜스 건너뜀, `tasks.md.lock`, 쓰기 전후 `[x]` 개수 검증 | `spec-implement` |
| `zero-init.sh` | 0→1 첫날 팩 설치 (룰은 라이브 `spirit/rules/`, 템플릿은 `_templates/zero/`) — 덮어쓰지 않고 SP 토큰 충돌만 경고 | `zero` |
| `zero-domain-risk.sh` | `config.yml` 의 `domain_risk` 블록 통째 교체 (`--show/--set/--default`) — 출고 예시 키가 남으면 triage 가 영원히 default_risk 로 흘러요 | `zero` |
| `zero-probe.sh` | 네거티브 프로브 — 일부러 위반을 만들어 차단이 실제로 도는지 확인 | `zero` |
Expand Down
Loading
Loading