-- Achievements: the playthrough case-state. Boolean facts earned by a player, each -- remembering the story node that awarded it. This is the NARRATIVE scope the phone -- gate, node-enable requirements, and gates read; level-local flags (025) promote up -- into it when a level node's achievement fires. A fact is true once (PK on player + -- key); the awarding node is provenance and is nullable (New Game / manual grants). CREATE TABLE osint.achievements ( playthrough_id UUID NOT NULL REFERENCES osint.playthroughs(id) ON DELETE CASCADE, flag_key TEXT NOT NULL CHECK (flag_key ~ '^[a-z][a-z0-9_.-]{0,63}$'), awarded_by_node_id UUID REFERENCES osint.story_nodes(id) ON DELETE SET NULL, earned_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), PRIMARY KEY (playthrough_id, flag_key) ); CREATE INDEX achievements_playthrough_idx ON osint.achievements (playthrough_id); COMMENT ON TABLE osint.achievements IS 'Boolean achievements earned by a player (playthrough), each remembering the awarding story node. The narrative case-state that gates the phone, node-enable requirements, and story gates.';