Files
Agent-System-Dev/scripts/lint-boundaries.sh
T
weichen 93ac63fb3d Compose immutable dependency sources and preserve branch transitions
Why:
Replace repeated submodule source pointers with consumer-owned language versions and fixed application sources, keeping independent repository edits and existing branches intact.

Evidence:
SELF task receipts contain startup/sync evidence, real Go and npm consumption, Native overlay/unlink, safe transition/ref preservation, credential boundary and historical build regressions. Exact committed full composition and RDM checks follow this checkpoint; formal acceptance and GATE CI remain pending.

Impact:
Add isolated build/test composition, source provenance and safe owner refresh, adapt governance and service build callers, remove replaced index links while retaining original Git metadata, and adopt reusable dependency standards.

Refs:
Documents approved dependency-workspace r1/R1-R15 and U1-U7 implementation plan; feature/dependency-workspace task card.
2026-10-13 17:18:07 +00:00

118 lines
4.2 KiB
Bash
Executable File

#!/usr/bin/env bash
# Public SDK isolation and sibling-library ratchets use the fixed composition map
# when supplied; a manual invocation uses sources prepared by the checkout owner.
set -euo pipefail
root=$(cd "$(dirname "$0")/.." && pwd)
fail=0
source_path() { python3 "$root/scripts/component-source.py" "$1"; }
module_path() {
local mod
mod=$(awk '/^module /{print $2; exit}' "$1/go.mod")
[ -n "$mod" ] || { echo "boundary: source lacks a module identity: $1" >&2; return 1; }
printf '%s\n' "$mod"
}
backend=$(source_path Agent-System-Backend)
intent=$(source_path Agent-Intent)
native=$(source_path Agent-Native)
squad=$(source_path Agent-Squad)
backend_mod=$(module_path "$backend")
intent_mod=$(module_path "$intent")
native_mod=$(module_path "$native")
squad_mod=$(module_path "$squad")
check() {
local path="$1"
if [ -d "$path" ] && rg -n --glob '*.go' --glob '*.ts' --glob '*.tsx' -F \
-e "$backend_mod/internal" -e 'agent-system-backend/internal' "$path" >/dev/null; then
echo "boundary: $path imports backend internal" >&2
rg -n --glob '*.go' --glob '*.ts' --glob '*.tsx' -F \
-e "$backend_mod/internal" -e 'agent-system-backend/internal' "$path" >&2
fail=1
fi
}
sdk="$backend/pkg/extension"
if [ -d "$sdk" ]; then
hits=$(rg -n --glob '*.go' --glob '!link/**' -F -e "$backend_mod/internal" \
-e 'agent-system-backend/internal' "$sdk" | { grep -v '/link/' || true; } || true)
if [ -n "$hits" ]; then
echo "boundary: pkg/extension imports backend internal" >&2
echo "$hits" >&2
fail=1
fi
fi
check "$root/examples"
# Preserve the allowlist's semantic package names when public module prefixes
# change. No baseline is regenerated during dependency migration.
normalize() {
local value="$1" idx
for idx in 0 1 2; do
case "$value" in
"${canonical[$idx]}") printf '%s' "${legacy[$idx]}"; return ;;
"${canonical[$idx]}"/*) printf '%s%s' "${legacy[$idx]}" "${value#"${canonical[$idx]}"}"; return ;;
esac
done
printf '%s' "$value"
}
canonical=("$intent_mod" "$native_mod" "$squad_mod")
legacy=(agent-intent agent-native agent-squad)
siblings=("${canonical[@]}" "${legacy[@]}")
allow="$root/policy/lib-deps-allowlist.txt"
observed=$(mktemp)
recorded=$(mktemp)
imports=$(mktemp)
trap 'rm -f "$observed" "$recorded" "$imports"' EXIT
for dir in "$intent" "$native" "$squad"; do
mod=$(module_path "$dir")
(cd "$root/scripts" && GOWORK=off go run lint-imports.go "$dir") > "$imports"
while read -r importer rest; do
for imp in $rest; do
for sib in "${siblings[@]}"; do
case "$imp" in "$sib"|"$sib"/*) ;; *) continue ;; esac
case "$importer" in "$mod"|"$mod"/*) ;; *) continue ;; esac
if [ "$(normalize "$sib")" != "$(normalize "$mod")" ]; then
printf '%s %s\n' "$(normalize "$importer")" "$(normalize "$imp")"
fi
done
done
done < "$imports"
done | sort -u > "$observed"
grep -v -e '^#' -e '^$' "$allow" | sort -u > "$recorded" || true
new_pairs=$(comm -13 "$recorded" "$observed" || true)
if [ -n "$new_pairs" ]; then
echo "boundary: new sibling-library import pairs" >&2
echo "$new_pairs" >&2
fail=1
fi
stale_pairs=$(comm -23 "$recorded" "$observed" || true)
if [ -n "$stale_pairs" ]; then
echo "warn: sibling-library pairs no longer imported; delete from policy/lib-deps-allowlist.txt" >&2
echo "$stale_pairs" >&2
fi
for dir in "$intent" "$native" "$squad"; do
mod=$(module_path "$dir")
deps_out=$(cd "$dir" && GOWORK=off go list -deps ./...) || fail=1
for sib in "${siblings[@]}"; do
[ "$(normalize "$sib")" = "$(normalize "$mod")" ] && continue
while IFS= read -r dep; do
case "$dep" in
"$sib"|"$sib"/*) echo "boundary: $mod core depends on $sib" >&2; fail=1 ;;
esac
done <<< "$deps_out"
done
done
while IFS= read -r file; do
case "$file" in
"$squad"/adapters/intent/*|"$backend"/internal/intentgate/*|"$backend"/internal/intentsem/*) ;;
*) echo "boundary: $file imports agent-intent" >&2; fail=1 ;;
esac
done < <(rg -l --glob '*.go' --glob '!**/deps/**' -F -e "\"$intent_mod\"" \
-e "\"$intent_mod/" -e '"agent-intent"' -e '"agent-intent/' "$native" "$squad" "$backend" || true)
[ "$fail" -eq 0 ] || exit 1
bash "$root/scripts/lint-architecture.sh"
echo "boundaries ok"