framework tools/git: issue-list, milestone-create, lane-brief R1/R4 conversions (P1 complete)

- issue-list + milestone-create: usage() default exit 2, value guards,
  missing-title via usage_error.
- lane-brief: getopts replaced with a while/case parser carrying R2
  long-flag aliases (--repo --milestone --label/--labels --login
  --limit) beside the short forms; login-resolution failure reclassified
  from exit 2 to exit 1 (credential class, not an invocation defect).
- Three suites enrolled (population 88); lane-brief pr-linkage suite
  still ALL PASS; green in both trees; mirrored to the brain tree.

With this, every agent-facing wrapper in tools/git carries the R1/R4
usage-error contract (22/22 non-guard wrappers; guards keep their own
contracts).
This commit is contained in:
2026-08-28 18:10:27 -05:00
parent bb23cb6feb
commit c8b4af59c3
7 changed files with 418 additions and 16 deletions
@@ -36,33 +36,46 @@ Examples:
$(basename "$0") -m "0.2.0" # Issues in milestone 0.2.0
$(basename "$0") --repo ddk/ai-bma # List issues from anywhere
EOF
exit "${1:-1}"
exit "${1:-2}"
}
# Parse arguments
# Usage-error contract (R4, 2026-08-28): usage errors print to STDERR and exit 2,
# distinct from provider, credential, and verification failures (exit 1).
usage_error() {
echo "Error: $*" >&2
usage
}
while [[ $# -gt 0 ]]; do
case $1 in
-s|--state)
[[ $# -ge 2 ]] || usage_error "option $1 requires a value"
STATE="$2"
shift 2
;;
-l|--label)
[[ $# -ge 2 ]] || usage_error "option $1 requires a value"
LABEL="$2"
shift 2
;;
-m|--milestone)
[[ $# -ge 2 ]] || usage_error "option $1 requires a value"
MILESTONE="$2"
shift 2
;;
-a|--assignee)
[[ $# -ge 2 ]] || usage_error "option $1 requires a value"
ASSIGNEE="$2"
shift 2
;;
-n|--limit)
[[ $# -ge 2 ]] || usage_error "option $1 requires a value"
LIMIT="$2"
shift 2
;;
-r|--repo)
[[ $# -ge 2 ]] || usage_error "option $1 requires a value"
REPO_OVERRIDE="$2"
shift 2
;;