Skip to content

Commit 6bff6ec

Browse files
feat(validator): recognise s-expression identity/version fields (#26)
## Summary Extend the identity-field and version-field regexes so they recognise s-expression form (\`(name \"...\")\`) alongside the existing TOML form (\`name = \"...\"\`). Same semantics, only syntax differs. ## Why The current regex only matches TOML kv pairs: \`\`\`bash [[ \"\$line\" =~ ^[[:space:]]*(agent[-_]id|name|project)[[:space:]]*= ]] \`\`\` Some valid A2ML dialects in the hyperpolymath estate use Lisp-style s-expressions for the metadata block — e.g. classification registries: \`\`\`a2ml (assail-classifications (metadata (version \"1.1.0\") (project \"boj-server\"))) \`\`\` These flag as \"Missing required identity field\" today even though \`project\` is structurally present. \`boj-server\`'s \`audits/assail-classifications.a2ml\` is the case that surfaced this — its Dogfood Gate has been red on main for 5+ consecutive runs purely on this false-positive. ## Patch Adds two parallel s-expression branches with explanatory comments. Match \`(field \"...\"\` at any indent so the metadata-block-nested form is recognised. ## Test plan - [x] \`bash -n validate-a2ml.sh\` — syntax check passes - [x] Synthetic fixture with \`(metadata (project \"boj-server\"))\` → 0 errors - [x] Actual boj-server \`audits/assail-classifications.a2ml\` → 0 errors (was 1) - [x] Negative control with neither kv nor s-expression identity → still errors as expected - [ ] CI on this PR (action self-test, if present) ## Downstream Once this lands and gets tagged, repos that pin a SHA can bump: - \`hyperpolymath/boj-server/.github/workflows/dogfood-gate.yml\` — pinned to \`59145c7d1039fa3059b3ecacdb50ee23d7505898\`. After this merges, bump to the new SHA to clear the recurring Dogfood Gate failure on main. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent d6ab0cb commit 6bff6ec

1 file changed

Lines changed: 15 additions & 1 deletion

File tree

validate-a2ml.sh

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,27 @@ validate_a2ml() {
129129
line_num=$((line_num + 1))
130130

131131
# Check for identity fields (various A2ML patterns)
132+
# TOML/kv form: `name = "..."`, `project = "..."`, `agent-id = "..."`
132133
if [[ "$line" =~ ^[[:space:]]*(agent[-_]id|name|project)[[:space:]]*= ]]; then
133134
has_identity=true
134135
fi
135-
# Check for version field
136+
# S-expression form: `(name "...")`, `(project "...")`,
137+
# `(agent-id "...")`. Some A2ML dialects (audit registries,
138+
# classification stores) use Lisp-style s-expressions for the
139+
# metadata block instead of TOML. Identity carries the same
140+
# semantics; only the syntax differs. Match at any indent so it
141+
# also picks up entries nested under `(metadata ...)`.
142+
if [[ "$line" =~ ^[[:space:]]*\([[:space:]]*(agent[-_]id|name|project)[[:space:]]+\" ]]; then
143+
has_identity=true
144+
fi
145+
# Check for version field — TOML form
136146
if [[ "$line" =~ ^[[:space:]]*(version|schema_version)[[:space:]]*= ]]; then
137147
has_version=true
138148
fi
149+
# Version field — s-expression form
150+
if [[ "$line" =~ ^[[:space:]]*\([[:space:]]*(version|schema_version)[[:space:]]+\" ]]; then
151+
has_version=true
152+
fi
139153
done < "$file"
140154

141155
# AI manifest files (0-AI-MANIFEST.a2ml, 0.1-AI-MANIFEST.a2ml, etc.)

0 commit comments

Comments
 (0)