Files
TheLadder/tools/story-to-pack/probe/gate3.py
T
JesseMarkowitzandClaude Opus 5 fa3769d0fe Add story-to-pack research and a structured situation review
Research toward building a content pack from a story corpus, kept on its own
branch and independent of the game. Records the selection experiments against
blind labels, and settles selection as gate G2 followed by a human review:
review.py writes REVIEW.md and a review.json form, apply_review.py checks the
filled form and writes situations.json for the next stage.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C6UDQ9o6L6Ey173U7XVou6
2026-09-15 06:59:35 -04:00

41 lines
1.5 KiB
Python

"""G3: S1 floor, percentile against the same-size null, mandatory member floor (MMIN), optional W.
Builds on gate2 (similarities, word test, k-means). On first import it samples the same-size null
distribution of S1 and caches the sorted samples in null-samples.pkl.
"""
import bisect, pathlib, pickle, random
import gate2 as g
HERE = pathlib.Path(__file__).resolve().parent
_path = HERE / 'null-samples.pkl'
if _path.exists():
NULLS = pickle.loads(_path.read_bytes())
else:
rnd, NULLS = random.Random(3033), {}
for m in range(5, 151):
need, samples = (1000 if m <= 60 else 200), []
while len(samples) < need:
members = rnd.sample(range(g.n), m)
if g.eligible(members):
samples.append(g.cohesion(members)[0])
NULLS[m] = sorted(samples)
_path.write_bytes(pickle.dumps(NULLS))
def percentile(s1, size):
samples = NULLS[min(max(size, 5), 150)]
return bisect.bisect_left(samples, s1) / len(samples)
def signals(m):
sig = g.signals(m) # size, stories, dominant, S1, Z1, MMIN, W, W_word, S6_old
sig['PCT'] = percentile(sig['S1'], sig['size'])
return sig
def passes(sig, gate):
if not (sig['size'] >= g.MIN_SIZE and sig['stories'] >= g.MIN_STORIES and sig['dominant'] <= g.MAX_DOMINANT):
return False
if sig['S1'] < gate['S1'] or sig['PCT'] < gate['PCT'] or sig['MMIN'] < gate['MMIN']:
return False
if gate.get('W') is not None and sig['W'] >= gate['W']:
return False
return True