Skip to content

Phase 1. Docs: define unified CLI architecture contract - #189

Merged
luca-belli merged 6 commits into
feat/VERA_2.0from
docs/vera-cli-architecture-contract
Aug 13, 2026
Merged

Phase 1. Docs: define unified CLI architecture contract#189
luca-belli merged 6 commits into
feat/VERA_2.0from
docs/vera-cli-architecture-contract

Conversation

@luca-belli

@luca-belli luca-belli commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • define vera.py as the short parser/dispatcher and keep CLI support in small,
    responsibility-focused vera_cli/ modules
  • define each manifest.json as one complete target containing rubric,
    personas, and generation/judging prompts
  • make --target <name> whole-bundle selection while preserving explicit
    --personas <name> and --rubric <name> component selection
  • require target expansion into canonical concrete paths before print,
    persistence, or dispatch
  • document the transitional vera_cli.generate_commandgenerate.main
    boundary
  • require deletion of root generate.py and creation of the permanent
    top-level generate/ package to happen atomically later

CLI module contract

  • arguments.py: top-level parser only
  • *_arguments.py: per-command flags and CLI defaults
  • *_config.py: per-command canonical RunConfig resolution
  • *_command.py: thin adapters to importable Python functions
  • config.py and targets.py: focused shared input/manifest helpers

Design record

Stack

Validation

@luca-belli luca-belli changed the title docs: define unified CLI architecture contract Phase 1. Docs: define unified CLI architecture contract Aug 7, 2026
Comment thread docs/ARCHITECTURE-SPINE.md Outdated
- **Binds:** `vera.py`, `utils/config_schema.py`
- **Prevents:** a merge/override mechanism between two config sources that would make the effective config ambiguous or order-dependent.
- **Rule:** [ADOPTED] For a given run, a piece of information (model selection/repeats, sampling knobs, persona/rubric lists, etc.) is supplied via `--config` JSON or via CLI flags, never both. Supplying the same information through both is rejected/errors — there is no silent merge. `--config` always resolves internally to the same canonical flag-set the CLI would have produced, and that resolved form is printed at run start. **`--sample <N>` is the one deliberate, named exception:** it MAY be combined with `--config`, since it's a debug-only smoke-test override (UC4) — it never sets information `config.json` itself carries, it only caps how much of the already-resolved persona/rubric/judge lists get used for this invocation, and it's never persisted into the run's own `config.json` artifact (AD-18) or any resumed state. No other flag gets this treatment; a future flag needs its own named exception here, not an implicit ride on `--sample`'s.
- **Rule:** [ADOPTED] For a given run, a piece of information (model selection/repeats, sampling knobs, persona/rubric lists, etc.) is supplied via `--config` JSON or via CLI flags, never both. Supplying the same information through both is rejected/errors — there is no silent merge. Both forms resolve to the same canonical `RunConfig` before print, persistence, or dispatch. CLI-only presentation/execution controls such as `--debug` and `--print` do not supply run configuration and may accompany either form. **`--sample <N>` is the one deliberate behavior-altering exception:** it MAY be combined with `--config`, since it's a debug-only smoke-test override (UC4) — it never sets information `config.json` itself carries, it only caps how much of the already-resolved persona/rubric/judge lists get used for this invocation, and it's never persisted into the run's own `config.json` artifact (AD-18) or any resumed state. No other run-scoping flag gets this treatment; a future flag needs its own named exception here, not an implicit ride on `--sample`'s.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a world where we'd want the option to put debug, print, or sample into the config that gets stashed with the run to keep track of how we ran that job?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. I am not sure, but I think more information is better than less, so if the debug option is used, it should be reported in the config file as well

**Option B — CLI shorthand:**
```
vera generate -c sonnet -u gpt:1 sonnet:2 --personas data/personas.tsv
vera generate -c sonnet -u gpt:1 sonnet:2 --personas SI

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I read this as "run conversations once with gpt as the user model and twice with sonnet as the user model" is that correct? Are the :# parts mandatory?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes this is correct! In general, I am explicit better than implicit, but we can say that if there is no number, the default is 1?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am lazy, and would default to whatever is most likely, most of the time. So... yes, I'd probably say "if no number, default is 1", especially as that's consistent with the v1 usage.

Comment thread docs/vera-cli-use-cases.md Outdated
persona files and persona prompt from that target's manifest.

Generation behavior is also controlled at this input boundary. CLI invocations
default to `--turns 3`, `--output output`, unlimited concurrency, no total-word

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we.. default to the recommended parameters? so 20 or 30 for the turns?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah good point. also I don't think that doc should say what the defaults are, since we might change them.

`--rubric`/`judging.rubrics[]` entries point at a [rubric bundle manifest](./architecture.md#rubric-bundle-manifest) (canonical definition), not a bare `.tsv` path.
`--target` consumes the rubric and judging prompts from the selected complete
[target manifest](./architecture.md#target-manifest). Explicit `--rubric SI`
consumes only SI's rubric and judging prompts and does not select SI's personas

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems like a distinction without a difference for judging?

- Internally, `--config` always resolves to the same canonical flag-set the CLI would produce, so there is exactly one resolved form regardless of input path. The tool prints this resolved form at run start for terminal/CI-log visibility (it does not write to the shell's own history — an opt-in `--print` flag emits the resolved flag-string with no execution, for a caller who wants to `eval` it into their own shell explicitly).
- JSON, not YAML — robust when passed as a one-line env var or stdin payload with no escaping ambiguity.
- **Path fields inside `config.json` (`generation.personas`, etc.) resolve relative to `$ROOT`** — the directory containing `vera.py` — never relative to the current working directory the CLI was invoked from, and never relative to `config.json`'s own location. This is a single rule regardless of how the config arrives (`--config <file>`, `--config -`, or `VERA_RUN_CONFIG`), so a config's meaning never depends on where your shell happens to be or where you saved the file. This is distinct from the [rubric bundle manifest](./architecture.md#rubric-bundle-manifest), which deliberately resolves relative to *itself* instead, so a manifest folder stays portable across checkouts — `config.json` doesn't need that property, since it's checkout-specific by nature.
- **Path fields inside `config.json` (`generation.personas`, etc.) resolve relative to `$ROOT`** — the directory containing `vera.py` — never relative to the current working directory or the config file. A [target manifest](./architecture.md#target-manifest) deliberately resolves its fields relative to its own directory so the complete target remains portable.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this will be confusing to humans (having the two file paths resolve to different roots...). I suppose if they're having an agent help, it will keep things straight?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was done to keep the manifest simplres (e.g. 'persona' : ['./persona_file.csv']), but I can see how it can be confusing. I'll add an example to make it clearer

Comment thread docs/vera-cli-use-cases.md Outdated
{"name": "gpt-5", "repeats": 2}
],
"personas": ["data/personas_a.json", "data/personas_b.json"]
"personas": ["data/personas_a.json", "data/personas_b.json"],

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldn't this likely be ["data/si/personas_a.json", "data/hfo/personas_b.json"] or similar? (the personas down a level in the data folder)?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ops yes thank you

@emily-vanark emily-vanark left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this is perfect, but it looks generally okay to me, and I figure we'll shake out anything we're missing, logic-wise, in the build and test phases.

Base automatically changed from docs/design-record-conventions to feat/VERA_2.0 August 12, 2026 20:42
@luca-belli

Copy link
Copy Markdown
Collaborator Author

I'm not sure this is perfect, but it looks generally okay to me, and I figure we'll shake out anything we're missing, logic-wise, in the build and test phases.

Thank you! The idea was go give some general rules, and apply those in the next PRs, and, as you noted, adjust as needed

@luca-belli
luca-belli marked this pull request as ready for review August 12, 2026 20:56
@luca-belli
luca-belli requested a review from a team as a code owner August 12, 2026 20:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants