# People dynamics protocol

This is the canonical contract for `.manuscript/PEOPLE-DYNAMICS.md`, Scriveno's derived map of how peoples relate and clash as collectives, and for how it is computed. The goal is one always-complete answer to "how does every people stand with every other", including the pairs with no dealings.

It is the collective-tier analog of the relationship and conflict maps. The sources are:

- `PEOPLES.md` -- the authored peoples and each one's "Relations with other peoples" section (standing, shared history, friction or bond)
- `.manuscript/PEOPLE-DYNAMICS.md` -- the derived pairwise map (the file you open to see every standing)

`PEOPLES.md` is the source of truth; `PEOPLE-DYNAMICS.md` is a derived view of it. Like `CONTEXT.md` and `CONFLICTS.md`, it is a neutral derived file -- the same filename across work types -- and it is not created at `/scr:new-work`; it is generated once two or more peoples exist.

## The completeness rule

For P peoples there are P*(P-1)/2 unordered pairs. Every pair appears in the map. A pair with an established standing shows it; a pair with none shows `no dealings`. There are no blanks: "no dealings" is a recorded value, not a gap, exactly as in the relationship and conflict maps. An absent pair means the derivation missed it (drift), not that the writer left it out.

## Derivation (source-first)

1. Read the peoples and their "Relations with other peoples" sections from `PEOPLES.md`.
2. For each people, parse the standing, shared history, and friction or bond toward each other people.
3. Enumerate every pair. Fill established pairs from step 2; mark every remaining pair `no dealings` where the writer has established there are none, or surface it as undefined where no one has said yet.
4. Render the pairwise matrix and the list of undefined pairs.

## Undefined pairs and exploration

The map distinguishes `no dealings` (the writer established there are none) from undefined (no one has said yet). Undefined pairs are surfaced so the writer can decide, via `/scr:new-people` or by editing the people entries. The system never invents a dynamic to fill a gap; it only surfaces the gap.

## Who regenerates PEOPLE-DYNAMICS.md

Rebuilt by the commands that change the peoples or refresh derived state, never by a read-only command:

- `/scr:new-people` -- after a people (and its relations) is added
- `/scr:save` -- alongside the other derived surfaces, when two or more peoples exist
- `/scr:scan --fix` -- when the map is missing or stale

`/scr:relationship-map --peoples` renders the map for the writer; the saved file is regenerated by the owners above.

## When this protocol does not apply

- **Work types without peoples.** Where `surface_applicability` marks `PEOPLES.md` not_applicable (academic, technical, poetry, speech), there is no people-dynamics map. Skip silently.
- **Fewer than two peoples.** A single people has no pairs; the map is generated once a second people exists.
- **Neutral filename.** Like the conflict map, this is always `PEOPLE-DYNAMICS.md` (the `CONTEXT.md` precedent), not renamed per group.

The protocol is a hint, not a hard gate. A command that cannot parse the people entries cleanly should say so and render what it can, rather than emit a wrong map.
