# Формат файлов ролей (спека 3.1), одинаковый для общего и проектного слоя. check_role_file(){ # $1 = путь, $2 = ожидаемое имя роли local f="$1" r="$2" h assert_file "$f существует" "$f" || return assert_eq "$f: строка 1" "$(sed -n '1p' "$f" | sed -E 's/^(# Роль: [a-z]+) — .*/\1/')" "# Роль: $r" assert_eq "$f: строка 2" "$(sed -n '2p' "$f")" "Эта роль заменяет предыдущую роль сессии целиком." h=$(grep -E '^## ' "$f" | tr '\n' '|') assert_eq "$f: четыре раздела по порядку" "$h" "## Процесс|## Читать на старте|## Не делать|## Делегировать|" } for r in dev admin analyst qa; do check_role_file "$ROOT/roles/$r.md" "$r"; done assert_grep "dev: чеклист закрытия перенесён" 'openspec archive' "$ROOT/roles/dev.md" assert_grep "dev: архив всегда отдельным PR" 'всегда отдельным PR' "$ROOT/roles/dev.md" assert_grep "dev: не cd при фоновом контроллере" 'cd' "$ROOT/roles/dev.md" assert_grep "dev: bounded обновляет спеку при смене API" 'спека .*обновляется в том же PR' "$ROOT/roles/dev.md" assert_grep "dev: маркировка R-n" 'R-n' "$ROOT/roles/dev.md" assert_grep "admin: Jira вместо Gitea" 'Jira' "$ROOT/roles/admin.md" assert_grep "analyst: код не пишется" 'не пиш' "$ROOT/roles/analyst.md" assert_grep "qa: код не меняется" 'не меня' "$ROOT/roles/qa.md" for r in dev admin analyst qa; do assert_grep "$r: есть строка brief:" '^- brief:' "$ROOT/roles/$r.md"; done