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.
118 lines
4.2 KiB
Bash
Executable File
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"
|