feat(cli): console entry points + the demo's stderr damping (P4 pkt. 5 og 2)
Two commands are now part of the install surface a fresh clone gets from `uv sync`: `portfolio-optimiser` (run:main) and `portfolio-optimiser-demo` (simulation:main). Deliberately two of five main()s — costsim/hitl/preflight stay module-invoked; every name here is a name the freeze has to carry. Pinned against the INSTALLED distribution's metadata, not the TOML: a [project.scripts] line that has never been synced is a claim, not a command. Measured: stdout is byte-identical across both invocation forms. stderr (P4 pkt. 2), the session's open decision, resolved by measurement rather than by preference. Damped: the round-cap notice only, via a filter on the emitting logger, keyed on the message and installed by main() — never at import, so a library consumer keeps its own logging config. NOT damped: the two ExperimentalWarnings. They fire while the package __init__ imports run -> agent_framework, always before simulation's own imports and under both invocation forms, so silencing them would mean filtering warnings inside the library package on every consumer's behalf; they are pinned in pkt. 3 instead. A console-script wrapper was rejected for a second reason: the two forms would then write different stderr, and a byte-fasit would pin the command rather than the program. stderr 6 -> 4 lines. A first implementation wrapped simulation's own agent_framework import in a scoped mute. Measurement showed it can never fire — the package __init__ has already imported agent_framework by then — so it was removed rather than left as a green-but-dead seam. Load-bearing MEASURED against the whole suite, five mutations all red + green control: remove [project.scripts] · typo the target · detach the main() call · make the filter drop everything · install the filter at import time. The typo mutation also felled a test: the resolve-assert re-checked the expected constant against itself, and now resolves what the distribution actually installs. 775 -> 785 passed / 4 skipped. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C2bxLcCRguxXzpM4priTMn
This commit is contained in:
parent
1522e2aaaa
commit
ab7f45aa95
6 changed files with 298 additions and 2 deletions
|
|
@ -30,6 +30,15 @@ dependencies = [
|
|||
"llm-ingestion-okf", # Door A ingest (§4–§6) — the shared implementation of shared/ingest-spec.md; zero runtime deps, MAF-free (D7)
|
||||
]
|
||||
|
||||
# Console entry points — the install surface a fresh clone gets from `uv sync` (P4 pkt. 5).
|
||||
# Deliberately TWO, not five: `run` is the framework CLI (three documented modes) and `simulation`
|
||||
# is the offline end-to-end proof the README points a newcomer at. `costsim` / `hitl` / `preflight`
|
||||
# keep the `python -m` form — they are operator utilities, not the product's front door, and every
|
||||
# name here is a name the freeze has to carry. Pinned by tests/test_console_entry_points.py.
|
||||
[project.scripts]
|
||||
portfolio-optimiser = "portfolio_optimiser.run:main"
|
||||
portfolio-optimiser-demo = "portfolio_optimiser.simulation:main"
|
||||
|
||||
# Distribution channel for the shared ingest library (mirrors portfolio-optimiser-claude,
|
||||
# verified in consumer CI): git pin against the public Forgejo repo — reproducible for every
|
||||
# consumer, uv.lock pins the exact commit behind the tag. Bump the rev on a new library tag.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue