feat(scheduler-sim-step-verbosity): task 1.2 - implement preamble deduplication

repl_print_event_summary() (repl_break.c) now compares the candidate
rendered timestamp and displayed session number against a new cache
on xce_sched_repl_state_s (repl_internal.h: last_echo_ts_human[32],
last_echo_session) before printing the "[sim] t=... session=..."
preamble. It prints and updates the cache only when either value has
changed, or no preamble has been printed yet this session (the cache's
zero-initialized default, which no real echoed event can produce);
otherwise the preamble is skipped and the cache is left untouched. The
event's own content line prints unconditionally either way
(Requirements 1.1-1.4, 2.2).

All 6 RED-phase tests (task 1.1) now pass, including the critical
raw-vs-rendered nuance test (Requirement 1.3). No regressions in the
Event Echo Gate suite or the sibling spec's breakpoints-inspection
suite (test_step_echoes_events_before_session_decisions specifically
confirmed still passing under the new dedup behavior).

repl_break.c grew from 949 to 980 lines (+31, 3.3% over the residual
already accepted in scheduler-sim-repl-verbosity task 9.2). Review
judged this small growth as accepted without a fresh empirical split
test: task 9.2's own split experiment (a larger +44-line growth)
already found extracting this file's lookup-table domain reaches only
838 lines (still over cap) while requiring 22 white-box test files'
#include lines to change - disproportionate churn this smaller
increment would only re-confirm.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YAWMhfRJFnmmnG8h97yUDd
This commit is contained in:
Rongsong Shen 2026-09-03 04:11:08 +00:00
parent 6a2aa47f5e
commit 56e007cb6b
No known key found for this signature in database
GPG key ID: 5BCDAAE0123E9FE2
3 changed files with 65 additions and 4 deletions

View file

@ -8,7 +8,7 @@
- _Requirements: 1.1, 1.2, 1.3, 1.4, 2.2_
- _Boundary: Event Echo Preamble Deduplicator_
- [ ] 1.2 Implement the preamble deduplication cache and print-skip logic
- [x] 1.2 Implement the preamble deduplication cache and print-skip logic
- Add the last-printed rendered timestamp and session cache to the REPL session state, zero-initialized alongside the state's existing fields; update the event echo path to compare the candidate rendered timestamp and session against the cache, printing and updating it only when either has changed (or no preamble has been printed yet this session), while always still printing the event's own content line unconditionally
- Observable: all tests from 1.1 pass; a captured transcript shows exactly one preamble line per distinct rendered (timestamp, session) run of consecutive echoed events, with every event's own content line still present
- After landing the implementation change, re-check `repl_break.c`'s line count against its already-accepted 949-line residual (design.md's Architecture Integration); if it meaningfully exceeds that residual, evaluate extracting `repl_print_event_summary()` and its Event Echo Gate neighbors into a new file rather than pre-splitting speculatively

View file

@ -674,13 +674,44 @@ static void repl_print_event_summary(xce_sched_sim_driver_t* sim,
{
xce_sched_repl_state_t* rs = sim->repl_state;
char ts_human[32];
uint64_t session_num;
repl_format_ts_human(xce_core_now(&(sim->core)), ts_human,
sizeof(ts_human));
fprintf(stdout, "[sim] t=%llu (%s) session=%llu\n",
(unsigned long long)xce_core_now(&(sim->core)), ts_human,
(unsigned long long)((rs != NULL) ? rs->session_count + 1 : 1));
session_num = (rs != NULL) ? rs->session_count + 1 : 1;
/*
* Event Echo Preamble Deduplicator (scheduler-sim-step-verbosity spec,
* task 1.2, design.md's "Event Echo Preamble Deduplicator" component,
* Req 1.1-1.4/2.2): print the preamble only when the candidate rendered
* timestamp or displayed session differs from the last preamble THIS
* function actually printed this session (rs->last_echo_ts_human/
* rs->last_echo_session), or when that cache is still at its
* zero-initialized "never printed" default (empty string / session 0 --
* values no real echoed event can produce, repl_internal.h's own doc
* comment on these fields). The comparison is on the RENDERED pair only,
* never the raw xce_core_now() value, which changes on every call (Req
* 1.3). `rs == NULL` cannot happen in practice (xce_repl_on_event() only
* reaches here when sim->repl_state != NULL), but is guarded the same
* defensive way session_num above already is, by printing unconditionally
* rather than dereferencing rs->last_echo_*.
*/
if ((rs == NULL) || (strcmp(rs->last_echo_ts_human, ts_human) != 0)
|| (rs->last_echo_session != session_num)) {
fprintf(stdout, "[sim] t=%llu (%s) session=%llu\n",
(unsigned long long)xce_core_now(&(sim->core)), ts_human,
(unsigned long long)session_num);
if (rs != NULL) {
snprintf(rs->last_echo_ts_human, sizeof(rs->last_echo_ts_human),
"%s", ts_human);
rs->last_echo_session = session_num;
}
}
/* The event's own content line below is printed UNCONDITIONALLY
* regardless of the preamble decision above -- this component only ever
* suppresses the preamble, never the content (Req 1.4, 2.2). */
switch (ev->type) {
case XCE_CORE_EVENT_CONFIG_PUSH:
fprintf(stdout, "[sim] event: CONFIG_PUSH\n");

View file

@ -260,6 +260,36 @@ struct xce_sched_repl_state_s {
* exception.
*/
xce_repl_units_mode_t units_mode;
/*
* Event Echo Preamble Deduplicator fields (scheduler-sim-step-verbosity
* spec, task 1.2, design.md's "Event Echo Preamble Deduplicator"
* component, Req 1.1-1.4/2.2) - cache the rendered (second-granularity)
* human timestamp and displayed session number of the last preamble
* ACTUALLY PRINTED by repl_print_event_summary() (repl_break.c), so a
* consecutive echoed event sharing the same rendered context can skip
* reprinting it instead of restating the same "[sim] t=... session=..."
* line before every single event. Like every field in this struct
* except `units_mode` above, both legitimately rely on calloc's
* zero-initialization being a valid default -- no explicit post-calloc
* assignment is needed here: an empty string / session 0 can never equal
* a real echoed event's rendered timestamp/session (session numbers
* start at 1, session_count + 1), so repl_print_event_summary()'s "no
* preceding echoed event this session" case (AC 1.2) is satisfied by the
* zero default alone. Written only by repl_print_event_summary(), only
* when it actually prints a preamble; read only there.
*/
char last_echo_ts_human[32]; /* last rendered human timestamp
* actually printed in a preamble; ""
* (calloc zero) until the first
* preamble prints this session. Same
* buffer size as repl_format_ts_human()
* output buffers elsewhere in this
* file family. */
uint64_t last_echo_session; /* last displayed session number
* actually printed in a preamble; 0
* (calloc zero) until the first
* preamble prints this session. */
};
/* repl_split_tokens/XCE_REPL_MAX_TOKENS/XCE_REPL_TOKEN_LEN (repl.c) -