Skip to content

compass(design): doc 11 D72/D74 - metrics clocks on virtual time, sim-time observer - #444

Draft
jgong5 wants to merge 2 commits into
feature/atomcompass_newfrom
compass/doc11-d72-virtual-time
Draft

jgong5 wants to merge 2 commits into
feature/atomcompass_newfrom
compass/doc11-d72-virtual-time

Conversation

@jgong5

@jgong5 jgong5 commented Sep 28, 2026 •

Copy link
Copy Markdown
Owner

Part of #443. Design-doc only.

Moves D72 and D74 of 11 onto the PDES time model: the three metrics clocks run on virtual time, and a sim-time observer scrapes /metrics.

What changes

  • Metrics clocks: the engine push gate (EngineCore.busy_loop, DPEngineCoreProc.busy_loop), the refresh loop's asyncio.sleep (_metrics_refresh_loop in api_server.py) and _last_refresh (AtomMetricsExporter.update) run on virtual time; none is allowlisted.
  • New observer: a periodic timer in the traffic LP scrapes /metrics every scrape_interval of simulated time over the existing traffic->frontend:http / frontend->traffic:stream channels. No new LP or channel; samples carry virtual timestamps.
  • New end of run: the traffic LP calls end_workload() (CA END) after its last scrape, so a periodic observer cannot keep a run alive.
  • The section headed "This corrects 01 D5" is replaced by a note that the virtual push cadence there stands. Per-step sampling is unchanged and coexists with the scrape series.
  • A follow-up commit (comment) renames the backfill table's category-A path to K1 of compass(design): doc 01 D4, D5, D9 and the decision log move to the PDES mechanisms #450.

Dev record

Named result

none.

Gates

none: no code.

Details

How and why the clocks move (D72). The push gate is a virtual timer whose next push is a local next event folded into the engine's NER time. The refresh loop's asyncio.sleep becomes virtual with no code change because the API server's loop runs on virtual time. _last_refresh joins the clock-read substitution list (D9 item 2 of 01). The old reasons for real clocks do not hold: at 100x, a push every 5 virtual seconds is one small message per 50 ms of wall time, which affects simulator speed, not the prediction; a wall-clock staleness problem exists only for someone watching the simulator on the wall clock.

D74: the per-step series is the ground truth for analysis; the scrape series is comparable with a real run's Prometheus at the same interval. The transport wording and dataflow diagram no longer say "wall timer" or "wall scrape".

Alignment: the D77 class-T row says _last_refresh is virtual. The decision-log rows for D72 and D74 are rewritten and marked revised 2026-09-28. The doc-11 row of the design/README.md index no longer says "Both metrics clock reads stay real". The follow-up commit: the emission-cost row of the backfill table said a hook inside "a Category-A path" would be invisible; #450 maps old category A to K1 (event cost, advance_to), the only path along which virtual time advances by a modelled duration, and the row now names that path.

Left to other PRs:

Register: none opened or closed; T40-T46 unaffected; the 12_open_items.md line "the clock-read sites of 11 D72" stays true.

Generated with Claude Code

…sim-time observer

D72 kept the engine metrics push gate, the API-server refresh loop and
_last_refresh on the real clock, allowlisted, and corrected doc 01 D5 to
match. All three now run on virtual time: the push gate and the refresh
loop are virtual timers, and metrics.py:408 joins the clock-read
substitution list. A periodic observer in the traffic LP scrapes /metrics
every scrape_interval of simulated time over the existing HTTP channels;
the run ends with its workload (end_workload), so the timers cannot keep
it alive. The "corrects 01 D5" passage is deleted.

D74 keeps per-step sampling and states that it coexists with the scrape
series. D74's transport wording, the class-T row, the decision log and
the README index row for doc 11 are aligned.

Part of #443.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ory A

Doc 01 D4 (#450) replaces the A/B/C1/C2/ignore categories with the nine PDES
mechanisms K1-K9; #53's category A maps to K1, the event cost priced through
advance_to. Doc 11's emission-cost row still said "Category-A path".

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@jgong5

jgong5 commented Sep 28, 2026 •

Copy link
Copy Markdown
Owner Author

Follow-up commit pushed, 11_metrics_support.md only. The backfill table's emission-cost row said a hook inside "a Category-A path" would be invisible. #450 rewrites D4 of 01 onto the PDES mechanisms K1-K9 and maps old category A to K1 (event cost, advance_to), the only path along which virtual time advances by a modelled duration. The row now names that path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

M1 M1: GPU-free as deployed on the PDES clock, scheduling parity with the real engine (D95)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant