internal/layer/conformance.go enforced A12 as "no key named standard_version", and so could not see the same pin as a versioned standard: path or as companion_version. It now detects a version of the standard or its companion in any key or value of the declaration (INTENT.md frontmatter, layer.yaml), including a version in a path, and excludes comments and schema_version. It refuses to be applied to pep-stance.yaml, pip-claims.yaml or evidence-classification.yaml, which A12 r2 does not reach (§3). Every run of check_layer_conformance and of the estate survey now prints the standard version it checks against (layer.ValidatedAgainst, kings-guard's pattern) and its scope (§4). The survey applies the same detection to peers' declarations; the receipt is refreshed because the survey's output changed (no peer declaration currently carries a version). Tests fail if a versioned standard: path or a companion_version comes back. flex-auth's own INTENT.md needed no change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 63291@bnt-lap001 Assistant-Session: 8bd77868-ca68-4f49-bb1e-d539ecc0d703
181 lines
6.2 KiB
Go
181 lines
6.2 KiB
Go
//go:build ignore
|
|
|
|
// Command survey_layer_declarations runs the §11 mechanical check across the
|
|
// estate rather than against flex-auth alone.
|
|
//
|
|
// Why this exists: §11 calls the layer declaration mechanically checkable, but
|
|
// every checker in the estate reads only its own file. A check that cannot
|
|
// disagree with anyone has not been run. FLEX-WP-0030 B1 was found by an ad-hoc
|
|
// shell survey, which is the same defect in a different costume — a finding
|
|
// nobody can reproduce is an assertion. This makes it a command.
|
|
//
|
|
// It checks TWO properties: whether each layer: value sits in the §3
|
|
// vocabulary (ASCII case folded, GH-DEC-2026-017 §2), and whether a
|
|
// declaration carries a standard or companion version in any key or value
|
|
// (A12 r2, GH-DEC-2026-020). It reads declarations only — INTENT.md frontmatter
|
|
// and layer.yaml — never stance, claims or classification maps. Every run prints
|
|
// the version it checks against and its scope. It does not apply flex-auth's own declaration
|
|
// rules to any other repository, and it does not grade anyone: §11 is explicit
|
|
// that a layer stated about a repository by another repository is not a
|
|
// declaration.
|
|
//
|
|
// go run tools/survey_layer_declarations.go --root ~ [--json out.json]
|
|
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
"os/user"
|
|
"path/filepath"
|
|
"sort"
|
|
"strings"
|
|
|
|
"github.com/netkingdom/flex-auth/internal/layer"
|
|
)
|
|
|
|
// Security-relevant counterparts from docs/conformance/boundaries-review.md.
|
|
var counterparts = []string{
|
|
"approval-engine", "audit-core", "flex-auth", "gate-house", "key-cape",
|
|
"kings-guard", "maturity-engine", "net-kingdom", "ops-mason", "ops-warden",
|
|
"secrets-engine", "tenant-engine", "user-engine", "zone-engine",
|
|
}
|
|
|
|
func filterRows(rows []layer.SurveyRow, keep []string) []layer.SurveyRow {
|
|
in := map[string]bool{}
|
|
for _, r := range keep {
|
|
in[r] = true
|
|
}
|
|
var out []layer.SurveyRow
|
|
for _, r := range rows {
|
|
if in[r.Repo] {
|
|
out = append(out, r)
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
func main() {
|
|
root := flag.String("root", "", "directory holding the repositories (default: home)")
|
|
jsonOut := flag.String("json", "", "write a receipt to this path")
|
|
catalogOnly := flag.Bool("catalog-only", false, "range over the §4 catalog rows alone, the set §11's obligations bind")
|
|
flag.Parse()
|
|
|
|
dir := *root
|
|
if dir == "" {
|
|
u, err := user.Current()
|
|
if err != nil {
|
|
fail(err)
|
|
}
|
|
dir = u.HomeDir
|
|
}
|
|
|
|
rows, err := layer.SurveyDeclarations(dir, counterparts)
|
|
if err != nil {
|
|
fail(err)
|
|
}
|
|
|
|
// §11 as amended by A11: a run MUST state its scope. A run over §4 and a
|
|
// run over every repository carrying a declaration answer different
|
|
// questions, and a report that does not say which it did cannot be acted
|
|
// on. This survey is estate-wide by construction — it was built to disagree
|
|
// with other repositories' checkers — so it says so and reports
|
|
// non-catalogued repositories as volunteers rather than as findings.
|
|
scope := layer.EstateScope(counterparts)
|
|
if *catalogOnly {
|
|
scope = layer.CatalogScope(counterparts)
|
|
rows = filterRows(rows, scope.Repos)
|
|
}
|
|
|
|
fmt.Print(layer.FormatSurvey(scope, rows))
|
|
|
|
spellings := layer.Spellings(rows)
|
|
undeclared := layer.Undeclared(rows)
|
|
|
|
fmt.Printf("\n%d counterparts surveyed, %d declared, %d undeclared.\n",
|
|
len(rows), len(rows)-len(undeclared), len(undeclared))
|
|
|
|
keys := make([]string, 0, len(spellings))
|
|
for k := range spellings {
|
|
keys = append(keys, k)
|
|
}
|
|
sort.Strings(keys)
|
|
|
|
fmt.Printf("\nSpellings of layer: (%d distinct)\n", len(keys))
|
|
for _, k := range keys {
|
|
fmt.Printf(" %-10s %s\n", k, strings.Join(spellings[k], ", "))
|
|
}
|
|
|
|
if len(undeclared) > 0 {
|
|
fmt.Printf("\nNo machine-readable declaration (§11 B2): %s\n", strings.Join(undeclared, ", "))
|
|
}
|
|
|
|
disagree := layer.SelfDisagreeing(rows)
|
|
if len(disagree) > 0 {
|
|
fmt.Printf("\nRepositories whose two §11 forms disagree (§11 B1): %d\n", len(disagree))
|
|
for _, r := range disagree {
|
|
fmt.Printf(" %-18s INTENT.md=%-8q %s=%q\n", r.Repo, r.Intent.Layer, r.File.Source, r.File.Layer)
|
|
}
|
|
fmt.Println("\nRuled (GH-DEC-2026-017 §1): INTENT.md governs; a layer.yaml is a derived")
|
|
fmt.Println("artifact and MUST agree. The disagreement is still reported, because")
|
|
fmt.Println("precedence says which value is the answer, not that the disagreement")
|
|
fmt.Println("did not happen. Rows marked 'spelling only' name the same layer.")
|
|
}
|
|
|
|
var offVocab []string
|
|
for _, r := range rows {
|
|
for _, f := range []layer.Form{r.Intent, r.File} {
|
|
if f.Found && !f.InVocabulary {
|
|
offVocab = append(offVocab, fmt.Sprintf("%s=%q", f.Source, f.Layer))
|
|
}
|
|
}
|
|
}
|
|
if len(offVocab) > 0 {
|
|
fmt.Printf("\nOutside the closed §3 vocabulary (four tokens, case folded): %s\n", strings.Join(offVocab, ", "))
|
|
}
|
|
|
|
pinned := layer.VersionPinned(rows)
|
|
if len(pinned) > 0 {
|
|
fmt.Printf("\nDeclarations carrying a standard or companion version (A12 r2): %d\n", len(pinned))
|
|
for _, p := range pinned {
|
|
fmt.Printf(" %s\n", p)
|
|
}
|
|
} else {
|
|
fmt.Println("\nNo declaration carries a standard or companion version (A12 r2).")
|
|
}
|
|
|
|
if vol := layer.VolunteerDeclarations(rows); len(vol) > 0 {
|
|
fmt.Printf("\nDeclared voluntarily, outside §4 catalog scope — welcome, and NOT a §11\nnon-conformance: %s\n", strings.Join(vol, ", "))
|
|
}
|
|
|
|
if *jsonOut != "" {
|
|
receipt := map[string]any{
|
|
"derived_at": "run time",
|
|
"validated_against": layer.ValidatedAgainst,
|
|
"version_pinned": pinned,
|
|
"scope": scope,
|
|
"root": dir,
|
|
"rows": rows,
|
|
"spellings": spellings,
|
|
"undeclared": undeclared,
|
|
"off_vocab": offVocab,
|
|
"self_disagreeing": disagree,
|
|
"volunteers": layer.VolunteerDeclarations(rows),
|
|
"checks_only": "the closed four-token §3 vocabulary, ASCII case folded per GH-DEC-2026-017 §2; and A12 r2 (GH-DEC-2026-020): no standard or companion version in any key or value of INTENT.md frontmatter or layer.yaml; stance, claims and classification maps not read; no flex-auth house rules applied to peers",
|
|
}
|
|
b, err := json.MarshalIndent(receipt, "", " ")
|
|
if err != nil {
|
|
fail(err)
|
|
}
|
|
if err := os.WriteFile(filepath.Clean(*jsonOut), append(b, '\n'), 0o644); err != nil {
|
|
fail(err)
|
|
}
|
|
fmt.Printf("\nReceipt: %s\n", *jsonOut)
|
|
}
|
|
}
|
|
|
|
func fail(err error) {
|
|
fmt.Fprintln(os.Stderr, "survey:", err)
|
|
os.Exit(1)
|
|
}
|