diff --git a/.kiro/specs/scheduler-sim-repl-verbosity/design.md b/.kiro/specs/scheduler-sim-repl-verbosity/design.md index 31b3a206..ed332407 100644 --- a/.kiro/specs/scheduler-sim-repl-verbosity/design.md +++ b/.kiro/specs/scheduler-sim-repl-verbosity/design.md @@ -285,6 +285,8 @@ int repl_fmt_jobid_range(char* buf, size_t bufsz, - Uses **bare** `rs->session_count`, matching `info session`'s/`info config`'s existing convention (`repl_info.c:848,898`) — **not** `session_count + 1`. That `+1` exists only in `repl_print_event_summary()` (repl_break.c:611) to label events echoed *mid-stream*, before the session containing them has finished and incremented the count; the prompt, by contrast, is only ever shown *after* a `step`/`continue` has returned control (i.e. after `xce_repl_on_begin_round()` for the just-finished session has already run), so the bare count is the session that just completed — the same number `info session` would report if queried at that exact prompt. Copying the `+1` convention here would make the prompt disagree with `info session` by one. - Built fresh on every `repl_command_loop()` iteration, immediately before the `readline()` call it feeds — never cached across iterations, since the session/timestamp can change between prompts. +**Accepted residual (post-review, task 6.2)**: this task's `repl_build_prompt()` addition pushed `repl.c` to 852 lines (6.5% over the 800-line cap, up from 1% after task 2.2) — the exact trigger task 2.2's own residual note anticipated. Review empirically tried extracting `repl_build_prompt()` into a new `repl_prompt.c` (matching the `repl_rollup.c` precedent): it links and passes, but 19 sibling white-box test files each `#include "../src/repl.c"` directly and would each need a matching new `#include` line to keep linking, and even after absorbing that churn `repl.c` only drops to 814 lines — still over cap. Given the function is a small, single-purpose 15-line formatter and the split doesn't even achieve compliance, extraction was judged disproportionate and reverted; 852 lines is accepted as this task's residual. Tasks 7-9's `repl_info.c`/`repl_params.c`/`repl.c` (`help`/`BP_KIND_TABLE` accessor) additions are unaffected — revisit `repl.c` specifically only if a later task adds to it again. + **Dependencies** - Inbound: `repl_command_loop()` (repl.c) — calls this immediately before its existing `readline(XCE_REPL_PROMPT)` line - Outbound: `repl_format_ts_human()` (repl.c, existing), `xce_core_now()` (core_clock.c, existing) diff --git a/.kiro/specs/scheduler-sim-repl-verbosity/tasks.md b/.kiro/specs/scheduler-sim-repl-verbosity/tasks.md index 8133f1f7..e5650a3c 100644 --- a/.kiro/specs/scheduler-sim-repl-verbosity/tasks.md +++ b/.kiro/specs/scheduler-sim-repl-verbosity/tasks.md @@ -65,7 +65,7 @@ - _Requirements: 5.5_ - _Boundary: REPL Prompt Context_ -- [ ] 6.2 (P) Implement the dynamic prompt +- [x] 6.2 (P) Implement the dynamic prompt - Build the prompt fresh on every `repl_command_loop()` iteration from the current session count and `xce_core_now()`/`repl_format_ts_human()`, falling back to the original plain prompt before any session begins - Observable: all tests from 6.1 pass; a live `step`/`continue` session shows the session/timestamp in the prompt starting from the first completed session, with no change to any command's own printed output - _Requirements: 5.5_ diff --git a/src/scheduler/src/repl.c b/src/scheduler/src/repl.c index f853a20f..5bbadf99 100644 --- a/src/scheduler/src/repl.c +++ b/src/scheduler/src/repl.c @@ -422,6 +422,42 @@ static bool repl_dispatch(xce_sched_sim_driver_t* sim, const char* line) return false; } +/* + * repl_build_prompt (scheduler-sim-repl-verbosity spec, task 6.2, design.md's + * "REPL Prompt Context" component, Req 5.5) - builds this iteration's + * readline() prompt into `buf` (bufsz-bounded): the plain XCE_REPL_PROMPT + * ("(sim) ") if no session has completed yet (rs->session_count == 0, the + * same zero-initialized value repl_state_ensure()'s calloc already + * guarantees), else "(sim session= t=) " using the BARE + * rs->session_count -- deliberately NOT +1, unlike repl_print_event_summary() + * (repl_break.c)'s unrelated mid-stream convention, which labels events + * echoed before the session containing them has finished/incremented the + * count. This prompt is only ever shown AFTER a step/continue has already + * returned control (i.e. after xce_repl_on_begin_round() for the + * just-finished session has run), so the bare count is the session that + * just completed -- the same number `info session` would report right now. + * The timestamp reuses xce_core_now(&sim->core)/repl_format_ts_human() + * verbatim (no new time source, no raw-epoch-ns component). A read-only + * formatter -- never blocks, never mutates sim/sim->repl_state -- so it is + * safe to call fresh on every loop iteration (never cached). + */ +static void repl_build_prompt(xce_sched_sim_driver_t* sim, char* buf, + size_t bufsz) +{ + xce_sched_repl_state_t* rs = sim->repl_state; + char ts_human[32]; + + if ((rs == NULL) || (rs->session_count == 0)) { + snprintf(buf, bufsz, "%s", XCE_REPL_PROMPT); + return; + } + + repl_format_ts_human(xce_core_now(&(sim->core)), ts_human, + sizeof(ts_human)); + snprintf(buf, bufsz, "(sim session=%llu t=%s) ", + (unsigned long long)rs->session_count, ts_human); +} + /* * repl_command_loop - the blocking prompt loop itself: readline() the * `(sim) ` prompt, add_history() on non-blank input (same convention @@ -433,11 +469,19 @@ static bool repl_dispatch(xce_sched_sim_driver_t* sim, const char* line) * that case either. Non-static (repl_internal.h) -- repl_break.c's * breakpoint-hit hooks re-enter it directly, the same way * xce_repl_post_session_check() below already does for a `step N` pause. + * The prompt itself is rebuilt fresh (repl_build_prompt()) immediately + * before every readline() call, never cached across iterations, since the + * session count/timestamp it shows can change between prompts (task 6.2, + * Req 5.5). */ void repl_command_loop(xce_sched_sim_driver_t* sim) { for (;;) { - char* line = readline(XCE_REPL_PROMPT); + char prompt[64]; + char* line; + + repl_build_prompt(sim, prompt, sizeof(prompt)); + line = readline(prompt); if (line == NULL) { repl_cmd_quit(sim); /* never returns */