feat(arch): add contracts skeleton and warn-mode arch-check

Give later waves a measurable import/table/path baseline without changing business behavior or occupying the integration slot.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
weichen
2026-09-14 13:00:32 +00:00
co-authored by Cursor
parent 241bfccc1e
commit e9d57ea772
6 changed files with 312 additions and 0 deletions
+151
View File
@@ -0,0 +1,151 @@
#!/usr/bin/env bash
# Architecture boundary check. Wave 0: warn by default, never rewrite code.
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
BOUNDARIES="${ROOT}/.doc/system-design/module-boundaries.yaml"
MODE="warn"
while [[ $# -gt 0 ]]; do
case "$1" in
--mode) MODE="${2:-warn}"; shift 2 ;;
--mode=*) MODE="${1#--mode=}"; shift ;;
*) echo "usage: $0 [--mode warn|block]" >&2; exit 2 ;;
esac
done
if [[ "${MODE}" != "warn" && "${MODE}" != "block" ]]; then
echo "mode must be warn or block" >&2
exit 2
fi
violations=0
warn() {
printf 'WARN %s\n' "$1"
violations=$((violations + 1))
}
lookup_imports() {
local pkg="$1"
awk -v pkg="$pkg" '
$1=="imports:" {sec=1; next}
sec && $1 ~ /^(table_owners|path_owners):/ { exit }
sec && $1 ~ /^[A-Za-z0-9_]+:$/ || sec && $1 ~ /^[A-Za-z0-9_]+:/ {
key=$1; sub(":","",key)
$1=""
gsub(/^[[:space:]]+|[[:space:]]+$/,"",$0)
gsub(/"/,"",$0)
if (key==pkg) { print $0; exit }
next
}
' "${BOUNDARIES}"
}
lookup_owners() {
local section="$1" key="$2"
awk -v secname="$section" -v key="$key" '
$0 ~ "^"secname":" {sec=1; next}
sec && $1 ~ /^(imports|table_owners|path_owners):/ && $1 !~ "^"secname":" { exit }
sec && $1 ~ /^[A-Za-z0-9_./]+:/ {
k=$1; sub(":","",k)
$1=""
gsub(/^[[:space:]]+|[[:space:]]+$/,"",$0)
if (k==key) { print $0; exit }
next
}
' "${BOUNDARIES}"
}
allowed_has() {
local needle="$1"
local list="$2"
[[ -z "${list}" ]] && return 1
IFS=',' read -r -a parts <<< "${list}"
for p in "${parts[@]}"; do
p="${p// /}"
[[ "${p}" == "${needle}" ]] && return 0
done
return 1
}
root_pkg() {
local rel="${1#chat-agent-system/internal/}"
echo "${rel%%/*}"
}
echo "arch-check mode=${MODE}"
echo "boundaries=${BOUNDARIES}"
while IFS= read -r line; do
[[ -z "${line}" ]] && continue
pkg="$(echo "${line}" | awk '{print $1}')"
root="$(root_pkg "${pkg}")"
[[ "${root}" == "workflow" ]] && continue
allow="$(lookup_imports "${root}")"
deps="$(echo "${line}" | awk '{for(i=2;i<=NF;i++) print $i}')"
for dep in ${deps}; do
[[ "${dep}" != chat-agent-system/internal/* ]] && continue
droot="$(root_pkg "${dep}")"
[[ "${droot}" == "${root}" ]] && continue
if ! allowed_has "${droot}" "${allow}"; then
warn "R-import ${root} -> ${droot} not in baseline allowlist"
fi
done
if [[ "${root}" == "contracts" ]]; then
for dep in ${deps}; do
if [[ "${dep}" == chat-agent-system/internal/* && "${dep}" != chat-agent-system/internal/contracts ]]; then
warn "R1 contracts imports ${dep}"
fi
done
fi
done < <(go list -f '{{.ImportPath}} {{join .Imports " "}}' ./internal/...)
declare -A seen_table
while IFS= read -r table; do
owners="$(lookup_owners table_owners "${table}")"
while IFS= read -r file; do
[[ -z "${file}" ]] && continue
rel="${file#${ROOT}/internal/}"
pkg="${rel%%/*}"
key="${table}|${pkg}"
[[ -n "${seen_table[$key]+x}" ]] && continue
seen_table[$key]=1
if ! allowed_has "${pkg}" "${owners}"; then
warn "R5 table ${table} mentioned in ${pkg} (target owner ${owners})"
fi
done < <(rg -l --glob '*.go' --glob '!*_test.go' --fixed-strings "${table}" "${ROOT}/internal" || true)
done <<'TABLES'
document_records
chat_messages
chat_turns
freeform_documents
task_runs
TABLES
declare -A seen_path
while IFS= read -r lit; do
owners="$(lookup_owners path_owners "${lit}")"
while IFS= read -r file; do
[[ -z "${file}" ]] && continue
rel="${file#${ROOT}/internal/}"
pkg="${rel%%/*}"
key="${lit}|${pkg}"
[[ -n "${seen_path[$key]+x}" ]] && continue
seen_path[$key]=1
if ! allowed_has "${pkg}" "${owners}"; then
warn "R6 path ${lit} mentioned in ${pkg} (target owner ${owners})"
fi
done < <(rg -l --glob '*.go' --glob '!*_test.go' --fixed-strings "${lit}" "${ROOT}/internal" || true)
done <<'PATHS'
output.md
data/dev
workspaces/
PATHS
echo "violations=${violations}"
if [[ "${MODE}" == "block" && "${violations}" -gt 0 ]]; then
echo "arch-check block: failing" >&2
exit 1
fi
echo "arch-check ${MODE}: recorded ${violations} baseline findings"
exit 0