114 lines
5.7 KiB
Bash
Executable File
114 lines
5.7 KiB
Bash
Executable File
#!/bin/sh
|
|
set -eu
|
|
|
|
# Validate the reviewed CommandRegistry as an input contract. This check is
|
|
# deliberately independent of Catalog/interface/provenance output policy so a
|
|
# malformed identity source cannot be hidden by a healthy generated snapshot.
|
|
|
|
ROOT="$(CDPATH= cd -- "$(dirname -- "$0")/../.." && pwd)"
|
|
cd "$ROOT"
|
|
. "$ROOT/scripts/policy/search.sh"
|
|
. "$ROOT/scripts/policy/policy-runtime.sh"
|
|
policy_prepare_runtime "$ROOT"
|
|
|
|
if [ -e internal/cli/schema_native_contracts.go ] ||
|
|
[ -e internal/cli/schema_native_contracts_generated.go ] ||
|
|
policy_search_go 'ApplyNativeRuntimeSchemaContracts|nativeRuntimeSchemaContracts|runtimeSchemaIdentityCandidate' internal/cli; then
|
|
printf '%s\n' 'native Schema identity materialization must not be reintroduced' >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Legacy hint maps used to select primary CLI paths and discover helper roots.
|
|
# They are identity/navigation sources, so bringing any of them back would
|
|
# silently reintroduce a second source beside CommandRegistry.
|
|
if policy_search_go '(schemaPrimaryCLIPath|RuntimeSchemaRootHint|RegisterRuntimeSchemaRoot|PrimaryCLIPaths|RegisterSchemaProductVisibility|SchemaProductVisibilityFor|productVisibility)' \
|
|
internal/cli; then
|
|
printf '%s\n' 'legacy Schema hint navigation or visibility sources must not be reintroduced' >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -f internal/cli/schema_command_registry.schema.json ] ||
|
|
! jq -e '
|
|
."$schema" == "./schema_command_registry.schema.json" and
|
|
.version == 1 and
|
|
(.products | type) == "array" and
|
|
(.products | length) > 0
|
|
' internal/cli/schema_command_registry.json >/dev/null; then
|
|
printf '%s\n' 'reviewed CommandRegistry is missing its local JSON Schema contract' >&2
|
|
exit 1
|
|
fi
|
|
|
|
# The registry argument is validation-only and all go:generate outputs must be
|
|
# downstream assets. Reject any directive that targets the reviewed input.
|
|
if ! grep -Eq '^//go:generate .*cmd_schema_agent_metadata .* -registry internal/cli/schema_command_registry\.json ' internal/cli/schema_agent_metadata.go; then
|
|
printf '%s\n' 'go generate must validate the reviewed CommandRegistry explicitly' >&2
|
|
exit 1
|
|
fi
|
|
if policy_search_go '^//go:generate .*-(output|output-dir|audit-output)(=|[[:space:]]+)([^[:space:]]*/)?schema_command_registry\.json([[:space:]]|$)' \
|
|
internal/cli ||
|
|
policy_search_go '^//go:generate .*(>|>>)[[:space:]]*([^[:space:]]*/)?schema_command_registry\.json([[:space:]]|$)' \
|
|
internal/cli; then
|
|
printf '%s\n' 'go generate must never overwrite the reviewed CommandRegistry' >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Embedded Agent/MCP/parameter metadata is intentionally expensive and must be
|
|
# parsed only through its sync.Once accessor. Each raw loader is allowed at
|
|
# exactly two production locations: its declaration and the assignment inside
|
|
# that accessor. Any third reference is an eager initializer or an accessor
|
|
# bypass and fails this static check.
|
|
check_schema_loader_references() {
|
|
loader="$1"
|
|
allowed="$2"
|
|
references="$(policy_search_production_go "${loader}\\(" internal/cli || true)"
|
|
count="$(printf '%s\n' "$references" | awk 'NF { count++ } END { print count + 0 }')"
|
|
if [ "$count" -ne 2 ]; then
|
|
printf 'Schema loader %s has %s production references, want exactly declaration + lazy accessor\n' "$loader" "$count" >&2
|
|
printf '%s\n' "$references" >&2
|
|
exit 1
|
|
fi
|
|
unexpected="$(printf '%s\n' "$references" | grep -Ev "$allowed" || true)"
|
|
if [ -n "$unexpected" ]; then
|
|
printf 'Schema loader %s is called outside its lazy accessor:\n%s\n' "$loader" "$unexpected" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
check_schema_loader_references \
|
|
'loadEmbeddedAgentMetadata' \
|
|
'^internal/cli/schema_agent_metadata\.go:[0-9]+:(func loadEmbeddedAgentMetadata\(\) embeddedAgentMetadata \{|[[:space:]]*runtimeEmbeddedAgentMetadataLazy\.metadata = loadEmbeddedAgentMetadata\(\))$'
|
|
check_schema_loader_references \
|
|
'loadEmbeddedMCPMetadata' \
|
|
'^internal/cli/runtime_schema\.go:[0-9]+:(func loadEmbeddedMCPMetadata\(\) embeddedMCPMetadata \{|[[:space:]]*runtimeEmbeddedMCPMetadataLazy\.metadata = loadEmbeddedMCPMetadata\(\))$'
|
|
check_schema_loader_references \
|
|
'loadSchemaParameterBindings' \
|
|
'^internal/cli/schema_parameter_bindings\.go:[0-9]+:(func loadSchemaParameterBindings\(\) \(schemaParameterBindingSnapshot, error\) \{|[[:space:]]*runtimeSchemaParameterBindingsLazy\.snapshot, runtimeSchemaParameterBindingsLazy\.err = loadSchemaParameterBindings\(\))$'
|
|
|
|
# Catch the common direct eager form statically; the fresh-process tests below
|
|
# additionally catch indirect or multi-line package initializers.
|
|
if policy_search_production_go '^[[:space:]]*var .*=[[:space:]]*(runtimeAgentMetadata|runtimeMCPMetadata|runtimeSchemaParameterBindingData)\(' \
|
|
internal/cli; then
|
|
printf '%s\n' 'Schema metadata accessors must not be called from package-scope variable initializers' >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Root construction may register the schema command, but app production code
|
|
# must never parse or inspect generation metadata. The schema command reads the
|
|
# already embedded Catalog only when it is actually executed.
|
|
if policy_search_production_go '(loadEmbeddedAgentMetadata|loadEmbeddedMCPMetadata|loadSchemaParameterBindings|runtimeAgentMetadata|runtimeMCPMetadata|runtimeSchemaParameterBindingData|EmbeddedSchemaParameterBindings)\(' \
|
|
internal/app; then
|
|
printf '%s\n' 'root/app production code must not access Schema generation metadata loaders or accessors' >&2
|
|
exit 1
|
|
fi
|
|
|
|
go test ./internal/cli \
|
|
-run '^(TestCommandRegistry.*|TestDecodeCommandRegistry.*|TestBuildEffectiveCommandRegistry.*|TestBindEffectiveCommandRegistry.*|TestRuntimeSchemaMetadataLoadsOnlyOnDemand)$' \
|
|
-count=1
|
|
|
|
go test ./internal/app \
|
|
-run '^TestOrdinaryRootCommandsDoNotLoadSchemaMetadata$' \
|
|
-count=1
|
|
|
|
printf 'schema CommandRegistry check: ok (%s reviewed commands)\n' \
|
|
"$(jq '[.products[].tools[]] | length' internal/cli/schema_command_registry.json)"
|