Add ratchet pathway forecast

This commit is contained in:
saymrwulf 2026-04-27 15:41:25 +02:00
parent f8d0fdc272
commit a4a19f30d8
4 changed files with 95 additions and 0 deletions

View file

@ -39,6 +39,23 @@ You do not need to babysit it. It will:
If you want the technical report, run `./scripts/ratchet report`. The normal workflow intentionally shows the cockpit first.
## Research Pathway
The cockpit has two different time horizons:
1. `DO THIS NOW` is the only command you should run next.
2. `Ratchet Pathway Forecast` tells you what the next stages probably look like.
The forecast is not a profit prediction. It is a workload and research-flow prediction.
It is split into:
1. `Immediate`: what happens now.
2. `Midterm`: what probably happens after the current run or sample.
3. `Longterm`: what could happen after multiple reports mature.
Expect the pathway to change after each report. That is the point of ratcheting: the next stage adapts to measured evidence instead of following a rigid plan.
## What The Actions Mean
`observe` means do not bid.

View file

@ -10,6 +10,14 @@ Run these commands from the repository root:
This prints the cockpit and tells you exactly what to do next.
The cockpit also prints `Ratchet Pathway Forecast`. That section is the stretched-out research path:
- Immediate: the next operational step.
- Midterm: the likely next experiment stage.
- Longterm: what could happen after multiple reports mature.
Those probabilities are workload and workflow estimates, not promises of mining profit.
If the cockpit tells you to collect one fresh sample, run:
```bash

View file

@ -47,6 +47,16 @@ def build_operator_cockpit(conn) -> str:
action=proposal.action if proposal else None,
)
)
lines.extend(["", "Ratchet Pathway Forecast"])
lines.extend(
_pathway_forecast(
active_watch=active_watch,
has_ocean=ocean is not None,
has_market=market is not None,
is_fresh=is_fresh,
action=proposal.action if proposal else None,
)
)
lines.extend(["", "How To Interpret The Current Action"])
lines.extend(_action_explanation(proposal.action if proposal else None))
lines.extend(["", "Ratchet Rule"])
@ -128,6 +138,61 @@ def _do_this_now(
]
def _pathway_forecast(
active_watch: str | None,
has_ocean: bool,
has_market: bool,
is_fresh: bool,
action: str | None,
) -> list[str]:
if active_watch:
return [
" Planning probabilities are workflow estimates, not profit probabilities.",
" Immediate, very likely: wait for the running watch to finish; workload is zero until it ends.",
" Midterm, likely: read the final cockpit and ledger summary; workload is about 5 minutes.",
" Longterm, possible: adjust one strategy knob if the report says the run taught us something.",
]
if not has_ocean or not has_market:
return [
" Planning probabilities are workflow estimates, not profit probabilities.",
" Immediate, certain: initialize local state; workload is one setup command.",
" Midterm, very likely: collect the first live sample; workload is one once command.",
" Longterm, likely: start passive watch experiments after fresh data exists.",
]
if not is_fresh:
return [
" Planning probabilities are workflow estimates, not profit probabilities.",
" Immediate, certain: refresh stale data with one once command; workload is under a minute.",
" Midterm, likely: if the fresh state still says manual_canary, run a 2-hour watch.",
" Longterm, possible: compare this fresh run against prior reports before changing any knob.",
]
if action == "manual_bid":
return [
" Planning probabilities are workflow estimates, not profit probabilities.",
" Immediate, certain: inspect the full report before any manual Braiins action.",
" Midterm, possible: manually place a tiny order only if the report still says manual_bid.",
" Longterm, uncertain: wait through maturity and compare realized outcome against modeled EV.",
]
if action == "manual_canary":
return [
" Planning probabilities are workflow estimates, not profit probabilities.",
" Immediate, very likely: run a 2-hour passive watch; workload is start command plus waiting.",
" Midterm, likely: use the generated run report to decide one next knob to test.",
" Longterm, possible: only after repeated mature evidence, consider a manual canary spend.",
]
return [
" Planning probabilities are workflow estimates, not profit probabilities.",
" Immediate, certain: do not bid.",
" Midterm, possible: run another passive watch later if you want more market coverage.",
" Longterm, possible: change one strategy knob only after multiple observe windows are logged.",
]
def _action_explanation(action: str | None) -> list[str]:
if action == "manual_bid":
return [

View file

@ -60,6 +60,10 @@ class GuidanceTests(unittest.TestCase):
self.assertIn("Latest strategy action: manual_canary", text)
self.assertIn("./scripts/ratchet watch 2", text)
self.assertIn("not proven profit", text)
self.assertIn("Ratchet Pathway Forecast", text)
self.assertIn("Immediate, very likely", text)
self.assertIn("Midterm, likely", text)
self.assertIn("Longterm, possible", text)
def test_stale_market_data_routes_operator_to_once(self) -> None:
conn = sqlite3.connect(":memory:")
@ -99,6 +103,7 @@ class GuidanceTests(unittest.TestCase):
self.assertIn("./scripts/ratchet once", text)
self.assertIn("latest Braiins sample is stale", text)
self.assertIn("DO THIS NOW", text)
self.assertIn("if the fresh state still says manual_canary", text)
if __name__ == "__main__":