|
| 1 | +# ADR-0007: engine/virtue -- seven sin/virtue axes; pull-and-resist under pressure |
| 2 | + |
| 3 | +**Status:** Proposed |
| 4 | +**Date:** 2026-05-27 |
| 5 | +**Author:** KAI HACKS AI (LLM-with-maintainer collaboration) |
| 6 | +**Supersedes:** -- |
| 7 | +**Superseded by:** -- |
| 8 | + |
| 9 | +## Context |
| 10 | + |
| 11 | +Issue #568 proposes a new engine domain: virtue. Each of the seven |
| 12 | +classical sin/virtue pairs is modelled as a continuous axis. At any |
| 13 | +moment in a scene, a persona sits somewhere on each axis. Where they |
| 14 | +sit at any moment is a choice -- not a fixed trait. Hard priming |
| 15 | +(culture, place, accumulated stress, formation) biases the slide but |
| 16 | +never locks it. |
| 17 | + |
| 18 | +The persona is under tension on every axis at all times -- pulled |
| 19 | +toward both poles simultaneously. The scene determines which pull |
| 20 | +is stronger in this moment. Behaviour is the evidence. The engine |
| 21 | +never explains. |
| 22 | + |
| 23 | +Virtue is the third of three interlocking engine ADRs: |
| 24 | + |
| 25 | +- ADR-0005 (heritage, merged) -- what the persona was *formed into* |
| 26 | +- ADR-0006 (hierarchy, open) -- what the persona *currently holds* |
| 27 | +- ADR-0007 (this ADR) -- what the persona *does under pressure* |
| 28 | + |
| 29 | +The three engines compose conceptually at the persona level. None |
| 30 | +of the three depends on the others at the file level: each engine |
| 31 | +ships on its own base and is invokable in isolation. The |
| 32 | +composition is meaningful (a persona under pressure draws on |
| 33 | +formation and current standing in choosing which pole pulls |
| 34 | +stronger), but the files do not import each other. Virtue names |
| 35 | +its own concepts in its own prose. |
| 36 | + |
| 37 | +## Decision |
| 38 | + |
| 39 | +1. **Add `engine/virtue/` as the tenth domain axis.** Follows |
| 40 | + ADR-0004's engine-anchor pattern. |
| 41 | + |
| 42 | +2. **Anchor flavour: process-anchor.** `process_virtue.md` is the |
| 43 | + axis's entry, IDLE-shaped (Initiated by / Direction / Lever / |
| 44 | + Echo). Virtue *fires*; it does not sit. The room reads which |
| 45 | + pole the persona moved toward, not whether the persona was |
| 46 | + "a virtuous person" or "a vicious person" -- the engine treats |
| 47 | + the firing as the event. |
| 48 | + |
| 49 | +3. **Seven axes, fourteen poles, each pole its own file.** The |
| 50 | + seven classical sin/virtue pairings, each pole as one |
| 51 | + HOLD-shaped position file describing the observable behaviour |
| 52 | + when that pole has just fired. |
| 53 | + |
| 54 | + | Axis | Sin pole | Virtue pole | |
| 55 | + |---|---|---| |
| 56 | + | Pride | `position_pride.md` | `position_humility.md` | |
| 57 | + | Wrath | `position_wrath.md` | `position_patience.md` | |
| 58 | + | Greed | `position_greed.md` | `position_generosity.md` | |
| 59 | + | Gluttony | `position_gluttony.md` | `position_temperance.md` | |
| 60 | + | Envy | `position_envy.md` | `position_gratitude.md` | |
| 61 | + | Lust | `position_lust.md` | `position_chastity.md` | |
| 62 | + | Sloth | `position_sloth.md` | `position_diligence.md` | |
| 63 | + |
| 64 | +4. **Pole position files describe how the persona *moves*, not |
| 65 | + who they *are*.** This is a different framing from the other |
| 66 | + engine position files. Where `position_dominant.md` describes |
| 67 | + what dominance *is* as a standing read on the persona, |
| 68 | + `position_pride.md` describes what the persona *does* when |
| 69 | + pride fires. The position file is the action and speech |
| 70 | + signature of one pole firing in one scene. The same persona |
| 71 | + may produce different pole-firings in different scenes; the |
| 72 | + file describes the firing, not the persona's permanent stance. |
| 73 | + |
| 74 | +5. **Behaviour is the evidence; the engine never explains.** No |
| 75 | + pole-position file names which pole fired in psychological |
| 76 | + terms. The narrator does not say "this is a moment of pride"; |
| 77 | + the narrator shows what pride looks like as it lands. The |
| 78 | + reader infers the firing from the move. This rule is load- |
| 79 | + bearing on the engine's purpose -- the engine models how the |
| 80 | + room reads the firing, and the room never reads a label. |
| 81 | + |
| 82 | +6. **Invocation mode: global.** Virtue is invoked for every |
| 83 | + persona, in every scene where pressure arrives. Per ADR-0004's |
| 84 | + `instructions.md` registry: |
| 85 | + |
| 86 | + ``` |
| 87 | + | virtue | engine/virtue/process_virtue.md | global | every persona | |
| 88 | + ``` |
| 89 | + |
| 90 | +7. **Standalone, like heritage and hierarchy.** This engine does |
| 91 | + not import from the other two. Concepts that the three engines |
| 92 | + share -- pressure, formation, current standing -- are named in |
| 93 | + each engine's own prose. A reader extracting `engine/virtue/` |
| 94 | + alone from a deployment zip has everything they need to invoke |
| 95 | + the engine. |
| 96 | + |
| 97 | +8. **Scholarly backbone:** Aristotle (virtue as the active mean, |
| 98 | + not the resting state), Baumeister (self-regulation failure |
| 99 | + and ego depletion -- why the sin pole pulls automatically when |
| 100 | + resources thin), Haidt (moral positioning as fast intuition |
| 101 | + first, slow reason second -- why behaviour-first matters). |
| 102 | + The Values-In-Action Classification (Seligman/Peterson) is |
| 103 | + deliberately excluded due to trademark constraints; Evagrius |
| 104 | + Ponticus is noted as historical context only. |
| 105 | + |
| 106 | +9. **Sub-engine structure -- three classes of file:** |
| 107 | + |
| 108 | + | Class | Count | Schema | Files | |
| 109 | + |---|---|---|---| |
| 110 | + | Anchor (process) | 1 | IDLE | `process_virtue.md` | |
| 111 | + | Pole positions | 14 | HOLD | one file per pole (7 sin + 7 virtue) | |
| 112 | + | Meta | 2 | per type | `README.md`, `REFERENCES.md` | |
| 113 | + |
| 114 | + Total: 17 files. Larger than heritage (14) or hierarchy (12), |
| 115 | + driven by the seven axes and two poles per axis. |
| 116 | + |
| 117 | +## Architecture |
| 118 | + |
| 119 | +### The anchor |
| 120 | + |
| 121 | +`process_virtue.md` is IDLE-shaped: |
| 122 | + |
| 123 | +- **Initiated by**: pressure arrives in a scene that the persona |
| 124 | + has to respond to. The pressure may be a demand, an absence, a |
| 125 | + threat, a temptation, a comparison, a delay -- whatever the |
| 126 | + scene puts in the persona's way that asks for a move along one |
| 127 | + of the seven axes. |
| 128 | +- **Direction**: along one or more of the seven axes; toward one |
| 129 | + of the two poles per axis. The persona slides toward the sin |
| 130 | + pole when the resources for resisting (attention, energy, |
| 131 | + practice, formation, capital) have thinned; toward the virtue |
| 132 | + pole when they hold. The direction is multi-axis simultaneously: |
| 133 | + one scene fires multiple poles, sometimes in opposite-axis |
| 134 | + directions. |
| 135 | +- **Lever**: the gap between the pull and the practice. The sin |
| 136 | + pole is the default when capacity is depleted; the virtue pole |
| 137 | + is the active practice that costs something to hold. The lever |
| 138 | + is the cost of holding the virtue pole versus the relief of |
| 139 | + letting the sin pole take over. |
| 140 | +- **Echo**: the room sees the persona's behaviour as the shape of |
| 141 | + which pole fired. The narrator does not name the firing; the |
| 142 | + reader infers it. The persona may or may not be aware which |
| 143 | + pole they just moved toward; their next move starts from where |
| 144 | + this one landed. |
| 145 | + |
| 146 | +The anchor enumerates the seven axes and the fourteen poles in |
| 147 | +its body with sibling links, per ADR-0004's down-link convention. |
| 148 | + |
| 149 | +### Pole positions |
| 150 | + |
| 151 | +Each of the fourteen pole-position files is HOLD-shaped, but the |
| 152 | +content describes the *firing of a pole* rather than a held |
| 153 | +position. The schema sections read: |
| 154 | + |
| 155 | +- **Has**: what just activated this pole. The pressure that lands |
| 156 | + and pulls the persona here in this scene. |
| 157 | +- **Orders**: what the pole demands of the persona's behaviour in |
| 158 | + the next beat -- the specific action or speech signature that |
| 159 | + is the room's evidence the pole has fired. |
| 160 | +- **Loses**: what the persona gives up by moving to this pole in |
| 161 | + this scene. (Even the virtue poles cost something; humility |
| 162 | + loses the credit one was owed, patience loses the relief of |
| 163 | + the response.) |
| 164 | +- **Drives**: how the persona handles the pull -- continues into |
| 165 | + the pole, or recoils, or resists, or oscillates. The pole's |
| 166 | + signature in the next beats. |
| 167 | + |
| 168 | +The room reads the pole-firing through the action and the speech, |
| 169 | +not through narrator commentary. Authoring discipline: a pole- |
| 170 | +position file that uses the word "pride" (or whichever sin) in |
| 171 | +its body has likely slipped into explaining; the engine fails |
| 172 | +when the engine names the firing. |
| 173 | + |
| 174 | +### The seven axes in shape |
| 175 | + |
| 176 | +The axes are not symmetric in the cost they impose. Each axis has |
| 177 | +its own texture; the pole-position files honour the difference. |
| 178 | + |
| 179 | +| Axis | What the persona is moving between | |
| 180 | +|---|---| |
| 181 | +| Pride / Humility | The claim of standing the room did not ask for, against the cost of asking for what is needed | |
| 182 | +| Wrath / Patience | The fast discharge of frustration, against the slow holding of the room together until the issue resolves | |
| 183 | +| Greed / Generosity | The take that protects the persona's own line, against the give that protects the others' | |
| 184 | +| Gluttony / Temperance | The reach for more of what soothes, against the stopping at what is enough | |
| 185 | +| Envy / Gratitude | The reading of others' having as the persona's own absence, against the reading of one's own portion as enough | |
| 186 | +| Lust / Chastity | The reach for the body or the position outside the persona's standing, against the holding of the standing the persona is in | |
| 187 | +| Sloth / Diligence | The refusal of the small effort the room needs, against the doing of the next thing required even when the room is not watching | |
| 188 | + |
| 189 | +These descriptions live in `process_virtue.md` and in the README; |
| 190 | +each individual pole file goes further into how its specific |
| 191 | +firing reads in the room. |
| 192 | + |
| 193 | +### Cross-engine composition (no file imports across the triad) |
| 194 | + |
| 195 | +Virtue composes at the persona level with every other engine in |
| 196 | +the codebase, but does not import files from heritage or |
| 197 | +hierarchy: |
| 198 | + |
| 199 | +- **`engine/heritage/`** -- conceptually paired. A persona's |
| 200 | + formation biases which sin pole is most accessible under |
| 201 | + pressure (the family field that rewarded patience produces a |
| 202 | + persona more practiced at it; the field that rewarded |
| 203 | + acquisition produces a persona more familiar with greed). The |
| 204 | + bias lives in the persona's history; this engine does not |
| 205 | + encode it as a rule. Virtue's pole files name the firing |
| 206 | + abstractly; the persona-level composition with heritage |
| 207 | + happens at scene-authoring time. |
| 208 | +- **`engine/hierarchy/`** -- conceptually paired. A persona's |
| 209 | + current standing biases which pole the room will read first. |
| 210 | + The dominant persona's wrath reads as authority; the excluded |
| 211 | + persona's wrath reads as insubordination. The pole fires the |
| 212 | + same; the room reads it differently. Virtue's files do not |
| 213 | + enumerate the reading-shifts; they name the firing. |
| 214 | +- **`engine/stress/`** (existing, non-triad) -- adjacent. |
| 215 | + Baumeister's depletion is why the sin pole pulls automatically |
| 216 | + under stress. The wiring is acknowledged in the README's |
| 217 | + cross-engine section; no file links. |
| 218 | +- **`engine/gender/`** (existing, non-triad) -- adjacent. The |
| 219 | + same pole-firing reads differently by gender position; the |
| 220 | + reading-shift is the room's, not the engine's. |
| 221 | +- **`engine/group/`**, **`engine/org/`**, **`engine/wow/`** |
| 222 | + (existing, non-triad) -- each may host pressures that trigger |
| 223 | + the firing; none has files imported here. |
| 224 | + |
| 225 | +### `instructions.md` registry entry |
| 226 | + |
| 227 | +Per ADR-0004 follow-up #1: |
| 228 | + |
| 229 | +``` |
| 230 | +| virtue | engine/virtue/process_virtue.md | global | every persona | |
| 231 | +``` |
| 232 | + |
| 233 | +Global because every scene has pressure of some shape, and every |
| 234 | +persona slides along at least one axis when pressure arrives. |
| 235 | + |
| 236 | +## Alternatives considered and rejected |
| 237 | + |
| 238 | +- **Position-anchor (`position_virtue.md`).** Considered: anchor |
| 239 | + virtue as the *current moral standing* the persona holds. |
| 240 | + Rejected: virtue is dynamic in this engine's framing -- it |
| 241 | + fires, it does not sit. The IDLE shape matches the firing; the |
| 242 | + HOLD shape would force the engine to model a "current virtue |
| 243 | + standing" that the issue (#568) explicitly excludes. |
| 244 | + |
| 245 | +- **Seven axis files instead of fourteen pole files.** Considered: |
| 246 | + one file per axis, with both poles in subsections. Rejected: |
| 247 | + loses the per-file voice that the engine convention requires. |
| 248 | + A `position_pride_humility.md` would have to carry two voices |
| 249 | + in one document; that contradicts the rule that each file in |
| 250 | + its own voice. Fourteen files is the cost. |
| 251 | + |
| 252 | +- **VIA Classification (Seligman/Peterson) as backbone.** |
| 253 | + Considered briefly. Rejected: trademark constraints in applied |
| 254 | + contexts. The Aristotle + Baumeister + Haidt synthesis covers |
| 255 | + the same ground without IP friction. |
| 256 | + |
| 257 | +- **Enumerating depletion-driven pull as a process file.** |
| 258 | + Considered: a separate `process_depletion.md` that fires when |
| 259 | + the persona's resources thin and the sin pole pulls |
| 260 | + automatically. Rejected: the depletion mechanism is part of the |
| 261 | + anchor's Initiated by + Lever sections. A separate process |
| 262 | + fragments the engine without adding distinction. |
| 263 | + |
| 264 | +- **Coupling virtue files to heritage's piece_*_capital.md or |
| 265 | + hierarchy's position_*.md.** Rejected by the standalone rule. |
| 266 | + Conceptual composition at the persona level is the model; |
| 267 | + file-level imports across the triad are not. |
| 268 | + |
| 269 | +- **A psychological-explanation layer.** Rejected by the |
| 270 | + behaviour-as-evidence rule. The engine ships the firing's |
| 271 | + shape; psychology is the reader's inference. |
| 272 | + |
| 273 | +- **Numbering the sin/virtue pairs by traditional order |
| 274 | + (capital-sins list).** Considered: the historical ordering |
| 275 | + (pride first, sloth last) carries weight. Adopted in the ADR |
| 276 | + table and the README ordering, since the historical order is |
| 277 | + also a reasonable reading order. Not enforced as a runtime |
| 278 | + property -- the engine reads any pole at any moment. |
| 279 | + |
| 280 | +- **Per-culture cultural-bias of which pole pulls first.** |
| 281 | + Considered: e.g. high-MAS cultures bias toward pride-pull; |
| 282 | + high-PDI cultures bias toward humility-pull. Rejected for the |
| 283 | + engine layer: the bias lives in the persona's heritage and the |
| 284 | + scene's culture, not in the virtue engine's files. The engine |
| 285 | + models the firing; the bias is upstream. |
| 286 | + |
| 287 | +## Consequences |
| 288 | + |
| 289 | +**Positive:** |
| 290 | + |
| 291 | +- Cultures gains a model of pressure-response that the existing |
| 292 | + engines do not have. Stress (fight / flight / freeze / fawn) |
| 293 | + models the body's response; virtue models the *moral-emotional* |
| 294 | + response, along seven well-defined axes. |
| 295 | +- The triad is complete. Heritage / hierarchy / virtue covers |
| 296 | + formation, current standing, and response-under-pressure. Each |
| 297 | + ships standalone; the composition at the persona level is the |
| 298 | + reading-power. |
| 299 | +- The behaviour-as-evidence rule generalises a discipline that |
| 300 | + good scene-authoring already practiced informally. The engine |
| 301 | + makes the rule explicit and supports authors in keeping the |
| 302 | + narrator silent about the firing. |
| 303 | +- Cross-engine composition without coupling. Virtue interacts |
| 304 | + with every other engine at the persona level (heritage biases |
| 305 | + which pole pulls; hierarchy biases which read the room |
| 306 | + performs; stress is the depletion mechanism; gender shifts the |
| 307 | + reading) without importing any of their files. The engine |
| 308 | + graph stays loose where it should be loose. |
| 309 | + |
| 310 | +**Negative:** |
| 311 | + |
| 312 | +- Authorial load. Fourteen pole-position files, each in its own |
| 313 | + voice, with the no-explaining discipline. Higher per-file |
| 314 | + authorial care than any preceding engine. The risk of slipping |
| 315 | + into "this is the moment of envy" prose is real and only |
| 316 | + authorial care catches it. |
| 317 | +- The behaviour-as-evidence discipline is unenforceable by |
| 318 | + validator. A pole-position file that names its own pole |
| 319 | + inside its body fails the rule; no test catches that. Review |
| 320 | + is the gate. |
| 321 | +- Seven axes is a strong claim about the dimensionality of |
| 322 | + moral-emotional response. Some sin/virtue pairings are more |
| 323 | + contested than others (lust/chastity has wider cultural |
| 324 | + variance than pride/humility, for example). The engine ships |
| 325 | + the seven; future ADRs may add additional axes or split an |
| 326 | + axis if scene-authoring evidence accumulates. |
| 327 | +- The triad-independence rule means the persona-level |
| 328 | + composition (heritage formation biases virtue's pulls, |
| 329 | + hierarchy standing biases the room's reading) lives in scene- |
| 330 | + authoring practice, not in any engine file. The composition |
| 331 | + must be carried by the authors; the files do not enforce it. |
| 332 | + |
| 333 | +## Open follow-ups |
| 334 | + |
| 335 | +1. **Engine implementation PR.** `culture/engine` branch into |
| 336 | + `culture/release`, the ~17 files described above. Standalone: |
| 337 | + does not block on heritage or hierarchy being on any specific |
| 338 | + branch. The engine implementation PR ships independently. |
| 339 | + |
| 340 | +2. **`instructions.md` registry entry.** Add the virtue row |
| 341 | + alongside heritage's and hierarchy's. Folds into the in- |
| 342 | + progress `instructions.md` work or a tiny follow-up PR. |
| 343 | + |
| 344 | +3. **Per-persona virtue annotation.** Not in scope for the |
| 345 | + engine itself. The 28 existing personas do not declare which |
| 346 | + poles fire most accessibly for them under pressure. A future |
| 347 | + content sweep can backfill if scene-authoring needs it; the |
| 348 | + engine ships without per-persona declarations. |
| 349 | + |
| 350 | +4. **An eighth axis or a split of an existing axis.** Deferred |
| 351 | + until scene-authoring accumulates evidence that the seven do |
| 352 | + not cover the response space. Examples of candidates: |
| 353 | + shame/dignity (related to but not the same as pride/humility), |
| 354 | + despair/hope (related to but not the same as sloth/diligence), |
| 355 | + fear/courage (not currently modelled). Out of scope for this |
| 356 | + ADR; recorded here so they are not silently lost. |
| 357 | + |
| 358 | +5. **Validator for virtue shape.** Optional governance after the |
| 359 | + engine lands and is used in practice: a test that walks pole- |
| 360 | + position files and asserts no file uses the word naming its |
| 361 | + own pole in its body. The behaviour-as-evidence rule |
| 362 | + formalised as a gate. Promotable to hard after some authoring |
| 363 | + experience confirms the rule is workable. |
| 364 | + |
| 365 | +6. **Heritage-virtue and hierarchy-virtue composition guides.** |
| 366 | + Not engine files; authoring documentation for how a persona's |
| 367 | + heritage biases which sin pole pulls, and how a persona's |
| 368 | + current hierarchy position shifts the room's reading of the |
| 369 | + pole-firing. Belongs in `docs/` or in a future authoring |
| 370 | + guide; out of scope for this engine ADR. |
| 371 | + |
| 372 | +--- |
| 373 | + |
| 374 | +*ADR-0007 -- v0.1.0 -- KAI Worlds* |
0 commit comments