diff --git a/README.md b/README.md index add279a..f04f428 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,7 @@ zwill survey create --name hello_world zwill raw add \ --survey hello_world \ --id questionnaire \ - --path "$ZWILL_REPO/examples/hello_world/raw/questionnaire.md" \ + --input-path "$ZWILL_REPO/examples/hello_world/raw/questionnaire.md" \ --kind questionnaire \ --title "Hello World Questionnaire" ``` @@ -131,7 +131,7 @@ For normal use, put those records in JSONL and import the file instead. The comm ```bash zwill respondent import \ --survey hello_world \ - --path "$ZWILL_REPO/examples/hello_world/respondents.jsonl" + --input-path "$ZWILL_REPO/examples/hello_world/respondents.jsonl" ``` Answers work the same way. You can add them one at a time, and each answer is validated against both the respondent id and the question's declared options. @@ -151,7 +151,7 @@ Or load the same answer records from JSONL: ```bash zwill answer import \ --survey hello_world \ - --path "$ZWILL_REPO/examples/hello_world/answers.jsonl" + --input-path "$ZWILL_REPO/examples/hello_world/answers.jsonl" ``` Inspect the respondent-by-question table: @@ -297,7 +297,7 @@ One-shot generated analysis uses the same staged pattern as the executive report ```bash zwill prob-results analysis-export --survey --job-id --path reports//one-shot-marginals.html zwill edsl-run --job .zwill/projects/default/practitioner_reports//job.edsl.json --path .zwill/projects/default/practitioner_reports//results.json.gz -zwill prob-results analysis-import --report-id --path .zwill/projects/default/practitioner_reports//results.json.gz +zwill prob-results analysis-import --report-id --input-path .zwill/projects/default/practitioner_reports//results.json.gz zwill prob-results analysis-render --report-id --path reports//one-shot-marginals.html ``` @@ -350,7 +350,7 @@ For AgentList exports, choose answer traits with `--question` or `--questions`; Inspect an exported AgentList: ```bash -zwill agent-list inspect --path agent_list.edsl.json +zwill agent-list inspect --input-path agent_list.edsl.json ``` Ask constructed agents a new question by exporting an EDSL job from the AgentList: @@ -367,7 +367,7 @@ zwill agent-study export \ --path agent_study_job.edsl.json zwill edsl-run --job agent_study_job.edsl.json --path agent_study_results.json.gz -zwill agent-study import --path agent_study_results.json.gz +zwill agent-study import --input-path agent_study_results.json.gz zwill agent-study report --format table ``` @@ -404,7 +404,7 @@ Use `--leakage-exclusion :` for target-speci Run with `zwill edsl-run`, then import and score: ```bash -zwill twin-results import --survey w158_ccpolicy --path twin_results.json.gz +zwill twin-results import --survey w158_ccpolicy --input-path twin_results.json.gz zwill twin-results report --survey w158_ccpolicy --job-id zwill twin-results report --survey w158_ccpolicy --job-id --format html --path twin_report.html ``` @@ -535,7 +535,7 @@ zwill twin-approach scaffold \ zwill twin-approach add \ --survey w158_ccpolicy \ - --path baseline_context.approach.json + --input-path baseline_context.approach.json zwill twin-approach add \ --survey w158_ccpolicy \ @@ -586,16 +586,16 @@ zwill twin-experiment init-plan \ --path policy_holdout_v1.json zwill twin-experiment approve \ - --path policy_holdout_v1.json \ + --input-path policy_holdout_v1.json \ --approved-by \ --note "Approved held-out targets, context policy, leakage exclusions, sample size, models, and seed." zwill twin-experiment export-plan \ - --path policy_holdout_v1.json \ + --input-path policy_holdout_v1.json \ --output-dir policy_holdout_v1_jobs ``` -Plans start as drafts and must be approved before export. `export-plan` writes a `manifest.json`, one EDSL job JSON per arm, approved-plan provenance, and planned experiment records in `experiments.json`. Running remains explicit: use `zwill edsl-run --job ` for each exported job, then `zwill twin-results import --survey --path `. After import, the existing comparison, plot, microdata, and report commands use the planned experiment records. +Plans start as drafts and must be approved before export. `export-plan` writes a `manifest.json`, one EDSL job JSON per arm, approved-plan provenance, and planned experiment records in `experiments.json`. Running remains explicit: use `zwill edsl-run --job ` for each exported job, then `zwill twin-results import --survey --input-path `. After import, the existing comparison, plot, microdata, and report commands use the planned experiment records. The approval review should check the held-out targets, construction approaches, context policy, target-specific leakage exclusions, respondent sample and seed, model list, and the prediction count formula: `respondents x held-out questions x approaches x models`. If a draft plan must be exported only for debugging, pass `--allow-unapproved`; this is intentionally visible in the command history. @@ -723,7 +723,7 @@ zwill edsl-run \ zwill twin-experiment report-import \ --report-id \ - --path .zwill/projects/default/practitioner_reports//results.json.gz + --input-path .zwill/projects/default/practitioner_reports//results.json.gz zwill twin-experiment report-render \ --report-id \ @@ -792,7 +792,7 @@ zwill edsl-run \ zwill twin-results executive-summary-import \ --report-id \ - --path .zwill/projects/default/practitioner_reports//results.json.gz + --input-path .zwill/projects/default/practitioner_reports//results.json.gz zwill twin-results executive-summary-render \ --report-id \ @@ -819,7 +819,7 @@ zwill edsl-run \ --path .zwill/projects/default/practitioner_reports//results.json.gz zwill twin-study practitioner-report-import \ - --path .zwill/projects/default/practitioner_reports//results.json.gz + --input-path .zwill/projects/default/practitioner_reports//results.json.gz zwill twin-study practitioner-report-render \ --report-id \ @@ -843,7 +843,7 @@ zwill edsl-run \ --path .zwill/projects/default/practitioner_reports//results.json.gz zwill twin-benchmark practitioner-report-import \ - --path .zwill/projects/default/practitioner_reports//results.json.gz + --input-path .zwill/projects/default/practitioner_reports//results.json.gz zwill twin-benchmark practitioner-report-render \ --report-id \ diff --git a/SPEC.md b/SPEC.md index 5436d7a..b9cf62f 100644 --- a/SPEC.md +++ b/SPEC.md @@ -123,7 +123,7 @@ Returns: "warnings": [], "errors": [], "next_steps": [ - "zwill raw add --survey hiring_study --id --path ", + "zwill raw add --survey hiring_study --id --input-path ", "zwill question add --survey hiring_study ..." ] } @@ -149,7 +149,7 @@ State written: zwill raw add \ --survey hiring_study \ --id questionnaire \ - --path raw/questionnaire.pdf \ + --input-path raw/questionnaire.pdf \ --kind questionnaire \ --title "Hiring Study Questionnaire" ``` @@ -262,7 +262,7 @@ Returns: "warnings": [], "errors": [], "next_steps": [ - "zwill answer import --survey hiring_study --path answers.jsonl" + "zwill answer import --survey hiring_study --input-path answers.jsonl" ] } ``` @@ -314,7 +314,7 @@ Returns: ### Bulk Import Questions ```bash -zwill question import --survey hiring_study --path questions.jsonl +zwill question import --survey hiring_study --input-path questions.jsonl ``` Each JSONL row is one question: @@ -383,7 +383,7 @@ Returns: Bulk import respondents: ```bash -zwill respondent import --survey hiring_study --path respondents.jsonl +zwill respondent import --survey hiring_study --input-path respondents.jsonl ``` Input: @@ -430,7 +430,7 @@ zwill agent-material add \ Bulk import agent material: ```bash -zwill agent-material import --survey hiring_study --path agent_material.jsonl +zwill agent-material import --survey hiring_study --input-path agent_material.jsonl ``` Input: @@ -537,7 +537,7 @@ Returns: ### Bulk Import Answers ```bash -zwill answer import --survey hiring_study --path answers.jsonl +zwill answer import --survey hiring_study --input-path answers.jsonl ``` Input: @@ -610,7 +610,7 @@ Users can attach markdown context to a survey. This is intended for source descr Append markdown context from a file: ```bash -zwill context add --survey hiring_study --path source_context.md +zwill context add --survey hiring_study --input-path source_context.md ``` Or from a command argument: @@ -644,7 +644,7 @@ Returns: Replace existing context: ```bash -zwill context set --survey hiring_study --path source_context.md +zwill context set --survey hiring_study --input-path source_context.md ``` Show stored context: @@ -727,7 +727,7 @@ This avoids presenting survey answers as cryptic generic traits. Users can overr Inspect an exported AgentList: ```bash -zwill agent-list inspect --path hiring_agents.edsl.json +zwill agent-list inspect --input-path hiring_agents.edsl.json ``` The inspector reports agent count, trait keys, codebook keys, instruction coverage, mean instruction length, export metadata, and a small agent preview. Use `--format json` for machine-readable output. @@ -760,7 +760,7 @@ The exported job is a normal EDSL `Jobs.to_dict()` serialization with the AgentL ```bash zwill edsl-run --job hiring_agent_study.edsl.json --path hiring_agent_study_results.json.gz -zwill agent-study import --path hiring_agent_study_results.json.gz +zwill agent-study import --input-path hiring_agent_study_results.json.gz ``` Imported AgentStudy results are stored in two forms: @@ -816,7 +816,7 @@ Import serialized EDSL `Results` from a probability job: ```bash zwill prob-results import \ --survey hiring_study \ - --path example_prob_job.json.gz + --input-path example_prob_job.json.gz ``` The command stores the raw Results file under `.zwill/projects//surveys//probability_jobs//raw/` and extracts one predicted probability distribution per EDSL result row. The default `job_id` is a deterministic hash of the Results survey/scenario/model payload; it can be overridden with `--job-id`. JSON answers wrapped in markdown fences are accepted. Extracted rows are stored in `.zwill/projects//surveys//probability_predictions.jsonl`. @@ -866,7 +866,7 @@ Run the exported job with `zwill edsl-run`, then import and score the Results: ```bash zwill twin-results import \ --survey hiring_study \ - --path hiring_twin_results.json.gz + --input-path hiring_twin_results.json.gz zwill twin-results report \ --survey hiring_study \ @@ -919,7 +919,7 @@ zwill twin-approach add \ --complete-cases \ --model openai:gpt-5.5 -zwill twin-approach add --survey hiring_study --path approach.json +zwill twin-approach add --survey hiring_study --input-path approach.json zwill twin-approach scaffold --survey hiring_study --approach-id baseline_context --path approach.json zwill twin-approach list --survey hiring_study zwill twin-approach show --survey hiring_study --approach-id baseline_context @@ -957,7 +957,7 @@ Experiment plans compile one or more registered or inline approaches into EDSL j ```bash zwill twin-experiment init-plan --survey hiring_study --plan-id holdout_v1 --heldout-questions q1,q2 --approach-id baseline_context --path holdout_v1.json -zwill twin-experiment export-plan --path holdout_v1.json --output-dir holdout_v1_jobs +zwill twin-experiment export-plan --input-path holdout_v1.json --output-dir holdout_v1_jobs ``` `init-plan` must write a valid editable JSON plan using existing survey question names, defaulting to the first multiple-choice question when no held-out question is provided. It must not mutate project state or export jobs. @@ -1021,7 +1021,7 @@ zwill twin-experiment report-export \ --report-model openai:gpt-5.5 zwill edsl-run --job .zwill/projects/default/practitioner_reports//job.edsl.json --path .zwill/projects/default/practitioner_reports//results.json.gz -zwill twin-experiment report-import --report-id --path .zwill/projects/default/practitioner_reports//results.json.gz +zwill twin-experiment report-import --report-id --input-path .zwill/projects/default/practitioner_reports//results.json.gz zwill twin-experiment report-render --report-id --path experiment_report.html ``` @@ -1040,7 +1040,7 @@ Respondent metadata (panel covariates such as age, party, region) is included as For a held-out question with `question_type: numeric`, `zwill edsl-export --survey --target numeric-twin-job --heldout-question ` builds a twin job in which the model predicts a **quantile distribution** (5th/25th/50th/75th/95th percentiles) of the value the respondent would give, honoring optional `numeric_min` / `numeric_max` bounds. Run it with `zwill edsl-run`, then: ```bash -zwill numeric-results import --survey --path numeric_results.json.gz +zwill numeric-results import --survey --input-path numeric_results.json.gz zwill numeric-results report --survey --job-id --format html --path numeric_report.html ``` @@ -1055,13 +1055,13 @@ Free-text (`free_text`) questions are validated by **coding them into themes** a zwill edsl-export --survey --target open-codebook-job --heldout-question \ --n-themes 8 --sample-answers 150 --model openai:gpt-5.5 --path codebook.edsl.json zwill edsl-run --job codebook.edsl.json --path codebook_results.json.gz -zwill open-coding codebook-import --survey --path codebook_results.json.gz +zwill open-coding codebook-import --survey --input-path codebook_results.json.gz # 2. Classify each respondent's answer into one codebook theme. zwill edsl-export --survey --target open-coding-job --heldout-question \ --coded-question-name _coded --model openai:gpt-5.5 --path coding.edsl.json zwill edsl-run --job coding.edsl.json --path coding_results.json.gz -zwill open-coding import --survey --path coding_results.json.gz +zwill open-coding import --survey --input-path coding_results.json.gz ``` `open-codebook-job` builds a single scenario that shows a sample of the answers (`--sample-answers`, default 150) and asks for at most `--n-themes` (default 8) mutually-exclusive themes. `codebook-import` stores it under `open_coding//codebook.json`. `open-coding-job` builds one scenario per respondent that classifies their actual answer into a codebook theme (or a reserved `unclassified` bucket). `open-coding import` writes a new `multiple_choice` question (`--coded-question-name`, default `_coded`; options = theme codes, labels = theme labels) plus one coded answer per respondent, and returns a warning if more than 20% of answers were `unclassified` (the codebook may not fit) or if the results carried multiple codings per respondent (code with a single model). The coded question is then validated exactly like any other multiple-choice target. @@ -1076,7 +1076,7 @@ Practitioner report generation follows the same export/run/import/render lifecyc `zwill twin-benchmark practitioner-report-export` accepts the same `--manifest` or `--config` sources for cross-survey benchmark/meta reports. Cross-survey reports should be used to compare exercises and models, not as the default practitioner narrative for one uploaded survey. -The exported job is run through `zwill edsl-run` or by another agent using EDSL `job.run()`. `zwill twin-benchmark practitioner-report-import --path ` stores the raw Results object under the matching report id and extracts the generated Markdown. `zwill twin-benchmark practitioner-report-render --report-id ` wraps the stored Markdown as standalone HTML using the stored benchmark payload; rendering must not call a frontier model. The HTML should embed source JSON and include a button that copies the Markdown report to the clipboard for LLM use. Public-facing report HTML should use Expected Parrot branding, should not mention the internal tool name, and should include canned boilerplate explaining why held-out questions are used as a proxy for new questions asked of instantiated digital twins. That boilerplate should explain that this is a high-bar test because survey designers typically avoid asking highly correlated questions. +The exported job is run through `zwill edsl-run` or by another agent using EDSL `job.run()`. `zwill twin-benchmark practitioner-report-import --input-path ` stores the raw Results object under the matching report id and extracts the generated Markdown. `zwill twin-benchmark practitioner-report-render --report-id ` wraps the stored Markdown as standalone HTML using the stored benchmark payload; rendering must not call a frontier model. The HTML should embed source JSON and include a button that copies the Markdown report to the clipboard for LLM use. Public-facing report HTML should use Expected Parrot branding, should not mention the internal tool name, and should include canned boilerplate explaining why held-out questions are used as a proxy for new questions asked of instantiated digital twins. That boilerplate should explain that this is a high-bar test because survey designers typically avoid asking highly correlated questions. `zwill twin-study practitioner-report` and `zwill twin-benchmark practitioner-report` remain one-step convenience commands. They should call the same export, EDSL run, import, and render machinery rather than using a separate hidden model-call path. diff --git a/examples/hello_world/README.md b/examples/hello_world/README.md index 10c5645..0f0ee29 100644 --- a/examples/hello_world/README.md +++ b/examples/hello_world/README.md @@ -7,7 +7,7 @@ This is the smallest useful `zwill` example: one survey question and five respon ```bash zwill init zwill survey create --name hello_world -zwill raw add --survey hello_world --id questionnaire --path examples/hello_world/raw/questionnaire.md --kind questionnaire --title "Hello World Questionnaire" +zwill raw add --survey hello_world --id questionnaire --input-path examples/hello_world/raw/questionnaire.md --kind questionnaire --title "Hello World Questionnaire" zwill question add --survey hello_world --question-name favorite_color --question-type multiple_choice --question-text "Which color do you like best?" --question-option red --question-option blue --question-option green --role survey_item --source-raw questionnaire --source-note "Single hello-world test question." zwill respondent add --survey hello_world --respondent-id r001 --weight 1.0 --metadata "sample_source=demo" zwill respondent add --survey hello_world --respondent-id r002 --weight 1.0 --metadata "sample_source=demo" diff --git a/examples/hello_world/agent_list_study.sh b/examples/hello_world/agent_list_study.sh index fb72e42..d7f6091 100755 --- a/examples/hello_world/agent_list_study.sh +++ b/examples/hello_world/agent_list_study.sh @@ -48,7 +48,7 @@ zwill_cmd edsl-export \ --include-agent-material \ --agent-material-kind profile \ --path agent_list.edsl.json -zwill_cmd agent-list inspect --path agent_list.edsl.json +zwill_cmd agent-list inspect --input-path agent_list.edsl.json zwill_cmd agent-study export \ --agent-list agent_list.edsl.json \ @@ -63,7 +63,7 @@ if [[ "${ZWILL_EXAMPLE_DRY_RUN:-0}" == "1" ]]; then zwill_cmd edsl-run --job agent_study_job.edsl.json --path agent_study_results.json.gz --dry-run else zwill_cmd edsl-run --job agent_study_job.edsl.json --path agent_study_results.json.gz - zwill_cmd agent-study import --path agent_study_results.json.gz --replace + zwill_cmd agent-study import --input-path agent_study_results.json.gz --replace zwill_cmd agent-study list zwill_cmd agent-study report --format table fi diff --git a/examples/hello_world/agent_material_twin.sh b/examples/hello_world/agent_material_twin.sh index 2895a96..5307e1f 100755 --- a/examples/hello_world/agent_material_twin.sh +++ b/examples/hello_world/agent_material_twin.sh @@ -53,7 +53,7 @@ if [[ "${ZWILL_EXAMPLE_DRY_RUN:-0}" == "1" ]]; then zwill_cmd edsl-run --job without_material_job.edsl.json --path without_material_results.json.gz --dry-run else zwill_cmd edsl-run --job without_material_job.edsl.json --path without_material_results.json.gz - zwill_cmd twin-results import --survey agent_material_hello --path without_material_results.json.gz --replace + zwill_cmd twin-results import --survey agent_material_hello --input-path without_material_results.json.gz --replace fi zwill_cmd edsl-export \ @@ -71,7 +71,7 @@ if [[ "${ZWILL_EXAMPLE_DRY_RUN:-0}" == "1" ]]; then zwill_cmd edsl-run --job with_material_job.edsl.json --path with_material_results.json.gz --dry-run else zwill_cmd edsl-run --job with_material_job.edsl.json --path with_material_results.json.gz - zwill_cmd twin-results import --survey agent_material_hello --path with_material_results.json.gz --replace + zwill_cmd twin-results import --survey agent_material_hello --input-path with_material_results.json.gz --replace zwill_cmd twin-study list --survey agent_material_hello --format json fi diff --git a/examples/hello_world/show_table.sh b/examples/hello_world/show_table.sh index e95ccdc..3d6c13b 100755 --- a/examples/hello_world/show_table.sh +++ b/examples/hello_world/show_table.sh @@ -9,7 +9,7 @@ export PATH="$(python3 -c 'import sysconfig; print(sysconfig.get_path("scripts") zwill init zwill survey create --name hello_world -zwill raw add --survey hello_world --id questionnaire --path "$REPO_ROOT/examples/hello_world/raw/questionnaire.md" --kind questionnaire --title "Hello World Questionnaire" +zwill raw add --survey hello_world --id questionnaire --input-path "$REPO_ROOT/examples/hello_world/raw/questionnaire.md" --kind questionnaire --title "Hello World Questionnaire" zwill question add --survey hello_world --question-name favorite_color --question-type multiple_choice --question-text "Which color do you like best?" --question-option red --question-option blue --question-option green --role survey_item --source-raw questionnaire --source-note "Single hello-world test question." zwill respondent add --survey hello_world --respondent-id r001 --weight 1.0 --metadata "sample_source=demo" zwill respondent add --survey hello_world --respondent-id r002 --weight 1.0 --metadata "sample_source=demo" diff --git a/examples/hello_world/twin_plan_lifecycle.sh b/examples/hello_world/twin_plan_lifecycle.sh index 0bdf702..b7d9789 100755 --- a/examples/hello_world/twin_plan_lifecycle.sh +++ b/examples/hello_world/twin_plan_lifecycle.sh @@ -77,7 +77,7 @@ zwill_cmd twin-approach add \ --model openai:gpt-5.5 zwill_cmd twin-experiment export-plan \ - --path "$REPO_ROOT/examples/hello_world/twin_plan.json" \ + --input-path "$REPO_ROOT/examples/hello_world/twin_plan.json" \ --output-dir jobs zwill_cmd twin-experiment plan-status --survey hello_twin_plan --plan-id hello_twin_plan diff --git a/examples/hiring_study/README.md b/examples/hiring_study/README.md index 1e1f899..cb60aa4 100644 --- a/examples/hiring_study/README.md +++ b/examples/hiring_study/README.md @@ -18,11 +18,11 @@ This fixture is an import-ready survey dataset for testing the `zwill` CLI contr ```bash zwill init zwill survey create --name hiring_study -zwill raw add --survey hiring_study --id questionnaire --path examples/hiring_study/raw/questionnaire.md --kind questionnaire --title "Hiring Study Questionnaire" -zwill raw add --survey hiring_study --id panel_export --path examples/hiring_study/raw/panel_export.csv --kind panel_export --title "Hiring Study Panel Export" -zwill question import --survey hiring_study --path examples/hiring_study/questions.jsonl -zwill respondent import --survey hiring_study --path examples/hiring_study/respondents.jsonl -zwill answer import --survey hiring_study --path examples/hiring_study/answers.jsonl +zwill raw add --survey hiring_study --id questionnaire --input-path examples/hiring_study/raw/questionnaire.md --kind questionnaire --title "Hiring Study Questionnaire" +zwill raw add --survey hiring_study --id panel_export --input-path examples/hiring_study/raw/panel_export.csv --kind panel_export --title "Hiring Study Panel Export" +zwill question import --survey hiring_study --input-path examples/hiring_study/questions.jsonl +zwill respondent import --survey hiring_study --input-path examples/hiring_study/respondents.jsonl +zwill answer import --survey hiring_study --input-path examples/hiring_study/answers.jsonl zwill status zwill commit --survey hiring_study ``` diff --git a/examples/pew_w154_diff1/README.md b/examples/pew_w154_diff1/README.md index ccf5191..ace18e0 100644 --- a/examples/pew_w154_diff1/README.md +++ b/examples/pew_w154_diff1/README.md @@ -31,7 +31,7 @@ zwill table --survey pew_w154_diff1 --limit 12 It also adds source documentation with: ```bash -zwill context add --survey pew_w154_diff1 --path examples/pew_w154_diff1/context.md +zwill context add --survey pew_w154_diff1 --input-path examples/pew_w154_diff1/context.md ``` Export the imported questions as an EDSL survey serialization: @@ -124,7 +124,7 @@ Import EDSL Results and extract one-shot probability predictions: ```bash zwill prob-results import \ --survey pew_w154_diff1 \ - --path pew_w154_diff1_probability_results.json.gz + --input-path pew_w154_diff1_probability_results.json.gz ``` Compare elicited probabilities to committed respondent marginals: diff --git a/examples/pew_w154_diff1/agent_study_example.sh b/examples/pew_w154_diff1/agent_study_example.sh index e639016..615c92f 100755 --- a/examples/pew_w154_diff1/agent_study_example.sh +++ b/examples/pew_w154_diff1/agent_study_example.sh @@ -55,7 +55,7 @@ run_step 01_agent_list_export \ run_step 02_agent_list_inspect \ zwill_cmd agent-list inspect \ - --path "$AGENT_LIST" \ + --input-path "$AGENT_LIST" \ --format json cp "$OUTDIR/02_agent_list_inspect.stdout.txt" "$AGENT_LIST_INSPECT" @@ -93,13 +93,13 @@ fi run_step 05_edsl_run_leadership \ zwill_cmd edsl-run --job "$MC_JOB" --path "$MC_RESULTS" run_step 06_agent_study_import_leadership \ - zwill_cmd agent-study import --path "$MC_RESULTS" --replace + zwill_cmd agent-study import --input-path "$MC_RESULTS" --replace cp "$OUTDIR/06_agent_study_import_leadership.stdout.txt" "$MC_IMPORT_LOG" run_step 07_edsl_run_gender_roles \ zwill_cmd edsl-run --job "$FT_JOB" --path "$FT_RESULTS" run_step 08_agent_study_import_gender_roles \ - zwill_cmd agent-study import --path "$FT_RESULTS" --replace + zwill_cmd agent-study import --input-path "$FT_RESULTS" --replace cp "$OUTDIR/08_agent_study_import_gender_roles.stdout.txt" "$FT_IMPORT_LOG" run_step 09_agent_study_report \ diff --git a/examples/pew_w154_diff1/agent_study_report.py b/examples/pew_w154_diff1/agent_study_report.py index 5b5bc0b..52fef6c 100755 --- a/examples/pew_w154_diff1/agent_study_report.py +++ b/examples/pew_w154_diff1/agent_study_report.py @@ -30,7 +30,7 @@ { "stem": "02_agent_list_inspect", "title": "Inspect the AgentList", - "command": "zwill agent-list inspect --path pew_w154_diff1_agent_list.edsl.json --format json", + "command": "zwill agent-list inspect --input-path pew_w154_diff1_agent_list.edsl.json --format json", "note": "Checks the number of agents, trait keys, instruction coverage, and a small preview before asking a new question.", }, { @@ -66,7 +66,7 @@ { "stem": "06_agent_study_import_leadership", "title": "Import the multiple-choice Results object", - "command": "zwill agent-study import --path pew_w154_diff1_agent_study_leadership_results.json.gz --replace", + "command": "zwill agent-study import --input-path pew_w154_diff1_agent_study_leadership_results.json.gz --replace", "note": "Stores the raw Results object and extracts one row per agent/model/question answer for reporting.", }, { @@ -78,7 +78,7 @@ { "stem": "08_agent_study_import_gender_roles", "title": "Import the free-text Results object", - "command": "zwill agent-study import --path pew_w154_diff1_agent_study_gender_roles_results.json.gz --replace", + "command": "zwill agent-study import --input-path pew_w154_diff1_agent_study_gender_roles_results.json.gz --replace", "note": "Stores the raw free-text Results object and extracts one row per agent/model/question answer.", }, { diff --git a/examples/pew_w154_diff1/ingest.sh b/examples/pew_w154_diff1/ingest.sh index 550ff60..752a682 100755 --- a/examples/pew_w154_diff1/ingest.sh +++ b/examples/pew_w154_diff1/ingest.sh @@ -19,12 +19,12 @@ cd "$WORKDIR" zwill init zwill survey create --name pew_w154_diff1 -zwill context add --survey pew_w154_diff1 --path "$REPO_ROOT/examples/pew_w154_diff1/context.md" -zwill raw add --survey pew_w154_diff1 --id w154_diff1_metadata --path "$SOURCE_DIR/W154_DIFF1_metadata.json" --kind metadata --title "Pew W154 DIFF1 Normalized Metadata" -zwill raw add --survey pew_w154_diff1 --id w154_diff1_respondents --path "$SOURCE_DIR/W154_DIFF1_respondents.csv" --kind respondent_data --title "Pew W154 DIFF1 Normalized Respondents" -zwill question import --survey pew_w154_diff1 --path "$IMPORT_DIR/questions.jsonl" -zwill respondent import --survey pew_w154_diff1 --path "$IMPORT_DIR/respondents.jsonl" -zwill answer import --survey pew_w154_diff1 --path "$IMPORT_DIR/answers.jsonl" +zwill context add --survey pew_w154_diff1 --input-path "$REPO_ROOT/examples/pew_w154_diff1/context.md" +zwill raw add --survey pew_w154_diff1 --id w154_diff1_metadata --input-path "$SOURCE_DIR/W154_DIFF1_metadata.json" --kind metadata --title "Pew W154 DIFF1 Normalized Metadata" +zwill raw add --survey pew_w154_diff1 --id w154_diff1_respondents --input-path "$SOURCE_DIR/W154_DIFF1_respondents.csv" --kind respondent_data --title "Pew W154 DIFF1 Normalized Respondents" +zwill question import --survey pew_w154_diff1 --input-path "$IMPORT_DIR/questions.jsonl" +zwill respondent import --survey pew_w154_diff1 --input-path "$IMPORT_DIR/respondents.jsonl" +zwill answer import --survey pew_w154_diff1 --input-path "$IMPORT_DIR/answers.jsonl" zwill commit --survey pew_w154_diff1 zwill status zwill table --survey pew_w154_diff1 --limit 12 diff --git a/examples/pew_w154_diff1/twin_building_tutorial.md b/examples/pew_w154_diff1/twin_building_tutorial.md index cc457d8..3ba30d5 100644 --- a/examples/pew_w154_diff1/twin_building_tutorial.md +++ b/examples/pew_w154_diff1/twin_building_tutorial.md @@ -47,7 +47,7 @@ zwill edsl-run \ zwill prob-results import \ --survey "$SURVEY" \ - --path "$OUT/one_shot_prior_results.json.gz" \ + --input-path "$OUT/one_shot_prior_results.json.gz" \ --replace ``` diff --git a/guides/company_digital_twin_evaluation.md b/guides/company_digital_twin_evaluation.md index b5d4d0b..e40ca4b 100644 --- a/guides/company_digital_twin_evaluation.md +++ b/guides/company_digital_twin_evaluation.md @@ -47,7 +47,7 @@ zwill survey create --name customer_validation Import raw files as provenance before converting them into questions, respondents, and answers: ```bash -zwill raw add --survey customer_validation --id source_workbook --path customer_data.xlsx --kind workbook +zwill raw add --survey customer_validation --id source_workbook --input-path customer_data.xlsx --kind workbook ``` For survey data, import: @@ -59,9 +59,9 @@ For survey data, import: Then commit the observed truth marginals: ```bash -zwill question import --survey customer_validation --path questions.jsonl -zwill respondent import --survey customer_validation --path respondents.jsonl -zwill answer import --survey customer_validation --path answers.jsonl +zwill question import --survey customer_validation --input-path questions.jsonl +zwill respondent import --survey customer_validation --input-path respondents.jsonl +zwill answer import --survey customer_validation --input-path answers.jsonl zwill commit --survey customer_validation ``` @@ -120,7 +120,7 @@ zwill edsl-run \ zwill prob-results import \ --survey customer_validation \ - --path one_shot_marginals_results.json.gz + --input-path one_shot_marginals_results.json.gz zwill prob-results report \ --survey customer_validation \ @@ -172,7 +172,7 @@ zwill edsl-run \ zwill twin-results import \ --survey customer_validation \ - --path twin_validation_results.json.gz + --input-path twin_validation_results.json.gz ``` For larger studies, use full respondent sets rather than small samples once the workflow is working. Sampling is useful for debugging, but it can make marginal diagnostics noisy. diff --git a/tests/test_cli_workflows.py b/tests/test_cli_workflows.py index 836aa07..1f7957b 100644 --- a/tests/test_cli_workflows.py +++ b/tests/test_cli_workflows.py @@ -424,7 +424,7 @@ def test_twin_results_retry_malformed_recovers_dropped_rows(tmp_path: Path, monk with gzip.open(results_path, "wt") as f: json.dump(results, f) imported = cli.cmd_twin_results_import( - argparse.Namespace(survey="demo", path=str(results_path), job_id=job_id, replace=False, merge=False, allow_missing_actual=False) + argparse.Namespace(survey="demo", input_path=str(results_path), job_id=job_id, replace=False, merge=False, allow_missing_actual=False) ) assert imported["data"]["extracted_count"] == 1 assert imported["data"]["issue_count"] == 1 @@ -453,7 +453,7 @@ def test_twin_results_retry_malformed_recovers_dropped_rows(tmp_path: Path, monk with gzip.open(retry_results_path, "wt") as f: json.dump(retry_results, f) merged = cli.cmd_twin_results_import( - argparse.Namespace(survey="demo", path=str(retry_results_path), job_id=job_id, replace=False, merge=True, allow_missing_actual=False) + argparse.Namespace(survey="demo", input_path=str(retry_results_path), job_id=job_id, replace=False, merge=True, allow_missing_actual=False) ) assert merged["data"]["issue_count"] == 0 rows = [r for r in cli.read_jsonl(cli.digital_twin_predictions_path(zwill_survey_path(tmp_path))) if r["job_id"] == job_id] @@ -643,8 +643,8 @@ def test_report_catalog_lists_readiness_and_commands(tmp_path: Path, monkeypatch second_path = tmp_path / "second.json" first_path.write_text(json.dumps(first)) second_path.write_text(json.dumps(second)) - run_cli("twin-results", "import", "--survey", "demo", "--path", str(first_path)) - run_cli("twin-results", "import", "--survey", "demo", "--path", str(second_path)) + run_cli("twin-results", "import", "--survey", "demo", "--input-path", str(first_path)) + run_cli("twin-results", "import", "--survey", "demo", "--input-path", str(second_path)) ready_catalog = cli.build_report_catalog("demo") ready_reports = {row["report_id"]: row for row in ready_catalog["reports"]} @@ -795,7 +795,7 @@ def test_practitioner_report_import_concatenates_multiple_sections(tmp_path: Pat with gzip.open(results_path, "wt") as f: json.dump(results, f) - run_cli("twin-benchmark", "practitioner-report-import", "--report-id", "multi-report", "--path", str(results_path)) + run_cli("twin-benchmark", "practitioner-report-import", "--report-id", "multi-report", "--input-path", str(results_path)) markdown = (report_dir / "report.md").read_text() assert "## Section A" in markdown @@ -848,12 +848,12 @@ def test_report_build_creates_incremental_bundle(tmp_path: Path, monkeypatch) -> } probability_path = tmp_path / "probability_results.json" probability_path.write_text(json.dumps(probability_results)) - run_cli("prob-results", "import", "--survey", "demo", "--path", str(probability_path)) + run_cli("prob-results", "import", "--survey", "demo", "--input-path", str(probability_path)) twin_results = json.loads((FIXTURES / "twin_results.json").read_text()) twin_path = tmp_path / "twin_results.json" twin_path.write_text(json.dumps(twin_results)) - run_cli("twin-results", "import", "--survey", "demo", "--path", str(twin_path)) + run_cli("twin-results", "import", "--survey", "demo", "--input-path", str(twin_path)) run_cli( "report", @@ -936,7 +936,7 @@ def test_agent_material_quarantine_blocks_commit_until_resolved(tmp_path: Path, ], ) - cli.cmd_agent_material_import(argparse.Namespace(survey="demo", path=str(path))) + cli.cmd_agent_material_import(argparse.Namespace(survey="demo", input_path=str(path))) try: cli.cmd_commit(argparse.Namespace(survey="demo")) except cli.ZwillError as exc: @@ -988,7 +988,7 @@ def test_agent_material_import_quarantines_invalid_rows_and_normalizes_tags(tmp_ ], ) - result = cli.cmd_agent_material_import(argparse.Namespace(survey="demo", path=str(path))) + result = cli.cmd_agent_material_import(argparse.Namespace(survey="demo", input_path=str(path))) rows = cli.agent_material_rows(zwill_survey_path(tmp_path)) issues = cli.read_jsonl(zwill_survey_path(tmp_path) / "quarantine.jsonl") @@ -1072,7 +1072,7 @@ def test_checkbox_answer_import_validates_each_selection(tmp_path: Path, monkeyp } ], ) - run_cli("question", "import", "--survey", "demo", "--path", str(questions)) + run_cli("question", "import", "--survey", "demo", "--input-path", str(questions)) answers = tmp_path / "answers.jsonl" write_jsonl( answers, @@ -1081,7 +1081,7 @@ def test_checkbox_answer_import_validates_each_selection(tmp_path: Path, monkeyp {"respondent_id": "r2", "question": "q_channels", "answer": "Email|Fax"}, ], ) - result = cli.cmd_answer_import(argparse.Namespace(survey="demo", path=str(answers))) + result = cli.cmd_answer_import(argparse.Namespace(survey="demo", input_path=str(answers))) assert result["data"]["imported_count"] == 1 assert result["data"]["quarantined_count"] == 1 issues = cli.read_jsonl(zwill_survey_path(tmp_path) / "quarantine.jsonl") @@ -1119,8 +1119,8 @@ def test_agent_material_import_duplicate_material_id_replaces_row(tmp_path: Path ], ) - cli.cmd_agent_material_import(argparse.Namespace(survey="demo", path=str(first))) - cli.cmd_agent_material_import(argparse.Namespace(survey="demo", path=str(second))) + cli.cmd_agent_material_import(argparse.Namespace(survey="demo", input_path=str(first))) + cli.cmd_agent_material_import(argparse.Namespace(survey="demo", input_path=str(second))) rows = cli.agent_material_rows(zwill_survey_path(tmp_path)) assert len(rows) == 1 @@ -1147,7 +1147,7 @@ def test_agent_material_cli_path_list_filters_and_show(tmp_path: Path, monkeypat "profile", "--title", "Profile", - "--path", + "--input-path", str(body_path), "--tag", "profile,preference", @@ -1423,7 +1423,7 @@ def test_agent_list_inspect_through_parser_writes_json(tmp_path: Path, monkeypat ) ) - run_cli("agent-list", "inspect", "--path", str(path), "--format", "json") + run_cli("agent-list", "inspect", "--input-path", str(path), "--format", "json") payload = json.loads(capsys.readouterr().out) assert payload["command"] == "zwill agent-list inspect" @@ -1448,7 +1448,7 @@ def test_agent_list_inspect_summarizes_traits_and_instructions(tmp_path: Path, m ) ) - summary = cli.cmd_agent_list_inspect(argparse.Namespace(path=str(path), format="json"))["data"] + summary = cli.cmd_agent_list_inspect(argparse.Namespace(input_path=str(path), format="json"))["data"] assert summary["agent_count"] == 2 assert summary["trait_keys"] == ["q1"] @@ -1467,13 +1467,13 @@ def test_agent_list_inspect_failure_cases_and_empty_list(tmp_path: Path, monkeyp for path in [not_agent_list, bad_agent_list]: try: - cli.cmd_agent_list_inspect(argparse.Namespace(path=str(path), format="json")) + cli.cmd_agent_list_inspect(argparse.Namespace(input_path=str(path), format="json")) except cli.ZwillError as exc: assert exc.code == "invalid_input" else: raise AssertionError(f"Expected invalid_input for {path}") - summary = cli.cmd_agent_list_inspect(argparse.Namespace(path=str(empty_agent_list), format="json"))["data"] + summary = cli.cmd_agent_list_inspect(argparse.Namespace(input_path=str(empty_agent_list), format="json"))["data"] assert summary["agent_count"] == 0 assert summary["trait_keys"] == [] assert summary["sample_agents"] == [] @@ -1831,17 +1831,17 @@ def test_agent_study_import_report_list_show_and_replace(tmp_path: Path, monkeyp with gzip.open(results_path, "wt") as f: json.dump(agent_study_results("agent-job"), f) - import_result = cli.cmd_agent_study_import(argparse.Namespace(path=str(results_path), job_id=None, replace=False)) + import_result = cli.cmd_agent_study_import(argparse.Namespace(input_path=str(results_path), job_id=None, replace=False)) assert import_result["data"]["job_id"] == "agent-job" assert import_result["data"]["extracted_count"] == 1 try: - cli.cmd_agent_study_import(argparse.Namespace(path=str(results_path), job_id=None, replace=False)) + cli.cmd_agent_study_import(argparse.Namespace(input_path=str(results_path), job_id=None, replace=False)) except cli.ZwillError as exc: assert exc.code == "already_exists" else: raise AssertionError("Expected duplicate import to require --replace.") - cli.cmd_agent_study_import(argparse.Namespace(path=str(results_path), job_id=None, replace=True)) + cli.cmd_agent_study_import(argparse.Namespace(input_path=str(results_path), job_id=None, replace=True)) answers = cli.read_jsonl(zwill_project_path(tmp_path) / "agent_studies" / "answers.jsonl") assert len(answers) == 1 @@ -1877,7 +1877,7 @@ def test_agent_study_import_records_malformed_rows_as_issues(tmp_path: Path, mon results_path = tmp_path / "bad_agent_results.json" results_path.write_text(json.dumps({"edsl_class_name": "Results", "zwill": {"agent_study_job_id": "bad"}, "data": [{"answer": {}}]})) - result = cli.cmd_agent_study_import(argparse.Namespace(path=str(results_path), job_id=None, replace=False)) + result = cli.cmd_agent_study_import(argparse.Namespace(input_path=str(results_path), job_id=None, replace=False)) assert result["data"]["extracted_count"] == 0 assert result["data"]["issue_count"] == 1 @@ -2083,7 +2083,7 @@ def _write(name: str, plan: dict) -> Path: return path def _validate(path: Path) -> dict: - return cli.cmd_twin_experiment_validate(argparse.Namespace(path=str(path), survey=None, plan_id=None)) + return cli.cmd_twin_experiment_validate(argparse.Namespace(input_path=str(path), survey=None, plan_id=None)) good = _validate( _write( @@ -2135,7 +2135,7 @@ def test_twin_context_includes_respondent_metadata_by_default(tmp_path: Path, mo create_tiny_binary_survey() md_path = tmp_path / "md.jsonl" write_jsonl(md_path, [{"respondent_id": "r1", "metadata": {"age_group": "35-44", "party": "Independent"}}]) - run_cli("respondent", "import", "--survey", "demo", "--path", str(md_path)) + run_cli("respondent", "import", "--survey", "demo", "--input-path", str(md_path)) monkeypatch.setattr( cli, "load_edsl_job_classes", @@ -2325,7 +2325,7 @@ def test_twin_approach_and_experiment_plan_export_jobs(tmp_path: Path, monkeypat survey="demo", approach_id="baseline", text="Hypothesis: one prior answer should be enough for this toy survey.", - path=None, + input_path=None, clear=False, ) ) @@ -2358,9 +2358,9 @@ def test_twin_approach_and_experiment_plan_export_jobs(tmp_path: Path, monkeypat } ) ) - run_cli("twin-experiment", "approve", "--path", str(plan_path), "--approved-by", "test-user") + run_cli("twin-experiment", "approve", "--input-path", str(plan_path), "--approved-by", "test-user") output_dir = tmp_path / "exports" - run_cli("twin-experiment", "export-plan", "--path", str(plan_path), "--output-dir", str(output_dir)) + run_cli("twin-experiment", "export-plan", "--input-path", str(plan_path), "--output-dir", str(output_dir)) manifest = json.loads((output_dir / "manifest.json").read_text()) assert manifest["kind"] == "twin_experiment_plan_export" @@ -2406,7 +2406,7 @@ def write_note(approach_id: str) -> None: survey="demo", approach_id=approach_id, text=f"Concurrent note for {approach_id}", - path=None, + input_path=None, clear=False, ) ) @@ -2507,7 +2507,7 @@ def test_twin_plan_authoring_helpers(tmp_path: Path, monkeypatch, capsys) -> Non assert plan["approval"]["approved"] is False approval = cli.cmd_twin_experiment_approve( argparse.Namespace( - path=str(plan_path), + input_path=str(plan_path), survey=None, approved_by="reviewer", note="Looks right.", @@ -2591,7 +2591,7 @@ def test_twin_experiment_export_requires_approved_plan(tmp_path: Path, monkeypat with pytest.raises(cli.ZwillError, match="approved"): cli.cmd_twin_experiment_export_plan( - argparse.Namespace(path=str(plan_path), survey=None, output_dir=str(tmp_path / "jobs"), plan_id=None, allow_unapproved=False) + argparse.Namespace(input_path=str(plan_path), survey=None, output_dir=str(tmp_path / "jobs"), plan_id=None, allow_unapproved=False) ) @@ -2622,9 +2622,9 @@ def test_twin_experiment_plan_status_import_and_bundle(tmp_path: Path, monkeypat } ) ) - run_cli("twin-experiment", "approve", "--path", str(plan_path)) + run_cli("twin-experiment", "approve", "--input-path", str(plan_path)) output_dir = tmp_path / "jobs" - run_cli("twin-experiment", "export-plan", "--path", str(plan_path), "--output-dir", str(output_dir)) + run_cli("twin-experiment", "export-plan", "--input-path", str(plan_path), "--output-dir", str(output_dir)) manifest = json.loads((output_dir / "manifest.json").read_text()) status_payload = cli.twin_plan_status_payload(zwill_survey_path(tmp_path), "bundle-plan") assert status_payload["imported_count"] == 0 @@ -2658,7 +2658,7 @@ def test_twin_experiment_plan_status_import_and_bundle(tmp_path: Path, monkeypat survey="demo", plan_id="bundle-plan", text="Compare whether calibrated context improves probability quality.", - path=None, + input_path=None, clear=False, ) ) @@ -2874,7 +2874,7 @@ def test_probability_results_import_and_reports(tmp_path: Path, monkeypatch) -> with gzip.open(results_path, "wt") as f: json.dump(results, f) - run_cli("prob-results", "import", "--survey", "demo", "--path", str(results_path)) + run_cli("prob-results", "import", "--survey", "demo", "--input-path", str(results_path)) predictions = (zwill_survey_path(tmp_path) / "probability_predictions.jsonl").read_text() assert '"yes":0.6' in predictions @@ -2954,7 +2954,7 @@ def fake_build_one_shot_job(args, report_context): with gzip.open(analysis_results_path, "wt") as f: json.dump(analysis_results, f) - run_cli("prob-results", "analysis-import", "--report-id", "one-shot-report-demo", "--path", str(analysis_results_path)) + run_cli("prob-results", "analysis-import", "--report-id", "one-shot-report-demo", "--input-path", str(analysis_results_path)) run_cli("prob-results", "analysis-render", "--report-id", "one-shot-report-demo", "--path", str(generated_html_path)) rendered = generated_html_path.read_text() assert "The one-shot baseline tracks this aggregate split" in rendered @@ -3048,7 +3048,7 @@ def test_twin_results_import_and_reports(tmp_path: Path, monkeypatch) -> None: with gzip.open(results_path, "wt") as f: json.dump(results, f) - run_cli("twin-results", "import", "--survey", "demo", "--path", str(results_path)) + run_cli("twin-results", "import", "--survey", "demo", "--input-path", str(results_path)) predictions = (zwill_survey_path(tmp_path) / "digital_twin_predictions.jsonl").read_text() assert '"probability_actual":0.8' in predictions assert '"marginal_probability_actual":1.0' in predictions @@ -3273,7 +3273,7 @@ def test_rank_battery_uses_joint_rank_twin_workflow(tmp_path: Path, monkeypatch) results_path = tmp_path / "rank_results.json.gz" with gzip.open(results_path, "wt") as f: json.dump(results, f) - run_cli("twin-results", "import", "--survey", "demo", "--path", str(results_path)) + run_cli("twin-results", "import", "--survey", "demo", "--input-path", str(results_path)) rank_rows = cli.read_jsonl(cli.rank_twin_predictions_path(sdir)) assert len(rank_rows) == 2 assert rank_rows[0]["spearman"] == pytest.approx(1.0) @@ -3339,7 +3339,7 @@ def test_twin_results_true_holdout_import_export_and_marginal_diagnostics(tmp_pa } twin_path = tmp_path / "true_holdout_results.json" twin_path.write_text(json.dumps(twin_results)) - run_cli("twin-results", "import", "--survey", "demo", "--path", str(twin_path), "--allow-missing-actual") + run_cli("twin-results", "import", "--survey", "demo", "--input-path", str(twin_path), "--allow-missing-actual") predictions = (zwill_survey_path(tmp_path) / "digital_twin_predictions.jsonl").read_text() assert '"actual_answer":null' in predictions @@ -3370,7 +3370,7 @@ def test_twin_results_true_holdout_import_export_and_marginal_diagnostics(tmp_pa } probability_path = tmp_path / "probability_results.json" probability_path.write_text(json.dumps(probability_results)) - run_cli("prob-results", "import", "--survey", "demo", "--path", str(probability_path)) + run_cli("prob-results", "import", "--survey", "demo", "--input-path", str(probability_path)) summary_path = tmp_path / "marginal_summary.csv" option_path = tmp_path / "marginal_options.csv" @@ -3612,7 +3612,7 @@ def test_twin_results_calibrate_marginal_to_probability_job(tmp_path: Path, monk twin_path = tmp_path / "twin_results.json.gz" with gzip.open(twin_path, "wt") as f: json.dump(twin_results, f) - run_cli("twin-results", "import", "--survey", "demo", "--path", str(twin_path)) + run_cli("twin-results", "import", "--survey", "demo", "--input-path", str(twin_path)) target_results = { "edsl_class_name": "Results", @@ -3632,7 +3632,7 @@ def test_twin_results_calibrate_marginal_to_probability_job(tmp_path: Path, monk target_path = tmp_path / "target_results.json.gz" with gzip.open(target_path, "wt") as f: json.dump(target_results, f) - run_cli("prob-results", "import", "--survey", "demo", "--path", str(target_path)) + run_cli("prob-results", "import", "--survey", "demo", "--input-path", str(target_path)) run_cli( "twin-results", @@ -3742,7 +3742,7 @@ def fake_run(args: argparse.Namespace) -> dict: return {"data": {"results_path": args.path, "digital_twin_job_id": "twin-demo"}} def fake_import(args: argparse.Namespace) -> dict: - calls.append(("import", args.path, args.job_id, args.replace)) + calls.append(("import", args.input_path, args.job_id, args.replace)) return {"data": {"job_id": args.job_id, "extracted_count": 1}} def fake_report(args: argparse.Namespace) -> None: @@ -3898,7 +3898,7 @@ def from_dict(_data): dry_run=False, ) ) - assert result["next_steps"] == [f"zwill twin-results import --survey --path {results_path}"] + assert result["next_steps"] == [f"zwill twin-results import --survey --input-path {results_path}"] def test_edsl_run_agent_study_job_suggests_results_written(tmp_path: Path, monkeypatch) -> None: @@ -3947,7 +3947,7 @@ def from_dict(_data): ) assert result["data"]["agent_study_job_id"] == "agent-study-demo" - assert result["next_steps"] == [f"zwill agent-study import --path {results_path}"] + assert result["next_steps"] == [f"zwill agent-study import --input-path {results_path}"] def test_edsl_run_enforces_approved_validation_count_delta(tmp_path: Path, monkeypatch) -> None: @@ -4059,7 +4059,7 @@ def test_twin_results_fixture_generates_golden_reports(tmp_path: Path, monkeypat monkeypatch.chdir(tmp_path) create_tiny_binary_survey() - run_cli("twin-results", "import", "--survey", "demo", "--path", str(FIXTURES / "twin_results.json")) + run_cli("twin-results", "import", "--survey", "demo", "--input-path", str(FIXTURES / "twin_results.json")) json_path = tmp_path / "fixture_report.json" csv_path = tmp_path / "fixture_report.csv" html_path = tmp_path / "fixture_report.html" @@ -4097,8 +4097,8 @@ def test_twin_study_list_show_and_compare(tmp_path: Path, monkeypatch) -> None: first_path.write_text(json.dumps(first)) second_path.write_text(json.dumps(second)) - run_cli("twin-results", "import", "--survey", "demo", "--path", str(first_path)) - run_cli("twin-results", "import", "--survey", "demo", "--path", str(second_path)) + run_cli("twin-results", "import", "--survey", "demo", "--input-path", str(first_path)) + run_cli("twin-results", "import", "--survey", "demo", "--input-path", str(second_path)) runs = cli.read_twin_run_manifest(zwill_survey_path(tmp_path)) assert {run["job_id"] for run in runs} == {"fixture-twin", "fixture-twin-2"} @@ -4191,8 +4191,8 @@ def test_twin_experiment_records_compares_and_selects_approaches(tmp_path: Path, first_path.write_text(json.dumps(first)) second_path.write_text(json.dumps(second)) - run_cli("twin-results", "import", "--survey", "demo", "--path", str(first_path)) - run_cli("twin-results", "import", "--survey", "demo", "--path", str(second_path)) + run_cli("twin-results", "import", "--survey", "demo", "--input-path", str(first_path)) + run_cli("twin-results", "import", "--survey", "demo", "--input-path", str(second_path)) run_cli( "twin-experiment", "record", @@ -4310,8 +4310,8 @@ def test_twin_experiment_report_export_import_render(tmp_path: Path, monkeypatch second_path = tmp_path / "second.json" first_path.write_text(json.dumps(first)) second_path.write_text(json.dumps(second)) - run_cli("twin-results", "import", "--survey", "demo", "--path", str(first_path)) - run_cli("twin-results", "import", "--survey", "demo", "--path", str(second_path)) + run_cli("twin-results", "import", "--survey", "demo", "--input-path", str(first_path)) + run_cli("twin-results", "import", "--survey", "demo", "--input-path", str(second_path)) job_with_material = tmp_path / "calibrated_job.edsl.json" job_with_material.write_text( json.dumps( @@ -4418,7 +4418,7 @@ def test_twin_experiment_report_export_import_render(tmp_path: Path, monkeypatch } ) ) - run_cli("twin-experiment", "report-import", "--path", str(results_path)) + run_cli("twin-experiment", "report-import", "--input-path", str(results_path)) html_path = tmp_path / "experiment_report.html" run_cli("twin-experiment", "report-render", "--report-id", report_id, "--path", str(html_path)) html = html_path.read_text() @@ -4432,7 +4432,7 @@ def test_twin_experiment_report_export_import_render(tmp_path: Path, monkeypatch def test_twin_benchmark_report_from_config(tmp_path: Path, monkeypatch) -> None: monkeypatch.chdir(tmp_path) create_tiny_binary_survey() - run_cli("twin-results", "import", "--survey", "demo", "--path", str(FIXTURES / "twin_results.json")) + run_cli("twin-results", "import", "--survey", "demo", "--input-path", str(FIXTURES / "twin_results.json")) config = json.loads((FIXTURES / "twin_benchmark.json").read_text()) config_path = tmp_path / "benchmark.json" @@ -4482,7 +4482,7 @@ def fake_generate_practitioner_report(args, payload, studies): def test_twin_benchmark_practitioner_report_export_import_render(tmp_path: Path, monkeypatch) -> None: monkeypatch.chdir(tmp_path) create_tiny_binary_survey() - run_cli("twin-results", "import", "--survey", "demo", "--path", str(FIXTURES / "twin_results.json")) + run_cli("twin-results", "import", "--survey", "demo", "--input-path", str(FIXTURES / "twin_results.json")) config = json.loads((FIXTURES / "twin_benchmark.json").read_text()) config_path = tmp_path / "benchmark.json" @@ -4539,7 +4539,7 @@ def fake_build_report_job(args, payload, studies): with gzip.open(results_path, "wt") as f: json.dump(results, f) - run_cli("twin-benchmark", "practitioner-report-import", "--path", str(results_path)) + run_cli("twin-benchmark", "practitioner-report-import", "--input-path", str(results_path)) assert "# Practitioner Report" in (report_dir / "report.md").read_text() html_path = tmp_path / "rendered.html" @@ -4553,7 +4553,7 @@ def fake_build_report_job(args, payload, studies): def test_twin_study_practitioner_report_export_import_render(tmp_path: Path, monkeypatch) -> None: monkeypatch.chdir(tmp_path) create_tiny_binary_survey() - run_cli("twin-results", "import", "--survey", "demo", "--path", str(FIXTURES / "twin_results.json")) + run_cli("twin-results", "import", "--survey", "demo", "--input-path", str(FIXTURES / "twin_results.json")) def fake_build_report_job(args, payload, studies): assert payload["report_kind"] == "single_survey_twin_validation" @@ -4609,7 +4609,7 @@ def fake_build_report_job(args, payload, studies): with gzip.open(results_path, "wt") as f: json.dump(results, f) - run_cli("twin-study", "practitioner-report-import", "--path", str(results_path)) + run_cli("twin-study", "practitioner-report-import", "--input-path", str(results_path)) html_path = tmp_path / "single_rendered.html" run_cli("twin-study", "practitioner-report-render", "--report-id", "single-report-demo", "--path", str(html_path)) html = html_path.read_text() @@ -4621,7 +4621,7 @@ def fake_build_report_job(args, payload, studies): def test_twin_results_executive_summary_export_import_render(tmp_path: Path, monkeypatch) -> None: monkeypatch.chdir(tmp_path) create_tiny_binary_survey() - run_cli("twin-results", "import", "--survey", "demo", "--path", str(FIXTURES / "twin_results.json")) + run_cli("twin-results", "import", "--survey", "demo", "--input-path", str(FIXTURES / "twin_results.json")) filter_args = argparse.Namespace(survey="demo", job_id=["fixture-twin"], jobs=None, model=None, question=None, questions=None) rows = cli.filtered_twin_prediction_rows(filter_args) diagnostics = cli.build_executive_summary( @@ -4716,7 +4716,7 @@ def fake_build_report_job(args, report_context): with gzip.open(results_path, "wt") as f: json.dump(results, f) - run_cli("twin-results", "executive-summary-import", "--report-id", "exec-report-demo", "--path", str(results_path)) + run_cli("twin-results", "executive-summary-import", "--report-id", "exec-report-demo", "--input-path", str(results_path)) rendered_html = tmp_path / "executive_rendered.html" run_cli("twin-results", "executive-summary-render", "--report-id", "exec-report-demo", "--path", str(rendered_html)) html = rendered_html.read_text() @@ -4844,7 +4844,7 @@ def test_twin_results_import_records_malformed_row_issues(tmp_path: Path, monkey results_path = tmp_path / "bad_twin_results.json" results_path.write_text(json.dumps(results)) - result = cli.cmd_twin_results_import(argparse.Namespace(survey="demo", path=str(results_path), job_id=None, replace=False)) + result = cli.cmd_twin_results_import(argparse.Namespace(survey="demo", input_path=str(results_path), job_id=None, replace=False)) assert result["data"]["extracted_count"] == 1 assert result["data"]["issue_count"] == 3 diff --git a/tests/test_guide_and_next.py b/tests/test_guide_and_next.py index 1dce6d7..b98f20b 100644 --- a/tests/test_guide_and_next.py +++ b/tests/test_guide_and_next.py @@ -80,9 +80,9 @@ def test_next_walks_the_pipeline(tmp_path, monkeypatch) -> None: [{"respondent_id": f"r{i}", "question": q, "answer": "a" if i % 2 else "b"} for i in range(4) for q in ("q1", "q2")], ) - assert main(["question", "import", "--survey", "demo", "--path", str(tmp_path / "q.jsonl")]) == 0 - assert main(["respondent", "import", "--survey", "demo", "--path", str(tmp_path / "r.jsonl")]) == 0 - assert main(["answer", "import", "--survey", "demo", "--path", str(tmp_path / "a.jsonl")]) == 0 + assert main(["question", "import", "--survey", "demo", "--input-path", str(tmp_path / "q.jsonl")]) == 0 + assert main(["respondent", "import", "--survey", "demo", "--input-path", str(tmp_path / "r.jsonl")]) == 0 + assert main(["answer", "import", "--survey", "demo", "--input-path", str(tmp_path / "a.jsonl")]) == 0 assert _stage() == "commit" assert main(["commit", "--survey", "demo"]) == 0 diff --git a/tests/test_twin_baseline.py b/tests/test_twin_baseline.py index ea6dd20..3ddff5b 100644 --- a/tests/test_twin_baseline.py +++ b/tests/test_twin_baseline.py @@ -218,9 +218,9 @@ def test_twin_baseline_cli_stores_predictions_and_flows_through_report(tmp_path, assert main(["init"]) == 0 assert main(["survey", "create", "--name", "demo"]) == 0 - assert main(["question", "import", "--survey", "demo", "--path", str(tmp_path / "questions.jsonl")]) == 0 - assert main(["respondent", "import", "--survey", "demo", "--path", str(tmp_path / "respondents.jsonl")]) == 0 - assert main(["answer", "import", "--survey", "demo", "--path", str(tmp_path / "answers.jsonl")]) == 0 + assert main(["question", "import", "--survey", "demo", "--input-path", str(tmp_path / "questions.jsonl")]) == 0 + assert main(["respondent", "import", "--survey", "demo", "--input-path", str(tmp_path / "respondents.jsonl")]) == 0 + assert main(["answer", "import", "--survey", "demo", "--input-path", str(tmp_path / "answers.jsonl")]) == 0 assert main(["commit", "--survey", "demo"]) == 0 args = argparse.Namespace( diff --git a/tests/test_twin_validate.py b/tests/test_twin_validate.py index 58a72c5..b57f8c9 100644 --- a/tests/test_twin_validate.py +++ b/tests/test_twin_validate.py @@ -106,9 +106,9 @@ def _build_survey(tmp_path: Path) -> tuple[dict, list[str]]: ) assert main(["init"]) == 0 assert main(["survey", "create", "--name", "demo"]) == 0 - assert main(["question", "import", "--survey", "demo", "--path", str(tmp_path / "questions.jsonl")]) == 0 - assert main(["respondent", "import", "--survey", "demo", "--path", str(tmp_path / "respondents.jsonl")]) == 0 - assert main(["answer", "import", "--survey", "demo", "--path", str(tmp_path / "answers.jsonl")]) == 0 + assert main(["question", "import", "--survey", "demo", "--input-path", str(tmp_path / "questions.jsonl")]) == 0 + assert main(["respondent", "import", "--survey", "demo", "--input-path", str(tmp_path / "respondents.jsonl")]) == 0 + assert main(["answer", "import", "--survey", "demo", "--input-path", str(tmp_path / "answers.jsonl")]) == 0 assert main(["commit", "--survey", "demo"]) == 0 return answers, options diff --git a/zwill/agent_studies.py b/zwill/agent_studies.py index d07dc6d..6f7387f 100644 --- a/zwill/agent_studies.py +++ b/zwill/agent_studies.py @@ -37,9 +37,9 @@ def agent_study_import_metadata(job_id: str) -> dict[str, Any]: def cmd_agent_study_import(args: argparse.Namespace) -> dict[str, Any]: require_project() - source = Path(args.path) + source = Path(args.input_path) if not source.exists(): - raise ZwillError("not_found", f"Results file does not exist: {args.path}.") + raise ZwillError("not_found", f"Results file does not exist: {args.input_path}.") results = read_json_or_gzip(source) if not isinstance(results, dict) or results.get("edsl_class_name") != "Results": raise ZwillError("invalid_input", "Expected an EDSL Results serialization.") diff --git a/zwill/cli.py b/zwill/cli.py index 8321460..4aa66ab 100644 --- a/zwill/cli.py +++ b/zwill/cli.py @@ -779,7 +779,7 @@ def cmd_survey_create(args: argparse.Namespace) -> dict[str, Any]: "ok", {"survey": existing}, next_steps=[ - f"zwill raw add --survey {args.name} --id --path ", + f"zwill raw add --survey {args.name} --id --input-path ", f"zwill question add --survey {args.name} ...", ], ) diff --git a/zwill/cli_parser.py b/zwill/cli_parser.py index 44ea7bd..a9ce068 100644 --- a/zwill/cli_parser.py +++ b/zwill/cli_parser.py @@ -191,7 +191,7 @@ def add_report_build_args(parser: argparse.ArgumentParser) -> None: agent_list = subparsers.add_parser("agent-list").add_subparsers(dest="agent_list_command", required=True) p = agent_list.add_parser("inspect", help="Inspect an exported EDSL AgentList JSON file.") - p.add_argument("--path", required=True, help="Path to an EDSL AgentList JSON file.") + p.add_argument("--input-path", required=True, help="Path to an EDSL AgentList JSON file.") p.add_argument("--format", choices=["table", "json"], default="table") p.set_defaults(func=cmd_agent_list_inspect, table_output=True) @@ -212,7 +212,7 @@ def add_report_build_args(parser: argparse.ArgumentParser) -> None: p.add_argument("--quiet", action="store_true", help="Suppress stdout (the job is still written to --path). Useful when scripting.") p.set_defaults(func=cmd_agent_study_export, raw_output=True) p = agent_study.add_parser("import", help="Import serialized EDSL Results from an agent-study job.") - p.add_argument("--path", required=True) + p.add_argument("--input-path", required=True) p.add_argument("--job-id", help="Override the agent-study job id.") p.add_argument("--replace", action="store_true", help="Replace an existing imported result set with the same job id.") p.set_defaults(func=cmd_agent_study_import) @@ -292,7 +292,7 @@ def add_report_build_args(parser: argparse.ArgumentParser) -> None: prob_results = subparsers.add_parser("prob-results").add_subparsers(dest="prob_results_command", required=True) p = prob_results.add_parser("import") p.add_argument("--survey", required=True) - p.add_argument("--path", required=True) + p.add_argument("--input-path", required=True) p.add_argument("--job-id") p.add_argument("--replace", action="store_true") p.set_defaults(func=cmd_probability_results_import) @@ -300,7 +300,7 @@ def add_report_build_args(parser: argparse.ArgumentParser) -> None: numeric_results = subparsers.add_parser("numeric-results").add_subparsers(dest="numeric_results_command", required=True) p = numeric_results.add_parser("import", help="Import and score continuous (quantile) twin predictions.") p.add_argument("--survey", required=True) - p.add_argument("--path", required=True) + p.add_argument("--input-path", required=True) p.add_argument("--job-id") p.add_argument("--replace", action="store_true") p.set_defaults(func=cmd_numeric_results_import) @@ -314,12 +314,12 @@ def add_report_build_args(parser: argparse.ArgumentParser) -> None: open_coding = subparsers.add_parser("open-coding").add_subparsers(dest="open_coding_command", required=True) p = open_coding.add_parser("codebook-import", help="Store a derived codebook of themes for a free_text question.") p.add_argument("--survey", required=True) - p.add_argument("--path", required=True, help="EDSL Results file from an open-codebook-job run.") + p.add_argument("--input-path", required=True, help="EDSL Results file from an open-codebook-job run.") p.add_argument("--question", help="Source free_text question (defaults to the one recorded in the results).") p.set_defaults(func=cmd_open_codebook_import) p = open_coding.add_parser("import", help="Create a coded multiple_choice question from an open-coding-job run.") p.add_argument("--survey", required=True) - p.add_argument("--path", required=True, help="EDSL Results file from an open-coding-job run.") + p.add_argument("--input-path", required=True, help="EDSL Results file from an open-coding-job run.") p.add_argument("--question", help="Source free_text question (defaults to the one recorded in the results).") p.add_argument("--coded-question-name", help="Name for the coded question (default _coded).") p.add_argument("--replace", action="store_true", help="Overwrite an existing coded question and its answers.") @@ -350,7 +350,7 @@ def add_report_build_args(parser: argparse.ArgumentParser) -> None: ) p.set_defaults(func=cmd_probability_results_analysis_export) p = prob_results.add_parser("analysis-import", help="Import EDSL Results from a one-shot analysis report-generation job.") - p.add_argument("--path", required=True, help="Serialized EDSL Results JSON or JSON.GZ.") + p.add_argument("--input-path", required=True, help="Serialized EDSL Results JSON or JSON.GZ.") p.add_argument("--report-id", help="Report id. Inferred from Results metadata when present.") p.add_argument("--replace", action="store_true", help="Replace an existing imported report result.") p.set_defaults(func=cmd_probability_results_analysis_import) @@ -407,7 +407,7 @@ def add_report_build_args(parser: argparse.ArgumentParser) -> None: twin_results = subparsers.add_parser("twin-results").add_subparsers(dest="twin_results_command", required=True) p = twin_results.add_parser("import") p.add_argument("--survey", required=True) - p.add_argument("--path", required=True) + p.add_argument("--input-path", required=True) p.add_argument("--job-id") p.add_argument("--replace", action="store_true") p.add_argument("--merge", action="store_true", help="Upsert rows into an existing job (by respondent/held-out/model) instead of replacing it. Use to re-import recovered rows from twin-results retry-malformed without losing the rows that already scored.") @@ -528,7 +528,7 @@ def add_report_build_args(parser: argparse.ArgumentParser) -> None: ) p.set_defaults(func=cmd_twin_results_executive_summary_export) p = twin_results.add_parser("executive-summary-import", help="Import EDSL Results from an executive summary report-generation job.") - p.add_argument("--path", required=True, help="Serialized EDSL Results JSON or JSON.GZ.") + p.add_argument("--input-path", required=True, help="Serialized EDSL Results JSON or JSON.GZ.") p.add_argument("--report-id", help="Executive report id. Inferred from Results metadata when present.") p.add_argument("--replace", action="store_true", help="Replace an existing imported report result.") p.set_defaults(func=cmd_twin_results_executive_summary_import) @@ -744,7 +744,7 @@ def add_report_build_args(parser: argparse.ArgumentParser) -> None: ) p.set_defaults(func=cmd_twin_study_practitioner_report_export) p = twin_study.add_parser("practitioner-report-import", help="Import EDSL Results from a one-survey practitioner report job.") - p.add_argument("--path", required=True, help="Serialized EDSL Results JSON or JSON.GZ.") + p.add_argument("--input-path", required=True, help="Serialized EDSL Results JSON or JSON.GZ.") p.add_argument("--report-id", help="Practitioner report id. Inferred from Results metadata when present.") p.add_argument("--replace", action="store_true", help="Replace an existing imported report result.") p.set_defaults(func=cmd_twin_study_practitioner_report_import) @@ -756,7 +756,7 @@ def add_report_build_args(parser: argparse.ArgumentParser) -> None: twin_approach = subparsers.add_parser("twin-approach").add_subparsers(dest="twin_approach_command", required=True) p = twin_approach.add_parser("add", help="Add or update a reusable digital twin construction approach.") p.add_argument("--survey", required=True) - p.add_argument("--path", help="JSON/YAML approach definition. If provided, inline flags are ignored.") + p.add_argument("--input-path", help="JSON/YAML approach definition. If provided, inline flags are ignored.") p.add_argument("--approach-id") p.add_argument("--name") description_group = p.add_mutually_exclusive_group() @@ -801,7 +801,7 @@ def add_report_build_args(parser: argparse.ArgumentParser) -> None: p.add_argument("--approach-id", required=True) note_group = p.add_mutually_exclusive_group() note_group.add_argument("--text", help="Markdown note text.") - note_group.add_argument("--path", help="Path to a Markdown note file.") + note_group.add_argument("--input-path", help="Path to a Markdown note file.") note_group.add_argument("--clear", action="store_true", help="Clear the note.") p.set_defaults(func=cmd_twin_approach_note) p = twin_approach.add_parser("scaffold", help="Write a starter JSON approach definition.") @@ -871,7 +871,7 @@ def add_report_build_args(parser: argparse.ArgumentParser) -> None: p.add_argument("--primary-metric", choices=sorted(TWIN_EXPERIMENT_METRICS), default="nll") p.set_defaults(func=cmd_twin_experiment_init_plan) p = twin_experiment.add_parser("approve", help="Mark a reviewed twin experiment plan as approved for export/run.") - p.add_argument("--path", required=True, help="JSON/YAML experiment plan.") + p.add_argument("--input-path", required=True, help="JSON/YAML experiment plan.") p.add_argument("--survey", help="Override or validate the survey in the plan.") p.add_argument("--approved-by", help="Name or identifier of the approving user. Defaults to user.") p.add_argument("--note", help="Approval note to preserve in plan provenance.") @@ -879,7 +879,7 @@ def add_report_build_args(parser: argparse.ArgumentParser) -> None: p.add_argument("--estimated-time", help="Optional estimated runtime note.") p.set_defaults(func=cmd_twin_experiment_approve) p = twin_experiment.add_parser("export-plan", help="Export EDSL jobs from a reusable twin experiment plan.") - p.add_argument("--path", required=True, help="JSON/YAML experiment plan.") + p.add_argument("--input-path", required=True, help="JSON/YAML experiment plan.") p.add_argument("--survey", help="Override survey in the plan.") p.add_argument("--output-dir", help="Directory to write job files and manifest.") p.add_argument("--plan-id", help="Override the plan id.") @@ -888,7 +888,7 @@ def add_report_build_args(parser: argparse.ArgumentParser) -> None: p = twin_experiment.add_parser( "validate", help="Lint a plan file (resolve questions/models/counts) before approve/export." ) - p.add_argument("--path", required=True, help="JSON/YAML experiment plan.") + p.add_argument("--input-path", required=True, help="JSON/YAML experiment plan.") p.add_argument("--survey", help="Override survey in the plan.") p.add_argument("--plan-id", help="Override the plan id.") p.set_defaults(func=cmd_twin_experiment_validate) @@ -902,7 +902,7 @@ def add_report_build_args(parser: argparse.ArgumentParser) -> None: p.add_argument("--plan-id", required=True) note_group = p.add_mutually_exclusive_group() note_group.add_argument("--text", help="Markdown note text.") - note_group.add_argument("--path", help="Path to a Markdown note file.") + note_group.add_argument("--input-path", help="Path to a Markdown note file.") note_group.add_argument("--clear", action="store_true", help="Clear the note.") p.set_defaults(func=cmd_twin_experiment_note) p = twin_experiment.add_parser("import-plan-results", help="Import Results files that match jobs in a plan manifest.") @@ -1017,7 +1017,7 @@ def add_report_build_args(parser: argparse.ArgumentParser) -> None: p.add_argument("--service-name", default="openai", help="EDSL service_name for unqualified report-generation models.") p.set_defaults(func=cmd_twin_experiment_report_export) p = twin_experiment.add_parser("report-import", help="Import EDSL Results from a twin-experiment report job.") - p.add_argument("--path", required=True, help="Serialized EDSL Results JSON or JSON.GZ.") + p.add_argument("--input-path", required=True, help="Serialized EDSL Results JSON or JSON.GZ.") p.add_argument("--report-id", help="Report id. Inferred from Results metadata when present.") p.add_argument("--replace", action="store_true", help="Replace an existing imported report result.") p.set_defaults(func=cmd_twin_experiment_report_import) @@ -1079,7 +1079,7 @@ def add_report_build_args(parser: argparse.ArgumentParser) -> None: ) p.set_defaults(func=cmd_twin_benchmark_practitioner_report_export) p = twin_benchmark.add_parser("practitioner-report-import", help="Import EDSL Results from a practitioner report job.") - p.add_argument("--path", required=True, help="Serialized EDSL Results JSON or JSON.GZ.") + p.add_argument("--input-path", required=True, help="Serialized EDSL Results JSON or JSON.GZ.") p.add_argument("--report-id", help="Practitioner report id. Inferred from Results metadata when present.") p.add_argument("--replace", action="store_true", help="Replace an existing imported report result.") p.set_defaults(func=cmd_twin_benchmark_practitioner_report_import) @@ -1123,7 +1123,7 @@ def add_report_build_args(parser: argparse.ArgumentParser) -> None: p = context.add_parser(command_name) p.add_argument("--survey", required=True) group = p.add_mutually_exclusive_group(required=True) - group.add_argument("--path") + group.add_argument("--input-path") group.add_argument("--text") p.set_defaults(func=func) p = context.add_parser("show") @@ -1147,7 +1147,7 @@ def add_report_build_args(parser: argparse.ArgumentParser) -> None: p = raw.add_parser("add") p.add_argument("--survey", required=True) p.add_argument("--id", required=True) - p.add_argument("--path", required=True) + p.add_argument("--input-path", required=True) p.add_argument("--kind", required=True) p.add_argument("--title", required=True) p.set_defaults(func=cmd_raw_add) @@ -1175,7 +1175,7 @@ def add_report_build_args(parser: argparse.ArgumentParser) -> None: description="Import questions from a JSONL file. Each row needs at least question_name, question_type, and question_text; multiple_choice questions also need question_options. Full schema: `zwill guide show import-format`.", ) p.add_argument("--survey", required=True) - p.add_argument("--path", required=True, help="JSONL file, one question object per line.") + p.add_argument("--input-path", required=True, help="JSONL file, one question object per line.") p.set_defaults(func=cmd_question_import) respondent = subparsers.add_parser("respondent").add_subparsers(dest="respondent_command", required=True) @@ -1193,7 +1193,7 @@ def add_report_build_args(parser: argparse.ArgumentParser) -> None: description="Import respondents from a JSONL file. Each row needs respondent_id; weight/metadata/source are optional. Answer import auto-creates unseen respondents. Full schema: `zwill guide show import-format`.", ) p.add_argument("--survey", required=True) - p.add_argument("--path", required=True, help="JSONL file, one respondent object per line.") + p.add_argument("--input-path", required=True, help="JSONL file, one respondent object per line.") p.set_defaults(func=cmd_respondent_import) agent_material = subparsers.add_parser("agent-material").add_subparsers(dest="agent_material_command", required=True) @@ -1204,7 +1204,7 @@ def add_report_build_args(parser: argparse.ArgumentParser) -> None: p.add_argument("--kind", required=True) p.add_argument("--title", required=True) group = p.add_mutually_exclusive_group(required=True) - group.add_argument("--path") + group.add_argument("--input-path") group.add_argument("--text") p.add_argument("--tag", action="append", help="Tag for this material. Repeatable or comma-separated.") p.add_argument("--include-by-default", action="store_true") @@ -1213,7 +1213,7 @@ def add_report_build_args(parser: argparse.ArgumentParser) -> None: p.set_defaults(func=cmd_agent_material_add) p = agent_material.add_parser("import") p.add_argument("--survey", required=True) - p.add_argument("--path", required=True) + p.add_argument("--input-path", required=True) p.set_defaults(func=cmd_agent_material_import) p = agent_material.add_parser("list") p.add_argument("--survey", required=True) @@ -1241,7 +1241,7 @@ def add_report_build_args(parser: argparse.ArgumentParser) -> None: description="Import answers from a JSONL file. Each row needs respondent_id, question, and either answer or missing_code. When the question has question_options, answer must be one of them or the row is quarantined. Full schema: `zwill guide show import-format`.", ) p.add_argument("--survey", required=True) - p.add_argument("--path", required=True, help="JSONL file, one answer object per line.") + p.add_argument("--input-path", required=True, help="JSONL file, one answer object per line.") p.set_defaults(func=cmd_answer_import) quarantine = subparsers.add_parser("quarantine").add_subparsers(dest="quarantine_command", required=True) diff --git a/zwill/edsl_integration.py b/zwill/edsl_integration.py index ba47a04..3ada617 100644 --- a/zwill/edsl_integration.py +++ b/zwill/edsl_integration.py @@ -582,7 +582,7 @@ def inspect_agent_list_dict(data: dict[str, Any]) -> dict[str, Any]: def cmd_agent_list_inspect(args: argparse.Namespace) -> dict[str, Any]: - data = read_json_or_gzip(Path(args.path)) + data = read_json_or_gzip(Path(args.input_path)) summary = inspect_agent_list_dict(data) if args.format == "json": print_json(envelope("zwill agent-list inspect", "ok", summary)) @@ -1185,17 +1185,17 @@ def cmd_edsl_run(args: argparse.Namespace) -> dict[str, Any]: }, next_steps=[ ( - f"zwill twin-benchmark practitioner-report-import --path {output_path}" + f"zwill twin-benchmark practitioner-report-import --input-path {output_path}" if results_dict.get("zwill", {}).get("practitioner_report_id") - else f"zwill twin-results import --survey --path {output_path}" + else f"zwill twin-results import --survey --input-path {output_path}" if results_dict.get("zwill", {}).get("digital_twin_job_id") - else f"zwill twin-results import --survey --path {output_path}" + else f"zwill twin-results import --survey --input-path {output_path}" if results_dict.get("zwill", {}).get("rank_utility_twin_job_id") - else f"zwill prob-results import --survey --path {output_path}" + else f"zwill prob-results import --survey --input-path {output_path}" if results_dict.get("zwill", {}).get("probability_job_id") - else f"zwill agent-study import --path {output_path}" + else f"zwill agent-study import --input-path {output_path}" if results_dict.get("zwill", {}).get("agent_study_job_id") - else f"zwill prob-results import --survey --path {output_path}" + else f"zwill prob-results import --survey --input-path {output_path}" ) ], ) diff --git a/zwill/guide_commands.py b/zwill/guide_commands.py index 5d207af..203a5a5 100644 --- a/zwill/guide_commands.py +++ b/zwill/guide_commands.py @@ -131,7 +131,7 @@ def _stage_for_survey(survey: str) -> dict[str, Any]: "stage": "import_data", "why": f"Survey '{survey}' has no imported questions/answers yet.", "next_command": ( - f"zwill question import --survey {survey} --path questions.jsonl " + f"zwill question import --survey {survey} --input-path questions.jsonl " f"# then respondent import + answer import" ), } diff --git a/zwill/guides/agent-workflow.md b/zwill/guides/agent-workflow.md index 6641426..29ceb86 100644 --- a/zwill/guides/agent-workflow.md +++ b/zwill/guides/agent-workflow.md @@ -102,7 +102,7 @@ next command. The full path: zwill edsl-export --survey --target probability-job \ --questions --model --path one_shot.edsl.json zwill edsl-run --job one_shot.edsl.json --path one_shot_results.json.gz - zwill prob-results import --survey --path one_shot_results.json.gz + zwill prob-results import --survey --input-path one_shot_results.json.gz zwill prob-results report --survey --job-id \ --format html --path one-shot-marginals.html ``` @@ -111,7 +111,7 @@ next command. The full path: zwill prob-results analysis-export --survey --job-id \ --path report_out/one-shot-marginals.html zwill edsl-run --job --path - zwill prob-results analysis-import --report-id --path + zwill prob-results analysis-import --report-id --input-path zwill prob-results analysis-render --report-id --path report_out/one-shot-marginals.html ``` 8. **Run the twin jobs** — pick 5–10 held-out questions spanning different use @@ -125,7 +125,7 @@ next command. The full path: --allow-unapproved \ --path twin.edsl.json zwill edsl-run --job twin.edsl.json --path twin_results.json.gz - zwill twin-results import --survey --path twin_results.json.gz + zwill twin-results import --survey --input-path twin_results.json.gz ``` Respondent metadata (panel covariates like age/party/region) is included as twin context **by default** — rendered as a "Respondent profile" block — for @@ -151,7 +151,7 @@ next command. The full path: ```bash zwill twin-results retry-malformed --survey --job-id --job twin.edsl.json zwill edsl-run --job --path - zwill twin-results import --survey --job-id --merge --path + zwill twin-results import --survey --job-id --merge --input-path ``` For validation runs beyond one-off debugging, prefer `twin-experiment` plans: the plan must specify held-out targets, all eligible questions considered, @@ -209,7 +209,7 @@ Validate them separately: zwill edsl-export --survey --target rank-utility-twin-job \ --rank-task-id --allow-unapproved --path rank.edsl.json zwill edsl-run --job rank.edsl.json --path rank_results.json.gz -zwill twin-results import --survey --path rank_results.json.gz +zwill twin-results import --survey --input-path rank_results.json.gz zwill twin-results rank-report --survey --rank-task-id \ --format html --path report_out/rank-.html ``` @@ -230,7 +230,7 @@ quantile climatology baseline: zwill edsl-export --survey --target numeric-twin-job \ --heldout-question --allow-unapproved --path numeric.edsl.json zwill edsl-run --job numeric.edsl.json --path numeric_results.json.gz -zwill numeric-results import --survey --path numeric_results.json.gz +zwill numeric-results import --survey --input-path numeric_results.json.gz zwill numeric-results report --survey --job-id \ --format html --path report_out/numeric.html ``` @@ -249,13 +249,13 @@ export → run → import cycles: zwill edsl-export --survey --target open-codebook-job \ --heldout-question --n-themes 8 --model openai:gpt-5.5 --path cb.json zwill edsl-run --job cb.json --path cb_results.json.gz -zwill open-coding codebook-import --survey --path cb_results.json.gz +zwill open-coding codebook-import --survey --input-path cb_results.json.gz # 2. Code every respondent's answer into one theme -> new multiple_choice question zwill edsl-export --survey --target open-coding-job \ --heldout-question --model openai:gpt-5.5 --path coding.json zwill edsl-run --job coding.json --path coding_results.json.gz -zwill open-coding import --survey --path coding_results.json.gz \ +zwill open-coding import --survey --input-path coding_results.json.gz \ --coded-question-name _coded ``` diff --git a/zwill/guides/import-format.md b/zwill/guides/import-format.md index 77ebccb..a875022 100644 --- a/zwill/guides/import-format.md +++ b/zwill/guides/import-format.md @@ -1,12 +1,12 @@ # Import file formats (questions / respondents / answers) `zwill question import`, `zwill respondent import`, and `zwill answer import` each -read a JSONL file (one JSON object per line) passed with `--path`. Every row is +read a JSONL file (one JSON object per line) passed with `--input-path`. Every row is stored keyed by its id (`question_name` / `respondent_id`), so re-importing a row with the same id overwrites the previous one. Extra fields you include are preserved verbatim; the fields below are the ones zwill reads. -## questions.jsonl — `zwill question import --survey --path questions.jsonl` +## questions.jsonl — `zwill question import --survey --input-path questions.jsonl` One row per question. @@ -34,7 +34,7 @@ Example row: {"question_name": "q3_seniority", "question_type": "multiple_choice", "question_text": "What is your seniority level?", "question_options": ["Junior", "Mid", "Senior", "Executive"], "role": "demographic", "source": {"raw_id": "smb_workbook", "note": "Q3"}} ``` -## respondents.jsonl — `zwill respondent import --survey --path respondents.jsonl` +## respondents.jsonl — `zwill respondent import --survey --input-path respondents.jsonl` One row per respondent. @@ -55,7 +55,7 @@ Example row: {"respondent_id": "R017", "weight": 1.0, "metadata": {"region": "US"}, "source": {"raw_id": "smb_workbook"}} ``` -## answers.jsonl — `zwill answer import --survey --path answers.jsonl` +## answers.jsonl — `zwill answer import --survey --input-path answers.jsonl` One row per (respondent, question) cell. diff --git a/zwill/guides/prompt-pipelines.md b/zwill/guides/prompt-pipelines.md index 50f835f..44ddf8a 100644 --- a/zwill/guides/prompt-pipelines.md +++ b/zwill/guides/prompt-pipelines.md @@ -65,7 +65,7 @@ zwill edsl-export --survey --target twin-probability-job \ --twin-prompt-pipeline examples/twin_pipelines/dialectical.json \ --model openai:gpt-5.5 --path twin.edsl.json zwill edsl-run --job twin.edsl.json --path twin_results.json.gz -zwill twin-results import --survey --path twin_results.json.gz +zwill twin-results import --survey --input-path twin_results.json.gz ``` `--twin-prompt-pipeline` overrides `--prompt-variant`. The import scores the final diff --git a/zwill/guides/rank.md b/zwill/guides/rank.md index d17688d..54cfb68 100644 --- a/zwill/guides/rank.md +++ b/zwill/guides/rank.md @@ -57,7 +57,7 @@ scores and compares them to the respondent's actual ranking: zwill edsl-export --survey --target rank-utility-twin-job \ --rank-task-id --allow-unapproved --path rank.edsl.json zwill edsl-run --job rank.edsl.json --path rank_results.json.gz -zwill twin-results import --survey --path rank_results.json.gz +zwill twin-results import --survey --input-path rank_results.json.gz zwill twin-results rank-report --survey --rank-task-id \ --format html --path report_out/rank-.html ``` @@ -75,7 +75,7 @@ you must pass **`--allow-missing-actual` to BOTH the export and the import**: ```bash zwill edsl-export ... --target rank-utility-twin-job --rank-task-id \ --allow-unapproved --allow-missing-actual --path rank.edsl.json -zwill twin-results import --survey --path rank_results.json.gz --allow-missing-actual +zwill twin-results import --survey --input-path rank_results.json.gz --allow-missing-actual ``` Without the flag on import, every partial-ranking row is dropped as diff --git a/zwill/numeric_commands.py b/zwill/numeric_commands.py index ce22af8..884a8de 100644 --- a/zwill/numeric_commands.py +++ b/zwill/numeric_commands.py @@ -150,9 +150,9 @@ def summarize_numeric_predictions(rows: list[dict[str, Any]], *, n_boot: int = 5 def cmd_numeric_results_import(args: argparse.Namespace) -> dict[str, Any]: sdir = require_survey(args.survey) - source = Path(args.path) + source = Path(args.input_path) if not source.exists(): - raise ZwillError("not_found", f"Results file does not exist: {args.path}.") + raise ZwillError("not_found", f"Results file does not exist: {args.input_path}.") results = read_json_or_gzip(source) if not isinstance(results, dict) or results.get("edsl_class_name") != "Results": raise ZwillError("invalid_input", "Expected an EDSL Results serialization.") diff --git a/zwill/open_ends_commands.py b/zwill/open_ends_commands.py index 25041ed..8090b37 100644 --- a/zwill/open_ends_commands.py +++ b/zwill/open_ends_commands.py @@ -36,9 +36,9 @@ def _raw_answer(row: dict[str, Any]) -> Any: def cmd_open_codebook_import(args: argparse.Namespace) -> dict[str, Any]: sdir = require_survey(args.survey) - source = Path(args.path) + source = Path(args.input_path) if not source.exists(): - raise ZwillError("not_found", f"Results file does not exist: {args.path}.") + raise ZwillError("not_found", f"Results file does not exist: {args.input_path}.") results = read_json_or_gzip(source) if not isinstance(results, dict) or results.get("edsl_class_name") != "Results": raise ZwillError("invalid_input", "Expected an EDSL Results serialization.") @@ -80,9 +80,9 @@ def cmd_open_codebook_import(args: argparse.Namespace) -> dict[str, Any]: def cmd_open_coding_import(args: argparse.Namespace) -> dict[str, Any]: sdir = require_survey(args.survey) - source = Path(args.path) + source = Path(args.input_path) if not source.exists(): - raise ZwillError("not_found", f"Results file does not exist: {args.path}.") + raise ZwillError("not_found", f"Results file does not exist: {args.input_path}.") results = read_json_or_gzip(source) if not isinstance(results, dict) or results.get("edsl_class_name") != "Results": raise ZwillError("invalid_input", "Expected an EDSL Results serialization.") diff --git a/zwill/practitioner_reports.py b/zwill/practitioner_reports.py index 9aa87d9..c400755 100644 --- a/zwill/practitioner_reports.py +++ b/zwill/practitioner_reports.py @@ -574,7 +574,7 @@ def cmd_twin_benchmark_practitioner_report_export(args: argparse.Namespace) -> d data, next_steps=[ f"zwill edsl-run --job {data['job_path']} --path {default_practitioner_report_paths(report_id)['dir'] / 'results.json.gz'}", - f"zwill twin-benchmark practitioner-report-import --report-id {report_id} --path {default_practitioner_report_paths(report_id)['dir'] / 'results.json.gz'}", + f"zwill twin-benchmark practitioner-report-import --report-id {report_id} --input-path {default_practitioner_report_paths(report_id)['dir'] / 'results.json.gz'}", f"zwill twin-benchmark practitioner-report-render --report-id {report_id}", ], ) @@ -600,16 +600,16 @@ def cmd_twin_study_practitioner_report_export(args: argparse.Namespace) -> dict[ data, next_steps=[ f"zwill edsl-run --job {data['job_path']} --path {default_practitioner_report_paths(report_id)['dir'] / 'results.json.gz'}", - f"zwill twin-study practitioner-report-import --report-id {report_id} --path {default_practitioner_report_paths(report_id)['dir'] / 'results.json.gz'}", + f"zwill twin-study practitioner-report-import --report-id {report_id} --input-path {default_practitioner_report_paths(report_id)['dir'] / 'results.json.gz'}", f"zwill twin-study practitioner-report-render --report-id {report_id}", ], ) def cmd_twin_benchmark_practitioner_report_import(args: argparse.Namespace) -> dict[str, Any]: - source = Path(args.path) + source = Path(args.input_path) if not source.exists(): - raise ZwillError("not_found", f"Results file does not exist: {args.path}.") + raise ZwillError("not_found", f"Results file does not exist: {args.input_path}.") results = read_json_or_gzip(source) if not isinstance(results, dict) or results.get("edsl_class_name") != "Results": raise ZwillError("invalid_input", "Expected an EDSL Results serialization.") @@ -682,7 +682,7 @@ def cmd_twin_benchmark_practitioner_report_render(args: argparse.Namespace) -> N raise ZwillError( "not_found", f"No imported practitioner report Markdown found for report id {report_id}.", - hint=f"Run `zwill twin-benchmark practitioner-report-import --report-id {report_id} --path `.", + hint=f"Run `zwill twin-benchmark practitioner-report-import --report-id {report_id} --input-path `.", ) context = read_json(paths["context"], {}) payload = context.get("benchmark_payload") @@ -748,7 +748,7 @@ def generate_practitioner_report_markdown( ) ) import_result = _cli().cmd_twin_benchmark_practitioner_report_import( - argparse.Namespace(path=str(results_path), report_id=report_id, replace=True) + argparse.Namespace(input_path=str(results_path), report_id=report_id, replace=True) ) markdown = default_paths["markdown"].read_text().strip() markdown_path = Path(args.markdown_path) if args.markdown_path else (output_path.with_suffix(".md") if output_path else None) @@ -1048,7 +1048,7 @@ def cmd_twin_experiment_report_export(args: argparse.Namespace) -> dict[str, Any data, next_steps=[ f"zwill edsl-run --job {data['job_path']} --path {default_practitioner_report_paths(report_id)['dir'] / 'results.json.gz'}", - f"zwill twin-experiment report-import --report-id {report_id} --path {default_practitioner_report_paths(report_id)['dir'] / 'results.json.gz'}", + f"zwill twin-experiment report-import --report-id {report_id} --input-path {default_practitioner_report_paths(report_id)['dir'] / 'results.json.gz'}", f"zwill twin-experiment report-render --report-id {report_id}", ], ) @@ -1103,7 +1103,7 @@ def cmd_twin_experiment_report(args: argparse.Namespace) -> None: run_param=None, ) ) - cmd_twin_experiment_report_import(argparse.Namespace(path=str(results_path), report_id=report_id, replace=True)) + cmd_twin_experiment_report_import(argparse.Namespace(input_path=str(results_path), report_id=report_id, replace=True)) markdown = default_paths["markdown"].read_text() generation = { **context.get("generation", {}), diff --git a/zwill/probability_commands.py b/zwill/probability_commands.py index 2e9bd66..ae9d214 100644 --- a/zwill/probability_commands.py +++ b/zwill/probability_commands.py @@ -12,9 +12,9 @@ def _cli(): def cmd_probability_results_import(args: argparse.Namespace) -> dict[str, Any]: sdir = require_survey(args.survey) - source = Path(args.path) + source = Path(args.input_path) if not source.exists(): - raise ZwillError("not_found", f"Results file does not exist: {args.path}.") + raise ZwillError("not_found", f"Results file does not exist: {args.input_path}.") results = read_json_or_gzip(source) if not isinstance(results, dict) or results.get("edsl_class_name") != "Results": raise ZwillError("invalid_input", "Expected an EDSL Results serialization.") @@ -250,7 +250,7 @@ def cmd_probability_results_analysis_export(args: argparse.Namespace) -> dict[st }, next_steps=[ f"zwill edsl-run --job {data['job_path']} --path {default_practitioner_report_paths(report_id)['dir'] / 'results.json.gz'}", - f"zwill prob-results analysis-import --report-id {report_id} --path {default_practitioner_report_paths(report_id)['dir'] / 'results.json.gz'}", + f"zwill prob-results analysis-import --report-id {report_id} --input-path {default_practitioner_report_paths(report_id)['dir'] / 'results.json.gz'}", f"zwill prob-results analysis-render --report-id {report_id} --path {path}", ], ) @@ -276,7 +276,7 @@ def cmd_probability_results_analysis_render(args: argparse.Namespace) -> dict[st raise ZwillError( "not_found", f"No imported generated one-shot analysis Markdown found for report id {args.report_id}.", - hint=f"Run `zwill prob-results analysis-import --report-id {args.report_id} --path `.", + hint=f"Run `zwill prob-results analysis-import --report-id {args.report_id} --input-path `.", ) context = read_json(paths["context"], {}) report_context = context.get("one_shot_analysis_context", {}) diff --git a/zwill/result_commands.py b/zwill/result_commands.py index 009f318..e9b75f5 100644 --- a/zwill/result_commands.py +++ b/zwill/result_commands.py @@ -6,9 +6,9 @@ def cmd_twin_results_import(args: argparse.Namespace) -> dict[str, Any]: sdir = require_survey(args.survey) - source = Path(args.path) + source = Path(args.input_path) if not source.exists(): - raise ZwillError("not_found", f"Results file does not exist: {args.path}.") + raise ZwillError("not_found", f"Results file does not exist: {args.input_path}.") results = read_json_or_gzip(source) if not isinstance(results, dict) or results.get("edsl_class_name") != "Results": raise ZwillError("invalid_input", "Expected an EDSL Results serialization.") @@ -158,7 +158,7 @@ def cmd_twin_results_retry_malformed(args: argparse.Namespace) -> dict[str, Any] raise ZwillError( "not_found", f"No import record found for twin job id {job_id}.", - hint=f"Import the results first: `zwill twin-results import --survey {args.survey} --path `.", + hint=f"Import the results first: `zwill twin-results import --survey {args.survey} --input-path `.", ) issues = read_json(import_path, {}).get("issues", []) if not issues: @@ -196,16 +196,16 @@ def cmd_twin_results_retry_malformed(args: argparse.Namespace) -> dict[str, Any] }, next_steps=[ f"zwill edsl-run --job {out_path} --path {results_path}", - f"zwill twin-results import --survey {args.survey} --job-id {job_id} --merge --path {results_path}", + f"zwill twin-results import --survey {args.survey} --job-id {job_id} --merge --input-path {results_path}", ], ) def cmd_rank_results_import(args: argparse.Namespace) -> dict[str, Any]: sdir = require_survey(args.survey) - source = Path(args.path) + source = Path(args.input_path) if not source.exists(): - raise ZwillError("not_found", f"Results file does not exist: {args.path}.") + raise ZwillError("not_found", f"Results file does not exist: {args.input_path}.") results = read_json_or_gzip(source) if not isinstance(results, dict) or results.get("edsl_class_name") != "Results": raise ZwillError("invalid_input", "Expected an EDSL Results serialization.") diff --git a/zwill/skills/digital-twin-practitioner-report/SKILL.md b/zwill/skills/digital-twin-practitioner-report/SKILL.md index 64275cb..683fe57 100644 --- a/zwill/skills/digital-twin-practitioner-report/SKILL.md +++ b/zwill/skills/digital-twin-practitioner-report/SKILL.md @@ -20,7 +20,7 @@ or the explicit artifact flow: ```bash zwill twin-study practitioner-report-export --survey --job-id zwill edsl-run --job .zwill/practitioner_reports//job.edsl.json --path .zwill/practitioner_reports//results.json.gz -zwill twin-study practitioner-report-import --path .zwill/practitioner_reports//results.json.gz +zwill twin-study practitioner-report-import --input-path .zwill/practitioner_reports//results.json.gz zwill twin-study practitioner-report-render --report-id --path practitioner_report.html ``` diff --git a/zwill/survey_commands.py b/zwill/survey_commands.py index 6d7ee40..11c62d4 100644 --- a/zwill/survey_commands.py +++ b/zwill/survey_commands.py @@ -5,9 +5,9 @@ def cmd_raw_add(args: argparse.Namespace) -> dict[str, Any]: sdir = require_survey(args.survey) - source = Path(args.path) + source = Path(args.input_path) if not source.exists() or not source.is_file(): - raise ZwillError("invalid_input", f"Raw path is not a file: {args.path}.") + raise ZwillError("invalid_input", f"Raw path is not a file: {args.input_path}.") stored_dir = sdir / "raw" / args.id stored_dir.mkdir(parents=True, exist_ok=True) stored = stored_dir / source.name @@ -16,7 +16,7 @@ def cmd_raw_add(args: argparse.Namespace) -> dict[str, Any]: "id": args.id, "kind": args.kind, "title": args.title, - "source_path": args.path, + "source_path": args.input_path, "source_hash": sha256(source), "stored_path": str(stored), "stored_hash": sha256(stored), @@ -38,11 +38,11 @@ def cmd_raw_list(args: argparse.Namespace) -> dict[str, Any]: def markdown_from_args(args: argparse.Namespace) -> tuple[str, str | None]: - if args.path: - path = Path(args.path) + if args.input_path: + path = Path(args.input_path) if not path.exists() or not path.is_file(): - raise ZwillError("invalid_input", f"Context path is not a file: {args.path}.") - return path.read_text(), args.path + raise ZwillError("invalid_input", f"Context path is not a file: {args.input_path}.") + return path.read_text(), args.input_path return args.text, None @@ -127,14 +127,14 @@ def cmd_question_add(args: argparse.Namespace) -> dict[str, Any]: rows.append(question) annotated, _rank_tasks = annotate_rank_items(rows) rewrite_jsonl(sdir / "questions.jsonl", annotated) - return envelope("zwill question add", "ok", {"question": question}, next_steps=[f"zwill answer import --survey {args.survey} --path answers.jsonl"]) + return envelope("zwill question add", "ok", {"question": question}, next_steps=[f"zwill answer import --survey {args.survey} --input-path answers.jsonl"]) def cmd_question_import(args: argparse.Namespace) -> dict[str, Any]: sdir = require_survey(args.survey) existing = questions_by_name(sdir) imported = [] - for row in read_jsonl(Path(args.path)): + for row in read_jsonl(Path(args.input_path)): existing[row["question_name"]] = row imported.append(row["question_name"]) annotated, rank_tasks = annotate_rank_items(list(existing.values())) @@ -186,7 +186,7 @@ def cmd_respondent_import(args: argparse.Namespace) -> dict[str, Any]: sdir = require_survey(args.survey) existing = respondents_by_id(sdir) imported = 0 - for row in read_jsonl(Path(args.path)): + for row in read_jsonl(Path(args.input_path)): existing[row["respondent_id"]] = row imported += 1 rewrite_jsonl(sdir / "respondents.jsonl", list(existing.values())) @@ -194,11 +194,11 @@ def cmd_respondent_import(args: argparse.Namespace) -> dict[str, Any]: def material_markdown_from_args(args: argparse.Namespace) -> tuple[str, str | None]: - if args.path: - path = Path(args.path) + if args.input_path: + path = Path(args.input_path) if not path.exists() or not path.is_file(): - raise ZwillError("invalid_input", f"Agent material path is not a file: {args.path}.") - return path.read_text().strip(), args.path + raise ZwillError("invalid_input", f"Agent material path is not a file: {args.input_path}.") + return path.read_text().strip(), args.input_path return args.text.strip(), None @@ -266,7 +266,7 @@ def cmd_agent_material_import(args: argparse.Namespace) -> dict[str, Any]: imported = 0 quarantined = 0 examples = [] - for line, row in enumerate(read_jsonl(Path(args.path)), 1): + for line, row in enumerate(read_jsonl(Path(args.input_path)), 1): material = dict(row) material.setdefault("material_id", next_agent_material_id(sdir, material.get("respondent_id", "unknown"), material.get("kind", "material"))) material.setdefault("title", material.get("kind", "Agent material")) @@ -347,7 +347,7 @@ def cmd_answer_import(args: argparse.Namespace) -> dict[str, Any]: quarantine_examples = [] valid_rows = [] implicit_respondents = [] - for line, row in enumerate(read_jsonl(Path(args.path)), 1): + for line, row in enumerate(read_jsonl(Path(args.input_path)), 1): question_name = row.get("question") issue = None if question_name not in questions: diff --git a/zwill/twin_approaches.py b/zwill/twin_approaches.py index b85c202..7d05075 100644 --- a/zwill/twin_approaches.py +++ b/zwill/twin_approaches.py @@ -88,8 +88,8 @@ def updater(approaches: list[dict[str, Any]]) -> list[dict[str, Any]]: def markdown_from_note_args(args: argparse.Namespace) -> str | None: if getattr(args, "clear", False): return "" - if getattr(args, "path", None): - return Path(args.path).read_text().strip() + if getattr(args, "input_path", None): + return Path(args.input_path).read_text().strip() if getattr(args, "text", None) is not None: return str(args.text).strip() return None @@ -97,8 +97,8 @@ def markdown_from_note_args(args: argparse.Namespace) -> str | None: def cmd_twin_approach_add(args: argparse.Namespace) -> dict[str, Any]: sdir = require_survey(args.survey) - if args.path: - approach = normalize_twin_approach_record(load_object_file(Path(args.path), kind="Twin approach"), source=str(args.path)) + if args.input_path: + approach = normalize_twin_approach_record(load_object_file(Path(args.input_path), kind="Twin approach"), source=str(args.input_path)) else: approach = twin_approach_from_args(args) upsert_twin_approach(sdir, approach) @@ -197,7 +197,7 @@ def cmd_twin_approach_scaffold(args: argparse.Namespace) -> dict[str, Any]: "zwill twin-approach scaffold", "ok", {"path": str(path), "approach": approach}, - next_steps=[f"zwill twin-approach add --survey {args.survey} --path {path}"], + next_steps=[f"zwill twin-approach add --survey {args.survey} --input-path {path}"], ) diff --git a/zwill/twin_experiments.py b/zwill/twin_experiments.py index acd2090..5ecad0a 100644 --- a/zwill/twin_experiments.py +++ b/zwill/twin_experiments.py @@ -389,7 +389,7 @@ def approved_plan_metadata(path: str | None) -> dict[str, Any] | None: "approval_required", "Twin validation plan is not approved.", context={"plan_path": str(plan_path), "plan_id": plan.get("plan_id")}, - hint=f"Review the plan, then run `zwill twin-experiment approve --path {plan_path}`.", + hint=f"Review the plan, then run `zwill twin-experiment approve --input-path {plan_path}`.", ) return { "plan_id": plan.get("plan_id") or plan_id_from_config(plan, plan_path), @@ -411,7 +411,7 @@ def require_twin_plan_approval(args: argparse.Namespace, *, command: str) -> dic raise ZwillError( "approval_required", f"{command} requires an approved validation plan.", - hint="Pass `--approved-plan ` after `zwill twin-experiment approve --path `, or pass `--allow-unapproved` for an explicit ad hoc/leakage/debug run.", + hint="Pass `--approved-plan ` after `zwill twin-experiment approve --input-path `, or pass `--allow-unapproved` for an explicit ad hoc/leakage/debug run.", ) @@ -553,12 +553,12 @@ def cmd_twin_experiment_init_plan(args: argparse.Namespace) -> dict[str, Any]: "ok", {"path": str(path), "plan": plan}, warnings=warnings or None, - next_steps=[f"zwill twin-experiment approve --path {path}", f"zwill twin-experiment export-plan --path {path}"], + next_steps=[f"zwill twin-experiment approve --input-path {path}", f"zwill twin-experiment export-plan --input-path {path}"], ) def cmd_twin_experiment_approve(args: argparse.Namespace) -> dict[str, Any]: - plan_path = Path(args.path) + plan_path = Path(args.input_path) plan = load_object_file(plan_path, kind="Twin experiment plan") survey = args.survey or plan.get("survey") sdir = require_survey(str(survey)) if survey else None @@ -598,12 +598,12 @@ def cmd_twin_experiment_approve(args: argparse.Namespace) -> dict[str, Any]: "prediction_count_estimate": estimate, }, warnings=[warning] if warning else None, - next_steps=[f"zwill twin-experiment export-plan --path {plan_path}"], + next_steps=[f"zwill twin-experiment export-plan --input-path {plan_path}"], ) def cmd_twin_experiment_export_plan(args: argparse.Namespace) -> dict[str, Any]: - plan_path = Path(args.path) + plan_path = Path(args.input_path) plan = load_object_file(plan_path, kind="Twin experiment plan") survey = args.survey or plan.get("survey") if not survey: @@ -615,7 +615,7 @@ def cmd_twin_experiment_export_plan(args: argparse.Namespace) -> dict[str, Any]: "approval_required", "Twin experiment plan must be approved before export.", context={"plan_path": str(plan_path), "plan_id": plan_id}, - hint=f"Review the plan, then run `zwill twin-experiment approve --path {plan_path}`.", + hint=f"Review the plan, then run `zwill twin-experiment approve --input-path {plan_path}`.", ) output_dir = Path(args.output_dir) if args.output_dir else digital_twin_jobs_dir(sdir) / "plans" / plan_id output_dir.mkdir(parents=True, exist_ok=True) @@ -751,13 +751,13 @@ def cmd_twin_experiment_export_plan(args: argparse.Namespace) -> dict[str, Any]: warnings=warnings or None, next_steps=[ ( - f"zwill twin-experiment approve --path {plan_path}" + f"zwill twin-experiment approve --input-path {plan_path}" if export_count_check.get("requires_reapproval") else f"zwill edsl-run --job {exported[0]['job_path']} --path " ) if exported else "", - f"zwill twin-results import --survey {survey} --path ", + f"zwill twin-results import --survey {survey} --input-path ", f"zwill twin-experiment compare --survey {survey} --metric {manifest['primary_metric']}", ], ) @@ -766,7 +766,7 @@ def cmd_twin_experiment_export_plan(args: argparse.Namespace) -> dict[str, Any]: def cmd_twin_experiment_validate(args: argparse.Namespace) -> dict[str, Any]: """Lint a plan file before approve/export: resolve questions, models, and counts, and surface problems/warnings without writing any jobs.""" - plan_path = Path(args.path) + plan_path = Path(args.input_path) plan = load_object_file(plan_path, kind="Twin experiment plan") survey = args.survey or plan.get("survey") if not survey: @@ -833,9 +833,9 @@ def cmd_twin_experiment_validate(args: argparse.Namespace) -> dict[str, Any]: count_check = prediction_count_check(approved_estimate, exported_prediction_count) if valid else None if valid and not is_plan_approved(plan): - next_steps = [f"zwill twin-experiment approve --path {plan_path}"] + next_steps = [f"zwill twin-experiment approve --input-path {plan_path}"] elif valid: - next_steps = [f"zwill twin-experiment export-plan --path {plan_path}"] + next_steps = [f"zwill twin-experiment export-plan --input-path {plan_path}"] else: next_steps = ["Fix the reported problems, then re-run validate."] return envelope( @@ -968,7 +968,7 @@ def cmd_twin_experiment_import_plan_results(args: argparse.Namespace) -> dict[st result = cmd_twin_results_import( argparse.Namespace( survey=str(survey), - path=str(path), + input_path=str(path), job_id=job_id, replace=args.replace, ) diff --git a/zwill/twin_studies.py b/zwill/twin_studies.py index c49b1fb..54b8269 100644 --- a/zwill/twin_studies.py +++ b/zwill/twin_studies.py @@ -352,7 +352,7 @@ def cmd_twin_study_run(args: argparse.Namespace) -> dict[str, Any]: import_result = cli.cmd_twin_results_import( argparse.Namespace( survey=args.survey, - path=str(results_path), + input_path=str(results_path), job_id=job_id, replace=args.replace, ) @@ -517,7 +517,7 @@ def cmd_twin_study_import_results_dir(args: argparse.Namespace) -> dict[str, Any result = _cli().cmd_twin_results_import( argparse.Namespace( survey=args.survey, - path=str(path), + input_path=str(path), job_id=job_id, replace=args.replace, allow_missing_actual=args.allow_missing_actual, diff --git a/zwill/twin_validation_commands.py b/zwill/twin_validation_commands.py index 3714857..7189f17 100644 --- a/zwill/twin_validation_commands.py +++ b/zwill/twin_validation_commands.py @@ -299,7 +299,7 @@ def cmd_twin_results_executive_summary_export(args: argparse.Namespace) -> dict[ }, next_steps=[ f"zwill edsl-run --job {data['job_path']} --path {default_practitioner_report_paths(report_id)['dir'] / 'results.json.gz'}", - f"zwill twin-results executive-summary-import --report-id {report_id} --path {default_practitioner_report_paths(report_id)['dir'] / 'results.json.gz'}", + f"zwill twin-results executive-summary-import --report-id {report_id} --input-path {default_practitioner_report_paths(report_id)['dir'] / 'results.json.gz'}", f"zwill twin-results executive-summary-render --report-id {report_id} --path {path}", ], ) @@ -325,7 +325,7 @@ def cmd_twin_results_executive_summary_render(args: argparse.Namespace) -> dict[ raise ZwillError( "not_found", f"No imported generated executive summary Markdown found for report id {args.report_id}.", - hint=f"Run `zwill twin-results executive-summary-import --report-id {args.report_id} --path `.", + hint=f"Run `zwill twin-results executive-summary-import --report-id {args.report_id} --input-path `.", ) context = read_json(paths["context"], {}) report_context = context.get("executive_report_context", {}) diff --git a/zwill/workflow_commands.py b/zwill/workflow_commands.py index 020301d..0a5a988 100644 --- a/zwill/workflow_commands.py +++ b/zwill/workflow_commands.py @@ -282,7 +282,7 @@ def cmd_workflow_pew_demo(args: argparse.Namespace) -> dict[str, Any]: cmd_context_set( argparse.Namespace( survey=survey_name, - path=str(repo_root / "examples" / survey_name / "context.md"), + input_path=str(repo_root / "examples" / survey_name / "context.md"), text=None, ) ) @@ -290,7 +290,7 @@ def cmd_workflow_pew_demo(args: argparse.Namespace) -> dict[str, Any]: argparse.Namespace( survey=survey_name, id="w154_diff1_metadata", - path=str(source_dir / "W154_DIFF1_metadata.json"), + input_path=str(source_dir / "W154_DIFF1_metadata.json"), kind="metadata", title="Pew W154 DIFF1 Normalized Metadata", ) @@ -299,14 +299,14 @@ def cmd_workflow_pew_demo(args: argparse.Namespace) -> dict[str, Any]: argparse.Namespace( survey=survey_name, id="w154_diff1_respondents", - path=str(source_dir / "W154_DIFF1_respondents.csv"), + input_path=str(source_dir / "W154_DIFF1_respondents.csv"), kind="respondent_data", title="Pew W154 DIFF1 Normalized Respondents", ) ) - cmd_question_import(argparse.Namespace(survey=survey_name, path=str(import_dir / "questions.jsonl"))) - cmd_respondent_import(argparse.Namespace(survey=survey_name, path=str(import_dir / "respondents.jsonl"))) - cmd_answer_import(argparse.Namespace(survey=survey_name, path=str(import_dir / "answers.jsonl"))) + cmd_question_import(argparse.Namespace(survey=survey_name, input_path=str(import_dir / "questions.jsonl"))) + cmd_respondent_import(argparse.Namespace(survey=survey_name, input_path=str(import_dir / "respondents.jsonl"))) + cmd_answer_import(argparse.Namespace(survey=survey_name, input_path=str(import_dir / "answers.jsonl"))) commit_result = cmd_commit(argparse.Namespace(survey=survey_name)) if not args.no_edsl: @@ -336,7 +336,7 @@ def cmd_workflow_pew_demo(args: argparse.Namespace) -> dict[str, Any]: import_result = cmd_probability_results_import( argparse.Namespace( survey=survey_name, - path=args.results_path, + input_path=args.results_path, job_id=args.job_id, replace=True, )