feat(aos-eval)!: name the two abstractions the schema was already using #1196
No reviewers
Labels
No labels
burndown-2026-06
autonomy
async-consult
autonomy
epic
autonomy
headless
autonomy
live-collab
coherence-core
priority
P0
priority
P1
priority
P2
priority
P3
priority
P4
qa-fixture
role/ai
role/creator
role/design
role/director
role/engineer
role/exec
role/human
role/ops
role/qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
coilyco-flight-deck/agentic-os!1196
Loading…
Reference in a new issue
No description provided.
Delete branch "aos/claude/sj87-entity-attribute"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The shared grading layer claimed to be deployment-agnostic and hardcoded one deployment's vocabulary three times.
axis_ofwas the clearest instance, withrole-fitandpersonality(agent-compose's words) sitting in the layer that is supposed to know nothing about it. The same chain repeated inannotateas three header rows and inexportas three fields.Breaking:
Challenge.roleisentity.boundary,against, andtraitcollapse intoattribute.Profile.group_orderisentity_orderandboundary_orderisattribute_order.PairResultfollows. Declaration schema isaos-eval.boundaries.v2, whoserole:key is nowentity:. Consumers pin by tag, so nothing breaks until a pin moves.The abstraction
A challenge tests one entity for one attribute. The entity is what is under test, a composed role in one deployment and a deployed lane in another. The attribute is what is being tested about it, a boundary or a personality in one and a clause in the other.
test_typealready said which kind, and the profile already let a deployment declare its own kinds, so the three concrete fields were one field wearing a deployment's clothes.axis_ofis now derived rather than enumerated, in three lines instead of a chain, and a deployment can declare a test type this layer has never heard of and still get an axis with detail on it.Also here
AGENT_COMPOSE.attribute_orderlisted three boundary slugs that stopped existing inagent-compose@12c7198. Corrected while the field was moving.personalitynow requires its attribute rather than leaving it optional, a tightening the collapse made free.The declaration module keeps the name
boundaries, because it declares the paired kind of attribute specifically, which is what a boundary is. Not every attribute pairs.Validation
63 tests pass.
ruff checkandpre-commit run --all-filespass.closes #1195
The shared layer claimed to be deployment-agnostic and hardcoded one deployment's vocabulary three times. `axis_of` was the clearest instance: if challenge.boundary and challenge.half: return f"{boundary}:{half}" if challenge.against: return f"role-fit:{against}" if challenge.trait: return f"personality:{trait}" return challenge.test_type `role-fit` and `personality` are agent-compose's words, sitting in the layer that is supposed to know nothing about it. sirens-echo declares only a boundary test type, so two of those branches were dead there, and any deployment adding a fourth kind fell through to a bare label with no axis detail. The same chain repeated in `annotate` as three header rows and in `export` as three fields. BREAKING CHANGE: `Challenge.role` is `entity`. `boundary`, `against`, and `trait` collapse into `attribute`. `Profile.group_order` is `entity_order` and `boundary_order` is `attribute_order`. `PairResult.role` and `.boundary` follow. The declaration schema is `aos-eval.boundaries.v2`, whose `role:` key is now `entity:`. Consumers pin by tag, so nothing breaks until a pin moves. ## What the abstraction is A challenge tests one **entity** for one **attribute**. The entity is what is under test, a composed role in one deployment and a deployed lane in another. The attribute is what is being tested about it, a boundary or a personality in one and a clause in the other. `test_type` already said which kind, and the profile already let a deployment declare its own kinds, so the three concrete fields were one field wearing a deployment's clothes. `axis_of` is now derived rather than enumerated, in three lines instead of a chain, and a deployment can declare a test type this layer has never heard of and still get an axis with detail on it. ## Also `AGENT_COMPOSE.attribute_order` listed three boundary slugs that stopped existing in `agent-compose@12c7198`. Corrected to the four current ones while the field was moving. `personality` now requires its attribute rather than leaving it optional, which is a tightening the collapse made free. The declaration module keeps the name `boundaries`, because it declares the paired kind of attribute specifically, which is what a boundary is. Not every attribute pairs. 63 tests pass. `ruff check` and `pre-commit run --all-files` pass. Co-authored-by: Kai Siren <coilysiren@gmail.com> Co-authored-by: Claude <noreply@anthropic.com> Agent-Role: aiTwo things the first commit left half-done, both of them the shared layer still knowing one deployment's vocabulary. BREAKING CHANGE: the `boundaries` command group and module are `attributes`, the declaration schema is `aos-eval.attributes.v1` with an `attributes:` key, and `--roster` takes an entity projection rather than agent-compose's `person.json`. ## The module was named for one kind of attribute I argued the `boundaries` name should stay because it declares the paired kind specifically and not every attribute pairs. That is true and it is not a reason to keep it. The pairing is what `inside` and `outside` already say on every entry, and a module named for the one deployment shape it serves is exactly the leak this change exists to remove. `Boundary` is `Attribute`, and a deployment whose attributes are clauses no longer reads a word that belongs to another. ## The roster read was the bigger miss `entity_header` still did this: spec = roster.get("roles", {}).get(entity) if boundary.get("owner") == entity: ... if spec.get("personalities"): ... Renaming the function and leaving the body was a rename, not an abstraction. `roles`, `boundaries`, and `personalities` are agent-compose's keys, so the layer that must not know them was reading four of them. The roster is now `{entity_order, entities: {name: {display_name, purpose, notes}}}`, where `notes` are lines the deployment already composed. Owns, defers, scoped, and traits are its words, so it renders them and this layer prints them. That drops the function from twenty lines to eight and removes the last place aos-eval could tell you what a personality is. 63 tests pass. `pre-commit run --all-files` passes. Refs #1195 Co-authored-by: Kai Siren <coilysiren@gmail.com> Co-authored-by: Claude <noreply@anthropic.com> Agent-Role: ai