refactor(person): flat data layout, freeform personalities, bounded prose (#233 #251 #255 #256 #257 #258) #260

Merged
coilysiren merged 4 commits from prose/257-258-233-second-person into main 2026-08-09 05:20:55 +00:00
Member

Closes #233. Closes #251. Closes #255. Closes #256. Closes #257. Closes #258.

Five commits, each one issue or one coherent sweep.

67518b7 prose sweep (#257, #233, #258)

Three issues over the same agent-facing strings, so they land as one pass rather than three rewrites of the same sentences.

Second person (#257). The roster skills were already uniform at 204 second-person pronouns and zero first person. The two surfaces that were not are the two an agent reads first: the native adaptation policy, fully third person, and the role-instruction preamble the bundle emits. Both now address the reader.

No assumed human (#258). Agent-compose's own prose never named Kai, so this was the vocabulary rather than the name. The reader is "the human", the word INVARIANT.md and the director charter already use, which covers a steering operator and an external consumer without inventing a distinction the prose then has to maintain. Evaluation prompts keep naming Kai, decided on #258.

Identity-led intro (#233). The Codex introduction prompt was a constant, so every session opened on identical text. The launch path now composes Angie, you are the curious, meticulous, and tenacious Engineer. ahead of it from the resolved seat, personalities, and role.

The adaptation-policy test restated most of that asset's prose as assertions, which is configuration copied into a test. It now asserts what the renderer owns: section structure and slug substitution.

09c9ec0 freeform personalities (#251)

All sixteen carried an identical five-section template of Presence, Attention, Tempo, Voice, and Balance. Nothing in the loader or the hooks required it: the shape was a leftover from the KDL fields of the same names, which the person contract dropped when definitions moved into SKILL.md trees. Role and boundary bodies are continuous prose, and personalities now match. Every sentence is preserved.

43739fd one directory per entity (#255)

data/role-engineer/{role.kdl,SKILL.md,evals.yaml}
data/personality-curious/{personality.kdl,SKILL.md}
data/boundary-suggest-human-comms/{boundary.kdl,SKILL.md}
data/invariant/INVARIANT.md

Ordering moves from filename prefixes to an order property on the entity node, the decision recorded on the issue, so a directory can move without resequencing the roster. The loader strips it before parsing, so the node model never sees a field that exists only to sequence.

One adapter projects the flat tree onto the section layout the parser already consumes. That keeps the on-disk shape and the parser independent and holds the diff to the layout rather than the loader. The embedded personality library collapses into the same tree, since a person package has always been able to own personalities directly. External libraries passed by flag are untouched.

Verified unchanged after the move: role order, boundary order, all sixteen personalities, provider id, and source strings.

9f8730d bounds at both ends (#256)

  • role body - 140 to 400 words, shipped range 178 to 362
  • personality body - 120 to 320 words, shipped range 150 to 270
  • boundary side - 80 to 400 words, shipped range 105 to 228

Ceilings bind every person package, since they protect the context budget of whoever loads it. Floors bind the roster this repo ships, since they are an editorial standard rather than a consumer protection, and an external package with deliberately terse prose is not wrong. Applying floors everywhere broke the contract fixtures and the shipped example profile, which is the loader making the same argument.

Evaluation matrices stay unbounded, as #256 asked.

Validation

go build ./..., go vet ./..., and pre-commit run --all-files are clean. The full go test ./... passes except TestLatestScoredResultsMatchCurrentPacks, which has failed on main since #231 for the digest reason and is owned by #240. No evaluation was run and evaluations/latest is untouched.

Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com

🤖 Generated with Claude Code

Closes #233. Closes #251. Closes #255. Closes #256. Closes #257. Closes #258. Five commits, each one issue or one coherent sweep. ## `67518b7` prose sweep (#257, #233, #258) Three issues over the same agent-facing strings, so they land as one pass rather than three rewrites of the same sentences. **Second person (#257).** The roster skills were already uniform at 204 second-person pronouns and zero first person. The two surfaces that were not are the two an agent reads first: the native adaptation policy, fully third person, and the role-instruction preamble the bundle emits. Both now address the reader. **No assumed human (#258).** Agent-compose's own prose never named Kai, so this was the vocabulary rather than the name. The reader is "the human", the word `INVARIANT.md` and the director charter already use, which covers a steering operator and an external consumer without inventing a distinction the prose then has to maintain. Evaluation prompts keep naming Kai, decided on #258. **Identity-led intro (#233).** The Codex introduction prompt was a constant, so every session opened on identical text. The launch path now composes `Angie, you are the curious, meticulous, and tenacious Engineer.` ahead of it from the resolved seat, personalities, and role. The adaptation-policy test restated most of that asset's prose as assertions, which is configuration copied into a test. It now asserts what the renderer owns: section structure and slug substitution. ## `09c9ec0` freeform personalities (#251) All sixteen carried an identical five-section template of Presence, Attention, Tempo, Voice, and Balance. Nothing in the loader or the hooks required it: the shape was a leftover from the KDL fields of the same names, which the person contract dropped when definitions moved into `SKILL.md` trees. Role and boundary bodies are continuous prose, and personalities now match. Every sentence is preserved. ## `43739fd` one directory per entity (#255) ```text data/role-engineer/{role.kdl,SKILL.md,evals.yaml} data/personality-curious/{personality.kdl,SKILL.md} data/boundary-suggest-human-comms/{boundary.kdl,SKILL.md} data/invariant/INVARIANT.md ``` Ordering moves from filename prefixes to an `order` property on the entity node, the decision recorded on the issue, so a directory can move without resequencing the roster. The loader strips it before parsing, so the node model never sees a field that exists only to sequence. One adapter projects the flat tree onto the section layout the parser already consumes. That keeps the on-disk shape and the parser independent and holds the diff to the layout rather than the loader. The embedded personality library collapses into the same tree, since a person package has always been able to own personalities directly. External libraries passed by flag are untouched. Verified unchanged after the move: role order, boundary order, all sixteen personalities, provider id, and source strings. ## `9f8730d` bounds at both ends (#256) * role body - 140 to 400 words, shipped range 178 to 362 * personality body - 120 to 320 words, shipped range 150 to 270 * boundary side - 80 to 400 words, shipped range 105 to 228 Ceilings bind every person package, since they protect the context budget of whoever loads it. Floors bind the roster this repo ships, since they are an editorial standard rather than a consumer protection, and an external package with deliberately terse prose is not wrong. Applying floors everywhere broke the contract fixtures and the shipped example profile, which is the loader making the same argument. Evaluation matrices stay unbounded, as #256 asked. ## Validation `go build ./...`, `go vet ./...`, and `pre-commit run --all-files` are clean. The full `go test ./...` passes except `TestLatestScoredResultsMatchCurrentPacks`, which has failed on `main` since #231 for the digest reason and is owned by #240. No evaluation was run and `evaluations/latest` is untouched. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Three sweeps over the same agent-facing strings, so they land as one pass
rather than three rewrites of the same sentences.

Second person (#257). The roster skills were already uniform, at 204
second-person pronouns and zero first person. The two surfaces that were
not are the two an agent reads first: the native adaptation policy, which
was fully third person, and the role-instruction preamble the bundle emits.
Both now address the reader.

No assumed human (#258). Agent-compose's own prose never named Kai, so this
is the vocabulary rather than the name. The reader is "the human", the word
the invariant and the director charter already use, which covers a steering
operator and an external consumer without inventing a distinction the prose
then has to maintain. Evaluation prompts keep naming Kai, decided in #258.

Identity-led intro (#233). The Codex introduction prompt was a constant, so
every session opened on identical text. The launch path now composes
"Angie, you are the curious, meticulous, and tenacious Engineer." ahead of
it from the resolved seat, personalities, and role.

The adaptation-policy test restated most of that asset's prose as
assertions, which is configuration copied into a test. It now asserts what
the renderer owns: the section structure and slug substitution.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Kai Siren <coilysiren@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Kai Siren <coilysiren@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
All sixteen personalities carried an identical five-section template of
Presence, Attention, Tempo, Voice, and Balance. Nothing in the loader or
the hooks required it. The shape was a leftover from the KDL fields of the
same names, which the person contract dropped when definitions moved into
SKILL.md trees.

Role and boundary bodies are continuous prose, and personalities now match
them. Every sentence is preserved and no personality gains or loses
doctrine, so the change is the shape rather than the content.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Kai Siren <coilysiren@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Every first-class entity now owns one directory, so a role's fragment,
body, and evaluation matrix sit together instead of being scattered across
roles/, evaluations/, and libraries/definitions/skills/.

    data/role-engineer/{role.kdl,SKILL.md,evals.yaml}
    data/personality-curious/{personality.kdl,SKILL.md}
    data/boundary-suggest-human-comms/{boundary.kdl,SKILL.md}
    data/invariant/INVARIANT.md

Ordering moves from filename prefixes to an `order` property on the entity
node, so a directory can move without resequencing the roster. The loader
strips it before parsing, so the node model never sees a field that exists
only to sequence.

One adapter projects the flat tree onto the section layout the parser
already consumes, which keeps the on-disk shape and the parser independent
and holds the diff to the layout rather than the loader. The embedded
personality library collapses into the same tree, since a person package
has always been able to own personalities directly. External libraries
passed by flag are untouched.

Verified unchanged after the move: role order, boundary order, all sixteen
personalities, provider id, and source strings.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Kai Siren <coilysiren@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Role bodies had a ceiling and nothing else. Personality bodies had neither.
Boundary sides had a ceiling from #254. A ceiling alone lets an entry thin
into a label without anything noticing.

* role body - 140 to 400 words, shipped range 178 to 362
* personality body - 120 to 320 words, shipped range 150 to 270
* boundary side - 80 to 400 words, shipped range 105 to 228

Ceilings bind every person package, since they protect the context budget
of whoever loads it. Floors bind the roster this repo ships, since they are
an editorial standard rather than a consumer protection, and an external
package with deliberately terse prose is not wrong. Applying floors to
external packages would have broken the contract fixtures and the shipped
example profile, which is the loader telling us the same thing.

Evaluation matrices stay unbounded, as the issue asked. They are fixtures
rather than doctrine.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Kai Siren <coilysiren@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
coilyco-flight-deck/agent-compose!260
No description provided.