Skip to content

[codex] Move moments to the story level#16

Merged
jhull merged 1 commit into
mainfrom
codex/story-level-moments
Jun 3, 2026
Merged

[codex] Move moments to the story level#16
jhull merged 1 commit into
mainfrom
codex/story-level-moments

Conversation

@jhull

@jhull jhull commented Jun 3, 2026

Copy link
Copy Markdown
Member

Summary

Moves NCP Moments from narrative-local storytelling into required story.moments[].

Moments are storytelling units: scenes, chapters, sequences, acts, levels, or comparable audience-facing containers. They belong to the story as a whole because a single storytelling unit can carry structural material from multiple narratives at once. For example, one scene can turn the public Objective Story, illustrate a private Relationship Story issue, and echo a Main Character Storypoint without becoming three duplicated scenes.

What changed

  • Adds required story.moments[] to the JSON schema and YAML schema twin.
  • Adds a reusable story_moment definition.
  • Requires story-level Moment references to qualify each storybeat_id and storypoint_id with narrative_id.
  • Adds storypoints[] references on Moments alongside storybeats[].
  • Removes narratives[].storytelling.moments[] from the schema so Moments have one unambiguous home.
  • Migrates existing examples to story-level Moments.
  • Adds examples/cross-narrative-moments.json to demonstrate one Moment referencing Storybeats and Storypoints from two narratives.
  • Adds invalid fixtures proving story-level Storybeat references must include narrative_id and narrative-local Moments are rejected.
  • Updates SPECIFICATION.md, schema reference docs, history, README, and copyright example.

Why

The previous shape implied that a Moment belonged to exactly one narrative because it lived at narratives[].storytelling.moments[]. That is too narrow for actual storytelling. A scene is experienced by the audience as part of the whole story, and it can legitimately relate to structural elements from different narratives.

Putting Moments only on story.moments[] preserves that audience-facing reality while keeping formal narrative structure intact. The Moment gathers references. The narrative_id on each reference tells consumers which narrative owns the Storybeat or Storypoint.

Having both story.moments[] and narratives[].storytelling.moments[] would create ambiguous ownership and invite duplicated or conflicting exports. This PR makes the model explicit: narratives own structure; the story owns storytelling Moments.

Compatibility

This is a schema-shape change for canonical exports because story.moments[] is now required and narratives[].storytelling.moments[] is no longer valid.

Importers that still receive older nested Moment payloads should migrate those entries up to story.moments[] and add narrative_id to each referenced Storybeat or Storypoint.

Validation

  • node tests/validate-schema.js -> Schema validation checks passed (8 valid + 11 invalid fixtures).
  • ruby -rjson -ryaml -e "json = JSON.parse(File.read('schema/ncp-schema.json')); yaml = YAML.load_file('schema/ncp-schema.yaml'); abort('schema mismatch') unless json == yaml; puts 'schema JSON/YAML equivalent'" -> schema JSON/YAML equivalent
  • git diff --check -> clean

@jhull jhull force-pushed the codex/story-level-moments branch from 1321fdc to 56f4aa8 Compare June 3, 2026 19:54
@jhull jhull force-pushed the codex/story-level-moments branch from 56f4aa8 to 7be8473 Compare June 3, 2026 20:04
@jhull jhull marked this pull request as ready for review June 3, 2026 20:06
@jhull jhull merged commit 90b6ab0 into main Jun 3, 2026
2 checks passed
@jhull jhull deleted the codex/story-level-moments branch June 3, 2026 20:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant