SPB Git

spb/wp45_uqo

Public
14.0 KB · 94 lines python
1"""Phase 6 — Claude Code integration: project-scoped slash commands (.claude/commands/jof-*.md), a skill (.claude/skills/jof250/SKILL.md)2and specialist agents (.claude/agents/jof-*.md). `install(scope="user")` copies the same files to ~/.claude/{commands,skills,agents}3(explicitly requested by the author; only files prefixed `jof-`/`jof250` are written; nothing else in ~/.claude is touched)."""4from __future__ import annotations5import os, shutil, json6from pathlib import Path7from .. import config8from ..provenance import ROOT, now_iso910JOF = f"{ROOT}/.venv/bin/jof250"11COMMANDS = {12 "jof-status": ("Show JoF-250 pipeline status (corpus, parsing, annotations, profiles, index, spend)", "", f"Run `{JOF} status` with Bash and report the output to the user verbatim, then one sentence on what is missing (if anything)."),13 "jof-corpus-audit": ("Re-run the JoF corpus inventory/verification and summarize the audit", "", f"Run `{JOF} corpus audit` (Crossref verification included; add `--no-verify` if the user is offline), then read `{ROOT}/data/manifests/corpus_audit.md` and summarize: included/excluded counts by year and type, duplicates, Crossref status, and any records needing review."),14 "jof-profile": ("Explain a measured JoF writing profile (empirical_asset_pricing, corporate_finance, financial_econometrics, theoretical_finance, …)", "[profile-name]",15                 f"Read `{ROOT}/profiles/$ARGUMENTS.yaml` (if `$ARGUMENTS` is empty, list `{ROOT}/profiles/`). Present the profile as a short structured brief: sample size and selection rule, length/structure medians with IQRs, abstract and introduction move patterns, contribution placement, identification/robustness/table conventions, and the caveat that observed frequencies are descriptive, not editorial rules."),16 "jof-outline": ("Propose a section outline for a manuscript using JoF-250 (profiles + structured retrieval)", "<paper-path> --section <name>",17                 f"Parse `$ARGUMENTS` as `<paper-path> [--section <name>]` (default section: introduction). Run `{JOF} write --paper <path> --section <name> --mode outline --output /tmp/jof-outline-<name>.tex`. Read the resulting `.tex` and `.report.md`; present the outline, the rhetorical rationale (change log), the flags, and the retrieval provenance. Never edit the manuscript."),18 "jof-write": ("Draft a manuscript section with the full JoF-250 engine (profiles, structured retrieval, verification, specialist referee)", "<paper-path> --section <name> [--condition A|B|C|D|E]",19               f"Parse `$ARGUMENTS` as `<paper-path> [--section <name>] [--condition X]` (defaults: introduction, E_full_engine). Run `{JOF} write --paper <path> --section <name> --mode write --condition <X> --output <paper-path>/jof250_proposals/<name>_<date>.tex` (create the folder; this is a NEW file, the manuscript is never modified). Then read the `.report.md` next to it and show: the proposed text location, the change log, every FLAG (facts the author must verify), the deterministic audit summary (numbers not in the manuscript, unknown citation keys, unsupported claims, corpus overlap), and retrieval provenance."),20 "jof-review": ("Produce a referee-style review of a manuscript (roles: referee, editor, table_editor, integrity, replication)", "<paper-path> [--role referee|editor|table_editor|integrity|replication] [--full]",21                f"Parse `$ARGUMENTS` as `<paper-path> [--role R] [--full]` (default role referee). If `--full`, run roles referee, editor, table_editor, integrity and replication in sequence. For each: `{JOF} review --paper <path> --role <R> --output <paper-path>/jof250_reviews/<R>_<date>.md`. Then read each report and give the user a prioritized synthesis (major issues first), keeping every number as written. Do not modify the manuscript."),22 "jof-upgrade": ("Rewrite/upgrade an existing section while preserving every result, number and citation", "<paper-path> --section <name> [--preserve-results]",23                 f"Parse `$ARGUMENTS` as `<paper-path> [--section <name>]`. Run `{JOF} write --paper <path> --section <name> --mode upgrade --output <paper-path>/jof250_proposals/<name>_upgrade_<date>.tex`. Read the `.report.md`: if the deterministic audit reports numbers missing from the output or new numbers not in the manuscript, say so prominently and do not recommend adopting the text until fixed. Show the diff summary and change log. The manuscript itself is never modified by the command; offer to apply the patch only if the user explicitly asks."),24 "jof-audit": ("Deterministic manuscript audit: tables, equations, citations/DOIs, unsupported claims, corpus overlap", "<paper-path> [--tables] [--equations]",25               f"Parse `$ARGUMENTS` as `<paper-path> [flags]`. Run `{JOF} audit --paper <path> --output /tmp/jof-audit.md` and present the report grouped by severity: broken references/labels and unknown citation keys first, then DOI resolution failures, then unsupported-claim sentences, then table/figure caption-and-notes issues, then overlap. Offer concrete fixes, as a patch proposal, not as silent edits."),26 "jof-evidence": ("Locate the evidence for a claim inside a manuscript (tables, numbers, sentences)", "<paper-path> --claim \"...\"",27                  f"Parse `$ARGUMENTS` as `<paper-path> --claim \"<text>\"`. Run `{JOF} evidence --paper <path> --claim \"<text>\"` and report the status (supported_by_table / mentioned_in_text / no_evidence_found) with the hits (table labels, sentences, numbers found). If no evidence is found, say so plainly and suggest what table or analysis would be needed."),28 "jof-benchmark": ("Run (or dry-run) the preregistered JoF-250 evaluation protocol", "[--protocol heldout_v1] [--dry-run]",29                   f"Parse `$ARGUMENTS`. Run `{JOF} benchmark --config {ROOT}/config/evaluation.yaml <args>` (use `--dry-run` to list tasks/conditions/cost estimate without API calls; a real run spends money — ask the user to confirm the printed budget first). Report the summary JSON and where outputs were written (`{ROOT}/experiments/outputs/`). Never present results that were not actually run."),30}31AGENTS = {32 "jof-corpus-auditor": ("Corpus Auditor — verifies the JoF-250 corpus inventory, manifest integrity, duplicates and bibliographic records", "haiku",33                        f"You audit the JoF-250 corpus. Use `{JOF} corpus audit` and the files under `{ROOT}/data/manifests/`. Report counts, exclusions, Crossref failures and any inconsistency between the frozen manifest and the folder. Never modify PDFs or the manifest by hand."),34 "jof-rhetorical-analyst": ("Rhetorical Analyst — explains the rhetorical structure of a section/manuscript against the measured JoF profiles", "sonnet",35                            f"You analyse scholarly writing structure. Load the relevant profile from `{ROOT}/profiles/` and, for the user's section, label each paragraph with its rhetorical move (motivation, tension, gap, preview of approach/results, contribution, roadmap, …), compare the sequence and placement with the profile's measured patterns, and recommend changes as proposals. Use `{JOF} retrieve --topic \"...\"` to show comparable published patterns with provenance. Never copy source sentences."),36 "jof-writing-editor": ("Finance Writing Editor — proposes rewrites that keep every fact, number and citation unchanged", "sonnet",37                        f"You edit academic finance prose. Run `{JOF} review --paper <path> --role editor --output <path>/jof250_reviews/editor.md` and then propose paragraph-level rewrites as a patch file (never edit the manuscript directly). Every number, sign, unit and citation key must be preserved; run `{JOF} audit --paper <path>` afterwards and report numeric preservation."),38 "jof-econometric-referee": ("Econometric Referee — identification, inference, robustness critique", "opus",39                             f"You referee empirical finance work. Run `{JOF} review --paper <path> --role referee --output <path>/jof250_reviews/referee.md`; focus on estimand, identifying assumptions, threats, standard errors/clustering, multiple testing, economic vs statistical significance, and whether causal language matches the design. Tie each comment to a section/table/equation. Do not invent results."),40 "jof-table-figure-editor": ("Table/Figure Editor — captions, notes, units, uncertainty", "sonnet",41                             f"Run `{JOF} review --paper <path> --role table_editor --output <path>/jof250_reviews/table_editor.md` and `{JOF} audit --paper <path>`. Propose corrected captions and notes for each table/figure (sample, unit, period, SEs, significance conventions, uncertainty in figures) as a patch; numbers never change."),42 "jof-integrity-auditor": ("Citation/Integrity Auditor — citations, DOIs, unsupported claims, numeric consistency, overlap", "sonnet",43                           f"Run `{JOF} audit --paper <path> --output <path>/jof250_reviews/audit.md` and `{JOF} review --paper <path> --role integrity --output <path>/jof250_reviews/integrity.md`. Report unknown citation keys, unresolved DOIs, prose numbers absent from tables, claims without anchors, causal overreach, and corpus overlap. Severity-ranked, minimal fixes, no speculation."),44 "jof-replication-auditor": ("Replication Auditor — what a replicator needs and what is missing", "sonnet",45                             f"Run `{JOF} review --paper <path> --role replication --output <path>/jof250_reviews/replication.md`. Produce a present/absent checklist (data access, sample filters, variable definitions, specifications, software, seeds, code/data availability) with locations and the questions the authors must answer."),46}47SKILL = f"""---48name: jof25049description: JoF-250 Writing Engine (UQO WP45) — draft, outline, upgrade, review and audit scholarly manuscripts (LaTeX/Markdown) using measured writing conventions from 276 pre-ChatGPT Journal of Finance articles. Use when the user asks to write or improve a paper section, get a referee report, audit tables/equations/citations, locate evidence for a claim, or inspect JoF writing profiles. Commands: /jof-status /jof-corpus-audit /jof-profile /jof-outline /jof-write /jof-review /jof-upgrade /jof-audit /jof-evidence /jof-benchmark.50---51# JoF-250 Writing Engine5253Backing CLI: `{JOF}` (Python 3.12 venv at `{ROOT}/.venv`). Project root: `{ROOT}`. Docs: `{ROOT}/docs/USER_GUIDE.md`.5455## What it does56- **Profiles** (`{ROOT}/profiles/*.yaml`): measured distributions (medians, IQRs, n) of section lengths, abstract/introduction rhetorical moves, contribution placement, identification language, robustness and table conventions, built from the train split of the corpus. Descriptive, not prescriptive.57- **Retrieval** (`jof250 retrieve --topic "..."`): hybrid BM25 + local embeddings over structural annotations and ≤400-char excerpts; every hit carries provenance (doc_id, DOI, year, page, section, confidence). Full texts are never exposed.58- **Engine** (`jof250 write --paper P --section S --mode outline|write|upgrade --condition E_full_engine --output F`): inspects the manuscript (LaTeX with \\input resolution, or Markdown), detects genre/subfield, selects a profile, retrieves rhetorical patterns, drafts, runs deterministic checks (numeric preservation, unknown citation keys, unsupported claims, corpus overlap) and a specialist-referee revision. Output = new file + `.report.md` (change log, flags, provenance, audit, diff). **The manuscript is never modified.**59- **Reviews** (`jof250 review --paper P --role referee|editor|table_editor|integrity|replication`), **audits** (`jof250 audit --paper P`), **evidence lookup** (`jof250 evidence --paper P --claim "..."`).6061## Rules for the assistant621. Always pass an explicit `--output` path under the user's paper folder (`jof250_proposals/`, `jof250_reviews/`) or `/tmp`; present proposals and diffs; apply changes only on explicit request.632. Read and relay the FLAGS and the deterministic audit; never present a generated number or citation as verified.643. For theory, methods or non-finance manuscripts, say which JoF conventions do not apply (the engine prints a genre note).654. API calls cost money (ledger: `{ROOT}/data/annotations/api_ledger.jsonl`; `jof250 status` shows spend). The benchmark command spends more: dry-run first.665. If the venv or index is missing, run `cd {ROOT} && make install && make index` (see `docs/INSTALL.md`).67"""6869def _cmd_md(name, desc, args, body):70    return f"---\ndescription: {desc}\nargument-hint: {args}\nallowed-tools: Bash({JOF}:*), Bash(ls:*), Bash(cat:*), Bash(mkdir:*), Read, Glob, Grep\n---\n{body}\n"7172def _agent_md(name, desc, model, body):73    return f"---\nname: {name}\ndescription: {desc}\nmodel: {model}\ntools: Bash, Read, Glob, Grep\n---\n{body}\n"7475def write_files(base: Path) -> list[str]:76    written = []77    (base / "commands").mkdir(parents=True, exist_ok=True); (base / "agents").mkdir(parents=True, exist_ok=True); (base / "skills" / "jof250").mkdir(parents=True, exist_ok=True)78    for n, (d, a, b) in COMMANDS.items():79        p = base / "commands" / f"{n}.md"; p.write_text(_cmd_md(n, d, a, b)); written.append(str(p))80    for n, (d, m, b) in AGENTS.items():81        p = base / "agents" / f"{n}.md"; p.write_text(_agent_md(n, d, m, b)); written.append(str(p))82    p = base / "skills" / "jof250" / "SKILL.md"; p.write_text(SKILL); written.append(str(p))83    return written8485def install(scope: str = "project", force: bool = False) -> dict:86    if scope == "project":87        files = write_files(ROOT / ".claude"); return {"scope": "project", "written": files}88    if scope == "user":89        home = Path(os.path.expanduser("~/.claude")); existing = [str(p) for p in list(home.glob("commands/jof-*.md")) + list(home.glob("agents/jof-*.md")) + list(home.glob("skills/jof250/SKILL.md"))]90        if existing and not force: return {"scope": "user", "written": [], "note": "jof- files already exist in ~/.claude; use --force to overwrite", "existing": existing}91        files = write_files(home); (home / "skills" / "jof250" / "INSTALLED_FROM").write_text(f"{ROOT}\n{now_iso()}\n")92        return {"scope": "user", "written": files, "note": "Only files named jof-*.md / skills/jof250 were written; ~/.claude/settings.json untouched."}93    raise ValueError("scope must be project or user")94
Files · main
Menu

Theme