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

@ -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) -