makdoong2-team 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +193 -0
- package/agents/makdoong2-analyzer.md +135 -0
- package/agents/makdoong2-engineer.md +165 -0
- package/agents/makdoong2-planner.md +267 -0
- package/agents/makdoong2-publisher.md +481 -0
- package/agents/makdoong2-team-leader.md +249 -0
- package/agents/makdoong2-verifier.md +353 -0
- package/assets/makdoong2-team.default.json +46 -0
- package/assets/makdoong2-team.schema.json +357 -0
- package/bin/cli.js +404 -0
- package/dist/agent-stage-config.d.ts +15 -0
- package/dist/agent-stage-config.js +119 -0
- package/dist/config.d.ts +79 -0
- package/dist/config.js +96 -0
- package/dist/logger.d.ts +14 -0
- package/dist/logger.js +131 -0
- package/dist/mcp-secret-injector.d.ts +56 -0
- package/dist/mcp-secret-injector.js +89 -0
- package/dist/model-chain-cli.d.ts +1 -0
- package/dist/model-chain-cli.js +21 -0
- package/dist/model-fallback-policy.d.ts +69 -0
- package/dist/model-fallback-policy.js +211 -0
- package/dist/opencode-plugin.d.ts +8 -0
- package/dist/opencode-plugin.js +2457 -0
- package/dist/poll-sub-session.d.ts +139 -0
- package/dist/poll-sub-session.js +494 -0
- package/dist/redact-secrets.d.ts +3 -0
- package/dist/redact-secrets.js +68 -0
- package/dist/session-index.d.ts +11 -0
- package/dist/session-index.js +71 -0
- package/dist/skill-mcp-registry.d.ts +59 -0
- package/dist/skill-mcp-registry.js +178 -0
- package/dist/stall-escalation.d.ts +1 -0
- package/dist/stall-escalation.js +22 -0
- package/dist/tmux-monitor.d.ts +193 -0
- package/dist/tmux-monitor.js +694 -0
- package/dist/verdict-hash.d.ts +1 -0
- package/dist/verdict-hash.js +62 -0
- package/gates/stage-analysis-verify.sh +84 -0
- package/gates/stage2-requirements-verify.sh +13 -0
- package/gates/stage3-scope-verify.sh +45 -0
- package/gates/stage4-dev-post-verify.sh +64 -0
- package/gates/stage4-dev-verify.sh +36 -0
- package/gates/stage5-coverage-verify.sh +36 -0
- package/gates/stage5-test-verify.sh +24 -0
- package/gates/stage6-commit-verify.sh +41 -0
- package/gates/stage6-post-commit-verify.sh +131 -0
- package/gates/stage7-post-pr-verify.sh +53 -0
- package/gates/stage7-pr-verify.sh +48 -0
- package/gates/stage8-post-review-verify.sh +84 -0
- package/gates/stage8-review-verify.sh +45 -0
- package/gates/verify.sh +44 -0
- package/opencode.json.example +40 -0
- package/package.json +84 -0
- package/postinstall.mjs +56 -0
- package/references/commit-convention.md +130 -0
- package/references/jira-issue-templates.md +203 -0
- package/references/pr-template.md +381 -0
- package/scripts/config.sh +46 -0
- package/scripts/coverage-record.sh +67 -0
- package/scripts/gate-policy-test.sh +152 -0
- package/scripts/install-lib.mjs +1029 -0
- package/scripts/lint-agent-prompts.sh +74 -0
- package/scripts/log-event.sh +44 -0
- package/scripts/model-policy.mjs +183 -0
- package/scripts/publish-if-changed.sh +207 -0
- package/scripts/release.sh +276 -0
- package/scripts/rollback-commits.sh +35 -0
- package/scripts/smoke-test.mjs +194 -0
- package/scripts/state.sh +192 -0
- package/scripts/test-postinstall.mjs +141 -0
- package/scripts/with-fallback.sh +56 -0
- package/scripts/wt-sync-ignored.sh +193 -0
- package/skills/_lib/load-secret.sh +149 -0
- package/skills/bamboo-ci/SKILL.md +81 -0
- package/skills/bamboo-ci/run-bamboo.sh +23 -0
- package/skills/bitbucket-research/SKILL.md +87 -0
- package/skills/bitbucket-research/run-repos.sh +23 -0
- package/skills/confluence-research/SKILL.md +75 -0
- package/skills/confluence-research/run-docs.sh +23 -0
- package/skills/github-oss-research/SKILL.md +59 -0
- package/skills/jira-research/SKILL.md +75 -0
- package/skills/jira-research/run-works.sh +23 -0
- package/src/hooks/guard-bash.sh +67 -0
- package/src/hooks/session-start.sh +96 -0
- package/src/hooks/sync-state.sh +47 -0
- package/stages/01-jira.md +43 -0
- package/stages/01-planning.md +229 -0
- package/stages/02-requirements.md +298 -0
- package/stages/03-scope.md +81 -0
- package/stages/04-analysis.md +281 -0
- package/stages/05-worktree-dev.md +124 -0
- package/stages/06-test.md +161 -0
- package/stages/07-commit.md +229 -0
- package/stages/08-pr.md +177 -0
- package/stages/09-review-comments.md +277 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# coverage-record.sh <issue> <pct> [attempt]
|
|
3
|
+
#
|
|
4
|
+
# makdoong2-team.json 의 coverage.threshold 를 읽어 pct 와 숫자 비교 후
|
|
5
|
+
# state.json 에 pass/fail 을 결정론적으로 기록한다.
|
|
6
|
+
#
|
|
7
|
+
# LLM 이 임계값을 해석하거나 판단하지 않도록 비교 로직을 shell 로 위임.
|
|
8
|
+
# engineer 는 커버리지 숫자만 추출해서 이 스크립트에 넘기면 된다.
|
|
9
|
+
#
|
|
10
|
+
# 사용:
|
|
11
|
+
# bash <SCRIPTS_DIR>/coverage-record.sh <이슈키> <pct> [attempt]
|
|
12
|
+
#
|
|
13
|
+
# 인수:
|
|
14
|
+
# <이슈키> — 예: PROJ-12345
|
|
15
|
+
# <pct> — 측정된 커버리지 퍼센트 (정수 또는 소수, 예: 87 / 87.3)
|
|
16
|
+
# [attempt] — 라운드 번호. 미지정 시 state.json 의 기존 coverage_attempt+1 로
|
|
17
|
+
# 자동 증가한다 (초회 호출은 1). engineer 가 3회 재시도 흐름에서
|
|
18
|
+
# 라운드를 수동으로 관리하지 않도록 하는 안전장치.
|
|
19
|
+
#
|
|
20
|
+
# 종료코드:
|
|
21
|
+
# 0 → pass (pct >= threshold)
|
|
22
|
+
# 1 → fail (pct < threshold)
|
|
23
|
+
#
|
|
24
|
+
# 의존: awk, jq (config.sh 경유), state.sh
|
|
25
|
+
set -euo pipefail
|
|
26
|
+
|
|
27
|
+
HERE="$(cd "$(dirname "$0")" && pwd)"
|
|
28
|
+
|
|
29
|
+
ISSUE="${1:?usage: coverage-record.sh <issue> <pct> [attempt]}"
|
|
30
|
+
PCT="${2:?usage: coverage-record.sh <issue> <pct> [attempt]}"
|
|
31
|
+
|
|
32
|
+
if [[ $# -ge 3 && -n "$3" ]]; then
|
|
33
|
+
ATTEMPT="$3"
|
|
34
|
+
else
|
|
35
|
+
PREV_ATTEMPT="$("$HERE/state.sh" get "$ISSUE" \
|
|
36
|
+
'.stages."2_implementation".substages."test".coverage_attempt' 2>/dev/null || echo "null")"
|
|
37
|
+
case "$PREV_ATTEMPT" in
|
|
38
|
+
''|null|None) ATTEMPT=1 ;;
|
|
39
|
+
*)
|
|
40
|
+
if [[ "$PREV_ATTEMPT" =~ ^[0-9]+$ ]]; then
|
|
41
|
+
ATTEMPT=$((PREV_ATTEMPT + 1))
|
|
42
|
+
else
|
|
43
|
+
ATTEMPT=1
|
|
44
|
+
fi
|
|
45
|
+
;;
|
|
46
|
+
esac
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
THRESHOLD="$("$HERE/config.sh" get coverage.threshold 95)"
|
|
50
|
+
|
|
51
|
+
"$HERE/state.sh" set "$ISSUE" \
|
|
52
|
+
'.stages."2_implementation".substages."test".coverage_pct' "$PCT"
|
|
53
|
+
"$HERE/state.sh" set "$ISSUE" \
|
|
54
|
+
'.stages."2_implementation".substages."test".coverage_attempt' "$ATTEMPT"
|
|
55
|
+
|
|
56
|
+
# awk: shell 산술은 정수 전용이므로 소수점 비교는 awk 에 위임
|
|
57
|
+
if awk "BEGIN{exit !($PCT + 0 >= $THRESHOLD + 0)}"; then
|
|
58
|
+
"$HERE/state.sh" set "$ISSUE" \
|
|
59
|
+
'.stages."2_implementation".substages."test".coverage' '"pass"'
|
|
60
|
+
echo "COVERAGE PASS: ${PCT}% >= ${THRESHOLD}% (라운드 ${ATTEMPT})"
|
|
61
|
+
exit 0
|
|
62
|
+
else
|
|
63
|
+
"$HERE/state.sh" set "$ISSUE" \
|
|
64
|
+
'.stages."2_implementation".substages."test".coverage' '"fail"'
|
|
65
|
+
echo "COVERAGE FAIL: ${PCT}% < ${THRESHOLD}% (라운드 ${ATTEMPT})"
|
|
66
|
+
exit 1
|
|
67
|
+
fi
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# gate-policy-test.sh — 작업 범주화(.policy) 기반 조건부 auto-approve 게이트 단위 테스트.
|
|
3
|
+
#
|
|
4
|
+
# 2단계에서 결정한 `.policy.auto_approve.<stage>` 마커가 stage3/4/6/8 진입 게이트의
|
|
5
|
+
# 사람-승인 분기를 올바르게 제어하는지 임시 git repo + state.json 픽스처로 검증한다.
|
|
6
|
+
# - minor (기본) → 모든 게이트 무인 통과
|
|
7
|
+
# - major (기본) → 모든 게이트 무인 통과 (category 는 위험도 라벨/opt-in 훅용)
|
|
8
|
+
# - HITL opt-in (auto_approve="false") → 해당 substage 만 변경 보고서 + 승인 요구
|
|
9
|
+
# - 구형 state (.policy 미설정) → 기존 사람-승인 동작 보존 (backward-compat)
|
|
10
|
+
#
|
|
11
|
+
# 의존: jq, git, bash. 실행: bash scripts/gate-policy-test.sh (exit 0=all pass / 1=fail)
|
|
12
|
+
set -uo pipefail
|
|
13
|
+
|
|
14
|
+
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
15
|
+
GATES="$REPO_ROOT/gates"
|
|
16
|
+
ISSUE="TEST-1"
|
|
17
|
+
|
|
18
|
+
pass=0; fail=0
|
|
19
|
+
|
|
20
|
+
TMP="$(mktemp -d)"
|
|
21
|
+
cleanup(){ rm -rf "$TMP"; }
|
|
22
|
+
trap cleanup EXIT
|
|
23
|
+
|
|
24
|
+
git init -q "$TMP"
|
|
25
|
+
ROOT="$(cd "$TMP" && git rev-parse --show-toplevel)"
|
|
26
|
+
SDIR="$ROOT/.makdoong2-team/$ISSUE"
|
|
27
|
+
mkdir -p "$SDIR"
|
|
28
|
+
STATE="$SDIR/state.json"
|
|
29
|
+
REPORT="$SDIR/change-report.md"
|
|
30
|
+
|
|
31
|
+
# 격리된 설정 디렉토리 — config.sh(coverage.threshold)가 결정론적으로 읽도록 XDG를 고정.
|
|
32
|
+
XDGHOME="$TMP/xdg"; mkdir -p "$XDGHOME/opencode"
|
|
33
|
+
printf '{"coverage":{"threshold":95}}\n' > "$XDGHOME/opencode/makdoong2-team.json"
|
|
34
|
+
|
|
35
|
+
# 기준 state.json에 jq 필터를 적용해 시나리오별 픽스처 작성 (신 hierarchical 구조).
|
|
36
|
+
BASE='{"issue":"TEST-1","worktree":"'"$ROOT"'","stages":{"1_planning":{"done":false,"substages":{"jira":{"done":true,"validation_passed":true},"requirements":{"done":false},"scope":{"done":false}}},"2_implementation":{"done":false,"substages":{"dev":{"done":false},"test":{"unit":"none","integration":"none","coverage":"none"}}},"3_delivery":{"done":false,"substages":{"commit":{"done":false},"pr":{"draft_url":null},"review":{"comments":0}}}},"policy":null}'
|
|
37
|
+
mk(){ echo "$BASE" | jq "$1" > "$STATE"; }
|
|
38
|
+
|
|
39
|
+
# expect <name> <want: pass|block> <gate-script>
|
|
40
|
+
expect(){
|
|
41
|
+
local name="$1" want="$2" script="$3" out rc got
|
|
42
|
+
out="$(cd "$ROOT" && XDG_CONFIG_HOME="$XDGHOME" bash "$GATES/$script" "$ISSUE" 2>&1)"; rc=$?
|
|
43
|
+
got=block; [ "$rc" -eq 0 ] && got=pass
|
|
44
|
+
if [ "$got" = "$want" ]; then
|
|
45
|
+
echo " ✓ $name ($want)"; pass=$((pass+1))
|
|
46
|
+
else
|
|
47
|
+
echo " ✗ $name: want=$want got=$got (rc=$rc)"; echo "$out" | head -1 | sed 's/^/ /'; fail=$((fail+1))
|
|
48
|
+
fi
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
echo ""
|
|
52
|
+
echo "[gate-policy-test] 조건부 auto-approve 게이트 분기"
|
|
53
|
+
echo ""
|
|
54
|
+
echo "── stage3-scope-verify (2→3) ──"
|
|
55
|
+
rm -f "$REPORT"
|
|
56
|
+
|
|
57
|
+
# minor (기본): auto_approve true → 승인/pending 무시하고 통과
|
|
58
|
+
mk '.stages."1_planning".substages."requirements".done=true | .stages."1_planning".substages."requirements".verification_pending=true | .policy={category:"minor",auto_approve:{"1_planning.requirements":true}}'
|
|
59
|
+
expect "minor 기본 auto-approve (승인 없이 통과)" pass stage3-scope-verify.sh
|
|
60
|
+
|
|
61
|
+
# major (기본): auto_approve true → 통과 (minor 와 동일 흐름 — category 는 라벨용)
|
|
62
|
+
mk '.stages."1_planning".substages."requirements".done=true | .policy={category:"major",auto_approve:{"1_planning.requirements":true}}'
|
|
63
|
+
expect "major 기본도 요구사항 게이트는 무인 통과" pass stage3-scope-verify.sh
|
|
64
|
+
|
|
65
|
+
# legacy(no policy) + 미승인 → 차단
|
|
66
|
+
mk '.stages."1_planning".substages."requirements".done=true | .stages."1_planning".substages."requirements".approved_by_user=false'
|
|
67
|
+
expect "구형 state 미승인 → 차단" block stage3-scope-verify.sh
|
|
68
|
+
|
|
69
|
+
# legacy(no policy) + 승인 → 통과
|
|
70
|
+
mk '.stages."1_planning".substages."requirements".done=true | .stages."1_planning".substages."requirements".approved_by_user=true | .stages."1_planning".substages."requirements".verification_pending=false'
|
|
71
|
+
expect "구형 state 사용자 승인 → 통과" pass stage3-scope-verify.sh
|
|
72
|
+
|
|
73
|
+
# auto-approve여도 인터뷰 미완료면 차단 (정합성 게이트는 독립)
|
|
74
|
+
mk '.stages."1_planning".substages."requirements".done=true | .stages."1_planning".substages."requirements".interview_required=true | .stages."1_planning".substages."requirements".interview_completed=false | .policy={category:"minor",auto_approve:{"1_planning.requirements":true}}'
|
|
75
|
+
expect "인터뷰 미완료 → 차단 (auto와 무관)" block stage3-scope-verify.sh
|
|
76
|
+
|
|
77
|
+
echo ""
|
|
78
|
+
echo "── stage4-dev-verify (3→4) ──"
|
|
79
|
+
# worktree 경로 검증을 위해 실제 git worktree 생성 (메인 repo의 형제)
|
|
80
|
+
WT="$(dirname "$TMP")/$(basename "$TMP")-TEST-1"
|
|
81
|
+
(cd "$ROOT" && git worktree add "$WT" -b test-branch 2>/dev/null || true)
|
|
82
|
+
mk '.stages."1_planning".substages."scope".done=true | .stages."1_planning".substages."scope".verification_pending=true | .stages."2_implementation".substages."analysis".done=true | .policy={category:"minor",auto_approve:{"1_planning.scope":true}} | .worktree="'"$WT"'"'
|
|
83
|
+
expect "minor auto-approve → 통과" pass stage4-dev-verify.sh
|
|
84
|
+
mk '.stages."1_planning".substages."scope".done=true | .stages."1_planning".substages."scope".approved_by_user=false | .stages."2_implementation".substages."analysis".done=true | .worktree="'"$WT"'"'
|
|
85
|
+
expect "구형 state 미승인 → 차단" block stage4-dev-verify.sh
|
|
86
|
+
mk '.stages."1_planning".substages."scope".done=true | .stages."1_planning".substages."scope".approved_by_user=true | .stages."2_implementation".substages."analysis".done=true | .worktree="'"$WT"'"'
|
|
87
|
+
expect "구형 state 승인 → 통과" pass stage4-dev-verify.sh
|
|
88
|
+
|
|
89
|
+
echo ""
|
|
90
|
+
echo "── stage6-commit-verify (5→6) ──"
|
|
91
|
+
TESTS='.stages."1_planning".substages."jira".done=true | .stages."1_planning".substages."requirements".done=true | .stages."1_planning".substages."scope".done=true | .stages."2_implementation".substages."dev".done=true | .stages."2_implementation".substages."test".unit="pass" | .stages."2_implementation".substages."test".integration="skip" | .stages."2_implementation".substages."test".coverage="exempt"'
|
|
92
|
+
|
|
93
|
+
# minor (기본): commit auto_approve true → 보고서/승인 없이 통과
|
|
94
|
+
rm -f "$REPORT"
|
|
95
|
+
mk "$TESTS | .policy={category:\"minor\",auto_approve:{\"3_delivery.commit\":true}}"
|
|
96
|
+
expect "minor 기본 → 휴먼 게이트 없이 통과" pass stage6-commit-verify.sh
|
|
97
|
+
|
|
98
|
+
# major (기본): commit auto_approve true → 보고서/승인 없이 통과 (minor 와 동일 흐름)
|
|
99
|
+
rm -f "$REPORT"
|
|
100
|
+
mk "$TESTS | .policy={category:\"major\",auto_approve:{\"3_delivery.commit\":true}}"
|
|
101
|
+
expect "major 기본 (auto_approve=true) → 휴먼 게이트 없이 통과" pass stage6-commit-verify.sh
|
|
102
|
+
|
|
103
|
+
# HITL opt-in: 보고서 없음 + pending 없음 = 초기 상태 → 통과 (publisher 첫 dispatch 허용)
|
|
104
|
+
rm -f "$REPORT"
|
|
105
|
+
mk "$TESTS | .policy={category:\"major\",auto_approve:{\"3_delivery.commit\":false}}"
|
|
106
|
+
expect "HITL opt-in + 보고서 없음 (초기 상태) → 통과" pass stage6-commit-verify.sh
|
|
107
|
+
|
|
108
|
+
# HITL opt-in: 보고서 없음 + pending=true → 차단 (publisher가 보고서 생성 후 pending 세팅, 승인 대기)
|
|
109
|
+
rm -f "$REPORT"
|
|
110
|
+
mk "$TESTS | .policy={category:\"major\",auto_approve:{\"3_delivery.commit\":false}} | .stages.\"3_delivery\".substages.\"commit\".verification_pending=true"
|
|
111
|
+
expect "HITL opt-in + 보고서 없음 + pending=true → 차단" block stage6-commit-verify.sh
|
|
112
|
+
|
|
113
|
+
# HITL opt-in: 보고서 있으나 미승인 → 차단
|
|
114
|
+
echo "# 변경 보고서" > "$REPORT"
|
|
115
|
+
mk "$TESTS | .policy={category:\"major\",auto_approve:{\"3_delivery.commit\":false}} | .stages.\"3_delivery\".substages.\"commit\".approved_by_user=false"
|
|
116
|
+
expect "HITL opt-in + 보고서O + 미승인 → 차단" block stage6-commit-verify.sh
|
|
117
|
+
|
|
118
|
+
# HITL opt-in: 보고서 있고 승인 + pending=false → 통과
|
|
119
|
+
mk "$TESTS | .policy={category:\"major\",auto_approve:{\"3_delivery.commit\":false}} | .stages.\"3_delivery\".substages.\"commit\".approved_by_user=true | .stages.\"3_delivery\".substages.\"commit\".verification_pending=false"
|
|
120
|
+
expect "HITL opt-in + 보고서O + 승인 → 통과" pass stage6-commit-verify.sh
|
|
121
|
+
|
|
122
|
+
# HITL opt-in: 승인했으나 verification_pending=true → 차단
|
|
123
|
+
mk "$TESTS | .policy={category:\"major\",auto_approve:{\"3_delivery.commit\":false}} | .stages.\"3_delivery\".substages.\"commit\".approved_by_user=true | .stages.\"3_delivery\".substages.\"commit\".verification_pending=true"
|
|
124
|
+
expect "HITL opt-in + pending 잔류 → 차단" block stage6-commit-verify.sh
|
|
125
|
+
|
|
126
|
+
# legacy(no policy) → 휴먼 게이트 없이 통과 (backward-compat)
|
|
127
|
+
rm -f "$REPORT"
|
|
128
|
+
mk "$TESTS"
|
|
129
|
+
expect "구형 state → 휴먼 게이트 없이 통과" pass stage6-commit-verify.sh
|
|
130
|
+
|
|
131
|
+
echo ""
|
|
132
|
+
echo "── stage8-review-verify (7→8) ──"
|
|
133
|
+
BV='.stages."1_planning".substages."jira".done=true | .stages."1_planning".substages."requirements".done=true | .stages."1_planning".substages."scope".done=true | .stages."2_implementation".substages."dev".done=true | .stages."2_implementation".substages."test".unit="pass" | .stages."3_delivery".substages."commit".done=true | .stages."3_delivery".substages."pr".draft_url="http://pr/1" | .stages."3_delivery".substages."pr".body_validation={no_orphan_scenarios:true,template_match:true,section_content_match:true} | .stages."3_delivery".substages."pr".reviewer_added=true | .stages."3_delivery".substages."review".comments=1 | .stages."3_delivery".substages."review".all_comments_inline=true'
|
|
134
|
+
mk "$BV | .policy={category:\"minor\",auto_approve:{\"3_delivery.pr\":true}}"
|
|
135
|
+
expect "minor auto-approve → 통과" pass stage8-review-verify.sh
|
|
136
|
+
mk "$BV | .stages.\"3_delivery\".substages.\"pr\".approved_by_user=false"
|
|
137
|
+
expect "구형 state 미승인 → 차단" block stage8-review-verify.sh
|
|
138
|
+
mk "$BV | .stages.\"3_delivery\".substages.\"pr\".approved_by_user=true | .stages.\"3_delivery\".substages.\"pr\".verification_pending=false"
|
|
139
|
+
expect "구형 state 승인 → 통과" pass stage8-review-verify.sh
|
|
140
|
+
mk '.stages."1_planning".substages."jira".done=true | .stages."1_planning".substages."requirements".done=true | .stages."1_planning".substages."scope".done=true | .stages."2_implementation".substages."dev".done=true | .stages."2_implementation".substages."test".unit="pass" | .stages."3_delivery".substages."commit".done=true | .stages."3_delivery".substages."pr".draft_url="http://pr/1" | .stages."3_delivery".substages."pr".body_validation={no_orphan_scenarios:false,template_match:true,section_content_match:true} | .stages."3_delivery".substages."pr".reviewer_added=true | .stages."3_delivery".substages."review".comments=1 | .stages."3_delivery".substages."review".all_comments_inline=true | .policy={category:"minor",auto_approve:{"3_delivery.pr":true}}'
|
|
141
|
+
expect "body_validation false → 차단 (auto와 무관)" block stage8-review-verify.sh
|
|
142
|
+
|
|
143
|
+
BSS='.stages."1_planning".substages."jira".done=true | .stages."1_planning".substages."requirements".done=true | .stages."1_planning".substages."scope".done=true | .stages."2_implementation".substages."dev".done=true | .stages."2_implementation".substages."test".unit="pass" | .stages."3_delivery".substages."commit".done=true | .stages."3_delivery".substages."pr".draft_url="http://pr/1" | .stages."3_delivery".substages."pr".body_validation={no_orphan_scenarios:true,template_match:true,section_content_match:true} | .stages."3_delivery".substages."pr".reviewer_self_skipped=true | .stages."3_delivery".substages."review".comments=1 | .stages."3_delivery".substages."review".all_comments_inline=true'
|
|
144
|
+
mk "$BSS | .policy={category:\"minor\",auto_approve:{\"3_delivery.pr\":true}}"
|
|
145
|
+
expect "reviewer_self_skipped=true → reviewer 없어도 통과" pass stage8-review-verify.sh
|
|
146
|
+
mk '.stages."1_planning".substages."jira".done=true | .stages."1_planning".substages."requirements".done=true | .stages."1_planning".substages."scope".done=true | .stages."2_implementation".substages."dev".done=true | .stages."2_implementation".substages."test".unit="pass" | .stages."3_delivery".substages."commit".done=true | .stages."3_delivery".substages."pr".draft_url="http://pr/1" | .stages."3_delivery".substages."pr".body_validation={no_orphan_scenarios:true,template_match:true,section_content_match:true} | .stages."3_delivery".substages."review".comments=1 | .stages."3_delivery".substages."review".all_comments_inline=true | .policy={category:"minor",auto_approve:{"3_delivery.pr":true}}'
|
|
147
|
+
expect "reviewer_added·reviewer_self_skipped 모두 없음 → 차단" block stage8-review-verify.sh
|
|
148
|
+
|
|
149
|
+
echo ""
|
|
150
|
+
echo "[gate-policy-test] $pass passed, $fail failed"
|
|
151
|
+
echo ""
|
|
152
|
+
[ "$fail" -eq 0 ]
|