feat(dirty-content-fingerprint): add --version-only composition with dirty_fingerprint

Adds xce_compose_version_ex() as a sibling of the existing, completely
untouched xce_compose_version(): when dirty_fingerprint is non-empty, it
strips a trailing -dirty from the commit field (anchored tail-slice
strcmp, not a substring search) and appends -<dirty_fingerprint> instead;
when empty/NULL, it delegates directly to the original function, so
output is structurally guaranteed byte-identical -- including the
Requirement 5.2 fallback case (dirty tree, fingerprint computation
failed) where commit_id's own pre-existing -dirty suffix already signals
"modified" with no new sentinel needed.

No main.c call sites touched -- consuming daemons (tasks 3.2/3.3) still
call the original xce_compose_version() and will switch to the new
function themselves.

Verified independently by review, full lib suite on both debug and ASAN
profiles: 301 tests, 0 failures, 0 ignored; suffix-anchoring, buffer
safety, and the empty-fingerprint delegation path all confirmed correct
by hand-tracing the implementation, not just trusting the test results.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Rongsong Shen 2026-08-21 05:19:12 +00:00
parent fc5cba15e1
commit 7ebcba6d49
No known key found for this signature in database
GPG key ID: 5BCDAAE0123E9FE2
4 changed files with 178 additions and 5 deletions

View file

@ -170,6 +170,21 @@ extern char* verbose_to_loglevel(int);
extern const char* xce_version_field(const char*);
extern int xce_compose_version(char*, size_t, const char*, const char*,
const char*);
/* dirty-content-fingerprint task 3.1: --version-only sibling of
* xce_compose_version() above. Same composition (prefix + commit +
* " built " + build_time), plus one more optional field: when
* dirty_fingerprint is non-empty, a trailing "-dirty" on commit is
* stripped and "-<dirty_fingerprint>" is appended in its place, producing
* "<commit>-<dirty_fingerprint>". When dirty_fingerprint is NULL or empty,
* this function delegates straight to xce_compose_version() and produces
* byte-identical output -- commit_id's own computation and its existing
* -dirty suffix are never touched by this function. The startup-log
* composition call sites (controller/scheduler/worker main.c) must keep
* calling xce_compose_version() directly, never this function -- this is
* what keeps the startup log's format unchanged per Requirement 3.2 of the
* dirty-content-fingerprint spec. */
extern int xce_compose_version_ex(char*, size_t, const char*, const char*,
const char*, const char*);
extern void set_error(char*, char*, int, int);
extern ectx_t* get_ectx(void);
extern int xce_vprintf(const char*, va_list);