Template
Apply answers to questions-v1.md (Q1–Q5):
- Q4: Remove crush.json and hooks/ entirely. All enforcement is now portable
via git hooks (pre-commit/pre-push) + check-rules.sh + AGENTS.md prose.
Works under Crush, OpenWebUI, Hermes, or any agent framework.
- Q5: Remove docs/JOURNAL.md. Redmine is the system of record for work;
Discourse for docs. JOURNAL.md was a stopgap.
- Q3: Add mandatory Discourse pointer-header check to check-rules.sh. Any
non-exempt tracked .md without a Discourse URL FAILs. All projects, no
exceptions.
- Q2: Reference real CLI container invocation paths
(KNEL-AIMiddleware/{redmine,discourse}-cli/) in AGENTS.md instead of the
missing bin/ shortcuts.
- Q1: Note tea + docker login are preconfigured on TSYS workstations.
Also: make test default is now no-op pass so the template self-validates;
make validate now passes clean on the repo itself (17 PASS / 0 FAIL).
💘 Generated with Crush
Assisted-by: Crush via Crush <crush@charm.land>
66 lines
2.6 KiB
Bash
Executable File
66 lines
2.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# garden.sh — the gardening loop.
|
|
#
|
|
# Reports doc sprawl and files that violate the "Discourse is the system of
|
|
# record for documentation; gitea .md files are stubs" policy. Run via
|
|
# `make garden`. Findings are WARNINGS (advisory); fix them at a natural break.
|
|
#
|
|
# What it checks:
|
|
# 1. Markdown sprawl: count of .md files per directory (top-10 by count).
|
|
# 2. Oversized .md files (default >300 lines) that don't cite a Discourse URL
|
|
# — candidates to migrate to Discourse, leaving a stub.
|
|
# 3. .md files with no Discourse link at all (informational; exempt: the
|
|
# operational files in EXEMPT_FILES).
|
|
set -euo pipefail
|
|
|
|
HERE="$(cd "$(dirname "$0")" && pwd)"
|
|
# shellcheck disable=SC1091
|
|
source "$HERE/lib/common.sh"
|
|
REPO_ROOT="$(repo_root)"
|
|
cd "$REPO_ROOT"
|
|
|
|
SIZE_LIMIT="${GARDEN_MD_LINE_LIMIT:-300}"
|
|
# Operational files that legitimately live next to code, not in Discourse.
|
|
EXEMPT_FILES="${GARDEN_EXEMPT:-AGENTS.md STATUS.md WORKING.md questions-v.*.md PATTERNS.md BASELINE-PROMPT.md README.md}"
|
|
|
|
log_step "Gardening report for $REPO_ROOT"
|
|
|
|
# --- 1. sprawl by directory -------------------------------------------------
|
|
log_info "Markdown file count by directory (top 10):"
|
|
find . -path ./.git -prune -o -name '*.md' -print 2>/dev/null \
|
|
| sed 's|/[^/]*$||' | sort | uniq -c | sort -rn | head -10 | sed 's/^/ /'
|
|
|
|
# --- 2. oversized .md without a Discourse link ------------------------------
|
|
log_info "Oversized .md (>${SIZE_LIMIT} lines) lacking a Discourse URL — migrate candidates:"
|
|
OVERSIZED=0
|
|
while IFS= read -r -d '' f; do
|
|
# skip exempt files (glob match against basename and relative path)
|
|
exempt=false
|
|
base=$(basename "$f")
|
|
rel=${f#./}
|
|
for pat in $EXEMPT_FILES; do
|
|
# shellcheck disable=SC2254 # glob match is intentional
|
|
case "$base" in $pat) exempt=true; break ;; esac
|
|
# shellcheck disable=SC2254
|
|
case "$rel" in $pat) exempt=true; break ;; esac
|
|
done
|
|
[ "$exempt" = true ] && continue
|
|
lines=$(wc -l < "$f" 2>/dev/null || echo 0)
|
|
if [ "$lines" -gt "$SIZE_LIMIT" ]; then
|
|
if ! grep -qiE 'community\.turnsys\.com|discourse' "$f" 2>/dev/null; then
|
|
printf ' %-60s %s lines\n' "$f" "$lines"
|
|
OVERSIZED=$((OVERSIZED + 1))
|
|
fi
|
|
fi
|
|
done < <(find . -path ./.git -prune -o -name '*.md' -print0 2>/dev/null)
|
|
[ "$OVERSIZED" -eq 0 ] && echo " (none)"
|
|
|
|
# --- 3. summary -------------------------------------------------------------
|
|
log_step "Gardening summary"
|
|
echo " Oversized non-Discourse .md files: $OVERSIZED"
|
|
if [ "$OVERSIZED" -eq 0 ]; then
|
|
log_ok "no migration candidates"
|
|
else
|
|
log_warn "$OVERSIZED file(s) to migrate to Discourse"
|
|
fi
|