Add read-only PQRST evidence export from pinned entries
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a0e759-301a-78b1-bbc1-040ef094b12d
This commit is contained in:
parent
bda6e4d6ec
commit
7d70cd3ad4
1 changed files with 55 additions and 0 deletions
55
scripts/export-pqrst.py
Normal file
55
scripts/export-pqrst.py
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Export hall entry evidence as JSONL, without changing or grading seats.
|
||||
|
||||
Usage: python3 export-pqrst.py /path/to/hall-of-helix [--revision HEAD]
|
||||
Only committed entries at the resolved revision are read. Every entry is emitted,
|
||||
including missing/malformed PQRST sections. Raw text is retained for review.
|
||||
"""
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import re
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def git(repo, *args):
|
||||
return subprocess.check_output(['git', '-C', str(repo), *args])
|
||||
|
||||
|
||||
def export(repo, revision):
|
||||
commit = git(repo, 'rev-parse', '--verify', revision + '^{commit}').decode().strip()
|
||||
paths = git(repo, 'ls-tree', '-r', '--name-only', '-z', commit, '--', 'entries/')
|
||||
for name in sorted(p.decode() for p in paths.split(b'\0') if p.endswith(b'.md')):
|
||||
raw = git(repo, 'show', f'{commit}:{name}')
|
||||
text = raw.decode('utf-8')
|
||||
fm = re.match(r'\A---\n(.*?)\n---(?:\n|$)', text, re.S)
|
||||
body = text[fm.end():] if fm else text
|
||||
sections = re.findall(r'^## PQRST estimate\s*\n(.*?)(?=^## |\Z)', body, re.M | re.S | re.I)
|
||||
blocks = []
|
||||
for section in sections:
|
||||
for match in re.finditer(r'^```[^\n]*\n(PQRST-Estimate\n.*?)^```[ \t]*$', section, re.M | re.S):
|
||||
record = match.group(1)
|
||||
fields = {}
|
||||
for field in re.finditer(r'^([A-Za-z][A-Za-z ]*):[ \t]*(.*?)(?=^[A-Za-z][A-Za-z ]*:|\Z)', record, re.M | re.S):
|
||||
fields.setdefault(field.group(1), []).append(field.group(2).strip())
|
||||
blocks.append({'raw': record, 'fields': fields})
|
||||
yield {
|
||||
'source_commit': commit, 'path': name,
|
||||
'sha256': hashlib.sha256(raw).hexdigest(),
|
||||
'frontmatter_raw': fm.group(1) if fm else None,
|
||||
'pqrst_sections': sections, 'blocks': blocks,
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('repo', type=Path)
|
||||
parser.add_argument('--revision', default='HEAD')
|
||||
args = parser.parse_args()
|
||||
for record in export(args.repo, args.revision):
|
||||
print(json.dumps(record, ensure_ascii=False))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue