fix(substrate): dangling handoffs + atomar manifest fill-out + validator extension
Group F — manifest, capability, role, and assembler cleanup (post-audit 2026-05-02).
Dangling handoff targets stripped:
- validator.toml: removed handoffs to physics-deriver, patent-compliance
- code-implementer.toml: removed physics-deriver handoff
- architect.toml: removed physics-deriver
- ml-implementer.toml: removed physics-deriver, fixed "multi-node multi-node" typo
- ml-researcher.toml: removed physics-deriver, patent-researcher
- researcher.toml: removed patent-researcher
None of those manifest files exist in _manifests/. Comments added explaining
the removal date for future re-authoring.
Validator extension (_assembler):
- src/validator.rs: extended validate() with check_handoff_targets — every
[[handoff]].target must point to existing _manifests/<name>.toml.
Future dangling handoffs blocked at validate time.
- src/validator_tests.rs (new, 133 LOC): unit tests for handoff-target check.
- tests/fixtures/_manifests/: added valid stubs for previously-missing manifests
(architect, critic, security-auditor, validator,
ml-implementer, ml-researcher, infra-implementer)
so existing fixtures pass the new validator gate.
- tests/snapshots/: insta snapshots updated for researcher + code-implementer.
Atomar manifest fill-out (replaced stock copy-paste with domain-specific):
- code-implementer-typescript: Drizzle/Zod/Next.js semantics
- code-implementer-go: mesh networking, embedded servers
- code-implementer-swift: SwiftUI, SPM, macOS menubar
- code-implementer-python: RULE 0.2 exception language
- code-implementer-flutter: Riverpod, Clean Architecture
- infra-implementer-cicd/iac/container/secrets: tool-specific bans + scopes
- researcher-web/code: output_extra_fields fixed (was code-implementer copy-paste
"Largest file LOC", "Tests pass count" — now sources cited /
evidence grade / gaps section)
Capability schema completeness:
- policy/no-git-ops + quality/cargo-check-green: added stage = "runtime"
- 8 capabilities: added explicit parents = [] (was missing/inconsistent)
Role schema:
- _roles/auditor.toml + merger.toml: added [taxonomy] + [lineage] (was missing)
- _roles/explorer.toml: added comment that "Explore" is the canonical Claude Code
subagent type (case-sensitive)
Reference path cleanup (manifest references):
- critic.toml: ~/.claude/skills/architecture-rules/... -> path:user-skills/...
- researcher.toml: stripped ~/.claude/agents/validator.md (machine-local)
Misc:
- frontend-validator.toml: renumbered duplicate step 6 -> step 7
kei-registry test fixture suppression:
- tests/fixtures/{atom-sample,fake-kit,mini-kit}/.kei-registry-ignore (3 new files)
- DNA-INDEX.md was inflating atom count by ~10% from test fixture rows; ignore-file
hooks ready, kei-registry walker implementation is a follow-up.
Tests: 59 passed; 0 failed; 1 ignored (pre-existing #[ignore]). cargo check clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
bf64839143
commit
57d37004ef
48 changed files with 670 additions and 203 deletions
|
|
@ -4,7 +4,7 @@
|
|||
//! Detailed sub-checks live in their own cubes:
|
||||
//! - `placeholders::check` — {{PLACEHOLDER}} substitution guard
|
||||
//! - `schemas_export::load` — dynamic artifact-schema whitelist loader
|
||||
//! - this file — structural checks + artifact-schema names
|
||||
//! - `validator_tests` — unit tests (split per Constructor Pattern)
|
||||
|
||||
use crate::manifest::Manifest;
|
||||
use crate::placeholders;
|
||||
|
|
@ -21,23 +21,40 @@ pub const OBLIGATORY: &[&str] = &["baseline", "evidence-grading", "memory-protoc
|
|||
pub const KNOWN_ARTIFACT_SCHEMAS: &[&str] = schemas_export::BUILTIN;
|
||||
|
||||
pub fn validate(m: &Manifest, blocks_dir: &Path) -> Result<(), String> {
|
||||
check_obligatory_blocks(m)?;
|
||||
check_blocks_exist(m, blocks_dir)?;
|
||||
check_handoff_targets(m, blocks_dir)?;
|
||||
check_domain_fields(m)?;
|
||||
placeholders::check(m)?;
|
||||
let known = schemas_export::load(blocks_dir);
|
||||
check_artifact_schemas(m, &known)?;
|
||||
check_substrate_role(m, blocks_dir)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn check_obligatory_blocks(m: &Manifest) -> Result<(), String> {
|
||||
for required in OBLIGATORY {
|
||||
if !m.blocks.iter().any(|b| b == required) {
|
||||
return Err(format!("missing obligatory block: {required}"));
|
||||
}
|
||||
}
|
||||
|
||||
if m.handoff.is_empty() {
|
||||
return Err("at least one handoff required".into());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn check_blocks_exist(m: &Manifest, blocks_dir: &Path) -> Result<(), String> {
|
||||
for block in &m.blocks {
|
||||
let path = blocks_dir.join(format!("{block}.md"));
|
||||
if !path.exists() {
|
||||
return Err(format!("block '{block}' not found at {}", path.display()));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn check_domain_fields(m: &Manifest) -> Result<(), String> {
|
||||
if m.domain_in.is_empty() {
|
||||
return Err("domain_in must have at least one entry".into());
|
||||
}
|
||||
|
|
@ -47,18 +64,32 @@ pub fn validate(m: &Manifest, blocks_dir: &Path) -> Result<(), String> {
|
|||
if m.role.trim().is_empty() {
|
||||
return Err("role must not be empty".into());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
placeholders::check(m)?;
|
||||
let known = schemas_export::load(blocks_dir);
|
||||
check_artifact_schemas(m, &known)?;
|
||||
check_substrate_role(m, blocks_dir)?;
|
||||
|
||||
/// Verify every `handoff[i].target` resolves to `_manifests/<target>.toml`.
|
||||
/// Prevents dangling references to unauthored manifests from silently
|
||||
/// passing validation. See audit 2026-05-02.
|
||||
pub fn check_handoff_targets(m: &Manifest, blocks_dir: &Path) -> Result<(), String> {
|
||||
let manifests_dir = blocks_dir
|
||||
.parent()
|
||||
.ok_or_else(|| "blocks_dir has no parent (can't locate _manifests/)".to_string())?
|
||||
.join("_manifests");
|
||||
for (i, h) in m.handoff.iter().enumerate() {
|
||||
let target_path = manifests_dir.join(format!("{}.toml", h.target));
|
||||
if !target_path.exists() {
|
||||
return Err(format!(
|
||||
"handoff[{i}].target '{}' has no manifest at {}",
|
||||
h.target,
|
||||
target_path.display()
|
||||
));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// If a manifest declares `substrate_role`, verify the role file exists
|
||||
/// and every capability it references has a `text.md`. Keeping the check
|
||||
/// here (not only at assemble time) turns mistakes into up-front failures.
|
||||
/// and every capability it references has a `text.md`.
|
||||
fn check_substrate_role(m: &Manifest, blocks_dir: &Path) -> Result<(), String> {
|
||||
let Some(role) = &m.substrate_role else { return Ok(()); };
|
||||
let root = blocks_dir
|
||||
|
|
@ -73,7 +104,7 @@ fn check_substrate_role(m: &Manifest, blocks_dir: &Path) -> Result<(), String> {
|
|||
|
||||
/// v0.15: if a manifest references artifact schema names, they must be in the
|
||||
/// known whitelist. Missing fields are allowed (non-breaking extension).
|
||||
fn check_artifact_schemas(m: &Manifest, known: &BTreeSet<String>) -> Result<(), String> {
|
||||
pub fn check_artifact_schemas(m: &Manifest, known: &BTreeSet<String>) -> Result<(), String> {
|
||||
if let Some(name) = &m.produces_artifact {
|
||||
check_known(name, "produces_artifact", known)?;
|
||||
}
|
||||
|
|
@ -99,101 +130,5 @@ fn check_known(name: &str, field: &str, known: &BTreeSet<String>) -> Result<(),
|
|||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::manifest::{Handoff, Manifest};
|
||||
|
||||
fn base() -> Manifest {
|
||||
Manifest {
|
||||
name: "test".into(),
|
||||
description: "d".into(),
|
||||
tools: vec!["Read".into()],
|
||||
model: "opus".into(),
|
||||
role: "r".into(),
|
||||
blocks: vec!["baseline".into(), "evidence-grading".into(), "memory-protocol".into()],
|
||||
domain_in: vec!["x".into()],
|
||||
forbidden_domain: vec!["y".into()],
|
||||
handoff: vec![Handoff {
|
||||
target: "a".into(),
|
||||
trigger: "b".into(),
|
||||
expects_artifact: None,
|
||||
produces_artifact: None,
|
||||
}],
|
||||
output_extra_fields: vec![],
|
||||
memory_project: None,
|
||||
project_claudemd: None,
|
||||
references: None,
|
||||
produces_artifact: None,
|
||||
substrate_role: None,
|
||||
rule_blocks: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
fn builtin_set() -> BTreeSet<String> {
|
||||
schemas_export::BUILTIN.iter().map(|s| (*s).to_string()).collect()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn artifact_schemas_absent_passes() {
|
||||
let m = base();
|
||||
assert!(check_artifact_schemas(&m, &builtin_set()).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn artifact_schemas_known_names_pass() {
|
||||
let mut m = base();
|
||||
m.produces_artifact = Some("spec".into());
|
||||
m.handoff[0].expects_artifact = Some("plan".into());
|
||||
m.handoff[0].produces_artifact = Some("patch".into());
|
||||
assert!(check_artifact_schemas(&m, &builtin_set()).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn artifact_schemas_reject_unknown_produces() {
|
||||
let mut m = base();
|
||||
m.produces_artifact = Some("not-a-schema".into());
|
||||
let err = check_artifact_schemas(&m, &builtin_set()).unwrap_err();
|
||||
assert!(err.contains("not-a-schema"), "err: {err}");
|
||||
assert!(err.contains("produces_artifact"), "err: {err}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn artifact_schemas_reject_unknown_expects_in_handoff() {
|
||||
let mut m = base();
|
||||
m.handoff[0].expects_artifact = Some("zzz".into());
|
||||
let err = check_artifact_schemas(&m, &builtin_set()).unwrap_err();
|
||||
assert!(err.contains("zzz"), "err: {err}");
|
||||
assert!(err.contains("handoff[0].expects_artifact"), "err: {err}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn builtin_schemas_do_not_drift_from_kei_artifact() {
|
||||
// Structural drift test (no runtime dep on kei-artifact): read the
|
||||
// primitive's source and confirm its BUILTIN list matches ours.
|
||||
let primitive = Path::new(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("..")
|
||||
.join("_primitives/_rust/kei-artifact/src/schemas.rs");
|
||||
if !primitive.exists() {
|
||||
eprintln!("skip drift test: primitive not at {}", primitive.display());
|
||||
return;
|
||||
}
|
||||
let src = std::fs::read_to_string(&primitive).unwrap();
|
||||
let mut names: Vec<String> = Vec::new();
|
||||
for line in src.lines() {
|
||||
let t = line.trim();
|
||||
if let Some(rest) = t.strip_prefix("(\"") {
|
||||
if let Some(end) = rest.find("\",") {
|
||||
names.push(rest[..end].to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
let mine: Vec<String> = schemas_export::BUILTIN
|
||||
.iter()
|
||||
.map(|s| (*s).to_string())
|
||||
.collect();
|
||||
assert_eq!(
|
||||
names, mine,
|
||||
"kei-artifact BUILTIN and schemas_export::BUILTIN drifted"
|
||||
);
|
||||
}
|
||||
}
|
||||
#[path = "validator_tests.rs"]
|
||||
mod tests;
|
||||
|
|
|
|||
133
_assembler/src/validator_tests.rs
Normal file
133
_assembler/src/validator_tests.rs
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
//! Unit tests for manifest validator. Split per Constructor Pattern (file <200 LOC).
|
||||
//! Imported by `validator.rs` as `#[cfg(test)] #[path = "validator_tests.rs"] mod tests;`
|
||||
|
||||
use super::{check_artifact_schemas, check_handoff_targets};
|
||||
use crate::manifest::{Handoff, Manifest};
|
||||
use crate::schemas_export;
|
||||
use std::collections::BTreeSet;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
fn base() -> Manifest {
|
||||
Manifest {
|
||||
name: "test".into(),
|
||||
description: "d".into(),
|
||||
tools: vec!["Read".into()],
|
||||
model: "opus".into(),
|
||||
role: "r".into(),
|
||||
blocks: vec![
|
||||
"baseline".into(),
|
||||
"evidence-grading".into(),
|
||||
"memory-protocol".into(),
|
||||
],
|
||||
domain_in: vec!["x".into()],
|
||||
forbidden_domain: vec!["y".into()],
|
||||
handoff: vec![Handoff {
|
||||
target: "a".into(),
|
||||
trigger: "b".into(),
|
||||
expects_artifact: None,
|
||||
produces_artifact: None,
|
||||
}],
|
||||
output_extra_fields: vec![],
|
||||
memory_project: None,
|
||||
project_claudemd: None,
|
||||
references: None,
|
||||
produces_artifact: None,
|
||||
substrate_role: None,
|
||||
rule_blocks: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
fn builtin_set() -> BTreeSet<String> {
|
||||
schemas_export::BUILTIN.iter().map(|s| (*s).to_string()).collect()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn artifact_schemas_absent_passes() {
|
||||
let m = base();
|
||||
assert!(check_artifact_schemas(&m, &builtin_set()).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn artifact_schemas_known_names_pass() {
|
||||
let mut m = base();
|
||||
m.produces_artifact = Some("spec".into());
|
||||
m.handoff[0].expects_artifact = Some("plan".into());
|
||||
m.handoff[0].produces_artifact = Some("patch".into());
|
||||
assert!(check_artifact_schemas(&m, &builtin_set()).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn artifact_schemas_reject_unknown_produces() {
|
||||
let mut m = base();
|
||||
m.produces_artifact = Some("not-a-schema".into());
|
||||
let err = check_artifact_schemas(&m, &builtin_set()).unwrap_err();
|
||||
assert!(err.contains("not-a-schema"), "err: {err}");
|
||||
assert!(err.contains("produces_artifact"), "err: {err}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn artifact_schemas_reject_unknown_expects_in_handoff() {
|
||||
let mut m = base();
|
||||
m.handoff[0].expects_artifact = Some("zzz".into());
|
||||
let err = check_artifact_schemas(&m, &builtin_set()).unwrap_err();
|
||||
assert!(err.contains("zzz"), "err: {err}");
|
||||
assert!(err.contains("handoff[0].expects_artifact"), "err: {err}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn handoff_target_present_passes() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let blocks = tmp.path().join("project/_blocks");
|
||||
let manifests = tmp.path().join("project/_manifests");
|
||||
fs::create_dir_all(&blocks).unwrap();
|
||||
fs::create_dir_all(&manifests).unwrap();
|
||||
fs::write(manifests.join("target-agent.toml"), b"").unwrap();
|
||||
let mut m = base();
|
||||
m.handoff[0].target = "target-agent".into();
|
||||
assert!(check_handoff_targets(&m, &blocks).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn handoff_target_missing_fails() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let blocks = tmp.path().join("project/_blocks");
|
||||
let manifests = tmp.path().join("project/_manifests");
|
||||
fs::create_dir_all(&blocks).unwrap();
|
||||
fs::create_dir_all(&manifests).unwrap();
|
||||
// Do NOT write target-agent.toml — tests that missing file → error.
|
||||
let mut m = base();
|
||||
m.handoff[0].target = "ghost-agent".into();
|
||||
let err = check_handoff_targets(&m, &blocks).unwrap_err();
|
||||
assert!(err.contains("ghost-agent"), "err: {err}");
|
||||
assert!(err.contains("handoff[0].target"), "err: {err}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn builtin_schemas_do_not_drift_from_kei_artifact() {
|
||||
let primitive = Path::new(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("..")
|
||||
.join("_primitives/_rust/kei-artifact/src/schemas.rs");
|
||||
if !primitive.exists() {
|
||||
eprintln!("skip drift test: primitive not at {}", primitive.display());
|
||||
return;
|
||||
}
|
||||
let src = std::fs::read_to_string(&primitive).unwrap();
|
||||
let mut names: Vec<String> = Vec::new();
|
||||
for line in src.lines() {
|
||||
let t = line.trim();
|
||||
if let Some(rest) = t.strip_prefix("(\"") {
|
||||
if let Some(end) = rest.find("\",") {
|
||||
names.push(rest[..end].to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
let mine: Vec<String> = schemas_export::BUILTIN
|
||||
.iter()
|
||||
.map(|s| (*s).to_string())
|
||||
.collect();
|
||||
assert_eq!(
|
||||
names, mine,
|
||||
"kei-artifact BUILTIN and schemas_export::BUILTIN drifted"
|
||||
);
|
||||
}
|
||||
27
_assembler/tests/fixtures/_manifests/architect.toml
vendored
Normal file
27
_assembler/tests/fixtures/_manifests/architect.toml
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# Fixture stub for handoff-target resolution tests. Minimal valid manifest.
|
||||
name = "architect"
|
||||
description = "Architect stub."
|
||||
tools = ["Read", "Glob", "Grep"]
|
||||
model = "opus"
|
||||
substrate_role = "read-only"
|
||||
role = "Stub architect."
|
||||
blocks = ["baseline", "evidence-grading", "memory-protocol"]
|
||||
domain_in = ["architecture review"]
|
||||
forbidden_domain = ["writing code"]
|
||||
|
||||
[[handoff]]
|
||||
target = "code-implementer"
|
||||
trigger = "structural finding implies refactor"
|
||||
|
||||
[taxonomy]
|
||||
kingdom = "manifest"
|
||||
mechanism = "compose"
|
||||
domain = "agent"
|
||||
layer = "agent-substrate"
|
||||
stage = "design-time"
|
||||
stability = "stable"
|
||||
language = "toml"
|
||||
|
||||
[lineage]
|
||||
creator = "ag-orchestrator-human"
|
||||
created = "2026-05-02"
|
||||
|
|
@ -74,9 +74,7 @@ trigger = "task involves ML training / inference / Modal / experiment runners /
|
|||
target = "infra-implementer"
|
||||
trigger = "task involves deploy / CI/CD / secrets / IaC / credentials / public-surface hosting"
|
||||
|
||||
[[handoff]]
|
||||
target = "physics-deriver"
|
||||
trigger = "task requires math derivation / theorem writing / theorem .md derivation"
|
||||
# physics-deriver / patent-compliance / patent-researcher manifests not yet authored — handoffs removed 2026-05-02 per audit
|
||||
|
||||
[[handoff]]
|
||||
target = "critic"
|
||||
|
|
@ -96,11 +94,11 @@ trigger = "structural decision (new module graph, cross-cutting refactor, contra
|
|||
|
||||
[references]
|
||||
extra = [
|
||||
"~/.claude/rules/code-style.md",
|
||||
"~/.claude/rules/git-conventions.md",
|
||||
"~/.claude/rules/dev-workflow.md",
|
||||
"~/.claude/rules/debugging.md",
|
||||
"~/.claude/rules/karpathy-behavioral.md",
|
||||
"path:user-rules/code-style.md",
|
||||
"path:user-rules/git-conventions.md",
|
||||
"path:user-rules/dev-workflow.md",
|
||||
"path:user-rules/debugging.md",
|
||||
"path:user-rules/karpathy-behavioral.md",
|
||||
"MEMORY.md → Architecture Overlay Incident (model_brain.py 227→354 LOC from \"fixes\" — never patch, fix root formulas)",
|
||||
]
|
||||
|
||||
|
|
|
|||
27
_assembler/tests/fixtures/_manifests/critic.toml
vendored
Normal file
27
_assembler/tests/fixtures/_manifests/critic.toml
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# Fixture stub for handoff-target resolution tests. Minimal valid manifest.
|
||||
name = "critic"
|
||||
description = "Code critic stub."
|
||||
tools = ["Read", "Glob", "Grep"]
|
||||
model = "sonnet"
|
||||
substrate_role = "read-only"
|
||||
role = "Stub critic."
|
||||
blocks = ["baseline", "evidence-grading", "memory-protocol"]
|
||||
domain_in = ["anti-pattern detection"]
|
||||
forbidden_domain = ["fixing issues"]
|
||||
|
||||
[[handoff]]
|
||||
target = "code-implementer"
|
||||
trigger = "confirmed findings need code edits"
|
||||
|
||||
[taxonomy]
|
||||
kingdom = "manifest"
|
||||
mechanism = "compose"
|
||||
domain = "agent"
|
||||
layer = "agent-substrate"
|
||||
stage = "design-time"
|
||||
stability = "stable"
|
||||
language = "toml"
|
||||
|
||||
[lineage]
|
||||
creator = "ag-orchestrator-human"
|
||||
created = "2026-05-02"
|
||||
27
_assembler/tests/fixtures/_manifests/infra-implementer.toml
vendored
Normal file
27
_assembler/tests/fixtures/_manifests/infra-implementer.toml
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# Fixture stub for handoff-target resolution tests. Minimal valid manifest.
|
||||
name = "infra-implementer"
|
||||
description = "Infra/deploy stub."
|
||||
tools = ["Read", "Write", "Bash"]
|
||||
model = "sonnet"
|
||||
substrate_role = "edit-local"
|
||||
role = "Stub infra-implementer."
|
||||
blocks = ["baseline", "evidence-grading", "memory-protocol"]
|
||||
domain_in = ["deploy", "CI/CD"]
|
||||
forbidden_domain = ["app code"]
|
||||
|
||||
[[handoff]]
|
||||
target = "code-implementer"
|
||||
trigger = "app code change needed"
|
||||
|
||||
[taxonomy]
|
||||
kingdom = "manifest"
|
||||
mechanism = "compose"
|
||||
domain = "agent"
|
||||
layer = "agent-substrate"
|
||||
stage = "design-time"
|
||||
stability = "stable"
|
||||
language = "toml"
|
||||
|
||||
[lineage]
|
||||
creator = "ag-orchestrator-human"
|
||||
created = "2026-05-02"
|
||||
27
_assembler/tests/fixtures/_manifests/ml-implementer.toml
vendored
Normal file
27
_assembler/tests/fixtures/_manifests/ml-implementer.toml
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# Fixture stub for handoff-target resolution tests. Minimal valid manifest.
|
||||
name = "ml-implementer"
|
||||
description = "ML training stub."
|
||||
tools = ["Read", "Write", "Bash"]
|
||||
model = "opus"
|
||||
substrate_role = "edit-local"
|
||||
role = "Stub ml-implementer."
|
||||
blocks = ["baseline", "evidence-grading", "memory-protocol"]
|
||||
domain_in = ["ML training"]
|
||||
forbidden_domain = ["theory writing"]
|
||||
|
||||
[[handoff]]
|
||||
target = "code-implementer"
|
||||
trigger = "inference path needs Rust"
|
||||
|
||||
[taxonomy]
|
||||
kingdom = "manifest"
|
||||
mechanism = "compose"
|
||||
domain = "agent"
|
||||
layer = "agent-substrate"
|
||||
stage = "design-time"
|
||||
stability = "stable"
|
||||
language = "toml"
|
||||
|
||||
[lineage]
|
||||
creator = "ag-orchestrator-human"
|
||||
created = "2026-05-02"
|
||||
27
_assembler/tests/fixtures/_manifests/ml-researcher.toml
vendored
Normal file
27
_assembler/tests/fixtures/_manifests/ml-researcher.toml
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# Fixture stub for handoff-target resolution tests. Minimal valid manifest.
|
||||
name = "ml-researcher"
|
||||
description = "ML researcher stub."
|
||||
tools = ["Read", "WebFetch", "WebSearch"]
|
||||
model = "opus"
|
||||
substrate_role = "read-only"
|
||||
role = "Stub ml-researcher."
|
||||
blocks = ["baseline", "evidence-grading", "memory-protocol"]
|
||||
domain_in = ["ML literature review"]
|
||||
forbidden_domain = ["running experiments"]
|
||||
|
||||
[[handoff]]
|
||||
target = "ml-implementer"
|
||||
trigger = "hypothesis ready to run"
|
||||
|
||||
[taxonomy]
|
||||
kingdom = "manifest"
|
||||
mechanism = "compose"
|
||||
domain = "agent"
|
||||
layer = "agent-substrate"
|
||||
stage = "design-time"
|
||||
stability = "stable"
|
||||
language = "toml"
|
||||
|
||||
[lineage]
|
||||
creator = "ag-orchestrator-human"
|
||||
created = "2026-05-02"
|
||||
|
|
@ -67,9 +67,7 @@ trigger = "claim needs hard verification (citation sanity, reproduce-in-tests, R
|
|||
target = "ml-researcher"
|
||||
trigger = "question is ML/RL specialized-node (Math-First + tooling-reuse + synthetic-to-real discipline)"
|
||||
|
||||
[[handoff]]
|
||||
target = "patent-researcher"
|
||||
trigger = "question touches patent prior art, FTO, or novelty (IP-aware handling required)"
|
||||
# physics-deriver / patent-compliance / patent-researcher manifests not yet authored — handoffs removed 2026-05-02 per audit
|
||||
|
||||
[[handoff]]
|
||||
target = "architect"
|
||||
|
|
@ -82,9 +80,8 @@ trigger = "findings suggest anti-pattern sweep or Constructor-Pattern violation
|
|||
# References (extra files beyond auto-included baseline/memory/project)
|
||||
[references]
|
||||
extra = [
|
||||
"~/.claude/rules/debugging.md",
|
||||
"~/.claude/rules/no-downgrade-constructive.md",
|
||||
"~/.claude/agents/validator.md",
|
||||
"path:user-rules/debugging.md",
|
||||
"path:user-rules/no-downgrade-constructive.md",
|
||||
]
|
||||
|
||||
[taxonomy]
|
||||
|
|
|
|||
27
_assembler/tests/fixtures/_manifests/security-auditor.toml
vendored
Normal file
27
_assembler/tests/fixtures/_manifests/security-auditor.toml
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# Fixture stub for handoff-target resolution tests. Minimal valid manifest.
|
||||
name = "security-auditor"
|
||||
description = "Security auditor stub."
|
||||
tools = ["Read", "Glob", "Grep"]
|
||||
model = "opus"
|
||||
substrate_role = "read-only"
|
||||
role = "Stub security-auditor."
|
||||
blocks = ["baseline", "evidence-grading", "memory-protocol"]
|
||||
domain_in = ["security review"]
|
||||
forbidden_domain = ["fixing code"]
|
||||
|
||||
[[handoff]]
|
||||
target = "code-implementer"
|
||||
trigger = "confirmed vulnerability needs fix"
|
||||
|
||||
[taxonomy]
|
||||
kingdom = "manifest"
|
||||
mechanism = "compose"
|
||||
domain = "agent"
|
||||
layer = "agent-substrate"
|
||||
stage = "design-time"
|
||||
stability = "stable"
|
||||
language = "toml"
|
||||
|
||||
[lineage]
|
||||
creator = "ag-orchestrator-human"
|
||||
created = "2026-05-02"
|
||||
27
_assembler/tests/fixtures/_manifests/validator.toml
vendored
Normal file
27
_assembler/tests/fixtures/_manifests/validator.toml
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# Fixture stub for handoff-target resolution tests. Minimal valid manifest.
|
||||
name = "validator"
|
||||
description = "Fact-checker stub."
|
||||
tools = ["Read"]
|
||||
model = "sonnet"
|
||||
substrate_role = "read-only"
|
||||
role = "Stub validator."
|
||||
blocks = ["baseline", "evidence-grading", "memory-protocol"]
|
||||
domain_in = ["claim verification"]
|
||||
forbidden_domain = ["fixing issues"]
|
||||
|
||||
[[handoff]]
|
||||
target = "code-implementer"
|
||||
trigger = "FALSE API claim needs fix"
|
||||
|
||||
[taxonomy]
|
||||
kingdom = "manifest"
|
||||
mechanism = "compose"
|
||||
domain = "agent"
|
||||
layer = "agent-substrate"
|
||||
stage = "design-time"
|
||||
stability = "stable"
|
||||
language = "toml"
|
||||
|
||||
[lineage]
|
||||
creator = "ag-orchestrator-human"
|
||||
created = "2026-05-02"
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
source: tests/golden.rs
|
||||
assertion_line: 47
|
||||
expression: out
|
||||
---
|
||||
---
|
||||
|
|
@ -358,7 +359,6 @@ Counter: each FAILED attempt on the SAME problem = +1. Success = reset.
|
|||
**Out (hand off):**
|
||||
- `ml-implementer` — task involves ML training / inference / Modal / experiment runners / Math-First paradigm
|
||||
- `infra-implementer` — task involves deploy / CI/CD / secrets / IaC / credentials / public-surface hosting
|
||||
- `physics-deriver` — task requires math derivation / theorem writing / theorem .md derivation
|
||||
- `critic` — anti-pattern sweep / code smell review on large diff (>500 LOC) or long function chains
|
||||
- `security-auditor` — code touches auth, crypto, network protocol, deserialization, FFI, or any HIGH-risk surface (see debugging.md Security Review)
|
||||
- `validator` — pre-commit citation or RULE 0.4 check on docs written alongside code
|
||||
|
|
@ -368,7 +368,6 @@ Counter: each FAILED attempt on the SAME problem = +1. Success = reset.
|
|||
|
||||
- **ml-implementer** — task involves ML training / inference / Modal / experiment runners / Math-First paradigm
|
||||
- **infra-implementer** — task involves deploy / CI/CD / secrets / IaC / credentials / public-surface hosting
|
||||
- **physics-deriver** — task requires math derivation / theorem writing / theorem .md derivation
|
||||
- **critic** — anti-pattern sweep / code smell review on large diff (>500 LOC) or long function chains
|
||||
- **security-auditor** — code touches auth, crypto, network protocol, deserialization, FFI, or any HIGH-risk surface (see debugging.md Security Review)
|
||||
- **validator** — pre-commit citation or RULE 0.4 check on docs written alongside code
|
||||
|
|
@ -415,9 +414,9 @@ Blockers / next: <list>
|
|||
|
||||
- `~/.claude/CLAUDE.md` — baseline umbrella
|
||||
- `~/.claude/memory/MEMORY.md` — memory index (adjust if your Claude Code user-slug path differs)
|
||||
- `~/.claude/rules/code-style.md`
|
||||
- `~/.claude/rules/git-conventions.md`
|
||||
- `~/.claude/rules/dev-workflow.md`
|
||||
- `~/.claude/rules/debugging.md`
|
||||
- `~/.claude/rules/karpathy-behavioral.md`
|
||||
- `path:user-rules/code-style.md`
|
||||
- `path:user-rules/git-conventions.md`
|
||||
- `path:user-rules/dev-workflow.md`
|
||||
- `path:user-rules/debugging.md`
|
||||
- `path:user-rules/karpathy-behavioral.md`
|
||||
- `MEMORY.md → Architecture Overlay Incident (model_brain.py 227→354 LOC from "fixes" — never patch, fix root formulas)`
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
---
|
||||
source: tests/golden.rs
|
||||
assertion_line: 33
|
||||
expression: out
|
||||
---
|
||||
---
|
||||
|
|
@ -188,7 +189,6 @@ Rules: architectural decision → E1-E2. Financial (compute) → ONLY E1. Data >
|
|||
**Out (hand off):**
|
||||
- `validator` — claim needs hard verification (citation sanity, reproduce-in-tests, RULE 0.4 gate before commit)
|
||||
- `ml-researcher` — question is ML/RL specialized-node (Math-First + tooling-reuse + synthetic-to-real discipline)
|
||||
- `patent-researcher` — question touches patent prior art, FTO, or novelty (IP-aware handling required)
|
||||
- `architect` — question is structural/architectural — dependency graph, pattern inventory, module boundaries
|
||||
- `critic` — findings suggest anti-pattern sweep or Constructor-Pattern violation review
|
||||
|
||||
|
|
@ -196,7 +196,6 @@ Rules: architectural decision → E1-E2. Financial (compute) → ONLY E1. Data >
|
|||
|
||||
- **validator** — claim needs hard verification (citation sanity, reproduce-in-tests, RULE 0.4 gate before commit)
|
||||
- **ml-researcher** — question is ML/RL specialized-node (Math-First + tooling-reuse + synthetic-to-real discipline)
|
||||
- **patent-researcher** — question touches patent prior art, FTO, or novelty (IP-aware handling required)
|
||||
- **architect** — question is structural/architectural — dependency graph, pattern inventory, module boundaries
|
||||
- **critic** — findings suggest anti-pattern sweep or Constructor-Pattern violation review
|
||||
|
||||
|
|
@ -239,6 +238,5 @@ Blockers / next: <list>
|
|||
|
||||
- `~/.claude/CLAUDE.md` — baseline umbrella
|
||||
- `~/.claude/memory/MEMORY.md` — memory index (adjust if your Claude Code user-slug path differs)
|
||||
- `~/.claude/rules/debugging.md`
|
||||
- `~/.claude/rules/no-downgrade-constructive.md`
|
||||
- `~/.claude/agents/validator.md`
|
||||
- `path:user-rules/debugging.md`
|
||||
- `path:user-rules/no-downgrade-constructive.md`
|
||||
|
|
|
|||
|
|
@ -30,5 +30,6 @@ stability = "stable"
|
|||
language = "rust"
|
||||
|
||||
[lineage]
|
||||
parents = []
|
||||
creator = "ag-orchestrator-human"
|
||||
created = "2026-04-23"
|
||||
|
|
|
|||
|
|
@ -30,5 +30,6 @@ stability = "stable"
|
|||
language = "rust"
|
||||
|
||||
[lineage]
|
||||
parents = []
|
||||
creator = "ag-orchestrator-human"
|
||||
created = "2026-04-23"
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ kingdom = "capability"
|
|||
mechanism = "gate"
|
||||
domain = "policy"
|
||||
layer = "agent-substrate"
|
||||
stage = "runtime"
|
||||
stability = "stable"
|
||||
language = "rust"
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ kingdom = "capability"
|
|||
mechanism = "verify"
|
||||
domain = "quality"
|
||||
layer = "agent-substrate"
|
||||
stage = "runtime"
|
||||
stability = "stable"
|
||||
language = "rust"
|
||||
|
||||
|
|
|
|||
|
|
@ -30,5 +30,6 @@ stability = "stable"
|
|||
language = "rust"
|
||||
|
||||
[lineage]
|
||||
parents = []
|
||||
creator = "ag-orchestrator-human"
|
||||
created = "2026-04-23"
|
||||
|
|
|
|||
|
|
@ -30,5 +30,6 @@ stability = "stable"
|
|||
language = "rust"
|
||||
|
||||
[lineage]
|
||||
parents = []
|
||||
creator = "ag-orchestrator-human"
|
||||
created = "2026-04-23"
|
||||
|
|
|
|||
|
|
@ -35,5 +35,6 @@ stability = "stable"
|
|||
language = "rust"
|
||||
|
||||
[lineage]
|
||||
parents = []
|
||||
creator = "ag-orchestrator-human"
|
||||
created = "2026-04-23"
|
||||
|
|
|
|||
|
|
@ -35,5 +35,6 @@ stability = "stable"
|
|||
language = "rust"
|
||||
|
||||
[lineage]
|
||||
parents = []
|
||||
creator = "ag-orchestrator-human"
|
||||
created = "2026-04-23"
|
||||
|
|
|
|||
|
|
@ -35,5 +35,6 @@ stability = "stable"
|
|||
language = "rust"
|
||||
|
||||
[lineage]
|
||||
parents = []
|
||||
creator = "ag-orchestrator-human"
|
||||
created = "2026-04-23"
|
||||
|
|
|
|||
|
|
@ -30,5 +30,6 @@ stability = "stable"
|
|||
language = "rust"
|
||||
|
||||
[lineage]
|
||||
parents = []
|
||||
creator = "ag-orchestrator-human"
|
||||
created = "2026-04-23"
|
||||
|
|
|
|||
|
|
@ -86,9 +86,7 @@ trigger = "system is ML/specialized-node-class and structural review must apply
|
|||
target = "validator"
|
||||
trigger = "architectural claim needs hard reproduction (build graph, import graph, coupling metric)"
|
||||
|
||||
[[handoff]]
|
||||
target = "physics-deriver"
|
||||
trigger = "structural review asks how a new theorem family fits the existing T1-T68 proof graph"
|
||||
# physics-deriver / patent-compliance / patent-researcher manifests not yet authored — handoffs removed 2026-05-02 per audit
|
||||
|
||||
# References (extra files beyond auto-included baseline/memory/project)
|
||||
[references]
|
||||
|
|
|
|||
|
|
@ -21,9 +21,28 @@ blocks = [
|
|||
"rule-double-audit",
|
||||
]
|
||||
|
||||
domain_in = ["task scope (verbatim user prompt)", "target paths / files"]
|
||||
forbidden_domain = ["hardcoded secrets (RULE 0.8)", "cross-language drift (use the matching sibling)"]
|
||||
output_extra_fields = ["Largest file LOC", "Tests pass count"]
|
||||
domain_in = [
|
||||
"Flutter multi-platform apps — iOS, Android, Web, macOS, Windows (RULE 0.2 exception #2 — existing Flutter app)",
|
||||
"Riverpod state management — NotifierProvider, AsyncNotifierProvider, @riverpod codegen",
|
||||
"Clean Architecture + Feature-First directory layout",
|
||||
"freezed value types + json_serializable for data models",
|
||||
"Supabase client integration, REST/Realtime subscriptions",
|
||||
"Constructor Pattern enforcement: file <200 LOC, function <30 LOC",
|
||||
]
|
||||
forbidden_domain = [
|
||||
"Writing Rust / Swift / Python / Go / TypeScript — hand off to matching sibling",
|
||||
"Hardcoded secrets (RULE 0.8) — every token by ENV var name, never inline",
|
||||
"setState in complex state — use Riverpod providers",
|
||||
"Business logic in Widget build() — extract to Notifier / service layer",
|
||||
"Writing tests later — tests land with the change or before it (Test-First)",
|
||||
"Skipping `flutter analyze` + `flutter test` before declaring done",
|
||||
]
|
||||
output_extra_fields = [
|
||||
"Language: Flutter/Dart (RULE 0.2 exception #2 — existing Flutter app)",
|
||||
"Plan-Mode used: <yes | no + trivial-edit exemption reason>",
|
||||
"Constructor Pattern compliance: largest file <N LOC / limit 200>, largest function <M LOC / limit 30>",
|
||||
"Tests: <name> — <pass/fail> — `flutter test`",
|
||||
]
|
||||
|
||||
[[handoff]]
|
||||
target = "validator"
|
||||
|
|
|
|||
|
|
@ -21,9 +21,27 @@ blocks = [
|
|||
"rule-double-audit",
|
||||
]
|
||||
|
||||
domain_in = ["task scope (verbatim user prompt)", "target paths / files"]
|
||||
forbidden_domain = ["hardcoded secrets (RULE 0.8)", "cross-language drift (use the matching sibling)"]
|
||||
output_extra_fields = ["Largest file LOC", "Tests pass count"]
|
||||
domain_in = [
|
||||
"Mesh networking nodes — TCP/UDP listeners, peer discovery, connection pools",
|
||||
"Lightweight CLI tools with cobra or stdlib flag (RULE 0.2 exception #2 — existing Go service)",
|
||||
"Embedded HTTP servers for sidecar services and health endpoints",
|
||||
"Go stdlib-first: prefer net/http, sync, encoding/json over heavy frameworks",
|
||||
"Constructor Pattern enforcement: file <200 LOC, function <30 LOC",
|
||||
]
|
||||
forbidden_domain = [
|
||||
"Writing Rust / Swift / Python / Flutter / TypeScript — hand off to matching sibling",
|
||||
"Hardcoded secrets (RULE 0.8) — every token by ENV var name, never inline",
|
||||
"Starting a new Go project without citing RULE 0.2 exception number",
|
||||
"Global mutable state — pass deps explicitly via constructor injection",
|
||||
"Goroutine leak — every goroutine must have a cancel path",
|
||||
"Writing tests later — tests land with the change or before it (Test-First)",
|
||||
]
|
||||
output_extra_fields = [
|
||||
"Language: Go (RULE 0.2 exception #2 — existing Go service / mesh)",
|
||||
"Plan-Mode used: <yes | no + trivial-edit exemption reason>",
|
||||
"Constructor Pattern compliance: largest file <N LOC / limit 200>, largest function <M LOC / limit 30>",
|
||||
"Tests: <name> — <pass/fail> — `go test ./...`",
|
||||
]
|
||||
|
||||
[[handoff]]
|
||||
target = "validator"
|
||||
|
|
|
|||
|
|
@ -21,9 +21,26 @@ blocks = [
|
|||
"rule-double-audit",
|
||||
]
|
||||
|
||||
domain_in = ["task scope (verbatim user prompt)", "target paths / files"]
|
||||
forbidden_domain = ["hardcoded secrets (RULE 0.8)", "cross-language drift (use the matching sibling)"]
|
||||
output_extra_fields = ["Largest file LOC", "Tests pass count"]
|
||||
domain_in = [
|
||||
"ML training scripts for models >10M params (RULE 0.2 exception #1 — PyTorch/JAX; inference stays Rust)",
|
||||
"Extending existing language-locked Python projects (RULE 0.2 exception #2)",
|
||||
"One-shot scripts <50 lines that will be deleted within 24h (RULE 0.2 exception #5)",
|
||||
"External-binding wrappers where Python-only SDK exists (RULE 0.2 exception #6)",
|
||||
"Constructor Pattern enforcement: file <200 LOC, function <30 LOC",
|
||||
]
|
||||
forbidden_domain = [
|
||||
"Writing Python without stating a RULE 0.2 exception number (1-7) — refuse and delegate to code-implementer-rust",
|
||||
"Starting new long-lived Python services — Rust is default for inference, servers, and tools",
|
||||
"Hardcoded secrets (RULE 0.8) — every token by ENV var name, never inline",
|
||||
"Global mutable state / singleton patterns outside of ML framework idioms",
|
||||
"Writing tests later — tests land with the change or before it (Test-First)",
|
||||
]
|
||||
output_extra_fields = [
|
||||
"Language: Python (RULE 0.2 exception #<N> — <stated reason>)",
|
||||
"Plan-Mode used: <yes | no + trivial-edit exemption reason>",
|
||||
"Constructor Pattern compliance: largest file <N LOC / limit 200>, largest function <M LOC / limit 30>",
|
||||
"Tests: <name> — <pass/fail> — `pytest`",
|
||||
]
|
||||
|
||||
[[handoff]]
|
||||
target = "validator"
|
||||
|
|
|
|||
|
|
@ -21,9 +21,27 @@ blocks = [
|
|||
"rule-double-audit",
|
||||
]
|
||||
|
||||
domain_in = ["task scope (verbatim user prompt)", "target paths / files"]
|
||||
forbidden_domain = ["hardcoded secrets (RULE 0.8)", "cross-language drift (use the matching sibling)"]
|
||||
output_extra_fields = ["Largest file LOC", "Tests pass count"]
|
||||
domain_in = [
|
||||
"macOS menubar apps — NSStatusItem + popover, switch `.regular` → `.accessory` pattern",
|
||||
"SwiftUI views + AppKit interop for macOS (RULE 0.2 exception #3 — platform-native UI)",
|
||||
"iOS apps — SwiftUI lifecycle, NavigationStack, @Observable, SwiftData",
|
||||
"SPM executables with `-Xlinker -sectcreate` info_plist embed + `codesign --force --sign -`",
|
||||
"Avoid MenuBarExtra with SPM executables — use NSStatusItem directly (platform known issue)",
|
||||
"Constructor Pattern enforcement: file <200 LOC, function <30 LOC",
|
||||
]
|
||||
forbidden_domain = [
|
||||
"Writing Rust / Python / Go / Flutter / TypeScript — hand off to matching sibling",
|
||||
"Hardcoded secrets (RULE 0.8) — every token by ENV var name, never inline",
|
||||
"Force-unwrapping optionals without fallback or guard",
|
||||
"MenuBarExtra with SPM executables (broken — use NSStatusItem)",
|
||||
"Writing tests later — tests land with the change or before it (Test-First)",
|
||||
]
|
||||
output_extra_fields = [
|
||||
"Language: Swift (RULE 0.2 exception #3 — platform-native macOS/iOS UI)",
|
||||
"Plan-Mode used: <yes | no + trivial-edit exemption reason>",
|
||||
"Constructor Pattern compliance: largest file <N LOC / limit 200>, largest function <M LOC / limit 30>",
|
||||
"Tests: <name> — <pass/fail> — `swift test`",
|
||||
]
|
||||
|
||||
[[handoff]]
|
||||
target = "validator"
|
||||
|
|
|
|||
|
|
@ -21,9 +21,28 @@ blocks = [
|
|||
"rule-double-audit",
|
||||
]
|
||||
|
||||
domain_in = ["task scope (verbatim user prompt)", "target paths / files"]
|
||||
forbidden_domain = ["hardcoded secrets (RULE 0.8)", "cross-language drift (use the matching sibling)"]
|
||||
output_extra_fields = ["Largest file LOC", "Tests pass count"]
|
||||
domain_in = [
|
||||
"Next.js 16 app-router pages, API routes, server actions",
|
||||
"Node services with Express / Hono — type-safe with Zod schemas",
|
||||
"Browser-DOM TypeScript — event handlers, fetch wrappers, Web APIs",
|
||||
"Drizzle ORM schemas + queries (PostgreSQL / SQLite / MySQL)",
|
||||
"Zod validation schemas for request/response contracts",
|
||||
"Constructor Pattern enforcement: file <200 LOC, function <30 LOC",
|
||||
]
|
||||
forbidden_domain = [
|
||||
"Writing Rust / Swift / Python / Go / Flutter — hand off to matching sibling",
|
||||
"Hardcoded secrets (RULE 0.8) — every token by ENV var name, never inline",
|
||||
"any=true / ts-ignore / @ts-expect-error without filed issue comment",
|
||||
"Raw SQL string-building — use Drizzle query builder or parameterised statements",
|
||||
"Writing tests later — tests land with the change or before it (Test-First)",
|
||||
]
|
||||
output_extra_fields = [
|
||||
"Language: TypeScript (RULE 0.2 exception #4 — browser/DOM)",
|
||||
"Plan-Mode used: <yes | no + trivial-edit exemption reason>",
|
||||
"Constructor Pattern compliance: largest file <N LOC / limit 200>, largest function <M LOC / limit 30>",
|
||||
"Tests: <name> — <pass/fail> — <command to reproduce>",
|
||||
"cargo-check: N/A (TypeScript) | tsc --noEmit: <pass/fail>",
|
||||
]
|
||||
|
||||
[[handoff]]
|
||||
target = "validator"
|
||||
|
|
|
|||
|
|
@ -74,9 +74,7 @@ trigger = "task involves ML training / inference / Modal / experiment runners /
|
|||
target = "infra-implementer"
|
||||
trigger = "task involves deploy / CI/CD / secrets / IaC / credentials / public-surface hosting"
|
||||
|
||||
[[handoff]]
|
||||
target = "physics-deriver"
|
||||
trigger = "task requires math derivation / theorem writing / theorem .md derivation"
|
||||
# physics-deriver / patent-compliance / patent-researcher manifests not yet authored — handoffs removed 2026-05-02 per audit
|
||||
|
||||
[[handoff]]
|
||||
target = "critic"
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ domain_in = [
|
|||
"Performance — N+1 queries, missing indexes, memory leaks, blocking I/O, hot-path allocations",
|
||||
"Tech debt — duplicated logic, inconsistent naming, missing tests, outdated deps",
|
||||
"Constructor-Pattern violations — files >200 LOC, functions >30 LOC, mixed responsibilities",
|
||||
"Cross-ref rules DB: `~/.claude/skills/architecture-rules/references/antipatterns.md`, `duplication.md`, `stack-compat.md`",
|
||||
"Cross-ref rules DB: `path:user-skills/architecture-rules/references/antipatterns.md`, `duplication.md`, `stack-compat.md`",
|
||||
]
|
||||
|
||||
forbidden_domain = [
|
||||
|
|
@ -71,13 +71,14 @@ target = "architect"
|
|||
trigger = "anti-pattern is structural (new family, needs design review)"
|
||||
|
||||
# References (extra files beyond auto-included baseline/memory/project)
|
||||
# ~/.claude/ absolute paths stripped — not portable across installs. See audit 2026-05-02.
|
||||
[references]
|
||||
extra = [
|
||||
"path:user-rules/debugging.md",
|
||||
"path:user-rules/code-style.md",
|
||||
"~/.claude/skills/architecture-rules/references/antipatterns.md",
|
||||
"~/.claude/skills/architecture-rules/references/duplication.md",
|
||||
"~/.claude/skills/architecture-rules/references/stack-compat.md",
|
||||
"path:user-skills/architecture-rules/references/antipatterns.md",
|
||||
"path:user-skills/architecture-rules/references/duplication.md",
|
||||
"path:user-skills/architecture-rules/references/stack-compat.md",
|
||||
]
|
||||
|
||||
[taxonomy]
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ Your steps in order, each emitting a section of the final report:
|
|||
|
||||
6. **A11y quick** — if `package.json` has `a11y-check` script, invoke. Else skip. Severity: WARN.
|
||||
|
||||
6. **Verdict block** — summary table: each check, status (PASS / WARN / FAIL), brief evidence pointer.
|
||||
7. **Verdict block** — summary table: each check, status (PASS / WARN / FAIL), brief evidence pointer.
|
||||
|
||||
You do NOT autofix. You do NOT spawn other agents. You do NOT commit. You report.
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -21,9 +21,27 @@ blocks = [
|
|||
"rule-double-audit",
|
||||
]
|
||||
|
||||
domain_in = ["task scope (verbatim user prompt)", "target paths / files"]
|
||||
forbidden_domain = ["hardcoded secrets (RULE 0.8)", "cross-language drift (use the matching sibling)"]
|
||||
output_extra_fields = ["Largest file LOC", "Tests pass count"]
|
||||
domain_in = [
|
||||
"GitHub Actions workflows — build matrices, caching, artifact upload/download",
|
||||
"GitLab CI pipelines — stages, rules, variables, Docker-in-Docker runners",
|
||||
"Forgejo / Gitea workflows (subset of GitHub Actions syntax)",
|
||||
"Build-and-deploy scripts — cargo build --release, docker build+push, npm run build",
|
||||
"Secret-injection from vault / GitHub Secrets / GitLab CI variables — ENV only, never inline",
|
||||
"Staged deploys — canary, blue/green, rollback triggers",
|
||||
]
|
||||
forbidden_domain = [
|
||||
"IaC (Terraform/Pulumi/CDK) — hand off to infra-implementer-iac",
|
||||
"Dockerfiles or OCI images — hand off to infra-implementer-container",
|
||||
"Secrets management (Vault, sops, age) — hand off to infra-implementer-secrets",
|
||||
"Hardcoded secrets in workflow YAML (RULE 0.8) — use `${{ secrets.NAME }}` / ENV refs",
|
||||
"Skipping build-cache steps — always cache cargo registry + target, node_modules, pip cache",
|
||||
]
|
||||
output_extra_fields = [
|
||||
"CI platform: GitHub Actions | GitLab CI | Forgejo",
|
||||
"Plan-Mode used: <yes | no + trivial-edit exemption reason>",
|
||||
"Jobs defined: <list with trigger events>",
|
||||
"Secrets used: <list of secret names — verify RULE 0.8 compliance>",
|
||||
]
|
||||
|
||||
[[handoff]]
|
||||
target = "validator"
|
||||
|
|
|
|||
|
|
@ -21,9 +21,28 @@ blocks = [
|
|||
"rule-double-audit",
|
||||
]
|
||||
|
||||
domain_in = ["task scope (verbatim user prompt)", "target paths / files"]
|
||||
forbidden_domain = ["hardcoded secrets (RULE 0.8)", "cross-language drift (use the matching sibling)"]
|
||||
output_extra_fields = ["Largest file LOC", "Tests pass count"]
|
||||
domain_in = [
|
||||
"Dockerfiles — multi-stage builds with cargo-chef (Rust), distroless final image",
|
||||
"OCI image labelling — `org.opencontainers.image.*` standard labels",
|
||||
"docker-compose for local dev + integration tests",
|
||||
"Helm chart templates for Kubernetes deployments",
|
||||
"Non-root user (`USER nonroot:nonroot`), layer-pinning with digest locks",
|
||||
"Build-cache optimisation: COPY Cargo.toml first, then src — avoid rebuilding deps on code changes",
|
||||
]
|
||||
forbidden_domain = [
|
||||
"App code changes — hand off to matching code-implementer sibling",
|
||||
"Kubernetes manifests outside Helm chart templates — hand off to infra-implementer-iac",
|
||||
"Hardcoded secrets in Dockerfile / compose (RULE 0.8) — use build-args + secret mounts only",
|
||||
"Running as root in final image",
|
||||
"FROM latest — always pin to a specific digest or version tag",
|
||||
]
|
||||
output_extra_fields = [
|
||||
"Base image: <registry/image:tag@digest>",
|
||||
"Plan-Mode used: <yes | no + trivial-edit exemption reason>",
|
||||
"Stages: <list of stage names + purpose>",
|
||||
"Final image size estimate: <MB>",
|
||||
"Non-root user: <yes | no>",
|
||||
]
|
||||
|
||||
[[handoff]]
|
||||
target = "validator"
|
||||
|
|
|
|||
|
|
@ -21,9 +21,27 @@ blocks = [
|
|||
"rule-double-audit",
|
||||
]
|
||||
|
||||
domain_in = ["task scope (verbatim user prompt)", "target paths / files"]
|
||||
forbidden_domain = ["hardcoded secrets (RULE 0.8)", "cross-language drift (use the matching sibling)"]
|
||||
output_extra_fields = ["Largest file LOC", "Tests pass count"]
|
||||
domain_in = [
|
||||
"Terraform HCL modules — resource-per-file, remote backend (S3/GCS/Terraform Cloud), lock file",
|
||||
"Pulumi (TypeScript or Go) — stack-per-env, explicit outputs, state in Pulumi Cloud or S3",
|
||||
"OpenTofu (Terraform OSS fork) — drop-in compatible HCL",
|
||||
"AWS CDK (TypeScript) — construct libraries, stack separation by lifecycle",
|
||||
"Module-per-resource-type layout: one directory per resource family",
|
||||
"State-management discipline: remote backend required, local state forbidden in production",
|
||||
]
|
||||
forbidden_domain = [
|
||||
"CI/CD yaml pipelines — hand off to infra-implementer-cicd",
|
||||
"Dockerfiles or OCI images — hand off to infra-implementer-container",
|
||||
"Hardcoded secrets in .tf / .ts / pulumi config (RULE 0.8) — use var + SecretManager refs",
|
||||
"Monolithic single-file IaC (>200 LOC) — decompose into modules",
|
||||
"Committing `terraform.tfstate` or `.tfstate.backup` to git — use remote backend only",
|
||||
]
|
||||
output_extra_fields = [
|
||||
"IaC tool: Terraform | Pulumi | OpenTofu | CDK",
|
||||
"Plan-Mode used: <yes | no + trivial-edit exemption reason>",
|
||||
"Resources defined: <list with provider + resource type>",
|
||||
"State backend: <remote backend details>",
|
||||
]
|
||||
|
||||
[[handoff]]
|
||||
target = "validator"
|
||||
|
|
|
|||
|
|
@ -21,9 +21,27 @@ blocks = [
|
|||
"rule-double-audit",
|
||||
]
|
||||
|
||||
domain_in = ["task scope (verbatim user prompt)", "target paths / files"]
|
||||
forbidden_domain = ["hardcoded secrets (RULE 0.8)", "cross-language drift (use the matching sibling)"]
|
||||
output_extra_fields = ["Largest file LOC", "Tests pass count"]
|
||||
domain_in = [
|
||||
"sops encryption — `.sops.yaml` key rules, `sops --encrypt` / `--decrypt` workflow",
|
||||
"age key generation + encryption for file-at-rest secrets",
|
||||
"HashiCorp Vault — dynamic secrets, AppRole auth, KV v2, lease renewal",
|
||||
"Cloudflare Secret / AWS Secrets Manager / GCP Secret Manager integration patterns",
|
||||
"ENV-var injection patterns: `.env` files gitignored, referenced via `$VAR` only (RULE 0.8)",
|
||||
"Rotation playbooks — how to rotate a token without downtime",
|
||||
]
|
||||
forbidden_domain = [
|
||||
"App code changes — hand off to matching code-implementer sibling",
|
||||
"CI/CD pipeline YAML — hand off to infra-implementer-cicd",
|
||||
"Hardcoded secret values anywhere (RULE 0.8 hard ban)",
|
||||
"Committing `.env` files with real values to git",
|
||||
"Storing secrets in IaC state files — use Secrets Manager + data source",
|
||||
]
|
||||
output_extra_fields = [
|
||||
"Secrets tool: sops | age | Vault | CF Secret | AWS SM | GCP SM",
|
||||
"Plan-Mode used: <yes | no + trivial-edit exemption reason>",
|
||||
"Secrets catalogued: <count + names (not values)>",
|
||||
"RULE 0.8 compliance: <all tokens by ENV var name — yes | violations listed>",
|
||||
]
|
||||
|
||||
[[handoff]]
|
||||
target = "validator"
|
||||
|
|
|
|||
|
|
@ -78,9 +78,7 @@ output_extra_fields = [
|
|||
]
|
||||
|
||||
# Handoffs MUST come after all top-level keys (TOML array-of-tables scope rule)
|
||||
[[handoff]]
|
||||
target = "physics-deriver"
|
||||
trigger = "numerical result implies a new theorem / refutation / observable classification (write to `theory/**/*.md`)"
|
||||
# physics-deriver / patent-compliance / patent-researcher manifests not yet authored — handoffs removed 2026-05-02 per audit
|
||||
|
||||
[[handoff]]
|
||||
target = "ml-researcher"
|
||||
|
|
@ -104,7 +102,7 @@ trigger = "anti-pattern sweep on training script (coefficient creep, E1-E11 chec
|
|||
|
||||
[[handoff]]
|
||||
target = "architect"
|
||||
trigger = "multi-node multi-node composition design, experiment matrix layout, benchmark/baseline integration"
|
||||
trigger = "multi-node composition design, experiment matrix layout, benchmark/baseline integration"
|
||||
|
||||
[references]
|
||||
extra = [
|
||||
|
|
@ -114,7 +112,7 @@ extra = [
|
|||
"path:user-rules/observable-classification.md",
|
||||
"path:user-rules/manifold-tangent-sanity.md",
|
||||
"path:user-rules/no-downgrade-constructive.md",
|
||||
"path:user-memory/wrong-paths-specialized-ml.md",
|
||||
"path:user-memory/wrong-paths-specialized-ml.md", # TODO verify path:user-memory exists in assembler resolver
|
||||
"MEMORY.md → Compute Cost Incident (2026-02-26): promised $27, spent $98.78 on Modal. NEVER AGAIN.",
|
||||
"MEMORY.md → Architecture Overlay Incident: model_brain.py 227→354 LOC from audit fixes. No Patching.",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -73,9 +73,7 @@ output_extra_fields = [
|
|||
target = "ml-implementer"
|
||||
trigger = "hypothesis is formulated and experiment must be run (train, benchmark, ablate, Monte Carlo)"
|
||||
|
||||
[[handoff]]
|
||||
target = "physics-deriver"
|
||||
trigger = "literature finding feeds a theorem / derivation in `~/your-project/theory/`"
|
||||
# physics-deriver / patent-compliance / patent-researcher manifests not yet authored — handoffs removed 2026-05-02 per audit
|
||||
|
||||
[[handoff]]
|
||||
target = "validator"
|
||||
|
|
@ -85,10 +83,6 @@ trigger = "citation sanity before commit (RULE 0.4 gate) or reproducibility clai
|
|||
target = "researcher"
|
||||
trigger = "non-ML sub-question surfaces (general library / API / pricing / doc lookup)"
|
||||
|
||||
[[handoff]]
|
||||
target = "patent-researcher"
|
||||
trigger = "ML finding is patent-relevant (prior art, FTO, novelty for a filable claim)"
|
||||
|
||||
[[handoff]]
|
||||
target = "architect"
|
||||
trigger = "question is about ML-system architecture (node graph, data-flow, module boundaries) not algorithm"
|
||||
|
|
@ -101,7 +95,7 @@ extra = [
|
|||
"path:user-rules/observable-classification.md",
|
||||
"path:user-rules/api-cost-guard.md",
|
||||
"path:user-rules/no-downgrade-constructive.md",
|
||||
"path:user-memory/wrong-paths-specialized-ml.md",
|
||||
"path:user-memory/wrong-paths-specialized-ml.md", # TODO verify path:user-memory exists in assembler resolver
|
||||
]
|
||||
|
||||
[taxonomy]
|
||||
|
|
|
|||
|
|
@ -17,9 +17,24 @@ blocks = [
|
|||
"memory-protocol",
|
||||
]
|
||||
|
||||
domain_in = ["task scope (verbatim user prompt)", "target paths / files"]
|
||||
forbidden_domain = ["hardcoded secrets (RULE 0.8)", "cross-language drift (use the matching sibling)"]
|
||||
output_extra_fields = ["Largest file LOC", "Tests pass count"]
|
||||
domain_in = [
|
||||
"Symbol discovery — Grep for function/type/constant definitions across the repo",
|
||||
"Dependency tracing — who imports X, what does X import (caller/callee graph via Grep)",
|
||||
"Ownership mapping — identify the canonical SSoT file for a type or route",
|
||||
"Analogue search — find existing implementations before proposing new code",
|
||||
"Constructor-Pattern audit — identify files >200 LOC or functions >30 LOC",
|
||||
]
|
||||
forbidden_domain = [
|
||||
"Web research — hand off to researcher-web",
|
||||
"Editing or writing code (read-only agent — no Edit / Write)",
|
||||
"Whole-file dumps when Grep + targeted Read suffices",
|
||||
"Fabricating file paths, function names, or line numbers",
|
||||
]
|
||||
output_extra_fields = [
|
||||
"Sources cited (≥2 for load-bearing)",
|
||||
"Evidence grade per claim",
|
||||
"Gaps section present",
|
||||
]
|
||||
|
||||
[[handoff]]
|
||||
target = "validator"
|
||||
|
|
|
|||
|
|
@ -17,9 +17,25 @@ blocks = [
|
|||
"memory-protocol",
|
||||
]
|
||||
|
||||
domain_in = ["task scope (verbatim user prompt)", "target paths / files"]
|
||||
forbidden_domain = ["hardcoded secrets (RULE 0.8)", "cross-language drift (use the matching sibling)"]
|
||||
output_extra_fields = ["Largest file LOC", "Tests pass count"]
|
||||
domain_in = [
|
||||
"Official documentation — vendor docs, RFC, spec, changelog, pricing page",
|
||||
"GitHub repositories — README, CHANGELOG, open issues, PR descriptions",
|
||||
"Academic and technical papers — arXiv, ACM DL, IEEE (cite with [VERIFIED: url] per RULE 0.4)",
|
||||
"Pricing and SLA pages — E1 only (primary source from vendor, not third-party comparison)",
|
||||
"Blog posts and tutorials — max E4; flag recency and single-source limit",
|
||||
]
|
||||
forbidden_domain = [
|
||||
"Local filesystem reads — hand off to researcher-code",
|
||||
"Hardcoded or paraphrased secret values anywhere",
|
||||
"Fabricating URLs, DOIs, authors, or version numbers (RULE 0.4 hard ban)",
|
||||
"Quoting Stack Overflow / Reddit / random blogs above E4",
|
||||
"Pricing claims from anything other than the vendor's own pricing page",
|
||||
]
|
||||
output_extra_fields = [
|
||||
"Sources cited (≥2 for load-bearing)",
|
||||
"Evidence grade per claim",
|
||||
"Gaps section present",
|
||||
]
|
||||
|
||||
[[handoff]]
|
||||
target = "validator"
|
||||
|
|
|
|||
|
|
@ -67,9 +67,7 @@ trigger = "claim needs hard verification (citation sanity, reproduce-in-tests, R
|
|||
target = "ml-researcher"
|
||||
trigger = "question is ML/RL specialized-node (Math-First + tooling-reuse + synthetic-to-real discipline)"
|
||||
|
||||
[[handoff]]
|
||||
target = "patent-researcher"
|
||||
trigger = "question touches patent prior art, FTO, or novelty (IP-aware handling required)"
|
||||
# physics-deriver / patent-compliance / patent-researcher manifests not yet authored — handoffs removed 2026-05-02 per audit
|
||||
|
||||
[[handoff]]
|
||||
target = "architect"
|
||||
|
|
@ -80,11 +78,11 @@ target = "critic"
|
|||
trigger = "findings suggest anti-pattern sweep or Constructor-Pattern violation review"
|
||||
|
||||
# References (extra files beyond auto-included baseline/memory/project)
|
||||
# ~/.claude/agents/validator.md stripped — machine-local file, not portable. See audit 2026-05-02.
|
||||
[references]
|
||||
extra = [
|
||||
"path:user-rules/debugging.md",
|
||||
"path:user-rules/no-downgrade-constructive.md",
|
||||
"~/.claude/agents/validator.md",
|
||||
]
|
||||
|
||||
[taxonomy]
|
||||
|
|
|
|||
|
|
@ -56,19 +56,13 @@ output_extra_fields = [
|
|||
"Overall verdict: ALL VERIFIED | PARTIAL (fix list) | BLOCK (FALSE findings present)",
|
||||
]
|
||||
|
||||
# Handoffs MUST come after all top-level keys (TOML array-of-tables scope rule)
|
||||
[[handoff]]
|
||||
target = "physics-deriver"
|
||||
trigger = "theory doc has FALSE or UNVERIFIED citation — rewrite before commit"
|
||||
# physics-deriver / patent-compliance / patent-researcher manifests not yet authored — handoffs removed 2026-05-02 per audit
|
||||
|
||||
# Handoffs MUST come after all top-level keys (TOML array-of-tables scope rule)
|
||||
[[handoff]]
|
||||
target = "ml-researcher"
|
||||
trigger = "claim needs literature/arXiv deep-search to resolve (returns `[VERIFIED: url]`)"
|
||||
|
||||
[[handoff]]
|
||||
target = "patent-compliance"
|
||||
trigger = "FALSE claim is in patent draft — pre-filing block"
|
||||
|
||||
[[handoff]]
|
||||
target = "code-implementer"
|
||||
trigger = "FALSE API/version claim is in code — needs fix before ship"
|
||||
|
|
|
|||
1
_primitives/_rust/kei-registry/tests/fixtures/atom-sample/.kei-registry-ignore
vendored
Normal file
1
_primitives/_rust/kei-registry/tests/fixtures/atom-sample/.kei-registry-ignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
# DNA-INDEX scanner: skip this directory (test fixture)
|
||||
1
_primitives/_rust/kei-registry/tests/fixtures/fake-kit/.kei-registry-ignore
vendored
Normal file
1
_primitives/_rust/kei-registry/tests/fixtures/fake-kit/.kei-registry-ignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
# DNA-INDEX scanner: skip this directory (test fixture)
|
||||
1
_primitives/_rust/kei-registry/tests/fixtures/mini-kit/.kei-registry-ignore
vendored
Normal file
1
_primitives/_rust/kei-registry/tests/fixtures/mini-kit/.kei-registry-ignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
# DNA-INDEX scanner: skip this directory (test fixture)
|
||||
|
|
@ -26,3 +26,17 @@ language = "toml"
|
|||
|
||||
[pipeline]
|
||||
handoff = ["merger"]
|
||||
|
||||
[taxonomy]
|
||||
kingdom = "role"
|
||||
mechanism = "audit"
|
||||
domain = "agent"
|
||||
layer = "agent-substrate"
|
||||
stage = "runtime"
|
||||
stability = "stable"
|
||||
language = "toml"
|
||||
|
||||
[lineage]
|
||||
parents = []
|
||||
creator = "ag-orchestrator-human"
|
||||
created = "2026-04-23"
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ name = "explorer"
|
|||
display-name = "explorer + cargo-check (read-only analyst with build probe)"
|
||||
description = "Read-only analyst that may run cargo-family commands for build/test introspection. No edits, no git, no non-cargo shell."
|
||||
spawnable = true
|
||||
# claude-subagent-type values are case-sensitive; "Explore" is the Claude Code built-in
|
||||
claude-subagent-type = "Explore"
|
||||
|
||||
[capabilities]
|
||||
|
|
|
|||
|
|
@ -26,3 +26,17 @@ language = "toml"
|
|||
|
||||
[pipeline]
|
||||
handoff = []
|
||||
|
||||
[taxonomy]
|
||||
kingdom = "role"
|
||||
mechanism = "merge"
|
||||
domain = "agent"
|
||||
layer = "agent-substrate"
|
||||
stage = "runtime"
|
||||
stability = "stable"
|
||||
language = "toml"
|
||||
|
||||
[lineage]
|
||||
parents = []
|
||||
creator = "ag-orchestrator-human"
|
||||
created = "2026-04-23"
|
||||
|
|
|
|||
Loading…
Reference in a new issue